Skip to content

Commit 5b5e434

Browse files
Added support for the array:append Metapath function.
1 parent aa516cd commit 5b5e434

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Portions of this software was developed by employees of the National Institute
3+
* of Standards and Technology (NIST), an agency of the Federal Government and is
4+
* being made available as a public service. Pursuant to title 17 United States
5+
* Code Section 105, works of NIST employees are not subject to copyright
6+
* protection in the United States. This software may be subject to foreign
7+
* copyright. Permission in the United States and in foreign countries, to the
8+
* extent that NIST may hold copyright, to use, copy, modify, create derivative
9+
* works, and distribute this software and its documentation without fee is hereby
10+
* granted on a non-exclusive basis, provided that this notice and disclaimer
11+
* of warranty appears in all copies.
12+
*
13+
* THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
14+
* EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
15+
* THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
16+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
17+
* INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
18+
* SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT
19+
* SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
20+
* INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
21+
* OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
22+
* CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
23+
* PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
24+
* OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
25+
*/
26+
27+
package gov.nist.secauto.metaschema.core.metapath.function.library;
28+
29+
import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
30+
import gov.nist.secauto.metaschema.core.metapath.ISequence;
31+
import gov.nist.secauto.metaschema.core.metapath.MetapathConstants;
32+
import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils;
33+
import gov.nist.secauto.metaschema.core.metapath.function.IArgument;
34+
import gov.nist.secauto.metaschema.core.metapath.function.IFunction;
35+
import gov.nist.secauto.metaschema.core.metapath.item.IItem;
36+
import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem;
37+
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
38+
39+
import java.util.ArrayList;
40+
import java.util.List;
41+
42+
import edu.umd.cs.findbugs.annotations.NonNull;
43+
44+
public class ArrayAppend {
45+
@NonNull
46+
public static final IFunction SIGNATURE = IFunction.builder()
47+
.name("append")
48+
.namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_ARRAY)
49+
.argument(IArgument.builder()
50+
.name("array")
51+
.type(IArrayItem.class)
52+
.one()
53+
.build())
54+
.argument(IArgument.builder()
55+
.name("appendage")
56+
.type(IItem.class)
57+
.zeroOrMore()
58+
.build())
59+
.returnType(IArrayItem.class)
60+
.returnOne()
61+
.functionHandler(ArrayAppend::execute)
62+
.build();
63+
64+
@SuppressWarnings("unused")
65+
@NonNull
66+
private static <T extends IItem> ISequence<IArrayItem<T>> execute(@NonNull IFunction function,
67+
@NonNull List<ISequence<?>> arguments,
68+
@NonNull DynamicContext dynamicContext,
69+
IItem focus) {
70+
IArrayItem<T> array = FunctionUtils.asType(ObjectUtils.requireNonNull(
71+
arguments.get(0).getFirstItem(true)));
72+
T appendage = FunctionUtils.asType(arguments.get(1).toArrayMember());
73+
74+
return ISequence.of(append(array, appendage));
75+
}
76+
77+
/**
78+
* An implementation of XPath 3.1 <a href=
79+
* "https://www.w3.org/TR/xpath-functions-31/#func-array-append">array:append</a>.
80+
*
81+
* @param <T>
82+
* the type of items in the given Metapath array
83+
* @param array
84+
* the target Metapath array
85+
* @param appendage
86+
* the Metapath item to append to the identified array
87+
* @return a new array containing the modification
88+
*/
89+
@SuppressWarnings("PMD.OnlyOneReturn")
90+
@NonNull
91+
public static <T extends IItem> IArrayItem<T> append(
92+
@NonNull IArrayItem<T> array,
93+
@NonNull T appendage) {
94+
95+
List<T> copy = new ArrayList<>(array);
96+
copy.add(appendage);
97+
98+
return IArrayItem.ofCollection(copy);
99+
}
100+
}

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ public DefaultFunctionLibrary() { // NOPMD - intentional
199199
registerFunction(ArraySize.SIGNATURE);
200200
// https://www.w3.org/TR/xpath-functions-31/#func-array-put
201201
registerFunction(ArrayPut.SIGNATURE);
202+
// https://www.w3.org/TR/xpath-functions-31/#func-array-append
203+
registerFunction(ArrayAppend.SIGNATURE);
202204

203205
// xpath casting functions
204206
registerFunction(
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Portions of this software was developed by employees of the National Institute
3+
* of Standards and Technology (NIST), an agency of the Federal Government and is
4+
* being made available as a public service. Pursuant to title 17 United States
5+
* Code Section 105, works of NIST employees are not subject to copyright
6+
* protection in the United States. This software may be subject to foreign
7+
* copyright. Permission in the United States and in foreign countries, to the
8+
* extent that NIST may hold copyright, to use, copy, modify, create derivative
9+
* works, and distribute this software and its documentation without fee is hereby
10+
* granted on a non-exclusive basis, provided that this notice and disclaimer
11+
* of warranty appears in all copies.
12+
*
13+
* THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
14+
* EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
15+
* THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
16+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
17+
* INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
18+
* SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT
19+
* SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
20+
* INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
21+
* OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
22+
* CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
23+
* PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
24+
* OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
25+
*/
26+
27+
package gov.nist.secauto.metaschema.core.metapath.function.library;
28+
29+
import static gov.nist.secauto.metaschema.core.metapath.TestUtils.array;
30+
import static gov.nist.secauto.metaschema.core.metapath.TestUtils.string;
31+
import static org.junit.jupiter.api.Assertions.assertEquals;
32+
33+
import gov.nist.secauto.metaschema.core.metapath.ExpressionTestBase;
34+
import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
35+
import gov.nist.secauto.metaschema.core.metapath.item.IItem;
36+
37+
import org.junit.jupiter.params.ParameterizedTest;
38+
import org.junit.jupiter.params.provider.Arguments;
39+
import org.junit.jupiter.params.provider.MethodSource;
40+
41+
import java.util.stream.Stream;
42+
43+
import edu.umd.cs.findbugs.annotations.NonNull;
44+
45+
class ArrayAppendTest
46+
extends ExpressionTestBase {
47+
private static Stream<Arguments> provideValues() { // NOPMD - false positive
48+
return Stream.of(
49+
Arguments.of(
50+
array(string("a"), string("b"), string("c"), string("d")),
51+
"array:append([\"a\", \"b\", \"c\"], \"d\")"),
52+
Arguments.of(
53+
array(string("a"), string("b"), string("c"), array(string("d"), string("e"))),
54+
"array:append([\"a\", \"b\", \"c\"], (\"d\", \"e\"))"));
55+
}
56+
57+
@ParameterizedTest
58+
@MethodSource("provideValues")
59+
void testExpression(@NonNull IItem expected, @NonNull String metapath) {
60+
61+
IItem result = MetapathExpression.compile(metapath)
62+
.evaluateAs(null, MetapathExpression.ResultType.NODE, newDynamicContext());
63+
assertEquals(expected, result);
64+
}
65+
}

0 commit comments

Comments
 (0)