1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.model.constraint.impl;
7   
8   import java.util.Map;
9   import java.util.Set;
10  
11  import dev.metaschema.core.datatype.markup.MarkupLine;
12  import dev.metaschema.core.datatype.markup.MarkupMultiline;
13  import dev.metaschema.core.metapath.IMetapathExpression;
14  import dev.metaschema.core.model.IAttributable;
15  import dev.metaschema.core.model.ISource;
16  import dev.metaschema.core.model.constraint.ConstraintInitializationException;
17  import dev.metaschema.core.model.constraint.ICardinalityConstraint;
18  import dev.metaschema.core.model.constraint.IConstraint;
19  import edu.umd.cs.findbugs.annotations.NonNull;
20  import edu.umd.cs.findbugs.annotations.Nullable;
21  
22  /**
23   * Represents a cardinality constraint.
24   * <p>
25   * Enforces that the number of items matching the target fall within the
26   * inclusive range described by the {@code minOccurs} or {@code maxOccurs}
27   * values.
28   */
29  public final class DefaultCardinalityConstraint
30      extends AbstractConfigurableMessageConstraint
31      implements ICardinalityConstraint {
32    @Nullable
33    private final Integer minOccurs;
34    @Nullable
35    private final Integer maxOccurs;
36  
37    /**
38     * Construct a new cardinality constraint.
39     *
40     * @param id
41     *          the optional identifier for the constraint
42     * @param formalName
43     *          the constraint's formal name or {@code null} if not provided
44     * @param description
45     *          the constraint's semantic description or {@code null} if not
46     *          provided
47     * @param source
48     *          information about the constraint source
49     * @param level
50     *          the significance of a violation of this constraint
51     * @param target
52     *          the Metapath expression identifying the nodes the constraint targets
53     * @param properties
54     *          a collection of associated properties
55     * @param minOccurs
56     *          if provided, the constraint ensures that the count of targets is at
57     *          least this value
58     * @param maxOccurs
59     *          if provided, the constraint ensures that the count of targets is at
60     *          most this value
61     * @param message
62     *          an optional message to emit when the constraint is violated
63     * @param remarks
64     *          optional remarks describing the intent of the constraint
65     */
66    @SuppressWarnings("PMD.ExcessiveParameterList")
67    public DefaultCardinalityConstraint(
68        @Nullable String id,
69        @Nullable String formalName,
70        @Nullable MarkupLine description,
71        @NonNull ISource source,
72        @NonNull Level level,
73        @NonNull IMetapathExpression target,
74        @NonNull Map<IAttributable.Key, Set<String>> properties,
75        @Nullable Integer minOccurs,
76        @Nullable Integer maxOccurs,
77        @Nullable String message,
78        @Nullable MarkupMultiline remarks) {
79      super(id, formalName, description, source, level, target, properties, message, remarks);
80      if (minOccurs == null && maxOccurs == null) {
81        throw new ConstraintInitializationException(
82            String.format("The constraint %s must provide at least one of minOccurs or maxOccurs in '%s'",
83                IConstraint.getConstraintIdentity(this),
84                source.getLocationHint()));
85      }
86      this.minOccurs = minOccurs;
87      this.maxOccurs = maxOccurs;
88    }
89  
90    @Override
91    public Integer getMinOccurs() {
92      return minOccurs;
93    }
94  
95    @Override
96    public Integer getMaxOccurs() {
97      return maxOccurs;
98    }
99  
100 }