You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cm...@apache.org on 2012/04/11 22:15:18 UTC
svn commit: r1324979 - in
/camel/branches/camel-2.9.x/components/camel-jaxb/src:
main/java/org/apache/camel/converter/jaxb/
test/java/org/apache/camel/converter/jaxb/
test/java/org/apache/camel/example/
Author: cmueller
Date: Wed Apr 11 20:15:17 2012
New Revision: 1324979
URL: http://svn.apache.org/viewvc?rev=1324979&view=rev
Log:
[CAMEL-3776] Change from pooling to using XMLStreamReaders for
everything which removes all the locks and much of the casting.
NOTE: right now, this REQUIRES woodstox as the StAX parser as the in-jdk
version is not thread safe in how StaxConverter uses it right now.
Modified:
camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java
camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java
camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java
camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java
Modified: camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java?rev=1324979&r1=1324978&r2=1324979&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java (original)
+++ camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java Wed Apr 11 20:15:17 2012
@@ -26,7 +26,6 @@ import java.io.UnsupportedEncodingExcept
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
@@ -34,7 +33,6 @@ import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.stream.FactoryConfigurationError;
-import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
@@ -46,6 +44,7 @@ import org.apache.camel.Processor;
import org.apache.camel.StreamCache;
import org.apache.camel.TypeConverter;
import org.apache.camel.component.bean.BeanInvocation;
+import org.apache.camel.converter.jaxp.StaxConverter;
import org.apache.camel.spi.TypeConverterAware;
import org.apache.camel.util.IOHelper;
import org.slf4j.Logger;
@@ -57,13 +56,10 @@ import org.slf4j.LoggerFactory;
public class FallbackTypeConverter implements TypeConverter, TypeConverterAware {
private static final transient Logger LOG = LoggerFactory.getLogger(FallbackTypeConverter.class);
private Map<Class<?>, JAXBContext> contexts = new HashMap<Class<?>, JAXBContext>();
- private Map<Class<?>, Unmarshaller> unmarshallers = new HashMap<Class<?>, Unmarshaller>();
- private XMLOutputFactory outputFactory;
private TypeConverter parentTypeConverter;
+ private StaxConverter staxConverter = new StaxConverter();
private boolean prettyPrint = true;
- private ReentrantLock unmarshallerLock = new ReentrantLock();
-
public boolean isPrettyPrint() {
return prettyPrint;
}
@@ -193,7 +189,7 @@ public class FallbackTypeConverter imple
marshaller.setProperty(Marshaller.JAXB_ENCODING, exchange.getProperty(Exchange.CHARSET_NAME, String.class));
}
if (needFiltering(exchange)) {
- XMLStreamWriter writer = getOutputFactory().createXMLStreamWriter(buffer);
+ XMLStreamWriter writer = exchange.getContext().getTypeConverter().convertTo(XMLStreamWriter.class, buffer);
FilteringXmlStreamWriter filteringWriter = new FilteringXmlStreamWriter(writer);
marshaller.marshal(value, filteringWriter);
} else {
@@ -206,16 +202,16 @@ public class FallbackTypeConverter imple
}
protected Object unmarshal(Unmarshaller unmarshaller, Exchange exchange, Object value) throws JAXBException, UnsupportedEncodingException, XMLStreamException {
- unmarshallerLock.lock();
try {
+ XMLStreamReader xmlReader = null;
if (value instanceof XMLStreamReader) {
- XMLStreamReader xmlReader = (XMLStreamReader) value;
- return unmarshaller.unmarshal(xmlReader);
+ xmlReader = (XMLStreamReader) value;
} else if (value instanceof InputStream) {
if (needFiltering(exchange)) {
- return unmarshaller.unmarshal(new NonXmlFilterReader(new InputStreamReader((InputStream)value, IOHelper.getCharsetName(exchange))));
+ xmlReader = staxConverter.createXMLStreamReader(new NonXmlFilterReader(new InputStreamReader((InputStream)value, IOHelper.getCharsetName(exchange))));
+ } else {
+ xmlReader = staxConverter.createXMLStreamReader((InputStream)value, exchange);
}
- return unmarshaller.unmarshal((InputStream)value);
} else if (value instanceof Reader) {
Reader reader = (Reader)value;
if (needFiltering(exchange)) {
@@ -223,17 +219,18 @@ public class FallbackTypeConverter imple
reader = new NonXmlFilterReader((Reader)value);
}
}
- return unmarshaller.unmarshal(reader);
+ xmlReader = staxConverter.createXMLStreamReader(reader);
} else if (value instanceof Source) {
- return unmarshaller.unmarshal((Source)value);
+ xmlReader = staxConverter.createXMLStreamReader((Source)value);
+ } else {
+ throw new IllegalArgumentException("Cannot convert from " + value.getClass());
}
+ return unmarshaller.unmarshal(xmlReader);
} finally {
- unmarshallerLock.unlock();
if (value instanceof Closeable) {
IOHelper.close((Closeable)value, "Unmarshalling", LOG);
}
}
- return null;
}
protected boolean needFiltering(Exchange exchange) {
@@ -251,19 +248,8 @@ public class FallbackTypeConverter imple
}
protected synchronized <T> Unmarshaller getOrCreateUnmarshaller(Class<T> type) throws JAXBException {
- Unmarshaller unmarshaller = unmarshallers.get(type);
- if (unmarshaller == null) {
- JAXBContext context = createContext(type);
- unmarshaller = context.createUnmarshaller();
- unmarshallers.put(type, unmarshaller);
- }
- return unmarshaller;
+ JAXBContext context = createContext(type);
+ return context.createUnmarshaller();
}
- public XMLOutputFactory getOutputFactory() {
- if (outputFactory == null) {
- outputFactory = XMLOutputFactory.newInstance();
- }
- return outputFactory;
- }
}
Modified: camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java?rev=1324979&r1=1324978&r2=1324979&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java (original)
+++ camel/branches/camel-2.9.x/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java Wed Apr 11 20:15:17 2012
@@ -21,7 +21,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
-import java.util.concurrent.locks.ReentrantLock;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
@@ -29,12 +28,9 @@ import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
-import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
@@ -70,8 +66,6 @@ public class JaxbDataFormat extends Serv
private Class partialClass;
private TypeConverter typeConverter;
- private Unmarshaller unmarshaller;
- private ReentrantLock lock = new ReentrantLock();
public JaxbDataFormat() {
}
@@ -130,7 +124,7 @@ public class JaxbDataFormat extends Serv
private FilteringXmlStreamWriter createFilteringWriter(OutputStream stream)
throws XMLStreamException, FactoryConfigurationError {
- XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(stream);
+ XMLStreamWriter writer = typeConverter.convertTo(XMLStreamWriter.class, stream);
FilteringXmlStreamWriter filteringWriter = new FilteringXmlStreamWriter(writer);
return filteringWriter;
}
@@ -140,29 +134,17 @@ public class JaxbDataFormat extends Serv
try {
Object answer;
- lock.lock();
- try {
- if (partialClass != null) {
- // partial unmarshalling
- if (needFiltering(exchange)) {
- Source source = new StreamSource(createNonXmlFilterReader(exchange, stream));
- answer = getUnmarshaller().unmarshal(source, partialClass);
- } else {
- XMLStreamReader xmlReader = typeConverter.convertTo(XMLStreamReader.class, stream);
- answer = getUnmarshaller().unmarshal(xmlReader, partialClass);
- }
-
- } else {
- if (needFiltering(exchange)) {
- NonXmlFilterReader reader = createNonXmlFilterReader(exchange, stream);
- answer = getUnmarshaller().unmarshal(reader);
- } else {
- XMLStreamReader xmlReader = typeConverter.convertTo(XMLStreamReader.class, stream);
- answer = getUnmarshaller().unmarshal(xmlReader);
- }
- }
- } finally {
- lock.unlock();
+ XMLStreamReader xmlReader;
+ if (needFiltering(exchange)) {
+ xmlReader = typeConverter.convertTo(XMLStreamReader.class, createNonXmlFilterReader(exchange, stream));
+ } else {
+ xmlReader = typeConverter.convertTo(XMLStreamReader.class, stream);
+ }
+ if (partialClass != null) {
+ // partial unmarshalling
+ answer = createUnmarshaller().unmarshal(xmlReader, partialClass);
+ } else {
+ answer = createUnmarshaller().unmarshal(xmlReader);
}
if (answer instanceof JAXBElement && isIgnoreJAXBElement()) {
@@ -265,10 +247,6 @@ public class JaxbDataFormat extends Serv
this.camelContext = camelContext;
}
- public Unmarshaller getUnmarshaller() {
- return unmarshaller;
- }
-
@Override
protected void doStart() throws Exception {
ObjectHelper.notNull(camelContext, "CamelContext");
@@ -280,7 +258,6 @@ public class JaxbDataFormat extends Serv
if (partClass != null) {
partialClass = camelContext.getClassResolver().resolveMandatoryClass(partClass);
}
- unmarshaller = getContext().createUnmarshaller();
typeConverter = camelContext.getTypeConverter();
}
@@ -308,5 +285,9 @@ public class JaxbDataFormat extends Serv
return JAXBContext.newInstance();
}
}
+
+ protected Unmarshaller createUnmarshaller() throws JAXBException {
+ return getContext().createUnmarshaller();
+ }
}
Modified: camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java?rev=1324979&r1=1324978&r2=1324979&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java (original)
+++ camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/converter/jaxb/JaxbDataFormatTest.java Wed Apr 11 20:15:17 2012
@@ -19,10 +19,8 @@ package org.apache.camel.converter.jaxb;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
-import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
@@ -35,18 +33,11 @@ import org.apache.camel.impl.DefaultCame
import org.apache.camel.impl.DefaultExchange;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.isA;
import static org.mockito.Matchers.same;
@@ -133,8 +124,9 @@ public class JaxbDataFormatTest {
jaxbDataFormat.setFilterNonXmlChars(false);
jaxbDataFormatMock = spy(jaxbDataFormat);
+
unmarshallerMock = mock(Unmarshaller.class);
- doReturn(unmarshallerMock).when(jaxbDataFormatMock).getUnmarshaller();
+ doReturn(unmarshallerMock).when(jaxbDataFormatMock).createUnmarshaller();
jaxbDataFormatMock.unmarshal(new DefaultExchange(camelContext), new ByteArrayInputStream(new byte[] {}));
@@ -144,14 +136,14 @@ public class JaxbDataFormatTest {
@Test
public void testUnmarshalFilteringEnabled() throws IOException, JAXBException {
jaxbDataFormat.setFilterNonXmlChars(true);
-
jaxbDataFormatMock = spy(jaxbDataFormat);
+
unmarshallerMock = mock(Unmarshaller.class);
- doReturn(unmarshallerMock).when(jaxbDataFormatMock).getUnmarshaller();
+ doReturn(unmarshallerMock).when(jaxbDataFormatMock).createUnmarshaller();
jaxbDataFormatMock.unmarshal(new DefaultExchange(camelContext), new ByteArrayInputStream(new byte[] {}));
- verify(unmarshallerMock).unmarshal(any(NonXmlFilterReader.class));
+ verify(unmarshallerMock).unmarshal((XMLStreamReader) argThat(instanceOf(XMLStreamReader.class)));
}
}
Modified: camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java?rev=1324979&r1=1324978&r2=1324979&view=diff
==============================================================================
--- camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java (original)
+++ camel/branches/camel-2.9.x/components/camel-jaxb/src/test/java/org/apache/camel/example/DataFormatConcurrentTest.java Wed Apr 11 20:15:17 2012
@@ -16,11 +16,15 @@
*/
package org.apache.camel.example;
+import java.io.StringWriter;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.converter.jaxb.JaxbDataFormat;
@@ -34,11 +38,29 @@ import org.junit.Test;
public class DataFormatConcurrentTest extends CamelTestSupport {
private int size = 2000;
+
+ private int fooBarSize = 50;
+
+ public String createPayload() throws Exception {
+ Foo foo = new Foo();
+ for (int x = 0; x < fooBarSize; x++) {
+ Bar bar = new Bar();
+ bar.setName("Name: " + x);
+ bar.setValue("value: " + x);
+ foo.getBarRefs().add(bar);
+ }
+ Marshaller m = JAXBContext.newInstance(Foo.class, Bar.class).createMarshaller();
+ StringWriter writer = new StringWriter();
+ m.marshal(foo, writer);
+ return writer.toString();
+ }
@Test
public void testUnmarshallConcurrent() throws Exception {
int counter = 10000;
- final String payload = "<purchaseOrder name='Wine' amount='123.45' price='2.22'/>";
+ //final String payload = "<purchaseOrder name='Wine' amount='123.45' price='2.22'/>";
+ final String payload = createPayload();
+ //System.out.println("Length: " + payload.length());
final CountDownLatch latch = new CountDownLatch(counter);
template.setDefaultEndpointUri("direct:unmarshal");
@@ -54,7 +76,7 @@ public class DataFormatConcurrentTest ex
}
// should finish on fast machines in less than 3 seconds
- assertTrue(latch.await(10, TimeUnit.SECONDS));
+ assertTrue(latch.await(15, TimeUnit.SECONDS));
//long end = System.currentTimeMillis();
//System.out.println("took " + (end - start) + "ms");
}