1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.core.model;
7   
8   import gov.nist.secauto.metaschema.core.metapath.StaticContext;
9   import gov.nist.secauto.metaschema.core.model.constraint.impl.InternalModelSource;
10  import gov.nist.secauto.metaschema.core.model.constraint.impl.StaticContextSource;
11  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
12  
13  import java.net.URI;
14  
15  import edu.umd.cs.findbugs.annotations.NonNull;
16  import edu.umd.cs.findbugs.annotations.Nullable;
17  
18  /**
19   * A descriptor that identifies where a given constraint was defined.
20   */
21  public interface ISource {
22    /**
23     * The relative location of the source.
24     */
25    enum SourceLocation {
26      /**
27       * A constraint embedded in a model.
28       */
29      MODEL,
30      /**
31       * A constraint defined externally from a model.
32       */
33      EXTERNAL;
34    }
35  
36    /**
37     * Get the descriptor for a
38     * {@link gov.nist.secauto.metaschema.core.model.ISource.SourceLocation#MODEL}
39     * source with as associated resource.
40     *
41     * @param module
42     *          the Metaschema module the constraint was defined in
43     * @return the source descriptor
44     * @since 2.0.0
45     */
46    @NonNull
47    static ISource moduleSource(@NonNull IModule module) {
48      return InternalModelSource.instance(module);
49    }
50  
51    /**
52     * Get the descriptor for a
53     * {@link gov.nist.secauto.metaschema.core.model.ISource.SourceLocation#EXTERNAL}
54     * source for the provided resource.
55     *
56     * @param location
57     *          the resource used as the source
58     *
59     * @return the source descriptor
60     */
61    @NonNull
62    static ISource externalSource(@NonNull String location) {
63      return externalSource(ObjectUtils.notNull(URI.create(location)));
64    }
65  
66    /**
67     * Get the descriptor for a
68     * {@link gov.nist.secauto.metaschema.core.model.ISource.SourceLocation#EXTERNAL}
69     * source for the provided resource.
70     *
71     * @param location
72     *          the resource used as the source
73     *
74     * @return the source descriptor
75     */
76    @NonNull
77    static ISource externalSource(@NonNull URI location) {
78      return StaticContextSource.instance(
79          StaticContext.builder()
80              .baseUri(location)
81              .build(),
82          true);
83    }
84  
85    /**
86     * Get the descriptor for a
87     * {@link gov.nist.secauto.metaschema.core.model.ISource.SourceLocation#EXTERNAL}
88     * source with as associated resource.
89     * <p>
90     * The provided static context idenfies the location of this source based on the
91     * {@link StaticContext#getBaseUri()} method.
92     *
93     * @param staticContext
94     *          the static Metapath context to use for compiling Metapath
95     *          expressions in this source
96     * @param useCached
97     *          if {@code true} use a previously cached source, otherwise create a
98     *          new one
99     *
100    * @return the source descriptor
101    */
102   @NonNull
103   static ISource externalSource(
104       @NonNull StaticContext staticContext,
105       boolean useCached) {
106     if (staticContext.getBaseUri() == null) {
107       throw new IllegalArgumentException("The static content must define a baseUri identifing the source resource.");
108     }
109     return StaticContextSource.instance(staticContext, useCached);
110   }
111 
112   /**
113    * Get the type of source.
114    *
115    * @return the type
116    */
117   @NonNull
118   ISource.SourceLocation getSourceType();
119 
120   /**
121    * Get the resource where the constraint was defined, if known.
122    *
123    * @return the resource or {@code null} if the resource is not known
124    */
125   @Nullable
126   URI getSource();
127 
128   /**
129    * Get a hint about where the source is location.
130    * <p>
131    * This value will typically be a URI or class name.
132    *
133    * @return the hint
134    */
135   @NonNull
136   String getLocationHint();
137 
138   /**
139    * Get the static Metapath context to use when compiling Metapath expressions.
140    *
141    * @return the static Metapath context
142    */
143   @NonNull
144   StaticContext getStaticContext();
145 }