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.HashSet;
9   import java.util.List;
10  import java.util.Set;
11  
12  import dev.metaschema.core.metapath.IExpression;
13  import dev.metaschema.core.metapath.cst.IExpressionVisitor;
14  import dev.metaschema.core.metapath.item.IItem;
15  import dev.metaschema.core.metapath.item.ISequence;
16  import dev.metaschema.core.util.ObjectUtils;
17  import edu.umd.cs.findbugs.annotations.NonNull;
18  
19  /**
20   * The CST node for a Metapath
21   * <a href="https://www.w3.org/TR/xpath-31/#combining_seq">except
22   * expression</a>.
23   */
24  public class Except
25      extends AbstractFilterExpression {
26  
27    /**
28     * Construct a except filter expression, which removes the items resulting from
29     * the filter expression from the items expression.
30     *
31     * @param text
32     *          the parsed text of the expression
33     * @param itemsExpression
34     *          an expression indicating the items to filter
35     * @param filterExpression
36     *          an expression indicating the items to omit
37     */
38    public Except(
39        @NonNull String text,
40        @NonNull IExpression itemsExpression,
41        @NonNull IExpression filterExpression) {
42      super(text, itemsExpression, filterExpression);
43    }
44  
45    @Override
46    protected ISequence<?> applyFilterTo(@NonNull List<? extends IItem> source, @NonNull List<? extends IItem> items) {
47      Set<IItem> filterSet = new HashSet<>(items);
48      return ISequence.of(ObjectUtils.notNull(source.stream()
49          .filter(item -> !filterSet.contains(item))));
50    }
51  
52    @Override
53    public <RESULT, CONTEXT> RESULT accept(@NonNull IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
54      return visitor.visitExcept(this, context);
55    }
56  }