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 }