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.cst.AbstractExpression;
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.metapath.item.node.INodeItem;
14  import dev.metaschema.core.metapath.type.IItemType;
15  import dev.metaschema.core.util.ObjectUtils;
16  import edu.umd.cs.findbugs.annotations.NonNull;
17  
18  /**
19   * The CST node for a Metapath
20   * <a href="https://www.w3.org/TR/xpath-31/#dt-expanded-qname">expanded QName
21   * name test</a>.
22   */
23  @SuppressWarnings("PMD.TestClassWithoutTestCases")
24  public class KindNodeTest
25      extends AbstractExpression
26      implements INodeTestExpression {
27  
28    @NonNull
29    private final IItemType type;
30  
31    /**
32     * Construct a new kind test expression.
33     *
34     * @param text
35     *          the parsed text of the expression
36     * @param type
37     *          the expected item type to test against
38     */
39    public KindNodeTest(@NonNull String text, @NonNull IItemType type) {
40      super(text);
41      this.type = type;
42    }
43  
44    @Override
45    public <RESULT, CONTEXT> RESULT accept(IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
46      return visitor.visitKindNodeTest(this, context);
47    }
48  
49    @Override
50    protected ISequence<? extends INodeItem> evaluate(DynamicContext dynamicContext, ISequence<?> focus) {
51      return ISequence.of(filterStream(ObjectUtils.notNull(focus.stream()
52          .map(item -> ItemUtils.checkItemIsNodeItem(dynamicContext, item)))));
53    }
54  
55    @SuppressWarnings("null")
56    @Override
57    public String toCSTString() {
58      return String.format("%s[kind=%s]", getClass().getName(), type.toSignature());
59    }
60  
61    @Override
62    public boolean match(INodeItem item) {
63      return type.isInstance(item);
64    }
65  }