001package gov.nist.secauto.oscal.lib.model; 002 003import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter; 004import gov.nist.secauto.metaschema.core.model.IBoundObject; 005import gov.nist.secauto.metaschema.core.model.IMetaschemaData; 006import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior; 007import gov.nist.secauto.metaschema.core.model.constraint.IConstraint; 008import gov.nist.secauto.metaschema.core.util.ObjectUtils; 009import gov.nist.secauto.metaschema.databind.model.annotations.AssemblyConstraints; 010import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly; 011import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag; 012import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; 013import gov.nist.secauto.metaschema.databind.model.annotations.Index; 014import gov.nist.secauto.metaschema.databind.model.annotations.IsUnique; 015import gov.nist.secauto.metaschema.databind.model.annotations.KeyField; 016import gov.nist.secauto.metaschema.databind.model.annotations.Let; 017import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly; 018import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints; 019import java.lang.Override; 020import java.lang.String; 021import java.util.LinkedList; 022import java.util.List; 023import java.util.UUID; 024import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 025import org.apache.commons.lang3.builder.ToStringStyle; 026 027/** 028 * A collection of component descriptions, which may optionally be grouped by capability. 029 */ 030@MetaschemaAssembly( 031 formalName = "Component Definition", 032 description = "A collection of component descriptions, which may optionally be grouped by capability.", 033 name = "component-definition", 034 moduleClass = OscalComponentDefinitionModule.class, 035 rootName = "component-definition", 036 valueConstraints = @ValueConstraints(lets = @Let(name = "all-imports", target = "import-component-definition ! recurse-depth('doc(resolve-uri(Q{http://csrc.nist.gov/ns/oscal/1.0}resolve-reference(@href)))/component-definition')")), 037 modelConstraints = @AssemblyConstraints(index = {@Index(level = IConstraint.Level.ERROR, target = "component", name = "index-system-component-uuid", keyFields = @KeyField(target = "@uuid"), remarks = "Since multiple `component` entries can be provided, each component must have a unique `uuid`."), @Index(id = "oscal-component-definition-index-metadata-scoped-role-id", formalName = "In-Scope Role Identifiers", description = "An index of role identifiers that are in-scope for the component-definition model. Roles are collected from imported component-definition. For a given role @id, a locally declared role takes precedence over a role that is imported, the role that was last imported.", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/role ! map:entry(@id,.))?*", name = "index-imports-metadata-role-id", keyFields = @KeyField(target = "@id")), @Index(id = "oscal-component-definition-index-metadata-scoped-location-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/location ! map:entry(@uuid,.))?*", name = "index-imports-metadata-location-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-component-definition-index-metadata-scoped-party-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/party ! map:entry(@uuid,.))?*", name = "index-imports-metadata-party-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-component-definition-index-metadata-scoped-party-organization-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/party[@type='organization'] ! map:entry(@uuid,.))?*", name = "index-imports-metadata-party-organization-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-component-definition-index-metadata-scoped-property-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports//prop[@uuid] ! map:entry(@uuid,.))?*", name = "index-imports-metadata-property-uuid", keyFields = @KeyField(target = "@uuid"))}, unique = {@IsUnique(id = "unique-component-definition-capability", level = IConstraint.Level.ERROR, target = "capability", keyFields = @KeyField(target = "@uuid"), remarks = "A given `component` must not be referenced more than once within the same `capability`."), @IsUnique(id = "oscal-unique-document-id", formalName = "Unique Document Identifier", description = "Ensure all document identifiers have a unique combination of @scheme and value.", level = IConstraint.Level.ERROR, target = "document-id", keyFields = {@KeyField(target = "@scheme"), @KeyField}), @IsUnique(id = "oscal-unique-property-in-context-location", formalName = "Unique Properties", description = "Ensure all properties are unique for a given location using a unique combination of @ns, @name, @class. @group. and @value.", level = IConstraint.Level.ERROR, target = ".//prop", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@name"), @KeyField(target = "@ns"), @KeyField(target = "@class"), @KeyField(target = "@group"), @KeyField(target = "@value")}), @IsUnique(id = "oscal-unique-link-in-context-location", formalName = "Unique Links", description = "Ensure all links are unique for a given location using a unique combination of @href, @rel, and @media-type.", level = IConstraint.Level.ERROR, target = ".//link", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@href"), @KeyField(target = "@rel"), @KeyField(target = "@media-type")}), @IsUnique(id = "oscal-unique-responsibility-in-context-location", formalName = "Unique Responsibilities", description = "Ensure all responsible-roles and responsible-parties are unique for a given location using a unique combination of @role-id and the combination of @party-uuid values.", level = IConstraint.Level.ERROR, target = ".//(responsible-party|responsible-role)", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@role-id"), @KeyField(target = "@party-uuid")}, remarks = "Since `responsible-party` and `responsible-role` associate multiple `party-uuid` entries with a single `role-id`, each role-id must be referenced only once.")}) 038) 039public class ComponentDefinition implements IBoundObject { 040 private final IMetaschemaData __metaschemaData; 041 042 /** 043 * "Provides a globally unique means to identify a given component definition instance." 044 */ 045 @BoundFlag( 046 formalName = "Component Definition Universally Unique Identifier", 047 description = "Provides a globally unique means to identify a given component definition instance.", 048 name = "uuid", 049 required = true, 050 typeAdapter = UuidAdapter.class 051 ) 052 private UUID _uuid; 053 054 @BoundAssembly( 055 formalName = "Document Metadata", 056 description = "Provides information about the containing document, and defines concepts that are shared across the document.", 057 useName = "metadata", 058 minOccurs = 1 059 ) 060 private Metadata _metadata; 061 062 @BoundAssembly( 063 formalName = "Import Component Definition", 064 description = "Loads a component definition from another resource.", 065 useName = "import-component-definition", 066 maxOccurs = -1, 067 groupAs = @GroupAs(name = "import-component-definitions", inJson = JsonGroupAsBehavior.LIST) 068 ) 069 private List<ImportComponentDefinition> _importComponentDefinitions; 070 071 @BoundAssembly( 072 formalName = "Component", 073 description = "A defined component that can be part of an implemented system.", 074 useName = "component", 075 maxOccurs = -1, 076 groupAs = @GroupAs(name = "components", inJson = JsonGroupAsBehavior.LIST) 077 ) 078 private List<DefinedComponent> _components; 079 080 @BoundAssembly( 081 formalName = "Capability", 082 description = "A grouping of other components and/or capabilities.", 083 useName = "capability", 084 maxOccurs = -1, 085 groupAs = @GroupAs(name = "capabilities", inJson = JsonGroupAsBehavior.LIST) 086 ) 087 private List<Capability> _capabilities; 088 089 @BoundAssembly( 090 formalName = "Back matter", 091 description = "A collection of resources that may be referenced from within the OSCAL document instance.", 092 useName = "back-matter" 093 ) 094 private BackMatter _backMatter; 095 096 public ComponentDefinition() { 097 this(null); 098 } 099 100 public ComponentDefinition(IMetaschemaData data) { 101 this.__metaschemaData = data; 102 } 103 104 @Override 105 public IMetaschemaData getMetaschemaData() { 106 return __metaschemaData; 107 } 108 109 public UUID getUuid() { 110 return _uuid; 111 } 112 113 public void setUuid(UUID value) { 114 _uuid = value; 115 } 116 117 public Metadata getMetadata() { 118 return _metadata; 119 } 120 121 public void setMetadata(Metadata value) { 122 _metadata = value; 123 } 124 125 public List<ImportComponentDefinition> getImportComponentDefinitions() { 126 return _importComponentDefinitions; 127 } 128 129 public void setImportComponentDefinitions(List<ImportComponentDefinition> value) { 130 _importComponentDefinitions = value; 131 } 132 133 /** 134 * Add a new {@link ImportComponentDefinition} item to the underlying collection. 135 * @param item the item to add 136 * @return {@code true} 137 */ 138 public boolean addImportComponentDefinition(ImportComponentDefinition item) { 139 ImportComponentDefinition value = ObjectUtils.requireNonNull(item,"item cannot be null"); 140 if (_importComponentDefinitions == null) { 141 _importComponentDefinitions = new LinkedList<>(); 142 } 143 return _importComponentDefinitions.add(value); 144 } 145 146 /** 147 * Remove the first matching {@link ImportComponentDefinition} item from the underlying collection. 148 * @param item the item to remove 149 * @return {@code true} if the item was removed or {@code false} otherwise 150 */ 151 public boolean removeImportComponentDefinition(ImportComponentDefinition item) { 152 ImportComponentDefinition value = ObjectUtils.requireNonNull(item,"item cannot be null"); 153 return _importComponentDefinitions != null && _importComponentDefinitions.remove(value); 154 } 155 156 public List<DefinedComponent> getComponents() { 157 return _components; 158 } 159 160 public void setComponents(List<DefinedComponent> value) { 161 _components = value; 162 } 163 164 /** 165 * Add a new {@link DefinedComponent} item to the underlying collection. 166 * @param item the item to add 167 * @return {@code true} 168 */ 169 public boolean addComponent(DefinedComponent item) { 170 DefinedComponent value = ObjectUtils.requireNonNull(item,"item cannot be null"); 171 if (_components == null) { 172 _components = new LinkedList<>(); 173 } 174 return _components.add(value); 175 } 176 177 /** 178 * Remove the first matching {@link DefinedComponent} item from the underlying collection. 179 * @param item the item to remove 180 * @return {@code true} if the item was removed or {@code false} otherwise 181 */ 182 public boolean removeComponent(DefinedComponent item) { 183 DefinedComponent value = ObjectUtils.requireNonNull(item,"item cannot be null"); 184 return _components != null && _components.remove(value); 185 } 186 187 public List<Capability> getCapabilities() { 188 return _capabilities; 189 } 190 191 public void setCapabilities(List<Capability> value) { 192 _capabilities = value; 193 } 194 195 /** 196 * Add a new {@link Capability} item to the underlying collection. 197 * @param item the item to add 198 * @return {@code true} 199 */ 200 public boolean addCapability(Capability item) { 201 Capability value = ObjectUtils.requireNonNull(item,"item cannot be null"); 202 if (_capabilities == null) { 203 _capabilities = new LinkedList<>(); 204 } 205 return _capabilities.add(value); 206 } 207 208 /** 209 * Remove the first matching {@link Capability} item from the underlying collection. 210 * @param item the item to remove 211 * @return {@code true} if the item was removed or {@code false} otherwise 212 */ 213 public boolean removeCapability(Capability item) { 214 Capability value = ObjectUtils.requireNonNull(item,"item cannot be null"); 215 return _capabilities != null && _capabilities.remove(value); 216 } 217 218 public BackMatter getBackMatter() { 219 return _backMatter; 220 } 221 222 public void setBackMatter(BackMatter value) { 223 _backMatter = value; 224 } 225 226 @Override 227 public String toString() { 228 return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString(); 229 } 230}