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