Skip to content

Commit

Permalink
Refactored the implementations supporting model container generation,…
Browse files Browse the repository at this point in the history
… by reducing the number of implementations and implementing a builder pattern to store container information while the container is being built. Also removed a bunch of unneccsary interfaces and unwound some significant spaghetti code.
  • Loading branch information
david-waltermire committed Nov 20, 2024
1 parent 57f6fbe commit 52786cc
Show file tree
Hide file tree
Showing 49 changed files with 1,888 additions and 2,047 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ public <TYPE extends IDataTypeAdapter<?>> TYPE getJavaTypeAdapterByClass(@NonNul
return (TYPE) typeByAdapterClass.get(clazz);
}

/**
* Lookup a specific {@link IDataTypeAdapter} instance by its item class.
*
* @param clazz
* the adapter class to get the instance for
* @return the instance or {@code null} if the instance is unknown to the type
* system
*/
@Nullable
public IDataTypeAdapter<?> getJavaTypeAdapterByItemClass(Class<? extends IAnyAtomicItem> clazz) {
return typeByItemClass.get(clazz);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,6 @@ private StaticContext(Builder builder) {
this.useWildcardWhenNamespaceNotDefaulted = builder.useWildcardWhenNamespaceNotDefaulted;
}

private EQNameFactory getEqNameFactory() {
return EQNameFactory.instance();
}

/**
* Get the static base URI to use in resolving URIs handled by the Metapath
* processor. This URI, if provided, will be used when a document base URI is
Expand Down Expand Up @@ -223,14 +219,14 @@ private String resolveBasicPrefix(@NonNull String prefix) {

@NonNull
private IEnhancedQName parseDataTypeName(@NonNull String name) {
return getEqNameFactory().parseName(
return EQNameFactory.instance().parseName(
name,
this::resolveBasicPrefix);
}

@NonNull
private IEnhancedQName parseFunctionName(@NonNull String name) {
return getEqNameFactory().parseName(
return EQNameFactory.instance().parseName(
name,
this::resolveFunctionPrefix);
}
Expand Down Expand Up @@ -262,11 +258,13 @@ private String resolveFunctionPrefix(@NonNull String prefix) {
* <li>Use {@link XMLConstants#NULL_NS_URI}.</li>
* </ol>
*
* @param name
* the name
* @return the parsed qualified name
*/
@NonNull
public IEnhancedQName parseFlagName(@NonNull String name) {
return getEqNameFactory().parseName(
return EQNameFactory.instance().parseName(
name,
this::resolveBasicPrefix);
}
Expand All @@ -287,11 +285,13 @@ public IEnhancedQName parseFlagName(@NonNull String name) {
* {@link Builder#defaultModelNamespace(String)}).</li>
* </ol>
*
* @param name
* the name
* @return the parsed qualified name
*/
@NonNull
public IEnhancedQName parseModelName(@NonNull String name) {
return getEqNameFactory().parseName(
return EQNameFactory.instance().parseName(
name,
this::resolveModelReferencePrefix);
}
Expand Down Expand Up @@ -324,11 +324,13 @@ private String resolveModelReferencePrefix(@NonNull String prefix) {
* <li>Use {@link XMLConstants#NULL_NS_URI}.</li>
* </ol>
*
* @param name
* the name
* @return the parsed qualified name
*/
@NonNull
public IEnhancedQName parseVariableName(@NonNull String name) {
return getEqNameFactory().parseName(
return EQNameFactory.instance().parseName(
name,
this::resolveBasicPrefix);
}
Expand All @@ -350,9 +352,9 @@ public Builder buildFrom() {
}

/**
* Indicates if a name match should use a wildcard for the namespace is the
* namespace does not have a value and the {@link #getDefaultModelNamespace()}
* is {@code null}.
* Indicates if a name match should use a wildcard for the namespace if the
* namespace does not have a value and the default model namespace is
* {@code null}.
*
* @return {@code true} if a wildcard match on the name space should be used or
* {@code false} otherwise
Expand Down Expand Up @@ -422,7 +424,6 @@ public Builder baseUri(@NonNull URI uri) {
* the namespace URI
* @return this builder
* @see StaticContext#lookupNamespaceForPrefix(String)
* @see StaticContext#lookupNamespaceURIForPrefix(String)
* @see StaticContext#getWellKnownNamespacesMap()
*/
@NonNull
Expand All @@ -443,7 +444,6 @@ public Builder namespace(@NonNull String prefix, @NonNull URI uri) {
* @throws IllegalArgumentException
* if the provided URI is invalid
* @see StaticContext#lookupNamespaceForPrefix(String)
* @see StaticContext#lookupNamespaceURIForPrefix(String)
* @see StaticContext#getWellKnownNamespacesMap()
*/
@NonNull
Expand All @@ -458,7 +458,6 @@ public Builder namespace(@NonNull String prefix, @NonNull String uri) {
* @param uri
* the namespace URI
* @return this builder
* @see StaticContext#getDefaultModelNamespace()
*/
@NonNull
public Builder defaultModelNamespace(@NonNull URI uri) {
Expand All @@ -475,7 +474,6 @@ public Builder defaultModelNamespace(@NonNull URI uri) {
* @return this builder
* @throws IllegalArgumentException
* if the provided URI is invalid
* @see StaticContext#getDefaultModelNamespace()
*/
@NonNull
public Builder defaultModelNamespace(@NonNull String uri) {
Expand All @@ -489,7 +487,6 @@ public Builder defaultModelNamespace(@NonNull String uri) {
* @param uri
* the namespace URI
* @return this builder
* @see StaticContext#getDefaultFunctionNamespace()
*/
@NonNull
public Builder defaultFunctionNamespace(@NonNull URI uri) {
Expand All @@ -506,7 +503,6 @@ public Builder defaultFunctionNamespace(@NonNull URI uri) {
* @return this builder
* @throws IllegalArgumentException
* if the provided URI is invalid
* @see StaticContext#getDefaultFunctionNamespace()
*/
@NonNull
public Builder defaultFunctionNamespace(@NonNull String uri) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,38 @@
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.model.xml.impl;
package gov.nist.secauto.metaschema.core.model;

import gov.nist.secauto.metaschema.core.model.IAssemblyInstanceGrouped;
import gov.nist.secauto.metaschema.core.model.IContainerModelSupport;
import gov.nist.secauto.metaschema.core.model.IFieldInstanceGrouped;
import gov.nist.secauto.metaschema.core.model.INamedModelInstanceGrouped;
import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
import gov.nist.secauto.metaschema.core.util.CollectionUtil;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Stream;

import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
* Supports grouped model instance operations on assembly model instances.
* Supports model instance operations on assembly model instances.
* <p>
* This implementation uses underlying {@link LinkedHashMap} instances to
* preserve ordering.
* <p>
* Since a choice group only contains named model instances (i.e., fields,
* assemblies), model instance operations are supported by the map returned by
* {@link #getNamedModelInstanceMap()}.
*
* @param <MI>
* the model instance Java type
* @param <NMI>
* the named model instance Java type
* @param <FI>
* the field instance Java type
* @param <AI>
* the assembly instance Java type
*/
public class DefaultGroupedModelContainerSupport<
NMI extends INamedModelInstanceGrouped,
FI extends IFieldInstanceGrouped,
AI extends IAssemblyInstanceGrouped>
implements IContainerModelSupport<NMI, NMI, FI, AI> {
public abstract class AbstractContainerModelSupport<
MI extends IModelInstance,
NMI extends INamedModelInstance,
FI extends IFieldInstance,
AI extends IAssemblyInstance>
implements IContainerModelSupport<MI, NMI, FI, AI> {

@NonNull
private final Map<IEnhancedQName, NMI> namedModelInstances;
Expand All @@ -53,29 +47,58 @@ public class DefaultGroupedModelContainerSupport<
* Construct an empty, mutable container.
*/
@SuppressWarnings("PMD.UseConcurrentHashMap")
public DefaultGroupedModelContainerSupport() {
public AbstractContainerModelSupport() {
this(
new LinkedHashMap<>(),
new LinkedHashMap<>(),
new LinkedHashMap<>());
}

/**
* Construct an immutable container from a collection of named model instances.
* Construct an new container using the provided collections.
*
* @param namedModelInstances
* a collection of named model instances
* @param fieldInstances
* a collection of field instances
* @param assemblyInstances
* a collection of assembly instances
*/
protected AbstractContainerModelSupport(
@NonNull Map<IEnhancedQName, NMI> namedModelInstances,
@NonNull Map<IEnhancedQName, FI> fieldInstances,
@NonNull Map<IEnhancedQName, AI> assemblyInstances) {
this.namedModelInstances = namedModelInstances;
this.fieldInstances = fieldInstances;
this.assemblyInstances = assemblyInstances;
}

/**
* Construct an immutable container from a collection of model instances.
*
* @param instances
* the collection of named model instances to add to the new container.
* the collection of model instances to add to the new container.
* @param namedModelClass
* the Java type for named model instances
* @param fieldClass
* the Java type for field instances
* @param assemblyClass
* the Java type for assembly instances
*/
@SuppressWarnings({ "PMD.UseConcurrentHashMap" })
@SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", justification = "Use of final fields")
private DefaultGroupedModelContainerSupport(
@NonNull Collection<NMI> instances,
@SuppressWarnings("PMD.UseConcurrentHashMap")
protected AbstractContainerModelSupport(
@NonNull Stream<NMI> instances,
@NonNull Class<NMI> namedModelClass,
@NonNull Class<FI> fieldClass,
@NonNull Class<AI> assemblyClass) {
assert namedModelClass.isAssignableFrom(fieldClass) : String.format(
"The field class '%s' is not assignment compatible to class '%s'.",
fieldClass.getName(),
namedModelClass.getName());
assert namedModelClass.isAssignableFrom(assemblyClass) : String.format(
"The assembly class '%s' is not assignment compatible to class '%s'.",
assemblyClass.getName(),
namedModelClass.getName());
assert !fieldClass.isAssignableFrom(assemblyClass) : String.format(
"The field class '%s' must not be assignment compatible to the assembly class '%s'.",
fieldClass.getName(),
Expand All @@ -84,7 +107,8 @@ private DefaultGroupedModelContainerSupport(
Map<IEnhancedQName, NMI> namedModelInstances = new LinkedHashMap<>();
Map<IEnhancedQName, FI> fieldInstances = new LinkedHashMap<>();
Map<IEnhancedQName, AI> assemblyInstances = new LinkedHashMap<>();
for (NMI instance : instances) {

instances.forEachOrdered(instance -> {
IEnhancedQName key = instance.getQName();
namedModelInstances.put(key, instance);

Expand All @@ -93,7 +117,7 @@ private DefaultGroupedModelContainerSupport(
} else if (assemblyClass.isInstance(instance)) {
assemblyInstances.put(key, assemblyClass.cast(instance));
}
}
});

this.namedModelInstances = namedModelInstances.isEmpty()
? CollectionUtil.emptyMap()
Expand All @@ -106,31 +130,6 @@ private DefaultGroupedModelContainerSupport(
: CollectionUtil.unmodifiableMap(assemblyInstances);
}

/**
* Construct an new container using the provided collections.
*
* @param namedModelInstances
* a collection of named model instances
* @param fieldInstances
* a collection of field instances
* @param assemblyInstances
* a collection of assembly instances
*/
protected DefaultGroupedModelContainerSupport(
@NonNull Map<IEnhancedQName, NMI> namedModelInstances,
@NonNull Map<IEnhancedQName, FI> fieldInstances,
@NonNull Map<IEnhancedQName, AI> assemblyInstances) {
this.namedModelInstances = namedModelInstances;
this.fieldInstances = fieldInstances;
this.assemblyInstances = assemblyInstances;
}

@SuppressWarnings("null")
@Override
public Collection<NMI> getModelInstances() {
return namedModelInstances.values();
}

@Override
public Map<IEnhancedQName, NMI> getNamedModelInstanceMap() {
return namedModelInstances;
Expand All @@ -145,4 +144,11 @@ public Map<IEnhancedQName, FI> getFieldInstanceMap() {
public Map<IEnhancedQName, AI> getAssemblyInstanceMap() {
return assemblyInstances;
}

@SuppressWarnings({ "PMD.EmptyFinalizer", "checkstyle:NoFinalizer" })
@Override
protected final void finalize() {
// Address SEI CERT Rule OBJ-11:
// https://wiki.sei.cmu.edu/confluence/display/java/OBJ11-J.+Be+wary+of+letting+constructors+throw+exceptions
}
}
Loading

0 comments on commit 52786cc

Please sign in to comment.