Skip to content

Commit

Permalink
Added the fn:name Metapath function.
Browse files Browse the repository at this point in the history
Added support for node items that are backed by a data model implementation.
  • Loading branch information
david-waltermire committed Dec 10, 2024
1 parent deb73be commit 2262817
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 110 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.metapath.function.library;

import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
import gov.nist.secauto.metaschema.core.metapath.MetapathConstants;
import gov.nist.secauto.metaschema.core.metapath.StaticContext;
import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils;
import gov.nist.secauto.metaschema.core.metapath.function.IArgument;
import gov.nist.secauto.metaschema.core.metapath.function.IFunction;
import gov.nist.secauto.metaschema.core.metapath.item.IItem;
import gov.nist.secauto.metaschema.core.metapath.item.ISequence;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.IDefinitionNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import java.util.List;

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

/**
* /** Implements
* <a href= "https://www.w3.org/TR/xpath-functions-31/#func-name">fn:name</a>
* functions.
*/
public final class FnName {
@NonNull
private static final String NAME = "name";
@NonNull
static final IFunction SIGNATURE_NO_ARG = IFunction.builder()
.name(NAME)
.namespace(MetapathConstants.NS_METAPATH_FUNCTIONS)
.deterministic()
.contextDependent()
.focusDependent()
.returnType(IStringItem.type())
.returnOne()
.functionHandler(FnName::executeNoArg)
.build();
@NonNull
static final IFunction SIGNATURE_ONE_ARG = IFunction.builder()
.name(NAME)
.namespace(MetapathConstants.NS_METAPATH_FUNCTIONS)
.deterministic()
.contextIndependent()
.focusDependent()
.argument(IArgument.builder()
.name("arg")
.type(INodeItem.type())
.zeroOrOne()
.build())
.returnType(IStringItem.type())
.returnOne()
.functionHandler(FnName::executeOneArg)
.build();

@SuppressWarnings("unused")
@NonNull
private static ISequence<IStringItem> executeNoArg(@NonNull IFunction function,
@NonNull List<ISequence<?>> arguments,
@NonNull DynamicContext dynamicContext,
IItem focus) {

INodeItem arg = FunctionUtils.asType(ObjectUtils.requireNonNull(focus));

return ISequence.of(
IStringItem.valueOf(fnName(arg, dynamicContext.getStaticContext())));
}

@SuppressWarnings("unused")
@NonNull
private static ISequence<IStringItem> executeOneArg(@NonNull IFunction function,
@NonNull List<ISequence<?>> arguments,
@NonNull DynamicContext dynamicContext,
IItem focus) {
INodeItem arg = FunctionUtils.asTypeOrNull(ObjectUtils.requireNonNull(arguments.get(0)).getFirstItem(true));

return ISequence.of(
IStringItem.valueOf(arg == null ? "" : fnName(arg, dynamicContext.getStaticContext())));
}

/**
* Get the name of the provided node item.
* <p>
* Based on the XPath 3.1
* <a href= "https://www.w3.org/TR/xpath-functions-31/#func-name">fn:name</a>
* function.
*
* @param arg
* the node item to get the name for
* @param staticContext
* the static context used to resolve the namespace prefix
* @return the name of the node if it has one, or an empty string otherwise
*/
@NonNull
public static String fnName(@NonNull INodeItem arg, @NonNull StaticContext staticContext) {
return arg instanceof IDefinitionNodeItem
? ((IDefinitionNodeItem<?, ?>) arg).getQName().toEQName(staticContext)
: "";
}

private FnName() {
// disable construction
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,14 @@
import gov.nist.secauto.metaschema.core.metapath.function.IArgument;
import gov.nist.secauto.metaschema.core.metapath.item.ICollectionValue;
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.item.atomic.IIntegerItem;
import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem;
import gov.nist.secauto.metaschema.core.metapath.type.ISequenceType;
import gov.nist.secauto.metaschema.core.metapath.type.Occurrence;
import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import edu.umd.cs.findbugs.annotations.NonNull;
Expand All @@ -36,18 +31,12 @@
*/
public abstract class AbstractArrayItem<ITEM extends ICollectionValue>
extends ImmutableCollections.AbstractImmutableDelegatedList<ITEM>
implements IArrayItem<ITEM> {
implements IArrayItem<ITEM>, IFeatureCollectionFunctionItem {
@NonNull
private static final IEnhancedQName QNAME = IEnhancedQName.of("array");
@NonNull
private static final Set<FunctionProperty> PROPERTIES = ObjectUtils.notNull(
EnumSet.of(FunctionProperty.DETERMINISTIC));
@NonNull
private static final List<IArgument> ARGUMENTS = ObjectUtils.notNull(List.of(
IArgument.builder().name("position").type(IIntegerItem.type()).one().build()));
@NonNull
private static final ISequenceType RESULT = ISequenceType.of(
IAnyAtomicItem.type(), Occurrence.ZERO_OR_ONE);

@NonNull
private static final IArrayItem<?> EMPTY = new ArrayItemN<>();
Expand All @@ -65,51 +54,16 @@ public static <T extends ICollectionValue> IArrayItem<T> empty() {
return (IArrayItem<T>) EMPTY;
}

@Override
public boolean isDeterministic() {
return true;
}

@Override
public boolean isContextDepenent() {
return false;
}

@Override
public boolean isFocusDependent() {
return false;
}

@Override
public IEnhancedQName getQName() {
return QNAME;
}

@Override
public Set<FunctionProperty> getProperties() {
return PROPERTIES;
}

@Override
public List<IArgument> getArguments() {
return ARGUMENTS;
}

@Override
public int arity() {
return 1;
}

@Override
public boolean isArityUnbounded() {
return false;
}

@Override
public ISequenceType getResult() {
return RESULT;
}

@Override
public ISequence<?> execute(List<? extends ISequence<?>> arguments, DynamicContext dynamicContext,
ISequence<?> focus) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,13 @@
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIntegerItem;
import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem;
import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey;
import gov.nist.secauto.metaschema.core.metapath.type.ISequenceType;
import gov.nist.secauto.metaschema.core.metapath.type.Occurrence;
import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import edu.umd.cs.findbugs.annotations.NonNull;
Expand All @@ -39,29 +35,19 @@
*/
public abstract class AbstractMapItem<VALUE extends ICollectionValue>
extends ImmutableCollections.AbstractImmutableDelegatedMap<IMapKey, VALUE>
implements IMapItem<VALUE> {
implements IMapItem<VALUE>, IFeatureCollectionFunctionItem {
/**
* The function qualified name.
*/
@NonNull
private static final IEnhancedQName QNAME = IEnhancedQName.of("map");
/**
* The function properties.
*/
@NonNull
private static final Set<FunctionProperty> PROPERTIES = ObjectUtils.notNull(
EnumSet.of(FunctionProperty.DETERMINISTIC));
/**
* The function arguments.
*/
@NonNull
private static final List<IArgument> ARGUMENTS = ObjectUtils.notNull(List.of(
IArgument.builder().name("key").type(IAnyAtomicItem.type()).one().build()));
@NonNull
private static final ISequenceType RESULT = ISequenceType.of(
IAnyAtomicItem.type(), Occurrence.ZERO_OR_ONE);

@NonNull
private static final IMapItem<?> EMPTY = new MapItemN<>();

/**
Expand All @@ -78,51 +64,16 @@ public static <V extends ICollectionValue> IMapItem<V> empty() {
return (IMapItem<V>) EMPTY;
}

@Override
public boolean isDeterministic() {
return true;
}

@Override
public boolean isContextDepenent() {
return false;
}

@Override
public boolean isFocusDependent() {
return false;
}

@Override
public IEnhancedQName getQName() {
return QNAME;
}

@Override
public Set<FunctionProperty> getProperties() {
return PROPERTIES;
}

@Override
public List<IArgument> getArguments() {
return ARGUMENTS;
}

@Override
public int arity() {
return 1;
}

@Override
public boolean isArityUnbounded() {
return false;
}

@Override
public ISequenceType getResult() {
return RESULT;
}

@Override
public ISequence<?> execute(List<? extends ISequence<?>> arguments, DynamicContext dynamicContext,
ISequence<?> focus) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

package gov.nist.secauto.metaschema.core.metapath.impl;

import gov.nist.secauto.metaschema.core.metapath.function.IFunction;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
import gov.nist.secauto.metaschema.core.metapath.type.ISequenceType;
import gov.nist.secauto.metaschema.core.metapath.type.Occurrence;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import java.util.EnumSet;
import java.util.Set;

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

public interface IFeatureCollectionFunctionItem extends IFunction {
/**
* The function properties.
*/
@NonNull
Set<FunctionProperty> PROPERTIES = ObjectUtils.notNull(
EnumSet.of(FunctionProperty.DETERMINISTIC));
/**
* The function result.
*/
@NonNull
ISequenceType RESULT = ISequenceType.of(
IAnyAtomicItem.type(), Occurrence.ZERO_OR_ONE);

@Override
default boolean isDeterministic() {
return true;
}

@Override
default boolean isContextDepenent() {
return false;
}

@Override
default boolean isFocusDependent() {
return false;
}

@Override
default Set<FunctionProperty> getProperties() {
return PROPERTIES;
}

@Override
default int arity() {
return 1;
}

@Override
default boolean isArityUnbounded() {
return false;
}

@Override
default ISequenceType getResult() {
return RESULT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

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

abstract class AbstractDefinitionNodeItem<D extends IDefinition, I extends INamedInstance>
public abstract class AbstractDefinitionNodeItem<D extends IDefinition, I extends INamedInstance>
extends AbstractNodeItem
implements IFeatureOrhpanedDefinitionNodeItem<D, I> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* A {@link INodeItem} supported by a {@link IFlagInstance}.
*/
abstract class AbstractFlagInstanceNodeItem
public abstract class AbstractFlagInstanceNodeItem
extends AbstractInstanceNodeItem<IFlagDefinition, IFlagInstance, IModelNodeItem<?, ?>>
implements IFlagNodeItem {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @param <D>
* the definition type
*/
abstract class AbstractGlobalDefinitionNodeItem<D extends IDefinition, I extends INamedInstance>
public abstract class AbstractGlobalDefinitionNodeItem<D extends IDefinition, I extends INamedInstance>
extends AbstractDefinitionNodeItem<D, I> {
@NonNull
private final IModuleNodeItem metaschemaNodeItem;
Expand Down
Loading

0 comments on commit 2262817

Please sign in to comment.