XmlFlagContainerSupport.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.model.IAssemblyDefinition;
import gov.nist.secauto.metaschema.core.model.IContainerFlagSupport;
import gov.nist.secauto.metaschema.core.model.IFieldDefinition;
import gov.nist.secauto.metaschema.core.model.IFlagContainerBuilder;
import gov.nist.secauto.metaschema.core.model.IFlagInstance;
import gov.nist.secauto.metaschema.core.model.IModelDefinition;
import gov.nist.secauto.metaschema.core.model.xml.XmlModuleConstants;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.FlagReferenceType;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GlobalAssemblyDefinitionType;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GlobalFieldDefinitionType;
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.model.xml.xmlbeans.InlineAssemblyDefinitionType;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.InlineFieldDefinitionType;
import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.InlineFlagDefinitionType;
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 edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
/**
* Supports parsing Metaschema assembly and field XMLBeans objects that contain
* flags.
*/
final class XmlFlagContainerSupport {
@SuppressWarnings("PMD.UseConcurrentHashMap")
@NonNull
private static final XmlObjectParser<Pair<IModelDefinition, IFlagContainerBuilder<IFlagInstance>>> XML_MODEL_PARSER
= new XmlObjectParser<>(ObjectUtils.notNull(
Map.ofEntries(
Map.entry(XmlModuleConstants.FLAG_QNAME, XmlFlagContainerSupport::handleFlag),
Map.entry(XmlModuleConstants.DEFINE_FLAG_QNAME, XmlFlagContainerSupport::handleDefineFlag)))) {
@Override
protected Handler<Pair<IModelDefinition, IFlagContainerBuilder<IFlagInstance>>> identifyHandler(
XmlCursor cursor,
XmlObject obj) {
Handler<Pair<IModelDefinition, IFlagContainerBuilder<IFlagInstance>>> retval;
if (obj instanceof FlagReferenceType) {
retval = XmlFlagContainerSupport::handleFlag;
} else if (obj instanceof InlineFlagDefinitionType) {
retval = XmlFlagContainerSupport::handleDefineFlag;
} else {
retval = super.identifyHandler(cursor, obj);
}
return retval;
}
};
private static void handleFlag( // NOPMD false positive
@NonNull XmlObject obj,
Pair<IModelDefinition, IFlagContainerBuilder<IFlagInstance>> state) {
XmlFlagInstance flagInstance = new XmlFlagInstance(
(FlagReferenceType) obj,
ObjectUtils.notNull(state.getLeft()));
state.getRight().flag(flagInstance);
}
private static void handleDefineFlag( // NOPMD false positive
@NonNull XmlObject obj,
Pair<IModelDefinition, IFlagContainerBuilder<IFlagInstance>> state) {
XmlInlineFlagDefinition flagInstance = new XmlInlineFlagDefinition(
(InlineFlagDefinitionType) obj,
ObjectUtils.notNull(state.getLeft()));
state.getRight().flag(flagInstance);
}
/**
* Generate a flag container from the provided XMLBeans instance.
*
* @param xmlField
* the XMLBeans instance
* @param container
* the field containing the flag
*/
@SuppressWarnings("PMD.OnlyOneReturn")
static IContainerFlagSupport<IFlagInstance> newInstance(
@NonNull GlobalFieldDefinitionType xmlField,
@NonNull IFieldDefinition container) {
if (!xmlField.getFlagList().isEmpty() || !xmlField.getDefineFlagList().isEmpty()) {
IFlagContainerBuilder<IFlagInstance> builder = xmlField.isSetJsonKey()
? IContainerFlagSupport.builder(container.getContainingModule().toFlagQName(
ObjectUtils.requireNonNull(xmlField.getJsonKey().getFlagRef())))
: IContainerFlagSupport.builder();
parseLocalFlags(xmlField, container, builder);
return builder.build();
}
return IContainerFlagSupport.empty();
}
/**
* Generate a flag container from the provided XMLBeans instance.
*
* @param xmlField
* the XMLBeans instance
* @param container
* the field containing the flag
*/
@SuppressWarnings("PMD.OnlyOneReturn")
static IContainerFlagSupport<IFlagInstance> newInstance(
@NonNull InlineFieldDefinitionType xmlField,
@NonNull IFieldDefinition container) {
if (!xmlField.getFlagList().isEmpty() || !xmlField.getDefineFlagList().isEmpty()) {
IFlagContainerBuilder<IFlagInstance> builder = xmlField.isSetJsonKey()
? IContainerFlagSupport.builder(container.getContainingModule().toFlagQName(
ObjectUtils.requireNonNull(xmlField.getJsonKey().getFlagRef())))
: IContainerFlagSupport.builder();
parseLocalFlags(xmlField, container, builder);
return builder.build();
}
return IContainerFlagSupport.empty();
}
/**
* Generate a flag container from the provided XMLBeans instance.
*
* @param xmlField
* the XMLBeans instance
* @param container
* the field containing the flag
*/
@SuppressWarnings("PMD.OnlyOneReturn")
static IContainerFlagSupport<IFlagInstance> newInstance(
@NonNull GroupedInlineFieldDefinitionType xmlField,
@NonNull IFieldDefinition container,
@Nullable String jsonKeyName) {
if (!xmlField.getFlagList().isEmpty() || !xmlField.getDefineFlagList().isEmpty()) {
IFlagContainerBuilder<IFlagInstance> builder = jsonKeyName == null
? IContainerFlagSupport.builder()
: IContainerFlagSupport.builder(container.getContainingModule().toFlagQName(jsonKeyName));
parseLocalFlags(xmlField, container, builder);
return builder.build();
}
return IContainerFlagSupport.empty();
}
/**
* Generate a flag container from the provided XMLBeans instance.
*
* @param xmlField
* the XMLBeans instance
* @param container
* the field containing the flag
*/
@SuppressWarnings("PMD.OnlyOneReturn")
static IContainerFlagSupport<IFlagInstance> newInstance(
@NonNull GlobalAssemblyDefinitionType xmlAssembly,
@NonNull IAssemblyDefinition container) {
if (!xmlAssembly.getFlagList().isEmpty() || !xmlAssembly.getDefineFlagList().isEmpty()) {
IFlagContainerBuilder<IFlagInstance> builder = xmlAssembly.isSetJsonKey()
? IContainerFlagSupport.builder(container.getContainingModule().toFlagQName(
ObjectUtils.requireNonNull(xmlAssembly.getJsonKey().getFlagRef())))
: IContainerFlagSupport.builder();
parseLocalFlags(xmlAssembly, container, builder);
return builder.build();
}
return IContainerFlagSupport.empty();
}
/**
* Generate a flag container from the provided XMLBeans instance.
*
* @param xmlField
* the XMLBeans instance
* @param container
* the field containing the flag
*/
@SuppressWarnings("PMD.OnlyOneReturn")
static IContainerFlagSupport<IFlagInstance> newInstance(
@NonNull InlineAssemblyDefinitionType xmlAssembly,
@NonNull IAssemblyDefinition container) {
if (!xmlAssembly.getFlagList().isEmpty() || !xmlAssembly.getDefineFlagList().isEmpty()) {
IFlagContainerBuilder<IFlagInstance> builder = xmlAssembly.isSetJsonKey()
? IContainerFlagSupport.builder(container.getContainingModule().toFlagQName(
ObjectUtils.requireNonNull(xmlAssembly.getJsonKey().getFlagRef())))
: IContainerFlagSupport.builder();
parseLocalFlags(xmlAssembly, container, builder);
return builder.build();
}
return IContainerFlagSupport.empty();
}
/**
* Generate a flag container from the provided XMLBeans instance.
*
* @param xmlField
* the XMLBeans instance
* @param container
* the field containing the flag
*/
@SuppressWarnings("PMD.OnlyOneReturn")
static IContainerFlagSupport<IFlagInstance> newInstance(
@NonNull GroupedInlineAssemblyDefinitionType xmlAssembly,
@NonNull IAssemblyDefinition container,
@Nullable String jsonKeyName) {
if (!xmlAssembly.getFlagList().isEmpty() || !xmlAssembly.getDefineFlagList().isEmpty()) {
IFlagContainerBuilder<IFlagInstance> builder = jsonKeyName == null
? IContainerFlagSupport.builder()
: IContainerFlagSupport.builder(container.getContainingModule().toFlagQName(jsonKeyName));
parseLocalFlags(xmlAssembly, container, builder);
return builder.build();
}
return IContainerFlagSupport.empty();
}
private static void parseLocalFlags(
@NonNull XmlObject xmlObject,
@NonNull IModelDefinition parent,
@NonNull IFlagContainerBuilder<IFlagInstance> builder) {
// handle flags
XML_MODEL_PARSER.parse(xmlObject, Pair.of(parent, builder));
}
private XmlFlagContainerSupport() {
// disable construction
}
}