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.IsUnique; 014import gov.nist.secauto.metaschema.databind.model.annotations.KeyField; 015import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly; 016import java.lang.Override; 017import java.lang.String; 018import java.util.LinkedList; 019import java.util.List; 020import java.util.UUID; 021import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 022import org.apache.commons.lang3.builder.ToStringStyle; 023 024/** 025 * Each OSCAL profile is defined by a <code>profile</code> element. 026 */ 027@MetaschemaAssembly( 028 formalName = "Profile", 029 description = "Each OSCAL profile is defined by a `profile` element.", 030 name = "profile", 031 moduleClass = OscalProfileModule.class, 032 rootName = "profile", 033 remarks = "An OSCAL document that describes a tailoring of controls from one or more catalogs, with possible modification of multiple controls. It provides mechanisms by which controls may be selected (`import`), merged or (re)structured (`merge`), and amended (`modify`). OSCAL profiles may select subsets of controls, set parameter values for them in application, and even adjust the representation of controls as given in and by a catalog. They may also serve as sources for further modification in and by other profiles, that import them.", 034 modelConstraints = @AssemblyConstraints(unique = {@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.")}) 035) 036public class Profile extends AbstractOscalInstance implements IBoundObject { 037 private final IMetaschemaData __metaschemaData; 038 039 /** 040 * "Provides a globally unique means to identify a given profile instance." 041 */ 042 @BoundFlag( 043 formalName = "Profile Universally Unique Identifier", 044 description = "Provides a globally unique means to identify a given profile instance.", 045 name = "uuid", 046 required = true, 047 typeAdapter = UuidAdapter.class 048 ) 049 private UUID _uuid; 050 051 @BoundAssembly( 052 formalName = "Document Metadata", 053 description = "Provides information about the containing document, and defines concepts that are shared across the document.", 054 useName = "metadata", 055 minOccurs = 1 056 ) 057 private Metadata _metadata; 058 059 @BoundAssembly( 060 formalName = "Import Resource", 061 description = "Designates a referenced source catalog or profile that provides a source of control information for use in creating a new overlay or baseline.", 062 useName = "import", 063 minOccurs = 1, 064 maxOccurs = -1, 065 groupAs = @GroupAs(name = "imports", inJson = JsonGroupAsBehavior.LIST) 066 ) 067 private List<ProfileImport> _imports; 068 069 @BoundAssembly( 070 formalName = "Merge Controls", 071 description = "Provides structuring directives that instruct how controls are organized after profile resolution.", 072 useName = "merge" 073 ) 074 private Merge _merge; 075 076 @BoundAssembly( 077 formalName = "Modify Controls", 078 description = "Set parameters or amend controls in resolution.", 079 useName = "modify" 080 ) 081 private Modify _modify; 082 083 @BoundAssembly( 084 formalName = "Back matter", 085 description = "A collection of resources that may be referenced from within the OSCAL document instance.", 086 useName = "back-matter" 087 ) 088 private BackMatter _backMatter; 089 090 public Profile() { 091 this(null); 092 } 093 094 public Profile(IMetaschemaData data) { 095 this.__metaschemaData = data; 096 } 097 098 @Override 099 public IMetaschemaData getMetaschemaData() { 100 return __metaschemaData; 101 } 102 103 public UUID getUuid() { 104 return _uuid; 105 } 106 107 public void setUuid(UUID value) { 108 _uuid = value; 109 } 110 111 public Metadata getMetadata() { 112 return _metadata; 113 } 114 115 public void setMetadata(Metadata value) { 116 _metadata = value; 117 } 118 119 public List<ProfileImport> getImports() { 120 return _imports; 121 } 122 123 public void setImports(List<ProfileImport> value) { 124 _imports = value; 125 } 126 127 /** 128 * Add a new {@link ProfileImport} item to the underlying collection. 129 * @param item the item to add 130 * @return {@code true} 131 */ 132 public boolean addImport(ProfileImport item) { 133 ProfileImport value = ObjectUtils.requireNonNull(item,"item cannot be null"); 134 if (_imports == null) { 135 _imports = new LinkedList<>(); 136 } 137 return _imports.add(value); 138 } 139 140 /** 141 * Remove the first matching {@link ProfileImport} item from the underlying collection. 142 * @param item the item to remove 143 * @return {@code true} if the item was removed or {@code false} otherwise 144 */ 145 public boolean removeImport(ProfileImport item) { 146 ProfileImport value = ObjectUtils.requireNonNull(item,"item cannot be null"); 147 return _imports != null && _imports.remove(value); 148 } 149 150 public Merge getMerge() { 151 return _merge; 152 } 153 154 public void setMerge(Merge value) { 155 _merge = value; 156 } 157 158 public Modify getModify() { 159 return _modify; 160 } 161 162 public void setModify(Modify value) { 163 _modify = value; 164 } 165 166 public BackMatter getBackMatter() { 167 return _backMatter; 168 } 169 170 public void setBackMatter(BackMatter value) { 171 _backMatter = value; 172 } 173 174 @Override 175 public String toString() { 176 return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString(); 177 } 178}