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