You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2010/01/09 15:25:04 UTC
svn commit: r897459 - in /camel/trunk:
camel-core/src/main/java/org/apache/camel/
camel-core/src/main/java/org/apache/camel/converter/
camel-core/src/main/java/org/apache/camel/model/dataformat/
camel-core/src/test/java/org/apache/camel/component/file/...
Author: ningjiang
Date: Sat Jan 9 14:25:03 2010
New Revision: 897459
URL: http://svn.apache.org/viewvc?rev=897459&view=rev
Log:
CAMEL-2330 applied the patch of Pavel with thanks
Added:
camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriter.java (with props)
camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java.orig
camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlCharFilterer.java (with props)
camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlFilterReader.java (with props)
camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriterTest.java (with props)
camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java (with props)
camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlCharFiltererTest.java (with props)
camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlFilterReaderTest.java (with props)
Removed:
camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbFilterReader.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java
camel/trunk/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/dataformat/JaxbDataFormat.java
camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FromFileMoveFileIfProcessFailsTest.java
camel/trunk/components/camel-cxf/pom.xml
camel/trunk/components/camel-jaxb/pom.xml
camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java
camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java
camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/jaxb/CamelJaxbTest.java
camel/trunk/components/camel-jaxb/src/test/resources/org/apache/camel/jaxb/CamelJaxbTest.xml
camel/trunk/parent/pom.xml
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java Sat Jan 9 14:25:03 2010
@@ -60,6 +60,8 @@
String ERRORHANDLER_HANDLED = "CamelErrorHandlerHandled";
String FAILURE_HANDLED = "CamelFailureHandled";
String FAILURE_ENDPOINT = "CamelFailureEndpoint";
+
+ String FILTER_NON_XML_CHARS = "CamelFilterNonXmlChars";
String FILE_LOCAL_WORK_PATH = "CamelFileLocalWorkPath";
String FILE_NAME = "CamelFileName";
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/converter/IOConverter.java Sat Jan 9 14:25:03 2010
@@ -327,7 +327,7 @@
return new ByteArrayInputStream(os.toByteArray());
}
- private static String getCharsetName(Exchange exchange) {
+ public static String getCharsetName(Exchange exchange) {
if (exchange != null) {
String charsetName = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
if (charsetName != null) {
@@ -337,7 +337,7 @@
return getDefaultCharsetName();
}
- private static String getDefaultCharsetName() {
+ public static String getDefaultCharsetName() {
return Charset.defaultCharset().toString();
}
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/dataformat/JaxbDataFormat.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/dataformat/JaxbDataFormat.java?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/dataformat/JaxbDataFormat.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/dataformat/JaxbDataFormat.java Sat Jan 9 14:25:03 2010
@@ -40,6 +40,8 @@
@XmlAttribute(required = false)
private Boolean ignoreJAXBElement;
@XmlAttribute(required = false)
+ private Boolean filterNonXmlChars;
+ @XmlAttribute(required = false)
private String encoding;
public JaxbDataFormat() {
@@ -75,6 +77,14 @@
this.ignoreJAXBElement = ignoreJAXBElement;
}
+ public Boolean getFilterNonXmlChars() {
+ return filterNonXmlChars;
+ }
+
+ public void setFilterNonXmlChars(Boolean filterNonXmlChars) {
+ this.filterNonXmlChars = filterNonXmlChars;
+ }
+
@Override
protected void configureDataFormat(DataFormat dataFormat) {
Boolean answer = ObjectHelper.toBoolean(getPrettyPrint());
@@ -89,6 +99,12 @@
} else { // the default value is true
setProperty(dataFormat, "ignoreJAXBElement", Boolean.TRUE);
}
+ answer = ObjectHelper.toBoolean(getFilterNonXmlChars());
+ if (answer != null && answer) {
+ setProperty(dataFormat, "filterNonXmlChars", Boolean.TRUE);
+ } else { // the default value is false
+ setProperty(dataFormat, "filterNonXmlChars", Boolean.FALSE);
+ }
if (encoding != null) {
setProperty(dataFormat, "encoding", encoding);
}
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FromFileMoveFileIfProcessFailsTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FromFileMoveFileIfProcessFailsTest.java?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FromFileMoveFileIfProcessFailsTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FromFileMoveFileIfProcessFailsTest.java Sat Jan 9 14:25:03 2010
@@ -47,11 +47,12 @@
return new RouteBuilder() {
public void configure() throws Exception {
from("file://target/movefile?moveFailed=error")
- .convertBodyTo(String.class).to("mock:foo").process(new Processor() {
- public void process(Exchange exchange) throws Exception {
- throw new IllegalArgumentException("Forced by unittest");
- }
- });
+ .convertBodyTo(String.class).to("mock:foo").process(
+ new Processor() {
+ public void process(Exchange exchange) throws Exception {
+ throw new IllegalArgumentException("Forced by unittest");
+ }
+ });
}
};
}
Modified: camel/trunk/components/camel-cxf/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/pom.xml?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/components/camel-cxf/pom.xml (original)
+++ camel/trunk/components/camel-cxf/pom.xml Sat Jan 9 14:25:03 2010
@@ -132,7 +132,7 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
-
+
<!-- Test Dependencies -->
<dependency>
<groupId>org.apache.camel</groupId>
Modified: camel/trunk/components/camel-jaxb/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/pom.xml?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/components/camel-jaxb/pom.xml (original)
+++ camel/trunk/components/camel-jaxb/pom.xml Sat Jan 9 14:25:03 2010
@@ -93,6 +93,16 @@
<artifactId>log4j</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>3.2.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
Modified: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java (original)
+++ camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java Sat Jan 9 14:25:03 2010
@@ -181,11 +181,11 @@
if (value instanceof InputStream) {
return unmarshaller.unmarshal((InputStream) value);
} else if (value instanceof Reader) {
- JaxbFilterReader filterReader;
- if (value instanceof JaxbFilterReader) {
- filterReader = (JaxbFilterReader) value;
+ NonXmlFilterReader filterReader;
+ if (value instanceof NonXmlFilterReader) {
+ filterReader = (NonXmlFilterReader) value;
} else {
- filterReader = new JaxbFilterReader((Reader)value);
+ filterReader = new NonXmlFilterReader((Reader)value);
}
return unmarshaller.unmarshal(filterReader);
} else if (value instanceof Source) {
Added: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriter.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriter.java?rev=897459&view=auto
==============================================================================
--- camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriter.java (added)
+++ camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriter.java Sat Jan 9 14:25:03 2010
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.jaxb;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ * {@link XMLStreamWriter} wrapper that filters out non-XML characters, see
+ * {@link NonXmlCharFilterer} for details. Filtering applies to
+ * <ul>
+ * <li>Characters</li>
+ * <li>CData</li>
+ * <li>Attributes</li>
+ * <li>Comments</li>
+ * </ul>
+ *
+ * @see XMLStreamWriter
+ */
+public class FilteringXmlStreamWriter implements XMLStreamWriter {
+ NonXmlCharFilterer nonXmlCharFilterer = new NonXmlCharFilterer();
+
+ private XMLStreamWriter writer;
+
+ /**
+ * @param writer
+ * target writer to wrap.
+ */
+ public FilteringXmlStreamWriter(XMLStreamWriter writer) {
+ this.writer = writer;
+ }
+
+ /**
+ * This method applies filtering before delegating call to {@link #writer}.
+ */
+ public void writeAttribute(String prefix, String namespaceURI, String localName, String value)
+ throws XMLStreamException {
+ String filteredValue = nonXmlCharFilterer.filter(value);
+ writer.writeAttribute(prefix, namespaceURI, localName, filteredValue);
+ }
+
+ /**
+ * This method applies filtering before delegating call to {@link #writer}.
+ */
+ public void writeAttribute(String namespaceURI, String localName, String value)
+ throws XMLStreamException {
+ String filteredValue = nonXmlCharFilterer.filter(value);
+ writer.writeAttribute(namespaceURI, localName, filteredValue);
+ }
+
+ /**
+ * This method applies filtering before delegating call to {@link #writer}.
+ */
+ public void writeAttribute(String localName, String value) throws XMLStreamException {
+ String filteredValue = nonXmlCharFilterer.filter(value);
+ writer.writeAttribute(localName, filteredValue);
+ }
+
+ /**
+ * This method applies filtering before delegating call to {@link #writer}.
+ */
+ public void writeCData(String data) throws XMLStreamException {
+ String filteredData = nonXmlCharFilterer.filter(data);
+ writer.writeCData(filteredData);
+ }
+
+ /**
+ * This method applies filtering before delegating call to {@link #writer}.
+ */
+ public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
+ nonXmlCharFilterer.filter(text, start, len);
+ writer.writeCharacters(text, start, len);
+ }
+
+ /**
+ * This method applies filtering before delegating call to {@link #writer}.
+ */
+ public void writeCharacters(String text) throws XMLStreamException {
+ String filteredText = nonXmlCharFilterer.filter(text);
+ writer.writeCharacters(filteredText);
+ }
+
+ /**
+ * This method applies filtering before delegating call to {@link #writer}.
+ */
+ public void writeComment(String data) throws XMLStreamException {
+ String filteredData = nonXmlCharFilterer.filter(data);
+ writer.writeComment(filteredData);
+ }
+
+ public void close() throws XMLStreamException {
+ writer.close();
+ }
+
+ public void flush() throws XMLStreamException {
+ writer.flush();
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return writer.getNamespaceContext();
+ }
+
+ public String getPrefix(String uri) throws XMLStreamException {
+ return writer.getPrefix(uri);
+ }
+
+ public Object getProperty(String name) throws IllegalArgumentException {
+ return writer.getProperty(name);
+ }
+
+ public void setDefaultNamespace(String uri) throws XMLStreamException {
+ writer.setDefaultNamespace(uri);
+ }
+
+ public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
+ writer.setNamespaceContext(context);
+ }
+
+ public void setPrefix(String prefix, String uri) throws XMLStreamException {
+ writer.setPrefix(prefix, uri);
+ }
+
+ public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
+ writer.writeDefaultNamespace(namespaceURI);
+ }
+
+ public void writeDTD(String dtd) throws XMLStreamException {
+ writer.writeDTD(dtd);
+ }
+
+ public void writeEmptyElement(String prefix, String localName, String namespaceURI)
+ throws XMLStreamException {
+ writer.writeEmptyElement(prefix, localName, namespaceURI);
+ }
+
+ public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
+ writer.writeEmptyElement(namespaceURI, localName);
+ }
+
+ public void writeEmptyElement(String localName) throws XMLStreamException {
+ writer.writeEmptyElement(localName);
+ }
+
+ public void writeEndDocument() throws XMLStreamException {
+ writer.writeEndDocument();
+ }
+
+ public void writeEndElement() throws XMLStreamException {
+ writer.writeEndElement();
+ }
+
+ public void writeEntityRef(String name) throws XMLStreamException {
+ writer.writeEntityRef(name);
+ }
+
+ public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
+ writer.writeNamespace(prefix, namespaceURI);
+ }
+
+ public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
+ writer.writeProcessingInstruction(target, data);
+ }
+
+ public void writeProcessingInstruction(String target) throws XMLStreamException {
+ writer.writeProcessingInstruction(target);
+ }
+
+ public void writeStartDocument() throws XMLStreamException {
+ writer.writeStartDocument();
+ }
+
+ public void writeStartDocument(String encoding, String version) throws XMLStreamException {
+ writer.writeStartDocument(encoding, version);
+ }
+
+ public void writeStartDocument(String version) throws XMLStreamException {
+ writer.writeStartDocument(version);
+ }
+
+ public void writeStartElement(String prefix, String localName, String namespaceURI)
+ throws XMLStreamException {
+ writer.writeStartElement(prefix, localName, namespaceURI);
+ }
+
+ public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
+ writer.writeStartElement(namespaceURI, localName);
+ }
+
+ public void writeStartElement(String localName) throws XMLStreamException {
+ writer.writeStartElement(localName);
+ }
+
+}
Propchange: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriter.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java (original)
+++ camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java Sat Jan 9 14:25:03 2010
@@ -18,13 +18,19 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
import org.apache.camel.Exchange;
+import org.apache.camel.converter.IOConverter;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.util.IOHelper;
@@ -35,10 +41,12 @@
* @version $Revision$
*/
public class JaxbDataFormat implements DataFormat {
+
private JAXBContext context;
private String contextPath;
private boolean prettyPrint = true;
private boolean ignoreJAXBElement = true;
+ private boolean filterNonXmlChars;
private String encoding;
public JaxbDataFormat() {
@@ -59,7 +67,7 @@
if (isPrettyPrint()) {
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
}
- // exchange take precedense over encoding option
+ // exchange take precedence over encoding option
String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
if (charset == null) {
charset = encoding;
@@ -68,17 +76,37 @@
marshaller.setProperty(Marshaller.JAXB_ENCODING, charset);
}
- marshaller.marshal(graph, stream);
+ marshal(exchange, graph, stream, marshaller);
} catch (JAXBException e) {
throw IOHelper.createIOException(e);
+ } catch (XMLStreamException e) {
+ throw IOHelper.createIOException(e);
}
}
+ void marshal(Exchange exchange, Object graph, OutputStream stream, Marshaller marshaller)
+ throws XMLStreamException, JAXBException {
+ if (needFiltering(exchange)) {
+ XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(stream);
+ FilteringXmlStreamWriter filteringWriter = new FilteringXmlStreamWriter(writer);
+ marshaller.marshal(graph, filteringWriter);
+ } else {
+ marshaller.marshal(graph, stream);
+ }
+ }
+
public Object unmarshal(Exchange exchange, InputStream stream) throws IOException, ClassNotFoundException {
try {
// must create a new instance of unmarshaller as its not thread safe
- Object answer = getContext().createUnmarshaller().unmarshal(stream);
+ Object answer;
+ Unmarshaller unmarshaller = getContext().createUnmarshaller();
+ if (needFiltering(exchange)) {
+ answer = unmarshaller.unmarshal(new NonXmlFilterReader(new InputStreamReader(stream)));
+ } else {
+ answer = unmarshaller.unmarshal(stream);
+ }
+
if (answer instanceof JAXBElement && isIgnoreJAXBElement()) {
answer = ((JAXBElement<?>)answer).getValue();
}
@@ -86,7 +114,12 @@
} catch (JAXBException e) {
throw IOHelper.createIOException(e);
}
- }
+ }
+
+ protected boolean needFiltering(Exchange exchange) {
+ // exchange property takes precedence over data format property
+ return exchange.getProperty(Exchange.FILTER_NON_XML_CHARS, filterNonXmlChars, Boolean.class);
+ }
// Properties
// -------------------------------------------------------------------------
@@ -125,6 +158,14 @@
this.prettyPrint = prettyPrint;
}
+ public boolean isFilterNonXmlChars() {
+ return filterNonXmlChars;
+ }
+
+ public void setFilterNonXmlChars(boolean filterNonXmlChars) {
+ this.filterNonXmlChars = filterNonXmlChars;
+ }
+
public String getEncoding() {
return encoding;
}
Added: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java.orig
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java.orig?rev=897459&view=auto
==============================================================================
--- camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java.orig (added)
+++ camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java.orig Sat Jan 9 14:25:03 2010
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.jaxb;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.util.IOHelper;
+
+/**
+ * A <a href="http://camel.apache.org/data-format.html">data format</a> ({@link DataFormat})
+ * using JAXB2 to marshal to and from XML
+ *
+ * @version $Revision: 834590 $
+ */
+public class JaxbDataFormat implements DataFormat {
+ private JAXBContext context;
+ private String contextPath;
+ private boolean prettyPrint = true;
+ private boolean ignoreJAXBElement = true;
+ private String encoding;
+
+ public JaxbDataFormat() {
+ }
+
+ public JaxbDataFormat(JAXBContext context) {
+ this.context = context;
+ }
+
+ public JaxbDataFormat(String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ public void marshal(Exchange exchange, Object graph, OutputStream stream) throws IOException {
+ try {
+ // must create a new instance of marshaller as its not thread safe
+ Marshaller marshaller = getContext().createMarshaller();
+ if (isPrettyPrint()) {
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ }
+ // exchange take precedense over encoding option
+ String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
+ if (charset == null) {
+ charset = encoding;
+ }
+ if (charset != null) {
+ marshaller.setProperty(Marshaller.JAXB_ENCODING, charset);
+ }
+
+ marshaller.marshal(graph, stream);
+
+ } catch (JAXBException e) {
+ throw IOHelper.createIOException(e);
+ }
+ }
+
+ public Object unmarshal(Exchange exchange, InputStream stream) throws IOException, ClassNotFoundException {
+ try {
+ // must create a new instance of unmarshaller as its not thread safe
+ Object answer = getContext().createUnmarshaller().unmarshal(stream);
+ if (answer instanceof JAXBElement && isIgnoreJAXBElement()) {
+ answer = ((JAXBElement<?>)answer).getValue();
+ }
+ return answer;
+ } catch (JAXBException e) {
+ throw IOHelper.createIOException(e);
+ }
+ }
+
+ // Properties
+ // -------------------------------------------------------------------------
+ public boolean isIgnoreJAXBElement() {
+ return ignoreJAXBElement;
+ }
+
+ public void setIgnoreJAXBElement(boolean flag) {
+ ignoreJAXBElement = flag;
+ }
+
+ public synchronized JAXBContext getContext() throws JAXBException {
+ if (context == null) {
+ context = createContext();
+ }
+ return context;
+ }
+
+ public void setContext(JAXBContext context) {
+ this.context = context;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public void setContextPath(String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ public boolean isPrettyPrint() {
+ return prettyPrint;
+ }
+
+ public void setPrettyPrint(boolean prettyPrint) {
+ this.prettyPrint = prettyPrint;
+ }
+
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ protected JAXBContext createContext() throws JAXBException {
+ if (contextPath != null) {
+ return JAXBContext.newInstance(contextPath);
+ } else {
+ return JAXBContext.newInstance();
+ }
+ }
+}
Added: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlCharFilterer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlCharFilterer.java?rev=897459&view=auto
==============================================================================
--- camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlCharFilterer.java (added)
+++ camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlCharFilterer.java Sat Jan 9 14:25:03 2010
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.jaxb;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Provides filtering of characters that do fall into <a
+ * href="http://www.w3.org/TR/2004/REC-xml-20040204/#NT-Char">range defined by
+ * XML 1.0 spec</a>. <i>Filtering</i> here means replacement with space char.
+ *
+ *
+ */
+class NonXmlCharFilterer {
+ private static final transient Log LOG = LogFactory.getLog(FilteringXmlStreamWriter.class);
+ private static final char REPLACEMENT_CHAR = ' ';
+
+ /**
+ * Determines whether specified character needs to be filtered.
+ */
+ boolean isFiltered(char c) {
+ // Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] |
+ // [#x10000-#x10FFFF]
+ // Won't be checking last interval, as it goes beyond 0xFFFF.
+ if (c == 0x9 || c == 0xA || c == 0xD || (c >= 0x20 && c <= 0xD7FF)
+ || (c >= 0xE000 && c <= 0xFFFD)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Filter specified char array by replacing non-XML chars with space. Only
+ * part of array specified by <code>offset</code> and <code>length</code> is
+ * affected.
+ *
+ * @return <code>true</code> if <code>content</code> was modified,
+ * <code>false</code> otherwise.
+ */
+ public boolean filter(char[] content, int offset, int length) {
+ if (content == null) {
+ return false;
+ }
+
+ boolean filtered = false;
+ for (int i = offset; i < offset + length; i++) {
+ if (isFiltered(content[i])) {
+ filtered = true;
+ content[i] = REPLACEMENT_CHAR;
+ }
+ }
+
+ if (filtered) {
+ LOG.warn("Identified and replaced non-XML chars");
+ }
+
+ return filtered;
+ }
+
+ /**
+ * Filter specified string by replacing illegal chars with space.
+ *
+ * @return filtered string
+ */
+ public String filter(String original) {
+ if (original == null) {
+ return null;
+ }
+
+ char[] chars = original.toCharArray();
+ if (!filter(chars, 0, chars.length)) {
+ return original;
+ }
+
+ String filtered = new String(chars);
+ LOG.warn("Illegal characters were filtered; original => \"" + original
+ + "\", filtered => \"" + filtered + "\"");
+ return filtered;
+ }
+
+}
Propchange: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlCharFilterer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlCharFilterer.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlFilterReader.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlFilterReader.java?rev=897459&view=auto
==============================================================================
--- camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlFilterReader.java (added)
+++ camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlFilterReader.java Sat Jan 9 14:25:03 2010
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.jaxb;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This FilterReader will filter out the non-XML characters, see
+ * {@link NonXmlCharFilterer} for details.
+ */
+public class NonXmlFilterReader extends FilterReader {
+ NonXmlCharFilterer nonXmlCharFilterer = new NonXmlCharFilterer();
+
+ protected NonXmlFilterReader(Reader in) {
+ super(in);
+ }
+
+ /**
+ * Reads characters into a portion of an array.
+ *
+ * @exception IOException
+ * If an I/O error occurs
+ */
+ public int read(char cbuf[], int off, int len) throws IOException {
+ int read = in.read(cbuf, off, len);
+ if (read > 0) {
+ nonXmlCharFilterer.filter(cbuf, off, read);
+ }
+ return read;
+ }
+
+}
Propchange: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlFilterReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/NonXmlFilterReader.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriterTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriterTest.java?rev=897459&view=auto
==============================================================================
--- camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriterTest.java (added)
+++ camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriterTest.java Sat Jan 9 14:25:03 2010
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.jaxb;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.easymock.classextension.EasyMockSupport;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.same;
+
+public class FilteringXmlStreamWriterTest extends EasyMockSupport {
+ private FilteringXmlStreamWriter filteringXmlStreamWriter;
+ private NonXmlCharFilterer nonXmlCharFiltererMock;
+ private XMLStreamWriter xmlStreamWriterMock;
+
+ // only testing non-generated methods, those that do apply filtering
+
+ @Before
+ public void setUp() {
+ xmlStreamWriterMock = createStrictMock(XMLStreamWriter.class);
+ nonXmlCharFiltererMock = createStrictMock(NonXmlCharFilterer.class);
+ filteringXmlStreamWriter = new FilteringXmlStreamWriter(xmlStreamWriterMock);
+ filteringXmlStreamWriter.nonXmlCharFilterer = nonXmlCharFiltererMock;
+ }
+
+ @Test
+ public void testWriteAttribute2Args() throws XMLStreamException {
+ expect(nonXmlCharFiltererMock.filter("value")).andReturn("filteredValue");
+ xmlStreamWriterMock.writeAttribute("localName", "filteredValue");
+ replayAll();
+
+ filteringXmlStreamWriter.writeAttribute("localName", "value");
+ verifyAll();
+ }
+
+ @Test
+ public void testWriteAttribute3Args() throws XMLStreamException {
+ expect(nonXmlCharFiltererMock.filter("value")).andReturn("filteredValue");
+ xmlStreamWriterMock.writeAttribute("namespaceURI", "localName", "filteredValue");
+ replayAll();
+
+ filteringXmlStreamWriter.writeAttribute("namespaceURI", "localName", "value");
+ verifyAll();
+ }
+
+ @Test
+ public void testWriteAttribute4Args() throws XMLStreamException {
+ expect(nonXmlCharFiltererMock.filter("value")).andReturn("filteredValue");
+ xmlStreamWriterMock.writeAttribute("prefix", "namespaceURI", "localName", "filteredValue");
+ replayAll();
+
+ filteringXmlStreamWriter.writeAttribute("prefix", "namespaceURI", "localName", "value");
+ verifyAll();
+ }
+
+ @Test
+ public void testWriteCData() throws XMLStreamException {
+ expect(nonXmlCharFiltererMock.filter("value")).andReturn("filteredValue");
+ xmlStreamWriterMock.writeCData("filteredValue");
+ replayAll();
+
+ filteringXmlStreamWriter.writeCData("value");
+ verifyAll();
+ }
+
+ @Test
+ public void testWriteCharacters1Arg() throws XMLStreamException {
+ expect(nonXmlCharFiltererMock.filter("value")).andReturn("filteredValue");
+ xmlStreamWriterMock.writeCharacters("filteredValue");
+ replayAll();
+
+ filteringXmlStreamWriter.writeCharacters("value");
+ verifyAll();
+ }
+
+ @Test
+ public void testWriteComment() throws XMLStreamException {
+ expect(nonXmlCharFiltererMock.filter("value")).andReturn("filteredValue");
+ xmlStreamWriterMock.writeComment("filteredValue");
+ replayAll();
+
+ filteringXmlStreamWriter.writeComment("value");
+ verifyAll();
+ }
+
+ @Test
+ public void testWriteCharacters3Args() throws XMLStreamException {
+ char[] buffer = new char[] {'a', 'b', 'c'};
+ expect(nonXmlCharFiltererMock.filter(same(buffer), eq(2), eq(3))).andReturn(true);
+ xmlStreamWriterMock.writeCharacters(same(buffer), eq(2), eq(3));
+ replayAll();
+
+ filteringXmlStreamWriter.writeCharacters(buffer, 2, 3);
+ verifyAll();
+ }
+
+}
Propchange: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriterTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/FilteringXmlStreamWriterTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java?rev=897459&view=auto
==============================================================================
--- camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java (added)
+++ camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java Sat Jan 9 14:25:03 2010
@@ -0,0 +1,120 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.jaxb;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.camel.Exchange;
+import org.easymock.classextension.EasyMockSupport;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.same;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class JaxbDataFormatTest extends EasyMockSupport {
+ private JaxbDataFormat jaxbDataFormat;
+ private Exchange exchangeMock;
+ private Marshaller marshallerMock;
+
+ @Before
+ public void setUp() {
+ jaxbDataFormat = new JaxbDataFormat();
+ marshallerMock = createStrictMock(Marshaller.class);
+ exchangeMock = createStrictMock(Exchange.class);
+ }
+
+ @Test
+ public void testNeedFiltering() {
+ // tests combinations of data format option and exchange property
+ expect(
+ exchangeMock.getProperty(Exchange.FILTER_NON_XML_CHARS, false,
+ Boolean.class)).andReturn(false);
+ replayAll();
+
+ assertFalse("Not expected filtering here", jaxbDataFormat.needFiltering(exchangeMock));
+ verifyAll();
+ resetAll();
+
+ expect(
+ exchangeMock.getProperty(Exchange.FILTER_NON_XML_CHARS, false,
+ Boolean.class)).andReturn(true);
+ replayAll();
+
+ assertTrue("Expected filtering here", jaxbDataFormat.needFiltering(exchangeMock));
+ verifyAll();
+ resetAll();
+
+ jaxbDataFormat.setFilterNonXmlChars(true);
+ expect(
+ exchangeMock.getProperty(Exchange.FILTER_NON_XML_CHARS, true,
+ Boolean.class)).andReturn(false);
+ replayAll();
+
+ assertFalse("Not expected filtering here", jaxbDataFormat.needFiltering(exchangeMock));
+ verifyAll();
+ resetAll();
+
+ expect(
+ exchangeMock.getProperty(Exchange.FILTER_NON_XML_CHARS, true,
+ Boolean.class)).andReturn(true);
+ replayAll();
+
+ assertTrue("Expected filtering here", jaxbDataFormat.needFiltering(exchangeMock));
+ verifyAll();
+ resetAll();
+ }
+
+ @Test
+ public void testMarshalFilteringDisabled() throws XMLStreamException, JAXBException {
+ JaxbDataFormat jaxbDataFormatMock = createMockBuilder(JaxbDataFormat.class)
+ .addMockedMethod("needFiltering").createStrictMock();
+ Object graph = new Object();
+ OutputStream stream = new ByteArrayOutputStream();
+
+ expect(jaxbDataFormatMock.needFiltering(exchangeMock)).andReturn(false);
+ marshallerMock.marshal(same(graph), same(stream));
+ replayAll();
+
+ jaxbDataFormatMock.marshal(exchangeMock, graph, stream, marshallerMock);
+ verifyAll();
+ }
+
+ @Test
+ public void testMarshalFilteringEnabled() throws XMLStreamException, JAXBException {
+ JaxbDataFormat jaxbDataFormatMock = createMockBuilder(JaxbDataFormat.class)
+ .addMockedMethod("needFiltering").createStrictMock();
+
+ Object graph = new Object();
+ OutputStream stream = new ByteArrayOutputStream();
+
+ expect(jaxbDataFormatMock.needFiltering(exchangeMock)).andReturn(true);
+ marshallerMock.marshal(same(graph), isA(FilteringXmlStreamWriter.class));
+ replayAll();
+
+ jaxbDataFormatMock.marshal(exchangeMock, graph, stream, marshallerMock);
+ verifyAll();
+ }
+}
Propchange: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlCharFiltererTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlCharFiltererTest.java?rev=897459&view=auto
==============================================================================
--- camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlCharFiltererTest.java (added)
+++ camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlCharFiltererTest.java Sat Jan 9 14:25:03 2010
@@ -0,0 +1,172 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.converter.jaxb;
+
+import org.easymock.Capture;
+import org.easymock.IAnswer;
+import org.easymock.classextension.EasyMockSupport;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.easymock.EasyMock.and;
+import static org.easymock.EasyMock.aryEq;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+public class NonXmlCharFiltererTest extends EasyMockSupport {
+ private NonXmlCharFilterer nonXmlCharFilterer;
+
+ @Before
+ public void setUp() {
+ nonXmlCharFilterer = new NonXmlCharFilterer();
+ }
+
+ @Test
+ public void testIsFilteredValidChars() {
+ // Per http://www.w3.org/TR/2004/REC-xml-20040204/#NT-Char
+ // Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] |
+ // [#x10000-#x10FFFF]
+ checkSingleValid(0x9);
+ checkSingleValid(0xA);
+ checkSingleValid(0xD);
+ checkRangeValid(0x20, 0xD7FF);
+ checkRangeValid(0xE000, 0xFFFD);
+ // not checking [0x10000, 0x10FFFF], as it goes beyond
+ // Character.MAX_VALUE
+ }
+
+ @Test
+ public void testIsFilteredInvalidChars() {
+ // Per http://www.w3.org/TR/2004/REC-xml-20040204/#NT-Char
+ // Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] |
+ // [#x10000-#x10FFFF]
+ checkRangeInvalid(0x0, 0x8);
+ checkRangeInvalid(0xB, 0xC);
+ checkRangeInvalid(0xE, 0x1F);
+ checkRangeInvalid(0xD800, 0xDFFF);
+ checkRangeInvalid(0xFFFE, 0xFFFF);
+ // no need to check beyond #x10FFFF as this is greater than
+ // Character.MAX_VALUE
+ }
+
+ @Test
+ public void testFilter1ArgNonFiltered() {
+ NonXmlCharFilterer nonXmlCharFiltererMock = createMockBuilder(NonXmlCharFilterer.class)
+ .addMockedMethod("filter", char[].class, int.class, int.class).createStrictMock();
+ String string = "abc";
+
+ expect(nonXmlCharFiltererMock.filter(aryEq(new char[] {'a', 'b', 'c'}), eq(0), eq(3)))
+ .andReturn(false);
+ replayAll();
+
+ String result = nonXmlCharFiltererMock.filter(string);
+ verifyAll();
+
+ assertSame("Should have returned the same string if nothing was filtered", string, result);
+ }
+
+ //@Test
+ //"This test can't be build with JDK 1.5"
+ /*
+ public void testFilter1ArgFiltered() {
+ NonXmlCharFilterer nonXmlCharFiltererMock = createMockBuilder(NonXmlCharFilterer.class)
+ .addMockedMethod("filter", char[].class, int.class, int.class).createStrictMock();
+ final Capture<char[]> bufferCapture = new Capture<char[]>();
+
+ expect(
+ nonXmlCharFiltererMock.filter(and(capture(bufferCapture), aryEq(new char[] {'a', 'b', 'c'})),
+ eq(0), eq(3))).andAnswer(new IAnswer<Boolean>() {
+ public Boolean answer() throws Throwable {
+ char[] buffer = bufferCapture.getValue();
+ buffer[0] = 'i';
+ buffer[1] = 'o';
+ return true;
+ }
+ });
+ replayAll();
+
+ String result = nonXmlCharFiltererMock.filter("abc");
+ verifyAll();
+
+ assertEquals("Should have returned filtered string", "ioc", result);
+ }*/
+
+ @Test
+ public void testFilter1ArgNullArg() {
+ NonXmlCharFilterer nonXmlCharFiltererMock = createStrictMock(NonXmlCharFilterer.class);
+ nonXmlCharFiltererMock.filter(null);
+ }
+
+ @Test
+ public void testFilter3Args() {
+ NonXmlCharFilterer nonXmlCharFiltererMock = createMockBuilder(NonXmlCharFilterer.class)
+ .addMockedMethod("isFiltered").createStrictMock();
+ char[] buffer = new char[] {'1', '2', '3', '4', '5', '6'};
+
+ expect(nonXmlCharFiltererMock.isFiltered('3')).andReturn(true);
+ expect(nonXmlCharFiltererMock.isFiltered('4')).andReturn(false);
+ expect(nonXmlCharFiltererMock.isFiltered('5')).andReturn(true);
+ replayAll();
+
+ nonXmlCharFiltererMock.filter(buffer, 2, 3);
+ verifyAll();
+
+ assertArrayEquals("Unexpected buffer contents",
+ new char[] {'1', '2', ' ', '4', ' ', '6'}, buffer);
+ }
+
+ @Test
+ public void testFilter3ArgsNullArg() {
+ NonXmlCharFilterer nonXmlCharFiltererMock = createStrictMock(NonXmlCharFilterer.class);
+ nonXmlCharFiltererMock.filter(null, 2, 3);
+ }
+
+ private void checkSingleValid(int charCode) {
+ checkRangeValid(charCode, charCode);
+ }
+
+ private void checkRangeValid(int startCharCodeInclusive, int endCharCodeInclusive) {
+ for (int charCode = startCharCodeInclusive; charCode <= endCharCodeInclusive; charCode++) {
+ if (nonXmlCharFilterer.isFiltered((char) charCode)) {
+ fail("Character " + asHex(charCode) + " from range ["
+ + asHex(startCharCodeInclusive) + "-" + asHex(endCharCodeInclusive)
+ + "] should be valid, but it is not");
+ }
+
+ }
+ }
+
+ private void checkRangeInvalid(int startCharCodeInclusive, int endCharCodeInclusive) {
+ for (int charCode = startCharCodeInclusive; charCode <= endCharCodeInclusive; charCode++) {
+ if (!nonXmlCharFilterer.isFiltered((char) charCode)) {
+ fail("Character " + asHex(charCode) + " from range ["
+ + asHex(startCharCodeInclusive) + "-" + asHex(endCharCodeInclusive)
+ + "] should not be valid, but it is");
+ }
+ }
+ }
+
+ private String asHex(int charCode) {
+ return "#x" + Integer.toHexString(charCode);
+ }
+}
Propchange: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlCharFiltererTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlCharFiltererTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlFilterReaderTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlFilterReaderTest.java?rev=897459&view=auto
==============================================================================
--- camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlFilterReaderTest.java (added)
+++ camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlFilterReaderTest.java Sat Jan 9 14:25:03 2010
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.jaxb;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.easymock.classextension.EasyMockSupport;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.easymock.EasyMock.anyInt;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.notNull;
+import static org.easymock.EasyMock.same;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+public class NonXmlFilterReaderTest extends EasyMockSupport {
+ private NonXmlFilterReader nonXmlFilterReader;
+ private NonXmlCharFilterer nonXmlCharFiltererMock;
+ private Reader readerMock;
+
+ @Before
+ public void setUp() {
+ readerMock = createStrictMock(Reader.class);
+ nonXmlCharFiltererMock = createStrictMock(NonXmlCharFilterer.class);
+ nonXmlFilterReader = new NonXmlFilterReader(readerMock);
+ nonXmlFilterReader.nonXmlCharFilterer = nonXmlCharFiltererMock;
+ }
+
+ @Test
+ public void testRead() throws IOException {
+ char[] buffer = new char[10];
+
+ expect(readerMock.read(same(buffer), eq(3), eq(5))).andDelegateTo(
+ new ConstantReader(new char[] {'a', 'b', 'c'}));
+ expect(nonXmlCharFiltererMock.filter(same(buffer), eq(3), eq(3))).andReturn(false);
+
+ replayAll();
+ int result = nonXmlFilterReader.read(buffer, 3, 5);
+ verifyAll();
+
+ assertEquals("Unexpected number of chars read", 3, result);
+ assertArrayEquals("Wrong buffer contents", new char[] {0, 0, 0, 'a', 'b', 'c', 0, 0, 0, 0},
+ buffer);
+ }
+
+ @Test
+ public void testReadEOS() throws IOException {
+ char[] buffer = new char[10];
+
+ expect(readerMock.read((char[]) notNull(), anyInt(), anyInt())).andReturn(-1);
+
+ replayAll();
+ int result = nonXmlFilterReader.read(buffer, 3, 5);
+ verifyAll();
+
+ assertEquals("Unexpected number of chars read", -1, result);
+ assertArrayEquals("Buffer should not have been affected",
+ new char[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, buffer);
+
+ }
+
+ static class ConstantReader extends Reader {
+ private char[] constant;
+
+ public ConstantReader(char[] constant) {
+ this.constant = constant;
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ int length = Math.min(len, constant.length);
+ System.arraycopy(constant, 0, cbuf, off, length);
+ return length;
+ }
+
+ }
+}
Propchange: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlFilterReaderTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/NonXmlFilterReaderTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/jaxb/CamelJaxbTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/jaxb/CamelJaxbTest.java?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/jaxb/CamelJaxbTest.java (original)
+++ camel/trunk/components/camel-jaxb/src/test/java/org/apache/camel/jaxb/CamelJaxbTest.java Sat Jan 9 14:25:03 2010
@@ -21,7 +21,7 @@
import javax.xml.bind.JAXBElement;
-
+import org.apache.camel.CamelExecutionException;
import org.apache.camel.Exchange;
import org.apache.camel.TypeConverter;
import org.apache.camel.builder.RouteBuilder;
@@ -46,7 +46,7 @@
}
@Test
- public void testFilteringUnmarshal() throws Exception {
+ public void testFilteringConvertorUnmarshal() throws Exception {
final byte[] buffers = "<Person><firstName>FOO</firstName><lastName>BAR\u0008</lastName></Person>".getBytes("UTF-8");
InputStream is = new ByteArrayInputStream(buffers);
Exchange exchange = new DefaultExchange(context);
@@ -55,7 +55,58 @@
PersonType person = converter.convertTo(PersonType.class, exchange, is);
assertNotNull("Person should not be null ", person);
assertEquals("Get the wrong first name ", person.getFirstName(), "FOO");
- assertEquals("Get the wrong second name ", person.getLastName(), "BAR");
+ assertEquals("Get the wrong second name ", person.getLastName(), "BAR ");
+ }
+
+ @Test
+ public void testUnmarshalBadCharsWithFiltering() throws Exception {
+ String xml = "<Person><firstName>FOO</firstName><lastName>BAR\u0008</lastName></Person>";
+
+ PersonType expected = new PersonType();
+ expected.setFirstName("FOO");
+ expected.setLastName("BAR ");
+ MockEndpoint resultEndpoint = resolveMandatoryEndpoint("mock:result", MockEndpoint.class);
+ resultEndpoint.expectedBodiesReceived(expected);
+
+ template.sendBody("direct:unmarshalFilteringEnabled", xml);
+ resultEndpoint.assertIsSatisfied();
+ }
+
+ @Test(expected = CamelExecutionException.class)
+ public void testUnmarshalBadCharsNoFiltering() throws Exception {
+ String xml = "<Person><firstName>FOO</firstName><lastName>BAR\u0008</lastName></Person>";
+ template.sendBody("direct:getJAXBElementValue", xml);
+ }
+
+ @Test
+ public void testMarshalBadCharsWithFiltering() throws Exception {
+ PersonType person = new PersonType();
+ person.setFirstName("foo\u0004");
+ person.setLastName("bar");
+
+ MockEndpoint resultEndpoint = resolveMandatoryEndpoint("mock:result", MockEndpoint.class);
+ resultEndpoint.expectedMessageCount(1);
+ template.sendBody("direct:marshalFilteringEnabled", person);
+ resultEndpoint.assertIsSatisfied();
+
+ String body = resultEndpoint.getReceivedExchanges().get(0).getIn().getBody(String.class);
+ assertFalse("Non-xml character wasn't replaced", body.contains("\u0004"));
+ }
+
+ @Test
+ public void testMarshalBadCharsNoFiltering() throws Exception {
+ PersonType person = new PersonType();
+ person.setFirstName("foo\u0004");
+ person.setLastName("bar");
+
+ MockEndpoint resultEndpoint = resolveMandatoryEndpoint("mock:result", MockEndpoint.class);
+ resultEndpoint.expectedMessageCount(1);
+ template.sendBody("direct:marshal", person);
+ resultEndpoint.assertIsSatisfied();
+
+ String body = resultEndpoint.getReceivedExchanges().get(0).getIn().getBody(String.class);
+ assertTrue("Non-xml character unexpectedly did not get into marshalled contents", body
+ .contains("\u0004"));
}
@Test
@@ -84,13 +135,30 @@
public void configure() throws Exception {
JaxbDataFormat dataFormat = new JaxbDataFormat("org.apache.camel.foo.bar");
dataFormat.setIgnoreJAXBElement(false);
+
+ JaxbDataFormat filterEnabledFormat = new JaxbDataFormat("org.apache.camel.foo.bar");
+ filterEnabledFormat.setFilterNonXmlChars(true);
+
from("direct:getJAXBElementValue")
.unmarshal(new JaxbDataFormat("org.apache.camel.foo.bar"))
.to("mock:result");
from("direct:getJAXBElement")
.unmarshal(dataFormat)
- .to("mock:result");
+ .to("mock:result");
+
+ from("direct:unmarshalFilteringEnabled")
+ .unmarshal(filterEnabledFormat)
+ .to("mock:result");
+
+ from("direct:marshal")
+ .marshal(dataFormat)
+ .to("mock:result");
+
+ from("direct:marshalFilteringEnabled")
+ .marshal(filterEnabledFormat)
+ .to("mock:result");
+
}
};
}
Modified: camel/trunk/components/camel-jaxb/src/test/resources/org/apache/camel/jaxb/CamelJaxbTest.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jaxb/src/test/resources/org/apache/camel/jaxb/CamelJaxbTest.xml?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/components/camel-jaxb/src/test/resources/org/apache/camel/jaxb/CamelJaxbTest.xml (original)
+++ camel/trunk/components/camel-jaxb/src/test/resources/org/apache/camel/jaxb/CamelJaxbTest.xml Sat Jan 9 14:25:03 2010
@@ -39,6 +39,27 @@
</unmarshal>
<to uri="mock:result"/>
</route>
+ <route>
+ <from uri="direct:marshal"/>
+ <marshal>
+ <jaxb contextPath="org.apache.camel.foo.bar"/>
+ </marshal>
+ <to uri="mock:result"/>
+ </route>
+ <route>
+ <from uri="direct:unmarshalFilteringEnabled"/>
+ <unmarshal>
+ <jaxb filterNonXmlChars="true" contextPath="org.apache.camel.foo.bar"/>
+ </unmarshal>
+ <to uri="mock:result"/>
+ </route>
+ <route>
+ <from uri="direct:marshalFilteringEnabled"/>
+ <marshal>
+ <jaxb filterNonXmlChars="true" contextPath="org.apache.camel.foo.bar"/>
+ </marshal>
+ <to uri="mock:result"/>
+ </route>
</camelContext>
<!-- END SNIPPET: example -->
Modified: camel/trunk/parent/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/parent/pom.xml?rev=897459&r1=897458&r2=897459&view=diff
==============================================================================
--- camel/trunk/parent/pom.xml (original)
+++ camel/trunk/parent/pom.xml Sat Jan 9 14:25:03 2010
@@ -73,7 +73,7 @@
<commons-pool-version>1.4</commons-pool-version>
<commons-dbcp-version>1.2.2</commons-dbcp-version>
<derby-version>10.4.2.0</derby-version>
- <easymock-version>2.4</easymock-version>
+ <easymock-version>2.5.2</easymock-version>
<flatpack-version>3.1.1</flatpack-version>
<freemarker-version>2.3.15</freemarker-version>
<hamcrest-version>1.2-dev1</hamcrest-version>