1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.metapath.function.library;
7   
8   import java.util.List;
9   
10  import dev.metaschema.core.metapath.DynamicContext;
11  import dev.metaschema.core.metapath.MetapathConstants;
12  import dev.metaschema.core.metapath.function.FunctionUtils;
13  import dev.metaschema.core.metapath.function.IArgument;
14  import dev.metaschema.core.metapath.function.IFunction;
15  import dev.metaschema.core.metapath.item.ICollectionValue;
16  import dev.metaschema.core.metapath.item.IItem;
17  import dev.metaschema.core.metapath.item.ISequence;
18  import dev.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
19  import dev.metaschema.core.metapath.item.function.IMapItem;
20  import dev.metaschema.core.util.ObjectUtils;
21  import edu.umd.cs.findbugs.annotations.NonNull;
22  import edu.umd.cs.findbugs.annotations.Nullable;
23  
24  /**
25   * Implements the XPath 3.1
26   * <a href= "https://www.w3.org/TR/xpath-functions-31/#func-map-get">map:get</a>
27   * function.
28   */
29  public final class MapGet {
30    private static final String NAME = "get";
31    @NonNull
32    static final IFunction SIGNATURE = IFunction.builder()
33        .name(NAME)
34        .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_MAP)
35        .deterministic()
36        .contextIndependent()
37        .focusIndependent()
38        .argument(IArgument.builder()
39            .name("map")
40            .type(IMapItem.type())
41            .one()
42            .build())
43        .argument(IArgument.builder()
44            .name("key")
45            .type(IAnyAtomicItem.type())
46            .one()
47            .build())
48        .returnType(IItem.type())
49        .returnZeroOrOne()
50        .functionHandler(MapGet::execute)
51        .build();
52  
53    private MapGet() {
54      // disable construction
55    }
56  
57    @SuppressWarnings("unused")
58    @NonNull
59    private static ISequence<?> execute(@NonNull IFunction function,
60        @NonNull List<ISequence<?>> arguments,
61        @NonNull DynamicContext dynamicContext,
62        IItem focus) {
63      IMapItem<?> map = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0).getFirstItem(true)));
64      IAnyAtomicItem key = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(1).getFirstItem(true)));
65  
66      ICollectionValue value = get(map, key);
67      return value == null ? ISequence.empty() : value.toSequence();
68    }
69  
70    /**
71     * An implementation of XPath 3.1 <a href=
72     * "https://www.w3.org/TR/xpath-functions-31/#func-map-get">map:get</a>.
73     *
74     * @param <V>
75     *          the type of items in the given Metapath map
76     * @param map
77     *          the map of Metapath items that is the target of retrieval
78     * @param key
79     *          the key for the item to retrieve
80     * @return the retrieved item
81     */
82    @Nullable
83    public static <V extends ICollectionValue> V get(
84        @NonNull IMapItem<V> map,
85        @NonNull IAnyAtomicItem key) {
86      return map.get(key.asMapKey());
87    }
88  }