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.model.constraint.IFeatureValueConstrained;
9   import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
10  
11  import java.util.Locale;
12  
13  import edu.umd.cs.findbugs.annotations.NonNull;
14  import edu.umd.cs.findbugs.annotations.Nullable;
15  
16  /**
17   * Represents a definition of a flag, field, or assembly in a Metaschema module.
18   * <p>
19   * Definitions are reusable components that specify the structure and
20   * constraints for data elements. They can be referenced by instances or defined
21   * inline.
22   */
23  public interface IDefinition extends INamedModelElement, IAttributable, IFeatureValueConstrained {
24    /**
25     * Describes the visibility of a definition to other modules.
26     */
27    enum ModuleScope {
28      /**
29       * The definition is scoped to only the defining module.
30       */
31      PRIVATE,
32      /**
33       * The definition is scoped to its defining module and any importing module.
34       */
35      PUBLIC;
36    }
37  
38    /**
39     * The default module scope for definitions.
40     */
41    @NonNull
42    ModuleScope DEFAULT_MODULE_SCOPE = ModuleScope.PUBLIC;
43  
44    /**
45     * Retrieve the definition's scope within the context of its defining module.
46     *
47     * @return the module scope
48     */
49    @NonNull
50    default ModuleScope getModuleScope() {
51      return ModuleScope.PRIVATE;
52    }
53  
54    /**
55     * The qualified name for the definition.
56     * <p>
57     * This name is the combination of the definition's namespace, which is the
58     * module's namespace, and the definition's name.
59     *
60     * @return the definition's qualified name
61     */
62    @NonNull
63    IEnhancedQName getDefinitionQName();
64  
65    /**
66     * Determine if the definition is defined inline, meaning the definition is
67     * declared where it is used.
68     * <p>
69     * If this method returns {@code false}, then {@link #getInlineInstance()} must
70     * return {@code null}.
71     *
72     * @return {@code true} if the definition is declared inline or {@code false} if
73     *         the definition is able to be globally referenced
74     * @see #getInlineInstance()
75     */
76    default boolean isInline() {
77      return getInlineInstance() != null;
78    }
79  
80    /**
81     * If {@link #isInline()} is {@code true}, return the instance the definition is
82     * inlined for.
83     * <p>
84     * If this method returns {@code null}, then {@link #getInlineInstance()} must
85     * return {@code false}.
86     *
87     * @return the instance or {@code null} otherwise
88     * @see #isInline()
89     */
90    INamedInstance getInlineInstance();
91  
92    /**
93     * Generates a coordinate string for the provided information element
94     * definition.
95     *
96     * A coordinate consists of the element's:
97     * <ul>
98     * <li>containing Metaschema's short name
99     * <li>model type
100    * <li>name
101    * <li>hash code
102    * </ul>
103    *
104    * @return the coordinate
105    */
106   @SuppressWarnings("null")
107   @Override
108   default String toCoordinates() {
109     return String.format("%s:%s-definition:%s(%d)",
110         getContainingModule().getShortName(),
111         getModelType().toString().toUpperCase(Locale.ROOT),
112         getName(),
113         hashCode());
114   }
115 
116   /**
117    * Get the resource location information for the provided item, if known.
118    *
119    * @param itemValue
120    *          the item to get the location information for
121    *
122    * @return the resource location information, or {@code null} if not known
123    */
124   @Nullable
125   default IResourceLocation getLocation(@NonNull Object itemValue) {
126     return itemValue instanceof IBoundObject ? ((IBoundObject) itemValue).getMetaschemaData() : null;
127   }
128 }