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