Skip to content

Commit c00dc46

Browse files
Added support for the map:keys Metapath function.
1 parent e8ea04f commit c00dc46

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

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
@@ -232,6 +232,8 @@ public DefaultFunctionLibrary() { // NOPMD - intentional
232232
registerFunction(MapMerge.SIGNATURE_TWO_ARG);
233233
// https://www.w3.org/TR/xpath-functions-31/#func-map-size
234234
registerFunction(MapSize.SIGNATURE);
235+
// https://www.w3.org/TR/xpath-functions-31/#func-map-keys
236+
registerFunction(MapKeys.SIGNATURE);
235237

236238
// https://www.w3.org/TR/xpath-functions-31/#func-map-entry
237239
registerFunction(MapEntry.SIGNATURE);
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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.IAnyAtomicItem;
37+
import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem;
38+
import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey;
39+
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
40+
41+
import java.util.List;
42+
import java.util.Map;
43+
import java.util.stream.Stream;
44+
45+
import edu.umd.cs.findbugs.annotations.NonNull;
46+
47+
public class MapKeys {
48+
@NonNull
49+
static final IFunction SIGNATURE = IFunction.builder()
50+
.name("keys")
51+
.namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_MAP)
52+
.deterministic()
53+
.contextIndependent()
54+
.focusIndependent()
55+
.argument(IArgument.builder()
56+
.name("map")
57+
.type(IMapItem.class)
58+
.one()
59+
.build())
60+
.returnType(IAnyAtomicItem.class)
61+
.returnZeroOrMore()
62+
.functionHandler(MapKeys::execute)
63+
.build();
64+
65+
/**
66+
* An implementation of XPath 3.1 <a href=
67+
* "https://www.w3.org/TR/xpath-functions-31/#func-map-size">map:size</a>.
68+
*
69+
* @param array
70+
* the arrays to join
71+
* @return a new combined array
72+
*/
73+
@SuppressWarnings("unused")
74+
@NonNull
75+
private static ISequence<IAnyAtomicItem> execute(@NonNull IFunction function,
76+
@NonNull List<ISequence<?>> arguments,
77+
@NonNull DynamicContext dynamicContext,
78+
IItem focus) {
79+
IMapItem<?> map = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0).getFirstItem(true)));
80+
81+
return ISequence.of(keys(map));
82+
}
83+
84+
public static Stream<IAnyAtomicItem> keys(@NonNull IMapItem<?> map) {
85+
return keys((Map<IMapKey, ?>) map);
86+
}
87+
88+
public static Stream<IAnyAtomicItem> keys(@NonNull Map<IMapKey, ?> map) {
89+
return map.keySet().stream()
90+
.map(IMapKey::getKey);
91+
}
92+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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.ISequence;
34+
import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
35+
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
36+
37+
import org.junit.jupiter.api.Test;
38+
39+
import java.util.HashSet;
40+
import java.util.Set;
41+
42+
class MapKeysTest
43+
extends ExpressionTestBase {
44+
45+
@Test
46+
void test() {
47+
ISequence<IAnyAtomicItem> result = MetapathExpression.compile("map:keys(map{1:\"yes\", 2:\"no\"})")
48+
.evaluateAs(null, MetapathExpression.ResultType.SEQUENCE);
49+
// use a set to allow any ordering of the keys, since we have no control over
50+
// their order
51+
Set<IAnyAtomicItem> keys = new HashSet<>(result);
52+
53+
assertEquals(Set.of(integer(1), integer(2)), keys);
54+
}
55+
}

0 commit comments

Comments
 (0)