XmlChoiceGroupInstance.java
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/
package gov.nist.secauto.metaschema.core.model.xml.impl;
import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
import gov.nist.secauto.metaschema.core.model.AbstractChoiceGroupInstance;
import gov.nist.secauto.metaschema.core.model.IAssemblyDefinition;
import gov.nist.secauto.metaschema.core.model.IAssemblyInstanceGrouped;
import gov.nist.secauto.metaschema.core.model.IChoiceGroupInstance;
import gov.nist.secauto.metaschema.core.model.IFieldInstanceGrouped;
import gov.nist.secauto.metaschema.core.model.INamedModelInstanceGrouped;
import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior;
import gov.nist.secauto.metaschema.core.model.XmlGroupAsBehavior;
import gov.nist.secauto.metaschema.core.model.xml.XmlModuleConstants;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GroupedAssemblyReferenceType;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GroupedChoiceType;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GroupedFieldReferenceType;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GroupedInlineAssemblyDefinitionType;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GroupedInlineFieldDefinitionType;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import java.util.Map;
import javax.xml.namespace.QName;
import edu.umd.cs.findbugs.annotations.NonNull;
import nl.talsmasoftware.lazy4j.Lazy;
class XmlChoiceGroupInstance
extends AbstractChoiceGroupInstance<
IAssemblyDefinition,
INamedModelInstanceGrouped,
IFieldInstanceGrouped,
IAssemblyInstanceGrouped> {
@NonNull
private final GroupedChoiceType xmlObject;
@NonNull
private final Lazy<XmlModelContainer> modelContainer;
/**
* Constructs a mutually exclusive choice between two possible objects.
*
* @param xmlObject
* the XML for the choice definition bound to Java objects
* @param parent
* the parent container, either a choice or assembly
*/
public XmlChoiceGroupInstance(
@NonNull GroupedChoiceType xmlObject,
@NonNull IAssemblyDefinition parent) {
super(parent);
this.xmlObject = xmlObject;
this.modelContainer = ObjectUtils.notNull(Lazy.lazy(() -> new XmlModelContainer(xmlObject, this)));
}
@Override
public XmlModelContainer getModelContainer() {
return ObjectUtils.notNull(modelContainer.get());
}
@Override
public IAssemblyDefinition getOwningDefinition() {
return getParentContainer();
}
// ----------------------------------------
// - Start XmlBeans driven code - CPD-OFF -
// ----------------------------------------
/**
* Get the underlying XML data.
*
* @return the underlying XML data
*/
@NonNull
protected GroupedChoiceType getXmlObject() {
return xmlObject;
}
@Override
public String getJsonDiscriminatorProperty() {
return getXmlObject().isSetDiscriminator()
? ObjectUtils.requireNonNull(getXmlObject().getDiscriminator())
: DEFAULT_JSON_DISCRIMINATOR_PROPERTY_NAME;
}
@Override
public String getJsonKeyFlagInstanceName() {
return getXmlObject().isSetJsonKey() ? getXmlObject().getJsonKey().getFlagRef() : null;
}
@Override
public String getGroupAsName() {
return getXmlObject().getGroupAs().getName();
}
@Override
public int getMinOccurs() {
return XmlModelParser.getMinOccurs(getXmlObject().getMinOccurs());
}
@Override
public int getMaxOccurs() {
return XmlModelParser.getMaxOccurs(getXmlObject().getMaxOccurs());
}
@Override
public JsonGroupAsBehavior getJsonGroupAsBehavior() {
return XmlModelParser.getJsonGroupAsBehavior(getXmlObject().getGroupAs());
}
@Override
public XmlGroupAsBehavior getXmlGroupAsBehavior() {
return XmlModelParser.getXmlGroupAsBehavior(getXmlObject().getGroupAs());
}
@Override
public MarkupMultiline getRemarks() {
// remarks not supported
return null;
}
// -------------------------------------
// - End XmlBeans driven code - CPD-ON -
// -------------------------------------
@SuppressWarnings("PMD.UseConcurrentHashMap")
@NonNull
private static final XmlObjectParser<Pair<IChoiceGroupInstance, XmlModelContainer>> XML_MODEL_PARSER
= new XmlObjectParser<>(ObjectUtils.notNull(
Map.ofEntries(
Map.entry(XmlModuleConstants.ASSEMBLY_QNAME, XmlChoiceGroupInstance::handleAssembly),
Map.entry(XmlModuleConstants.DEFINE_ASSEMBLY_QNAME, XmlChoiceGroupInstance::handleDefineAssembly),
Map.entry(XmlModuleConstants.FIELD_QNAME, XmlChoiceGroupInstance::handleField),
Map.entry(XmlModuleConstants.DEFINE_FIELD_QNAME, XmlChoiceGroupInstance::handleDefineField)))) {
@Override
protected Handler<Pair<IChoiceGroupInstance, XmlModelContainer>>
identifyHandler(XmlCursor cursor, XmlObject obj) {
Handler<Pair<IChoiceGroupInstance, XmlModelContainer>> retval;
if (obj instanceof GroupedFieldReferenceType) {
retval = XmlChoiceGroupInstance::handleField;
} else if (obj instanceof GroupedInlineFieldDefinitionType) {
retval = XmlChoiceGroupInstance::handleDefineField;
} else if (obj instanceof GroupedAssemblyReferenceType) {
retval = XmlChoiceGroupInstance::handleAssembly;
} else if (obj instanceof GroupedInlineAssemblyDefinitionType) {
retval = XmlChoiceGroupInstance::handleDefineAssembly;
} else {
retval = super.identifyHandler(cursor, obj);
}
return retval;
}
};
private static void handleField( // NOPMD false positive
@NonNull XmlObject obj,
Pair<IChoiceGroupInstance, XmlModelContainer> state) {
IFieldInstanceGrouped instance = new XmlGroupedFieldInstance(
(GroupedFieldReferenceType) obj,
ObjectUtils.notNull(state.getLeft()));
ObjectUtils.notNull(state.getRight()).append(instance);
}
private static void handleDefineField( // NOPMD false positive
@NonNull XmlObject obj,
Pair<IChoiceGroupInstance, XmlModelContainer> state) {
IFieldInstanceGrouped instance = new XmlGroupedInlineFieldDefinition(
(GroupedInlineFieldDefinitionType) obj,
ObjectUtils.notNull(state.getLeft()));
ObjectUtils.notNull(state.getRight()).append(instance);
}
private static void handleAssembly( // NOPMD false positive
@NonNull XmlObject obj,
Pair<IChoiceGroupInstance, XmlModelContainer> state) {
IAssemblyInstanceGrouped instance = new XmlGroupedAssemblyInstance(
(GroupedAssemblyReferenceType) obj,
ObjectUtils.notNull(state.getLeft()));
ObjectUtils.notNull(state.getRight()).append(instance);
}
private static void handleDefineAssembly( // NOPMD false positive
@NonNull XmlObject obj,
Pair<IChoiceGroupInstance, XmlModelContainer> state) {
IAssemblyInstanceGrouped instance = new XmlGroupedInlineAssemblyDefinition(
(GroupedInlineAssemblyDefinitionType) obj,
ObjectUtils.notNull(state.getLeft()));
ObjectUtils.notNull(state.getRight()).append(instance);
}
private static class XmlModelContainer
extends DefaultGroupedModelContainerSupport<
INamedModelInstanceGrouped,
IFieldInstanceGrouped,
IAssemblyInstanceGrouped> {
/**
* Parse a choice group XMLBeans object.
*
* @param xmlObject
* the XMLBeans object
* @param parent
* the parent Metaschema node, either an assembly definition or choice
*/
public XmlModelContainer(
@NonNull GroupedChoiceType xmlObject,
@NonNull IChoiceGroupInstance parent) {
XML_MODEL_PARSER.parse(xmlObject, Pair.of(parent, this));
}
public void append(@NonNull IFieldInstanceGrouped instance) {
QName key = instance.getXmlQName();
getFieldInstanceMap().put(key, instance);
getNamedModelInstanceMap().put(key, instance);
}
public void append(@NonNull IAssemblyInstanceGrouped instance) {
QName key = instance.getXmlQName();
getAssemblyInstanceMap().put(key, instance);
getNamedModelInstanceMap().put(key, instance);
}
}
}