001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.oscal.lib.model.control; 007 008import java.util.ArrayList; 009import java.util.Arrays; 010import java.util.Collection; 011import java.util.LinkedList; 012import java.util.List; 013import java.util.Objects; 014import java.util.stream.Stream; 015 016import dev.metaschema.core.datatype.markup.MarkupLine; 017import dev.metaschema.core.datatype.markup.MarkupMultiline; 018import dev.metaschema.core.util.CollectionUtil; 019import dev.metaschema.core.util.ObjectUtils; 020import dev.metaschema.oscal.lib.model.Link; 021import dev.metaschema.oscal.lib.model.Parameter; 022import dev.metaschema.oscal.lib.model.ParameterConstraint; 023import dev.metaschema.oscal.lib.model.ParameterGuideline; 024import dev.metaschema.oscal.lib.model.ParameterSelection; 025import dev.metaschema.oscal.lib.model.Property; 026import dev.metaschema.oscal.lib.model.metadata.IProperty; 027import edu.umd.cs.findbugs.annotations.NonNull; 028 029public abstract class AbstractParameter implements IParameter { 030 031 @Override 032 public Stream<String> getParameterReferences() { 033 034 // handle prop name="aggregates" 035 Stream<String> aggregatesIds = CollectionUtil.listOrEmpty(getProps()).stream() 036 .filter(Objects::nonNull) 037 .filter(prop -> prop.isNamespaceEqual(IProperty.OSCAL_NAMESPACE) && "aggregates".equals(prop.getName())) 038 .map(Property::getValue); 039 040 // handle select/choice/insert 041 ParameterSelection selection = getSelect(); 042 043 Stream<String> selectInsertIds; 044 if (selection == null) { 045 selectInsertIds = Stream.empty(); 046 } else { 047 selectInsertIds = CollectionUtil.listOrEmpty(selection.getChoice()).stream() 048 .filter(Objects::nonNull) 049 .flatMap(choice -> choice.getInserts(insert -> "param".equals(insert.getType().toString())).stream() 050 .map(insert -> insert.getIdReference().toString())); 051 } 052 Stream<String> retval = Stream.concat(aggregatesIds, selectInsertIds) 053 .filter(Objects::nonNull) 054 .distinct(); 055 assert retval != null; 056 return retval; 057 } 058 059 @NonNull 060 public static Builder builder(@NonNull String id) { 061 return new Builder(id); 062 } 063 064 public static class Builder { 065 @NonNull 066 private final String id; 067 068 private String clazz; 069 private final List<Property> props = new LinkedList<>(); 070 private final List<Link> links = new LinkedList<>(); 071 private MarkupLine label; 072 private MarkupMultiline usage; 073 private final List<ParameterConstraint> constraints = new LinkedList<>(); 074 private final List<ParameterGuideline> guidelines = new LinkedList<>(); 075 private List<String> values = new LinkedList<>(); 076 private ParameterSelection selection; 077 private MarkupMultiline remarks; 078 079 public Builder(@NonNull String id) { 080 this.id = ObjectUtils.requireNonNull(id); 081 } 082 083 @NonNull 084 public Builder clazz(@NonNull String value) { 085 this.clazz = ObjectUtils.requireNonNull(value); 086 return this; 087 } 088 089 @NonNull 090 public Builder prop(@NonNull Property value) { 091 this.props.add(ObjectUtils.requireNonNull(value)); 092 return this; 093 } 094 095 @NonNull 096 public Builder link(@NonNull Link value) { 097 this.links.add(ObjectUtils.requireNonNull(value)); 098 return this; 099 } 100 101 @NonNull 102 public Builder label(@NonNull String markdown) { 103 return label(MarkupLine.fromMarkdown(Objects.requireNonNull(markdown))); 104 } 105 106 @NonNull 107 public Builder label(@NonNull MarkupLine value) { 108 this.label = ObjectUtils.requireNonNull(value); 109 return this; 110 } 111 112 @NonNull 113 public Builder usage(@NonNull String markdown) { 114 return usage(MarkupMultiline.fromMarkdown(ObjectUtils.requireNonNull(markdown))); 115 } 116 117 @NonNull 118 public Builder usage(@NonNull MarkupMultiline value) { 119 this.usage = ObjectUtils.requireNonNull(value); 120 return this; 121 } 122 123 @NonNull 124 public Builder constraint(@NonNull ParameterConstraint value) { 125 this.constraints.add(ObjectUtils.requireNonNull(value)); 126 return this; 127 } 128 129 @NonNull 130 public Builder guideline(@NonNull ParameterGuideline value) { 131 this.guidelines.add(ObjectUtils.requireNonNull(value)); 132 return this; 133 } 134 135 @SuppressWarnings("null") 136 @NonNull 137 public Builder values(@NonNull String... values) { 138 return values(Arrays.asList(values)); 139 } 140 141 @NonNull 142 public Builder values(@NonNull Collection<String> values) { 143 this.values = new ArrayList<>(values); 144 return this; 145 } 146 147 @NonNull 148 public Builder select(@NonNull ParameterSelection value) { 149 this.selection = Objects.requireNonNull(value); 150 return this; 151 } 152 153 @NonNull 154 public Builder remarks(@NonNull MarkupMultiline value) { 155 this.remarks = Objects.requireNonNull(value); 156 return this; 157 } 158 159 @NonNull 160 public Parameter build() { 161 Parameter retval = new Parameter(); 162 retval.setId(id); 163 164 if (clazz != null) { 165 retval.setClazz(clazz); 166 } 167 if (!props.isEmpty()) { 168 retval.setProps(props); 169 } 170 if (!links.isEmpty()) { 171 retval.setLinks(links); 172 } 173 if (label != null) { 174 retval.setLabel(label); 175 } 176 if (usage != null) { 177 retval.setUsage(usage); 178 } 179 if (!constraints.isEmpty()) { 180 retval.setConstraints(constraints); 181 } 182 if (!guidelines.isEmpty()) { 183 retval.setGuidelines(guidelines); 184 } 185 if (!values.isEmpty()) { 186 retval.setValues(values); 187 } 188 if (selection != null) { 189 retval.setSelect(selection); 190 } 191 if (remarks != null) { 192 retval.setRemarks(remarks); 193 } 194 return retval; 195 } 196 } 197}