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