Merge.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.BooleanAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.StringAdapter;
import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
import java.lang.Boolean;
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;

/**
 * Provides structuring directives that instruct how controls are organized after profile resolution.
 */
@MetaschemaAssembly(
    formalName = "Merge Controls",
    description = "Provides structuring directives that instruct how controls are organized after profile resolution.",
    name = "merge",
    metaschema = OscalProfileMetaschema.class
)
public class Merge {
  /**
   * "A Combine element defines how to resolve duplicate instances of the same control (e.g., controls with the same ID)."
   */
  @BoundAssembly(
      formalName = "Combination Rule",
      description = "A Combine element defines how to resolve duplicate instances of the same control (e.g., controls with the same ID).",
      useName = "combine"
  )
  private Combine _combine;

  /**
   * "Directs that controls appear without any grouping structure."
   */
  @BoundAssembly(
      formalName = "Flat Without Grouping",
      description = "Directs that controls appear without any grouping structure.",
      useName = "flat",
      minOccurs = 1
  )
  private Flat _flat;

  /**
   * "Indicates that the controls selected should retain their original grouping as defined in the import source."
   */
  @BoundField(
      formalName = "Group As-Is",
      description = "Indicates that the controls selected should retain their original grouping as defined in the import source.",
      useName = "as-is",
      minOccurs = 1
  )
  @BoundFieldValue(
      typeAdapter = BooleanAdapter.class
  )
  private Boolean _asIs;

  /**
   * "Provides an alternate grouping structure that selected controls will be placed in."
   */
  @BoundAssembly(
      formalName = "Custom Grouping",
      description = "Provides an alternate grouping structure that selected controls will be placed in.",
      useName = "custom",
      minOccurs = 1,
      remarks = "The `custom` element represents a custom arrangement or organization of controls in the resolution of a catalog. This structuring directive gives the profile author the ability to define an entirely different organization of controls as compared to their source catalog(s)."
  )
  private Custom _custom;

  public Merge() {
  }

  public Combine getCombine() {
    return _combine;
  }

  public void setCombine(Combine value) {
    _combine = value;
  }

  public Flat getFlat() {
    return _flat;
  }

  public void setFlat(Flat value) {
    _flat = value;
  }

  public Boolean getAsIs() {
    return _asIs;
  }

  public void setAsIs(Boolean value) {
    _asIs = value;
  }

  public Custom getCustom() {
    return _custom;
  }

  public void setCustom(Custom value) {
    _custom = value;
  }

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

  /**
   * A Combine element defines how to resolve duplicate instances of the same control (e.g., controls with the same ID).
   */
  @MetaschemaAssembly(
      formalName = "Combination Rule",
      description = "A Combine element defines how to resolve duplicate instances of the same control (e.g., controls with the same ID).",
      name = "combine",
      metaschema = OscalProfileMetaschema.class
  )
  @ValueConstraints(
      expect = @Expect(id = "req-merge-combine", level = IConstraint.Level.ERROR, test = "not(@method='merge')")
  )
  public static class Combine {
    @BoundFlag(
        formalName = "Combination Method",
        description = "Declare how clashing controls should be handled.",
        useName = "method",
        typeAdapter = StringAdapter.class
    )
    @ValueConstraints(
        allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, values = {@AllowedValue(value = "use-first", description = "Use the first definition - the first control with a given ID is used; subsequent ones are discarded"), @AllowedValue(value = "merge", description = "\\*\\*(*deprecated* )\\*\\* \\*\\*(*unspecified*)\\*\\* Merge - controls with the same ID are combined"), @AllowedValue(value = "keep", description = "Keep - controls with the same ID are kept, retaining the clash")})
    )
    private String _method;

    public Combine() {
    }

    public String getMethod() {
      return _method;
    }

    public void setMethod(String value) {
      _method = value;
    }

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

  /**
   * Directs that controls appear without any grouping structure.
   */
  @MetaschemaAssembly(
      formalName = "Flat Without Grouping",
      description = "Directs that controls appear without any grouping structure.",
      name = "flat",
      metaschema = OscalProfileMetaschema.class
  )
  public static class Flat {
    public Flat() {
    }

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

  /**
   * Provides an alternate grouping structure that selected controls will be placed in.
   */
  @MetaschemaAssembly(
      formalName = "Custom Grouping",
      description = "Provides an alternate grouping structure that selected controls will be placed in.",
      name = "custom",
      metaschema = OscalProfileMetaschema.class,
      remarks = "The `custom` element represents a custom arrangement or organization of controls in the resolution of a catalog. This structuring directive gives the profile author the ability to define an entirely different organization of controls as compared to their source catalog(s)."
  )
  public static class Custom {
    @BoundAssembly(
        formalName = "Control Group",
        description = "A group of (selected) controls or of groups of controls.",
        useName = "group",
        maxOccurs = -1
    )
    @GroupAs(
        name = "groups",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<ProfileGroup> _groups;

    @BoundAssembly(
        formalName = "Insert Controls",
        description = "Specifies which controls to use in the containing context.",
        useName = "insert-controls",
        maxOccurs = -1
    )
    @GroupAs(
        name = "insert-controls",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<InsertControls> _insertControls;

    public Custom() {
    }

    public List<ProfileGroup> getGroups() {
      return _groups;
    }

    public void setGroups(List<ProfileGroup> value) {
      _groups = value;
    }

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

    /**
     * Remove the first matching {@link ProfileGroup} 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 removeGroup(ProfileGroup item) {
      ProfileGroup value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _groups == null ? false : _groups.remove(value);
    }

    public List<InsertControls> getInsertControls() {
      return _insertControls;
    }

    public void setInsertControls(List<InsertControls> value) {
      _insertControls = value;
    }

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

    /**
     * Remove the first matching {@link InsertControls} 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 removeInsertControls(InsertControls item) {
      InsertControls value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _insertControls == null ? false : _insertControls.remove(value);
    }

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