Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CXF-7491] make Stax & XSLT interceptors Charset-aware #309

Open
wants to merge 5 commits into
base: 3.1.x-fixes
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.apache.cxf.interceptor.StaxInInterceptor;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.staxutils.StaxUtils;

Expand Down Expand Up @@ -79,9 +80,11 @@ public void handleMessage(Message message) {
protected void transformXReader(Message message, XMLStreamReader xReader) {
CachedOutputStream cachedOS = new CachedOutputStream();
try {
StaxUtils.copy(xReader, cachedOS);
InputStream transformedIS = XSLTUtils.transform(getXSLTTemplate(), cachedOS.getInputStream());
XMLStreamReader transformedReader = StaxUtils.createXMLStreamReader(transformedIS);
final String encoding = MessageUtils.getMessageEncoding(message);

StaxUtils.copy(xReader, cachedOS, encoding);
InputStream transformedIS = XSLTUtils.transform(getXSLTTemplate(), cachedOS.getInputStream(), encoding);
XMLStreamReader transformedReader = StaxUtils.createXMLStreamReader(transformedIS, encoding);
message.setContent(XMLStreamReader.class, transformedReader);
} catch (XMLStreamException e) {
throw new Fault("STAX_COPY", LOG, e, e.getMessage());
Expand All @@ -103,7 +106,8 @@ protected void transformXReader(Message message, XMLStreamReader xReader) {

protected void transformIS(Message message, InputStream is) {
try {
InputStream transformedIS = XSLTUtils.transform(getXSLTTemplate(), is);
InputStream transformedIS = XSLTUtils.transform(getXSLTTemplate(), is,
MessageUtils.getMessageEncoding(message));
message.setContent(InputStream.class, transformedIS);
} finally {
try {
Expand All @@ -116,7 +120,7 @@ protected void transformIS(Message message, InputStream is) {

protected void transformReader(Message message, Reader reader) {
try {
Reader transformedReader = XSLTUtils.transform(getXSLTTemplate(), reader);
Reader transformedReader = XSLTUtils.transform(getXSLTTemplate(), reader); // reader encapsulates encoding
message.setContent(Reader.class, transformedReader);
} finally {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.apache.cxf.io.CachedOutputStreamCallback;
import org.apache.cxf.io.CachedWriter;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
import org.apache.cxf.staxutils.StaxUtils;
Expand Down Expand Up @@ -94,7 +95,8 @@ protected void transformXWriter(Message message, XMLStreamWriter xWriter) {

protected void transformOS(Message message, OutputStream out) {
CachedOutputStream wrapper = new CachedOutputStream();
CachedOutputStreamCallback callback = new XSLTCachedOutputStreamCallback(getXSLTTemplate(), out);
CachedOutputStreamCallback callback = new XSLTCachedOutputStreamCallback(getXSLTTemplate(), out,
MessageUtils.getMessageEncoding(message));
wrapper.registerCallback(callback);
message.setContent(OutputStream.class, wrapper);
}
Expand Down Expand Up @@ -147,10 +149,12 @@ public void close() {
public static class XSLTCachedOutputStreamCallback implements CachedOutputStreamCallback {
private final Templates xsltTemplate;
private final OutputStream origStream;
private final String encoding;

public XSLTCachedOutputStreamCallback(Templates xsltTemplate, OutputStream origStream) {
public XSLTCachedOutputStreamCallback(Templates xsltTemplate, OutputStream origStream, String encoding) {
this.xsltTemplate = xsltTemplate;
this.origStream = origStream;
this.encoding = encoding;
}

@Override
Expand All @@ -161,7 +165,7 @@ public void onFlush(CachedOutputStream wrapper) {
public void onClose(CachedOutputStream wrapper) {
InputStream transformedStream = null;
try {
transformedStream = XSLTUtils.transform(xsltTemplate, wrapper.getInputStream());
transformedStream = XSLTUtils.transform(xsltTemplate, wrapper.getInputStream(), encoding);
IOUtils.copyAndCloseInput(transformedStream, origStream);
} catch (IOException e) {
throw new Fault("STREAM_COPY", LOG, e, e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;

import javax.xml.stream.XMLStreamReader;
Expand Down Expand Up @@ -50,10 +51,10 @@ private XSLTUtils() {

}

public static InputStream transform(Templates xsltTemplate, InputStream in) {
public static InputStream transform(Templates xsltTemplate, InputStream in, String encoding) {
CachedOutputStream out = new CachedOutputStream();
try {
XMLStreamReader reader = StaxUtils.createXMLStreamReader(in);
XMLStreamReader reader = StaxUtils.createXMLStreamReader(in, encoding);
Source beforeSource = new StaxSource(reader);

Transformer trans = xsltTemplate.newTransformer();
Expand All @@ -77,6 +78,9 @@ public static InputStream transform(Templates xsltTemplate, InputStream in) {
}
}
}
public static InputStream transform(Templates xsltTemplate, InputStream in) {
return transform(xsltTemplate, in, StandardCharsets.UTF_8.name());
}

public static Reader transform(Templates xsltTemplate, Reader inReader) {
CachedWriter outWriter = new CachedWriter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,20 @@ public void handleMessage(Message message) {
&& !MessageUtils.getContextualBoolean(message, contextPropertyName, false)) {
return;
}

XMLStreamReader reader = message.getContent(XMLStreamReader.class);
InputStream is = message.getContent(InputStream.class);

XMLStreamReader transformReader = createTransformReaderIfNeeded(reader, is);

final String encoding = MessageUtils.getMessageEncoding(message);
XMLStreamReader transformReader = createTransformReaderIfNeeded(reader, is, encoding);
if (transformReader != null) {
message.setContent(XMLStreamReader.class, transformReader);
}

}

protected XMLStreamReader createTransformReaderIfNeeded(XMLStreamReader reader, InputStream is) {
return TransformUtils.createTransformReaderIfNeeded(reader, is,
protected XMLStreamReader createTransformReaderIfNeeded(XMLStreamReader reader, InputStream is, String encoding) {
return TransformUtils.createTransformReaderIfNeeded(reader, is, encoding,
inDropElements,
inElementsMap,
inAppendMap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@


/**
* Creates an XMLStreamReader from the InputStream on the Message.
* Creates an XMLStreamWriter from the OutputStream on the Message.
*/
public class TransformOutInterceptor extends AbstractPhaseInterceptor<Message> {

Expand Down Expand Up @@ -91,11 +91,12 @@ public void handleMessage(Message message) {
|| MessageUtils.isTrue(message.getContextualProperty(TRANSFORM_SKIP))) {
return;
}

XMLStreamWriter writer = message.getContent(XMLStreamWriter.class);
OutputStream out = message.getContent(OutputStream.class);

XMLStreamWriter transformWriter = createTransformWriterIfNeeded(writer, out);

final String encoding = MessageUtils.getMessageEncoding(message);
XMLStreamWriter transformWriter = createTransformWriterIfNeeded(writer, out, encoding);
if (transformWriter != null) {
message.setContent(XMLStreamWriter.class, transformWriter);
if (MessageUtils.isRequestor(message)) {
Expand All @@ -108,8 +109,8 @@ public void handleMessage(Message message) {
}
}

protected XMLStreamWriter createTransformWriterIfNeeded(XMLStreamWriter writer, OutputStream os) {
return TransformUtils.createTransformWriterIfNeeded(writer, os,
protected XMLStreamWriter createTransformWriterIfNeeded(XMLStreamWriter writer, OutputStream os, String encoding) {
return TransformUtils.createTransformWriterIfNeeded(writer, os, encoding,
outElementsMap,
outDropElements,
outAppendMap,
Expand Down
12 changes: 12 additions & 0 deletions core/src/main/java/org/apache/cxf/message/MessageUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.apache.cxf.message;

import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;

import org.w3c.dom.Node;
Expand Down Expand Up @@ -188,4 +189,15 @@ public static boolean isDOMPresent(Message m) {
*/
}

/**
* Returns the effective encoding of the message (which defaults to UTF_8 if unspecified)
*/
public static String getMessageEncoding(Message m) {
String encoding = (String)m.getContextualProperty(Message.ENCODING);
if (encoding == null) {
encoding = StandardCharsets.UTF_8.name();
}
return encoding;
}

}
32 changes: 20 additions & 12 deletions core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,6 @@ private static boolean setProperty(XMLInputFactory f, String p, Object o) {
return false;
}



public static XMLStreamWriter createXMLStreamWriter(Writer out) {
XMLOutputFactory factory = getXMLOutputFactory();
Expand Down Expand Up @@ -581,7 +580,10 @@ public static boolean skipToStartOfElement(DepthXMLStreamReader in) throws XMLSt
return false;
}
public static void copy(Source source, OutputStream os) throws XMLStreamException {
XMLStreamWriter writer = createXMLStreamWriter(os);
copy(source, os, StandardCharsets.UTF_8.name());
}
public static void copy(Source source, OutputStream os, String encoding) throws XMLStreamException {
XMLStreamWriter writer = createXMLStreamWriter(os, encoding);
try {
copy(source, writer);
} finally {
Expand Down Expand Up @@ -678,7 +680,14 @@ public static void copy(XMLStreamReader reader, OutputStream os)
StaxUtils.copy(reader, xsw);
xsw.close();
}


public static void copy(XMLStreamReader reader, OutputStream os, String encoding)
throws XMLStreamException {
XMLStreamWriter xsw = StaxUtils.createXMLStreamWriter(os, encoding);
StaxUtils.copy(reader, xsw);
xsw.close();
}

public static void writeTo(Node node, OutputStream os) throws XMLStreamException {
copy(new DOMSource(node), os);
}
Expand Down Expand Up @@ -1135,8 +1144,12 @@ public static Document read(Source s) throws XMLStreamException {
}
}
}

public static Document read(InputStream s) throws XMLStreamException {
XMLStreamReader reader = createXMLStreamReader(s);
return read(s, StandardCharsets.UTF_8.name());
}
public static Document read(InputStream s, String charset) throws XMLStreamException {
XMLStreamReader reader = createXMLStreamReader(s, charset);
try {
return read(reader);
} finally {
Expand All @@ -1147,6 +1160,7 @@ public static Document read(InputStream s) throws XMLStreamException {
}
}
}

public static Document read(Reader s) throws XMLStreamException {
XMLStreamReader reader = createXMLStreamReader(s);
try {
Expand Down Expand Up @@ -1736,15 +1750,9 @@ public static XMLStreamReader createXMLStreamReader(InputStream in, String encod
* @param in
*/
public static XMLStreamReader createXMLStreamReader(InputStream in) {
XMLInputFactory factory = getXMLInputFactory();
try {
return factory.createXMLStreamReader(in);
} catch (XMLStreamException e) {
throw new RuntimeException("Couldn't parse stream.", e);
} finally {
returnXMLInputFactory(factory);
}
return createXMLStreamReader(in, StandardCharsets.UTF_8.name());
}

public static XMLStreamReader createXMLStreamReader(String systemId, InputStream in) {
XMLInputFactory factory = getXMLInputFactory();
try {
Expand Down
Loading