001// Generated from: ../../../../../../../../oscal/src/metaschema/oscal_catalog_metaschema.xml 002// Do not edit - changes will be lost when regenerated. 003package dev.metaschema.oscal.lib.model; 004 005import dev.metaschema.core.datatype.adapter.TokenAdapter; 006import dev.metaschema.core.datatype.markup.MarkupLine; 007import dev.metaschema.core.datatype.markup.MarkupLineAdapter; 008import dev.metaschema.core.model.IBoundObject; 009import dev.metaschema.core.model.IMetaschemaData; 010import dev.metaschema.core.model.JsonGroupAsBehavior; 011import dev.metaschema.core.model.constraint.IConstraint; 012import dev.metaschema.core.util.ObjectUtils; 013import dev.metaschema.databind.model.annotations.AllowedValue; 014import dev.metaschema.databind.model.annotations.AllowedValues; 015import dev.metaschema.databind.model.annotations.BoundAssembly; 016import dev.metaschema.databind.model.annotations.BoundField; 017import dev.metaschema.databind.model.annotations.BoundFlag; 018import dev.metaschema.databind.model.annotations.Expect; 019import dev.metaschema.databind.model.annotations.GroupAs; 020import dev.metaschema.databind.model.annotations.IndexHasKey; 021import dev.metaschema.databind.model.annotations.KeyField; 022import dev.metaschema.databind.model.annotations.MetaschemaAssembly; 023import dev.metaschema.databind.model.annotations.ValueConstraints; 024import dev.metaschema.oscal.lib.model.control.catalog.AbstractControl; 025import edu.umd.cs.findbugs.annotations.NonNull; 026import edu.umd.cs.findbugs.annotations.Nullable; 027import java.util.LinkedList; 028import java.util.List; 029import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 030import org.apache.commons.lang3.builder.ToStringStyle; 031 032/** 033 * A <a href="https://pages.nist.gov/OSCAL/concepts/terminology/#control">structured object</a> representing a requirement or guideline, which when implemented will reduce an aspect of risk related to an information system and its information. 034 */ 035@MetaschemaAssembly( 036 formalName = "Control", 037 description = "A [structured object](https://pages.nist.gov/OSCAL/concepts/terminology/#control) representing a requirement or guideline, which when implemented will reduce an aspect of risk related to an information system and its information.", 038 name = "control", 039 moduleClass = OscalCatalogModule.class, 040 remarks = "Each security or privacy control within the catalog is defined by a distinct control instance. Controls may be as complex or as simple as a catalog defines them. They may be decomposed or further specified into child `control` objects, for example to represent control enhancements or specific breakouts of control functionality, to be maintained as discrete requirements. Controls may also contain structured parts (using `part`) and they may be grouped together in families or classes with `group`.\n" 041 + "\n" 042 + "Control structures in OSCAL will also exhibit regularities and rules that are not codified in OSCAL but in its applications or domains of application. For example, for catalogs describing controls as defined by NIST SP 800-53, a control must have a part with the name \"statement\", which represents the textual narrative of the control. This \"statement\" part must occur only once, but may have nested parts to allow for multiple paragraphs or sections of text. This organization supports addressability of this data content as long as, and only insofar as, it is consistently implemented across the control set. As given with these model definitions, constraints defined and assigned here can aid in ensuring this regularity; but other such constraints and other useful patterns of use remain to be discovered and described.", 043 valueConstraints = @ValueConstraints(allowedValues = {@AllowedValues(id = "oscal-control-prop-name", level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "label", description = "A human-readable label for the parent context, which may be rendered in place of the actual identifier for some use cases."), @AllowedValue(value = "sort-id", description = "An alternative identifier, whose value is easily sortable among other such values in the document."), @AllowedValue(value = "alt-identifier", description = "An alternate or aliased identifier for the parent context."), @AllowedValue(value = "status", description = "The status of a `control`. For example, a value of 'withdrawn' can indicate that the `control` has been withdrawn and should no longer be used.")}), @AllowedValues(id = "oscal-control-prop-status-value", level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='status']/@value", values = {@AllowedValue(value = "withdrawn", description = "The control is no longer used."), @AllowedValue(value = "Withdrawn", description = "\\*\\*(deprecated)\\*\\*\\* Use 'withdrawn' instead.", deprecatedVersion = "1.0.0")}), @AllowedValues(id = "oscal-control-link-rel-type", level = IConstraint.Level.ERROR, target = "link/@rel", allowOthers = true, values = {@AllowedValue(value = "reference", description = "The link cites an external resource related to this control."), @AllowedValue(value = "related", description = "The link identifies another control with bearing to this control."), @AllowedValue(value = "required", description = "The link identifies another control that must be present if this control is present."), @AllowedValue(value = "incorporated-into", description = "The link identifies other control content where this control content is now addressed."), @AllowedValue(value = "moved-to", description = "The containing control definition was moved to the referenced control.")}), @AllowedValues(id = "oscal-control-part-name", level = IConstraint.Level.ERROR, target = "part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "overview", description = "An introduction to a control or a group of controls."), @AllowedValue(value = "statement", description = "A set of implementation requirements or recommendations."), @AllowedValue(value = "guidance", description = "Additional information to consider when selecting, implementing, assessing, and monitoring a control."), @AllowedValue(value = "example", description = "An example of an implemented requirement or control statement."), @AllowedValue(value = "assessment", description = "\\*\\*(deprecated)\\*\\* Use 'assessment-method' instead.", deprecatedVersion = "1.0.1"), @AllowedValue(value = "assessment-method", description = "The part describes a method-based assessment over a set of assessment objects.")}), @AllowedValues(id = "oscal-control-statement-part-subpart-name", level = IConstraint.Level.ERROR, target = "part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='statement']//part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = @AllowedValue(value = "item", description = "An individual item within a control statement."), remarks = "Nested statement parts are \"item\" parts."), @AllowedValues(id = "oscal-control-statement-part-name", level = IConstraint.Level.ERROR, target = ".//part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "objective", description = "\\*\\*(deprecated)\\*\\* Use 'assessment-objective' instead.", deprecatedVersion = "1.0.1"), @AllowedValue(value = "assessment-objective", description = "The part describes a set of assessment objectives.")}, remarks = "Objectives can be nested."), @AllowedValues(id = "oscal-control-objective-part-subpart-name", level = IConstraint.Level.ERROR, target = "part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name=('assessment','assessment-method')]/part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "objects", description = "\\*\\*(deprecated)\\*\\* Use 'assessment-objects' instead.", deprecatedVersion = "1.0.1"), @AllowedValue(value = "assessment-objects", description = "Provides a listing of assessment objects.")}, remarks = "Assessment objects appear on assessment methods."), @AllowedValues(id = "oscal-control-statement-part-prop-name", level = IConstraint.Level.ERROR, target = "part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name=('assessment','assessment-method')]/prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = @AllowedValue(value = "method", description = "\\*\\*(deprecated)\\*\\* Use 'method' in the 'http://csrc.nist.gov/ns/rmf' namespace. The assessment method to use. This typically appears on parts with the name \"assessment-method\".", deprecatedVersion = "1.0.1")), @AllowedValues(id = "oscal-control-statement-part-rmf-prop-name", level = IConstraint.Level.ERROR, target = "part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name=('assessment','assessment-method')]/prop[has-oscal-namespace('http://csrc.nist.gov/ns/rmf')]/@name", values = @AllowedValue(value = "method", description = "The assessment method to use. This typically appears on parts with the name \"assessment-method\".")), @AllowedValues(id = "oscal-control-objective-part-method-prop-value", level = IConstraint.Level.ERROR, target = "part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name=('assessment','assessment-method')]/prop[has-oscal-namespace(('http://csrc.nist.gov/ns/oscal','http://csrc.nist.gov/ns/rmf')) and @name='method']/@value", values = {@AllowedValue(value = "INTERVIEW", description = "The process of holding discussions with individuals or groups of individuals within an organization to once again, facilitate assessor understanding, achieve clarification, or obtain evidence."), @AllowedValue(value = "EXAMINE", description = "The process of reviewing, inspecting, observing, studying, or analyzing one or more assessment objects (i.e., specifications, mechanisms, or activities)."), @AllowedValue(value = "TEST", description = "The process of exercising one or more assessment objects (i.e., activities or mechanisms) under specified conditions to compare actual with expected behavior.")})}, indexHasKey = @IndexHasKey(id = "oscal-catalog-groups-controls-parts", level = IConstraint.Level.WARNING, target = "link[@rel=('related','required','incorporated-into','moved-to') and starts-with(@href,'#')]", indexName = "catalog-groups-controls-parts", keyFields = @KeyField(target = "@href", pattern = "#(.*)")), expect = {@Expect(id = "oscal-catalog-control-require-statement-when-not-withdrawn", level = IConstraint.Level.ERROR, test = "prop[@name='status']/@value=('withdrawn','Withdrawn') or part[@name='statement']"), @Expect(id = "oscal-method-part-has-method-prop", level = IConstraint.Level.WARNING, target = "part[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name=('assessment','assessment-method')]", test = "prop[has-oscal-namespace(('http://csrc.nist.gov/ns/oscal','http://csrc.nist.gov/ns/rmf')) and @name='method']")}) 044) 045public class Control extends AbstractControl implements IBoundObject { 046 private final IMetaschemaData __metaschemaData; 047 048 /** 049 * Identifies a control such that it can be referenced in the defining catalog and other OSCAL instances (e.g., profiles). 050 */ 051 @BoundFlag( 052 formalName = "Control Identifier", 053 description = "Identifies a control such that it can be referenced in the defining catalog and other OSCAL instances (e.g., profiles).", 054 name = "id", 055 required = true, 056 typeAdapter = TokenAdapter.class 057 ) 058 private String _id; 059 060 /** 061 * A textual label that provides a sub-type or characterization of the control. 062 */ 063 @BoundFlag( 064 formalName = "Control Class", 065 description = "A textual label that provides a sub-type or characterization of the control.", 066 name = "class", 067 typeAdapter = TokenAdapter.class, 068 remarks = "A `class` can be used in validation rules to express extra constraints over named items of a specific `class` value.\n" 069 + "\n" 070 + "A `class` can also be used in an OSCAL profile as a means to target an alteration to control content." 071 ) 072 private String _clazz; 073 074 /** 075 * A name given to the control, which may be used by a tool for display and navigation. 076 */ 077 @BoundField( 078 formalName = "Control Title", 079 description = "A name given to the control, which may be used by a tool for display and navigation.", 080 useName = "title", 081 minOccurs = 1, 082 typeAdapter = MarkupLineAdapter.class 083 ) 084 private MarkupLine _title; 085 086 /** 087 * Parameters provide a mechanism for the dynamic assignment of value(s) in a control. 088 */ 089 @BoundAssembly( 090 formalName = "Parameter", 091 description = "Parameters provide a mechanism for the dynamic assignment of value(s) in a control.", 092 useName = "param", 093 maxOccurs = -1, 094 groupAs = @GroupAs(name = "params", inJson = JsonGroupAsBehavior.LIST) 095 ) 096 private List<Parameter> _params; 097 098 /** 099 * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. 100 */ 101 @BoundAssembly( 102 formalName = "Property", 103 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.", 104 useName = "prop", 105 maxOccurs = -1, 106 groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST) 107 ) 108 private List<Property> _props; 109 110 /** 111 * A reference to a local or remote resource, that has a specific relation to the containing object. 112 */ 113 @BoundAssembly( 114 formalName = "Link", 115 description = "A reference to a local or remote resource, that has a specific relation to the containing object.", 116 useName = "link", 117 maxOccurs = -1, 118 groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST) 119 ) 120 private List<Link> _links; 121 122 /** 123 * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part. 124 */ 125 @BoundAssembly( 126 formalName = "Part", 127 description = "An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.", 128 useName = "part", 129 maxOccurs = -1, 130 groupAs = @GroupAs(name = "parts", inJson = JsonGroupAsBehavior.LIST) 131 ) 132 private List<ControlPart> _parts; 133 134 /** 135 * A <a href="https://pages.nist.gov/OSCAL/concepts/terminology/#control">structured object</a> representing a requirement or guideline, which when implemented will reduce an aspect of risk related to an information system and its information. 136 */ 137 @BoundAssembly( 138 formalName = "Control", 139 description = "A [structured object](https://pages.nist.gov/OSCAL/concepts/terminology/#control) representing a requirement or guideline, which when implemented will reduce an aspect of risk related to an information system and its information.", 140 useName = "control", 141 maxOccurs = -1, 142 groupAs = @GroupAs(name = "controls", inJson = JsonGroupAsBehavior.LIST) 143 ) 144 private List<Control> _controls; 145 146 /** 147 * Constructs a new {@code dev.metaschema.oscal.lib.model.Control} instance with no metadata. 148 */ 149 public Control() { 150 this(null); 151 } 152 153 /** 154 * Constructs a new {@code dev.metaschema.oscal.lib.model.Control} instance with the specified metadata. 155 * 156 * @param data 157 * the metaschema data, or {@code null} if none 158 */ 159 public Control(IMetaschemaData data) { 160 this.__metaschemaData = data; 161 } 162 163 @Override 164 public IMetaschemaData getMetaschemaData() { 165 return __metaschemaData; 166 } 167 168 /** 169 * Get the "{@literal Control Identifier}". 170 * 171 * <p> 172 * Identifies a control such that it can be referenced in the defining catalog and other OSCAL instances (e.g., profiles). 173 * 174 * @return the id value 175 */ 176 @NonNull 177 public String getId() { 178 return _id; 179 } 180 181 /** 182 * Set the "{@literal Control Identifier}". 183 * 184 * <p> 185 * Identifies a control such that it can be referenced in the defining catalog and other OSCAL instances (e.g., profiles). 186 * 187 * @param value 188 * the id value to set 189 */ 190 public void setId(@NonNull String value) { 191 _id = value; 192 } 193 194 /** 195 * Get the "{@literal Control Class}". 196 * 197 * <p> 198 * A textual label that provides a sub-type or characterization of the control. 199 * 200 * @return the class value, or {@code null} if not set 201 */ 202 @Nullable 203 public String getClazz() { 204 return _clazz; 205 } 206 207 /** 208 * Set the "{@literal Control Class}". 209 * 210 * <p> 211 * A textual label that provides a sub-type or characterization of the control. 212 * 213 * @param value 214 * the class value to set, or {@code null} to clear 215 */ 216 public void setClazz(@Nullable String value) { 217 _clazz = value; 218 } 219 220 /** 221 * Get the "{@literal Control Title}". 222 * 223 * <p> 224 * A name given to the control, which may be used by a tool for display and navigation. 225 * 226 * @return the title value 227 */ 228 @NonNull 229 public MarkupLine getTitle() { 230 return _title; 231 } 232 233 /** 234 * Set the "{@literal Control Title}". 235 * 236 * <p> 237 * A name given to the control, which may be used by a tool for display and navigation. 238 * 239 * @param value 240 * the title value to set 241 */ 242 public void setTitle(@NonNull MarkupLine value) { 243 _title = value; 244 } 245 246 /** 247 * Get the "{@literal Parameter}". 248 * 249 * <p> 250 * Parameters provide a mechanism for the dynamic assignment of value(s) in a control. 251 * 252 * @return the param value 253 */ 254 @NonNull 255 public List<Parameter> getParams() { 256 if (_params == null) { 257 _params = new LinkedList<>(); 258 } 259 return ObjectUtils.notNull(_params); 260 } 261 262 /** 263 * Set the "{@literal Parameter}". 264 * 265 * <p> 266 * Parameters provide a mechanism for the dynamic assignment of value(s) in a control. 267 * 268 * @param value 269 * the param value to set 270 */ 271 public void setParams(@NonNull List<Parameter> value) { 272 _params = value; 273 } 274 275 /** 276 * Add a new {@link Parameter} item to the underlying collection. 277 * @param item the item to add 278 * @return {@code true} 279 */ 280 public boolean addParam(Parameter item) { 281 Parameter value = ObjectUtils.requireNonNull(item,"item cannot be null"); 282 if (_params == null) { 283 _params = new LinkedList<>(); 284 } 285 return _params.add(value); 286 } 287 288 /** 289 * Remove the first matching {@link Parameter} item from the underlying collection. 290 * @param item the item to remove 291 * @return {@code true} if the item was removed or {@code false} otherwise 292 */ 293 public boolean removeParam(Parameter item) { 294 Parameter value = ObjectUtils.requireNonNull(item,"item cannot be null"); 295 return _params != null && _params.remove(value); 296 } 297 298 /** 299 * Get the "{@literal Property}". 300 * 301 * <p> 302 * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. 303 * 304 * @return the prop value 305 */ 306 @NonNull 307 public List<Property> getProps() { 308 if (_props == null) { 309 _props = new LinkedList<>(); 310 } 311 return ObjectUtils.notNull(_props); 312 } 313 314 /** 315 * Set the "{@literal Property}". 316 * 317 * <p> 318 * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. 319 * 320 * @param value 321 * the prop value to set 322 */ 323 public void setProps(@NonNull List<Property> value) { 324 _props = value; 325 } 326 327 /** 328 * Add a new {@link Property} item to the underlying collection. 329 * @param item the item to add 330 * @return {@code true} 331 */ 332 public boolean addProp(Property item) { 333 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 334 if (_props == null) { 335 _props = new LinkedList<>(); 336 } 337 return _props.add(value); 338 } 339 340 /** 341 * Remove the first matching {@link Property} item from the underlying collection. 342 * @param item the item to remove 343 * @return {@code true} if the item was removed or {@code false} otherwise 344 */ 345 public boolean removeProp(Property item) { 346 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 347 return _props != null && _props.remove(value); 348 } 349 350 /** 351 * Get the "{@literal Link}". 352 * 353 * <p> 354 * A reference to a local or remote resource, that has a specific relation to the containing object. 355 * 356 * @return the link value 357 */ 358 @NonNull 359 public List<Link> getLinks() { 360 if (_links == null) { 361 _links = new LinkedList<>(); 362 } 363 return ObjectUtils.notNull(_links); 364 } 365 366 /** 367 * Set the "{@literal Link}". 368 * 369 * <p> 370 * A reference to a local or remote resource, that has a specific relation to the containing object. 371 * 372 * @param value 373 * the link value to set 374 */ 375 public void setLinks(@NonNull List<Link> value) { 376 _links = value; 377 } 378 379 /** 380 * Add a new {@link Link} item to the underlying collection. 381 * @param item the item to add 382 * @return {@code true} 383 */ 384 public boolean addLink(Link item) { 385 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 386 if (_links == null) { 387 _links = new LinkedList<>(); 388 } 389 return _links.add(value); 390 } 391 392 /** 393 * Remove the first matching {@link Link} item from the underlying collection. 394 * @param item the item to remove 395 * @return {@code true} if the item was removed or {@code false} otherwise 396 */ 397 public boolean removeLink(Link item) { 398 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 399 return _links != null && _links.remove(value); 400 } 401 402 /** 403 * Get the "{@literal Part}". 404 * 405 * <p> 406 * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part. 407 * 408 * @return the part value 409 */ 410 @NonNull 411 public List<ControlPart> getParts() { 412 if (_parts == null) { 413 _parts = new LinkedList<>(); 414 } 415 return ObjectUtils.notNull(_parts); 416 } 417 418 /** 419 * Set the "{@literal Part}". 420 * 421 * <p> 422 * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part. 423 * 424 * @param value 425 * the part value to set 426 */ 427 public void setParts(@NonNull List<ControlPart> value) { 428 _parts = value; 429 } 430 431 /** 432 * Add a new {@link ControlPart} item to the underlying collection. 433 * @param item the item to add 434 * @return {@code true} 435 */ 436 public boolean addPart(ControlPart item) { 437 ControlPart value = ObjectUtils.requireNonNull(item,"item cannot be null"); 438 if (_parts == null) { 439 _parts = new LinkedList<>(); 440 } 441 return _parts.add(value); 442 } 443 444 /** 445 * Remove the first matching {@link ControlPart} item from the underlying collection. 446 * @param item the item to remove 447 * @return {@code true} if the item was removed or {@code false} otherwise 448 */ 449 public boolean removePart(ControlPart item) { 450 ControlPart value = ObjectUtils.requireNonNull(item,"item cannot be null"); 451 return _parts != null && _parts.remove(value); 452 } 453 454 /** 455 * Get the "{@literal Control}". 456 * 457 * <p> 458 * A <a href="https://pages.nist.gov/OSCAL/concepts/terminology/#control">structured object</a> representing a requirement or guideline, which when implemented will reduce an aspect of risk related to an information system and its information. 459 * 460 * @return the control value 461 */ 462 @NonNull 463 public List<Control> getControls() { 464 if (_controls == null) { 465 _controls = new LinkedList<>(); 466 } 467 return ObjectUtils.notNull(_controls); 468 } 469 470 /** 471 * Set the "{@literal Control}". 472 * 473 * <p> 474 * A <a href="https://pages.nist.gov/OSCAL/concepts/terminology/#control">structured object</a> representing a requirement or guideline, which when implemented will reduce an aspect of risk related to an information system and its information. 475 * 476 * @param value 477 * the control value to set 478 */ 479 public void setControls(@NonNull List<Control> value) { 480 _controls = value; 481 } 482 483 /** 484 * Add a new {@link Control} item to the underlying collection. 485 * @param item the item to add 486 * @return {@code true} 487 */ 488 public boolean addControl(Control item) { 489 Control value = ObjectUtils.requireNonNull(item,"item cannot be null"); 490 if (_controls == null) { 491 _controls = new LinkedList<>(); 492 } 493 return _controls.add(value); 494 } 495 496 /** 497 * Remove the first matching {@link Control} item from the underlying collection. 498 * @param item the item to remove 499 * @return {@code true} if the item was removed or {@code false} otherwise 500 */ 501 public boolean removeControl(Control item) { 502 Control value = ObjectUtils.requireNonNull(item,"item cannot be null"); 503 return _controls != null && _controls.remove(value); 504 } 505 506 @Override 507 public String toString() { 508 return ObjectUtils.notNull(new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString()); 509 } 510}