001package gov.nist.secauto.oscal.lib.model; 002 003import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValue; 004import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValues; 005import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly; 006import gov.nist.secauto.metaschema.binding.model.annotations.BoundField; 007import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue; 008import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag; 009import gov.nist.secauto.metaschema.binding.model.annotations.Expect; 010import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs; 011import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly; 012import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints; 013import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior; 014import gov.nist.secauto.metaschema.model.common.constraint.IConstraint; 015import gov.nist.secauto.metaschema.model.common.datatype.adapter.BooleanAdapter; 016import gov.nist.secauto.metaschema.model.common.datatype.adapter.StringAdapter; 017import gov.nist.secauto.metaschema.model.common.util.ObjectUtils; 018import java.lang.Boolean; 019import java.lang.Override; 020import java.lang.String; 021import java.util.LinkedList; 022import java.util.List; 023import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle; 024import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 025 026/** 027 * Provides structuring directives that instruct how controls are organized after profile resolution. 028 */ 029@MetaschemaAssembly( 030 formalName = "Merge Controls", 031 description = "Provides structuring directives that instruct how controls are organized after profile resolution.", 032 name = "merge", 033 metaschema = OscalProfileMetaschema.class 034) 035public class Merge { 036 /** 037 * "A Combine element defines how to resolve duplicate instances of the same control (e.g., controls with the same ID)." 038 */ 039 @BoundAssembly( 040 formalName = "Combination Rule", 041 description = "A Combine element defines how to resolve duplicate instances of the same control (e.g., controls with the same ID).", 042 useName = "combine" 043 ) 044 private Combine _combine; 045 046 /** 047 * "Directs that controls appear without any grouping structure." 048 */ 049 @BoundAssembly( 050 formalName = "Flat Without Grouping", 051 description = "Directs that controls appear without any grouping structure.", 052 useName = "flat", 053 minOccurs = 1 054 ) 055 private Flat _flat; 056 057 /** 058 * "Indicates that the controls selected should retain their original grouping as defined in the import source." 059 */ 060 @BoundField( 061 formalName = "Group As-Is", 062 description = "Indicates that the controls selected should retain their original grouping as defined in the import source.", 063 useName = "as-is", 064 minOccurs = 1 065 ) 066 @BoundFieldValue( 067 typeAdapter = BooleanAdapter.class 068 ) 069 private Boolean _asIs; 070 071 /** 072 * "Provides an alternate grouping structure that selected controls will be placed in." 073 */ 074 @BoundAssembly( 075 formalName = "Custom Grouping", 076 description = "Provides an alternate grouping structure that selected controls will be placed in.", 077 useName = "custom", 078 minOccurs = 1, 079 remarks = "The `custom` element represents a custom arrangement or organization of controls in the resolution of a catalog. This structuring directive gives the profile author the ability to define an entirely different organization of controls as compared to their source catalog(s)." 080 ) 081 private Custom _custom; 082 083 public Merge() { 084 } 085 086 public Combine getCombine() { 087 return _combine; 088 } 089 090 public void setCombine(Combine value) { 091 _combine = value; 092 } 093 094 public Flat getFlat() { 095 return _flat; 096 } 097 098 public void setFlat(Flat value) { 099 _flat = value; 100 } 101 102 public Boolean getAsIs() { 103 return _asIs; 104 } 105 106 public void setAsIs(Boolean value) { 107 _asIs = value; 108 } 109 110 public Custom getCustom() { 111 return _custom; 112 } 113 114 public void setCustom(Custom value) { 115 _custom = value; 116 } 117 118 @Override 119 public String toString() { 120 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString(); 121 } 122 123 /** 124 * A Combine element defines how to resolve duplicate instances of the same control (e.g., controls with the same ID). 125 */ 126 @MetaschemaAssembly( 127 formalName = "Combination Rule", 128 description = "A Combine element defines how to resolve duplicate instances of the same control (e.g., controls with the same ID).", 129 name = "combine", 130 metaschema = OscalProfileMetaschema.class 131 ) 132 @ValueConstraints( 133 expect = @Expect(id = "req-merge-combine", level = IConstraint.Level.ERROR, test = "not(@method='merge')") 134 ) 135 public static class Combine { 136 @BoundFlag( 137 formalName = "Combination Method", 138 description = "Declare how clashing controls should be handled.", 139 useName = "method", 140 typeAdapter = StringAdapter.class 141 ) 142 @ValueConstraints( 143 allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, values = {@AllowedValue(value = "use-first", description = "Use the first definition - the first control with a given ID is used; subsequent ones are discarded"), @AllowedValue(value = "merge", description = "\\*\\*(*deprecated* )\\*\\* \\*\\*(*unspecified*)\\*\\* Merge - controls with the same ID are combined"), @AllowedValue(value = "keep", description = "Keep - controls with the same ID are kept, retaining the clash")}) 144 ) 145 private String _method; 146 147 public Combine() { 148 } 149 150 public String getMethod() { 151 return _method; 152 } 153 154 public void setMethod(String value) { 155 _method = value; 156 } 157 158 @Override 159 public String toString() { 160 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString(); 161 } 162 } 163 164 /** 165 * Directs that controls appear without any grouping structure. 166 */ 167 @MetaschemaAssembly( 168 formalName = "Flat Without Grouping", 169 description = "Directs that controls appear without any grouping structure.", 170 name = "flat", 171 metaschema = OscalProfileMetaschema.class 172 ) 173 public static class Flat { 174 public Flat() { 175 } 176 177 @Override 178 public String toString() { 179 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString(); 180 } 181 } 182 183 /** 184 * Provides an alternate grouping structure that selected controls will be placed in. 185 */ 186 @MetaschemaAssembly( 187 formalName = "Custom Grouping", 188 description = "Provides an alternate grouping structure that selected controls will be placed in.", 189 name = "custom", 190 metaschema = OscalProfileMetaschema.class, 191 remarks = "The `custom` element represents a custom arrangement or organization of controls in the resolution of a catalog. This structuring directive gives the profile author the ability to define an entirely different organization of controls as compared to their source catalog(s)." 192 ) 193 public static class Custom { 194 @BoundAssembly( 195 formalName = "Control Group", 196 description = "A group of (selected) controls or of groups of controls.", 197 useName = "group", 198 maxOccurs = -1 199 ) 200 @GroupAs( 201 name = "groups", 202 inJson = JsonGroupAsBehavior.LIST 203 ) 204 private List<ProfileGroup> _groups; 205 206 @BoundAssembly( 207 formalName = "Insert Controls", 208 description = "Specifies which controls to use in the containing context.", 209 useName = "insert-controls", 210 maxOccurs = -1 211 ) 212 @GroupAs( 213 name = "insert-controls", 214 inJson = JsonGroupAsBehavior.LIST 215 ) 216 private List<InsertControls> _insertControls; 217 218 public Custom() { 219 } 220 221 public List<ProfileGroup> getGroups() { 222 return _groups; 223 } 224 225 public void setGroups(List<ProfileGroup> value) { 226 _groups = value; 227 } 228 229 /** 230 * Add a new {@link ProfileGroup} item to the underlying collection. 231 * @param item the item to add 232 * @return {@code true} 233 */ 234 public boolean addGroup(ProfileGroup item) { 235 ProfileGroup value = ObjectUtils.requireNonNull(item,"item cannot be null"); 236 if (_groups == null) { 237 _groups = new LinkedList<>(); 238 } 239 return _groups.add(value); 240 } 241 242 /** 243 * Remove the first matching {@link ProfileGroup} item from the underlying collection. 244 * @param item the item to remove 245 * @return {@code true} if the item was removed or {@code false} otherwise 246 */ 247 public boolean removeGroup(ProfileGroup item) { 248 ProfileGroup value = ObjectUtils.requireNonNull(item,"item cannot be null"); 249 return _groups == null ? false : _groups.remove(value); 250 } 251 252 public List<InsertControls> getInsertControls() { 253 return _insertControls; 254 } 255 256 public void setInsertControls(List<InsertControls> value) { 257 _insertControls = value; 258 } 259 260 /** 261 * Add a new {@link InsertControls} item to the underlying collection. 262 * @param item the item to add 263 * @return {@code true} 264 */ 265 public boolean addInsertControls(InsertControls item) { 266 InsertControls value = ObjectUtils.requireNonNull(item,"item cannot be null"); 267 if (_insertControls == null) { 268 _insertControls = new LinkedList<>(); 269 } 270 return _insertControls.add(value); 271 } 272 273 /** 274 * Remove the first matching {@link InsertControls} item from the underlying collection. 275 * @param item the item to remove 276 * @return {@code true} if the item was removed or {@code false} otherwise 277 */ 278 public boolean removeInsertControls(InsertControls item) { 279 InsertControls value = ObjectUtils.requireNonNull(item,"item cannot be null"); 280 return _insertControls == null ? false : _insertControls.remove(value); 281 } 282 283 @Override 284 public String toString() { 285 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString(); 286 } 287 } 288}