• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.9
/exist-core/src/main/java/org/exist/xquery/functions/util/BuiltinFunctions.java
1
/*
1✔
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 *
24
 * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
25
 *       The original license header is included below.
26
 *
27
 * =====================================================================
28
 *
29
 * eXist-db Open Source Native XML Database
30
 * Copyright (C) 2001 The eXist-db Authors
31
 *
32
 * info@exist-db.org
33
 * http://www.exist-db.org
34
 *
35
 * This library is free software; you can redistribute it and/or
36
 * modify it under the terms of the GNU Lesser General Public
37
 * License as published by the Free Software Foundation; either
38
 * version 2.1 of the License, or (at your option) any later version.
39
 *
40
 * This library is distributed in the hope that it will be useful,
41
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
42
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
43
 * Lesser General Public License for more details.
44
 *
45
 * You should have received a copy of the GNU Lesser General Public
46
 * License along with this library; if not, write to the Free Software
47
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
48
 */
49
package org.exist.xquery.functions.util;
50

51
import org.apache.logging.log4j.LogManager;
52
import org.apache.logging.log4j.Logger;
53
import org.exist.dom.QName;
54
import org.exist.xquery.Module;
55
import org.exist.xquery.*;
56
import org.exist.xquery.functions.fn.FunOnFunctions;
57
import org.exist.xquery.value.*;
58

59
import javax.annotation.Nullable;
60
import java.util.Iterator;
61
import java.util.Set;
62
import java.util.TreeSet;
63
import java.util.stream.StreamSupport;
64

65
/**
66
 * Returns a sequence containing the QNames of all built-in functions
67
 * currently registered in the query engine.
68
 *
69
 * @author wolf
70
 */
71
public class BuiltinFunctions extends BasicFunction {
72

73
        protected static final Logger logger = LogManager.getLogger(BuiltinFunctions.class);
1✔
74

75
        public final static FunctionSignature[] signatures = {
1✔
76
                        new FunctionSignature(
1✔
77
                                        new QName("registered-functions", UtilModule.NAMESPACE_URI, UtilModule.PREFIX),
1✔
78
                                        "Returns a sequence containing the QNames of all functions " +
1✔
79
                                                        "declared in the module identified by the specified namespace URI. " +
80
                                                        "An error is raised if no module is found for the specified URI.",
81
                                        new SequenceType[] { new FunctionParameterSequenceType("namespace-uri", Type.STRING, Cardinality.EXACTLY_ONE, "The namespace URI of the function module") },
1✔
82
                                        new FunctionReturnSequenceType(Type.STRING, Cardinality.ONE_OR_MORE, "the sequence of function names")),
1✔
83
                        new FunctionSignature(
1✔
84
                                        new QName("registered-functions", UtilModule.NAMESPACE_URI, UtilModule.PREFIX),
1✔
85
                                        "Returns a sequence containing the QNames of all functions " +
1✔
86
                                                        "currently known to the system, including functions in imported and built-in modules.",
87
                                        null,
1✔
88
                                        new FunctionReturnSequenceType(Type.STRING, Cardinality.ONE_OR_MORE, "the sequence of function names")),
1✔
89
                        new FunctionSignature(
1✔
90
                                        new QName("declared-variables", UtilModule.NAMESPACE_URI, UtilModule.PREFIX),
1✔
91
                                        "Returns a sequence containing the QNames of all variables " +
1✔
92
                                                        "declared in the module identified by the specified namespace URI. " +
93
                                                        "An error is raised if no module is found for the specified URI.",
94
                                        new SequenceType[] { new FunctionParameterSequenceType("namespace-uri", Type.STRING, Cardinality.EXACTLY_ONE, "The namespace URI of the function module") },
1✔
95
                                        new FunctionReturnSequenceType(Type.STRING, Cardinality.ONE_OR_MORE, "the sequence of function names")),
1✔
96
                        new FunctionSignature(
1✔
97
                                        new QName("list-functions", UtilModule.NAMESPACE_URI, UtilModule.PREFIX),
1✔
98
                                        "Returns a sequence of function items for each function in the current module.",
1✔
99
                                        null,
1✔
100
                                        new FunctionReturnSequenceType(Type.FUNCTION, Cardinality.ZERO_OR_MORE, "sequence of function references"),
1✔
101
                                        "Use inspect:module-functions#0 instead."),
1✔
102
                        new FunctionSignature(
1✔
103
                                        new QName("list-functions", UtilModule.NAMESPACE_URI, UtilModule.PREFIX),
1✔
104
                                        "Returns a sequence of function items for each function in the specified module.",
1✔
105
                                        new SequenceType[] { new FunctionParameterSequenceType("namespace-uri", Type.STRING, Cardinality.EXACTLY_ONE, "The namespace URI of the function module") },
1✔
106
                                        new FunctionReturnSequenceType(Type.FUNCTION, Cardinality.ZERO_OR_MORE, "sequence of function references"),
1✔
107
                                        "Use inspect:module-functions-by-uri#1 instead.")
1✔
108
        };
1✔
109

110
        public BuiltinFunctions(final XQueryContext context, final FunctionSignature signature) {
111
                super(context, signature);
1✔
112
        }
1✔
113

114
        @Override
115
        public Sequence eval(final Sequence[] args, final Sequence contextSequence)
116
                        throws XPathException {
117

118
                final ValueSequence resultSeq = new ValueSequence();
1✔
119
                if (getArgumentCount() == 1) {
1✔
120
                        final String uri = args[0].getStringValue();
1✔
121

122
                        // Get 'internal' modules
123
                        @Nullable Module[] modules = context.getModules(uri);
1✔
124

125
                        // If not found, try to load Java module
126
                        if ((modules == null || modules.length == 0) && context.getRepository().isPresent()) {
1!
127
                                modules = new Module[] { context.getRepository().get().resolveJavaModule(uri, context) };
×
128
                        }
129

130
                        // There is no module after all
131
                        if (modules == null || modules.length == 0) {
1!
132
                                throw new XPathException(this, "No module found matching namespace URI: " + uri);
×
133
                        }
134

135
                        if (isCalledAs("declared-variables")) {
1!
136
                                addVariablesFromModules(resultSeq, modules);
×
137

138
                        } else if (isCalledAs("list-functions")) {
1!
139
                                addFunctionRefsFromModules(resultSeq, modules);
×
140

141
                        } else {
×
142
                                addFunctionsFromModules(resultSeq, modules);
1✔
143
                        }
144
                } else {
1✔
145
                        if (isCalledAs("list-functions")) {
1!
146
                                addFunctionRefsFromContext(resultSeq);
×
147

148
                        } else {
×
149
                                // registered-functions
150
                                final Iterable<Module> iterableModules = () -> context.getModules();
1✔
151
                                final Module[] modules = StreamSupport.stream(iterableModules.spliterator(), false).toArray(Module[]::new);
1✔
152
                                addFunctionsFromModules(resultSeq, modules);
1✔
153

154
                                // Add all functions declared in the local module
155
                                for (final Iterator<UserDefinedFunction> i = context.localFunctions(); i.hasNext(); ) {
1✔
156
                                        final UserDefinedFunction func = i.next();
1✔
157
                                        final FunctionSignature sig = func.getSignature();
1✔
158
                                        resultSeq.add(new QNameValue(this, context, sig.getName()));
1✔
159
                                }
160
                        }
161
                }
162
                return resultSeq;
1✔
163
        }
164

165
        private void addFunctionsFromModules(final ValueSequence resultSeq, final Module[] modules) {
166
                final Set<QName> set = new TreeSet<>();
1✔
167
                for (final Module module : modules) {
1✔
168
                        final FunctionSignature[] signatures = module.listFunctions();
1✔
169
                        // add to set to remove duplicate QName's
170
                        for (final FunctionSignature signature : signatures) {
1✔
171
                                final QName qname = signature.getName();
1✔
172
                                set.add(qname);
1✔
173
                        }
174
                        for (final QName qname : set) {
1✔
175
                                resultSeq.add(new QNameValue(this, context, qname));
1✔
176
                        }
177
                }
178
        }
1✔
179

180
        private void addFunctionRefsFromModules(final ValueSequence resultSeq, final Module[] modules) throws XPathException {
181
                for (final Module module : modules) {
×
182
                        final FunctionSignature[] signatures = module.listFunctions();
×
183
                        for (final FunctionSignature signature : signatures) {
×
184
                                final FunctionCall call = FunOnFunctions.lookupFunction(this, signature.getName(), signature.getArgumentCount());
×
185
                                if (call != null) {
×
186
                                        resultSeq.add(new FunctionReference(this, call));
×
187
                                }
188
                        }
189
                }
190
        }
×
191

192
        private void addFunctionRefsFromContext(final ValueSequence resultSeq) throws XPathException {
193
                for (final Iterator<UserDefinedFunction> i = context.localFunctions(); i.hasNext(); ) {
×
194
                        final UserDefinedFunction f = i.next();
×
195
                        final FunctionCall call =
×
196
                                        FunOnFunctions.lookupFunction(this, f.getSignature().getName(), f.getSignature().getArgumentCount());
×
197
                        if (call != null) {
×
198
                                resultSeq.add(new FunctionReference(this, call));
×
199
                        }
200
                }
201
        }
×
202

203
        private void addVariablesFromModules(final ValueSequence resultSeq, final Module[] modules) {
204
                for (final Module module : modules) {
×
205
                        for (final Iterator<QName> i = module.getGlobalVariables(); i.hasNext(); ) {
×
206
                                resultSeq.add(new QNameValue(this, context, i.next()));
×
207
                        }
208
                }
209
        }
×
210
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc