Parameter.java

package gov.nist.secauto.oscal.lib.model;

import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValue;
import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValues;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundField;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag;
import gov.nist.secauto.metaschema.binding.model.annotations.Expect;
import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs;
import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly;
import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints;
import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior;
import gov.nist.secauto.metaschema.model.common.constraint.IConstraint;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.TokenAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultiline;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter;
import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
import gov.nist.secauto.oscal.lib.model.control.AbstractParameter;
import java.lang.Override;
import java.lang.String;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;

/**
 * Parameters provide a mechanism for the dynamic assignment of value(s) in a control.
 */
@MetaschemaAssembly(
    formalName = "Parameter",
    description = "Parameters provide a mechanism for the dynamic assignment of value(s) in a control.",
    name = "parameter",
    metaschema = OscalControlCommonMetaschema.class,
    remarks = "In a catalog, a parameter is typically used as a placeholder for the future assignment of a parameter value, although the OSCAL model allows for the direct assignment of a value if desired by the control author. The `value` may be optionally used to specify one or more values. If no value is provided, then it is expected that the value will be provided at the Profile or Implementation layer.\n"
            + "\n"
            + "A parameter can include a variety of metadata options that support the future solicitation of one or more values. A `label` provides a textual placeholder that can be used in a tool to solicit parameter value input, or to display in catalog documentation. The `desc` provides a short description of what the parameter is used for, which can be used in tooling to help a user understand how to use the parameter. A `constraint` can be used to provide criteria for the allowed values. A `guideline` provides a recommendation for the use of a parameter."
)
@ValueConstraints(
    allowedValues = {
        @AllowedValues(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 = "alt-label", description = "An alternate to the value provided by the parameter's label. This will typically be qualified by a class.")}),
        @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/rmf')]/@name", values = @AllowedValue(value = "aggregates", description = "The parent parameter provides an aggregation of two or more other parameters, each described by this property."))
    },
    expect = @Expect(level = IConstraint.Level.ERROR, test = "not(exists(@depends-on))", message = "depends-on is deprecated")
)
public class Parameter extends AbstractParameter {
  @BoundFlag(
      formalName = "Parameter Identifier",
      description = "A unique identifier for the parameter.",
      useName = "id",
      required = true,
      typeAdapter = TokenAdapter.class
  )
  private String _id;

  @BoundFlag(
      formalName = "Parameter Class",
      description = "A textual label that provides a characterization of the type, purpose, use or scope of the parameter.",
      useName = "class",
      typeAdapter = TokenAdapter.class,
      remarks = "A `class` can be used in validation rules to express extra constraints over named items of a specific `class` value."
  )
  private String _clazz;

  @BoundFlag(
      formalName = "Depends on",
      description = "**(deprecated)** Another parameter invoking this one. This construct has been deprecated and should not be used.",
      useName = "depends-on",
      typeAdapter = TokenAdapter.class
  )
  private String _dependsOn;

  @BoundAssembly(
      formalName = "Property",
      description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
      useName = "prop",
      maxOccurs = -1
  )
  @GroupAs(
      name = "props",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Property> _props;

  @BoundAssembly(
      formalName = "Link",
      description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
      useName = "link",
      maxOccurs = -1
  )
  @GroupAs(
      name = "links",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Link> _links;

  /**
   * "A short, placeholder name for the parameter, which can be used as a substitute for a <code>value</code> if no value is assigned."
   */
  @BoundField(
      formalName = "Parameter Label",
      description = "A short, placeholder name for the parameter, which can be used as a substitute for a `value` if no value is assigned.",
      useName = "label",
      remarks = "The label value is intended use when rendering a parameter in generated documentation or a user interface when a parameter is referenced. Note that labels are not required to be distinctive, which means that parameters within the same control may have the same label."
  )
  @BoundFieldValue(
      typeAdapter = MarkupLineAdapter.class
  )
  private MarkupLine _label;

  /**
   * "Describes the purpose and use of a parameter."
   */
  @BoundField(
      formalName = "Parameter Usage Description",
      description = "Describes the purpose and use of a parameter.",
      useName = "usage"
  )
  @BoundFieldValue(
      typeAdapter = MarkupMultilineAdapter.class
  )
  private MarkupMultiline _usage;

  @BoundAssembly(
      formalName = "Constraint",
      description = "A formal or informal expression of a constraint or test.",
      useName = "constraint",
      maxOccurs = -1
  )
  @GroupAs(
      name = "constraints",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<ParameterConstraint> _constraints;

  @BoundAssembly(
      formalName = "Guideline",
      description = "A prose statement that provides a recommendation for the use of a parameter.",
      useName = "guideline",
      maxOccurs = -1
  )
  @GroupAs(
      name = "guidelines",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<ParameterGuideline> _guidelines;

  @BoundField(
      formalName = "Parameter Value",
      description = "A parameter value or set of values.",
      useName = "value",
      maxOccurs = -1,
      remarks = "A set of values provided in a catalog can be redefined in OSCAL's `profile` or `system-security-plan` models."
  )
  @GroupAs(
      name = "values",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<String> _values;

  @BoundAssembly(
      formalName = "Selection",
      description = "Presenting a choice among alternatives.",
      useName = "select",
      remarks = "The OSCAL parameter `value` construct can be used to prescribe a specific parameter value in a catalog or profile. In cases where a prescriptive value is not possible in a catalog or profile, it may be possible to constrain the set of possible values to a few options. Use of `select` in a parameter instead of `value` is a way of defining value options that **may** be set.\n"
              + "\n"
              + "A set of allowed parameter values expressed as a set of options which may be selected. These options constrain the permissible values that may be selected for the containing parameter. When the value assignment is made, such as in an OSCAL profile or system security plan, the actual selected value can be examined to determine if it matches one of the permissible choices for the parameter value.\n"
              + "\n"
              + "When the value of `how-many` is set to \"one-or-more\", multiple values may be assigned reflecting more than one choice."
  )
  private ParameterSelection _select;

  @BoundField(
      formalName = "Remarks",
      description = "Additional commentary about the containing object.",
      useName = "remarks"
  )
  @BoundFieldValue(
      typeAdapter = MarkupMultilineAdapter.class
  )
  private MarkupMultiline _remarks;

  public Parameter() {
  }

  public String getId() {
    return _id;
  }

  public void setId(String value) {
    _id = value;
  }

  public String getClazz() {
    return _clazz;
  }

  public void setClazz(String value) {
    _clazz = value;
  }

  public String getDependsOn() {
    return _dependsOn;
  }

  public void setDependsOn(String value) {
    _dependsOn = value;
  }

  public List<Property> getProps() {
    return _props;
  }

  public void setProps(List<Property> value) {
    _props = value;
  }

  /**
   * Add a new {@link Property} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addProp(Property item) {
    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_props == null) {
      _props = new LinkedList<>();
    }
    return _props.add(value);
  }

  /**
   * Remove the first matching {@link Property} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeProp(Property item) {
    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _props == null ? false : _props.remove(value);
  }

  public List<Link> getLinks() {
    return _links;
  }

  public void setLinks(List<Link> value) {
    _links = value;
  }

  /**
   * Add a new {@link Link} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addLink(Link item) {
    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_links == null) {
      _links = new LinkedList<>();
    }
    return _links.add(value);
  }

  /**
   * Remove the first matching {@link Link} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeLink(Link item) {
    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _links == null ? false : _links.remove(value);
  }

  public MarkupLine getLabel() {
    return _label;
  }

  public void setLabel(MarkupLine value) {
    _label = value;
  }

  public MarkupMultiline getUsage() {
    return _usage;
  }

  public void setUsage(MarkupMultiline value) {
    _usage = value;
  }

  public List<ParameterConstraint> getConstraints() {
    return _constraints;
  }

  public void setConstraints(List<ParameterConstraint> value) {
    _constraints = value;
  }

  /**
   * Add a new {@link ParameterConstraint} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addConstraint(ParameterConstraint item) {
    ParameterConstraint value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_constraints == null) {
      _constraints = new LinkedList<>();
    }
    return _constraints.add(value);
  }

  /**
   * Remove the first matching {@link ParameterConstraint} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeConstraint(ParameterConstraint item) {
    ParameterConstraint value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _constraints == null ? false : _constraints.remove(value);
  }

  public List<ParameterGuideline> getGuidelines() {
    return _guidelines;
  }

  public void setGuidelines(List<ParameterGuideline> value) {
    _guidelines = value;
  }

  /**
   * Add a new {@link ParameterGuideline} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addGuideline(ParameterGuideline item) {
    ParameterGuideline value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_guidelines == null) {
      _guidelines = new LinkedList<>();
    }
    return _guidelines.add(value);
  }

  /**
   * Remove the first matching {@link ParameterGuideline} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeGuideline(ParameterGuideline item) {
    ParameterGuideline value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _guidelines == null ? false : _guidelines.remove(value);
  }

  public List<String> getValues() {
    return _values;
  }

  public void setValues(List<String> value) {
    _values = value;
  }

  /**
   * Add a new {@link String} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addValue(String item) {
    String value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_values == null) {
      _values = new LinkedList<>();
    }
    return _values.add(value);
  }

  /**
   * Remove the first matching {@link String} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeValue(String item) {
    String value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _values == null ? false : _values.remove(value);
  }

  public ParameterSelection getSelect() {
    return _select;
  }

  public void setSelect(ParameterSelection value) {
    _select = value;
  }

  public MarkupMultiline getRemarks() {
    return _remarks;
  }

  public void setRemarks(MarkupMultiline value) {
    _remarks = value;
  }

  @Override
  public String toString() {
    return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
  }
}