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.IItem;
16  import dev.metaschema.core.metapath.item.ISequence;
17  import dev.metaschema.core.metapath.item.atomic.IBooleanItem;
18  import dev.metaschema.core.util.ObjectUtils;
19  import edu.umd.cs.findbugs.annotations.NonNull;
20  
21  /**
22   * /** Implements <a href=
23   * "https://www.w3.org/TR/xpath-functions-31/#func-deep-equal">fn:deep-equal</a>
24   * functions.
25   * <p>
26   * This implementation does not implement the three-arg variant with collation
27   * at this time.
28   */
29  public final class FnDeepEqual {
30    @NonNull
31    private static final String NAME = "deep-equal";
32    @NonNull
33    static final IFunction SIGNATURE_TWO_ARG = IFunction.builder()
34        .name(NAME)
35        .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS)
36        .deterministic()
37        .contextDependent()
38        .focusIndependent()
39        .argument(IArgument.builder()
40            .name("parameter1")
41            .type(IItem.type())
42            .zeroOrMore()
43            .build())
44        .argument(IArgument.builder()
45            .name("parameter2")
46            .type(IItem.type())
47            .zeroOrMore()
48            .build())
49        .returnType(IBooleanItem.type())
50        .returnOne()
51        .functionHandler(FnDeepEqual::executeTwoArg)
52        .build();
53  
54    @SuppressWarnings("unused")
55    @NonNull
56    private static ISequence<IBooleanItem> executeTwoArg(@NonNull IFunction function,
57        @NonNull List<ISequence<?>> arguments,
58        @NonNull DynamicContext dynamicContext,
59        IItem focus) {
60      ISequence<?> parameter1
61          = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0)));
62      ISequence<?> parameter2
63          = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(1)));
64  
65      // FIXME: support implicit timezone
66      return ISequence.of(
67          IBooleanItem.valueOf(parameter1.deepEquals(parameter2, dynamicContext)));
68    }
69  
70    private FnDeepEqual() {
71      // disable construction
72    }
73  }