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.MetaschemaConstants;
9   import gov.nist.secauto.metaschema.core.model.constraint.IFeatureModelConstrained;
10  import gov.nist.secauto.metaschema.core.model.util.ModuleUtils;
11  import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
12  
13  import edu.umd.cs.findbugs.annotations.NonNull;
14  import edu.umd.cs.findbugs.annotations.Nullable;
15  
16  /**
17   * Represents an assembly definition in a Metaschema module.
18   * <p>
19   * An assembly is a complex structured data object that may contain flags,
20   * fields, and other nested assemblies. Assembly definitions may be designated
21   * as root elements for documents.
22   */
23  public interface IAssemblyDefinition
24      extends IModelDefinition, IContainerModelAssembly, IAssembly, IFeatureModelConstrained {
25    /**
26     * The qualified name for the model property in Metaschema.
27     */
28    IEnhancedQName MODEL_QNAME = IEnhancedQName.of(MetaschemaConstants.METASCHEMA_NAMESPACE, "model");
29  
30    /**
31     * Check if the assembly is a top-level root assembly.
32     *
33     * @return {@code true} if the assembly is a top-level root, or {@code false}
34     *         otherwise
35     */
36    default boolean isRoot() {
37      // not a root by default
38      return false;
39    }
40  
41    /**
42     * Get the root name if this assembly is a top-level root.
43     *
44     * @return the root name if this assembly is a top-level root, or {@code null}
45     *         otherwise
46     */
47    @Nullable
48    default String getRootName() {
49      // not a root by default
50      return null;
51    }
52  
53    /**
54     * Get the root index to use for binary data, if this assembly is a top-level
55     * root.
56     *
57     * @return the root index if provided and this assembly is a top-level root, or
58     *         {@code null} otherwise
59     */
60    @Nullable
61    default Integer getRootIndex() {
62      // not a root by default
63      return null;
64    }
65  
66    /**
67     * Get the XML qualified name to use in XML as the root element.
68     *
69     * @return the root XML qualified name if this assembly is a top-level root, or
70     *         {@code null} otherwise
71     */
72    default IEnhancedQName getRootQName() {
73      IEnhancedQName retval = null;
74      String rootName = getRootName();
75      if (rootName != null) {
76        retval = ModuleUtils.parseModelName(getContainingModule(), rootName);
77      }
78      return retval;
79    }
80  
81    /**
82     * Get the name used for the associated property in JSON/YAML.
83     *
84     * @return the root JSON property name if this assembly is a top-level root, or
85     *         {@code null} otherwise
86     */
87    default String getRootJsonName() {
88      return getRootName();
89    }
90  
91    @Override
92    default boolean isInline() {
93      // not inline by default
94      return false;
95    }
96  
97    @Override
98    default IAssemblyInstance getInlineInstance() {
99      // not inline by default
100     return null;
101   }
102 
103   @Override
104   default IAssemblyDefinition getOwningDefinition() {
105     return this;
106   }
107   //
108   // @Override
109   // default IAssemblyNodeItem getNodeItem() {
110   // return null;
111   // }
112 
113   @Override
114   default boolean hasChildren() {
115     return IModelDefinition.super.hasChildren() || IContainerModelAssembly.super.hasChildren();
116   }
117 
118   /**
119    * A visitor callback.
120    *
121    * @param <CONTEXT>
122    *          the type of the context parameter
123    * @param <RESULT>
124    *          the type of the visitor result
125    * @param visitor
126    *          the calling visitor
127    * @param context
128    *          a parameter used to pass contextual information between visitors
129    * @return the visitor result
130    */
131   @Override
132   default <CONTEXT, RESULT> RESULT accept(@NonNull IModelElementVisitor<CONTEXT, RESULT> visitor, CONTEXT context) {
133     return visitor.visitAssemblyDefinition(this, context);
134   }
135 }