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.datatype.markup.MarkupMultiline;
9   import gov.nist.secauto.metaschema.core.metapath.MetapathException;
10  import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
11  import gov.nist.secauto.metaschema.core.model.ISource;
12  import gov.nist.secauto.metaschema.core.model.constraint.impl.DefaultLet;
13  
14  import javax.xml.namespace.QName;
15  
16  import edu.umd.cs.findbugs.annotations.NonNull;
17  import edu.umd.cs.findbugs.annotations.Nullable;
18  
19  /**
20   * Represents a variable assignment for use in Metaschema module constraints.
21   */
22  @SuppressWarnings("PMD.ShortClassName")
23  public interface ILet {
24    /**
25     * Create a new Let expression by compiling the provided Metapath expression
26     * string.
27     *
28     * @param name
29     *          the let expression variable name
30     * @param valueExpression
31     *          a Metapath expression string representing the variable value
32     * @param source
33     *          the source descriptor for the resource containing the constraint
34     * @param remarks
35     *          remarks about the let statement
36     * @return the original let statement with the same name or {@code null}
37     */
38    @SuppressWarnings("PMD.ShortMethodName")
39    @NonNull
40    static ILet of(
41        @NonNull QName name,
42        @NonNull String valueExpression,
43        @NonNull ISource source,
44        @Nullable MarkupMultiline remarks) {
45      try {
46        return of(
47            name,
48            MetapathExpression.compile(valueExpression, source.getStaticContext()),
49            source,
50            remarks);
51      } catch (MetapathException ex) {
52        throw new MetapathException(
53            String.format("Unable to compile the let expression '%s=%s'%s. %s",
54                name,
55                valueExpression,
56                source.getSource() == null ? "" : " in " + source.getSource(),
57                ex.getMessage()),
58            ex);
59      }
60    }
61  
62    /**
63     * Create a new Let expression.
64     *
65     * @param name
66     *          the let expression variable name
67     * @param valueExpression
68     *          a Metapath expression representing the variable value
69     * @param source
70     *          the source descriptor for the resource containing the constraint
71     * @param remarks
72     *          remarks about the let statement
73     * @return the original let statement with the same name or {@code null}
74     */
75    @SuppressWarnings("PMD.ShortMethodName")
76    @NonNull
77    static ILet of(
78        @NonNull QName name,
79        @NonNull MetapathExpression valueExpression,
80        @NonNull ISource source,
81        @Nullable MarkupMultiline remarks) {
82      return new DefaultLet(name, valueExpression, source, remarks);
83    }
84  
85    /**
86     * Get the name of the let variable.
87     *
88     * @return the name
89     */
90    @NonNull
91    QName getName();
92  
93    /**
94     * Get the Metapath expression to use to query the value.
95     *
96     * @return the Metapath expression to use to query the value
97     */
98    @NonNull
99    MetapathExpression getValueExpression();
100 
101   /**
102    * Information about the source resource containing the let statement.
103    *
104    * @return the source information
105    */
106   @NonNull
107   ISource getSource();
108 
109   /**
110    * Get the remarks associated with the let statement.
111    *
112    * @return the remark or {@code null} if no remarks are defined
113    */
114   @Nullable
115   MarkupMultiline getRemarks();
116 }