001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.oscal.lib.model.control.catalog; 007 008import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; 009import gov.nist.secauto.metaschema.core.util.CollectionUtil; 010import gov.nist.secauto.metaschema.core.util.ObjectUtils; 011import gov.nist.secauto.oscal.lib.model.CatalogGroup; 012import gov.nist.secauto.oscal.lib.model.Control; 013import gov.nist.secauto.oscal.lib.model.ControlPart; 014import gov.nist.secauto.oscal.lib.model.Link; 015import gov.nist.secauto.oscal.lib.model.Parameter; 016import gov.nist.secauto.oscal.lib.model.Property; 017import gov.nist.secauto.oscal.lib.model.control.AbstractParameter; 018 019import java.util.LinkedList; 020import java.util.List; 021import java.util.Objects; 022import java.util.stream.Stream; 023 024import edu.umd.cs.findbugs.annotations.NonNull; 025 026public abstract class AbstractCatalogGroup 027 implements ICatalogGroup { 028 029 @NonNull 030 @Override 031 public Stream<String> getReferencedParameterIds() { 032 033 // get parameters referenced by the group's parts 034 Stream<String> insertIds = CollectionUtil.listOrEmpty(getParts()).stream() 035 // Get the full part hierarchy 036 .flatMap(part -> Stream.concat(Stream.of(part), part.getPartsRecursively())) 037 // Get the inserts for each part 038 .flatMap(part -> part.getInserts(insert -> "param".equals(insert.getType().toString()))) 039 // Get the param ids for each insert 040 .map(insert -> insert.getIdReference().toString()) 041 .flatMap(ObjectUtils::filterNull); 042 043 // get parameters referenced by the control's parameters 044 Stream<String> parameterIds = CollectionUtil.listOrEmpty(getParams()).stream() 045 .flatMap(ObjectUtils::filterNull) 046 .flatMap(AbstractParameter::getParameterReferences); 047 048 return ObjectUtils.notNull( 049 Stream.concat(insertIds, parameterIds).distinct()); 050 } 051 052 @NonNull 053 public static Builder builder(@NonNull String id) { 054 return new Builder(id); 055 } 056 057 public static class Builder { 058 @NonNull 059 private final String id; 060 061 private String clazz; 062 private MarkupLine title; 063 private final List<Parameter> params = new LinkedList<>(); 064 private final List<Property> props = new LinkedList<>(); 065 private final List<Link> links = new LinkedList<>(); 066 private final List<ControlPart> parts = new LinkedList<>(); 067 private final List<CatalogGroup> groups = new LinkedList<>(); 068 private final List<Control> controls = new LinkedList<>(); 069 070 public Builder(@NonNull String id) { 071 this.id = ObjectUtils.requireNonNull(id, "id"); 072 } 073 074 @NonNull 075 public Builder clazz(@NonNull String value) { 076 this.clazz = ObjectUtils.requireNonNull(value, "value"); 077 return this; 078 } 079 080 @NonNull 081 public Builder title(@NonNull String markdown) { 082 this.title = MarkupLine.fromMarkdown(Objects.requireNonNull(markdown, "markdown")); 083 return this; 084 } 085 086 @NonNull 087 public Builder title(@NonNull MarkupLine value) { 088 this.title = ObjectUtils.requireNonNull(value, "value"); 089 return this; 090 } 091 092 @NonNull 093 public Builder param(@NonNull Parameter value) { 094 this.params.add(Objects.requireNonNull(value, "value")); 095 return this; 096 } 097 098 @NonNull 099 public Builder prop(@NonNull Property value) { 100 this.props.add(Objects.requireNonNull(value, "value")); 101 return this; 102 } 103 104 @NonNull 105 public Builder link(@NonNull Link value) { 106 this.links.add(Objects.requireNonNull(value, "value")); 107 return this; 108 } 109 110 @NonNull 111 public Builder part(@NonNull ControlPart value) { 112 this.parts.add(Objects.requireNonNull(value, "value")); 113 return this; 114 } 115 116 @NonNull 117 public Builder group(@NonNull CatalogGroup value) { 118 this.groups.add(Objects.requireNonNull(value, "value")); 119 return this; 120 } 121 122 @NonNull 123 public Builder control(@NonNull Control value) { 124 this.controls.add(Objects.requireNonNull(value, "value")); 125 return this; 126 } 127 128 @NonNull 129 public CatalogGroup build() { 130 CatalogGroup retval = new CatalogGroup(); 131 retval.setId(id); 132 133 if (title == null) { 134 throw new IllegalStateException("a title must be provided"); 135 } 136 retval.setTitle(title); 137 138 if (clazz != null) { 139 retval.setClazz(clazz); 140 } 141 if (!params.isEmpty()) { 142 retval.setParams(params); 143 } 144 if (!props.isEmpty()) { 145 retval.setProps(props); 146 } 147 if (!links.isEmpty()) { 148 retval.setLinks(links); 149 } 150 if (!parts.isEmpty()) { 151 retval.setParts(parts); 152 } 153 if (!controls.isEmpty()) { 154 retval.setControls(controls); 155 } 156 if (!groups.isEmpty()) { 157 retval.setGroups(groups); 158 } 159 160 return retval; 161 } 162 } 163}