View Javadoc
1   /*
2    * Portions of this software was developed by employees of the National Institute
3    * of Standards and Technology (NIST), an agency of the Federal Government and is
4    * being made available as a public service. Pursuant to title 17 United States
5    * Code Section 105, works of NIST employees are not subject to copyright
6    * protection in the United States. This software may be subject to foreign
7    * copyright. Permission in the United States and in foreign countries, to the
8    * extent that NIST may hold copyright, to use, copy, modify, create derivative
9    * works, and distribute this software and its documentation without fee is hereby
10   * granted on a non-exclusive basis, provided that this notice and disclaimer
11   * of warranty appears in all copies.
12   *
13   * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
14   * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
15   * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
17   * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
18   * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
19   * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
20   * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
21   * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
22   * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
23   * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
24   * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
25   */
26  
27  package gov.nist.secauto.metaschema.core.model.xml; // NOPMD - excessive public methods and coupling is unavoidable
28  
29  import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
30  import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
31  import gov.nist.secauto.metaschema.core.model.AbstractAssemblyInstance;
32  import gov.nist.secauto.metaschema.core.model.IAssemblyDefinition;
33  import gov.nist.secauto.metaschema.core.model.IAssemblyInstance;
34  import gov.nist.secauto.metaschema.core.model.IChoiceInstance;
35  import gov.nist.secauto.metaschema.core.model.IFeatureFlagContainer;
36  import gov.nist.secauto.metaschema.core.model.IFeatureInlinedDefinition;
37  import gov.nist.secauto.metaschema.core.model.IFeatureModelContainer;
38  import gov.nist.secauto.metaschema.core.model.IFieldInstance;
39  import gov.nist.secauto.metaschema.core.model.IFlagInstance;
40  import gov.nist.secauto.metaschema.core.model.IModelContainer;
41  import gov.nist.secauto.metaschema.core.model.IModelInstance;
42  import gov.nist.secauto.metaschema.core.model.IModule;
43  import gov.nist.secauto.metaschema.core.model.INamedModelInstance;
44  import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior;
45  import gov.nist.secauto.metaschema.core.model.ModuleScopeEnum;
46  import gov.nist.secauto.metaschema.core.model.XmlGroupAsBehavior;
47  import gov.nist.secauto.metaschema.core.model.constraint.IConstraint.ExternalModelSource;
48  import gov.nist.secauto.metaschema.core.model.constraint.IModelConstrained;
49  import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.InlineAssemblyDefinitionType;
50  import gov.nist.secauto.metaschema.core.util.CollectionUtil;
51  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
52  
53  import java.util.Collection;
54  import java.util.Collections;
55  import java.util.Map;
56  import java.util.Set;
57  
58  import javax.xml.namespace.QName;
59  
60  import edu.umd.cs.findbugs.annotations.NonNull;
61  import nl.talsmasoftware.lazy4j.Lazy;
62  
63  /**
64   * Represents a Metaschema assembly definition declared locally as an instance.
65   */
66  class XmlInlineAssemblyDefinition
67      extends AbstractAssemblyInstance {
68    @NonNull
69    private final InlineAssemblyDefinitionType xmlAssembly;
70    @NonNull
71    private final InternalAssemblyDefinition assemblyDefinition;
72  
73    /**
74     * Constructs a new Metaschema assembly definition from an XML representation
75     * bound to Java objects.
76     *
77     * @param xmlAssembly
78     *          the XML representation bound to Java objects
79     * @param parent
80     *          the parent container, either a choice or assembly
81     */
82    public XmlInlineAssemblyDefinition(
83        @NonNull InlineAssemblyDefinitionType xmlAssembly,
84        @NonNull IModelContainer parent) {
85      super(parent);
86      this.xmlAssembly = xmlAssembly;
87      this.assemblyDefinition = new InternalAssemblyDefinition();
88    }
89  
90    @Override
91    public InternalAssemblyDefinition getDefinition() {
92      return assemblyDefinition;
93    }
94  
95    // ----------------------------------------
96    // - Start Annotation driven code - CPD-OFF
97    // ----------------------------------------
98  
99    /**
100    * Get the underlying XML model.
101    *
102    * @return the XML model
103    */
104   protected InlineAssemblyDefinitionType getXmlAssembly() {
105     return xmlAssembly;
106   }
107 
108   @Override
109   public String getFormalName() {
110     return getXmlAssembly().isSetFormalName() ? getXmlAssembly().getFormalName() : null;
111   }
112 
113   @SuppressWarnings("null")
114   @Override
115   public MarkupLine getDescription() {
116     return getXmlAssembly().isSetDescription()
117         ? MarkupStringConverter.toMarkupString(getXmlAssembly().getDescription())
118         : null;
119   }
120 
121   @Override
122   public Map<QName, Set<String>> getProperties() {
123     return ModelFactory.toProperties(CollectionUtil.listOrEmpty(getXmlAssembly().getPropList()));
124   }
125 
126   @SuppressWarnings("null")
127   @Override
128   public String getName() {
129     return getXmlAssembly().getName();
130   }
131 
132   @Override
133   public String getGroupAsName() {
134     return getXmlAssembly().isSetGroupAs() ? getXmlAssembly().getGroupAs().getName() : null;
135   }
136 
137   @Override
138   public int getMinOccurs() {
139     return XmlModelParser.getMinOccurs(getXmlAssembly().getMinOccurs());
140   }
141 
142   @Override
143   public int getMaxOccurs() {
144     return XmlModelParser.getMaxOccurs(getXmlAssembly().getMaxOccurs());
145   }
146 
147   @Override
148   public JsonGroupAsBehavior getJsonGroupAsBehavior() {
149     return XmlModelParser.getJsonGroupAsBehavior(getXmlAssembly().getGroupAs());
150   }
151 
152   @Override
153   public XmlGroupAsBehavior getXmlGroupAsBehavior() {
154     return XmlModelParser.getXmlGroupAsBehavior(getXmlAssembly().getGroupAs());
155   }
156 
157   @SuppressWarnings("null")
158   @Override
159   public MarkupMultiline getRemarks() {
160     return getXmlAssembly().isSetRemarks() ? MarkupStringConverter.toMarkupString(getXmlAssembly().getRemarks()) : null;
161   }
162 
163   // --------------------------------------
164   // - End Annotation driven code - CPD-ON
165   // --------------------------------------
166 
167   @Override
168   public String getUseName() {
169     // an inline definition doesn't have a use name
170     return null;
171   }
172 
173   @Override
174   public Object getValue(@NonNull Object parentValue) {
175     // there is no value
176     return null;
177   }
178 
179   @SuppressWarnings("null")
180   @Override
181   public Collection<?> getItemValues(Object instanceValue) {
182     // there are no item values
183     return Collections.emptyList();
184   }
185 
186   /**
187    * The corresponding definition for the local flag instance.
188    */
189   @SuppressWarnings("PMD.GodClass")
190   private final class InternalAssemblyDefinition
191       implements IAssemblyDefinition,
192       IFeatureInlinedDefinition<IAssemblyInstance>,
193       IFeatureModelContainer<IModelInstance, INamedModelInstance, IFieldInstance, IAssemblyInstance, IChoiceInstance>,
194       IFeatureFlagContainer<IFlagInstance> {
195     private final Lazy<XmlFlagContainerSupport> flagContainer;
196     private final Lazy<XmlModelContainerSupport> modelContainer;
197     private final Lazy<IModelConstrained> constraints;
198 
199     private InternalAssemblyDefinition() {
200       this.flagContainer = Lazy.lazy(() -> new XmlFlagContainerSupport(xmlAssembly, this));
201       this.modelContainer = Lazy.lazy(() -> new XmlModelContainerSupport(xmlAssembly, this));
202       this.constraints = Lazy.lazy(() -> {
203         IModelConstrained retval;
204         if (getXmlAssembly().isSetConstraint()) {
205           retval = new AssemblyConstraintSupport(
206               ObjectUtils.notNull(getXmlAssembly().getConstraint()),
207               ExternalModelSource.instance(
208                   ObjectUtils.requireNonNull(getContainingModule().getLocation())));
209         } else {
210           retval = new AssemblyConstraintSupport();
211         }
212         return retval;
213       });
214     }
215 
216     // REFACTOR: get rid of this and similar methods
217     @Override
218     public boolean isInline() {
219       return true;
220     }
221 
222     @Override
223     @NonNull
224     public IAssemblyInstance getInlineInstance() {
225       return XmlInlineAssemblyDefinition.this;
226     }
227 
228     @Override
229     public String getFormalName() {
230       return XmlInlineAssemblyDefinition.this.getFormalName();
231     }
232 
233     @Override
234     public MarkupLine getDescription() {
235       return XmlInlineAssemblyDefinition.this.getDescription();
236     }
237 
238     @Override
239     public @NonNull Map<QName, Set<String>> getProperties() {
240       return XmlInlineAssemblyDefinition.this.getProperties();
241     }
242 
243     @Override
244     public ModuleScopeEnum getModuleScope() {
245       return ModuleScopeEnum.LOCAL;
246     }
247 
248     @Override
249     public String getName() {
250       return XmlInlineAssemblyDefinition.this.getName();
251     }
252 
253     @Override
254     public String getUseName() {
255       // always use the name instead
256       return null;
257     }
258 
259     @Override
260     public boolean isRoot() {
261       // a local assembly is never a root
262       return false;
263     }
264 
265     @Override
266     public String getRootName() {
267       // a local assembly is never a root
268       return null;
269     }
270 
271     @SuppressWarnings("null")
272     @Override
273     public XmlFlagContainerSupport getFlagContainer() {
274       return flagContainer.get();
275     }
276 
277     @SuppressWarnings("null")
278     @Override
279     public XmlModelContainerSupport getModelContainer() {
280       return modelContainer.get();
281     }
282 
283     @SuppressWarnings("null")
284     @Override
285     public IModelConstrained getConstraintSupport() {
286       return constraints.get();
287     }
288 
289     @Override
290     public MarkupMultiline getRemarks() {
291       return XmlInlineAssemblyDefinition.this.getRemarks();
292     }
293 
294     @Override
295     public IModule getContainingModule() {
296       return XmlInlineAssemblyDefinition.super.getContainingDefinition().getContainingModule();
297     }
298   }
299 }