1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.metapath.cst.path;
7   
8   import dev.metaschema.core.metapath.DynamicContext;
9   import dev.metaschema.core.metapath.IExpression;
10  import dev.metaschema.core.metapath.cst.IExpressionVisitor;
11  import dev.metaschema.core.metapath.item.ISequence;
12  import dev.metaschema.core.metapath.item.ItemUtils;
13  import dev.metaschema.core.util.CustomCollectors;
14  import dev.metaschema.core.util.ObjectUtils;
15  import edu.umd.cs.findbugs.annotations.NonNull;
16  
17  /**
18   * An expression that finds a child of the document root using the {@code right}
19   * expression.
20   * <p>
21   * Based on the XPath 3.1
22   * <a href= "https://www.w3.org/TR/xpath-31/#id-path-operator">path
23   * operator</a>.
24   */
25  public class RootSlashPath
26      extends AbstractRootPathExpression {
27  
28    /**
29     * Construct a new expression that finds a child of the document root using the
30     * {@code node} expression.
31     *
32     * @param text
33     *          the parsed text of the expression
34     * @param node
35     *          the path to evaluate relative to the document root
36     */
37    public RootSlashPath(@NonNull String text, @NonNull IExpression node) {
38      super(text, node);
39    }
40  
41    @Override
42    public <RESULT, CONTEXT> RESULT accept(IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
43      return visitor.visitRootSlashPath(this, context);
44    }
45  
46    @Override
47    protected ISequence<?> evaluate(DynamicContext dynamicContext, ISequence<?> focus) {
48      ISequence<?> roots = ObjectUtils.notNull(focus.stream()
49          .map(item -> ItemUtils.checkItemIsNodeItem(dynamicContext, item))
50          // the previous checks for a null instance
51          .flatMap(item -> Axis.ANCESTOR_OR_SELF.execute(ObjectUtils.notNull(item)).limit(1))
52          .collect(CustomCollectors.toSequence()));
53      return getExpression().accept(dynamicContext, roots);
54    }
55  }