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.datatype.markup.MarkupLine;
9   import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
10  import gov.nist.secauto.metaschema.core.metapath.EQNameUtils;
11  import gov.nist.secauto.metaschema.core.metapath.StaticContext;
12  
13  import java.net.URI;
14  import java.util.Collection;
15  import java.util.List;
16  import java.util.Map;
17  
18  import javax.xml.namespace.QName;
19  
20  import edu.umd.cs.findbugs.annotations.NonNull;
21  import edu.umd.cs.findbugs.annotations.Nullable;
22  
23  /**
24   * Represents a Metaschema module.
25   */
26  public interface IModule {
27    /**
28     * Retrieves the location where the Metaschema module was loaded from.
29     *
30     * @return the location, or {@code null} if this information is not available
31     */
32    URI getLocation();
33  
34    /**
35     * Get the source information for the module.
36     *
37     * @return the source information
38     */
39    @NonNull
40    ISource getSource();
41  
42    /**
43     * Get the long name for the Metaschema module.
44     *
45     * @return the name
46     */
47    @NonNull
48    MarkupLine getName();
49  
50    /**
51     * Get the revision of the Metaschema module.
52     *
53     * @return the revision
54     */
55    @NonNull
56    String getVersion();
57  
58    /**
59     * Retrieve the remarks associated with this Metaschema module, if any.
60     *
61     * @return the remarks or {@code null} if no remarks are defined
62     */
63    @Nullable
64    MarkupMultiline getRemarks();
65  
66    /**
67     * Retrieves the unique short name for the Metaschema module, which provides a
68     * textual identifier for the Metaschema module.
69     *
70     * @return the short name
71     */
72    @NonNull
73    String getShortName();
74  
75    /**
76     * Retrieves the XML namespace associated with the Metaschema module.
77     *
78     * @return a namespace
79     */
80    @NonNull
81    URI getXmlNamespace();
82  
83    /**
84     * Retrieve the JSON schema base URI associated with the Metaschema module.
85     *
86     * @return the base URI
87     */
88    @NonNull
89    URI getJsonBaseUri();
90  
91    /**
92     * Get the qualified name associated with the Metaschema module.
93     *
94     * @return the qualified name
95     */
96    default QName getQName() {
97      return new QName(getXmlNamespace().toASCIIString(), getShortName());
98    }
99  
100   /**
101    * Retrieves all Metaschema modules imported by this Metaschema module.
102    *
103    * @return a list of imported Metaschema modules
104    */
105   @NonNull
106   List<? extends IModule> getImportedModules();
107 
108   /**
109    * Retrieve the imported Metaschema module with the specified name, if it
110    * exists.
111    *
112    * @param name
113    *          the short name of the Metschema module to retrieve
114    * @return the imported Metaschema module or {@code null} if it doesn't exist
115    */
116   @Nullable
117   IModule getImportedModuleByShortName(String name);
118 
119   /**
120    * Retrieves the top-level assembly definitions in this Metaschema module.
121    *
122    * @return the collection of assembly definitions
123    */
124   @NonNull
125   Collection<? extends IAssemblyDefinition> getAssemblyDefinitions();
126 
127   /**
128    * Retrieves the top-level assembly definition in this Metaschema module with
129    * the matching name, if it exists.
130    *
131    * @param name
132    *          the definition name
133    *
134    * @return the matching assembly definition, or {@code null} if none match
135    */
136   @Nullable
137   IAssemblyDefinition getAssemblyDefinitionByName(@NonNull QName name);
138 
139   /**
140    * Retrieves the top-level field definitions in this Metaschema module.
141    *
142    * @return the collection of field definitions
143    */
144   @NonNull
145   Collection<? extends IFieldDefinition> getFieldDefinitions();
146 
147   /**
148    * Retrieves the top-level field definition in this Metaschema module with the
149    * matching name, if it exists.
150    *
151    * @param name
152    *          the definition name
153    *
154    * @return the matching field definition, or {@code null} if none match
155    */
156   @Nullable
157   IFieldDefinition getFieldDefinitionByName(@NonNull QName name);
158 
159   /**
160    * Retrieves the top-level assembly and field definitions in this Metaschema
161    * module.
162    *
163    * @return a listing of assembly and field definitions
164    */
165   @NonNull
166   List<? extends IModelDefinition> getAssemblyAndFieldDefinitions();
167 
168   /**
169    * Retrieves the top-level flag definitions in this Metaschema module.
170    *
171    * @return the collection of flag definitions
172    */
173   @NonNull
174   Collection<? extends IFlagDefinition> getFlagDefinitions();
175 
176   /**
177    * Retrieves the top-level flag definition in this Metaschema module with the
178    * matching name, if it exists.
179    *
180    * @param name
181    *          the definition name
182    *
183    * @return the matching flag definition, or {@code null} if none match
184    */
185   @Nullable
186   IFlagDefinition getFlagDefinitionByName(@NonNull QName name);
187 
188   /**
189    * Retrieves the assembly definition with a matching name from either: 1) the
190    * top-level assembly definitions from this Metaschema module, or 2) global
191    * assembly definitions from each imported Metaschema module in reverse order of
192    * import.
193    *
194    * @param name
195    *          the name of the assembly to find
196    * @return the assembly definition
197    */
198   @Nullable
199   IAssemblyDefinition getScopedAssemblyDefinitionByName(@NonNull QName name);
200 
201   /**
202    * Retrieves the field definition with a matching name from either: 1) the
203    * top-level field definitions from this Metaschema module, or 2) global field
204    * definitions from each imported Metaschema module in reverse order of import.
205    *
206    * @param name
207    *          the name of the field definition to find
208    * @return the field definition
209    */
210   @Nullable
211   IFieldDefinition getScopedFieldDefinitionByName(@NonNull QName name);
212 
213   /**
214    * Retrieves the flag definition with a matching name from either: 1) the
215    * top-level flag definitions from this Metaschema module, or 2) global flag
216    * definitions from each imported Metaschema module in reverse order of import.
217    *
218    * @param name
219    *          the name of the flag definition to find
220    * @return the flag definition
221    */
222   @Nullable
223   IFlagDefinition getScopedFlagDefinitionByName(@NonNull QName name);
224 
225   /**
226    * Retrieves the top-level assembly definitions that are marked as roots from
227    * the current Metaschema module.
228    *
229    * @return a listing of assembly definitions marked as root
230    */
231   @NonNull
232   Collection<? extends IAssemblyDefinition> getRootAssemblyDefinitions();
233 
234   /**
235    * Retrieve the top-level flag definitions that are marked global in this
236    * Metaschema module or in any imported Metaschema modules. The resulting
237    * collection is built by adding global definitions from each imported
238    * Metaschema module in order of import, then adding global definitions from the
239    * current Metaschema module. Such a map is built in this way for each imported
240    * Metaschema module in the chain. Values for clashing keys will be replaced in
241    * this order, giving preference to the "closest" definition.
242    *
243    * @return the collection of exported flag definitions
244    */
245   @NonNull
246   Collection<? extends IFlagDefinition> getExportedFlagDefinitions();
247 
248   /**
249    * Retrieves the exported named flag definition, if it exists.
250    * <p>
251    * For information about how flag definitions are exported see
252    * {@link #getExportedFlagDefinitions()}.
253    *
254    * @param name
255    *          the definition name
256    * @return the flag definition, or {@code null} if it doesn't exist.
257    */
258   @Nullable
259   IFlagDefinition getExportedFlagDefinitionByName(@NonNull QName name);
260 
261   /**
262    * Retrieve the top-level field definitions that are marked global in this
263    * Metaschema module or in any imported Metaschema module. The resulting
264    * collection is built by adding global definitions from each imported
265    * Metaschema module in order of import, then adding global definitions from the
266    * current Metaschema module. Such a map is built in this way for each imported
267    * Metaschema module in the chain. Values for clashing keys will be replaced in
268    * this order, giving preference to the "closest" definition
269    *
270    * @return the collection of exported field definitions
271    */
272   @NonNull
273   Collection<? extends IFieldDefinition> getExportedFieldDefinitions();
274 
275   /**
276    * Retrieves the exported named field definition, if it exists.
277    * <p>
278    * For information about how field definitions are exported see
279    * {@link #getExportedFieldDefinitions()}.
280    *
281    * @param name
282    *          the definition name
283    * @return the field definition, or {@code null} if it doesn't exist.
284    */
285   @Nullable
286   IFieldDefinition getExportedFieldDefinitionByName(@NonNull QName name);
287 
288   /**
289    * Retrieve the top-level assembly definitions that are marked global in this
290    * Metaschema module or in any imported Metaschema module. The resulting
291    * collection is built by adding global definitions from each imported
292    * Metaschema module in order of import, then adding global definitions from the
293    * current Metaschema module. This collection is built in this way for each
294    * imported Metaschema module in the chain. Items with duplicate names will be
295    * replaced in this order, giving preference to the "closest" definition
296    *
297    * @return the collection of exported assembly definitions
298    */
299   @NonNull
300   Collection<? extends IAssemblyDefinition> getExportedAssemblyDefinitions();
301 
302   /**
303    * Retrieves the exported named assembly definition, if it exists.
304    * <p>
305    * For information about how assembly definitions are exported see
306    * {@link #getExportedAssemblyDefinitions()}.
307    *
308    * @param name
309    *          the definition name
310    * @return the assembly definition, or {@code null} if it doesn't exist.
311    */
312   @Nullable
313   IAssemblyDefinition getExportedAssemblyDefinitionByName(@NonNull QName name);
314 
315   /**
316    * Retrieves the top-level assembly definitions that are marked as roots from
317    * the current Metaschema module and any imported Metaschema modules.
318    *
319    * @return a listing of assembly definitions marked as root
320    */
321   @NonNull
322   Collection<? extends IAssemblyDefinition> getExportedRootAssemblyDefinitions();
323 
324   /**
325    * Retrieves the exported named root assembly definition, if it exists.
326    * <p>
327    * For information about how assembly definitions are exported see
328    * {@link #getExportedAssemblyDefinitions()}.
329    *
330    * @param name
331    *          the root name
332    * @return the assembly definition, or {@code null} if it doesn't exist.
333    */
334   @Nullable
335   IAssemblyDefinition getExportedRootAssemblyDefinitionByName(QName name);
336 
337   /**
338    * Get the mapping of prefix to namespace URI for use in resolving the namespace
339    * of lexical qualified named in Metapath.
340    *
341    * @return the mapping
342    */
343   @NonNull
344   Map<String, String> getNamespaceBindings();
345 
346   /**
347    * Used to parse a flag name reference to produce a qualified name.
348    *
349    * @param nameRef
350    *          the name reference
351    * @return the qualified name
352    */
353   @NonNull
354   default QName toFlagQName(@NonNull String nameRef) {
355     return EQNameUtils.parseName(
356         nameRef,
357         getModuleStaticContext().getFlagPrefixResolver());
358   }
359 
360   /**
361    * Used to parse a flag name reference to produce a qualified name.
362    *
363    * @param modelNamespace
364    *          the namespace to use or {@code null}
365    * @param nameRef
366    *          the name reference
367    * @return the qualified name
368    */
369   @NonNull
370   default QName toFlagQName(@Nullable String modelNamespace, @NonNull String nameRef) {
371     return modelNamespace == null
372         ? new QName(nameRef)
373         : new QName(modelNamespace, nameRef);
374   }
375 
376   /**
377    * Used to parse a model name reference to produce a qualified name.
378    *
379    * @param nameRef
380    *          the name reference
381    * @return the qualified name
382    */
383   @NonNull
384   default QName toModelQName(@NonNull String nameRef) {
385     return EQNameUtils.parseName(
386         nameRef,
387         getModuleStaticContext().getModelPrefixResolver());
388   }
389 
390   /**
391    * Used to parse a flag name reference to produce a qualified name.
392    *
393    * @param modelNamespace
394    *          the namespace to use or {@code null}
395    * @param nameRef
396    *          the name reference
397    * @return the qualified name
398    */
399   @NonNull
400   default QName toModelQName(@Nullable String modelNamespace, @NonNull String nameRef) {
401     String namespace = modelNamespace == null ? getXmlNamespace().toASCIIString() : modelNamespace;
402     return new QName(namespace, nameRef);
403   }
404 
405   /**
406    * Get the Metapath static context for compiling Metapath expressions that query
407    * instances of this model.
408    *
409    * @return the static context
410    */
411   @NonNull
412   StaticContext getModuleStaticContext();
413 }