• 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

78.22
/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java
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.fn;
50

51
import it.unimi.dsi.fastutil.shorts.ShortSet;
52
import org.exist.xquery.*;
53
import org.exist.xquery.value.*;
54
import org.w3c.dom.Node;
55

56
import java.net.URI;
57
import java.net.URISyntaxException;
58

59
import static org.exist.util.StringUtil.notNullOrEmptyOrWs;
60
import static org.exist.xquery.FunctionDSL.optParam;
61
import static org.exist.xquery.FunctionDSL.returnsOpt;
62
import static org.exist.xquery.functions.fn.FnModule.functionSignature;
63

64
/**
65
 * @author wolf
66
 */
67
public class FunBaseURI extends BasicFunction {
68

69
    private static final ShortSet QUICK_STOPS = ShortSet.of(
1✔
70
        Node.ELEMENT_NODE,
1✔
71
        Node.ATTRIBUTE_NODE,
1✔
72
        Node.PROCESSING_INSTRUCTION_NODE,
1✔
73
        Node.COMMENT_NODE,
1✔
74
        Node.TEXT_NODE,
1✔
75
        Node.DOCUMENT_NODE
1✔
76
    );
77

78
    public static final String FS_BASE_URI = "base-uri";
79
    public static final String FS_STATIC_BASE_URI = "static-base-uri";
80

81
    static final FunctionSignature FS_BASE_URI_0 = functionSignature(
1✔
82
            FS_BASE_URI,
1✔
83
            "Returns the base URI of the context node. " +
1✔
84
                    "It is equivalent to calling fn:base-uri(.).",
85
            returnsOpt(Type.ANY_URI, "The base URI from the context node.")
1✔
86
    );
87

88
    static final FunctionSignature FS_STATIC_BASE_URI_0 = functionSignature(
1✔
89
            FS_STATIC_BASE_URI,
1✔
90
            "Returns the value of the static base URI property from the static context. " +
1✔
91
                    "If the base-uri property is undefined, the empty sequence is returned.",
92
            returnsOpt(Type.ANY_URI, "The base URI from the static context.")
1✔
93
    );
94

95
    private static final FunctionParameterSequenceType FS_PARAM_NODE
1✔
96
            = optParam("arg", Type.NODE, "The node.");
1✔
97

98
    static final FunctionSignature FS_BASE_URI_1 = functionSignature(
1✔
99
            FS_BASE_URI,
1✔
100
            "Returns the base URI of a node." +
1✔
101
                    "If $arg is the empty sequence, the empty sequence is returned.",
102
            returnsOpt(Type.ANY_URI, "The base URI from $arg."),
1✔
103
            FS_PARAM_NODE
1✔
104
    );
1✔
105

106
    public FunBaseURI(XQueryContext context, FunctionSignature signature) {
107
        super(context, signature);
1✔
108
    }
1✔
109

110
    /* (non-Javadoc)
111
     * @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[],
112
     * org.exist.xquery.value.Sequence)
113
     */
114
    public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
115

116
        if (isCalledAs(FS_STATIC_BASE_URI)) {
1!
117
            if (context.isBaseURIDeclared()) {
×
118
                // use whatever value is defined, does not need to be absolute
119
                return context.getBaseURI();
×
120

121
            } else {
122
                // Quick escape
123
                return Sequence.EMPTY_SEQUENCE;
×
124
            }
125
        }
126

127

128
        NodeValue nodeValue;
129

130
        // Called as base-uri
131
        if (args.length == 0) {
1✔
132
            if (contextSequence == null) {
1!
133
                throw new XPathException(this, ErrorCodes.XPDY0002, "The context item is absent");
×
134
            }
135
            if (contextSequence.isEmpty()) {
1!
136
                return Sequence.EMPTY_SEQUENCE;
×
137
            }
138
            final Item item = contextSequence.itemAt(0);
1✔
139
            if (!Type.subTypeOf(item.getType(), Type.NODE)) {
1!
140
                throw new XPathException(this, ErrorCodes.XPTY0004, "Context item is not a node");
×
141
            }
142
            nodeValue = (NodeValue) item;
1✔
143

144

145
        } else {
1✔
146
            if (args[0].isEmpty()) {
1!
147
                return Sequence.EMPTY_SEQUENCE;
×
148
            } else {
149
                nodeValue = (NodeValue) args[0].itemAt(0);
1✔
150
            }
151
        }
152

153
        Sequence result = Sequence.EMPTY_SEQUENCE;
1✔
154

155
        final Node node = nodeValue.getNode();
1✔
156
        final short type = node.getNodeType();
1✔
157

158
        // Namespace node does not exist in xquery, hence left out of array.
159

160
        // Quick escape
161
        if (!QUICK_STOPS.contains(type)) {
1!
162
            return Sequence.EMPTY_SEQUENCE;
×
163
        }
164

165
        // Constructed Comment nodes/PIs/Attributes do not have a baseURI according tests
166
        if ((node.getNodeType() == Node.COMMENT_NODE
1!
167
                || node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE
1✔
168
                || node.getNodeType() == Node.ATTRIBUTE_NODE)
1✔
169
                && nodeValue.getOwnerDocument().getDocumentElement() == null) {
1!
170
            return Sequence.EMPTY_SEQUENCE;
1✔
171
        }
172

173
        // "" when not set // check with isBaseURIDeclared()
174
        final AnyURIValue contextBaseURI = context.getBaseURI();
1✔
175
        final boolean hasContextBaseURI = context.isBaseURIDeclared();
1✔
176

177
        // "" when not set, can be null
178
        final String nodeBaseURI = node.getBaseURI();
1✔
179
        final boolean hasNodeBaseURI = notNullOrEmptyOrWs(nodeBaseURI);
1✔
180

181
        try {
182
            if (hasNodeBaseURI) {
1✔
183
                // xml:base is defined
184
                URI nbURI = new URI(nodeBaseURI);
1✔
185
                final boolean nbURIAbsolute = nbURI.isAbsolute();
1✔
186

187
                if (!nbURIAbsolute && hasContextBaseURI) {
1✔
188
                    // when xml:base is not an absolute URL and there is a contextURI
189
                    // join them
190
                    final URI newURI = contextBaseURI.toURI().resolve(nodeBaseURI);
1✔
191
                    result = new AnyURIValue(this, newURI);
1✔
192

193
                } else {
1✔
194
                    // just take xml:base value
195
                    result = new AnyURIValue(this, nbURI);
1✔
196
                }
197

198
            } else if (hasContextBaseURI) {
1!
199
                // if there is no xml:base, take the root document, if present.
200
                result = contextBaseURI;
×
201
            }
202

203
        } catch (URISyntaxException e) {
×
204
            LOG.debug(e.getMessage());
×
205
        }
206

207
        return result;
1✔
208
    }
209
}
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