Skip to content

Commit b269542

Browse files
committed
fn:transform - refactor into own package
The fn:transform implementation is large, and has accumulated many static and dynamic subclasses of FnTransform. This change creates its own package, and creates several top level classes in this package. The FnTransform module itself becomes a much smaller stub around a call into a Transform object which is part of the new package.
1 parent c2d9f54 commit b269542

File tree

7 files changed

+1280
-1108
lines changed

7 files changed

+1280
-1108
lines changed

exist-core/src/main/java/org/exist/xquery/functions/fn/FnTransform.java

Lines changed: 10 additions & 1099 deletions
Large diffs are not rendered by default.

exist-core/src/main/java/org/exist/xquery/functions/fn/Convert.java renamed to exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Convert.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2121
*/
2222

23-
package org.exist.xquery.functions.fn;
23+
package org.exist.xquery.functions.fn.transform;
2424

2525
import net.sf.saxon.s9api.*;
2626
import net.sf.saxon.type.BuiltInAtomicType;
@@ -29,6 +29,7 @@
2929
import org.exist.xquery.ErrorCodes;
3030
import org.exist.xquery.XPathException;
3131
import org.exist.xquery.functions.array.ArrayType;
32+
import org.exist.xquery.functions.fn.FnTransform;
3233
import org.exist.xquery.value.*;
3334
import org.w3c.dom.Document;
3435
import org.w3c.dom.Node;
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* eXist-db Open Source Native XML Database
3+
* Copyright (C) 2001 The eXist-db Authors
4+
*
5+
6+
* http://www.exist-db.org
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2.1 of the License, or (at your option) any later version.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with this library; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
23+
package org.exist.xquery.functions.fn.transform;
24+
25+
import net.sf.saxon.s9api.*;
26+
import net.sf.saxon.serialize.SerializationProperties;
27+
import org.exist.dom.memtree.DocumentBuilderReceiver;
28+
import org.exist.dom.memtree.DocumentImpl;
29+
import org.exist.dom.memtree.MemTreeBuilder;
30+
import org.exist.xquery.ErrorCodes;
31+
import org.exist.xquery.XPathException;
32+
import org.exist.xquery.XQueryContext;
33+
import org.exist.xquery.value.NodeValue;
34+
import org.exist.xquery.value.Sequence;
35+
import org.exist.xquery.value.StringValue;
36+
import org.exist.xquery.value.ValueSequence;
37+
import org.w3c.dom.Node;
38+
import org.w3c.dom.NodeList;
39+
40+
import java.io.StringWriter;
41+
42+
class Delivery {
43+
44+
enum Format {
45+
DOCUMENT,
46+
SERIALIZED,
47+
RAW
48+
}
49+
50+
final XQueryContext context;
51+
final Format format;
52+
final SerializationProperties serializationProperties;
53+
MemTreeBuilder builder;
54+
StringWriter stringWriter;
55+
56+
RawDestination rawDestination;
57+
58+
Delivery(final XQueryContext context, final Format format, final SerializationProperties serializationProperties) {
59+
this.context = context;
60+
this.format = format;
61+
this.serializationProperties = serializationProperties;
62+
}
63+
64+
final Destination createDestination(final Xslt30Transformer xslt30Transformer, final boolean forceCreation) {
65+
switch (format) {
66+
case DOCUMENT:
67+
if (!forceCreation) {
68+
this.builder = context.getDocumentBuilder();
69+
} else {
70+
this.builder = new MemTreeBuilder(context);
71+
this.builder.startDocument();
72+
}
73+
return new SAXDestination(new DocumentBuilderReceiver(builder));
74+
case SERIALIZED:
75+
final Serializer serializer = xslt30Transformer.newSerializer();
76+
final SerializationProperties stylesheetProperties = serializer.getSerializationProperties();
77+
78+
final SerializationProperties combinedProperties =
79+
SerializationParameters.combinePropertiesAndCharacterMaps(
80+
stylesheetProperties,
81+
serializationProperties);
82+
83+
serializer.setOutputProperties(combinedProperties);
84+
stringWriter = new StringWriter();
85+
serializer.setOutputWriter(stringWriter);
86+
return serializer;
87+
case RAW:
88+
this.rawDestination = new RawDestination();
89+
return rawDestination;
90+
default:
91+
return null;
92+
}
93+
}
94+
95+
private String getSerializedString() {
96+
97+
if (stringWriter == null) {
98+
return null;
99+
}
100+
return stringWriter.getBuffer().toString();
101+
}
102+
103+
private DocumentImpl getDocument() {
104+
if (builder == null) {
105+
return null;
106+
}
107+
return builder.getDocument();
108+
}
109+
110+
private XdmValue getXdmValue() {
111+
if (rawDestination == null) {
112+
return null;
113+
}
114+
return rawDestination.getXdmValue();
115+
}
116+
117+
Sequence convert() throws XPathException {
118+
119+
switch (format) {
120+
case SERIALIZED:
121+
return new StringValue(getSerializedString());
122+
case RAW:
123+
//TODO (AP) rawOutput and mediation via document when the Xdm value is complex, is a hack
124+
final XdmValue xdmValue = getXdmValue();
125+
if (xdmValue != null) {
126+
return Convert.ToExist.of(xdmValue);
127+
}
128+
final DocumentImpl document = getDocument();
129+
if (document != null) {
130+
return rawOutput(getDocument());
131+
}
132+
throw new XPathException(ErrorCodes.FOXT0003, "No RAW output has been constructed by the transformation.");
133+
case DOCUMENT:
134+
default:
135+
return getDocument();
136+
}
137+
}
138+
139+
private static Sequence rawOutput(final NodeValue outputDocument) throws XPathException {
140+
final Node node = outputDocument.getNode();
141+
if (node != null) {
142+
final NodeList children = node.getChildNodes();
143+
final int length = children.getLength();
144+
if (length == 0) {
145+
return Sequence.EMPTY_SEQUENCE;
146+
} else if (length == 1) {
147+
final Node item = children.item(0);
148+
if (item instanceof NodeValue) {
149+
return (NodeValue)item;
150+
}
151+
} else {
152+
final ValueSequence valueSequence = new ValueSequence();
153+
for (int i = 0; i < children.getLength(); i++) {
154+
final Node child = children.item(i);
155+
if (child instanceof NodeValue) {
156+
valueSequence.add((NodeValue)child);
157+
}
158+
}
159+
return valueSequence;
160+
}
161+
throw new XPathException(ErrorCodes.XPTY0004, "Unable to produce raw output from contents of: " + outputDocument);
162+
}
163+
return Sequence.EMPTY_SEQUENCE;
164+
}
165+
166+
}

0 commit comments

Comments
 (0)