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