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