From bf717b528d59ebee54ee508e598043494fbfa7a2 Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Fri, 3 May 2024 12:05:11 -0400 Subject: [PATCH] interim commit --- .../core/model/AbstractAssemblyInstance.java | 19 ++- .../core/model/AbstractFieldInstance.java | 19 ++- .../core/model/AbstractFlagInstance.java | 19 ++- .../model/AbstractInlineFlagDefinition.java | 4 +- .../IFeatureDefinitionReferenceInstance.java | 30 ---- .../IBoundContainerModelChoiceGroup.java | 5 +- .../databind/model/IBoundDefinitionModel.java | 3 +- .../databind/model/IBoundInstanceFlag.java | 4 +- .../databind/model/IBoundInstanceModel.java | 10 -- .../model/annotations/BoundAssembly.java | 11 -- .../model/annotations/BoundField.java | 10 -- .../databind/model/annotations/BoundFlag.java | 12 -- .../impl/AbstractBoundAnnotatedJavaField.java | 78 ---------- .../impl/AbstractBoundInstanceField.java | 144 ------------------ .../impl/AbstractBoundInstanceJavaField.java | 60 -------- .../AbstractBoundInstanceModelJavaField.java | 85 ----------- .../databind/model/impl/DefinitionField.java | 31 +++- ...FeatureBoundContainerModelChoiceGroup.java | 12 +- .../impl/IFeatureInstanceModelGroupAs.java | 10 ++ .../model/impl/InstanceFlagInline.java | 44 ++++-- .../impl/InstanceModelAssemblyComplex.java | 57 +++++-- .../model/impl/InstanceModelChoiceGroup.java | 64 ++++++-- .../model/impl/InstanceModelFieldComplex.java | 122 +++++++++++++-- .../model/impl/InstanceModelFieldScalar.java | 128 ++++++++++++++-- 24 files changed, 458 insertions(+), 523 deletions(-) delete mode 100644 databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundAnnotatedJavaField.java delete mode 100644 databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceField.java delete mode 100644 databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceJavaField.java delete mode 100644 databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceModelJavaField.java diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractAssemblyInstance.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractAssemblyInstance.java index 60c97e50f..640761284 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractAssemblyInstance.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractAssemblyInstance.java @@ -43,10 +43,27 @@ protected AbstractAssemblyInstance(@NonNull PARENT parent) { } @Override - public final DEFINITION getDefinition() { + public DEFINITION getDefinition() { // this should always be not null return ObjectUtils.asType(ObjectUtils.requireNonNull( getContainingModule() .getScopedAssemblyDefinitionByName(getReferencedDefinitionQName()))); } + + /** + * Generates a "coordinate" string for the assembly instance. + * + * @return the coordinate + */ + @SuppressWarnings("null") + @Override + public String toCoordinates() { + IDefinition definition = getDefinition(); + return String.format("assembly instance %s -> %s in module %s (@%d(%d)", + getXmlQName(), + definition.getDefinitionQName(), + getContainingDefinition().getContainingModule().getShortName(), + hashCode(), + definition.hashCode()); + } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractFieldInstance.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractFieldInstance.java index c45a9e188..630a336e4 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractFieldInstance.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractFieldInstance.java @@ -43,10 +43,27 @@ protected AbstractFieldInstance(@NonNull PARENT parent) { } @Override - public final DEFINITION getDefinition() { + public DEFINITION getDefinition() { // this should always be not null return ObjectUtils.asType(ObjectUtils.requireNonNull( getContainingModule() .getScopedFieldDefinitionByName(getReferencedDefinitionQName()))); } + + /** + * Generates a "coordinate" string for the assembly instance. + * + * @return the coordinate + */ + @SuppressWarnings("null") + @Override + public String toCoordinates() { + IDefinition definition = getDefinition(); + return String.format("field instance %s -> %s in module %s (@%d(%d)", + getXmlQName(), + definition.getDefinitionQName(), + getContainingDefinition().getContainingModule().getShortName(), + hashCode(), + definition.hashCode()); + } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractFlagInstance.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractFlagInstance.java index 155974f88..0a3307734 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractFlagInstance.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractFlagInstance.java @@ -50,7 +50,24 @@ public final DEFINITION getDefinition() { } @Override - public final IModelDefinition getContainingDefinition() { + public final PARENT getContainingDefinition() { return getParentContainer(); } + + /** + * Generates a "coordinate" string for the assembly instance. + * + * @return the coordinate + */ + @SuppressWarnings("null") + @Override + public String toCoordinates() { + IDefinition definition = getDefinition(); + return String.format("flag instance %s -> %s in module %s (@%d(%d)", + getXmlQName(), + definition.getDefinitionQName(), + getContainingDefinition().getContainingModule().getShortName(), + hashCode(), + definition.hashCode()); + } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractInlineFlagDefinition.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractInlineFlagDefinition.java index 6dddb75ee..927efc077 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractInlineFlagDefinition.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/AbstractInlineFlagDefinition.java @@ -39,7 +39,7 @@ public abstract class AbstractInlineFlagDefinition< IFeatureDefinitionInstanceInlined { protected AbstractInlineFlagDefinition(@NonNull PARENT parent) { - super(parent, name -> parent.getContainingModule().toModelQName(name)); + super(parent, name -> parent.getContainingModule().toFlagQName(name)); } @Override @@ -54,7 +54,7 @@ public final INSTANCE getInlineInstance() { } @Override - public IModelDefinition getContainingDefinition() { + public PARENT getContainingDefinition() { return getParentContainer(); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/IFeatureDefinitionReferenceInstance.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/IFeatureDefinitionReferenceInstance.java index 16e54f0ff..e4fc03b98 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/IFeatureDefinitionReferenceInstance.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/IFeatureDefinitionReferenceInstance.java @@ -28,8 +28,6 @@ import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; -import java.util.Locale; - import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; @@ -103,32 +101,4 @@ default Object getEffectiveDefaultValue() { } return retval; } - - /** - * Generates a "coordinate" string for the provided information element - * instance. - * - * A coordinate consists of the element's: - * - * - * @return the coordinate - */ - @SuppressWarnings("null") - @Override - default String toCoordinates() { - IDefinition definition = getDefinition(); - return String.format("%s-instance:%s:%s/%s@%d(%d)", - getModelType().toString().toLowerCase(Locale.ROOT), - getContainingDefinition().getContainingModule().getShortName(), - definition.getName(), - getName(), - hashCode(), - definition.hashCode()); - } } diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundContainerModelChoiceGroup.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundContainerModelChoiceGroup.java index 9f11998eb..c8523e9f1 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundContainerModelChoiceGroup.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundContainerModelChoiceGroup.java @@ -38,9 +38,8 @@ public interface IBoundContainerModelChoiceGroup extends IContainerModelGrouped { @Override - default Collection getModelInstances() { - return getNamedModelInstances(); - } + @NonNull + Collection getModelInstances(); @Override @NonNull diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundDefinitionModel.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundDefinitionModel.java index 59ca1ce3e..2afe9bf7b 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundDefinitionModel.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundDefinitionModel.java @@ -27,6 +27,7 @@ package gov.nist.secauto.metaschema.databind.model; import gov.nist.secauto.metaschema.core.model.IModelDefinition; +import gov.nist.secauto.metaschema.databind.model.info.IItemValueHandler; import java.util.Collection; @@ -37,7 +38,7 @@ */ // REFACTOR: rename to IBoundDefinitionModel public interface IBoundDefinitionModel - extends IBoundDefinition, IModelDefinition { + extends IBoundDefinition, IModelDefinition, IItemValueHandler { @Override IBoundInstanceModelNamed getInlineInstance(); diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundInstanceFlag.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundInstanceFlag.java index f04701ccf..617ddaf50 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundInstanceFlag.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundInstanceFlag.java @@ -114,9 +114,7 @@ default IBoundInstanceFlag getInstance() { */ @Override @NonNull - default IBoundInstanceFlag getDefinition() { - return this; - } + IBoundDefinitionFlag getDefinition(); @Override @NonNull diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundInstanceModel.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundInstanceModel.java index e8a3945b9..6ee165e49 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundInstanceModel.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/IBoundInstanceModel.java @@ -123,14 +123,4 @@ default Collection getItemValues(Object value) { default Object getValue(Object parent) { return IBoundInstance.super.getValue(parent); } - - /** - * {@inheritDoc} - *

- * Always bound to a field. - */ - @Override - default void setValue(Object parentObject, Object value) { - IBoundInstance.super.setValue(parentObject, value); - } } diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundAssembly.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundAssembly.java index 3e4cf04c8..a56ace9f1 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundAssembly.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundAssembly.java @@ -97,17 +97,6 @@ */ int useIndex() default Integer.MIN_VALUE; - /** - * The namespace to use for associated XML elements. - *

- * If the value is "##default", then element name is derived from the namespace - * provided in the package-info. - * - * @return the namespace - */ - @NonNull - String namespace() default ModelUtil.DEFAULT_STRING_VALUE; - /** * A non-negative number that indicates the minimum occurrence of the model * instance. diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundField.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundField.java index 21db7dfd4..26d43e7fa 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundField.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundField.java @@ -127,16 +127,6 @@ @NonNull String defaultValue() default ModelUtil.NULL_VALUE; - /** - * The namespace to use for associated XML elements. - *

- * If the value is "##default", then element name is derived from the namespace - * provided in the package-info. - * - * @return the namespace - */ - String namespace() default ModelUtil.DEFAULT_STRING_VALUE; - /** * If the data type allows it, determines if the field's value must be wrapped * with an XML element. diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundFlag.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundFlag.java index 061188c30..d7bcdc12f 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundFlag.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/annotations/BoundFlag.java @@ -89,18 +89,6 @@ */ int useIndex() default Integer.MIN_VALUE; - /** - * XML target namespace of the XML Schema element. - *

- * If the value is "##default", then namespace is derived from the namespace - * provided in the package-info. If the value is "##none", the namespace will be - * {@code null}. - * - * @return the namespace - */ - @NonNull - String namespace() default ModelUtil.NO_STRING_VALUE; - /** * The default value of the flag represented as a string. *

diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundAnnotatedJavaField.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundAnnotatedJavaField.java deleted file mode 100644 index b5a38f1da..000000000 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundAnnotatedJavaField.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Portions of this software was developed by employees of the National Institute - * of Standards and Technology (NIST), an agency of the Federal Government and is - * being made available as a public service. Pursuant to title 17 United States - * Code Section 105, works of NIST employees are not subject to copyright - * protection in the United States. This software may be subject to foreign - * copyright. Permission in the United States and in foreign countries, to the - * extent that NIST may hold copyright, to use, copy, modify, create derivative - * works, and distribute this software and its documentation without fee is hereby - * granted on a non-exclusive basis, provided that this notice and disclaimer - * of warranty appears in all copies. - * - * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER - * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY - * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM - * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE - * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT - * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, - * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, - * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, - * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR - * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT - * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. - */ - -package gov.nist.secauto.metaschema.databind.model.impl; - -import gov.nist.secauto.metaschema.databind.model.IFeatureJavaField; -import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; - -import edu.umd.cs.findbugs.annotations.NonNull; - -public abstract class AbstractBoundAnnotatedJavaField implements IFeatureJavaField { - @NonNull - private final Field javaField; - @NonNull - private final A annotation; - - /** - * Construct a new binding between a Java field and a binding Java annotation. - * - * @param javaField - * the bound Java field - * @param annotationClass - * the binding annotation Java class - */ - protected AbstractBoundAnnotatedJavaField( - @NonNull Field javaField, - @NonNull Class annotationClass) { - this.javaField = javaField; - this.annotation = ModelUtil.getAnnotation(javaField, annotationClass); - } - - /** - * Get the bound Java field. - * - * @return the bound Java field - */ - @Override - @NonNull - public Field getField() { - return javaField; - } - - /** - * Get the binding Java annotation. - * - * @return the binding Java annotation - */ - @NonNull - public A getAnnotation() { - return annotation; - } -} diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceField.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceField.java deleted file mode 100644 index 78d6fa2ff..000000000 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceField.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Portions of this software was developed by employees of the National Institute - * of Standards and Technology (NIST), an agency of the Federal Government and is - * being made available as a public service. Pursuant to title 17 United States - * Code Section 105, works of NIST employees are not subject to copyright - * protection in the United States. This software may be subject to foreign - * copyright. Permission in the United States and in foreign countries, to the - * extent that NIST may hold copyright, to use, copy, modify, create derivative - * works, and distribute this software and its documentation without fee is hereby - * granted on a non-exclusive basis, provided that this notice and disclaimer - * of warranty appears in all copies. - * - * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER - * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY - * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM - * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE - * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT - * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, - * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, - * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, - * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR - * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT - * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. - */ - -package gov.nist.secauto.metaschema.databind.model.impl; - -import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; -import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; -import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly; -import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelField; -import gov.nist.secauto.metaschema.databind.model.IGroupAs; -import gov.nist.secauto.metaschema.databind.model.annotations.BoundField; -import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; -import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil; - -import java.lang.reflect.Field; - -import javax.xml.namespace.QName; - -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -// TODO: implement getProperties() -public abstract class AbstractBoundInstanceField - extends AbstractBoundInstanceModelJavaField - implements IBoundInstanceModelField { - @NonNull - private final IGroupAs groupAs; - - /** - * Construct a new field instance bound to a Java field. - * - * @param javaField - * the Java field bound to this instance - * @param containingDefinition - * the definition containing this instance - */ - @SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", justification = "Use of final fields") - protected AbstractBoundInstanceField( - @NonNull Field javaField, - @NonNull IBoundDefinitionModelAssembly containingDefinition) { - super(javaField, BoundField.class, containingDefinition); - this.groupAs = ModelUtil.groupAs( - getAnnotation().groupAs(), - () -> containingDefinition.getXmlNamespace()); - if (getMaxOccurs() == -1 || getMaxOccurs() > 1) { - if (IGroupAs.SINGLETON_GROUP_AS.equals(this.groupAs)) { - throw new IllegalStateException(String.format("Field '%s' on class '%s' is missing the '%s' annotation.", - javaField.getName(), - javaField.getDeclaringClass().getName(), - GroupAs.class.getName())); // NOPMD false positive - } - } else if (!IGroupAs.SINGLETON_GROUP_AS.equals(this.groupAs)) { - // max is 1 and a groupAs is set - throw new IllegalStateException( - String.format( - "Field '%s' on class '%s' has the '%s' annotation, but maxOccurs=1. A groupAs must not be specfied.", - javaField.getName(), - javaField.getDeclaringClass().getName(), - GroupAs.class.getName())); // NOPMD false positive - } - } - - // ------------------------------------------ - // - Start annotation driven code - CPD-OFF - - // ------------------------------------------ - - @Override - public IGroupAs getGroupAs() { - return groupAs; - } - - @Override - public String getFormalName() { - return ModelUtil.resolveNoneOrValue(getAnnotation().formalName()); - } - - @Override - public MarkupLine getDescription() { - return ModelUtil.resolveToMarkupLine(getAnnotation().description()); - } - - @Override - public Integer getUseIndex() { - int value = getAnnotation().useIndex(); - return value == Integer.MIN_VALUE ? null : value; - } - - @Override - public QName getXmlQName() { - return getContainingModule().toModelQName( - ModelUtil.resolveOptionalNamespace( - getAnnotation().namespace(), - () -> null), - getEffectiveName()); - } - - @Override - public boolean isInXmlWrapped() { - return getAnnotation().inXmlWrapped(); - } - - @Override - public final int getMinOccurs() { - return getAnnotation().minOccurs(); - } - - @Override - public final int getMaxOccurs() { - return getAnnotation().maxOccurs(); - } - - @Override - public MarkupMultiline getRemarks() { - return ModelUtil.resolveToMarkupMultiline(getAnnotation().remarks()); - } - - // @Override - // public String getJsonKeyFlagName() { - // return IBoundInstanceModelField.super.getJsonKeyFlagName(); - // } -} diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceJavaField.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceJavaField.java deleted file mode 100644 index 0778d737a..000000000 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceJavaField.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Portions of this software was developed by employees of the National Institute - * of Standards and Technology (NIST), an agency of the Federal Government and is - * being made available as a public service. Pursuant to title 17 United States - * Code Section 105, works of NIST employees are not subject to copyright - * protection in the United States. This software may be subject to foreign - * copyright. Permission in the United States and in foreign countries, to the - * extent that NIST may hold copyright, to use, copy, modify, create derivative - * works, and distribute this software and its documentation without fee is hereby - * granted on a non-exclusive basis, provided that this notice and disclaimer - * of warranty appears in all copies. - * - * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER - * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY - * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM - * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE - * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT - * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, - * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, - * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, - * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR - * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT - * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. - */ - -package gov.nist.secauto.metaschema.databind.model.impl; - -import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModel; -import gov.nist.secauto.metaschema.databind.model.IBoundInstance; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; - -import edu.umd.cs.findbugs.annotations.NonNull; - -public abstract class AbstractBoundInstanceJavaField - extends AbstractBoundAnnotatedJavaField - implements IBoundInstance { - @NonNull - private final P containingDefinition; - - protected AbstractBoundInstanceJavaField( - @NonNull Field javaField, - @NonNull Class annotationClass, - @NonNull P containingDefinition) { - super(javaField, annotationClass); - this.containingDefinition = containingDefinition; - } - - @Override - public P getContainingDefinition() { - return containingDefinition; - } - - @Override - public P getParentContainer() { - return containingDefinition; - } -} diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceModelJavaField.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceModelJavaField.java deleted file mode 100644 index f3b639c9a..000000000 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundInstanceModelJavaField.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Portions of this software was developed by employees of the National Institute - * of Standards and Technology (NIST), an agency of the Federal Government and is - * being made available as a public service. Pursuant to title 17 United States - * Code Section 105, works of NIST employees are not subject to copyright - * protection in the United States. This software may be subject to foreign - * copyright. Permission in the United States and in foreign countries, to the - * extent that NIST may hold copyright, to use, copy, modify, create derivative - * works, and distribute this software and its documentation without fee is hereby - * granted on a non-exclusive basis, provided that this notice and disclaimer - * of warranty appears in all copies. - * - * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER - * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY - * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM - * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE - * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT - * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, - * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, - * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, - * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR - * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT - * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. - */ - -package gov.nist.secauto.metaschema.databind.model.impl; - -import gov.nist.secauto.metaschema.core.util.ObjectUtils; -import gov.nist.secauto.metaschema.databind.io.BindingException; -import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly; -import gov.nist.secauto.metaschema.databind.model.info.IModelInstanceCollectionInfo; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; - -import edu.umd.cs.findbugs.annotations.NonNull; -import nl.talsmasoftware.lazy4j.Lazy; - -public abstract class AbstractBoundInstanceModelJavaField - extends AbstractBoundInstanceJavaField - implements IFeatureInstanceModelGroupAs { - - @NonNull - private final Lazy collectionInfo; - - public AbstractBoundInstanceModelJavaField( - @NonNull Field javaField, - @NonNull Class annotationClass, - @NonNull IBoundDefinitionModelAssembly containingDefinition) { - super(javaField, annotationClass, containingDefinition); - this.collectionInfo = ObjectUtils.notNull(Lazy.lazy(() -> IModelInstanceCollectionInfo.of(this))); - } - - /** - * Gets information about the bound property. - * - * @return the collection information for the bound property - */ - @SuppressWarnings("null") - @Override - @NonNull - public IModelInstanceCollectionInfo getCollectionInfo() { - return collectionInfo.get(); - } - // - // @Override - // public Object getValue(Object parent) { - // return IFeatureInstanceModelGroupAs.super.getValue(parent); - // } - - @Override - public void setValue(Object parentObject, Object value) { - IFeatureInstanceModelGroupAs.super.setValue(parentObject, value); - } - - @Override - public void deepCopy(@NonNull Object fromInstance, @NonNull Object toInstance) throws BindingException { - Object value = getValue(fromInstance); - if (value != null) { - value = getCollectionInfo().deepCopyItems(fromInstance, toInstance); - } - setValue(toInstance, value); - } -} diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/DefinitionField.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/DefinitionField.java index 63290376b..ed8dfb849 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/DefinitionField.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/DefinitionField.java @@ -118,7 +118,7 @@ public static DefinitionField newInstance( * the Metaschema binding context managing this class */ @SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", justification = "Use of final fields, except JSON key") - public DefinitionField( + private DefinitionField( @NonNull Class clazz, @NonNull MetaschemaField annotation, @NonNull Class moduleClass, @@ -232,9 +232,12 @@ public MarkupMultiline getRemarks() { } protected class FieldValue - extends AbstractBoundAnnotatedJavaField implements IBoundFieldValue { @NonNull + private final Field javaField; + @NonNull + private final BoundFieldValue annotation; + @NonNull private final IDataTypeAdapter javaTypeAdapter; @Nullable private final Object defaultValue; @@ -250,13 +253,35 @@ protected class FieldValue protected FieldValue( @NonNull Field javaField, @NonNull Class annotationClass) { - super(javaField, annotationClass); + this.javaField = javaField; + this.annotation = ModelUtil.getAnnotation(javaField, annotationClass); this.javaTypeAdapter = ModelUtil.getDataTypeAdapter( getAnnotation().typeAdapter(), getBindingContext()); this.defaultValue = ModelUtil.resolveNullOrValue(getAnnotation().defaultValue(), this.javaTypeAdapter); } + /** + * Get the bound Java field. + * + * @return the bound Java field + */ + @Override + @NonNull + public Field getField() { + return javaField; + } + + /** + * Get the binding Java annotation. + * + * @return the binding Java annotation + */ + @NonNull + public BoundFieldValue getAnnotation() { + return annotation; + } + @Override public IBoundDefinitionModelFieldComplex getParentFieldDefinition() { return DefinitionField.this; diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/IFeatureBoundContainerModelChoiceGroup.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/IFeatureBoundContainerModelChoiceGroup.java index a06db00b2..a707fa3a9 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/IFeatureBoundContainerModelChoiceGroup.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/IFeatureBoundContainerModelChoiceGroup.java @@ -27,6 +27,7 @@ package gov.nist.secauto.metaschema.databind.model.impl; import gov.nist.secauto.metaschema.core.model.IContainerModelSupport; +import gov.nist.secauto.metaschema.core.model.IFeatureContainerModelGrouped; import gov.nist.secauto.metaschema.databind.model.IBoundContainerModelChoiceGroup; import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelGroupedAssembly; import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelGroupedField; @@ -39,8 +40,12 @@ import edu.umd.cs.findbugs.annotations.NonNull; public interface IFeatureBoundContainerModelChoiceGroup - extends IBoundContainerModelChoiceGroup { + extends IBoundContainerModelChoiceGroup, IFeatureContainerModelGrouped< + IBoundInstanceModelGroupedNamed, + IBoundInstanceModelGroupedField, + IBoundInstanceModelGroupedAssembly> { + @Override @NonNull IContainerModelSupport< IBoundInstanceModelGroupedNamed, @@ -48,6 +53,11 @@ public interface IFeatureBoundContainerModelChoiceGroup IBoundInstanceModelGroupedField, IBoundInstanceModelGroupedAssembly> getModelContainer(); + @Override + default Collection getModelInstances() { + return getModelContainer().getModelInstances(); + } + @Override default IBoundInstanceModelGroupedNamed getNamedModelInstanceByName(QName name) { return getModelContainer().getNamedModelInstanceMap().get(name); diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/IFeatureInstanceModelGroupAs.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/IFeatureInstanceModelGroupAs.java index 1b41acae5..cc2ee1b59 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/IFeatureInstanceModelGroupAs.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/IFeatureInstanceModelGroupAs.java @@ -28,6 +28,7 @@ import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior; import gov.nist.secauto.metaschema.core.model.XmlGroupAsBehavior; +import gov.nist.secauto.metaschema.databind.io.BindingException; import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModel; import gov.nist.secauto.metaschema.databind.model.IGroupAs; @@ -56,4 +57,13 @@ default JsonGroupAsBehavior getJsonGroupAsBehavior() { default XmlGroupAsBehavior getXmlGroupAsBehavior() { return getGroupAs().getXmlGroupAsBehavior(); } + + @Override + default void deepCopy(@NonNull Object fromInstance, @NonNull Object toInstance) throws BindingException { + Object value = getValue(fromInstance); + if (value != null) { + value = getCollectionInfo().deepCopyItems(fromInstance, toInstance); + } + setValue(toInstance, value); + } } diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceFlagInline.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceFlagInline.java index 733676fbc..a81b180e2 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceFlagInline.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceFlagInline.java @@ -29,11 +29,13 @@ import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; +import gov.nist.secauto.metaschema.core.model.AbstractInlineFlagDefinition; import gov.nist.secauto.metaschema.core.model.constraint.ISource; import gov.nist.secauto.metaschema.core.model.constraint.IValueConstrained; import gov.nist.secauto.metaschema.core.model.constraint.ValueConstraintSet; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import gov.nist.secauto.metaschema.databind.IBindingContext; +import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionFlag; import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModel; import gov.nist.secauto.metaschema.databind.model.IBoundInstanceFlag; import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag; @@ -45,8 +47,6 @@ import java.lang.reflect.Field; import java.util.Optional; -import javax.xml.namespace.QName; - import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import nl.talsmasoftware.lazy4j.Lazy; @@ -57,9 +57,14 @@ */ // TODO: implement getProperties() public class InstanceFlagInline - extends AbstractBoundInstanceJavaField + extends AbstractInlineFlagDefinition + // extends AbstractBoundInstanceJavaField implements IBoundInstanceFlag { @NonNull + private final Field javaField; + @NonNull + private final BoundFlag annotation; + @NonNull private final IDataTypeAdapter javaTypeAdapter; @Nullable private final Object defaultValue; @@ -77,7 +82,9 @@ public class InstanceFlagInline public InstanceFlagInline( @NonNull Field javaField, @NonNull IBoundDefinitionModel containingDefinition) { - super(javaField, BoundFlag.class, containingDefinition); + super(containingDefinition); + this.javaField = javaField; + this.annotation = ModelUtil.getAnnotation(javaField, BoundFlag.class); Class> adapterClass = ObjectUtils.notNull(getAnnotation().typeAdapter()); this.javaTypeAdapter = ModelUtil.getDataTypeAdapter( adapterClass, @@ -92,6 +99,26 @@ public InstanceFlagInline( })); } + /** + * Get the bound Java field. + * + * @return the bound Java field + */ + @Override + @NonNull + public Field getField() { + return javaField; + } + + /** + * Get the binding Java annotation. + * + * @return the binding Java annotation + */ + @NonNull + public BoundFlag getAnnotation() { + return annotation; + } // ------------------------------------------ // - Start annotation driven code - CPD-OFF - // ------------------------------------------ @@ -151,15 +178,6 @@ public Integer getUseIndex() { return getAnnotation().useIndex(); } - @Override - public QName getXmlQName() { - return getContainingModule().toFlagQName( - ModelUtil.resolveOptionalNamespace( - getAnnotation().namespace(), - () -> null), - getEffectiveName()); - } - @Override @Nullable public MarkupMultiline getRemarks() { diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelAssemblyComplex.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelAssemblyComplex.java index 09019b9dc..3e76320f9 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelAssemblyComplex.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelAssemblyComplex.java @@ -28,7 +28,7 @@ import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; -import gov.nist.secauto.metaschema.core.model.IFeatureDefinitionReferenceInstance; +import gov.nist.secauto.metaschema.core.model.AbstractAssemblyInstance; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly; import gov.nist.secauto.metaschema.databind.model.IBoundInstanceFlag; @@ -38,6 +38,7 @@ import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly; import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil; +import gov.nist.secauto.metaschema.databind.model.info.IModelInstanceCollectionInfo; import java.lang.reflect.Field; import java.util.Map; @@ -53,9 +54,18 @@ */ // TODO: implement getProperties() public class InstanceModelAssemblyComplex - extends AbstractBoundInstanceModelJavaField - implements IBoundInstanceModelAssembly, - IFeatureDefinitionReferenceInstance { + extends AbstractAssemblyInstance< + IBoundDefinitionModelAssembly, + IBoundDefinitionModelAssembly, + IBoundInstanceModelAssembly, + IBoundDefinitionModelAssembly> + implements IBoundInstanceModelAssembly, IFeatureInstanceModelGroupAs { + @NonNull + private final Field javaField; + @NonNull + private final BoundAssembly annotation; + @NonNull + private final Lazy collectionInfo; @NonNull private final IBoundDefinitionModelAssembly definition; @NonNull @@ -79,11 +89,12 @@ public InstanceModelAssemblyComplex( @NonNull Field javaField, @NonNull IBoundDefinitionModelAssembly definition, @NonNull IBoundDefinitionModelAssembly containingDefinition) { - super(javaField, BoundAssembly.class, containingDefinition); + super(containingDefinition); + this.javaField = javaField; + this.annotation = ModelUtil.getAnnotation(javaField, BoundAssembly.class); + this.collectionInfo = ObjectUtils.notNull(Lazy.lazy(() -> IModelInstanceCollectionInfo.of(this))); this.definition = definition; - this.groupAs = ModelUtil.groupAs( - getAnnotation().groupAs(), - () -> containingDefinition.getXmlNamespace()); + this.groupAs = ModelUtil.groupAs(this.annotation.groupAs(), () -> containingDefinition.getXmlNamespace()); if (getMaxOccurs() == -1 || getMaxOccurs() > 1) { if (IGroupAs.SINGLETON_GROUP_AS.equals(this.groupAs)) { throw new IllegalStateException(String.format("Field '%s' on class '%s' is missing the '%s' annotation.", @@ -102,11 +113,32 @@ public InstanceModelAssemblyComplex( } this.jsonProperties = ObjectUtils.notNull(Lazy.lazy(() -> { IBoundInstanceFlag jsonKey = getEffectiveJsonKey(); - Predicate flagFilter = jsonKey == null ? null : (flag) -> !jsonKey.equals(flag); + Predicate flagFilter = jsonKey == null ? null : flag -> !jsonKey.equals(flag); return getDefinition().getJsonProperties(flagFilter); })); } + @Override + public Field getField() { + return javaField; + } + + /** + * Get the binding Java annotation. + * + * @return the binding Java annotation + */ + @NonNull + public BoundAssembly getAnnotation() { + return annotation; + } + + @SuppressWarnings("null") + @Override + public IModelInstanceCollectionInfo getCollectionInfo() { + return collectionInfo.get(); + } + // ------------------------------------------ // - Start annotation driven code - CPD-OFF - // ------------------------------------------ @@ -147,13 +179,6 @@ public Integer getUseIndex() { return value == Integer.MIN_VALUE ? null : value; } - @Override - public String getXmlNamespace() { - return ModelUtil.resolveOptionalNamespace( - getAnnotation().namespace(), - () -> getContainingDefinition().getXmlNamespace()); - } - @Override public final int getMinOccurs() { return getAnnotation().minOccurs(); diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelChoiceGroup.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelChoiceGroup.java index 685e143b5..ea681689a 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelChoiceGroup.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelChoiceGroup.java @@ -26,6 +26,7 @@ package gov.nist.secauto.metaschema.databind.model.impl; +import gov.nist.secauto.metaschema.core.model.AbstractChoiceGroupInstance; import gov.nist.secauto.metaschema.core.model.IContainerModelSupport; import gov.nist.secauto.metaschema.core.util.CollectionUtil; import gov.nist.secauto.metaschema.core.util.CustomCollectors; @@ -42,6 +43,7 @@ import gov.nist.secauto.metaschema.databind.model.annotations.BoundGroupedField; import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil; +import gov.nist.secauto.metaschema.databind.model.info.IModelInstanceCollectionInfo; import java.lang.reflect.Field; import java.util.Arrays; @@ -49,6 +51,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -64,9 +67,20 @@ * Implements a Metaschema module choice group instance bound to a Java field. */ public class InstanceModelChoiceGroup - extends AbstractBoundInstanceModelJavaField + extends AbstractChoiceGroupInstance< + IBoundDefinitionModelAssembly, + IBoundInstanceModelGroupedNamed, + IBoundInstanceModelGroupedField, + IBoundInstanceModelGroupedAssembly> + // extends AbstractBoundInstanceModelJavaField implements IBoundInstanceModelChoiceGroup, - IFeatureBoundContainerModelChoiceGroup { + IFeatureBoundContainerModelChoiceGroup, IFeatureInstanceModelGroupAs { + @NonNull + private final Field javaField; + @NonNull + private final BoundChoiceGroup annotation; + @NonNull + private final Lazy collectionInfo; @NonNull private final IGroupAs groupAs; @NonNull @@ -90,10 +104,11 @@ public class InstanceModelChoiceGroup public InstanceModelChoiceGroup( @NonNull Field javaField, @NonNull IBoundDefinitionModelAssembly containingDefinition) { - super(javaField, BoundChoiceGroup.class, containingDefinition); - this.groupAs = ModelUtil.groupAs( - getAnnotation().groupAs(), - () -> containingDefinition.getXmlNamespace()); + super(containingDefinition); + this.javaField = javaField; + this.annotation = ModelUtil.getAnnotation(javaField, BoundChoiceGroup.class); + this.collectionInfo = ObjectUtils.notNull(Lazy.lazy(() -> IModelInstanceCollectionInfo.of(this))); + this.groupAs = ModelUtil.groupAs(this.annotation.groupAs(), () -> containingDefinition.getXmlNamespace()); if (getMaxOccurs() == -1 || getMaxOccurs() > 1) { if (IGroupAs.SINGLETON_GROUP_AS.equals(this.groupAs)) { throw new IllegalStateException(String.format("Field '%s' on class '%s' is missing the '%s' annotation.", @@ -111,8 +126,8 @@ public InstanceModelChoiceGroup( GroupAs.class.getName())); } this.modelContainer = ObjectUtils.notNull(Lazy.lazy(() -> new ChoiceGroupModelContainerSupport( - getAnnotation().assemblies(), - getAnnotation().fields(), + this.annotation.assemblies(), + this.annotation.fields(), this))); this.classToInstanceMap = ObjectUtils.notNull(Lazy.lazy(() -> Collections.unmodifiableMap( getNamedModelInstances().stream() @@ -123,15 +138,36 @@ public InstanceModelChoiceGroup( this.qnameToInstanceMap = ObjectUtils.notNull(Lazy.lazy(() -> Collections.unmodifiableMap( getNamedModelInstances().stream() .collect(Collectors.toMap( - item -> item.getXmlQName(), + IBoundInstanceModelGroupedNamed::getXmlQName, CustomCollectors.identity()))))); this.discriminatorToInstanceMap = ObjectUtils.notNull(Lazy.lazy(() -> Collections.unmodifiableMap( getNamedModelInstances().stream() .collect(Collectors.toMap( - item -> item.getEffectiveDisciminatorValue(), + IBoundInstanceModelGroupedNamed::getEffectiveDisciminatorValue, CustomCollectors.identity()))))); } + @Override + public Field getField() { + return javaField; + } + + /** + * Get the binding Java annotation. + * + * @return the binding Java annotation + */ + @NonNull + public BoundChoiceGroup getAnnotation() { + return annotation; + } + + @SuppressWarnings("null") + @Override + public IModelInstanceCollectionInfo getCollectionInfo() { + return collectionInfo.get(); + } + // ------------------------------------------ // - Start annotation driven code - CPD-OFF - // ------------------------------------------ @@ -264,7 +300,7 @@ public ChoiceGroupModelContainerSupport( container); }) .collect(Collectors.toMap( - instance -> instance.getXmlQName(), + IBoundInstanceModelGroupedAssembly::getXmlQName, Function.identity(), CustomCollectors.useLastMapper(), LinkedHashMap::new)))); @@ -274,7 +310,7 @@ public ChoiceGroupModelContainerSupport( return IBoundInstanceModelGroupedField.newInstance(instance, container); }) .collect(Collectors.toMap( - instance -> instance.getXmlQName(), + IBoundInstanceModelGroupedField::getXmlQName, Function.identity(), CustomCollectors.useLastMapper(), LinkedHashMap::new)))); @@ -282,8 +318,8 @@ public ChoiceGroupModelContainerSupport( this.assemblyInstances.entrySet().stream(), this.fieldInstances.entrySet().stream()) .collect(Collectors.toMap( - entry -> entry.getKey(), - entry -> entry.getValue(), + Entry::getKey, + Entry::getValue, CustomCollectors.useLastMapper(), LinkedHashMap::new)))); } diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelFieldComplex.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelFieldComplex.java index b8c3b701b..c273f709f 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelFieldComplex.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelFieldComplex.java @@ -26,7 +26,9 @@ package gov.nist.secauto.metaschema.databind.model.impl; -import gov.nist.secauto.metaschema.core.model.IFeatureDefinitionReferenceInstance; +import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; +import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; +import gov.nist.secauto.metaschema.core.model.AbstractFieldInstance; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly; import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelFieldComplex; @@ -34,7 +36,11 @@ import gov.nist.secauto.metaschema.databind.model.IBoundInstanceFlag; import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelFieldComplex; import gov.nist.secauto.metaschema.databind.model.IBoundProperty; +import gov.nist.secauto.metaschema.databind.model.IGroupAs; +import gov.nist.secauto.metaschema.databind.model.annotations.BoundField; +import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil; +import gov.nist.secauto.metaschema.databind.model.info.IModelInstanceCollectionInfo; import java.lang.reflect.Field; import java.util.Map; @@ -49,9 +55,20 @@ * supported by a bound definition class. */ public class InstanceModelFieldComplex - extends AbstractBoundInstanceField - implements IBoundInstanceModelFieldComplex, - IFeatureDefinitionReferenceInstance { + extends AbstractFieldInstance< + IBoundDefinitionModelAssembly, + IBoundDefinitionModelFieldComplex, + IBoundInstanceModelFieldComplex, + IBoundDefinitionModelAssembly> + implements IBoundInstanceModelFieldComplex, IFeatureInstanceModelGroupAs { + @NonNull + private final Field javaField; + @NonNull + private final BoundField annotation; + @NonNull + private final Lazy collectionInfo; + @NonNull + private final IGroupAs groupAs; @NonNull private final DefinitionField definition; @NonNull @@ -75,7 +92,29 @@ public InstanceModelFieldComplex( @NonNull Field javaField, @NonNull DefinitionField definition, @NonNull IBoundDefinitionModelAssembly containingDefinition) { - super(javaField, containingDefinition); + super(containingDefinition); + this.javaField = javaField; + this.annotation = ModelUtil.getAnnotation(javaField, BoundField.class); + this.collectionInfo = ObjectUtils.notNull(Lazy.lazy(() -> IModelInstanceCollectionInfo.of(this))); + this.groupAs = ModelUtil.groupAs( + this.annotation.groupAs(), + () -> containingDefinition.getXmlNamespace()); + if (getMaxOccurs() == -1 || getMaxOccurs() > 1) { + if (IGroupAs.SINGLETON_GROUP_AS.equals(this.groupAs)) { + throw new IllegalStateException(String.format("Field '%s' on class '%s' is missing the '%s' annotation.", + javaField.getName(), + javaField.getDeclaringClass().getName(), + GroupAs.class.getName())); // NOPMD false positive + } + } else if (!IGroupAs.SINGLETON_GROUP_AS.equals(this.groupAs)) { + // max is 1 and a groupAs is set + throw new IllegalStateException( + String.format( + "Field '%s' on class '%s' has the '%s' annotation, but maxOccurs=1. A groupAs must not be specfied.", + javaField.getName(), + javaField.getDeclaringClass().getName(), + GroupAs.class.getName())); // NOPMD false positive + } this.definition = definition; if (!isEffectiveValueWrappedInXml()) { @@ -84,7 +123,8 @@ public InstanceModelFieldComplex( String.format("Field '%s' on class '%s' is requested to be unwrapped, but it has flags preventing this.", javaField.getName(), containingDefinition.getBoundClass().getName())); - } else if (!getDefinition().getJavaTypeAdapter().isUnrappedValueAllowedInXml()) { + } + if (!getDefinition().getJavaTypeAdapter().isUnrappedValueAllowedInXml()) { throw new IllegalStateException( String.format( "Field '%s' on class '%s' is requested to be unwrapped, but its data type '%s' does not allow this.", @@ -117,15 +157,32 @@ public InstanceModelFieldComplex( Predicate flagFilter = null; IBoundInstanceFlag jsonKey = getEffectiveJsonKey(); if (jsonKey != null) { - flagFilter = (flag) -> !jsonKey.equals(flag); + flagFilter = flag -> !jsonKey.equals(flag); } return getDefinition().getJsonProperties(flagFilter); })); } - // ------------------------------------------ - // - Start annotation driven code - CPD-OFF - - // ------------------------------------------ + @Override + public Field getField() { + return javaField; + } + + /** + * Get the binding Java annotation. + * + * @return the binding Java annotation + */ + @NonNull + public BoundField getAnnotation() { + return annotation; + } + + @SuppressWarnings("null") + @Override + public IModelInstanceCollectionInfo getCollectionInfo() { + return collectionInfo.get(); + } @Override public final DefinitionField getDefinition() { @@ -142,8 +199,53 @@ public Map getJsonProperties() { return ObjectUtils.notNull(jsonProperties.get()); } + // ------------------------------------------ + // - Start annotation driven code - CPD-OFF - + // ------------------------------------------ + + @Override + public IGroupAs getGroupAs() { + return groupAs; + } + + @Override + public String getFormalName() { + return ModelUtil.resolveNoneOrValue(getAnnotation().formalName()); + } + + @Override + public MarkupLine getDescription() { + return ModelUtil.resolveToMarkupLine(getAnnotation().description()); + } + @Override public String getUseName() { return ModelUtil.resolveNoneOrValue(getAnnotation().useName()); } + + @Override + public Integer getUseIndex() { + int value = getAnnotation().useIndex(); + return value == Integer.MIN_VALUE ? null : value; + } + + @Override + public boolean isInXmlWrapped() { + return getAnnotation().inXmlWrapped(); + } + + @Override + public final int getMinOccurs() { + return getAnnotation().minOccurs(); + } + + @Override + public final int getMaxOccurs() { + return getAnnotation().maxOccurs(); + } + + @Override + public MarkupMultiline getRemarks() { + return ModelUtil.resolveToMarkupMultiline(getAnnotation().remarks()); + } } diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelFieldScalar.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelFieldScalar.java index b5b480f33..08e56758b 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelFieldScalar.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/InstanceModelFieldScalar.java @@ -27,14 +27,21 @@ package gov.nist.secauto.metaschema.databind.model.impl; import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter; +import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; +import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; +import gov.nist.secauto.metaschema.core.model.AbstractNamedModelInstance; import gov.nist.secauto.metaschema.core.model.constraint.ISource; import gov.nist.secauto.metaschema.core.model.constraint.IValueConstrained; import gov.nist.secauto.metaschema.core.model.constraint.ValueConstraintSet; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly; import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelFieldScalar; +import gov.nist.secauto.metaschema.databind.model.IGroupAs; +import gov.nist.secauto.metaschema.databind.model.annotations.BoundField; +import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil; import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints; +import gov.nist.secauto.metaschema.databind.model.info.IModelInstanceCollectionInfo; import java.lang.reflect.Field; import java.util.Optional; @@ -44,8 +51,16 @@ import nl.talsmasoftware.lazy4j.Lazy; public class InstanceModelFieldScalar - extends AbstractBoundInstanceField - implements IBoundInstanceModelFieldScalar { + extends AbstractNamedModelInstance + implements IBoundInstanceModelFieldScalar, IFeatureInstanceModelGroupAs { + @NonNull + private final Field javaField; + @NonNull + private final BoundField annotation; + @NonNull + private final Lazy collectionInfo; + @NonNull + private final IGroupAs groupAs; @NonNull private final IDataTypeAdapter javaTypeAdapter; @Nullable @@ -64,23 +79,63 @@ public class InstanceModelFieldScalar public InstanceModelFieldScalar( @NonNull Field javaField, @NonNull IBoundDefinitionModelAssembly containingDefinition) { - super(javaField, containingDefinition); + super(containingDefinition); + this.javaField = javaField; + this.annotation = ModelUtil.getAnnotation(javaField, BoundField.class); + this.collectionInfo = ObjectUtils.notNull(Lazy.lazy(() -> IModelInstanceCollectionInfo.of(this))); + this.groupAs = ModelUtil.groupAs( + this.annotation.groupAs(), + () -> containingDefinition.getXmlNamespace()); + if (getMaxOccurs() == -1 || getMaxOccurs() > 1) { + if (IGroupAs.SINGLETON_GROUP_AS.equals(this.groupAs)) { + throw new IllegalStateException(String.format("Field '%s' on class '%s' is missing the '%s' annotation.", + javaField.getName(), + javaField.getDeclaringClass().getName(), + GroupAs.class.getName())); // NOPMD false positive + } + } else if (!IGroupAs.SINGLETON_GROUP_AS.equals(this.groupAs)) { + // max is 1 and a groupAs is set + throw new IllegalStateException( + String.format( + "Field '%s' on class '%s' has the '%s' annotation, but maxOccurs=1. A groupAs must not be specfied.", + javaField.getName(), + javaField.getDeclaringClass().getName(), + GroupAs.class.getName())); // NOPMD false positive + } + this.javaTypeAdapter = ModelUtil.getDataTypeAdapter( - getAnnotation().typeAdapter(), + this.annotation.typeAdapter(), containingDefinition.getBindingContext()); - this.defaultValue = ModelUtil.resolveDefaultValue(getAnnotation().defaultValue(), this.javaTypeAdapter); + this.defaultValue = ModelUtil.resolveDefaultValue(this.annotation.defaultValue(), this.javaTypeAdapter); this.constraints = ObjectUtils.notNull(Lazy.lazy(() -> { IValueConstrained retval = new ValueConstraintSet(); - ValueConstraints valueAnnotation = getAnnotation().valueConstraints(); + ValueConstraints valueAnnotation = this.annotation.valueConstraints(); ConstraintSupport.parse(valueAnnotation, ISource.modelSource(), retval); return retval; })); } - // ------------------------------------------ - // - Start annotation driven code - CPD-OFF - - // ------------------------------------------ + @Override + public Field getField() { + return javaField; + } + + /** + * Get the binding Java annotation. + * + * @return the binding Java annotation + */ + @NonNull + public BoundField getAnnotation() { + return annotation; + } + + @SuppressWarnings("null") + @Override + public IModelInstanceCollectionInfo getCollectionInfo() { + return collectionInfo.get(); + } @SuppressWarnings("null") @Override @@ -94,6 +149,56 @@ public IDataTypeAdapter getJavaTypeAdapter() { return javaTypeAdapter; } + @Override + public Object getDefaultValue() { + return defaultValue; + } + + // ------------------------------------------ + // - Start annotation driven code - CPD-OFF - + // ------------------------------------------ + + @Override + public IGroupAs getGroupAs() { + return groupAs; + } + + @Override + public String getFormalName() { + return ModelUtil.resolveNoneOrValue(getAnnotation().formalName()); + } + + @Override + public MarkupLine getDescription() { + return ModelUtil.resolveToMarkupLine(getAnnotation().description()); + } + + @Override + public Integer getUseIndex() { + int value = getAnnotation().useIndex(); + return value == Integer.MIN_VALUE ? null : value; + } + + @Override + public boolean isInXmlWrapped() { + return getAnnotation().inXmlWrapped(); + } + + @Override + public final int getMinOccurs() { + return getAnnotation().minOccurs(); + } + + @Override + public final int getMaxOccurs() { + return getAnnotation().maxOccurs(); + } + + @Override + public MarkupMultiline getRemarks() { + return ModelUtil.resolveToMarkupMultiline(getAnnotation().remarks()); + } + @Override public String getName() { // the name is stored as a usename to remain consistent with non-scalar valued @@ -102,11 +207,6 @@ public String getName() { Optional.ofNullable(ModelUtil.resolveNoneOrValue(getAnnotation().useName())).orElse(getField().getName())); } - @Override - public Object getDefaultValue() { - return defaultValue; - } - // ---------------------------------------- // - End annotation driven code - CPD-OFF - // ----------------------------------------