1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.metapath.cst.items;
7   
8   import java.util.List;
9   
10  import dev.metaschema.core.metapath.DynamicContext;
11  import dev.metaschema.core.metapath.IExpression;
12  import dev.metaschema.core.metapath.cst.IExpressionVisitor;
13  import dev.metaschema.core.metapath.item.ICollectionValue;
14  import dev.metaschema.core.metapath.item.IItem;
15  import dev.metaschema.core.metapath.item.ISequence;
16  import dev.metaschema.core.metapath.item.function.IArrayItem;
17  import dev.metaschema.core.metapath.item.function.IKeySpecifier;
18  import dev.metaschema.core.metapath.item.function.IMapItem;
19  import dev.metaschema.core.util.ObjectUtils;
20  import edu.umd.cs.findbugs.annotations.NonNull;
21  
22  /**
23   * An implementation of
24   * <a href="https://www.w3.org/TR/xpath-31/#id-unary-lookup">Unary Lookup
25   * Operators</a> supporting access to items in Metapath maps and arrays.
26   * <p>
27   * Provides support for various types of key- and index-based lookups related to
28   * {@link IMapItem} and {@link IArrayItem} objects.
29   */
30  public class UnaryLookup
31      extends AbstractLookup {
32    /**
33     * Construct a new unary lookup expression that uses the provided key specifier.
34     *
35     * @param text
36     *          the parsed text of the expression
37     * @param keySpecifier
38     *          the key specifier used to determine matching entries
39     */
40    public UnaryLookup(@NonNull String text, @NonNull IKeySpecifier keySpecifier) {
41      super(text, keySpecifier);
42    }
43  
44    @SuppressWarnings("null")
45    @Override
46    public List<? extends IExpression> getChildren() {
47      return List.of();
48    }
49  
50    @Override
51    protected ISequence<? extends IItem> evaluate(DynamicContext dynamicContext, ISequence<?> focus) {
52      IKeySpecifier specifier = getKeySpecifier();
53  
54      return ISequence.of(ObjectUtils.notNull(focus.stream()
55          .flatMap(item -> {
56            assert item != null;
57            return specifier.lookup(item, dynamicContext, focus);
58          })
59          .flatMap(ICollectionValue::normalizeAsItems)));
60    }
61  
62    @Override
63    public <RESULT, CONTEXT> RESULT accept(@NonNull IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
64      return visitor.visitUnaryLookup(this, context);
65    }
66  }