FlagContainerSupport.java
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/
package gov.nist.secauto.metaschema.databind.model.metaschema.impl;
import gov.nist.secauto.metaschema.core.model.IContainerFlagSupport;
import gov.nist.secauto.metaschema.core.model.IFlagContainerBuilder;
import gov.nist.secauto.metaschema.core.model.IFlagDefinition;
import gov.nist.secauto.metaschema.core.model.IFlagInstance;
import gov.nist.secauto.metaschema.core.model.IModule;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelChoiceGroup;
import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelGroupedAssembly;
import gov.nist.secauto.metaschema.databind.model.metaschema.IBindingDefinitionModel;
import gov.nist.secauto.metaschema.databind.model.metaschema.binding.FlagReference;
import gov.nist.secauto.metaschema.databind.model.metaschema.binding.InlineDefineFlag;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.namespace.QName;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@SuppressWarnings("PMD.OnlyOneReturn")
public final class FlagContainerSupport {
@SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", justification = "Use of final fields")
@NonNull
public static IContainerFlagSupport<IFlagInstance> newFlagContainer(
@Nullable List<Object> flags,
@NonNull IBoundInstanceModelGroupedAssembly bindingInstance,
@NonNull IBindingDefinitionModel parent,
@Nullable String jsonKeyName) {
if (flags == null || flags.isEmpty()) {
return IContainerFlagSupport.empty();
}
// create temporary collections to store the child binding objects
IFlagContainerBuilder<IFlagInstance> builder = jsonKeyName == null
? IContainerFlagSupport.builder()
: IContainerFlagSupport.builder(parent.getContainingModule().toFlagQName(jsonKeyName));
// create counter to track child positions
AtomicInteger flagReferencePosition = new AtomicInteger();
AtomicInteger flagInlineDefinitionPosition = new AtomicInteger();
IBoundInstanceModelChoiceGroup instance = ObjectUtils.requireNonNull(
bindingInstance.getDefinition().getChoiceGroupInstanceByName("flags"));
flags.stream()
.map(obj -> {
assert obj != null;
IBoundInstanceModelGroupedAssembly objInstance
= (IBoundInstanceModelGroupedAssembly) instance.getItemInstance(obj);
IFlagInstance flag;
if (obj instanceof InlineDefineFlag) {
flag = new InstanceFlagInline(
(InlineDefineFlag) obj,
objInstance,
flagInlineDefinitionPosition.incrementAndGet(),
parent);
} else if (obj instanceof FlagReference) {
flag = newFlagInstance(
(FlagReference) obj,
objInstance,
flagReferencePosition.incrementAndGet(),
parent);
} else {
throw new UnsupportedOperationException(String.format("Unknown flag instance class: %s", obj.getClass()));
}
return flag;
}).forEachOrdered(builder::flag);
return builder.build();
}
@NonNull
private static IFlagInstance newFlagInstance(
@NonNull FlagReference obj,
@NonNull IBoundInstanceModelGroupedAssembly objInstance,
int position,
@NonNull IBindingDefinitionModel parent) {
IModule module = parent.getContainingModule();
QName qname = module.toFlagQName(ObjectUtils.requireNonNull(obj.getRef()));
IFlagDefinition definition = module.getScopedFlagDefinitionByName(qname);
if (definition == null) {
throw new IllegalStateException(
String.format("Unable to resolve flag reference '%s' in definition '%s' in module '%s'",
qname,
parent.getName(),
module.getShortName()));
}
return new InstanceFlagReference(obj, objInstance, position, definition, parent);
}
private FlagContainerSupport() {
// disable construction
}
}