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.ModuleScopeEnum;
25  import gov.nist.secauto.metaschema.core.model.constraint.AssemblyConstraintSet;
26  import gov.nist.secauto.metaschema.core.model.constraint.IModelConstrained;
27  import gov.nist.secauto.metaschema.core.model.constraint.ISource;
28  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
29  import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelGroupedAssembly;
30  import gov.nist.secauto.metaschema.databind.model.binding.metaschema.AssemblyConstraints;
31  import gov.nist.secauto.metaschema.databind.model.binding.metaschema.JsonKey;
32  import gov.nist.secauto.metaschema.databind.model.binding.metaschema.METASCHEMA;
33  import gov.nist.secauto.metaschema.databind.model.metaschema.IBindingDefinitionModelAssembly;
34  import gov.nist.secauto.metaschema.databind.model.metaschema.IBindingMetaschemaModule;
35  
36  import java.util.Map;
37  import java.util.Set;
38  
39  import edu.umd.cs.findbugs.annotations.NonNull;
40  import nl.talsmasoftware.lazy4j.Lazy;
41  
42  public class DefinitionAssemblyGlobal
43      extends AbstractGlobalAssemblyDefinition<
44          IBindingMetaschemaModule,
45          IAssemblyInstance,
46          IFlagInstance,
47          IModelInstanceAbsolute,
48          INamedModelInstanceAbsolute,
49          IFieldInstanceAbsolute,
50          IAssemblyInstanceAbsolute,
51          IChoiceInstance,
52          IChoiceGroupInstance>
53      implements IBindingDefinitionModelAssembly {
54    @NonNull
55    private final METASCHEMA.DefineAssembly binding;
56    @NonNull
57    private final Map<IAttributable.Key, Set<String>> properties;
58    @NonNull
59    private final Lazy<IContainerFlagSupport<IFlagInstance>> flagContainer;
60    @NonNull
61    private final Lazy<IContainerModelAssemblySupport<
62        IModelInstanceAbsolute,
63        INamedModelInstanceAbsolute,
64        IFieldInstanceAbsolute,
65        IAssemblyInstanceAbsolute,
66        IChoiceInstance,
67        IChoiceGroupInstance>> modelContainer;
68    @NonNull
69    private final Lazy<IModelConstrained> modelConstraints;
70    @NonNull
71    private final Lazy<IAssemblyNodeItem> boundNodeItem;
72  
73    /**
74     * Construct a new global assembly definition.
75     *
76     * @param binding
77     *          the assembly reference object bound to a Java class
78     * @param bindingInstance
79     *          the Metaschema module instance for the bound assembly reference
80     *          object
81     * @param position
82     *          the zero-based position of this instance relative to its bound
83     *          object siblings
84     * @param module
85     *          the containing Metaschema module
86     * @param nodeItemFactory
87     *          the node item factory used to generate child nodes
88     */
89    public DefinitionAssemblyGlobal(
90        @NonNull METASCHEMA.DefineAssembly binding,
91        @NonNull IBoundInstanceModelGroupedAssembly bindingInstance,
92        int position,
93        @NonNull IBindingMetaschemaModule module,
94        @NonNull INodeItemFactory nodeItemFactory) {
95      super(module);
96      this.binding = binding;
97      this.properties = ModelSupport.parseProperties(ObjectUtils.requireNonNull(binding.getProps()));
98      this.flagContainer = ObjectUtils.notNull(Lazy.lazy(() -> {
99        JsonKey jsonKey = getBinding().getJsonKey();
100       return FlagContainerSupport.newFlagContainer(
101           binding.getFlags(),
102           bindingInstance,
103           this,
104           jsonKey == null ? null : jsonKey.getFlagRef());
105     }));
106     this.modelContainer = ObjectUtils.notNull(Lazy.lazy(() -> AssemblyModelContainerSupport.of(
107         binding.getModel(),
108         ObjectUtils.requireNonNull(bindingInstance.getDefinition().getAssemblyInstanceByName(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, ISource.modelSource(module));
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 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 ModuleScopeEnum 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 }