1
2
3
4
5
6 package dev.metaschema.core.metapath.cst;
7
8 import java.util.List;
9 import java.util.stream.Collectors;
10 import java.util.stream.Stream;
11
12 import dev.metaschema.core.metapath.DynamicContext;
13 import dev.metaschema.core.metapath.IExpression;
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.type.InvalidTypeMetapathException;
18 import dev.metaschema.core.util.ObjectUtils;
19 import edu.umd.cs.findbugs.annotations.NonNull;
20
21
22
23
24
25
26 public class FunctionCallAccessor
27 extends AbstractExpression {
28 @NonNull
29 private final IExpression base;
30 @NonNull
31 private final List<IExpression> arguments;
32
33
34
35
36
37
38
39
40
41
42
43
44 public FunctionCallAccessor(@NonNull String text, @NonNull IExpression base, @NonNull List<IExpression> arguments) {
45 super(text);
46 this.base = base;
47 this.arguments = arguments;
48 }
49
50
51
52
53
54
55 @NonNull
56 public IExpression getBase() {
57 return base;
58 }
59
60
61
62
63
64
65 @NonNull
66 public List<IExpression> getArguments() {
67 return arguments;
68 }
69
70 @SuppressWarnings("null")
71 @Override
72 public List<IExpression> getChildren() {
73 return Stream.concat(Stream.of(getBase()), getArguments().stream())
74 .collect(Collectors.toUnmodifiableList());
75 }
76
77 @Override
78 protected ISequence<?> evaluate(DynamicContext dynamicContext, ISequence<?> focus) {
79 ISequence<?> target = getBase().accept(dynamicContext, focus);
80 IItem collection = target.getFirstItem(true);
81
82 if (!(collection instanceof IFunction)) {
83 throw new InvalidTypeMetapathException(
84 collection,
85 "The base expression did not evaluate to a function.")
86 .registerEvaluationContext(dynamicContext);
87 }
88
89 return ((IFunction) collection).execute(ObjectUtils.notNull(getArguments().stream()
90 .map(expr -> expr.accept(dynamicContext, focus))
91 .collect(Collectors.toUnmodifiableList())), dynamicContext, focus);
92 }
93
94 @Override
95 public <RESULT, CONTEXT> RESULT accept(@NonNull IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
96 return visitor.visitFunctionCallAccessor(this, context);
97 }
98 }