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.ISource;
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.xml.XmlModuleConstants;
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.metaschema.IBindingDefinitionModelAssembly;
31  import gov.nist.secauto.metaschema.databind.model.metaschema.IBindingMetaschemaModule;
32  import gov.nist.secauto.metaschema.databind.model.metaschema.binding.AssemblyConstraints;
33  import gov.nist.secauto.metaschema.databind.model.metaschema.binding.JsonKey;
34  import gov.nist.secauto.metaschema.databind.model.metaschema.binding.METASCHEMA;
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(() -> AssemblyModelGenerator.of(
107         binding.getModel(),
108         ObjectUtils.requireNonNull(bindingInstance.getDefinition()
109             .getAssemblyInstanceByName(XmlModuleConstants.MODEL_QNAME.getIndexPosition())),
110         this,
111         nodeItemFactory)));
112 
113     ISource source = module.getSource();
114 
115     this.modelConstraints = ObjectUtils.notNull(Lazy.lazy(() -> {
116       IModelConstrained retval = new AssemblyConstraintSet(source);
117       AssemblyConstraints constraints = getBinding().getConstraint();
118       if (constraints != null) {
119         ConstraintBindingSupport.parse(retval, constraints, source);
120       }
121       return retval;
122     }));
123     this.boundNodeItem = ObjectUtils.notNull(Lazy.lazy(() -> ObjectUtils.requireNonNull(ModelSupport.toNodeItem(
124         module,
125         bindingInstance.getQName(),
126         position))));
127   }
128 
129   @NonNull
130   private METASCHEMA.DefineAssembly getBinding() {
131     return binding;
132   }
133 
134   @Override
135   public IContainerFlagSupport<IFlagInstance> getFlagContainer() {
136     return ObjectUtils.notNull(flagContainer.get());
137   }
138 
139   @Override
140   public IContainerModelAssemblySupport<
141       IModelInstanceAbsolute,
142       INamedModelInstanceAbsolute,
143       IFieldInstanceAbsolute,
144       IAssemblyInstanceAbsolute,
145       IChoiceInstance,
146       IChoiceGroupInstance> getModelContainer() {
147     return ObjectUtils.notNull(modelContainer.get());
148   }
149 
150   @Override
151   public IModelConstrained getConstraintSupport() {
152     return ObjectUtils.notNull(modelConstraints.get());
153   }
154 
155   @Override
156   public IAssemblyNodeItem getSourceNodeItem() {
157     return ObjectUtils.notNull(boundNodeItem.get());
158   }
159 
160   @Override
161   public Map<IAttributable.Key, Set<String>> getProperties() {
162     return properties;
163   }
164 
165   // ---------------------------------------
166   // - Start binding driven code - CPD-OFF -
167   // ---------------------------------------
168 
169   @Override
170   public String getFormalName() {
171     return getBinding().getFormalName();
172   }
173 
174   @Override
175   public MarkupLine getDescription() {
176     return getBinding().getDescription();
177   }
178 
179   @Override
180   public String getName() {
181     return ObjectUtils.notNull(getBinding().getName());
182   }
183 
184   @Override
185   public ModuleScope getModuleScope() {
186     return ModelSupport.moduleScope(ObjectUtils.requireNonNull(getBinding().getScope()));
187   }
188 
189   @Override
190   public Integer getIndex() {
191     return ModelSupport.index(getBinding().getIndex());
192   }
193 
194   @Override
195   public String getUseName() {
196     return ModelSupport.useName(getBinding().getUseName());
197   }
198 
199   @Override
200   public Integer getUseIndex() {
201     return ModelSupport.useIndex(getBinding().getUseName());
202   }
203 
204   @Override
205   public MarkupMultiline getRemarks() {
206     return ModelSupport.remarks(getBinding().getRemarks());
207   }
208 
209   @Override
210   public boolean isRoot() {
211     return getRootName() != null || getRootIndex() != null;
212   }
213 
214   @Override
215   public String getRootName() {
216     return ModelSupport.rootName(getBinding().getRootName());
217   }
218 
219   @Override
220   public Integer getRootIndex() {
221     return ModelSupport.rootIndex(getBinding().getRootName());
222   }
223 }