001package gov.nist.secauto.oscal.lib.model; 002 003import gov.nist.secauto.metaschema.core.datatype.adapter.TokenAdapter; 004import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter; 005import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; 006import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultilineAdapter; 007import gov.nist.secauto.metaschema.core.model.IBoundObject; 008import gov.nist.secauto.metaschema.core.model.IMetaschemaData; 009import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior; 010import gov.nist.secauto.metaschema.core.model.constraint.IConstraint; 011import gov.nist.secauto.metaschema.core.util.ObjectUtils; 012import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValue; 013import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValues; 014import gov.nist.secauto.metaschema.databind.model.annotations.AssemblyConstraints; 015import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly; 016import gov.nist.secauto.metaschema.databind.model.annotations.BoundField; 017import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag; 018import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; 019import gov.nist.secauto.metaschema.databind.model.annotations.IsUnique; 020import gov.nist.secauto.metaschema.databind.model.annotations.KeyField; 021import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly; 022import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints; 023import java.lang.Override; 024import java.lang.String; 025import java.util.LinkedList; 026import java.util.List; 027import java.util.UUID; 028import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 029import org.apache.commons.lang3.builder.ToStringStyle; 030 031/** 032 * Identifies which statements within a control are addressed. 033 */ 034@MetaschemaAssembly( 035 formalName = "Specific Control Statement", 036 description = "Identifies which statements within a control are addressed.", 037 name = "statement", 038 moduleClass = OscalSspModule.class, 039 valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, target = "responsible-role/@role-id", allowOthers = true, values = {@AllowedValue(value = "asset-owner", description = "Accountable for ensuring the asset is managed in accordance with organizational policies and procedures."), @AllowedValue(value = "asset-administrator", description = "Responsible for administering a set of assets."), @AllowedValue(value = "security-operations", description = "Members of the security operations center (SOC)."), @AllowedValue(value = "network-operations", description = "Members of the network operations center (NOC)."), @AllowedValue(value = "incident-response", description = "Responsible for responding to an event that could lead to loss of, or disruption to, an organization's operations, services or functions."), @AllowedValue(value = "help-desk", description = "Responsible for providing information and support to users."), @AllowedValue(value = "configuration-management", description = "Responsible for the configuration management processes governing changes to the asset.")})), 040 modelConstraints = @AssemblyConstraints(unique = {@IsUnique(id = "unique-ssp-statement-responsible-role", level = IConstraint.Level.ERROR, target = "responsible-role", keyFields = @KeyField(target = "@role-id"), remarks = "Since `responsible-role` associates multiple `party-uuid` entries with a single `role-id`, each role-id must be referenced only once."), @IsUnique(id = "unique-ssp-implemented-requirement-statement-by-component", level = IConstraint.Level.ERROR, target = "by-component", keyFields = @KeyField(target = "@component-uuid"), remarks = "Since `by-component` can reference `component` entries using the component's uuid, each component must be referenced only once. This ensures that all implementation statements are contained in the same `by-component` entry.")}) 041) 042public class Statement implements IBoundObject { 043 private final IMetaschemaData __metaschemaData; 044 045 /** 046 * "A <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#human-oriented\">human-oriented</a> identifier reference to a <code>control statement</code>." 047 */ 048 @BoundFlag( 049 formalName = "Control Statement Reference", 050 description = "A [human-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#human-oriented) identifier reference to a `control statement`.", 051 name = "statement-id", 052 required = true, 053 typeAdapter = TokenAdapter.class, 054 remarks = "A reference to the specific implemented statement associated with a control." 055 ) 056 private String _statementId; 057 058 /** 059 * "A <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented\">machine-oriented</a>, <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique\">globally unique</a> identifier with <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance\">cross-instance</a> scope that can be used to reference this control statement elsewhere in <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#ssp-identifiers\">this or other OSCAL instances</a>. The <em>UUID</em> of the <code>control statement</code> in the source OSCAL instance is sufficient to reference the data item locally or globally (e.g., in an imported OSCAL instance)." 060 */ 061 @BoundFlag( 062 formalName = "Control Statement Reference Universally Unique Identifier", 063 description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented), [globally unique](https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique) identifier with [cross-instance](https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance) scope that can be used to reference this control statement elsewhere in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#ssp-identifiers). The *UUID* of the `control statement` in the source OSCAL instance is sufficient to reference the data item locally or globally (e.g., in an imported OSCAL instance).", 064 name = "uuid", 065 required = true, 066 typeAdapter = UuidAdapter.class 067 ) 068 private UUID _uuid; 069 070 @BoundAssembly( 071 formalName = "Property", 072 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.", 073 useName = "prop", 074 maxOccurs = -1, 075 groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST) 076 ) 077 private List<Property> _props; 078 079 @BoundAssembly( 080 formalName = "Link", 081 description = "A reference to a local or remote resource, that has a specific relation to the containing object.", 082 useName = "link", 083 maxOccurs = -1, 084 groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST) 085 ) 086 private List<Link> _links; 087 088 @BoundAssembly( 089 formalName = "Responsible Role", 090 description = "A reference to a role with responsibility for performing a function relative to the containing object, optionally associated with a set of persons and/or organizations that perform that role.", 091 useName = "responsible-role", 092 maxOccurs = -1, 093 groupAs = @GroupAs(name = "responsible-roles", inJson = JsonGroupAsBehavior.LIST) 094 ) 095 private List<ResponsibleRole> _responsibleRoles; 096 097 @BoundAssembly( 098 formalName = "Component Control Implementation", 099 description = "Defines how the referenced component implements a set of controls.", 100 useName = "by-component", 101 maxOccurs = -1, 102 groupAs = @GroupAs(name = "by-components", inJson = JsonGroupAsBehavior.LIST) 103 ) 104 private List<ByComponent> _byComponents; 105 106 @BoundField( 107 formalName = "Remarks", 108 description = "Additional commentary about the containing object.", 109 useName = "remarks", 110 typeAdapter = MarkupMultilineAdapter.class 111 ) 112 private MarkupMultiline _remarks; 113 114 public Statement() { 115 this(null); 116 } 117 118 public Statement(IMetaschemaData data) { 119 this.__metaschemaData = data; 120 } 121 122 @Override 123 public IMetaschemaData getMetaschemaData() { 124 return __metaschemaData; 125 } 126 127 public String getStatementId() { 128 return _statementId; 129 } 130 131 public void setStatementId(String value) { 132 _statementId = value; 133 } 134 135 public UUID getUuid() { 136 return _uuid; 137 } 138 139 public void setUuid(UUID value) { 140 _uuid = value; 141 } 142 143 public List<Property> getProps() { 144 return _props; 145 } 146 147 public void setProps(List<Property> value) { 148 _props = value; 149 } 150 151 /** 152 * Add a new {@link Property} item to the underlying collection. 153 * @param item the item to add 154 * @return {@code true} 155 */ 156 public boolean addProp(Property item) { 157 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 158 if (_props == null) { 159 _props = new LinkedList<>(); 160 } 161 return _props.add(value); 162 } 163 164 /** 165 * Remove the first matching {@link Property} item from the underlying collection. 166 * @param item the item to remove 167 * @return {@code true} if the item was removed or {@code false} otherwise 168 */ 169 public boolean removeProp(Property item) { 170 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 171 return _props != null && _props.remove(value); 172 } 173 174 public List<Link> getLinks() { 175 return _links; 176 } 177 178 public void setLinks(List<Link> value) { 179 _links = value; 180 } 181 182 /** 183 * Add a new {@link Link} item to the underlying collection. 184 * @param item the item to add 185 * @return {@code true} 186 */ 187 public boolean addLink(Link item) { 188 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 189 if (_links == null) { 190 _links = new LinkedList<>(); 191 } 192 return _links.add(value); 193 } 194 195 /** 196 * Remove the first matching {@link Link} item from the underlying collection. 197 * @param item the item to remove 198 * @return {@code true} if the item was removed or {@code false} otherwise 199 */ 200 public boolean removeLink(Link item) { 201 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 202 return _links != null && _links.remove(value); 203 } 204 205 public List<ResponsibleRole> getResponsibleRoles() { 206 return _responsibleRoles; 207 } 208 209 public void setResponsibleRoles(List<ResponsibleRole> value) { 210 _responsibleRoles = value; 211 } 212 213 /** 214 * Add a new {@link ResponsibleRole} item to the underlying collection. 215 * @param item the item to add 216 * @return {@code true} 217 */ 218 public boolean addResponsibleRole(ResponsibleRole item) { 219 ResponsibleRole value = ObjectUtils.requireNonNull(item,"item cannot be null"); 220 if (_responsibleRoles == null) { 221 _responsibleRoles = new LinkedList<>(); 222 } 223 return _responsibleRoles.add(value); 224 } 225 226 /** 227 * Remove the first matching {@link ResponsibleRole} item from the underlying collection. 228 * @param item the item to remove 229 * @return {@code true} if the item was removed or {@code false} otherwise 230 */ 231 public boolean removeResponsibleRole(ResponsibleRole item) { 232 ResponsibleRole value = ObjectUtils.requireNonNull(item,"item cannot be null"); 233 return _responsibleRoles != null && _responsibleRoles.remove(value); 234 } 235 236 public List<ByComponent> getByComponents() { 237 return _byComponents; 238 } 239 240 public void setByComponents(List<ByComponent> value) { 241 _byComponents = value; 242 } 243 244 /** 245 * Add a new {@link ByComponent} item to the underlying collection. 246 * @param item the item to add 247 * @return {@code true} 248 */ 249 public boolean addByComponent(ByComponent item) { 250 ByComponent value = ObjectUtils.requireNonNull(item,"item cannot be null"); 251 if (_byComponents == null) { 252 _byComponents = new LinkedList<>(); 253 } 254 return _byComponents.add(value); 255 } 256 257 /** 258 * Remove the first matching {@link ByComponent} item from the underlying collection. 259 * @param item the item to remove 260 * @return {@code true} if the item was removed or {@code false} otherwise 261 */ 262 public boolean removeByComponent(ByComponent item) { 263 ByComponent value = ObjectUtils.requireNonNull(item,"item cannot be null"); 264 return _byComponents != null && _byComponents.remove(value); 265 } 266 267 public MarkupMultiline getRemarks() { 268 return _remarks; 269 } 270 271 public void setRemarks(MarkupMultiline value) { 272 _remarks = value; 273 } 274 275 @Override 276 public String toString() { 277 return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString(); 278 } 279}