From 6f3bf09b419d5a8a80eb8abfa2306228efef4636 Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Sun, 29 Dec 2024 13:05:18 -0500 Subject: [PATCH] Added Javadocs and performed light refactoring. --- .../metapath/cst/AbstractCSTVisitorBase.java | 4 + .../core/metapath/cst/AbstractExpression.java | 31 +------ .../metapath/cst/DynamicFunctionCall.java | 3 +- .../metaschema/core/metapath/cst/For.java | 3 +- .../metapath/cst/FunctionCallAccessor.java | 3 +- .../metaschema/core/metapath/cst/Let.java | 3 +- .../core/metapath/cst/StaticFunctionCall.java | 3 +- .../core/metapath/cst/VariableReference.java | 3 +- .../metapath/cst/items/AbstractLookup.java | 5 +- .../cst/items/ArraySequenceConstructor.java | 4 +- .../cst/items/ArraySquareConstructor.java | 4 +- .../metapath/cst/items/MapConstructor.java | 7 +- .../core/metapath/cst/items/Range.java | 4 +- .../core/metapath/cst/logic/Negate.java | 2 +- .../cst/logic/PredicateExpression.java | 9 +- .../metapath/cst/logic/ValueComparison.java | 4 +- .../math/AbstractArithmeticExpression.java | 5 +- .../AbstractBasicArithmeticExpression.java | 15 +++- .../metapath/cst/math/IntegerDivision.java | 4 +- .../AbstractNamedInstanceExpression.java | 13 +-- .../core/metapath/cst/path/Flag.java | 1 - .../core/metapath/cst/path/KindNodeTest.java | 2 + .../core/metapath/cst/path/ModelInstance.java | 1 - .../core/metapath/cst/path/Step.java | 5 +- .../core/metapath/cst/type/Treat.java | 4 +- .../AbstractGlobalDefinitionNodeItem.java | 21 ++++- .../core/model/AbstractGlobalDefinition.java | 5 ++ .../IFeatureDefinitionInstanceInlined.java | 5 ++ .../constraint/AssemblyConstraintSet.java | 20 ++--- .../constraint/ITargetedConstraints.java | 9 -- .../model/constraint/IValueConstrained.java | 9 ++ .../model/constraint/ValueConstraintSet.java | 41 +++++++++- .../core/metapath/ExpressionTestBase.java | 9 +- .../item/node/MockNodeItemFactory.java | 82 +++++++++++++++++-- .../model/mocking/AbstractMockitoFactory.java | 6 ++ .../AbstractBoundDefinitionModelComplex.java | 6 ++ .../model/metaschema/impl/ModelSupport.java | 2 +- 37 files changed, 254 insertions(+), 103 deletions(-) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/{ => path}/AbstractNamedInstanceExpression.java (73%) diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractCSTVisitorBase.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractCSTVisitorBase.java index afa4387c9..9c401deff 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractCSTVisitorBase.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractCSTVisitorBase.java @@ -28,6 +28,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +/** + * Provides utility methods for processing Metapath abstract syntax tree (AST) + * nodes to produce a compact syntax tree (CST). + */ @SuppressWarnings({ "PMD.CouplingBetweenObjects" }) diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractExpression.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractExpression.java index c1cce8dc6..7b9bbde81 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractExpression.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractExpression.java @@ -5,34 +5,11 @@ package gov.nist.secauto.metaschema.core.metapath.cst; -import gov.nist.secauto.metaschema.core.metapath.item.ISequence; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; -import gov.nist.secauto.metaschema.core.metapath.type.TypeMetapathException; - -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - +/** + * A common base class for Metapath expression implementations, providing common + * utility functions. + */ public abstract class AbstractExpression implements IExpression { - /** - * Get the first data item of the provided {@code sequence} cast to an - * {@link IAnyAtomicItem}. - * - * @param sequence - * the sequence to get the data item from - * @param requireSingleton - * if {@code true} then a {@link TypeMetapathException} is thrown if - * the sequence contains more than one item - * @return {@code null} if the sequence is empty, or the item otherwise - * @throws TypeMetapathException - * if the sequence contains more than one item and requireSingleton is - * {@code true}, or if the data item cannot be cast - */ - @Nullable - public static IAnyAtomicItem getFirstDataItem(@NonNull ISequence sequence, - boolean requireSingleton) { - return ISequence.of(sequence.atomize()).getFirstItem(requireSingleton); - } - @Override public String toString() { return CSTPrinter.toString(this); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/DynamicFunctionCall.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/DynamicFunctionCall.java index 26941f69c..896571c3a 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/DynamicFunctionCall.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/DynamicFunctionCall.java @@ -23,7 +23,8 @@ * determine the function and multiple argument expressions that are used to * determine the function arguments. */ -public class DynamicFunctionCall implements IExpression { +public class DynamicFunctionCall + extends AbstractExpression { @NonNull private final IExpression functionIdentifier; @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/For.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/For.java index 35c95228f..b5483f66c 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/For.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/For.java @@ -22,7 +22,8 @@ * expression supporting variable-based iteration. */ @SuppressWarnings("PMD.ShortClassName") -public class For implements IExpression { +public class For + extends AbstractExpression { @NonNull private final Let.VariableDeclaration variable; @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/FunctionCallAccessor.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/FunctionCallAccessor.java index 60a8a2e71..8e28455ce 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/FunctionCallAccessor.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/FunctionCallAccessor.java @@ -25,7 +25,8 @@ import edu.umd.cs.findbugs.annotations.NonNull; -public class FunctionCallAccessor implements IExpression { +public class FunctionCallAccessor + extends AbstractExpression { @NonNull private final IExpression base; @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/Let.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/Let.java index 47c887a87..4cb9432f3 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/Let.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/Let.java @@ -21,7 +21,8 @@ * expression supporting variable value binding. */ @SuppressWarnings("PMD.ShortClassName") -public class Let implements IExpression { +public class Let + extends AbstractExpression { @NonNull private final VariableDeclaration variable; @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/StaticFunctionCall.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/StaticFunctionCall.java index cc1ee416e..e00662a13 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/StaticFunctionCall.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/StaticFunctionCall.java @@ -33,7 +33,8 @@ */ // FIXME: Change compilation to error when a non-existant function is called. // Manage this error where the compilation is requested -public class StaticFunctionCall implements IExpression { +public class StaticFunctionCall + extends AbstractExpression { @NonNull private final Lazy functionSupplier; @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/VariableReference.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/VariableReference.java index c775e8647..12981e137 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/VariableReference.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/VariableReference.java @@ -20,7 +20,8 @@ * variable * reference. */ -public class VariableReference implements IExpression { +public class VariableReference + extends AbstractExpression { @NonNull private final IEnhancedQName name; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/AbstractLookup.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/AbstractLookup.java index 5ad3d9a5e..40077d764 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/AbstractLookup.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/AbstractLookup.java @@ -5,7 +5,7 @@ package gov.nist.secauto.metaschema.core.metapath.cst.items; -import gov.nist.secauto.metaschema.core.metapath.cst.IExpression; +import gov.nist.secauto.metaschema.core.metapath.cst.AbstractExpression; import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IKeySpecifier; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; @@ -20,7 +20,8 @@ * Provides support for various types of key- and index-based lookups related to * {@link IMapItem} and {@link IArrayItem} objects. */ -public abstract class AbstractLookup implements IExpression { +public abstract class AbstractLookup + extends AbstractExpression { @NonNull private final IKeySpecifier keySpecifier; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/ArraySequenceConstructor.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/ArraySequenceConstructor.java index 26f584d77..c6aaa6a4d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/ArraySequenceConstructor.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/ArraySequenceConstructor.java @@ -6,6 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.cst.items; import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.cst.AbstractExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; import gov.nist.secauto.metaschema.core.metapath.item.ISequence; @@ -20,7 +21,8 @@ * Array Curly * Constructor supporting the creation of a Metapath {@link IArrayItem}. */ -public class ArraySequenceConstructor implements IExpression { +public class ArraySequenceConstructor + extends AbstractExpression { @Nullable private final IExpression expr; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/ArraySquareConstructor.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/ArraySquareConstructor.java index 5668989eb..49f9b869b 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/ArraySquareConstructor.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/ArraySquareConstructor.java @@ -6,6 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.cst.items; import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.cst.AbstractExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; import gov.nist.secauto.metaschema.core.metapath.item.IItem; @@ -21,7 +22,8 @@ * Array Square * Constructor supporting the creation of a Metapath {@link IArrayItem}. */ -public class ArraySquareConstructor implements IExpression { +public class ArraySquareConstructor + extends AbstractExpression { @NonNull private final List children; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/MapConstructor.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/MapConstructor.java index 82836ac45..eca376d81 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/MapConstructor.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/MapConstructor.java @@ -6,6 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.cst.items; import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.cst.AbstractExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; import gov.nist.secauto.metaschema.core.metapath.item.ICollectionValue; @@ -27,7 +28,8 @@ * Map * Constructor supporting the creation of a Metapath {@link IMapItem}. */ -public class MapConstructor implements IExpression { +public class MapConstructor + extends AbstractExpression { @NonNull private final List entries; @@ -74,7 +76,8 @@ public RESULT accept(IExpressionVisitor visit /** * A map entry expression used to produce an entry in a {@link IMapItem}. */ - public static class Entry implements IExpression { + public static class Entry + extends AbstractExpression { @NonNull private final IExpression keyExpression; @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/Range.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/Range.java index c30ffe2bc..6eea4baab 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/Range.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/items/Range.java @@ -47,8 +47,8 @@ public Class getBaseResultType() { @Override public ISequence accept(DynamicContext dynamicContext, ISequence focus) { - IAnyAtomicItem leftItem = getFirstDataItem(getLeft().accept(dynamicContext, focus), true); - IAnyAtomicItem rightItem = getFirstDataItem(getRight().accept(dynamicContext, focus), true); + IAnyAtomicItem leftItem = ISequence.of(getLeft().accept(dynamicContext, focus).atomize()).getFirstItem(true); + IAnyAtomicItem rightItem = ISequence.of(getRight().accept(dynamicContext, focus).atomize()).getFirstItem(true); IIntegerItem left = leftItem == null ? null : IIntegerItem.cast(leftItem); IIntegerItem right = rightItem == null ? null : IIntegerItem.cast(rightItem); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/Negate.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/Negate.java index 41c245413..716c5191b 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/Negate.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/Negate.java @@ -55,7 +55,7 @@ public RESULT accept(IExpressionVisitor visit @Override public ISequence accept(DynamicContext dynamicContext, ISequence focus) { INumericItem item = FunctionUtils.toNumericOrNull( - getFirstDataItem(getChild().accept(dynamicContext, focus), true)); + ISequence.of(getChild().accept(dynamicContext, focus).atomize()).getFirstItem(true)); if (item != null) { item = OperationFunctions.opNumericUnaryMinus(item); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/PredicateExpression.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/PredicateExpression.java index 35d63d1c7..f5bf016b8 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/PredicateExpression.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/PredicateExpression.java @@ -7,6 +7,7 @@ import gov.nist.secauto.metaschema.core.metapath.DynamicContext; import gov.nist.secauto.metaschema.core.metapath.MetapathEvaluationFeature; +import gov.nist.secauto.metaschema.core.metapath.cst.AbstractExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; import gov.nist.secauto.metaschema.core.metapath.cst.items.IntegerLiteral; @@ -25,7 +26,8 @@ import edu.umd.cs.findbugs.annotations.NonNull; -public class PredicateExpression implements IExpression { +public class PredicateExpression + extends AbstractExpression { @NonNull private final IExpression base; @NonNull @@ -82,10 +84,7 @@ ISequence accept(@NonNull DynamicContext dynamicContext, AtomicInteger index = new AtomicInteger(); Stream stream = ObjectUtils.notNull( - retval.stream().map(item -> { - // build a positional index of the items - return Map.entry(BigInteger.valueOf(index.incrementAndGet()), item); - }).filter(entry -> { + retval.stream().map(item -> Map.entry(BigInteger.valueOf(index.incrementAndGet()), item)).filter(entry -> { @SuppressWarnings("null") @NonNull IItem item = entry.getValue(); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/ValueComparison.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/ValueComparison.java index 00c1727c8..85bb1438d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/ValueComparison.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/logic/ValueComparison.java @@ -48,8 +48,8 @@ public RESULT accept(IExpressionVisitor visit @Override public ISequence accept(DynamicContext dynamicContext, ISequence focus) { - IAnyAtomicItem left = getFirstDataItem(getLeft().accept(dynamicContext, focus), false); - IAnyAtomicItem right = getFirstDataItem(getRight().accept(dynamicContext, focus), false); + IAnyAtomicItem left = ISequence.of(getLeft().accept(dynamicContext, focus).atomize()).getFirstItem(false); + IAnyAtomicItem right = ISequence.of(getRight().accept(dynamicContext, focus).atomize()).getFirstItem(false); return resultOrEmpty(left, right); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/AbstractArithmeticExpression.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/AbstractArithmeticExpression.java index f2d9b7343..e204d9e61 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/AbstractArithmeticExpression.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/AbstractArithmeticExpression.java @@ -15,8 +15,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * An immutable binary expression that supports arithmetic evaluation. The - * result type is determined through static analysis of the sub-expressions, + * An immutable binary expression that supports arithmetic evaluation. + *

+ * The result type is determined through static analysis of the sub-expressions, * which may result in a more specific type that is a sub-class of the base * result type. * diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/AbstractBasicArithmeticExpression.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/AbstractBasicArithmeticExpression.java index e04d0a18b..5b863ccb3 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/AbstractBasicArithmeticExpression.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/AbstractBasicArithmeticExpression.java @@ -13,6 +13,17 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +/** + * An immutable binary expression that supports basic arithmetic evaluation. + *

+ * The result type is determined through static analysis of the sub-expressions, + * which may result in a more specific type that is a sub-class of the base + * result type. + *

+ * The arithmetic operation method + * {@link #operation(IAnyAtomicItem, IAnyAtomicItem)} must be implemented by + * extending classes to provide the evaluation logic. + */ public abstract class AbstractBasicArithmeticExpression extends AbstractArithmeticExpression { @@ -35,8 +46,8 @@ public Class getBaseResultType() { @Override public ISequence accept(DynamicContext dynamicContext, ISequence focus) { - IAnyAtomicItem leftItem = getFirstDataItem(getLeft().accept(dynamicContext, focus), true); - IAnyAtomicItem rightItem = getFirstDataItem(getRight().accept(dynamicContext, focus), true); + IAnyAtomicItem leftItem = ISequence.of(getLeft().accept(dynamicContext, focus).atomize()).getFirstItem(true); + IAnyAtomicItem rightItem = ISequence.of(getRight().accept(dynamicContext, focus).atomize()).getFirstItem(true); return resultOrEmpty(leftItem, rightItem); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/IntegerDivision.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/IntegerDivision.java index f72ee98a2..a5e141fe6 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/IntegerDivision.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/math/IntegerDivision.java @@ -46,9 +46,9 @@ public RESULT accept(IExpressionVisitor visit @Override public ISequence accept(DynamicContext dynamicContext, ISequence focus) { INumericItem dividend = FunctionUtils.toNumericOrNull( - getFirstDataItem(getLeft().accept(dynamicContext, focus), true)); + ISequence.of(getLeft().accept(dynamicContext, focus).atomize()).getFirstItem(true)); INumericItem divisor = FunctionUtils.toNumericOrNull( - getFirstDataItem(getRight().accept(dynamicContext, focus), true)); + ISequence.of(getRight().accept(dynamicContext, focus).atomize()).getFirstItem(true)); return resultOrEmpty(dividend, divisor); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractNamedInstanceExpression.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/AbstractNamedInstanceExpression.java similarity index 73% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractNamedInstanceExpression.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/AbstractNamedInstanceExpression.java index cc540b378..57a41bc4e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractNamedInstanceExpression.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/AbstractNamedInstanceExpression.java @@ -3,18 +3,21 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.cst; +package gov.nist.secauto.metaschema.core.metapath.cst.path; -import gov.nist.secauto.metaschema.core.metapath.cst.path.AbstractPathExpression; -import gov.nist.secauto.metaschema.core.metapath.cst.path.INodeTestExpression; -import gov.nist.secauto.metaschema.core.metapath.cst.path.NameNodeTest; -import gov.nist.secauto.metaschema.core.metapath.cst.path.WildcardNodeTest; +import gov.nist.secauto.metaschema.core.metapath.cst.IExpression; import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem; import java.util.List; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A path expression that references a named instance. + * + * @param + * the Java type of the referenced node item + */ public abstract class AbstractNamedInstanceExpression extends AbstractPathExpression { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/Flag.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/Flag.java index a62979ebe..68804af62 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/Flag.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/Flag.java @@ -6,7 +6,6 @@ package gov.nist.secauto.metaschema.core.metapath.cst.path; import gov.nist.secauto.metaschema.core.metapath.DynamicContext; -import gov.nist.secauto.metaschema.core.metapath.cst.AbstractNamedInstanceExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; import gov.nist.secauto.metaschema.core.metapath.item.ISequence; import gov.nist.secauto.metaschema.core.metapath.item.ItemUtils; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/KindNodeTest.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/KindNodeTest.java index 113d9c1ac..0084e03c2 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/KindNodeTest.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/KindNodeTest.java @@ -6,6 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.cst.path; import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.cst.AbstractExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; import gov.nist.secauto.metaschema.core.metapath.item.ISequence; import gov.nist.secauto.metaschema.core.metapath.item.ItemUtils; @@ -22,6 +23,7 @@ */ @SuppressWarnings("PMD.TestClassWithoutTestCases") public class KindNodeTest + extends AbstractExpression implements INodeTestExpression { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/ModelInstance.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/ModelInstance.java index eb58c88fd..36868f80e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/ModelInstance.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/ModelInstance.java @@ -6,7 +6,6 @@ package gov.nist.secauto.metaschema.core.metapath.cst.path; import gov.nist.secauto.metaschema.core.metapath.DynamicContext; -import gov.nist.secauto.metaschema.core.metapath.cst.AbstractNamedInstanceExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; import gov.nist.secauto.metaschema.core.metapath.item.ISequence; import gov.nist.secauto.metaschema.core.metapath.item.ItemUtils; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/Step.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/Step.java index aff388ef2..0492c9b48 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/Step.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/path/Step.java @@ -6,6 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.cst.path; import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.cst.AbstractExpression; import gov.nist.secauto.metaschema.core.metapath.cst.ExpressionUtils; import gov.nist.secauto.metaschema.core.metapath.cst.IExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; @@ -23,7 +24,9 @@ * with the evaluation of a series of predicate expressions that filter the * result of the evaluation. */ -public class Step implements IExpression { // NOPMD - intentional +@SuppressWarnings("PMD.ShortClassName") +public class Step + extends AbstractExpression { @NonNull private final Axis axisExpression; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/type/Treat.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/type/Treat.java index 00c74e7b8..231b63ace 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/type/Treat.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/type/Treat.java @@ -7,6 +7,7 @@ import gov.nist.secauto.metaschema.core.metapath.DynamicContext; import gov.nist.secauto.metaschema.core.metapath.DynamicMetapathException; +import gov.nist.secauto.metaschema.core.metapath.cst.AbstractExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpression; import gov.nist.secauto.metaschema.core.metapath.cst.IExpressionVisitor; import gov.nist.secauto.metaschema.core.metapath.item.IItem; @@ -23,7 +24,8 @@ * "cast as" operator. */ @SuppressWarnings("PMD.ShortClassName") -public class Treat implements IExpression { +public class Treat + extends AbstractExpression { @NonNull private final IExpression value; @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/node/AbstractGlobalDefinitionNodeItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/node/AbstractGlobalDefinitionNodeItem.java index 16e50f847..22e567842 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/node/AbstractGlobalDefinitionNodeItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/node/AbstractGlobalDefinitionNodeItem.java @@ -22,6 +22,14 @@ public abstract class AbstractGlobalDefinitionNodeItem getIndexConstraints() { - Lock readLock = instanceLock.readLock(); + Lock readLock = getLock().readLock(); readLock.lock(); try { return CollectionUtil.unmodifiableList(indexConstraints); @@ -53,7 +53,7 @@ public List getIndexConstraints() { @Override public List getUniqueConstraints() { - Lock readLock = instanceLock.readLock(); + Lock readLock = getLock().readLock(); readLock.lock(); try { return CollectionUtil.unmodifiableList(uniqueConstraints); @@ -64,7 +64,7 @@ public List getUniqueConstraints() { @Override public List getHasCardinalityConstraints() { - Lock readLock = instanceLock.readLock(); + Lock readLock = getLock().readLock(); readLock.lock(); try { return CollectionUtil.unmodifiableList(cardinalityConstraints); @@ -75,10 +75,10 @@ public List getHasCardinalityConstraints() { @Override public final void addConstraint(@NonNull IIndexConstraint constraint) { - Lock writeLock = instanceLock.writeLock(); + Lock writeLock = getLock().writeLock(); writeLock.lock(); try { - constraints.add(constraint); + getConstraintsInternal().add(constraint); indexConstraints.add(constraint); } finally { writeLock.unlock(); @@ -87,10 +87,10 @@ public final void addConstraint(@NonNull IIndexConstraint constraint) { @Override public final void addConstraint(@NonNull IUniqueConstraint constraint) { - Lock writeLock = instanceLock.writeLock(); + Lock writeLock = getLock().writeLock(); writeLock.lock(); try { - constraints.add(constraint); + getConstraintsInternal().add(constraint); uniqueConstraints.add(constraint); } finally { writeLock.unlock(); @@ -99,10 +99,10 @@ public final void addConstraint(@NonNull IUniqueConstraint constraint) { @Override public final void addConstraint(@NonNull ICardinalityConstraint constraint) { - Lock writeLock = instanceLock.writeLock(); + Lock writeLock = getLock().writeLock(); writeLock.lock(); try { - constraints.add(constraint); + getConstraintsInternal().add(constraint); cardinalityConstraints.add(constraint); } finally { writeLock.unlock(); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/ITargetedConstraints.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/ITargetedConstraints.java index 81ab656d1..6dc8d4de7 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/ITargetedConstraints.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/ITargetedConstraints.java @@ -9,7 +9,6 @@ import gov.nist.secauto.metaschema.core.model.IAssemblyDefinition; import gov.nist.secauto.metaschema.core.model.IFieldDefinition; import gov.nist.secauto.metaschema.core.model.IFlagDefinition; -import gov.nist.secauto.metaschema.core.model.ISource; import edu.umd.cs.findbugs.annotations.NonNull; @@ -18,14 +17,6 @@ * Metapath expression. */ public interface ITargetedConstraints extends IValueConstrained { - /** - * Get information about the resource the constraints were sources from. - * - * @return the source information - */ - @NonNull - ISource getSource(); - /** * Get the Metapath expression used to identify the target of the constraint. * diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/IValueConstrained.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/IValueConstrained.java index e9ca08a1d..b912003b1 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/IValueConstrained.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/IValueConstrained.java @@ -5,6 +5,7 @@ package gov.nist.secauto.metaschema.core.model.constraint; +import gov.nist.secauto.metaschema.core.model.ISource; import gov.nist.secauto.metaschema.core.qname.IEnhancedQName; import java.util.List; @@ -17,6 +18,14 @@ * Metaschema field or flag data instance. */ public interface IValueConstrained { + /** + * Get information about the resource the constraints were loaded from. + * + * @return the source information + */ + @NonNull + ISource getSource(); + /** * Retrieve the ordered collection of constraints. * diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/ValueConstraintSet.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/ValueConstraintSet.java index d67847319..f9df2cc3f 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/ValueConstraintSet.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/constraint/ValueConstraintSet.java @@ -30,7 +30,7 @@ public class ValueConstraintSet implements IValueConstrained { @NonNull private final Map lets = new LinkedHashMap<>(); @NonNull - protected final List constraints = new LinkedList<>(); + private final List constraints = new LinkedList<>(); @NonNull private final List allowedValuesConstraints = new LinkedList<>(); @NonNull @@ -40,17 +40,50 @@ public class ValueConstraintSet implements IValueConstrained { @NonNull private final List expectConstraints = new LinkedList<>(); @NonNull - protected final ReadWriteLock instanceLock = new ReentrantReadWriteLock(); - + private final ReadWriteLock instanceLock = new ReentrantReadWriteLock(); + + /** + * Construct a new constraint set. + * + * @param source + * information about the resource the constraints were loaded from + */ public ValueConstraintSet(@NonNull ISource source) { this.source = source; } - @NonNull + @Override public ISource getSource() { return source; } + /** + * Get the read-write lock used to manage access to the underlying constraint + * collections. + *

+ * This can be used by extending classes to control read/write access to + * constraint data, supporting multi-threaded access. + * + * @return the lock + */ + @NonNull + protected ReadWriteLock getLock() { + return instanceLock; + } + + /** + * Get the underlying constraint collection. + *

+ * Access to the returned collection is not thread safe. Callers should use + * {@link #getLock()} to get the read/write lock for managing access. + * + * @return the constraint collection + */ + @NonNull + protected List getConstraintsInternal() { + return constraints; + } + @Override public Map getLetExpressions() { return lets; diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/ExpressionTestBase.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/ExpressionTestBase.java index 89cc6efb2..3cd880008 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/ExpressionTestBase.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/ExpressionTestBase.java @@ -21,10 +21,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; public class ExpressionTestBase { + /** + * A Metaschema model namespace for use in unit tests. + */ @NonNull - protected static final URI NS_URI = ObjectUtils.notNull(URI.create("http://example.com/ns")); - @NonNull - protected static final String NS = ObjectUtils.notNull(NS_URI.toASCIIString()); + protected static final String NS = "http://example.com/ns"; @SuppressWarnings("exports") @NonNull @@ -52,7 +53,7 @@ protected static DynamicContext newDynamicContext() { return new DynamicContext(StaticContext.builder() .baseUri(baseUri) - .defaultModelNamespace(NS_URI) + .defaultModelNamespace(NS) .build()); } diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/node/MockNodeItemFactory.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/node/MockNodeItemFactory.java index 10831650c..6a94d6bfa 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/node/MockNodeItemFactory.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/node/MockNodeItemFactory.java @@ -24,11 +24,27 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -// TODO: Integrate with classes in gov.nist.secauto.metaschema.core.testing +/** + * Generates mock node item objects. + */ +// FIXME: Integrate with classes in gov.nist.secauto.metaschema.core.testing @SuppressWarnings("checkstyle:MissingJavadocMethodCheck") @SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT") public class MockNodeItemFactory extends AbstractMockitoFactory { + /** + * Construct a new mocked document node item. + * + * @param documentURI + * the URI representing document's resource location. + * @param rootName + * the qualified name of the document's root node item + * @param flags + * the root node item's child flag node items + * @param modelItems + * the root node item's child model node items + * @return the mocked document node item + */ @NonNull public IDocumentNodeItem document( URI documentURI, @@ -54,14 +70,26 @@ public IDocumentNodeItem document( doReturn(definition).when(root).getDefinition(); doReturn(rootName).when(definition).getDefinitionQName(); - handleChildren(document, CollectionUtil.emptyList(), CollectionUtil.singletonList(root)); - handleChildren(root, flags, modelItems); + handleModelChildren(document, CollectionUtil.emptyList(), CollectionUtil.singletonList(root)); + handleModelChildren(root, flags, modelItems); return document; } + /** + * Generate mock calls for methods related to the node item's children nodes. + * + * @param + * the Java type of the node item + * @param item + * the node item to mock + * @param flags + * the node item's child flag node items + * @param modelItems + * the node item's child model node items + */ @SuppressWarnings("null") - protected void handleChildren( + protected void handleModelChildren( @NonNull T item, List flags, List> modelItems) { @@ -118,6 +146,15 @@ protected void handleChildren( return CollectionUtil.unmodifiableMap(retval); } + /** + * Construct a new mocked flag node item. + * + * @param name + * the qualified name of the flag node item + * @param value + * the flag's value + * @return the mocked flag node item + */ @NonNull public IFlagNodeItem flag(@NonNull IEnhancedQName name, @NonNull IAnyAtomicItem value) { IFlagNodeItem flag = mock(IFlagNodeItem.class, ObjectUtils.notNull(name.toString())); @@ -132,16 +169,36 @@ public IFlagNodeItem flag(@NonNull IEnhancedQName name, @NonNull IAnyAtomicItem doReturn(name).when(definition).getDefinitionQName(); doReturn(value.getJavaTypeAdapter()).when(definition).getJavaTypeAdapter(); - handleChildren(flag, CollectionUtil.emptyList(), CollectionUtil.emptyList()); + handleModelChildren(flag, CollectionUtil.emptyList(), CollectionUtil.emptyList()); return flag; } + /** + * Construct a new mocked field node item with no child flags. + * + * @param name + * the qualified name of the field node item + * @param value + * the field's value + * @return the mocked field node item + */ @NonNull public IFieldNodeItem field(@NonNull IEnhancedQName name, @NonNull IAnyAtomicItem value) { return field(name, value, CollectionUtil.emptyList()); } + /** + * Construct a new mocked field node item with no child flags. + * + * @param name + * the qualified name of the field node item + * @param value + * the field's value + * @param flags + * the node item's child flag node items + * @return the mocked field node item + */ @NonNull public IFieldNodeItem field( @NonNull IEnhancedQName name, @@ -159,10 +216,21 @@ public IFieldNodeItem field( doReturn(name).when(definition).getDefinitionQName(); doReturn(value.getJavaTypeAdapter()).when(definition).getJavaTypeAdapter(); - handleChildren(field, ObjectUtils.requireNonNull(flags), CollectionUtil.emptyList()); + handleModelChildren(field, ObjectUtils.requireNonNull(flags), CollectionUtil.emptyList()); return field; } + /** + * Construct a new mocked field node item with no child flags. + * + * @param name + * the qualified name of the field node item + * @param flags + * the node item's child flag node items + * @param modelItems + * the node item's child model node items + * @return the mocked field node item + */ @NonNull public IAssemblyNodeItem assembly( @NonNull IEnhancedQName name, @@ -178,7 +246,7 @@ public IAssemblyNodeItem assembly( doReturn(definition).when(assembly).getDefinition(); doReturn(name).when(definition).getDefinitionQName(); - handleChildren(assembly, ObjectUtils.requireNonNull(flags), ObjectUtils.requireNonNull(modelItems)); + handleModelChildren(assembly, ObjectUtils.requireNonNull(flags), ObjectUtils.requireNonNull(modelItems)); return assembly; } diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/testing/model/mocking/AbstractMockitoFactory.java b/core/src/test/java/gov/nist/secauto/metaschema/core/testing/model/mocking/AbstractMockitoFactory.java index bb957adb2..b7ba9f01c 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/testing/model/mocking/AbstractMockitoFactory.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/testing/model/mocking/AbstractMockitoFactory.java @@ -17,9 +17,15 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +/** + * A mocking factory that uses Mockito to produce mock objects. + */ public class AbstractMockitoFactory implements IMockFactory { + /** + * Construct a new mocking factory. + */ protected AbstractMockitoFactory() { // allow construction by extending classes } diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundDefinitionModelComplex.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundDefinitionModelComplex.java index ae0c16825..2abe96c47 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundDefinitionModelComplex.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/impl/AbstractBoundDefinitionModelComplex.java @@ -6,6 +6,7 @@ package gov.nist.secauto.metaschema.databind.model.impl; import gov.nist.secauto.metaschema.core.model.IBoundObject; +import gov.nist.secauto.metaschema.core.model.ISource; import gov.nist.secauto.metaschema.core.model.util.ModuleUtils; import gov.nist.secauto.metaschema.core.qname.IEnhancedQName; import gov.nist.secauto.metaschema.core.util.ObjectUtils; @@ -82,6 +83,11 @@ public IBoundModule getContainingModule() { return module; } + @Override + public ISource getSource() { + return getContainingModule().getSource(); + } + @Override @NonNull public IBindingContext getBindingContext() { diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/metaschema/impl/ModelSupport.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/metaschema/impl/ModelSupport.java index 181b6182f..31f555409 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/metaschema/impl/ModelSupport.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/model/metaschema/impl/ModelSupport.java @@ -128,7 +128,7 @@ public static IDataTypeAdapter dataType( retval = MetaschemaDataTypeProvider.DEFAULT_DATA_TYPE; } else { IEnhancedQName qname = IEnhancedQName.of(MetapathConstants.NS_METAPATH, dataType); - IAtomicOrUnionType type; + IAtomicOrUnionType type; try { source.getStaticContext(); type = StaticContext.lookupAtomicType(qname);