001// Generated from: ../../../../../../../../oscal/src/metaschema/oscal_control-common_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.adapter.UriAdapter; 007import dev.metaschema.core.datatype.markup.MarkupLine; 008import dev.metaschema.core.datatype.markup.MarkupLineAdapter; 009import dev.metaschema.core.datatype.markup.MarkupMultiline; 010import dev.metaschema.core.datatype.markup.MarkupMultilineAdapter; 011import dev.metaschema.core.model.IBoundObject; 012import dev.metaschema.core.model.IMetaschemaData; 013import dev.metaschema.core.model.JsonGroupAsBehavior; 014import dev.metaschema.core.model.constraint.IConstraint; 015import dev.metaschema.core.util.ObjectUtils; 016import dev.metaschema.databind.model.annotations.AllowedValue; 017import dev.metaschema.databind.model.annotations.AllowedValues; 018import dev.metaschema.databind.model.annotations.BoundAssembly; 019import dev.metaschema.databind.model.annotations.BoundField; 020import dev.metaschema.databind.model.annotations.BoundFlag; 021import dev.metaschema.databind.model.annotations.GroupAs; 022import dev.metaschema.databind.model.annotations.MetaschemaAssembly; 023import dev.metaschema.databind.model.annotations.ValueConstraints; 024import dev.metaschema.oscal.lib.model.control.AbstractPart; 025import edu.umd.cs.findbugs.annotations.NonNull; 026import edu.umd.cs.findbugs.annotations.Nullable; 027import java.net.URI; 028import java.util.LinkedList; 029import java.util.List; 030import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 031import org.apache.commons.lang3.builder.ToStringStyle; 032 033/** 034 * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part. 035 */ 036@MetaschemaAssembly( 037 formalName = "Part", 038 description = "An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.", 039 name = "part", 040 moduleClass = OscalControlCommonModule.class, 041 remarks = "A `part` provides for logical partitioning of prose, and can be thought of as a grouping structure (e.g., section). A `part` can have child parts allowing for arbitrary nesting of prose content (e.g., statement hierarchy). A `part` can contain `prop` objects that allow for enriching prose text with structured name/value information.\n" 042 + "\n" 043 + "A `part` can be assigned an optional `id`, which allows references to this part from within a catalog, or within an instance of another OSCAL model that has a need to reference the part. Examples of where part referencing is used in OSCAL include:\n" 044 + "\n" 045 + "- Referencing a part by id to tailor (make modifications to) a control statement in a profile.\n" 046 + "- Referencing a control statement represented by a part in a system security plan implemented-requirement where a statement-level response is desired.\n" 047 + "\n" 048 + "Use of `part` and `prop` provides for a wide degree of extensibility within the OSCAL catalog model. The optional `ns` provides a means to qualify a part's `name`, allowing for organization-specific vocabularies to be defined with clear semantics. Any organization that extends OSCAL in this way should consistently assign a `ns` value that represents the organization, making a given namespace qualified `name` unique to that organization. This allows the combination of `ns` and `name` to always be unique and unambiguous, even when mixed with extensions from other organizations. Each organization is responsible for governance of their own extensions, and is strongly encouraged to publish their extensions as standards to their user community. If no `ns` is provided, the name is expected to be in the \"OSCAL\" namespace.\n" 049 + "\n" 050 + "To ensure a `ns` is unique to an organization and naming conflicts are avoided, a URI containing a DNS or other globally defined organization name should be used. For example, if FedRAMP and DoD both extend OSCAL, FedRAMP will use the `ns` `http://fedramp.gov/ns/oscal`, while DoD might use the `ns` `https://defense.gov` for any organization specific `name`.\n" 051 + "\n" 052 + "Tools that process OSCAL content are not required to interpret unrecognized OSCAL extensions; however, OSCAL compliant tools should not modify or remove unrecognized extensions, unless there is a compelling reason to do so, such as data sensitivity.", 053 valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(id = "oscal-part-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.")})) 054) 055public class ControlPart extends AbstractPart implements IBoundObject { 056 private final IMetaschemaData __metaschemaData; 057 058 /** 059 * A unique identifier for the part. 060 */ 061 @BoundFlag( 062 formalName = "Part Identifier", 063 description = "A unique identifier for the part.", 064 name = "id", 065 typeAdapter = TokenAdapter.class, 066 remarks = "While a part is not required to have an id, it is often desirable for an identifier to be provided, which allows the part to be referenced elsewhere in OSCAL document instances. For this reason, it is RECOMMENDED to provide a part identifier." 067 ) 068 private String _id; 069 070 /** 071 * A textual label that uniquely identifies the part's semantic type, which exists in a value space qualified by the <code>ns</code>. 072 */ 073 @BoundFlag( 074 formalName = "Part Name", 075 description = "A textual label that uniquely identifies the part's semantic type, which exists in a value space qualified by the `ns`.", 076 name = "name", 077 required = true, 078 typeAdapter = TokenAdapter.class 079 ) 080 private String _name; 081 082 /** 083 * An optional namespace qualifying the part's <code>name</code>. This allows different organizations to associate distinct semantics with the same name. 084 */ 085 @BoundFlag( 086 formalName = "Part Namespace", 087 description = "An optional namespace qualifying the part's `name`. This allows different organizations to associate distinct semantics with the same name.", 088 name = "ns", 089 defaultValue = "http://csrc.nist.gov/ns/oscal", 090 typeAdapter = UriAdapter.class, 091 remarks = "This value must be an [absolute URI](https://pages.nist.gov/OSCAL/concepts/uri-use/#absolute-uri) that serves as a [naming system identifier](https://pages.nist.gov/OSCAL/concepts/uri-use/#use-as-a-naming-system-identifier).\n" 092 + "\n" 093 + "When a `ns` is not provided, its value should be assumed to be `http://csrc.nist.gov/ns/oscal` and the name should be a name defined by the associated OSCAL model." 094 ) 095 private URI _ns; 096 097 /** 098 * An optional textual providing a sub-type or characterization of the part's <code>name</code>, or a category to which the part belongs. 099 */ 100 @BoundFlag( 101 formalName = "Part Class", 102 description = "An optional textual providing a sub-type or characterization of the part's `name`, or a category to which the part belongs.", 103 name = "class", 104 typeAdapter = TokenAdapter.class, 105 remarks = "One use of this flag is to distinguish or discriminate between the semantics of multiple parts of the same control with the same `name` and `ns` (since even within a given namespace it can be useful to overload a name).\n" 106 + "\n" 107 + "A `class` can be used in validation rules to express extra constraints over named items of a specific `class` value.\n" 108 + "\n" 109 + "A `class` can also be used in an OSCAL profile as a means to target an alteration to control content." 110 ) 111 private String _clazz; 112 113 /** 114 * An optional name given to the part, which may be used by a tool for display and navigation. 115 */ 116 @BoundField( 117 formalName = "Part Title", 118 description = "An optional name given to the part, which may be used by a tool for display and navigation.", 119 useName = "title", 120 typeAdapter = MarkupLineAdapter.class 121 ) 122 private MarkupLine _title; 123 124 /** 125 * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. 126 */ 127 @BoundAssembly( 128 formalName = "Property", 129 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.", 130 useName = "prop", 131 maxOccurs = -1, 132 groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST) 133 ) 134 private List<Property> _props; 135 136 /** 137 * Permits multiple paragraphs, lists, tables etc. 138 */ 139 @BoundField( 140 formalName = "Part Text", 141 description = "Permits multiple paragraphs, lists, tables etc.", 142 useName = "prose", 143 inXmlWrapped = false, 144 typeAdapter = MarkupMultilineAdapter.class 145 ) 146 private MarkupMultiline _prose; 147 148 /** 149 * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part. 150 */ 151 @BoundAssembly( 152 formalName = "Part", 153 description = "An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.", 154 useName = "part", 155 maxOccurs = -1, 156 groupAs = @GroupAs(name = "parts", inJson = JsonGroupAsBehavior.LIST) 157 ) 158 private List<ControlPart> _parts; 159 160 /** 161 * A reference to a local or remote resource, that has a specific relation to the containing object. 162 */ 163 @BoundAssembly( 164 formalName = "Link", 165 description = "A reference to a local or remote resource, that has a specific relation to the containing object.", 166 useName = "link", 167 maxOccurs = -1, 168 groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST) 169 ) 170 private List<Link> _links; 171 172 /** 173 * Constructs a new {@code dev.metaschema.oscal.lib.model.ControlPart} instance with no metadata. 174 */ 175 public ControlPart() { 176 this(null); 177 } 178 179 /** 180 * Constructs a new {@code dev.metaschema.oscal.lib.model.ControlPart} instance with the specified metadata. 181 * 182 * @param data 183 * the metaschema data, or {@code null} if none 184 */ 185 public ControlPart(IMetaschemaData data) { 186 this.__metaschemaData = data; 187 } 188 189 @Override 190 public IMetaschemaData getMetaschemaData() { 191 return __metaschemaData; 192 } 193 194 /** 195 * Get the "{@literal Part Identifier}". 196 * 197 * <p> 198 * A unique identifier for the part. 199 * 200 * @return the id value, or {@code null} if not set 201 */ 202 @Nullable 203 public String getId() { 204 return _id; 205 } 206 207 /** 208 * Set the "{@literal Part Identifier}". 209 * 210 * <p> 211 * A unique identifier for the part. 212 * 213 * @param value 214 * the id value to set, or {@code null} to clear 215 */ 216 public void setId(@Nullable String value) { 217 _id = value; 218 } 219 220 /** 221 * Get the "{@literal Part Name}". 222 * 223 * <p> 224 * A textual label that uniquely identifies the part's semantic type, which exists in a value space qualified by the <code>ns</code>. 225 * 226 * @return the name value 227 */ 228 @NonNull 229 public String getName() { 230 return _name; 231 } 232 233 /** 234 * Set the "{@literal Part Name}". 235 * 236 * <p> 237 * A textual label that uniquely identifies the part's semantic type, which exists in a value space qualified by the <code>ns</code>. 238 * 239 * @param value 240 * the name value to set 241 */ 242 public void setName(@NonNull String value) { 243 _name = value; 244 } 245 246 /** 247 * Get the "{@literal Part Namespace}". 248 * 249 * <p> 250 * An optional namespace qualifying the part's <code>name</code>. This allows different organizations to associate distinct semantics with the same name. 251 * 252 * @return the ns value, or {@code null} if not set 253 */ 254 @Nullable 255 public URI getNs() { 256 return _ns; 257 } 258 259 /** 260 * Set the "{@literal Part Namespace}". 261 * 262 * <p> 263 * An optional namespace qualifying the part's <code>name</code>. This allows different organizations to associate distinct semantics with the same name. 264 * 265 * @param value 266 * the ns value to set, or {@code null} to clear 267 */ 268 public void setNs(@Nullable URI value) { 269 _ns = value; 270 } 271 272 /** 273 * Get the "{@literal Part Class}". 274 * 275 * <p> 276 * An optional textual providing a sub-type or characterization of the part's <code>name</code>, or a category to which the part belongs. 277 * 278 * @return the class value, or {@code null} if not set 279 */ 280 @Nullable 281 public String getClazz() { 282 return _clazz; 283 } 284 285 /** 286 * Set the "{@literal Part Class}". 287 * 288 * <p> 289 * An optional textual providing a sub-type or characterization of the part's <code>name</code>, or a category to which the part belongs. 290 * 291 * @param value 292 * the class value to set, or {@code null} to clear 293 */ 294 public void setClazz(@Nullable String value) { 295 _clazz = value; 296 } 297 298 /** 299 * Get the "{@literal Part Title}". 300 * 301 * <p> 302 * An optional name given to the part, which may be used by a tool for display and navigation. 303 * 304 * @return the title value, or {@code null} if not set 305 */ 306 @Nullable 307 public MarkupLine getTitle() { 308 return _title; 309 } 310 311 /** 312 * Set the "{@literal Part Title}". 313 * 314 * <p> 315 * An optional name given to the part, which may be used by a tool for display and navigation. 316 * 317 * @param value 318 * the title value to set, or {@code null} to clear 319 */ 320 public void setTitle(@Nullable MarkupLine value) { 321 _title = value; 322 } 323 324 /** 325 * Get the "{@literal Property}". 326 * 327 * <p> 328 * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. 329 * 330 * @return the prop value 331 */ 332 @NonNull 333 public List<Property> getProps() { 334 if (_props == null) { 335 _props = new LinkedList<>(); 336 } 337 return ObjectUtils.notNull(_props); 338 } 339 340 /** 341 * Set the "{@literal Property}". 342 * 343 * <p> 344 * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair. 345 * 346 * @param value 347 * the prop value to set 348 */ 349 public void setProps(@NonNull List<Property> value) { 350 _props = value; 351 } 352 353 /** 354 * Add a new {@link Property} item to the underlying collection. 355 * @param item the item to add 356 * @return {@code true} 357 */ 358 public boolean addProp(Property item) { 359 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 360 if (_props == null) { 361 _props = new LinkedList<>(); 362 } 363 return _props.add(value); 364 } 365 366 /** 367 * Remove the first matching {@link Property} item from the underlying collection. 368 * @param item the item to remove 369 * @return {@code true} if the item was removed or {@code false} otherwise 370 */ 371 public boolean removeProp(Property item) { 372 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 373 return _props != null && _props.remove(value); 374 } 375 376 /** 377 * Get the "{@literal Part Text}". 378 * 379 * <p> 380 * Permits multiple paragraphs, lists, tables etc. 381 * 382 * @return the prose value, or {@code null} if not set 383 */ 384 @Nullable 385 public MarkupMultiline getProse() { 386 return _prose; 387 } 388 389 /** 390 * Set the "{@literal Part Text}". 391 * 392 * <p> 393 * Permits multiple paragraphs, lists, tables etc. 394 * 395 * @param value 396 * the prose value to set, or {@code null} to clear 397 */ 398 public void setProse(@Nullable MarkupMultiline value) { 399 _prose = 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 Link}". 456 * 457 * <p> 458 * A reference to a local or remote resource, that has a specific relation to the containing object. 459 * 460 * @return the link value 461 */ 462 @NonNull 463 public List<Link> getLinks() { 464 if (_links == null) { 465 _links = new LinkedList<>(); 466 } 467 return ObjectUtils.notNull(_links); 468 } 469 470 /** 471 * Set the "{@literal Link}". 472 * 473 * <p> 474 * A reference to a local or remote resource, that has a specific relation to the containing object. 475 * 476 * @param value 477 * the link value to set 478 */ 479 public void setLinks(@NonNull List<Link> value) { 480 _links = value; 481 } 482 483 /** 484 * Add a new {@link Link} item to the underlying collection. 485 * @param item the item to add 486 * @return {@code true} 487 */ 488 public boolean addLink(Link item) { 489 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 490 if (_links == null) { 491 _links = new LinkedList<>(); 492 } 493 return _links.add(value); 494 } 495 496 /** 497 * Remove the first matching {@link Link} 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 removeLink(Link item) { 502 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 503 return _links != null && _links.remove(value); 504 } 505 506 @Override 507 public String toString() { 508 return ObjectUtils.notNull(new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString()); 509 } 510}