Skip to content

Commit f59578a

Browse files
committed
Enable the serialization and deserialization of all DOM Node types within function parameter values. Previously only Node.DOCUMENT_NODE was correctly supported.
1 parent 8cf232c commit f59578a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+870
-103
lines changed

client/src/main/java/org/apache/xmlrpc/client/XmlRpcStreamTransport.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
import org.apache.xmlrpc.common.XmlRpcStreamConfig;
3030
import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
3131
import org.apache.xmlrpc.parser.XmlRpcResponseParser;
32+
import org.apache.xmlrpc.serializer.SerializerHandler;
3233
import org.apache.xmlrpc.serializer.XmlRpcWriter;
3334
import org.apache.xmlrpc.util.SAXParsers;
34-
import org.xml.sax.ContentHandler;
3535
import org.xml.sax.InputSource;
3636
import org.xml.sax.SAXException;
3737
import org.xml.sax.XMLReader;
@@ -75,7 +75,7 @@ public void write(OutputStream pStream)
7575
throws XmlRpcException, IOException, SAXException {
7676
final XmlRpcStreamConfig config = (XmlRpcStreamConfig) request.getConfig();
7777
try {
78-
ContentHandler h = getClient().getXmlWriterFactory().getXmlWriter(config, pStream);
78+
SerializerHandler h = getClient().getXmlWriterFactory().getXmlWriter(config, pStream);
7979
XmlRpcWriter xw = new XmlRpcWriter(config, h, getClient().getTypeFactory());
8080
xw.write(request);
8181
pStream.close();
@@ -200,6 +200,7 @@ protected Object readResponse(XmlRpcStreamRequestConfig pConfig, InputStream pSt
200200
try {
201201
xp = new XmlRpcResponseParser(pConfig, getClient().getTypeFactory());
202202
xr.setContentHandler(xp);
203+
xr.setProperty("http://xml.org/sax/properties/lexical-handler", xp);
203204
xr.parse(isource);
204205
} catch (SAXException e) {
205206
throw new XmlRpcClientException("Failed to parse server's response: " + e.getMessage(), e);

common/src/main/java/org/apache/xmlrpc/jaxb/JaxbParser.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,30 @@
2020

2121
import javax.xml.bind.JAXBContext;
2222
import javax.xml.bind.JAXBException;
23-
import javax.xml.bind.UnmarshallerHandler;
2423

2524
import org.apache.xmlrpc.XmlRpcException;
2625
import org.apache.xmlrpc.parser.ExtParser;
27-
import org.xml.sax.ContentHandler;
26+
import org.apache.xmlrpc.parser.ParserHandler;
27+
import org.xml.sax.Attributes;
2828
import org.xml.sax.SAXException;
2929

3030

3131
/** A parser for JAXB objects.
3232
*/
3333
public class JaxbParser extends ExtParser {
34-
private final JAXBContext context;
35-
private UnmarshallerHandler handler;
34+
private final JAXBContext context;
35+
private UnmarshallerParserHandler handler;
3636

3737
/** Creates a new instance with the given context.
3838
* @param pContext The context being used for creating unmarshallers.
3939
*/
4040
public JaxbParser(JAXBContext pContext) {
41-
context = pContext;
41+
context = pContext;
4242
}
4343

44-
protected ContentHandler getExtHandler() throws SAXException {
44+
protected ParserHandler getExtHandler(Attributes attrs) throws SAXException {
4545
try {
46-
handler = context.createUnmarshaller().getUnmarshallerHandler();
46+
handler = new UnmarshallerParserHandler(context.createUnmarshaller().getUnmarshallerHandler());
4747
} catch (JAXBException e) {
4848
throw new SAXException(e);
4949
}

common/src/main/java/org/apache/xmlrpc/jaxb/JaxbSerializer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import javax.xml.bind.JAXBException;
2323

2424
import org.apache.xmlrpc.serializer.ExtSerializer;
25+
import org.apache.xmlrpc.serializer.SerializerHandler;
2526
import org.xml.sax.Attributes;
2627
import org.xml.sax.ContentHandler;
2728
import org.xml.sax.Locator;
@@ -46,7 +47,7 @@ public JaxbSerializer(JAXBContext pContext) {
4647

4748
protected String getTagName() { return JAXB_TAG; }
4849

49-
protected void serialize(final ContentHandler pHandler, Object pObject) throws SAXException {
50+
protected void serialize(final SerializerHandler pHandler, Object pObject) throws SAXException {
5051
/* We must ensure, that startDocument() and endDocument() events
5152
* are suppressed. So we replace the content handler with the following:
5253
*/
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.xmlrpc.jaxb;
20+
21+
import org.apache.xmlrpc.parser.ParserHandler;
22+
import org.xml.sax.Attributes;
23+
import org.xml.sax.Locator;
24+
import org.xml.sax.SAXException;
25+
26+
import javax.xml.bind.JAXBException;
27+
import javax.xml.bind.UnmarshallerHandler;
28+
29+
public class UnmarshallerParserHandler implements UnmarshallerHandler, ParserHandler {
30+
31+
private UnmarshallerHandler handler;
32+
33+
public UnmarshallerParserHandler(final UnmarshallerHandler handler) {
34+
this.handler = handler;
35+
}
36+
37+
public void startDocument() throws SAXException {
38+
handler.startDocument();
39+
}
40+
41+
public void endDocument() throws SAXException {
42+
handler.endDocument();
43+
}
44+
45+
public void startPrefixMapping(String prefix, String uri) throws SAXException {
46+
handler.startPrefixMapping(prefix, uri);
47+
}
48+
49+
public void endPrefixMapping(String prefix) throws SAXException {
50+
handler.endPrefixMapping(prefix);
51+
}
52+
53+
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
54+
handler.startElement(uri, localName, qName, atts);
55+
}
56+
57+
public void endElement(String uri, String localName, String qName) throws SAXException {
58+
handler.endElement(uri, localName, qName);
59+
}
60+
61+
public void characters(char[] ch, int start, int length) throws SAXException {
62+
handler.characters(ch, start, length);
63+
}
64+
65+
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
66+
handler.ignorableWhitespace(ch, start, length);
67+
}
68+
69+
public void processingInstruction(String target, String data) throws SAXException {
70+
handler.processingInstruction(target, data);
71+
}
72+
73+
public void setDocumentLocator(Locator locator) {
74+
handler.setDocumentLocator(locator);
75+
}
76+
77+
public void skippedEntity(String name) throws SAXException {
78+
handler.skippedEntity(name);
79+
}
80+
81+
public void comment(char[] ch, int start, int length) throws SAXException {
82+
}
83+
84+
public void startDTD(String name, String publicId, String systemId) throws SAXException {
85+
}
86+
87+
public void endDTD() throws SAXException {
88+
}
89+
90+
public void startEntity(String name) throws SAXException {
91+
}
92+
93+
public void endEntity(String name) throws SAXException {
94+
}
95+
96+
public void startCDATA() throws SAXException {
97+
}
98+
99+
public void endCDATA() throws SAXException {
100+
}
101+
102+
public Object getResult() throws JAXBException, IllegalStateException {
103+
return handler.getResult();
104+
}
105+
}

common/src/main/java/org/apache/xmlrpc/parser/ExtParser.java

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
import org.apache.xmlrpc.serializer.XmlRpcWriter;
2727
import org.xml.sax.Attributes;
28-
import org.xml.sax.ContentHandler;
2928
import org.xml.sax.Locator;
3029
import org.xml.sax.SAXException;
3130
import org.xml.sax.SAXParseException;
@@ -36,17 +35,18 @@
3635
*/
3736
public abstract class ExtParser implements TypeParser {
3837
private Locator locator;
39-
private ContentHandler handler;
38+
private ParserHandler handler;
4039
private int level = 0;
4140
private final List prefixes = new ArrayList();
4241

4342
/** Returns a content handler for parsing the actual
4443
* contents.
44+
* @param attrs Attributes form the Element we are creating the parser for.
4545
* @return A SAX handler for parsing the XML inside
4646
* the outer ex:foo element.
4747
* @throws SAXException Creating the handler failed.
4848
*/
49-
protected abstract ContentHandler getExtHandler() throws SAXException;
49+
protected abstract ParserHandler getExtHandler(final Attributes attrs) throws SAXException;
5050

5151
/** Returns the outer node name.
5252
* @return the outer node name
@@ -130,7 +130,7 @@ public void startElement(String pURI, String pLocalName,
130130
new QName(pURI, pLocalName),
131131
locator);
132132
}
133-
handler = getExtHandler();
133+
handler = getExtHandler(pAttrs);
134134
handler.startDocument();
135135
for (int i = 0; i < prefixes.size(); i += 2) {
136136
handler.startPrefixMapping((String) prefixes.get(i),
@@ -158,4 +158,46 @@ public void endElement(String pURI, String pLocalName, String pQName)
158158
break;
159159
}
160160
}
161+
162+
public void comment(char[] ch, int start, int length) throws SAXException {
163+
if (handler != null) {
164+
handler.comment(ch, start, length);
165+
}
166+
}
167+
168+
public void startCDATA() throws SAXException {
169+
if (handler != null) {
170+
handler.startCDATA();
171+
}
172+
}
173+
174+
public void endCDATA() throws SAXException {
175+
if (handler != null) {
176+
handler.endCDATA();
177+
}
178+
}
179+
180+
public void startDTD(String name, String publicId, String systemId) throws SAXException {
181+
if (handler != null) {
182+
handler.startDTD(name, publicId, systemId);
183+
}
184+
}
185+
186+
public void endDTD() throws SAXException {
187+
if (handler != null) {
188+
handler.endDTD();
189+
}
190+
}
191+
192+
public void startEntity(String name) throws SAXException {
193+
if (handler != null) {
194+
handler.startEntity(name);
195+
}
196+
}
197+
198+
public void endEntity(String name) throws SAXException {
199+
if (handler != null) {
200+
handler.endEntity(name);
201+
}
202+
}
161203
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.xmlrpc.parser;
20+
21+
import org.apache.ws.commons.serialize.DOMBuilder;
22+
import org.apache.xmlrpc.serializer.NodeSerializer;
23+
import org.w3c.dom.CDATASection;
24+
import org.w3c.dom.Comment;
25+
import org.w3c.dom.Node;
26+
import org.xml.sax.SAXException;
27+
28+
import java.lang.reflect.Field;
29+
30+
public class ExtendedDOMBuilder extends DOMBuilder implements ParserHandler {
31+
32+
private static final String STUB_ELEM_NAME = "stub-element";
33+
34+
private final boolean wrapInElement;
35+
private Field fldCurrentNode = null;
36+
private CDATASection cdataSection = null;
37+
38+
public ExtendedDOMBuilder() {
39+
this(false);
40+
}
41+
42+
public ExtendedDOMBuilder(final boolean wrapInElement) {
43+
super();
44+
this.wrapInElement = wrapInElement;
45+
}
46+
47+
public void startDocument() throws SAXException {
48+
super.startDocument();
49+
if (wrapInElement) {
50+
startElement(NodeSerializer.NS_DOM, STUB_ELEM_NAME, NodeSerializer.PREFIX_DOM + ':' + STUB_ELEM_NAME, TypeParserImpl.ZERO_ATTRIBUTES);
51+
}
52+
}
53+
54+
public void endDocument() throws SAXException {
55+
if (wrapInElement) {
56+
endElement(NodeSerializer.NS_DOM, STUB_ELEM_NAME, NodeSerializer.PREFIX_DOM + ':' + STUB_ELEM_NAME);
57+
}
58+
super.endDocument();
59+
}
60+
61+
public void characters(char[] ch, int start, int length) throws SAXException {
62+
if (cdataSection != null) {
63+
cdataSection.appendData(new String(ch, start, length));
64+
} else {
65+
super.characters(ch, start, length);
66+
}
67+
}
68+
69+
public void startCDATA() throws SAXException {
70+
this.cdataSection = getDocument().createCDATASection("");
71+
}
72+
73+
public void endCDATA() throws SAXException {
74+
getCurrentNode().appendChild(cdataSection);
75+
this.cdataSection = null;
76+
}
77+
78+
public void comment(char[] ch, int start, int length) throws SAXException {
79+
Comment comment = getDocument().createComment(new String(ch, start, length));
80+
getCurrentNode().appendChild(comment);
81+
}
82+
83+
public void startDTD(String name, String publicId, String systemId) throws SAXException {
84+
}
85+
86+
public void endDTD() throws SAXException {
87+
88+
}
89+
90+
public void startEntity(String name) throws SAXException {
91+
}
92+
93+
public void endEntity(String name) throws SAXException {
94+
95+
}
96+
97+
private Node getCurrentNode() throws SAXException {
98+
try {
99+
if (fldCurrentNode == null) {
100+
this.fldCurrentNode = DOMBuilder.class.getDeclaredField("currentNode");
101+
this.fldCurrentNode.setAccessible(true);
102+
}
103+
104+
return (Node) fldCurrentNode.get(this);
105+
106+
} catch (final NoSuchFieldException e) {
107+
throw new SAXException("Unable to access currentNode", e);
108+
} catch (final IllegalAccessException e) {
109+
throw new SAXException("Unable to access currentNode", e);
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)