Skip to content

Commit e8ea04f

Browse files
Added support for the map:size Metapath function. Fixed a bug causing empty maps to not be constructed properly.
1 parent b58559d commit e8ea04f

File tree

4 files changed

+148
-1
lines changed

4 files changed

+148
-1
lines changed

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/BuildCSTVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ protected IExpression handleLet(LetexprContext context) {
273273

274274
@Override
275275
protected MapConstructor handleMapConstructor(MapconstructorContext context) {
276-
return context.getChildCount() == 2
276+
return context.getChildCount() == 3
277277
// empty
278278
? new MapConstructor(CollectionUtil.emptyList())
279279
// with members

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
@@ -230,6 +230,8 @@ public DefaultFunctionLibrary() { // NOPMD - intentional
230230
// https://www.w3.org/TR/xpath-functions-31/#func-map-merge
231231
registerFunction(MapMerge.SIGNATURE_ONE_ARG);
232232
registerFunction(MapMerge.SIGNATURE_TWO_ARG);
233+
// https://www.w3.org/TR/xpath-functions-31/#func-map-size
234+
registerFunction(MapSize.SIGNATURE);
233235

234236
// https://www.w3.org/TR/xpath-functions-31/#func-map-entry
235237
registerFunction(MapEntry.SIGNATURE);
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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.atomic.IIntegerItem;
37+
import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem;
38+
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
39+
40+
import java.util.List;
41+
42+
import edu.umd.cs.findbugs.annotations.NonNull;
43+
44+
public class MapSize {
45+
@NonNull
46+
static final IFunction SIGNATURE = IFunction.builder()
47+
.name("size")
48+
.namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_MAP)
49+
.deterministic()
50+
.contextIndependent()
51+
.focusIndependent()
52+
.argument(IArgument.builder()
53+
.name("map")
54+
.type(IMapItem.class)
55+
.one()
56+
.build())
57+
.returnType(IIntegerItem.class)
58+
.returnOne()
59+
.functionHandler(MapSize::execute)
60+
.build();
61+
62+
/**
63+
* An implementation of XPath 3.1 <a href=
64+
* "https://www.w3.org/TR/xpath-functions-31/#func-map-size">map:size</a>.
65+
*
66+
* @param array
67+
* the arrays to join
68+
* @return a new combined array
69+
*/
70+
@SuppressWarnings("unused")
71+
@NonNull
72+
private static ISequence<IIntegerItem> execute(@NonNull IFunction function,
73+
@NonNull List<ISequence<?>> arguments,
74+
@NonNull DynamicContext dynamicContext,
75+
IItem focus) {
76+
IMapItem<?> map = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0).getFirstItem(true)));
77+
78+
return ISequence.of(IIntegerItem.valueOf(map.size()));
79+
}
80+
}
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.integer;
30+
import static org.junit.jupiter.api.Assertions.assertEquals;
31+
32+
import gov.nist.secauto.metaschema.core.metapath.ExpressionTestBase;
33+
import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
34+
import gov.nist.secauto.metaschema.core.metapath.item.IItem;
35+
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIntegerItem;
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 MapSizeTest
46+
extends ExpressionTestBase {
47+
private static Stream<Arguments> provideValues() { // NOPMD - false positive
48+
return Stream.of(
49+
Arguments.of(
50+
integer(0),
51+
"map:size(map{})"),
52+
Arguments.of(
53+
integer(2),
54+
"map:size(map{\"true\":1, \"false\":0})"));
55+
}
56+
57+
@ParameterizedTest
58+
@MethodSource("provideValues")
59+
void testExpression(@NonNull IIntegerItem 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)