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