1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.databind.model.metaschema.impl;
7   
8   import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
9   import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
10  import gov.nist.secauto.metaschema.core.metapath.item.node.IAssemblyNodeItem;
11  import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItemFactory;
12  import gov.nist.secauto.metaschema.core.model.AbstractGlobalAssemblyDefinition;
13  import gov.nist.secauto.metaschema.core.model.IAssemblyInstance;
14  import gov.nist.secauto.metaschema.core.model.IAssemblyInstanceAbsolute;
15  import gov.nist.secauto.metaschema.core.model.IAttributable;
16  import gov.nist.secauto.metaschema.core.model.IChoiceGroupInstance;
17  import gov.nist.secauto.metaschema.core.model.IChoiceInstance;
18  import gov.nist.secauto.metaschema.core.model.IContainerFlagSupport;
19  import gov.nist.secauto.metaschema.core.model.IContainerModelAssemblySupport;
20  import gov.nist.secauto.metaschema.core.model.IFieldInstanceAbsolute;
21  import gov.nist.secauto.metaschema.core.model.IFlagInstance;
22  import gov.nist.secauto.metaschema.core.model.IModelInstanceAbsolute;
23  import gov.nist.secauto.metaschema.core.model.INamedModelInstanceAbsolute;
24  import gov.nist.secauto.metaschema.core.model.constraint.AssemblyConstraintSet;
25  import gov.nist.secauto.metaschema.core.model.constraint.IModelConstrained;
26  import gov.nist.secauto.metaschema.core.model.xml.XmlModuleConstants;
27  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
28  import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelGroupedAssembly;
29  import gov.nist.secauto.metaschema.databind.model.metaschema.IBindingDefinitionModelAssembly;
30  import gov.nist.secauto.metaschema.databind.model.metaschema.IBindingMetaschemaModule;
31  import gov.nist.secauto.metaschema.databind.model.metaschema.binding.AssemblyConstraints;
32  import gov.nist.secauto.metaschema.databind.model.metaschema.binding.JsonKey;
33  import gov.nist.secauto.metaschema.databind.model.metaschema.binding.METASCHEMA;
34  
35  import java.util.Map;
36  import java.util.Set;
37  
38  import edu.umd.cs.findbugs.annotations.NonNull;
39  import nl.talsmasoftware.lazy4j.Lazy;
40  
41  public class DefinitionAssemblyGlobal
42      extends AbstractGlobalAssemblyDefinition<
43          IBindingMetaschemaModule,
44          IAssemblyInstance,
45          IFlagInstance,
46          IModelInstanceAbsolute,
47          INamedModelInstanceAbsolute,
48          IFieldInstanceAbsolute,
49          IAssemblyInstanceAbsolute,
50          IChoiceInstance,
51          IChoiceGroupInstance>
52      implements IBindingDefinitionModelAssembly {
53    @NonNull
54    private final METASCHEMA.DefineAssembly binding;
55    @NonNull
56    private final Map<IAttributable.Key, Set<String>> properties;
57    @NonNull
58    private final Lazy<IContainerFlagSupport<IFlagInstance>> flagContainer;
59    @NonNull
60    private final Lazy<IContainerModelAssemblySupport<
61        IModelInstanceAbsolute,
62        INamedModelInstanceAbsolute,
63        IFieldInstanceAbsolute,
64        IAssemblyInstanceAbsolute,
65        IChoiceInstance,
66        IChoiceGroupInstance>> modelContainer;
67    @NonNull
68    private final Lazy<IModelConstrained> modelConstraints;
69    @NonNull
70    private final Lazy<IAssemblyNodeItem> boundNodeItem;
71  
72    /**
73     * Construct a new global assembly definition.
74     *
75     * @param binding
76     *          the assembly reference object bound to a Java class
77     * @param bindingInstance
78     *          the Metaschema module instance for the bound assembly reference
79     *          object
80     * @param position
81     *          the zero-based position of this instance relative to its bound
82     *          object siblings
83     * @param module
84     *          the containing Metaschema module
85     * @param nodeItemFactory
86     *          the node item factory used to generate child nodes
87     */
88    public DefinitionAssemblyGlobal(
89        @NonNull METASCHEMA.DefineAssembly binding,
90        @NonNull IBoundInstanceModelGroupedAssembly bindingInstance,
91        int position,
92        @NonNull IBindingMetaschemaModule module,
93        @NonNull INodeItemFactory nodeItemFactory) {
94      super(module);
95      this.binding = binding;
96      this.properties = ModelSupport.parseProperties(ObjectUtils.requireNonNull(binding.getProps()));
97      this.flagContainer = ObjectUtils.notNull(Lazy.lazy(() -> {
98        JsonKey jsonKey = getBinding().getJsonKey();
99        return FlagContainerSupport.newFlagContainer(
100           binding.getFlags(),
101           bindingInstance,
102           this,
103           jsonKey == null ? null : jsonKey.getFlagRef());
104     }));
105     this.modelContainer = ObjectUtils.notNull(Lazy.lazy(() -> AssemblyModelContainerSupport.of(
106         binding.getModel(),
107         ObjectUtils.requireNonNull(bindingInstance.getDefinition()
108             .getAssemblyInstanceByName(XmlModuleConstants.MODEL_QNAME)),
109         this,
110         nodeItemFactory)));
111     this.modelConstraints = ObjectUtils.notNull(Lazy.lazy(() -> {
112       IModelConstrained retval = new AssemblyConstraintSet();
113       AssemblyConstraints constraints = getBinding().getConstraint();
114       if (constraints != null) {
115         ConstraintBindingSupport.parse(retval, constraints, module.getSource());
116       }
117       return retval;
118     }));
119     this.boundNodeItem = ObjectUtils.notNull(Lazy.lazy(() -> ObjectUtils.requireNonNull(ModelSupport.toNodeItem(
120         module,
121         bindingInstance.getXmlQName(),
122         position))));
123   }
124 
125   @NonNull
126   protected METASCHEMA.DefineAssembly getBinding() {
127     return binding;
128   }
129 
130   @Override
131   public IContainerFlagSupport<IFlagInstance> getFlagContainer() {
132     return ObjectUtils.notNull(flagContainer.get());
133   }
134 
135   @Override
136   public IContainerModelAssemblySupport<
137       IModelInstanceAbsolute,
138       INamedModelInstanceAbsolute,
139       IFieldInstanceAbsolute,
140       IAssemblyInstanceAbsolute,
141       IChoiceInstance,
142       IChoiceGroupInstance> getModelContainer() {
143     return ObjectUtils.notNull(modelContainer.get());
144   }
145 
146   @Override
147   public IModelConstrained getConstraintSupport() {
148     return ObjectUtils.notNull(modelConstraints.get());
149   }
150 
151   @Override
152   public IAssemblyNodeItem getSourceNodeItem() {
153     return ObjectUtils.notNull(boundNodeItem.get());
154   }
155 
156   @Override
157   public Map<IAttributable.Key, Set<String>> getProperties() {
158     return properties;
159   }
160 
161   // ---------------------------------------
162   // - Start binding driven code - CPD-OFF -
163   // ---------------------------------------
164 
165   @Override
166   public String getFormalName() {
167     return getBinding().getFormalName();
168   }
169 
170   @Override
171   public MarkupLine getDescription() {
172     return getBinding().getDescription();
173   }
174 
175   @Override
176   public String getName() {
177     return ObjectUtils.notNull(getBinding().getName());
178   }
179 
180   @Override
181   public ModuleScope getModuleScope() {
182     return ModelSupport.moduleScope(ObjectUtils.requireNonNull(getBinding().getScope()));
183   }
184 
185   @Override
186   public Integer getIndex() {
187     return ModelSupport.index(getBinding().getIndex());
188   }
189 
190   @Override
191   public String getUseName() {
192     return ModelSupport.useName(getBinding().getUseName());
193   }
194 
195   @Override
196   public Integer getUseIndex() {
197     return ModelSupport.useIndex(getBinding().getUseName());
198   }
199 
200   @Override
201   public MarkupMultiline getRemarks() {
202     return ModelSupport.remarks(getBinding().getRemarks());
203   }
204 
205   @Override
206   public boolean isRoot() {
207     return getRootName() != null || getRootIndex() != null;
208   }
209 
210   @Override
211   public String getRootName() {
212     return ModelSupport.rootName(getBinding().getRootName());
213   }
214 
215   @Override
216   public Integer getRootIndex() {
217     return ModelSupport.rootIndex(getBinding().getRootName());
218   }
219 }