1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.core.model.constraint;
7   
8   import gov.nist.secauto.metaschema.core.metapath.IMetapathExpression;
9   import gov.nist.secauto.metaschema.core.model.constraint.impl.DefaultExpectConstraint;
10  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
11  
12  import edu.umd.cs.findbugs.annotations.NonNull;
13  
14  /**
15   * Represents a rule requiring a Metaschema assembly, field, or flag data
16   * instance to pass a Metapath-based test.
17   * <p>
18   * A custom message can be used to indicate what a test failure signifies.
19   */
20  public interface IExpectConstraint extends IConfigurableMessageConstraint {
21    @Override
22    default Type getType() {
23      return Type.EXPECT;
24    }
25  
26    /**
27     * Get the test to use to validate selected nodes.
28     *
29     * @return the test metapath expression to use
30     */
31    @NonNull
32    IMetapathExpression getTest();
33  
34    @Override
35    default <T, R> R accept(IConstraintVisitor<T, R> visitor, T state) {
36      return visitor.visitExpectConstraint(this, state);
37    }
38  
39    /**
40     * Create a new constraint builder.
41     *
42     * @return the builder
43     */
44    @NonNull
45    static Builder builder() {
46      return new Builder();
47    }
48  
49    /**
50     * Provides a builder pattern for constructing a new {@link IExpectConstraint}.
51     */
52    final class Builder
53        extends AbstractConfigurableMessageConstraintBuilder<Builder, IExpectConstraint> {
54      private IMetapathExpression test;
55  
56      private Builder() {
57        // disable construction
58      }
59  
60      /**
61       * Use the provided test to validate selected nodes.
62       *
63       * @param test
64       *          the test metapath expression to use
65       * @return this builder
66       */
67      @NonNull
68      public Builder test(@NonNull IMetapathExpression test) {
69        this.test = test;
70        return this;
71      }
72  
73      @Override
74      protected Builder getThis() {
75        return this;
76      }
77  
78      @Override
79      protected void validate() {
80        super.validate();
81  
82        ObjectUtils.requireNonNull(getTest());
83      }
84  
85      private IMetapathExpression getTest() {
86        return test;
87      }
88  
89      @Override
90      protected IExpectConstraint newInstance() {
91        return new DefaultExpectConstraint(
92            getId(),
93            getFormalName(),
94            getDescription(),
95            ObjectUtils.notNull(getSource()),
96            getLevel(),
97            getTarget(),
98            getProperties(),
99            ObjectUtils.requireNonNull(getTest()),
100           getMessage(),
101           getRemarks());
102     }
103   }
104 }