Skip to content

Commit

Permalink
Added support for remarks in let statements. resolves metaschema-fram…
Browse files Browse the repository at this point in the history
  • Loading branch information
david-waltermire committed Oct 26, 2024
1 parent 209457a commit d75ae34
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ private static ISequence<IStringItem> executeOneArg(@NonNull IFunction function,
@NonNull List<ISequence<?>> arguments, @NonNull DynamicContext dynamicContext, IItem focus) {

// From the XPath 3.1 specification:
// If the value of $arg is the empty sequence, the zero-length string is returned.
// If the value of $arg is the empty sequence, the zero-length string is
// returned.
if (arguments.get(0).size() == 0) {
return ISequence.of(IStringItem.valueOf(""));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ private static ISequence<IStringItem> executeOneArg(@NonNull IFunction function,
@NonNull List<ISequence<?>> arguments, @NonNull DynamicContext dynamicContext, IItem focus) {

// From the XPath 3.1 specification:
// If the value of $arg is the empty sequence, the zero-length string is returned.
// If the value of $arg is the empty sequence, the zero-length string is
// returned.
if (arguments.get(0).size() == 0) {
return ISequence.of(IStringItem.valueOf(""));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ private static <T extends ICollectionValue> ISequence<IMapItem<T>> execute(@NonN
@NonNull DynamicContext dynamicContext,
IItem focus) {
IAnyAtomicItem key = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0).getFirstItem(true)));
@SuppressWarnings("unchecked")
T value = (T) arguments.get(1).toCollectionValue();
@SuppressWarnings("unchecked") T value = (T) arguments.get(1).toCollectionValue();

return entry(key, value).asSequence();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ private enum Duplicates {
private final CustomCollectors.DuplicateHandler<IMapKey, ICollectionValue> duplicateHander;

static {
@SuppressWarnings("PMD.UseConcurrentHashMap")
Map<String, Duplicates> map = new HashMap<>();
@SuppressWarnings("PMD.UseConcurrentHashMap") Map<String, Duplicates> map = new HashMap<>();
for (Duplicates value : values()) {
map.put(value.getName(), value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ private static <V extends ICollectionValue> ISequence<?> execute(@NonNull IFunct
IItem focus) {
IMapItem<V> map = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0).getFirstItem(true)));
IAnyAtomicItem key = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(1).getFirstItem(true)));
@SuppressWarnings("unchecked")
V value = (V) ObjectUtils.requireNonNull(arguments.get(2)).toCollectionValue();
@SuppressWarnings("unchecked") V value = (V) ObjectUtils.requireNonNull(arguments.get(2)).toCollectionValue();

return put(map, key, value).asSequence();
}
Expand All @@ -95,8 +94,7 @@ public static <V extends ICollectionValue> IMapItem<V> put(
@NonNull IMapItem<V> map,
@NonNull IAnyAtomicItem key,
@NonNull V value) {
@SuppressWarnings("PMD.UseConcurrentHashMap")
Map<IMapKey, V> copy = new HashMap<>(map);
@SuppressWarnings("PMD.UseConcurrentHashMap") Map<IMapKey, V> copy = new HashMap<>(map);
copy.put(key.asMapKey(), value);

return IMapItem.ofCollection(copy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ public static ISequence<INodeItem> recurseDepth(

return ISequence.of(ObjectUtils.notNull(initialContext.stream()
.flatMap(item -> {
@NonNull
ISequence<INodeItem> metapathResult = recursionMetapath.evaluate(item, dynamicContext);
@NonNull ISequence<INodeItem> metapathResult = recursionMetapath.evaluate(item, dynamicContext);
// ensure this is list backed
metapathResult.getValue();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@

package gov.nist.secauto.metaschema.core.model.constraint;

import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
import gov.nist.secauto.metaschema.core.metapath.MetapathException;
import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
import gov.nist.secauto.metaschema.core.model.constraint.impl.DefaultLet;

import javax.xml.namespace.QName;

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

/**
* Represents a variable assignment for use in Metaschema module constraints.
*/
@SuppressWarnings("PMD.ShortClassName")
public interface ILet {
/**
Expand All @@ -25,16 +30,23 @@ public interface ILet {
* a Metapath expression string representing the variable value
* @param source
* the source descriptor for the resource containing the constraint
* @param remarks
* remarks about the let statement
* @return the original let statement with the same name or {@code null}
*/
@SuppressWarnings("PMD.ShortMethodName")
@NonNull
static ILet of(
@NonNull QName name,
@NonNull String valueExpression,
@NonNull ISource source) {
@NonNull ISource source,
@Nullable MarkupMultiline remarks) {
try {
return of(name, MetapathExpression.compile(valueExpression, source.getStaticContext()), source);
return of(
name,
MetapathExpression.compile(valueExpression, source.getStaticContext()),
source,
remarks);
} catch (MetapathException ex) {
throw new MetapathException(
String.format("Unable to compile the let expression '%s=%s'%s. %s",
Expand All @@ -55,15 +67,18 @@ static ILet of(
* a Metapath expression representing the variable value
* @param source
* the source descriptor for the resource containing the constraint
* @param remarks
* remarks about the let statement
* @return the original let statement with the same name or {@code null}
*/
@SuppressWarnings("PMD.ShortMethodName")
@NonNull
static ILet of(
@NonNull QName name,
@NonNull MetapathExpression valueExpression,
@NonNull ISource source) {
return new DefaultLet(name, valueExpression, source);
@NonNull ISource source,
@Nullable MarkupMultiline remarks) {
return new DefaultLet(name, valueExpression, source, remarks);
}

/**
Expand All @@ -89,4 +104,12 @@ static ILet of(
*/
@NonNull
ISource getSource();

/**
* Get the remarks associated with the let statement.
*
* @return the remark or {@code null} if no remarks are defined
*/
@Nullable
MarkupMultiline getRemarks();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,30 @@

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

import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
import gov.nist.secauto.metaschema.core.model.constraint.ILet;
import gov.nist.secauto.metaschema.core.model.constraint.ISource;

import javax.xml.namespace.QName;

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

/**
* A variable assignment for use in Metaschema module constraints.
* <p>
* This class is immutable.
*/
public class DefaultLet implements ILet {
@NonNull
private final QName name;
@NonNull
private final MetapathExpression valueExpression;
@NonNull
private final ISource source;
@Nullable
private final MarkupMultiline remarks;

/**
* Construct a new let statement.
Expand All @@ -30,14 +39,18 @@ public class DefaultLet implements ILet {
* the Metapath expression used to query the value
* @param source
* the source of the let statement
* @param remarks
* remarks about the let statement
*/
public DefaultLet(
@NonNull QName name,
@NonNull MetapathExpression metapath,
@NonNull ISource source) {
@NonNull ISource source,
@Nullable MarkupMultiline remarks) {
this.name = name;
this.valueExpression = metapath;
this.source = source;
this.remarks = remarks;
}

@Override
Expand All @@ -55,4 +68,9 @@ public MetapathExpression getValueExpression() {
public ISource getSource() {
return source;
}

@Override
public MarkupMultiline getRemarks() {
return remarks;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,14 @@ public static ICardinalityConstraint newCardinalityConstraint(
public static ILet newLet(
@NonNull ConstraintLetType xmlObject,
@NonNull ISource source) {

// TODO: figure out how to resolve the namespace prefix on var
return ILet.of(
new QName(xmlObject.getVar()),
ObjectUtils.notNull(xmlObject.getExpression()),
source);
source,
xmlObject.isSetRemarks()
? remarks(ObjectUtils.notNull(xmlObject.getRemarks()))
: null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,10 @@ private static void applyLetAssignments(
letAnnotation.addMember("name", "$S", let.getName());
letAnnotation.addMember("target", "$S", let.getValueExpression().getPath());

// TODO: Support remarks
// MarkupMultiline remarks = let.getRemarks();
// if (remarks != null) {
// constraintAnnotation.addMember("remarks", "$S",
// remarks.toMarkdown());
// }
MarkupMultiline remarks = let.getRemarks();
if (remarks != null) {
letAnnotation.addMember("remarks", "$S", remarks.toMarkdown());
}

annotation.addMember("lets", "$L", letAnnotation.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

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

/**
* Represents a constraint let statement used to assign the result of a Metapath
* expression to a variable.
*/
@Documented
@Retention(RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;

@SuppressWarnings("PMD.CouplingBetweenObjects")
final class ConstraintFactory {
private ConstraintFactory() {
// disable
Expand Down Expand Up @@ -324,6 +325,14 @@ static ICardinalityConstraint newCardinalityConstraint(@NonNull HasCardinality c

@NonNull
static ILet newLetExpression(@NonNull Let annotation, @NonNull ISource source) {
return ILet.of(new QName(annotation.name()), annotation.target(), source);
String remarkMarkdown = annotation.remarks();
MarkupMultiline remarks = remarkMarkdown.isBlank()
? null
: MarkupMultiline.fromMarkdown(remarkMarkdown);
return ILet.of(
new QName(annotation.name()),
annotation.target(),
source,
remarks);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter;
import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
import gov.nist.secauto.metaschema.core.model.constraint.AbstractConstraintBuilder;
import gov.nist.secauto.metaschema.core.model.constraint.AbstractKeyConstraintBuilder;
import gov.nist.secauto.metaschema.core.model.constraint.IAllowedValuesConstraint;
Expand All @@ -23,7 +24,6 @@
import gov.nist.secauto.metaschema.core.model.constraint.IUniqueConstraint;
import gov.nist.secauto.metaschema.core.model.constraint.IValueConstrained;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import gov.nist.secauto.metaschema.databind.model.binding.metaschema.ConstraintLetExpression;
import gov.nist.secauto.metaschema.databind.model.binding.metaschema.ConstraintValueEnum;
import gov.nist.secauto.metaschema.databind.model.binding.metaschema.FlagAllowedValues;
import gov.nist.secauto.metaschema.databind.model.binding.metaschema.FlagExpect;
Expand Down Expand Up @@ -53,11 +53,25 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;

/**
* Supports parsing constraints declared within a bound object.
*/
@SuppressWarnings("PMD.CouplingBetweenObjects")
public final class ConstraintBindingSupport {
private ConstraintBindingSupport() {
// disable construction
}

/**
* Parse a constraint set.
*
* @param constraintSet
* the parsed constraint set
* @param constraints
* the constraint definitions to parse
* @param source
* the source of the constraints
*/
public static void parse(
@NonNull IValueConstrained constraintSet,
@NonNull IValueConstraintsBase constraints,
Expand All @@ -82,6 +96,16 @@ public static void parse(
}
}

/**
* Parse a constraint set.
*
* @param constraintSet
* the parsed constraint set
* @param constraints
* the constraint definitions to parse
* @param source
* the source of the constraints
*/
public static void parse(
@NonNull IValueConstrained constraintSet,
@NonNull IValueTargetedConstraintsBase constraints,
Expand All @@ -106,6 +130,16 @@ public static void parse(
}
}

/**
* Parse a constraint set.
*
* @param constraintSet
* the parsed constraint set
* @param constraints
* the constraint definitions to parse
* @param source
* the source of the constraints
*/
public static void parse(
@NonNull IModelConstrained constraintSet,
@NonNull IModelConstraintsBase constraints,
Expand Down Expand Up @@ -139,17 +173,36 @@ public static void parse(
}
}

/**
* Parse the let clause in a constraint set.
*
* @param constraintSet
* the parsed constraint set
* @param constraints
* the constraint definitions to parse
* @param source
* the source of the constraint
*/
public static void parseLet(
@NonNull IValueConstrained constraintSet,
@NonNull IValueConstraintsBase constraints,
@NonNull ISource source) {
// parse let expressions
for (ConstraintLetExpression letObj : constraints.getLets()) {
ILet let = ILet.of(
ObjectUtils.requireNonNull(new QName(letObj.getVar())),
ObjectUtils.requireNonNull(letObj.getExpression()), source);
constraintSet.addLetExpression(let);
}
constraints.getLets().stream()
.map(letObj -> {
MarkupMultiline remarks = null;
Remarks remarkObj = letObj.getRemarks();
if (remarkObj != null) {
remarks = remarkObj.getRemark();
}

return ILet.of(
ObjectUtils.requireNonNull(new QName(letObj.getVar())),
ObjectUtils.requireNonNull(letObj.getExpression()),
source,
remarks);
})
.forEachOrdered(constraintSet::addLetExpression);
}

@NonNull
Expand Down
Loading

0 comments on commit d75ae34

Please sign in to comment.