diff --git a/exist-core/pom.xml b/exist-core/pom.xml
index af67af24689..69118b5523f 100644
--- a/exist-core/pom.xml
+++ b/exist-core/pom.xml
@@ -613,6 +613,11 @@
test
+
+ de.bottlecaps
+ markup-blitz
+ 1.3
+
@@ -1004,6 +1009,7 @@ The BaseX Team. The original license statement is also included below.]]>
default-compile
+ 11
org/exist/storage/lock/EnsureLockingAspect.java
diff --git a/exist-core/src/main/java/org/exist/http/RESTServer.java b/exist-core/src/main/java/org/exist/http/RESTServer.java
index 76b8868f137..8b4c0fe7b9c 100644
--- a/exist-core/src/main/java/org/exist/http/RESTServer.java
+++ b/exist-core/src/main/java/org/exist/http/RESTServer.java
@@ -1808,14 +1808,19 @@ private void writeResourceAs(final DocumentImpl resource, final DBBroker broker,
outputProperties.setProperty("omit-xml-declaration", "no");
}
- final OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), encoding);
- sax.setOutput(writer, outputProperties);
- serializer.setSAXHandlers(sax, sax);
+ try {
+ final OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), encoding);
+ sax.setOutput(writer, outputProperties);
+ serializer.setSAXHandlers(sax, sax);
- serializer.toSAX(resource);
+ serializer.toSAX(resource);
- writer.flush();
- writer.close(); // DO NOT use in try-write-resources, otherwise ther response stream is always closed, and we can't report the errors
+ // writer.flush(); // Not needed, because close() will flush the stream.
+ writer.close(); // DO NOT use in try-with-resources, otherwise the response stream is always closed, and we can't report the errors
+ } catch (org.eclipse.jetty.io.EofException connectionInterrupted) {
+ // Don't throw the EofException, which is caused by the client hanging up.
+ LOG.info("Ignored EofException while writing response to ReST client: {}", connectionInterrupted.getMessage());
+ }
} catch (final SAXException saxe) {
LOG.warn(saxe);
throw new BadRequestException("Error while serializing XML: " + saxe.getMessage());
diff --git a/exist-core/src/main/java/org/exist/http/urlrewrite/XQueryURLRewrite.java b/exist-core/src/main/java/org/exist/http/urlrewrite/XQueryURLRewrite.java
index dd265781c75..2c9b13ccd53 100644
--- a/exist-core/src/main/java/org/exist/http/urlrewrite/XQueryURLRewrite.java
+++ b/exist-core/src/main/java/org/exist/http/urlrewrite/XQueryURLRewrite.java
@@ -362,6 +362,13 @@ protected void service(final HttpServletRequest request, final HttpServletRespon
}
}
} catch (final Throwable e) {
+ if (e instanceof IllegalArgumentException) {
+ LOG.warn("Invalid URI: {}", e.getMessage());
+ response.getWriter().print(e.getMessage());
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ response.flushBuffer();
+ return;
+ }
LOG.error("Error while processing {}: {}", request.getRequestURI(), e.getMessage(), e);
throw new ServletException("An error occurred while processing request to " + request.getRequestURI() + ": "
+ e.getMessage(), e);
diff --git a/exist-core/src/main/java/org/exist/xquery/LetExpr.java b/exist-core/src/main/java/org/exist/xquery/LetExpr.java
index 05dae3376c6..e9c9a91d168 100644
--- a/exist-core/src/main/java/org/exist/xquery/LetExpr.java
+++ b/exist-core/src/main/java/org/exist/xquery/LetExpr.java
@@ -1,234 +1,235 @@
-/*
- * eXist-db Open Source Native XML Database
- * Copyright (C) 2001 The eXist-db Authors
- *
- * info@exist-db.org
- * http://www.exist-db.org
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-package org.exist.xquery;
-
-import org.exist.dom.QName;
-import org.exist.xquery.util.ExpressionDumper;
-import org.exist.xquery.value.*;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Implements an XQuery let-expression.
- *
- * @author Wolfgang Meier
- */
-public class LetExpr extends BindingExpression {
-
- public LetExpr(XQueryContext context) {
- super(context);
- }
-
- @Override
- public ClauseType getType() {
- return ClauseType.LET;
- }
-
- @Override
- public void analyze(final AnalyzeContextInfo contextInfo) throws XPathException {
- super.analyze(contextInfo);
- //Save the local variable stack
- final LocalVariable mark = context.markLocalVariables(false);
- try {
- contextInfo.setParent(this);
- final AnalyzeContextInfo varContextInfo = new AnalyzeContextInfo(contextInfo);
- inputSequence.analyze(varContextInfo);
- //Declare the iteration variable
- final LocalVariable inVar = new LocalVariable(QName.parse(context, varName, null));
- inVar.setSequenceType(sequenceType);
- inVar.setStaticType(varContextInfo.getStaticReturnType());
- context.declareVariableBinding(inVar);
- //Reset the context position
- context.setContextSequencePosition(0, null);
-
- returnExpr.analyze(contextInfo);
- } catch (final QName.IllegalQNameException e) {
- throw new XPathException(this, ErrorCodes.XPST0081, "No namespace defined for prefix " + varName);
- } finally {
- // restore the local variable stack
- context.popLocalVariables(mark);
- }
- }
-
- /* (non-Javadoc)
- * @see org.exist.xquery.Expression#eval(org.exist.xquery.StaticContext, org.exist.dom.persistent.DocumentSet, org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
- */
- public Sequence eval(Sequence contextSequence, Item contextItem)
- throws XPathException {
- if (context.getProfiler().isEnabled()){
- context.getProfiler().start(this);
- context.getProfiler().message(this, Profiler.DEPENDENCIES,
- "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
- if (contextSequence != null)
- {context.getProfiler().message(this, Profiler.START_SEQUENCES,
- "CONTEXT SEQUENCE", contextSequence);}
- if (contextItem != null)
- {context.getProfiler().message(this, Profiler.START_SEQUENCES,
- "CONTEXT ITEM", contextItem.toSequence());}
- }
- context.expressionStart(this);
- context.pushDocumentContext();
- try {
- //Save the local variable stack
- LocalVariable mark = context.markLocalVariables(false);
- Sequence in;
- LocalVariable var;
- Sequence resultSequence = null;
- try {
- // evaluate input sequence
- in = inputSequence.eval(contextSequence, null);
- clearContext(getExpressionId(), in);
- // Declare the iteration variable
- var = createVariable(varName);
- var.setSequenceType(sequenceType);
- context.declareVariableBinding(var);
- var.setValue(in);
- if (sequenceType == null)
- {var.checkType();} //Just because it makes conversions !
- var.setContextDocs(inputSequence.getContextDocSet());
- registerUpdateListener(in);
-
- resultSequence = returnExpr.eval(contextSequence, null);
-
- if (sequenceType != null) {
- Cardinality actualCardinality;
- if (var.getValue().isEmpty()) {actualCardinality = Cardinality.EMPTY_SEQUENCE;}
- else if (var.getValue().hasMany()) {actualCardinality = Cardinality._MANY;}
- else {actualCardinality = Cardinality.EXACTLY_ONE;}
- //Type.EMPTY is *not* a subtype of other types ; checking cardinality first
- if (!sequenceType.getCardinality().isSuperCardinalityOrEqualOf(actualCardinality))
- {throw new XPathException(this, ErrorCodes.XPTY0004,
- "Invalid cardinality for variable $" + varName +
- ". Expected " +
- sequenceType.getCardinality().getHumanDescription() +
- ", got " + actualCardinality.getHumanDescription(), in);}
- //TODO : ignore nodes right now ; they are returned as xs:untypedAtomicType
- if (!Type.subTypeOf(sequenceType.getPrimaryType(), Type.NODE)) {
- if (!var.getValue().isEmpty() && !Type.subTypeOf(var.getValue()
- .getItemType(), sequenceType.getPrimaryType())) {
- throw new XPathException(this, ErrorCodes.XPTY0004,
- "Invalid type for variable $" + varName +
- ". Expected " + Type.getTypeName(sequenceType.getPrimaryType()) +
- ", got " +Type.getTypeName(var.getValue().getItemType()), in);
- }
- //Here is an attempt to process the nodes correctly
- } else {
- //Same as above : we probably may factorize
- if (!var.getValue().isEmpty() && !sequenceType.checkType(var.getValue())) {
- final Sequence value = var.getValue();
- final SequenceType valueType = new SequenceType(value.getItemType(), value.getCardinality());
- if ((!value.isEmpty()) && sequenceType.getPrimaryType() == Type.DOCUMENT && value.getItemType() == Type.DOCUMENT) {
- // it's a document... we need to get the document element's name
- final NodeValue nvItem = (NodeValue) value.itemAt(0);
- final Document doc;
- if (nvItem instanceof Document) {
- doc = (Document) nvItem;
- } else {
- doc = nvItem.getOwnerDocument();
- }
- if (doc != null) {
- final Element elem = doc.getDocumentElement();
- if (elem != null) {
- valueType.setNodeName(new QName(elem.getLocalName(), elem.getNamespaceURI()));
- }
- }
- }
-
- if ((!value.isEmpty()) && sequenceType.getPrimaryType() == Type.ELEMENT && value.getItemType() == Type.ELEMENT) {
- final NodeValue nvItem = (NodeValue) value.itemAt(0);
- valueType.setNodeName(nvItem.getQName());
- }
-
- throw new XPathException(
- this,
- ErrorCodes.XPTY0004,
- String.format("Invalid type for variable $%s. Expected %s, got %s", varName, sequenceType.toString(), valueType.toString()), in);
- }
- }
- }
- } finally {
- // Restore the local variable stack
- context.popLocalVariables(mark, resultSequence);
- }
- clearContext(getExpressionId(), in);
- if (context.getProfiler().isEnabled())
- {context.getProfiler().end(this, "", resultSequence);}
- if (resultSequence == null)
- {return Sequence.EMPTY_SEQUENCE;}
- if (!(resultSequence instanceof DeferredFunctionCall)) {
- setActualReturnType(resultSequence.getItemType());
- }
- if (getPreviousClause() == null) {
- resultSequence = postEval(resultSequence);
- }
- return resultSequence;
- } finally {
- context.popDocumentContext();
- context.expressionEnd(this);
- }
- }
-
- /* (non-Javadoc)
- * @see org.exist.xquery.Expression#dump(org.exist.xquery.util.ExpressionDumper)
- */
- public void dump(ExpressionDumper dumper) {
- dumper.display("let ", line);
- dumper.startIndent();
- dumper.display("$").display(varName);
- dumper.display(" := ");
- inputSequence.dump(dumper);
- dumper.endIndent();
- //TODO : QuantifiedExpr
- if (returnExpr instanceof LetExpr)
- {dumper.display(", ");}
- else
- {dumper.nl().display("return ");}
- dumper.startIndent();
- returnExpr.dump(dumper);
- dumper.endIndent();
- }
-
- public String toString() {
- final StringBuilder result = new StringBuilder();
- result.append("let ");
- result.append("$").append(varName);
- result.append(" := ");
- result.append(inputSequence.toString());
- result.append(" ");
- //TODO : QuantifiedExpr
- if (returnExpr instanceof LetExpr)
- {result.append(", ");}
- else
- {result.append("return ");}
- result.append(returnExpr.toString());
- return result.toString();
- }
-
- public void accept(ExpressionVisitor visitor) {
- visitor.visitLetExpression(this);
- }
-
- @Override
- public boolean allowMixedNodesInReturn() {
- return true;
- }
+/*
+ * eXist-db Open Source Native XML Database
+ * Copyright (C) 2001 The eXist-db Authors
+ *
+ * info@exist-db.org
+ * http://www.exist-db.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.xquery;
+
+import org.exist.dom.QName;
+import org.exist.xquery.util.ExpressionDumper;
+import org.exist.xquery.value.*;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Implements an XQuery let-expression.
+ *
+ * @author Wolfgang Meier
+ */
+public class LetExpr extends BindingExpression {
+
+ public LetExpr(XQueryContext context) {
+ super(context);
+ }
+
+ @Override
+ public ClauseType getType() {
+ return ClauseType.LET;
+ }
+
+ @Override
+ public void analyze(final AnalyzeContextInfo contextInfo) throws XPathException {
+ super.analyze(contextInfo);
+ //Save the local variable stack
+ final LocalVariable mark = context.markLocalVariables(false);
+ try {
+ contextInfo.setParent(this);
+ final AnalyzeContextInfo varContextInfo = new AnalyzeContextInfo(contextInfo);
+ inputSequence.analyze(varContextInfo);
+ //Declare the iteration variable
+ final LocalVariable inVar = new LocalVariable(QName.parse(context, varName, null));
+ inVar.setSequenceType(sequenceType);
+ inVar.setStaticType(varContextInfo.getStaticReturnType());
+ context.declareVariableBinding(inVar);
+ //Reset the context position
+ context.setContextSequencePosition(0, null);
+
+ returnExpr.analyze(contextInfo);
+ } catch (final QName.IllegalQNameException e) {
+ throw new XPathException(this, ErrorCodes.XPST0081, "No namespace defined for prefix " + varName);
+ } finally {
+ // restore the local variable stack
+ context.popLocalVariables(mark);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.exist.xquery.Expression#eval(org.exist.xquery.StaticContext, org.exist.dom.persistent.DocumentSet, org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
+ */
+ public Sequence eval(Sequence contextSequence, Item contextItem)
+ throws XPathException {
+ if (context.getProfiler().isEnabled()){
+ context.getProfiler().start(this);
+ context.getProfiler().message(this, Profiler.DEPENDENCIES,
+ "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
+ if (contextSequence != null)
+ {context.getProfiler().message(this, Profiler.START_SEQUENCES,
+ "CONTEXT SEQUENCE", contextSequence);}
+ if (contextItem != null)
+ {context.getProfiler().message(this, Profiler.START_SEQUENCES,
+ "CONTEXT ITEM", contextItem.toSequence());}
+ }
+ context.expressionStart(this);
+ context.pushDocumentContext();
+ try {
+ //Save the local variable stack
+ LocalVariable mark = context.markLocalVariables(false);
+ Sequence in;
+ LocalVariable var;
+ Sequence resultSequence = null;
+ try {
+ // evaluate input sequence
+ in = inputSequence.eval(contextSequence, null);
+ clearContext(getExpressionId(), in);
+ // Declare the iteration variable
+ var = createVariable(varName);
+ var.setSequenceType(sequenceType);
+ context.declareVariableBinding(var);
+ var.setValue(in);
+ if (sequenceType == null)
+ {var.checkType();} //Just because it makes conversions !
+ var.setContextDocs(inputSequence.getContextDocSet());
+ registerUpdateListener(in);
+
+ if (sequenceType != null) {
+ Cardinality actualCardinality;
+ if (var.getValue().isEmpty()) {actualCardinality = Cardinality.EMPTY_SEQUENCE;}
+ else if (var.getValue().hasMany()) {actualCardinality = Cardinality._MANY;}
+ else {actualCardinality = Cardinality.EXACTLY_ONE;}
+ //Type.EMPTY is *not* a subtype of other types ; checking cardinality first
+ if (!sequenceType.getCardinality().isSuperCardinalityOrEqualOf(actualCardinality))
+ {throw new XPathException(this, ErrorCodes.XPTY0004,
+ "Invalid cardinality for variable $" + varName +
+ ". Expected " +
+ sequenceType.getCardinality().getHumanDescription() +
+ ", got " + actualCardinality.getHumanDescription(), in);}
+ //TODO : ignore nodes right now ; they are returned as xs:untypedAtomicType
+ if (!Type.subTypeOf(sequenceType.getPrimaryType(), Type.NODE)) {
+ if (!var.getValue().isEmpty() && !Type.subTypeOf(var.getValue()
+ .getItemType(), sequenceType.getPrimaryType())) {
+ throw new XPathException(this, ErrorCodes.XPTY0004,
+ "Invalid type for variable $" + varName +
+ ". Expected " + Type.getTypeName(sequenceType.getPrimaryType()) +
+ ", got " +Type.getTypeName(var.getValue().getItemType()), in);
+ }
+ //Here is an attempt to process the nodes correctly
+ } else {
+ //Same as above : we probably may factorize
+ if (!var.getValue().isEmpty() && !sequenceType.checkType(var.getValue())) {
+ final Sequence value = var.getValue();
+ final SequenceType valueType = new SequenceType(value.getItemType(), value.getCardinality());
+ if ((!value.isEmpty()) && sequenceType.getPrimaryType() == Type.DOCUMENT && value.getItemType() == Type.DOCUMENT) {
+ // it's a document... we need to get the document element's name
+ final NodeValue nvItem = (NodeValue) value.itemAt(0);
+ final Document doc;
+ if (nvItem instanceof Document) {
+ doc = (Document) nvItem;
+ } else {
+ doc = nvItem.getOwnerDocument();
+ }
+ if (doc != null) {
+ final Element elem = doc.getDocumentElement();
+ if (elem != null) {
+ valueType.setNodeName(new QName(elem.getLocalName(), elem.getNamespaceURI()));
+ }
+ }
+ }
+
+ if ((!value.isEmpty()) && sequenceType.getPrimaryType() == Type.ELEMENT && value.getItemType() == Type.ELEMENT) {
+ final NodeValue nvItem = (NodeValue) value.itemAt(0);
+ valueType.setNodeName(nvItem.getQName());
+ }
+
+ throw new XPathException(
+ this,
+ ErrorCodes.XPTY0004,
+ String.format("Invalid type for variable $%s. Expected %s, got %s", varName, sequenceType.toString(), valueType.toString()), in);
+ }
+ }
+ }
+
+ resultSequence = returnExpr.eval(contextSequence, null);
+
+ } finally {
+ // Restore the local variable stack
+ context.popLocalVariables(mark, resultSequence);
+ }
+ clearContext(getExpressionId(), in);
+ if (context.getProfiler().isEnabled())
+ {context.getProfiler().end(this, "", resultSequence);}
+ if (resultSequence == null)
+ {return Sequence.EMPTY_SEQUENCE;}
+ if (!(resultSequence instanceof DeferredFunctionCall)) {
+ setActualReturnType(resultSequence.getItemType());
+ }
+ if (getPreviousClause() == null) {
+ resultSequence = postEval(resultSequence);
+ }
+ return resultSequence;
+ } finally {
+ context.popDocumentContext();
+ context.expressionEnd(this);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.exist.xquery.Expression#dump(org.exist.xquery.util.ExpressionDumper)
+ */
+ public void dump(ExpressionDumper dumper) {
+ dumper.display("let ", line);
+ dumper.startIndent();
+ dumper.display("$").display(varName);
+ dumper.display(" := ");
+ inputSequence.dump(dumper);
+ dumper.endIndent();
+ //TODO : QuantifiedExpr
+ if (returnExpr instanceof LetExpr)
+ {dumper.display(", ");}
+ else
+ {dumper.nl().display("return ");}
+ dumper.startIndent();
+ returnExpr.dump(dumper);
+ dumper.endIndent();
+ }
+
+ public String toString() {
+ final StringBuilder result = new StringBuilder();
+ result.append("let ");
+ result.append("$").append(varName);
+ result.append(" := ");
+ result.append(inputSequence.toString());
+ result.append(" ");
+ //TODO : QuantifiedExpr
+ if (returnExpr instanceof LetExpr)
+ {result.append(", ");}
+ else
+ {result.append("return ");}
+ result.append(returnExpr.toString());
+ return result.toString();
+ }
+
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visitLetExpression(this);
+ }
+
+ @Override
+ public boolean allowMixedNodesInReturn() {
+ return true;
+ }
}
\ No newline at end of file
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/FnInvisibleXml.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/FnInvisibleXml.java
new file mode 100644
index 00000000000..a9f5a584bab
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/FnInvisibleXml.java
@@ -0,0 +1,157 @@
+package org.exist.xquery.functions.fn;
+
+import static org.exist.xquery.FunctionDSL.optParam;
+import static org.exist.xquery.FunctionDSL.param;
+import static org.exist.xquery.functions.fn.FnModule.functionSignature;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.exist.xquery.BasicFunction;
+import org.exist.xquery.Cardinality;
+import org.exist.xquery.ErrorCodes;
+import org.exist.xquery.Expression;
+import org.exist.xquery.Function;
+import org.exist.xquery.FunctionCall;
+import org.exist.xquery.FunctionFactory;
+import org.exist.xquery.FunctionSignature;
+import org.exist.xquery.XPathException;
+import org.exist.xquery.XQueryContext;
+import org.exist.xquery.functions.map.MapType;
+import org.exist.xquery.value.BooleanValue;
+import org.exist.xquery.value.FunctionReference;
+import org.exist.xquery.value.FunctionReturnSequenceType;
+import org.exist.xquery.value.Sequence;
+import org.exist.xquery.value.StringValue;
+import org.exist.xquery.value.Type;
+
+import de.bottlecaps.markup.Blitz;
+import de.bottlecaps.markup.blitz.Parser;
+
+/**
+ * Implementation of
+ * fn:invisible-xml(
+ * $grammar as item()? := (),
+ * $options as map(*)? := {}
+ * ) as function(xs:string) as item()
+ * @see https://qt4cg.org/specifications/xpath-functions-40/Overview.html#ixml-functions
+ *
+ * To do:
+ * - Use the Markup Blitz serializer instead of parsing serialized XML.
+ */
+public class FnInvisibleXml extends BasicFunction
+{
+
+ private static final String FS_INVISIBLE_XML_NAME = "invisible-xml";
+
+ static final FunctionSignature FS_INVISIBLE_XML = functionSignature(
+ FnInvisibleXml.FS_INVISIBLE_XML_NAME,
+ "Returns an ixml parser from a grammar. The parser returns an XML representation of the input string as parsed by the provided grammar.",
+ new FunctionReturnSequenceType(Type.FUNCTION_REFERENCE, Cardinality.EXACTLY_ONE, "A function that can be used to parse an input string."),
+ optParam("grammar", Type.ITEM, "The ixml grammar used to generate the parser"),
+ optParam("options", Type.MAP, "The options for the parser genarator and the parser itself")
+ );
+
+ private static final String IXML_GRAMMAR_RESOURCE = "org/exist/xquery/lib/ixml.ixml";
+
+
+ public FnInvisibleXml(final XQueryContext context, final FunctionSignature signature) {
+ super(context, signature);
+ }
+
+ @Override
+ public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
+ // Handle $grammar and $options parameters.
+ final String grammar;
+ if (args[0].isEmpty()) {
+ grammar = getIxmlGrammar();
+ } else {
+ grammar = ((StringValue)args[0].itemAt(0)).getStringValue();
+ }
+ final Blitz.Option[] options;
+ if (args[1].isEmpty()) {
+ options = new Blitz.Option[0];
+ } else {
+ options = getOptions((MapType) args[1].itemAt(0));
+ }
+ // Generate the Markup Blitz parser for the grammar.
+ final Parser parser = Blitz.generate(grammar, options);
+ // Make an IxmlParser function from the Markup Blitz parser. The signature is fn(xs:string) as item()
+ FunctionSignature parserSignature = functionSignature(
+ "generated-ixml-parser",
+ "Generated ixml parser, only used internally",
+ new FunctionReturnSequenceType(Type.ITEM, Cardinality.EXACTLY_ONE, "The result of parsing the input string"),
+ param("input", Type.STRING, "The input string")
+ );
+ final IxmlParser ixmlParser = new IxmlParser(context, parserSignature, parser);
+ // Make a function reference that can be used as the result.
+ FunctionCall functionCall = FunctionFactory.wrap(context, ixmlParser);
+ return new FunctionReference(functionCall);
+ }
+
+ // Read the ixml grammar from a resource.
+ private String getIxmlGrammar() throws XPathException {
+ try (final InputStream ixmlGrammarStream = FnInvisibleXml.class.getClassLoader().getResourceAsStream(IXML_GRAMMAR_RESOURCE)) {
+ if (ixmlGrammarStream == null) {
+ throw new XPathException(ErrorCodes.FODC0002, "The ixml grammar resource cannot be found at "+IXML_GRAMMAR_RESOURCE);
+ }
+ try ( InputStreamReader ixmlGrammarStreamReader = new InputStreamReader(ixmlGrammarStream);
+ BufferedReader reader = new BufferedReader(ixmlGrammarStreamReader)) {
+ return reader.lines().collect(Collectors.joining(System.lineSeparator()));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new XPathException(ErrorCodes.FODC0002, "The ixml grammar resource cannot be opened at "+IXML_GRAMMAR_RESOURCE, e);
+ }
+ }
+
+ // Get Markup Blitz options from the $options as map(*) parameter.
+ private Blitz.Option[] getOptions(final MapType options) throws XPathException {
+ List optionsList = new ArrayList();
+ Sequence failOnError = options.get(new StringValue("fail-on-error"));
+ if (!failOnError.isEmpty() && ((BooleanValue)failOnError.itemAt(0).convertTo(Type.BOOLEAN)).getValue()) {
+ optionsList.add(Blitz.Option.FAIL_ON_ERROR);
+ }
+ return optionsList.stream().toArray(Blitz.Option[]::new);
+ }
+
+
+ /**
+ * A BasicFunction for the generated ixml parser.
+ */
+ private static final class IxmlParser extends BasicFunction {
+
+ private Parser parser;
+
+ public IxmlParser(XQueryContext context, FunctionSignature signature, Parser parser) throws XPathException
+ {
+ super(context, signature);
+ this.parser = parser;
+ // We must set the arguments, which is not done automatically from the signature.
+ final List ixmlParserArgs = new ArrayList<>(1);
+ ixmlParserArgs.add(new Function.Placeholder(context));
+ this.setArguments(ixmlParserArgs);
+ }
+
+ @Override
+ public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException
+ {
+ final String input = ((StringValue)args[0].itemAt(0)).getStringValue();
+ // Parse the input string.
+ final String output = parser.parse(input);
+ // The output is serialized XML, which we need to parse.
+ ParsingFunctions xmlParser = new ParsingFunctions(context, ParsingFunctions.signatures[0]);
+ final Sequence[] xmlParserArgs = new Sequence[1];
+ xmlParserArgs[0] = new StringValue(output).toSequence();
+ return xmlParser.eval(xmlParserArgs, contextSequence);
+ }
+
+ }
+
+}
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/FnModule.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/FnModule.java
index 61545789f63..4cec86f8abe 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/fn/FnModule.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/FnModule.java
@@ -1,320 +1,321 @@
-/*
- * eXist-db Open Source Native XML Database
- * Copyright (C) 2001 The eXist-db Authors
- *
- * info@exist-db.org
- * http://www.exist-db.org
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-package org.exist.xquery.functions.fn;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.exist.dom.QName;
-import org.exist.xquery.*;
-import org.exist.xquery.value.FunctionParameterSequenceType;
-import org.exist.xquery.value.FunctionReturnSequenceType;
-
-/**
- * Module function definitions for xpath-functions module.
- *
- * @author Wolfgang Meier
- * @author ljo
- */
-public class FnModule extends AbstractInternalModule {
-
- public final static String PREFIX = "";
- public final static String INCLUSION_DATE = "2004-01-29";
- public final static String RELEASED_IN_VERSION = "pre eXist-1.0";
-
- public final static FunctionDef[] functions = {
- new FunctionDef(FunAbs.signature, FunAbs.class),
- new FunctionDef(FunAvg.signature, FunAvg.class),
- new FunctionDef(FunBaseURI.FS_BASE_URI_0, FunBaseURI.class),
- new FunctionDef(FunBaseURI.FS_BASE_URI_1, FunBaseURI.class),
- new FunctionDef(FunBaseURI.FS_STATIC_BASE_URI_0, FunBaseURI.class),
- new FunctionDef(FunBoolean.signature, FunBoolean.class),
- new FunctionDef(FunCeiling.signature, FunCeiling.class),
- new FunctionDef(FunCodepointEqual.signature, FunCodepointEqual.class),
- new FunctionDef(FunCodepointsToString.signature, FunCodepointsToString.class),
- new FunctionDef(FunCollationKey.FS_COLLATION_KEY_SIGNATURES[0], FunCollationKey.class),
- new FunctionDef(FunCollationKey.FS_COLLATION_KEY_SIGNATURES[1], FunCollationKey.class),
- new FunctionDef(FunCompare.signatures[0], FunCompare.class),
- new FunctionDef(FunCompare.signatures[1], FunCompare.class),
- new FunctionDef(FunConcat.signature, FunConcat.class),
- new FunctionDef(FunContains.signatures[0], FunContains.class),
- new FunctionDef(FunContains.signatures[1], FunContains.class),
- new FunctionDef(FunCount.signature, FunCount.class),
- new FunctionDef(FunCurrentDateTime.fnCurrentDate, FunCurrentDateTime.class),
- new FunctionDef(FunCurrentDateTime.fnCurrentDateTime, FunCurrentDateTime.class),
- new FunctionDef(FunCurrentDateTime.fnCurrentTime, FunCurrentDateTime.class),
- new FunctionDef(FunData.signatures[0], FunData.class),
- new FunctionDef(FunData.signatures[1], FunData.class),
- new FunctionDef(FunDateTime.signature, FunDateTime.class),
- new FunctionDef(FunDeepEqual.signatures[0], FunDeepEqual.class),
- new FunctionDef(FunDeepEqual.signatures[1], FunDeepEqual.class),
- new FunctionDef(FunDefaultCollation.signature, FunDefaultCollation.class),
- new FunctionDef(FnDefaultLanguage.FS_DEFAULT_LANGUAGE, FnDefaultLanguage.class),
- new FunctionDef(FunDistinctValues.signatures[0], FunDistinctValues.class),
- new FunctionDef(FunDistinctValues.signatures[1], FunDistinctValues.class),
- new FunctionDef(FunDoc.signature, FunDoc.class),
- new FunctionDef(FunDocAvailable.signature, FunDocAvailable.class),
- new FunctionDef(FunDocumentURI.FS_DOCUMENT_URI_0, FunDocumentURI.class),
- new FunctionDef(FunDocumentURI.FS_DOCUMENT_URI_1, FunDocumentURI.class),
- new FunctionDef(FunElementWithId.FS_ELEMENT_WITH_ID_SIGNATURES[0], FunElementWithId.class),
- new FunctionDef(FunElementWithId.FS_ELEMENT_WITH_ID_SIGNATURES[1], FunElementWithId.class),
- new FunctionDef(FunEmpty.signature, FunEmpty.class),
- new FunctionDef(FunEncodeForURI.signature, FunEncodeForURI.class),
- new FunctionDef(FunEndsWith.signatures[0], FunEndsWith.class),
- new FunctionDef(FunEndsWith.signatures[1], FunEndsWith.class),
- new FunctionDef(FunError.signature[0], FunError.class),
- new FunctionDef(FunError.signature[1], FunError.class),
- new FunctionDef(FunError.signature[2], FunError.class),
- new FunctionDef(FunError.signature[3], FunError.class),
- new FunctionDef(FunEscapeHTMLURI.signature, FunEscapeHTMLURI.class),
- new FunctionDef(FunEscapeURI.signature, FunEscapeURI.class),
- new FunctionDef(FunExactlyOne.signature, FunExactlyOne.class),
- new FunctionDef(FunExists.signature, FunExists.class),
- new FunctionDef(FunFloor.signature, FunFloor.class),
- new FunctionDef(FnFormatDates.FNS_FORMAT_DATETIME_2, FnFormatDates.class),
- new FunctionDef(FnFormatDates.FNS_FORMAT_DATETIME_5, FnFormatDates.class),
- new FunctionDef(FnFormatDates.FNS_FORMAT_DATE_2, FnFormatDates.class),
- new FunctionDef(FnFormatDates.FNS_FORMAT_DATE_5, FnFormatDates.class),
- new FunctionDef(FnFormatDates.FNS_FORMAT_TIME_2, FnFormatDates.class),
- new FunctionDef(FnFormatDates.FNS_FORMAT_TIME_5, FnFormatDates.class),
- new FunctionDef(FnFormatIntegers.FS_FORMAT_INTEGER[0], FnFormatIntegers.class),
- new FunctionDef(FnFormatIntegers.FS_FORMAT_INTEGER[1], FnFormatIntegers.class),
- new FunctionDef(FnFormatNumbers.FS_FORMAT_NUMBER[0], FnFormatNumbers.class),
- new FunctionDef(FnFormatNumbers.FS_FORMAT_NUMBER[1], FnFormatNumbers.class),
- new FunctionDef(FunGenerateId.signatures[0], FunGenerateId.class),
- new FunctionDef(FunGenerateId.signatures[1], FunGenerateId.class),
- new FunctionDef(FunGetDateComponent.fnDayFromDate, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnMonthFromDate, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnYearFromDate, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnTimezoneFromDate, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnHoursFromTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnMinutesFromTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnSecondsFromTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnTimezoneFromTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnDayFromDateTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnMonthFromDateTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnYearFromDateTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnHoursFromDateTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnMinutesFromDateTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnSecondsFromDateTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDateComponent.fnTimezoneFromDateTime, FunGetDateComponent.class),
- new FunctionDef(FunGetDurationComponent.fnYearsFromDuration, FunGetDurationComponent.class),
- new FunctionDef(FunGetDurationComponent.fnMonthsFromDuration, FunGetDurationComponent.class),
- new FunctionDef(FunGetDurationComponent.fnDaysFromDuration, FunGetDurationComponent.class),
- new FunctionDef(FunGetDurationComponent.fnHoursFromDuration, FunGetDurationComponent.class),
- new FunctionDef(FunGetDurationComponent.fnMinutesFromDuration, FunGetDurationComponent.class),
- new FunctionDef(FunGetDurationComponent.fnSecondsFromDuration, FunGetDurationComponent.class),
- new FunctionDef(FunAdjustTimezone.fnAdjustDateToTimezone[0], FunAdjustTimezone.class),
- new FunctionDef(FunAdjustTimezone.fnAdjustDateToTimezone[1], FunAdjustTimezone.class),
- new FunctionDef(FunAdjustTimezone.fnAdjustTimeToTimezone[0], FunAdjustTimezone.class),
- new FunctionDef(FunAdjustTimezone.fnAdjustTimeToTimezone[1], FunAdjustTimezone.class),
- new FunctionDef(FunAdjustTimezone.fnAdjustDateTimeToTimezone[0], FunAdjustTimezone.class),
- new FunctionDef(FunAdjustTimezone.fnAdjustDateTimeToTimezone[1], FunAdjustTimezone.class),
- new FunctionDef(FunParseIetfDate.FNS_PARSE_IETF_DATE, FunParseIetfDate.class),
- new FunctionDef(FnHasChildren.FNS_HAS_CHILDREN_0, FnHasChildren.class),
- new FunctionDef(FnHasChildren.FNS_HAS_CHILDREN_1, FnHasChildren.class),
- new FunctionDef(FunId.signature[0], FunId.class),
- new FunctionDef(FunId.signature[1], FunId.class),
- new FunctionDef(FunIdRef.signature[0], FunIdRef.class),
- new FunctionDef(FunIdRef.signature[1], FunIdRef.class),
- new FunctionDef(FunImplicitTimezone.signature, FunImplicitTimezone.class),
- new FunctionDef(FunIndexOf.fnIndexOf[0], FunIndexOf.class),
- new FunctionDef(FunIndexOf.fnIndexOf[1], FunIndexOf.class),
- new FunctionDef(FnInnerMost.FNS_INNERMOST, FnInnerMost.class),
- new FunctionDef(FunIRIToURI.signature, FunIRIToURI.class),
- new FunctionDef(FunInScopePrefixes.signature, FunInScopePrefixes.class),
- new FunctionDef(FunInsertBefore.signature, FunInsertBefore.class),
- new FunctionDef(FunLang.signatures[0], FunLang.class),
- new FunctionDef(FunLang.signatures[1], FunLang.class),
- new FunctionDef(FunLast.signature, FunLast.class),
- new FunctionDef(FunLocalName.signatures[0], FunLocalName.class),
- new FunctionDef(FunLocalName.signatures[1], FunLocalName.class),
- new FunctionDef(FunOnFunctions.signatures[0], FunOnFunctions.class),
- new FunctionDef(FunOnFunctions.signatures[1], FunOnFunctions.class),
- new FunctionDef(FunOnFunctions.signatures[2], FunOnFunctions.class),
- new FunctionDef(FunMatches.signatures[0], FunMatches.class),
- new FunctionDef(FunMatches.signatures[1], FunMatches.class),
- new FunctionDef(FunMax.signatures[0], FunMax.class),
- new FunctionDef(FunMax.signatures[1], FunMax.class),
- new FunctionDef(FunMin.signatures[0], FunMin.class),
- new FunctionDef(FunMin.signatures[1], FunMin.class),
- new FunctionDef(FunNodeName.signatures[0], FunNodeName.class),
- new FunctionDef(FunNodeName.signatures[1], FunNodeName.class),
- new FunctionDef(FunName.signatures[0], FunName.class),
- new FunctionDef(FunName.signatures[1], FunName.class),
- new FunctionDef(FunNamespaceURI.signatures[0], FunNamespaceURI.class),
- new FunctionDef(FunNamespaceURI.signatures[1], FunNamespaceURI.class),
- new FunctionDef(FunNamespaceURIForPrefix.signature, FunNamespaceURIForPrefix.class),
- new FunctionDef(FunNilled.FUNCTION_SIGNATURES_NILLED[0], FunNilled.class),
- new FunctionDef(FunNilled.FUNCTION_SIGNATURES_NILLED[1], FunNilled.class),
- new FunctionDef(FunNormalizeSpace.signatures[0], FunNormalizeSpace.class),
- new FunctionDef(FunNormalizeSpace.signatures[1], FunNormalizeSpace.class),
- new FunctionDef(FunNormalizeUnicode.signatures[0], FunNormalizeUnicode.class),
- new FunctionDef(FunNormalizeUnicode.signatures[1], FunNormalizeUnicode.class),
- new FunctionDef(FunNot.signature, FunNot.class),
- new FunctionDef(FunNumber.signatures[0], FunNumber.class),
- new FunctionDef(FunNumber.signatures[1], FunNumber.class),
- new FunctionDef(FunOneOrMore.signature, FunOneOrMore.class),
- new FunctionDef(FnOuterMost.FNS_OUTERMOST, FnOuterMost.class),
- new FunctionDef(FunPath.FS_PATH_SIGNATURES[0], FunPath.class),
- new FunctionDef(FunPath.FS_PATH_SIGNATURES[1], FunPath.class),
- new FunctionDef(FunPosition.signature, FunPosition.class),
- new FunctionDef(FunQName.signature, FunQName.class),
- new FunctionDef(FunRemove.signature, FunRemove.class),
- new FunctionDef(FunReplace.FS_REPLACE[0], FunReplace.class),
- new FunctionDef(FunReplace.FS_REPLACE[1], FunReplace.class),
- new FunctionDef(FunReverse.signature, FunReverse.class),
- new FunctionDef(FunResolveURI.signatures[0], FunResolveURI.class),
- new FunctionDef(FunResolveURI.signatures[1], FunResolveURI.class),
- new FunctionDef(FunRoot.signatures[0], FunRoot.class),
- new FunctionDef(FunRoot.signatures[1], FunRoot.class),
- new FunctionDef(FunRound.FN_ROUND_SIGNATURES[0], FunRound.class),
- new FunctionDef(FunRound.FN_ROUND_SIGNATURES[1], FunRound.class),
- new FunctionDef(FunRoundHalfToEven.FN_ROUND_HALF_TO_EVEN_SIGNATURES[0], FunRoundHalfToEven.class),
- new FunctionDef(FunRoundHalfToEven.FN_ROUND_HALF_TO_EVEN_SIGNATURES[1], FunRoundHalfToEven.class),
- new FunctionDef(FunSerialize.signatures[0], FunSerialize.class),
- new FunctionDef(FunSerialize.signatures[1], FunSerialize.class),
- new FunctionDef(FunStartsWith.signatures[0], FunStartsWith.class),
- new FunctionDef(FunStartsWith.signatures[1], FunStartsWith.class),
- new FunctionDef(FunString.signatures[0], FunString.class),
- new FunctionDef(FunString.signatures[1], FunString.class),
- new FunctionDef(FunStringJoin.signatures[0], FunStringJoin.class),
- new FunctionDef(FunStringJoin.signatures[1], FunStringJoin.class),
- new FunctionDef(FunStringToCodepoints.signature, FunStringToCodepoints.class),
- new FunctionDef(FunStrLength.signatures[0], FunStrLength.class),
- new FunctionDef(FunStrLength.signatures[1], FunStrLength.class),
- new FunctionDef(FunSubSequence.signatures[0], FunSubSequence.class),
- new FunctionDef(FunSubSequence.signatures[1], FunSubSequence.class),
- new FunctionDef(FunSubstring.signatures[0], FunSubstring.class),
- new FunctionDef(FunSubstring.signatures[1], FunSubstring.class),
- new FunctionDef(FunSubstringAfter.signatures[0], FunSubstringAfter.class),
- new FunctionDef(FunSubstringAfter.signatures[1], FunSubstringAfter.class),
- new FunctionDef(FunSubstringBefore.signatures[0], FunSubstringBefore.class),
- new FunctionDef(FunSubstringBefore.signatures[1], FunSubstringBefore.class),
- new FunctionDef(FunSum.signatures[0], FunSum.class),
- new FunctionDef(FunSum.signatures[1], FunSum.class),
- new FunctionDef(FunTokenize.FS_TOKENIZE[0], FunTokenize.class),
- new FunctionDef(FunTokenize.FS_TOKENIZE[1], FunTokenize.class),
- new FunctionDef(FunTokenize.FS_TOKENIZE[2], FunTokenize.class),
- new FunctionDef(FunTrace.FS_TRACE1, FunTrace.class),
- new FunctionDef(FunTrace.FS_TRACE2, FunTrace.class),
- new FunctionDef(FnTransform.FS_TRANSFORM, FnTransform.class),
- new FunctionDef(FunTranslate.signature, FunTranslate.class),
- new FunctionDef(FunTrueOrFalse.fnTrue, FunTrueOrFalse.class),
- new FunctionDef(FunTrueOrFalse.fnFalse, FunTrueOrFalse.class),
- new FunctionDef(FunUpperOrLowerCase.fnLowerCase, FunUpperOrLowerCase.class),
- new FunctionDef(FunUpperOrLowerCase.fnUpperCase, FunUpperOrLowerCase.class),
- new FunctionDef(FunUriCollection.FS_URI_COLLECTION_SIGNATURES[0], FunUriCollection.class),
- new FunctionDef(FunUriCollection.FS_URI_COLLECTION_SIGNATURES[1], FunUriCollection.class),
- new FunctionDef(FunXmlToJson.FS_XML_TO_JSON[0], FunXmlToJson.class),
- new FunctionDef(FunXmlToJson.FS_XML_TO_JSON[1], FunXmlToJson.class),
- new FunctionDef(FunZeroOrOne.signature, FunZeroOrOne.class),
- new FunctionDef(FunUnordered.signature, FunUnordered.class),
- new FunctionDef(ExtCollection.signature, ExtCollection.class),
- new FunctionDef(QNameFunctions.localNameFromQName, QNameFunctions.class),
- new FunctionDef(QNameFunctions.prefixFromQName, QNameFunctions.class),
- new FunctionDef(QNameFunctions.namespaceURIFromQName, QNameFunctions.class),
- new FunctionDef(FunResolveQName.signature, FunResolveQName.class),
- new FunctionDef(FunEquals.signatures[0], FunEquals.class),
- new FunctionDef(FunEquals.signatures[1], FunEquals.class),
- new FunctionDef(FunAnalyzeString.signatures[0], FunAnalyzeString.class),
- new FunctionDef(FunAnalyzeString.signatures[1], FunAnalyzeString.class),
- new FunctionDef(FunHeadTail.signatures[0], FunHeadTail.class),
- new FunctionDef(FunHeadTail.signatures[1], FunHeadTail.class),
- new FunctionDef(FunHigherOrderFun.FN_FOR_EACH, FunHigherOrderFun.class),
- new FunctionDef(FunHigherOrderFun.FN_FOR_EACH_PAIR, FunHigherOrderFun.class),
- new FunctionDef(FunHigherOrderFun.FN_FILTER, FunHigherOrderFun.class),
- new FunctionDef(FunHigherOrderFun.FN_FOLD_LEFT, FunHigherOrderFun.class),
- new FunctionDef(FunHigherOrderFun.FN_FOLD_RIGHT, FunHigherOrderFun.class),
- new FunctionDef(FunHigherOrderFun.FN_APPLY, FunHigherOrderFun.class),
- new FunctionDef(FunEnvironment.signature[0], FunEnvironment.class),
- new FunctionDef(FunEnvironment.signature[1], FunEnvironment.class),
- new FunctionDef(ParsingFunctions.signatures[0], ParsingFunctions.class),
- new FunctionDef(ParsingFunctions.signatures[1], ParsingFunctions.class),
- new FunctionDef(JSON.FS_PARSE_JSON[0], JSON.class),
- new FunctionDef(JSON.FS_PARSE_JSON[1], JSON.class),
- new FunctionDef(JSON.FS_JSON_DOC[0], JSON.class),
- new FunctionDef(JSON.FS_JSON_DOC[1], JSON.class),
- new FunctionDef(JSON.FS_JSON_TO_XML[0], JSON.class),
- new FunctionDef(JSON.FS_JSON_TO_XML[1], JSON.class),
- new FunctionDef(LoadXQueryModule.LOAD_XQUERY_MODULE_1, LoadXQueryModule.class),
- new FunctionDef(LoadXQueryModule.LOAD_XQUERY_MODULE_2, LoadXQueryModule.class),
- new FunctionDef(FunSort.signatures[0], FunSort.class),
- new FunctionDef(FunSort.signatures[1], FunSort.class),
- new FunctionDef(FunSort.signatures[2], FunSort.class),
- new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT[0], FunUnparsedText.class),
- new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT[1], FunUnparsedText.class),
- new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT_LINES[0], FunUnparsedText.class),
- new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT_LINES[1], FunUnparsedText.class),
- new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT_AVAILABLE[0], FunUnparsedText.class),
- new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT_AVAILABLE[1], FunUnparsedText.class),
- new FunctionDef(FnRandomNumberGenerator.FS_RANDOM_NUMBER_GENERATOR[0], FnRandomNumberGenerator.class),
- new FunctionDef(FnRandomNumberGenerator.FS_RANDOM_NUMBER_GENERATOR[1], FnRandomNumberGenerator.class),
- new FunctionDef(FunContainsToken.FS_CONTAINS_TOKEN[0], FunContainsToken.class),
- new FunctionDef(FunContainsToken.FS_CONTAINS_TOKEN[1], FunContainsToken.class)
- };
-
- static {
- Arrays.sort(functions, new FunctionComparator());
- }
-
- public final static ErrorCodes.ErrorCode SENR0001 = new ErrorCodes.ErrorCode("SENR0001", "serialization error in fn:serialize");
- public final static ErrorCodes.ErrorCode SEPM0019 = new ErrorCodes.ErrorCode("SEPM0019", "It is an error if an instance of the data model " +
- "used to specify the settings of serialization parameters specifies the value of the same parameter more than once.");
-
- public FnModule(Map> parameters) {
- super(functions, parameters, true);
- }
-
- @Override
- public String getDescription() {
- return "A module with the XQuery/XPath Core Library Functions";
- }
-
- @Override
- public String getNamespaceURI() {
- return Function.BUILTIN_FUNCTION_NS;
- }
-
- @Override
- public String getDefaultPrefix() {
- return PREFIX;
- }
-
- @Override
- public String getReleaseVersion() {
- return RELEASED_IN_VERSION;
- }
-
- static FunctionSignature functionSignature(final String name, final String description,
- final FunctionReturnSequenceType returnType, final FunctionParameterSequenceType... paramTypes) {
- return FunctionDSL.functionSignature(new QName(name, Function.BUILTIN_FUNCTION_NS), description,
- returnType, paramTypes);
- }
-
- static FunctionSignature[] functionSignatures(final String name, final String description,
- final FunctionReturnSequenceType returnType, final FunctionParameterSequenceType[][] variableParamTypes) {
- return FunctionDSL.functionSignatures(new QName(name, Function.BUILTIN_FUNCTION_NS), description,
- returnType, variableParamTypes);
- }
-}
+/*
+ * eXist-db Open Source Native XML Database
+ * Copyright (C) 2001 The eXist-db Authors
+ *
+ * info@exist-db.org
+ * http://www.exist-db.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.xquery.functions.fn;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.exist.dom.QName;
+import org.exist.xquery.*;
+import org.exist.xquery.value.FunctionParameterSequenceType;
+import org.exist.xquery.value.FunctionReturnSequenceType;
+
+/**
+ * Module function definitions for xpath-functions module.
+ *
+ * @author Wolfgang Meier
+ * @author ljo
+ */
+public class FnModule extends AbstractInternalModule {
+
+ public final static String PREFIX = "";
+ public final static String INCLUSION_DATE = "2004-01-29";
+ public final static String RELEASED_IN_VERSION = "pre eXist-1.0";
+
+ public final static FunctionDef[] functions = {
+ new FunctionDef(FunAbs.signature, FunAbs.class),
+ new FunctionDef(FunAvg.signature, FunAvg.class),
+ new FunctionDef(FunBaseURI.FS_BASE_URI_0, FunBaseURI.class),
+ new FunctionDef(FunBaseURI.FS_BASE_URI_1, FunBaseURI.class),
+ new FunctionDef(FunBaseURI.FS_STATIC_BASE_URI_0, FunBaseURI.class),
+ new FunctionDef(FunBoolean.signature, FunBoolean.class),
+ new FunctionDef(FunCeiling.signature, FunCeiling.class),
+ new FunctionDef(FunCodepointEqual.signature, FunCodepointEqual.class),
+ new FunctionDef(FunCodepointsToString.signature, FunCodepointsToString.class),
+ new FunctionDef(FunCollationKey.FS_COLLATION_KEY_SIGNATURES[0], FunCollationKey.class),
+ new FunctionDef(FunCollationKey.FS_COLLATION_KEY_SIGNATURES[1], FunCollationKey.class),
+ new FunctionDef(FunCompare.signatures[0], FunCompare.class),
+ new FunctionDef(FunCompare.signatures[1], FunCompare.class),
+ new FunctionDef(FunConcat.signature, FunConcat.class),
+ new FunctionDef(FunContains.signatures[0], FunContains.class),
+ new FunctionDef(FunContains.signatures[1], FunContains.class),
+ new FunctionDef(FunCount.signature, FunCount.class),
+ new FunctionDef(FunCurrentDateTime.fnCurrentDate, FunCurrentDateTime.class),
+ new FunctionDef(FunCurrentDateTime.fnCurrentDateTime, FunCurrentDateTime.class),
+ new FunctionDef(FunCurrentDateTime.fnCurrentTime, FunCurrentDateTime.class),
+ new FunctionDef(FunData.signatures[0], FunData.class),
+ new FunctionDef(FunData.signatures[1], FunData.class),
+ new FunctionDef(FunDateTime.signature, FunDateTime.class),
+ new FunctionDef(FunDeepEqual.signatures[0], FunDeepEqual.class),
+ new FunctionDef(FunDeepEqual.signatures[1], FunDeepEqual.class),
+ new FunctionDef(FunDefaultCollation.signature, FunDefaultCollation.class),
+ new FunctionDef(FnDefaultLanguage.FS_DEFAULT_LANGUAGE, FnDefaultLanguage.class),
+ new FunctionDef(FunDistinctValues.signatures[0], FunDistinctValues.class),
+ new FunctionDef(FunDistinctValues.signatures[1], FunDistinctValues.class),
+ new FunctionDef(FunDoc.signature, FunDoc.class),
+ new FunctionDef(FunDocAvailable.signature, FunDocAvailable.class),
+ new FunctionDef(FunDocumentURI.FS_DOCUMENT_URI_0, FunDocumentURI.class),
+ new FunctionDef(FunDocumentURI.FS_DOCUMENT_URI_1, FunDocumentURI.class),
+ new FunctionDef(FunElementWithId.FS_ELEMENT_WITH_ID_SIGNATURES[0], FunElementWithId.class),
+ new FunctionDef(FunElementWithId.FS_ELEMENT_WITH_ID_SIGNATURES[1], FunElementWithId.class),
+ new FunctionDef(FunEmpty.signature, FunEmpty.class),
+ new FunctionDef(FunEncodeForURI.signature, FunEncodeForURI.class),
+ new FunctionDef(FunEndsWith.signatures[0], FunEndsWith.class),
+ new FunctionDef(FunEndsWith.signatures[1], FunEndsWith.class),
+ new FunctionDef(FunError.signature[0], FunError.class),
+ new FunctionDef(FunError.signature[1], FunError.class),
+ new FunctionDef(FunError.signature[2], FunError.class),
+ new FunctionDef(FunError.signature[3], FunError.class),
+ new FunctionDef(FunEscapeHTMLURI.signature, FunEscapeHTMLURI.class),
+ new FunctionDef(FunEscapeURI.signature, FunEscapeURI.class),
+ new FunctionDef(FunExactlyOne.signature, FunExactlyOne.class),
+ new FunctionDef(FunExists.signature, FunExists.class),
+ new FunctionDef(FunFloor.signature, FunFloor.class),
+ new FunctionDef(FnFormatDates.FNS_FORMAT_DATETIME_2, FnFormatDates.class),
+ new FunctionDef(FnFormatDates.FNS_FORMAT_DATETIME_5, FnFormatDates.class),
+ new FunctionDef(FnFormatDates.FNS_FORMAT_DATE_2, FnFormatDates.class),
+ new FunctionDef(FnFormatDates.FNS_FORMAT_DATE_5, FnFormatDates.class),
+ new FunctionDef(FnFormatDates.FNS_FORMAT_TIME_2, FnFormatDates.class),
+ new FunctionDef(FnFormatDates.FNS_FORMAT_TIME_5, FnFormatDates.class),
+ new FunctionDef(FnFormatIntegers.FS_FORMAT_INTEGER[0], FnFormatIntegers.class),
+ new FunctionDef(FnFormatIntegers.FS_FORMAT_INTEGER[1], FnFormatIntegers.class),
+ new FunctionDef(FnFormatNumbers.FS_FORMAT_NUMBER[0], FnFormatNumbers.class),
+ new FunctionDef(FnFormatNumbers.FS_FORMAT_NUMBER[1], FnFormatNumbers.class),
+ new FunctionDef(FunGenerateId.signatures[0], FunGenerateId.class),
+ new FunctionDef(FunGenerateId.signatures[1], FunGenerateId.class),
+ new FunctionDef(FunGetDateComponent.fnDayFromDate, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnMonthFromDate, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnYearFromDate, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnTimezoneFromDate, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnHoursFromTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnMinutesFromTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnSecondsFromTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnTimezoneFromTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnDayFromDateTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnMonthFromDateTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnYearFromDateTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnHoursFromDateTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnMinutesFromDateTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnSecondsFromDateTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDateComponent.fnTimezoneFromDateTime, FunGetDateComponent.class),
+ new FunctionDef(FunGetDurationComponent.fnYearsFromDuration, FunGetDurationComponent.class),
+ new FunctionDef(FunGetDurationComponent.fnMonthsFromDuration, FunGetDurationComponent.class),
+ new FunctionDef(FunGetDurationComponent.fnDaysFromDuration, FunGetDurationComponent.class),
+ new FunctionDef(FunGetDurationComponent.fnHoursFromDuration, FunGetDurationComponent.class),
+ new FunctionDef(FunGetDurationComponent.fnMinutesFromDuration, FunGetDurationComponent.class),
+ new FunctionDef(FunGetDurationComponent.fnSecondsFromDuration, FunGetDurationComponent.class),
+ new FunctionDef(FunAdjustTimezone.fnAdjustDateToTimezone[0], FunAdjustTimezone.class),
+ new FunctionDef(FunAdjustTimezone.fnAdjustDateToTimezone[1], FunAdjustTimezone.class),
+ new FunctionDef(FunAdjustTimezone.fnAdjustTimeToTimezone[0], FunAdjustTimezone.class),
+ new FunctionDef(FunAdjustTimezone.fnAdjustTimeToTimezone[1], FunAdjustTimezone.class),
+ new FunctionDef(FunAdjustTimezone.fnAdjustDateTimeToTimezone[0], FunAdjustTimezone.class),
+ new FunctionDef(FunAdjustTimezone.fnAdjustDateTimeToTimezone[1], FunAdjustTimezone.class),
+ new FunctionDef(FunParseIetfDate.FNS_PARSE_IETF_DATE, FunParseIetfDate.class),
+ new FunctionDef(FnHasChildren.FNS_HAS_CHILDREN_0, FnHasChildren.class),
+ new FunctionDef(FnHasChildren.FNS_HAS_CHILDREN_1, FnHasChildren.class),
+ new FunctionDef(FunId.signature[0], FunId.class),
+ new FunctionDef(FunId.signature[1], FunId.class),
+ new FunctionDef(FunIdRef.signature[0], FunIdRef.class),
+ new FunctionDef(FunIdRef.signature[1], FunIdRef.class),
+ new FunctionDef(FunImplicitTimezone.signature, FunImplicitTimezone.class),
+ new FunctionDef(FunIndexOf.fnIndexOf[0], FunIndexOf.class),
+ new FunctionDef(FunIndexOf.fnIndexOf[1], FunIndexOf.class),
+ new FunctionDef(FnInnerMost.FNS_INNERMOST, FnInnerMost.class),
+ new FunctionDef(FunIRIToURI.signature, FunIRIToURI.class),
+ new FunctionDef(FunInScopePrefixes.signature, FunInScopePrefixes.class),
+ new FunctionDef(FunInsertBefore.signature, FunInsertBefore.class),
+ new FunctionDef(FunLang.signatures[0], FunLang.class),
+ new FunctionDef(FunLang.signatures[1], FunLang.class),
+ new FunctionDef(FunLast.signature, FunLast.class),
+ new FunctionDef(FunLocalName.signatures[0], FunLocalName.class),
+ new FunctionDef(FunLocalName.signatures[1], FunLocalName.class),
+ new FunctionDef(FunOnFunctions.signatures[0], FunOnFunctions.class),
+ new FunctionDef(FunOnFunctions.signatures[1], FunOnFunctions.class),
+ new FunctionDef(FunOnFunctions.signatures[2], FunOnFunctions.class),
+ new FunctionDef(FunMatches.signatures[0], FunMatches.class),
+ new FunctionDef(FunMatches.signatures[1], FunMatches.class),
+ new FunctionDef(FunMax.signatures[0], FunMax.class),
+ new FunctionDef(FunMax.signatures[1], FunMax.class),
+ new FunctionDef(FunMin.signatures[0], FunMin.class),
+ new FunctionDef(FunMin.signatures[1], FunMin.class),
+ new FunctionDef(FunNodeName.signatures[0], FunNodeName.class),
+ new FunctionDef(FunNodeName.signatures[1], FunNodeName.class),
+ new FunctionDef(FunName.signatures[0], FunName.class),
+ new FunctionDef(FunName.signatures[1], FunName.class),
+ new FunctionDef(FunNamespaceURI.signatures[0], FunNamespaceURI.class),
+ new FunctionDef(FunNamespaceURI.signatures[1], FunNamespaceURI.class),
+ new FunctionDef(FunNamespaceURIForPrefix.signature, FunNamespaceURIForPrefix.class),
+ new FunctionDef(FunNilled.FUNCTION_SIGNATURES_NILLED[0], FunNilled.class),
+ new FunctionDef(FunNilled.FUNCTION_SIGNATURES_NILLED[1], FunNilled.class),
+ new FunctionDef(FunNormalizeSpace.signatures[0], FunNormalizeSpace.class),
+ new FunctionDef(FunNormalizeSpace.signatures[1], FunNormalizeSpace.class),
+ new FunctionDef(FunNormalizeUnicode.signatures[0], FunNormalizeUnicode.class),
+ new FunctionDef(FunNormalizeUnicode.signatures[1], FunNormalizeUnicode.class),
+ new FunctionDef(FunNot.signature, FunNot.class),
+ new FunctionDef(FunNumber.signatures[0], FunNumber.class),
+ new FunctionDef(FunNumber.signatures[1], FunNumber.class),
+ new FunctionDef(FunOneOrMore.signature, FunOneOrMore.class),
+ new FunctionDef(FnOuterMost.FNS_OUTERMOST, FnOuterMost.class),
+ new FunctionDef(FunPath.FS_PATH_SIGNATURES[0], FunPath.class),
+ new FunctionDef(FunPath.FS_PATH_SIGNATURES[1], FunPath.class),
+ new FunctionDef(FunPosition.signature, FunPosition.class),
+ new FunctionDef(FunQName.signature, FunQName.class),
+ new FunctionDef(FunRemove.signature, FunRemove.class),
+ new FunctionDef(FunReplace.FS_REPLACE[0], FunReplace.class),
+ new FunctionDef(FunReplace.FS_REPLACE[1], FunReplace.class),
+ new FunctionDef(FunReverse.signature, FunReverse.class),
+ new FunctionDef(FunResolveURI.signatures[0], FunResolveURI.class),
+ new FunctionDef(FunResolveURI.signatures[1], FunResolveURI.class),
+ new FunctionDef(FunRoot.signatures[0], FunRoot.class),
+ new FunctionDef(FunRoot.signatures[1], FunRoot.class),
+ new FunctionDef(FunRound.FN_ROUND_SIGNATURES[0], FunRound.class),
+ new FunctionDef(FunRound.FN_ROUND_SIGNATURES[1], FunRound.class),
+ new FunctionDef(FunRoundHalfToEven.FN_ROUND_HALF_TO_EVEN_SIGNATURES[0], FunRoundHalfToEven.class),
+ new FunctionDef(FunRoundHalfToEven.FN_ROUND_HALF_TO_EVEN_SIGNATURES[1], FunRoundHalfToEven.class),
+ new FunctionDef(FunSerialize.signatures[0], FunSerialize.class),
+ new FunctionDef(FunSerialize.signatures[1], FunSerialize.class),
+ new FunctionDef(FunStartsWith.signatures[0], FunStartsWith.class),
+ new FunctionDef(FunStartsWith.signatures[1], FunStartsWith.class),
+ new FunctionDef(FunString.signatures[0], FunString.class),
+ new FunctionDef(FunString.signatures[1], FunString.class),
+ new FunctionDef(FunStringJoin.signatures[0], FunStringJoin.class),
+ new FunctionDef(FunStringJoin.signatures[1], FunStringJoin.class),
+ new FunctionDef(FunStringToCodepoints.signature, FunStringToCodepoints.class),
+ new FunctionDef(FunStrLength.signatures[0], FunStrLength.class),
+ new FunctionDef(FunStrLength.signatures[1], FunStrLength.class),
+ new FunctionDef(FunSubSequence.signatures[0], FunSubSequence.class),
+ new FunctionDef(FunSubSequence.signatures[1], FunSubSequence.class),
+ new FunctionDef(FunSubstring.signatures[0], FunSubstring.class),
+ new FunctionDef(FunSubstring.signatures[1], FunSubstring.class),
+ new FunctionDef(FunSubstringAfter.signatures[0], FunSubstringAfter.class),
+ new FunctionDef(FunSubstringAfter.signatures[1], FunSubstringAfter.class),
+ new FunctionDef(FunSubstringBefore.signatures[0], FunSubstringBefore.class),
+ new FunctionDef(FunSubstringBefore.signatures[1], FunSubstringBefore.class),
+ new FunctionDef(FunSum.signatures[0], FunSum.class),
+ new FunctionDef(FunSum.signatures[1], FunSum.class),
+ new FunctionDef(FunTokenize.FS_TOKENIZE[0], FunTokenize.class),
+ new FunctionDef(FunTokenize.FS_TOKENIZE[1], FunTokenize.class),
+ new FunctionDef(FunTokenize.FS_TOKENIZE[2], FunTokenize.class),
+ new FunctionDef(FunTrace.FS_TRACE1, FunTrace.class),
+ new FunctionDef(FunTrace.FS_TRACE2, FunTrace.class),
+ new FunctionDef(FnTransform.FS_TRANSFORM, FnTransform.class),
+ new FunctionDef(FunTranslate.signature, FunTranslate.class),
+ new FunctionDef(FunTrueOrFalse.fnTrue, FunTrueOrFalse.class),
+ new FunctionDef(FunTrueOrFalse.fnFalse, FunTrueOrFalse.class),
+ new FunctionDef(FunUpperOrLowerCase.fnLowerCase, FunUpperOrLowerCase.class),
+ new FunctionDef(FunUpperOrLowerCase.fnUpperCase, FunUpperOrLowerCase.class),
+ new FunctionDef(FunUriCollection.FS_URI_COLLECTION_SIGNATURES[0], FunUriCollection.class),
+ new FunctionDef(FunUriCollection.FS_URI_COLLECTION_SIGNATURES[1], FunUriCollection.class),
+ new FunctionDef(FunXmlToJson.FS_XML_TO_JSON[0], FunXmlToJson.class),
+ new FunctionDef(FunXmlToJson.FS_XML_TO_JSON[1], FunXmlToJson.class),
+ new FunctionDef(FunZeroOrOne.signature, FunZeroOrOne.class),
+ new FunctionDef(FunUnordered.signature, FunUnordered.class),
+ new FunctionDef(ExtCollection.signature, ExtCollection.class),
+ new FunctionDef(QNameFunctions.localNameFromQName, QNameFunctions.class),
+ new FunctionDef(QNameFunctions.prefixFromQName, QNameFunctions.class),
+ new FunctionDef(QNameFunctions.namespaceURIFromQName, QNameFunctions.class),
+ new FunctionDef(FunResolveQName.signature, FunResolveQName.class),
+ new FunctionDef(FunEquals.signatures[0], FunEquals.class),
+ new FunctionDef(FunEquals.signatures[1], FunEquals.class),
+ new FunctionDef(FunAnalyzeString.signatures[0], FunAnalyzeString.class),
+ new FunctionDef(FunAnalyzeString.signatures[1], FunAnalyzeString.class),
+ new FunctionDef(FunHeadTail.signatures[0], FunHeadTail.class),
+ new FunctionDef(FunHeadTail.signatures[1], FunHeadTail.class),
+ new FunctionDef(FunHigherOrderFun.FN_FOR_EACH, FunHigherOrderFun.class),
+ new FunctionDef(FunHigherOrderFun.FN_FOR_EACH_PAIR, FunHigherOrderFun.class),
+ new FunctionDef(FunHigherOrderFun.FN_FILTER, FunHigherOrderFun.class),
+ new FunctionDef(FunHigherOrderFun.FN_FOLD_LEFT, FunHigherOrderFun.class),
+ new FunctionDef(FunHigherOrderFun.FN_FOLD_RIGHT, FunHigherOrderFun.class),
+ new FunctionDef(FunHigherOrderFun.FN_APPLY, FunHigherOrderFun.class),
+ new FunctionDef(FunEnvironment.signature[0], FunEnvironment.class),
+ new FunctionDef(FunEnvironment.signature[1], FunEnvironment.class),
+ new FunctionDef(ParsingFunctions.signatures[0], ParsingFunctions.class),
+ new FunctionDef(ParsingFunctions.signatures[1], ParsingFunctions.class),
+ new FunctionDef(JSON.FS_PARSE_JSON[0], JSON.class),
+ new FunctionDef(JSON.FS_PARSE_JSON[1], JSON.class),
+ new FunctionDef(JSON.FS_JSON_DOC[0], JSON.class),
+ new FunctionDef(JSON.FS_JSON_DOC[1], JSON.class),
+ new FunctionDef(JSON.FS_JSON_TO_XML[0], JSON.class),
+ new FunctionDef(JSON.FS_JSON_TO_XML[1], JSON.class),
+ new FunctionDef(LoadXQueryModule.LOAD_XQUERY_MODULE_1, LoadXQueryModule.class),
+ new FunctionDef(LoadXQueryModule.LOAD_XQUERY_MODULE_2, LoadXQueryModule.class),
+ new FunctionDef(FunSort.signatures[0], FunSort.class),
+ new FunctionDef(FunSort.signatures[1], FunSort.class),
+ new FunctionDef(FunSort.signatures[2], FunSort.class),
+ new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT[0], FunUnparsedText.class),
+ new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT[1], FunUnparsedText.class),
+ new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT_LINES[0], FunUnparsedText.class),
+ new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT_LINES[1], FunUnparsedText.class),
+ new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT_AVAILABLE[0], FunUnparsedText.class),
+ new FunctionDef(FunUnparsedText.FS_UNPARSED_TEXT_AVAILABLE[1], FunUnparsedText.class),
+ new FunctionDef(FnRandomNumberGenerator.FS_RANDOM_NUMBER_GENERATOR[0], FnRandomNumberGenerator.class),
+ new FunctionDef(FnRandomNumberGenerator.FS_RANDOM_NUMBER_GENERATOR[1], FnRandomNumberGenerator.class),
+ new FunctionDef(FunContainsToken.FS_CONTAINS_TOKEN[0], FunContainsToken.class),
+ new FunctionDef(FunContainsToken.FS_CONTAINS_TOKEN[1], FunContainsToken.class),
+ new FunctionDef(FnInvisibleXml.FS_INVISIBLE_XML, FnInvisibleXml.class)
+ };
+
+ static {
+ Arrays.sort(functions, new FunctionComparator());
+ }
+
+ public final static ErrorCodes.ErrorCode SENR0001 = new ErrorCodes.ErrorCode("SENR0001", "serialization error in fn:serialize");
+ public final static ErrorCodes.ErrorCode SEPM0019 = new ErrorCodes.ErrorCode("SEPM0019", "It is an error if an instance of the data model " +
+ "used to specify the settings of serialization parameters specifies the value of the same parameter more than once.");
+
+ public FnModule(Map> parameters) {
+ super(functions, parameters, true);
+ }
+
+ @Override
+ public String getDescription() {
+ return "A module with the XQuery/XPath Core Library Functions";
+ }
+
+ @Override
+ public String getNamespaceURI() {
+ return Function.BUILTIN_FUNCTION_NS;
+ }
+
+ @Override
+ public String getDefaultPrefix() {
+ return PREFIX;
+ }
+
+ @Override
+ public String getReleaseVersion() {
+ return RELEASED_IN_VERSION;
+ }
+
+ static FunctionSignature functionSignature(final String name, final String description,
+ final FunctionReturnSequenceType returnType, final FunctionParameterSequenceType... paramTypes) {
+ return FunctionDSL.functionSignature(new QName(name, Function.BUILTIN_FUNCTION_NS), description,
+ returnType, paramTypes);
+ }
+
+ static FunctionSignature[] functionSignatures(final String name, final String description,
+ final FunctionReturnSequenceType returnType, final FunctionParameterSequenceType[][] variableParamTypes) {
+ return FunctionDSL.functionSignatures(new QName(name, Function.BUILTIN_FUNCTION_NS), description,
+ returnType, variableParamTypes);
+ }
+}
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/FunHigherOrderFun.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/FunHigherOrderFun.java
index 599f1c9ac14..1656fe65773 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/fn/FunHigherOrderFun.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/FunHigherOrderFun.java
@@ -224,6 +224,9 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence)
}
} else if (isCalledAs("apply")) {
try (final FunctionReference ref = (FunctionReference) args[0].itemAt(0)) {
+ // Sometimes the function reference has no realUser in its context. In that case we set it using prepareForExecution().
+ if (ref.getCall().getContext().getRealUser() == null)
+ ref.getCall().getContext().prepareForExecution();
ref.analyze(cachedContextInfo);
final ArrayType array = (ArrayType) args[1].itemAt(0);
if (funcRefHasDifferentArity(ref, array.getSize())) {
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Convert.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Convert.java
index 35e5b310763..0fcbf32e5d2 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Convert.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Convert.java
@@ -26,17 +26,23 @@
import net.sf.saxon.type.BuiltInAtomicType;
import org.exist.dom.QName;
import org.exist.dom.memtree.DocumentImpl;
+import org.exist.dom.persistent.NodeProxy;
import org.exist.xquery.ErrorCodes;
import org.exist.xquery.XPathException;
import org.exist.xquery.functions.array.ArrayType;
import org.exist.xquery.functions.fn.FnTransform;
+import org.exist.xquery.functions.map.AbstractMapType;
import org.exist.xquery.value.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
+import io.lacuna.bifurcan.IEntry;
+
import javax.xml.transform.dom.DOMSource;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Type conversion to and from Saxon
@@ -119,11 +125,18 @@ static net.sf.saxon.s9api.QName of(final QNameValue qName) {
}
XdmValue of(final Item item) throws XPathException {
+ if (item instanceof NodeProxy) {
+ return ofNode(((NodeProxy) item).getNode());
+ }
final int itemType = item.getType();
if (Type.subTypeOf(itemType, Type.ATOMIC)) {
return ofAtomic((AtomicValue) item);
} else if (Type.subTypeOf(itemType, Type.NODE)) {
return ofNode((Node) item);
+ } else if (Type.subTypeOf(itemType, Type.MAP)) {
+ return ofMap((AbstractMapType) item);
+ } else if (Type.subTypeOf(itemType, Type.ARRAY)) {
+ return ofArray((ArrayType) item);
}
throw new XPathException(ErrorCodes.XPTY0004,
"Item " + item + " of type " + Type.getTypeName(itemType) + COULD_NOT_BE_CONVERTED + "XdmValue");
@@ -140,14 +153,12 @@ static private XdmValue ofAtomic(final AtomicValue atomicValue) throws XPathExce
} else if (Type.subTypeOf(itemType, Type.STRING)) {
return XdmValue.makeValue(((StringValue) atomicValue).getStringValue());
}
-
throw new XPathException(ErrorCodes.XPTY0004,
"Atomic value " + atomicValue + " of type " + Type.getTypeName(itemType) +
COULD_NOT_BE_CONVERTED + "XdmValue");
}
private XdmValue ofNode(final Node node) throws XPathException {
-
final DocumentBuilder sourceBuilder = newDocumentBuilder();
try {
if (node instanceof DocumentImpl) {
@@ -167,6 +178,25 @@ private XdmValue ofNode(final Node node) throws XPathException {
}
}
+ private XdmValue ofMap(final AbstractMapType map) throws XPathException {
+ Map xdmMap = new HashMap();
+ for (IEntry entry : map) {
+ XdmAtomicValue key = (XdmAtomicValue) ofAtomic(entry.key());
+ XdmValue value = of(entry.value());
+ xdmMap.put(key, value);
+ }
+ return new XdmMap(xdmMap);
+ }
+
+ private XdmValue ofArray(final ArrayType array) throws XPathException {
+ int size = array.getSize();
+ XdmValue[] members = new XdmValue[size];
+ for (int i = 0; i < size; ++i) {
+ members[i] = of(array.get(i));
+ }
+ return new XdmArray(members);
+ }
+
XdmValue[] of(final ArrayType values) throws XPathException {
final int size = values.getSize();
final XdmValue[] result = new XdmValue[size];
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Transform.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
index 34e2b5e33f1..62aa04ebbde 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
@@ -192,8 +192,10 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
final Transform.TemplateInvocation invocation = new Transform.TemplateInvocation(
options, sourceNode, delivery, xslt30Transformer, resultDocuments);
return invocation.invoke();
- } catch (final SaxonApiException | UncheckedXPathException e) {
- throw originalXPathException("Could not transform input: ", e, ErrorCodes.FOXT0003);
+ } catch (final SaxonApiException e) {
+ throw originalXPathException("Could not transform with "+options.xsltSource._1+" line "+e.getLineNumber()+": ", e, ErrorCodes.FOXT0003);
+ } catch (final UncheckedXPathException e) {
+ throw originalXPathException("Could not transform with "+options.xsltSource._1+" line "+e.getXPathException().getLocationAsString()+": ", e, ErrorCodes.FOXT0003);
}
} else {
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/TreeUtils.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/TreeUtils.java
index dae639ea3bf..e710d6ec60d 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/TreeUtils.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/TreeUtils.java
@@ -24,6 +24,7 @@
import net.sf.saxon.s9api.XdmNode;
import org.exist.xquery.value.NodeValue;
+import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -64,20 +65,41 @@ static StringBuilder pathTo(final Node node) {
static List treeIndex(final Node node) {
final Node parent = node.getParentNode();
if (parent == null) {
- return new ArrayList<>();
+ final List index = new ArrayList<>();
+ // The root element always index 0 within the document node.
+ // Some node implementations (e.g., org.exist.dom.memtree.NodeImpl) do not always have an associated document.
+ // In this case, the nodeIndex must get an extra 0 index to be valid for xdmDocument.
+ if (! (node instanceof Document)) {
+ index.add(0);
+ }
+ return index;
}
final List index = treeIndex(parent);
- Node sibling = node.getPreviousSibling();
+ Node sibling = previousSiblingNotAttribute(node);
int position = 0;
while (sibling != null) {
position += 1;
- sibling = sibling.getPreviousSibling();
+ sibling = previousSiblingNotAttribute(sibling);
}
index.add(position);
return index;
}
+ /**
+ * A org.exist.dom.persistent.StoredNode returns attributes of an element as previous siblings of the element's children.
+ * This is not compatible with the way xdmNodeAtIndex works, so we need to compensate for this.
+ * @param node
+ * @return the previous sibling of `node` that is not an attribute.
+ */
+ private static Node previousSiblingNotAttribute(Node node) {
+ Node sibling = node.getPreviousSibling();
+ if (sibling instanceof Attr) {
+ return null;
+ }
+ return sibling;
+ }
+
static XdmNode xdmNodeAtIndex(final XdmNode xdmNode, final List index) {
if (index.isEmpty()) {
return xdmNode;
diff --git a/exist-core/src/main/resources/org/exist/xquery/lib/ixml.ixml b/exist-core/src/main/resources/org/exist/xquery/lib/ixml.ixml
new file mode 100644
index 00000000000..70fcb4f58a5
--- /dev/null
+++ b/exist-core/src/main/resources/org/exist/xquery/lib/ixml.ixml
@@ -0,0 +1,72 @@
+{version 2024-03-19}
+ ixml: s, (prolog, RS)?, rule++RS, s.
+ -s: (whitespace; comment)*. {Optional spacing}
+ -RS: (whitespace; comment)+. {Required spacing}
+ -whitespace: -[Zs];
+ tab;
+ lf;
+ cr.
+ -tab: -#9.
+ -lf: -#a.
+ -cr: -#d.
+ comment: -'{', (cchar; comment)*, -'}'.
+ -cchar: ~['{}'].
+ prolog: version.
+ version: -'ixml', RS, -'version', RS, string, s, -'.'.
+ rule: naming, -['=:'], s, -alts, -'.'.
+ -naming: (mark, s)?, name, s, ('>', s, alias, s)?.
+ @name: namestart, namefollower*.
+ -namestart: ['_'; L].
+-namefollower: namestart;
+ ['-.·‿⁀'; Nd; Mn].
+ @alias: name.
+ alts: alt++(-[';|'], s).
+ alt: term**(-',', s).
+ -term: factor;
+ option;
+ repeat0;
+ repeat1.
+ -factor: terminal;
+ nonterminal;
+ insertion;
+ -'(', s, alts, -')', s.
+ repeat0: factor, (-'*', s; -'**', s, sep).
+ repeat1: factor, (-'+', s; -'++', s, sep).
+ option: factor, -'?', s.
+ @mark: ['@^-'].
+ sep: factor.
+ nonterminal: naming.
+ -terminal: literal;
+ charset.
+ literal: quoted;
+ encoded.
+ -quoted: (tmark, s)?, string, s.
+ @tmark: ['^-'].
+ @string: -'"', dchar+, -'"';
+ -'''', schar+, -''''.
+ dchar: ~['"'; Cc];
+ '"', -'"'. {all characters except controls; quotes must be doubled}
+ schar: ~[''''; Cc];
+ '''', -''''. {all characters except controls; quotes must be doubled}
+ -encoded: (tmark, s)?, -'#', hex, s.
+ @hex: ['0'-'9'; 'a'-'f'; 'A'-'F']+.
+ -charset: inclusion;
+ exclusion.
+ inclusion: (tmark, s)?, set.
+ exclusion: (tmark, s)?, -'~', s, set.
+ -set: -'[', s, (member, s)**(-[';|'], s), -']', s.
+ member: string;
+ -'#', hex;
+ range;
+ class.
+ -range: from, s, -'-', s, to.
+ @from: character.
+ @to: character.
+ -character: -'"', dchar, -'"';
+ -'''', schar, -'''';
+ '#', hex.
+ -class: code.
+ @code: capital, letter?.
+ -capital: ['A'-'Z'].
+ -letter: ['A'-'Z'; 'a'-'z'].
+ insertion: -'+', s, (string; -'#', hex), s.
\ No newline at end of file
diff --git a/exist-docker/pom.xml b/exist-docker/pom.xml
index 78ad8637666..9f76e18f92d 100644
--- a/exist-docker/pom.xml
+++ b/exist-docker/pom.xml
@@ -22,7 +22,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-->
-
+
4.0.0
@@ -187,14 +189,18 @@
-
-
+
+
false
-
+
META-INF/mailcap
-
+
META-INF/mailcap.default
diff --git a/extensions/modules/sql/src/main/java/org/exist/xquery/modules/sql/GetConnectionFunction.java b/extensions/modules/sql/src/main/java/org/exist/xquery/modules/sql/GetConnectionFunction.java
index 5230ffa8179..01698e7bd8f 100644
--- a/extensions/modules/sql/src/main/java/org/exist/xquery/modules/sql/GetConnectionFunction.java
+++ b/extensions/modules/sql/src/main/java/org/exist/xquery/modules/sql/GetConnectionFunction.java
@@ -33,6 +33,7 @@
package org.exist.xquery.modules.sql;
import com.zaxxer.hikari.HikariDataSource;
+import com.zaxxer.hikari.HikariPoolMXBean;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -173,18 +174,27 @@ private Connection getConnectionFromPool(final Sequence[] args) throws XPathExce
throw new XPathException(this, "There is no configured connection pool named: " + poolName);
}
+ Connection connection = null;
try {
if (args.length == 3) {
final String username = args[1].getStringValue();
final String password = args[2].getStringValue();
- return pool.getConnection(username, password);
+ connection = pool.getConnection(username, password);
} else {
- return pool.getConnection();
+ connection = pool.getConnection();
}
} catch (final SQLException sqle) {
LOGGER.error("sql:get-connection-from-pool() Cannot retrieve connection from pool: " + poolName, sqle);
throw new XPathException(this, "sql:get-connection-from-pool() Cannot retrieve connection from pool: " + poolName, sqle);
}
+
+ HikariPoolMXBean poolBean = pool.getHikariPoolMXBean();
+
+ if (poolBean.getThreadsAwaitingConnection() > 0) {
+ LOGGER.info("getConnectionFromPool("+poolName+"), "+poolBean.getActiveConnections()+" active, "+poolBean.getIdleConnections()+" available, "+poolBean.getThreadsAwaitingConnection()+" waiting, "+poolBean.getTotalConnections()+" total connections.");
+ }
+
+ return connection;
}
private static FunctionSignature[] functionSignatures(final String name, final String description, final FunctionReturnSequenceType returnType, final FunctionParameterSequenceType[][] variableParamTypes) {
diff --git a/extensions/modules/sql/src/main/java/org/exist/xquery/modules/sql/SQLModule.java b/extensions/modules/sql/src/main/java/org/exist/xquery/modules/sql/SQLModule.java
index cbff3e400ff..f1af6a053de 100644
--- a/extensions/modules/sql/src/main/java/org/exist/xquery/modules/sql/SQLModule.java
+++ b/extensions/modules/sql/src/main/java/org/exist/xquery/modules/sql/SQLModule.java
@@ -37,25 +37,35 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.exist.dom.QName;
import org.exist.xquery.*;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
import java.sql.SQLException;
-
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.exist.xquery.modules.ModuleUtils;
import org.exist.xquery.modules.ModuleUtils.ContextMapEntryModifier;
-import org.exist.xquery.value.FunctionParameterSequenceType;
-import org.exist.xquery.value.FunctionReturnSequenceType;
-
import javax.annotation.Nullable;
import static org.exist.xquery.FunctionDSL.functionDefs;
@@ -86,6 +96,7 @@ public class SQLModule extends AbstractInternalModule {
public final static String PREPARED_STATEMENTS_CONTEXTVAR = "_eXist_sql_prepared_statements";
private static final Map CONNECTION_POOLS = new ConcurrentHashMap<>();
+ private static final Map NO_CONNECTION_POOLS = new ConcurrentHashMap<>();
private static final Pattern POOL_NAME_PATTERN = Pattern.compile("(pool\\.[0-9]+)\\.name");
public SQLModule(final Map> parameters) {
@@ -105,7 +116,8 @@ public SQLModule(final Map> parameters) {
final String poolId = poolNameMatcher.group(1);
final String poolName = parameter.getValue().get(0).toString();
if (poolName != null && !poolName.isEmpty()) {
- if (!CONNECTION_POOLS.containsKey(poolName)) {
+ boolean connectionFailure = NO_CONNECTION_POOLS.size() > 0;
+ if (!CONNECTION_POOLS.containsKey(poolName) && !connectionFailure) {
final Properties poolProperties = new Properties();;
poolProperties.setProperty("poolName", poolName);
@@ -121,9 +133,18 @@ public SQLModule(final Map> parameters) {
}
}
- final HikariConfig hikariConfig = new HikariConfig(poolProperties);
- final HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
- CONNECTION_POOLS.put(poolName, hikariDataSource);
+ try {
+ final HikariConfig hikariConfig = new HikariConfig(poolProperties);
+ final HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
+ CONNECTION_POOLS.put(poolName, hikariDataSource);
+ } catch (Exception ex) {
+ connectionFailure = true;
+ }
+ }
+ if (connectionFailure && !NO_CONNECTION_POOLS.containsKey(poolName)) {
+ LOG.warn("No database connection for "+poolName+" could be made. Also not for "+String.join(", ", NO_CONNECTION_POOLS.keySet()));
+ CONNECTION_POOLS.put(poolName, new NoConnectionHikariDataSource());
+ NO_CONNECTION_POOLS.put(poolName, new Date());
}
}
}
@@ -291,4 +312,185 @@ public void modifyEntry(final Entry entry) {
}
});
}
+
+ class NoConnectionHikariDataSource extends HikariDataSource {
+ @Override
+ public Connection getConnection() throws SQLException
+ {
+ return new Connection() {
+
+ @Override
+ public T unwrap(Class iface) throws SQLException { return null; }
+
+ @Override
+ public boolean isWrapperFor(Class> iface) throws SQLException { return false; }
+
+ @Override
+ public Statement createStatement() throws SQLException { return null; }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql) throws SQLException { return null; }
+
+ @Override
+ public CallableStatement prepareCall(String sql) throws SQLException { return null; }
+
+ @Override
+ public String nativeSQL(String sql) throws SQLException { return null; }
+
+ @Override
+ public void setAutoCommit(boolean autoCommit) throws SQLException {}
+
+ @Override
+ public boolean getAutoCommit() throws SQLException { return false; }
+
+ @Override
+ public void commit() throws SQLException {}
+
+ @Override
+ public void rollback() throws SQLException {}
+
+ @Override
+ public void close() throws SQLException {}
+
+ @Override
+ public boolean isClosed() throws SQLException { return false; }
+
+ @Override
+ public DatabaseMetaData getMetaData() throws SQLException { return null; }
+
+ @Override
+ public void setReadOnly(boolean readOnly) throws SQLException {}
+
+ @Override
+ public boolean isReadOnly() throws SQLException { return false; }
+
+ @Override
+ public void setCatalog(String catalog) throws SQLException {}
+
+ @Override
+ public String getCatalog() throws SQLException { return null; }
+
+ @Override
+ public void setTransactionIsolation(int level) throws SQLException {}
+
+ @Override
+ public int getTransactionIsolation() throws SQLException { return 0;}
+
+ @Override
+ public SQLWarning getWarnings() throws SQLException { return null; }
+
+ @Override
+ public void clearWarnings() throws SQLException {}
+
+ @Override
+ public Statement createStatement(int resultSetType, int resultSetConcurrency)
+ throws SQLException { return null; }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int resultSetType,
+ int resultSetConcurrency) throws SQLException { return null; }
+
+ @Override
+ public CallableStatement prepareCall(String sql, int resultSetType,
+ int resultSetConcurrency) throws SQLException { return null; }
+
+ @Override
+ public Map> getTypeMap() throws SQLException { return null; }
+
+ @Override
+ public void setTypeMap(Map> map) throws SQLException {}
+
+ @Override
+ public void setHoldability(int holdability) throws SQLException {}
+
+ @Override
+ public int getHoldability() throws SQLException { return 0; }
+
+ @Override
+ public Savepoint setSavepoint() throws SQLException { return null; }
+
+ @Override
+ public Savepoint setSavepoint(String name) throws SQLException { return null; }
+
+ @Override
+ public void rollback(Savepoint savepoint) throws SQLException {}
+
+ @Override
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {}
+
+ @Override
+ public Statement createStatement(int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException { return null; }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null; }
+
+ @Override
+ public CallableStatement prepareCall(String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null; }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+ throws SQLException { return null; }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+ throws SQLException { return null; }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, String[] columnNames)
+ throws SQLException { return null; }
+
+ @Override
+ public Clob createClob() throws SQLException { return null; }
+
+ @Override
+ public Blob createBlob() throws SQLException { return null; }
+
+ @Override
+ public NClob createNClob() throws SQLException { return null; }
+
+ @Override
+ public SQLXML createSQLXML() throws SQLException { return null; }
+
+ @Override
+ public boolean isValid(int timeout) throws SQLException { return false; }
+
+ @Override
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {}
+
+ @Override
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {}
+
+ @Override
+ public String getClientInfo(String name) throws SQLException { return null; }
+
+ @Override
+ public Properties getClientInfo() throws SQLException { return null; }
+
+ @Override
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException { return null; }
+
+ @Override
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException { return null; }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {}
+
+ @Override
+ public String getSchema() throws SQLException { return null; }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {}
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds)
+ throws SQLException {}
+
+ @Override
+ public int getNetworkTimeout() throws SQLException { return 0; }
+ };
+ }
+ }
}