AbstractConstraint.java

  1. /*
  2.  * Portions of this software was developed by employees of the National Institute
  3.  * of Standards and Technology (NIST), an agency of the Federal Government and is
  4.  * being made available as a public service. Pursuant to title 17 United States
  5.  * Code Section 105, works of NIST employees are not subject to copyright
  6.  * protection in the United States. This software may be subject to foreign
  7.  * copyright. Permission in the United States and in foreign countries, to the
  8.  * extent that NIST may hold copyright, to use, copy, modify, create derivative
  9.  * works, and distribute this software and its documentation without fee is hereby
  10.  * granted on a non-exclusive basis, provided that this notice and disclaimer
  11.  * of warranty appears in all copies.
  12.  *
  13.  * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
  14.  * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
  15.  * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
  16.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
  17.  * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
  18.  * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
  19.  * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
  20.  * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
  21.  * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
  22.  * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
  23.  * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
  24.  * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
  25.  */

  26. package gov.nist.secauto.metaschema.core.model.constraint;

  27. import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
  28. import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
  29. import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
  30. import gov.nist.secauto.metaschema.core.util.CollectionUtil;
  31. import gov.nist.secauto.metaschema.core.util.ObjectUtils;

  32. import java.util.LinkedHashMap;
  33. import java.util.LinkedHashSet;
  34. import java.util.Map;
  35. import java.util.Objects;
  36. import java.util.Set;

  37. import javax.xml.namespace.QName;

  38. import edu.umd.cs.findbugs.annotations.NonNull;
  39. import edu.umd.cs.findbugs.annotations.Nullable;

  40. public abstract class AbstractConstraint implements IConstraint { // NOPMD - intentional data class
  41.   @Nullable
  42.   private final String id;
  43.   @Nullable
  44.   private final String formalName;
  45.   @Nullable
  46.   private final MarkupLine description;
  47.   @NonNull
  48.   private final ISource source;
  49.   @NonNull
  50.   private final Level level;
  51.   @NonNull
  52.   private final MetapathExpression target;
  53.   @Nullable
  54.   private final MarkupMultiline remarks;
  55.   @NonNull
  56.   private final Map<QName, Set<String>> properties;

  57.   /**
  58.    * Construct a new Metaschema constraint.
  59.    *
  60.    * @param id
  61.    *          the optional identifier for the constraint
  62.    * @param formalName
  63.    *          the constraint's formal name or {@code null} if not provided
  64.    * @param description
  65.    *          the constraint's semantic description or {@code null} if not
  66.    *          provided
  67.    * @param source
  68.    *          information about the constraint source
  69.    * @param level
  70.    *          the significance of a violation of this constraint
  71.    * @param target
  72.    *          the Metapath expression identifying the nodes the constraint targets
  73.    * @param properties
  74.    *          a collection of associated properties
  75.    * @param remarks
  76.    *          optional remarks describing the intent of the constraint
  77.    */
  78.   protected AbstractConstraint(
  79.       @Nullable String id,
  80.       @Nullable String formalName,
  81.       @Nullable MarkupLine description,
  82.       @NonNull ISource source,
  83.       @NonNull Level level,
  84.       @NonNull MetapathExpression target,
  85.       @NonNull Map<QName, Set<String>> properties,
  86.       @Nullable MarkupMultiline remarks) {
  87.     Objects.requireNonNull(target);
  88.     this.id = id;
  89.     this.formalName = formalName;
  90.     this.description = description;
  91.     this.source = source;
  92.     this.level = ObjectUtils.requireNonNull(level, "level");
  93.     this.target = ObjectUtils.requireNonNull(target, "target");
  94.     this.properties = properties;
  95.     this.remarks = remarks;
  96.   }

  97.   @Override
  98.   public String getId() {
  99.     return id;
  100.   }

  101.   @Override
  102.   public MarkupLine getDescription() {
  103.     return description;
  104.   }

  105.   @Override
  106.   public String getFormalName() {
  107.     return formalName;
  108.   }

  109.   @Override
  110.   public ISource getSource() {
  111.     return source;
  112.   }

  113.   @Override
  114.   @NonNull
  115.   public Level getLevel() {
  116.     return level;
  117.   }

  118.   @Override
  119.   public MetapathExpression getTarget() {
  120.     return target;
  121.   }

  122.   @Override
  123.   public Map<QName, Set<String>> getProperties() {
  124.     return CollectionUtil.unmodifiableMap(properties);
  125.   }

  126.   @Override
  127.   public MarkupMultiline getRemarks() {
  128.     return remarks;
  129.   }

  130.   public abstract static class AbstractConstraintBuilder<
  131.       T extends AbstractConstraintBuilder<T,
  132.           R>,
  133.       R extends AbstractConstraint> {
  134.     private String id;
  135.     private String formalName;
  136.     private MarkupLine description;
  137.     private ISource source;
  138.     @NonNull
  139.     private Level level = IConstraint.DEFAULT_LEVEL;
  140.     @NonNull
  141.     private MetapathExpression target = IConstraint.DEFAULT_TARGET;
  142.     @NonNull
  143.     private Map<QName, Set<String>> properties = new LinkedHashMap<>(); // NOPMD not thread safe
  144.     private MarkupMultiline remarks;

  145.     protected abstract T getThis();

  146.     public T identifier(@NonNull String id) {
  147.       this.id = id;
  148.       return getThis();
  149.     }

  150.     public T formalName(@NonNull String name) {
  151.       this.formalName = name;
  152.       return getThis();
  153.     }

  154.     public T description(@NonNull MarkupLine description) {
  155.       this.description = description;
  156.       return getThis();
  157.     }

  158.     public T source(@NonNull ISource source) {
  159.       this.source = source;
  160.       return getThis();
  161.     }

  162.     public T level(@NonNull Level level) {
  163.       this.level = level;
  164.       return getThis();
  165.     }

  166.     public T target(@NonNull MetapathExpression target) {
  167.       this.target = target;
  168.       return getThis();
  169.     }

  170.     public T properties(@NonNull Map<QName, Set<String>> properties) {
  171.       this.properties = properties;
  172.       return getThis();
  173.     }

  174.     public T property(@NonNull QName name, @NonNull String value) {
  175.       return property(name, CollectionUtil.singleton(value));
  176.     }

  177.     public T property(@NonNull QName name, @NonNull Set<String> newValues) {
  178.       Set<String> existingValues = properties.get(name);
  179.       if (existingValues == null) {
  180.         existingValues = new LinkedHashSet<>();
  181.         properties.put(name, existingValues);
  182.       }

  183.       existingValues.addAll(newValues);
  184.       return getThis();
  185.     }

  186.     public T remarks(@NonNull MarkupMultiline remarks) {
  187.       this.remarks = remarks;
  188.       return getThis();
  189.     }

  190.     protected void validate() {
  191.       ObjectUtils.requireNonNull(getSource());
  192.     }

  193.     @NonNull
  194.     protected abstract R newInstance();

  195.     @NonNull
  196.     public R build() {
  197.       validate();
  198.       return newInstance();
  199.     }

  200.     protected String getId() {
  201.       return id;
  202.     }

  203.     protected String getFormalName() {
  204.       return formalName;
  205.     }

  206.     protected MarkupLine getDescription() {
  207.       return description;
  208.     }

  209.     protected ISource getSource() {
  210.       return source;
  211.     }

  212.     @NonNull
  213.     protected Level getLevel() {
  214.       return level;
  215.     }

  216.     @NonNull
  217.     protected MetapathExpression getTarget() {
  218.       return target;
  219.     }

  220.     @NonNull
  221.     protected Map<QName, Set<String>> getProperties() {
  222.       return properties;
  223.     }

  224.     protected MarkupMultiline getRemarks() {
  225.       return remarks;
  226.     }
  227.   }
  228. }