Hi Babak It should be okay for the unmarshal processor to return null, which means the body should be set to null as a result. You have introduced a not null check, which now will cause problems.
Also this check will always pass as getBody will lazy create an empty body as its stated in its javadoc. You should use hasBody() to check for that instead > ObjectHelper.notNull(message.getBody(), "body", message); Some tests that fails due this are https://builds.apache.org/job/Camel.trunk.fulltest/728/ On Sun, Mar 4, 2012 at 1:39 PM, <bvah...@apache.org> wrote: > Author: bvahdat > Date: Sun Mar 4 12:39:03 2012 > New Revision: 1296787 > > URL: http://svn.apache.org/viewvc?rev=1296787&view=rev > Log: > CAMEL-4797: DataFormat.unmarshal() should allow to return Message or Exchange > to make it more flexible. > > Added: > > camel/trunk/camel-core/src/test/java/org/apache/camel/processor/UnmarshalProcessorTest.java > (with props) > Modified: > > camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java > camel/trunk/camel-core/src/main/java/org/apache/camel/spi/DataFormat.java > > Modified: > camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java > URL: > http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java?rev=1296787&r1=1296786&r2=1296787&view=diff > ============================================================================== > --- > camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java > (original) > +++ > camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java > Sun Mar 4 12:39:03 2012 > @@ -23,6 +23,7 @@ import org.apache.camel.CamelContextAwar > import org.apache.camel.Exchange; > import org.apache.camel.Message; > import org.apache.camel.Processor; > +import org.apache.camel.RuntimeCamelException; > import org.apache.camel.Traceable; > import org.apache.camel.spi.DataFormat; > import org.apache.camel.support.ServiceSupport; > @@ -50,13 +51,28 @@ public class UnmarshalProcessor extends > > InputStream stream = ExchangeHelper.getMandatoryInBody(exchange, > InputStream.class); > try { > - // lets setup the out message before we invoke the dataFormat > - // so that it can mutate it if necessary > + // lets setup the out message before we invoke the dataFormat so > that it can mutate it if necessary > Message out = exchange.getOut(); > out.copyFrom(exchange.getIn()); > > Object result = dataFormat.unmarshal(exchange, stream); > - out.setBody(result); > + if (result instanceof Exchange) { > + if (result != exchange) { > + // it's not allowed to return another exchange other > than the one provided to dataFormat > + throw new RuntimeCamelException("The returned exchange " > + result + " is not the same as " + exchange + " provided to the DataFormat"); > + } > + } else if (result instanceof Message) { > + Message message = (Message) result; > + > + // message body should be already set properly by the > dataFormat > + ObjectHelper.notNull(message.getBody(), "body", message); > + > + // the dataformat has probably set headers, attachments, > etc. so let's use it as the outbound payload > + exchange.setOut((Message) result); > + } else { > + ObjectHelper.notNull(result, "result"); > + out.setBody(result); > + } > } catch (Exception e) { > // remove OUT message, as an exception occurred > exchange.setOut(null); > > Modified: > camel/trunk/camel-core/src/main/java/org/apache/camel/spi/DataFormat.java > URL: > http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/DataFormat.java?rev=1296787&r1=1296786&r2=1296787&view=diff > ============================================================================== > --- camel/trunk/camel-core/src/main/java/org/apache/camel/spi/DataFormat.java > (original) > +++ camel/trunk/camel-core/src/main/java/org/apache/camel/spi/DataFormat.java > Sun Mar 4 12:39:03 2012 > @@ -20,6 +20,7 @@ import java.io.InputStream; > import java.io.OutputStream; > > import org.apache.camel.Exchange; > +import org.apache.camel.Message; > > /** > * Represents a > @@ -48,11 +49,14 @@ public interface DataFormat { > * <b>Notice:</b> The result is set as body on the exchange OUT message. > * It is possible to mutate the OUT message provided in the given > exchange parameter. > * For instance adding headers to the OUT message will be preserved. > + * <p/> > + * It's also legal to return the <b>same</b> passed <tt>exchange</tt> as > is but also a > + * {@link Message} object as well which will be used as the OUT message > of <tt>exchange</tt>. > * > * @param exchange the current exchange > * @param stream the input stream with the object to be unmarshalled > * @return the unmarshalled object > - * @throws Exception can be thrown > + * @throws Exception can be thrown, for example when the body of the OUT > message becomes <tt>null</tt> > */ > Object unmarshal(Exchange exchange, InputStream stream) throws Exception; > } > > Added: > camel/trunk/camel-core/src/test/java/org/apache/camel/processor/UnmarshalProcessorTest.java > URL: > http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/UnmarshalProcessorTest.java?rev=1296787&view=auto > ============================================================================== > --- > camel/trunk/camel-core/src/test/java/org/apache/camel/processor/UnmarshalProcessorTest.java > (added) > +++ > camel/trunk/camel-core/src/test/java/org/apache/camel/processor/UnmarshalProcessorTest.java > Sun Mar 4 12:39:03 2012 > @@ -0,0 +1,101 @@ > +/** > + * 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.processor; > + > +import java.io.InputStream; > +import java.io.OutputStream; > + > +import org.apache.camel.CamelContext; > +import org.apache.camel.Exchange; > +import org.apache.camel.Message; > +import org.apache.camel.RuntimeCamelException; > +import org.apache.camel.TestSupport; > +import org.apache.camel.impl.DefaultCamelContext; > +import org.apache.camel.impl.DefaultMessage; > +import org.apache.camel.spi.DataFormat; > + > +public class UnmarshalProcessorTest extends TestSupport { > + > + public void testDataFormatReturnsSameExchange() throws Exception { > + Exchange exchange = createExchangeWithBody(new > DefaultCamelContext(), "body"); > + UnmarshalProcessor processor = new UnmarshalProcessor(new > MyDataFormat(exchange)); > + > + processor.process(exchange); > + > + // as the process method call above acts as noop there's nothing to > assert on > + } > + > + public void testDataFormatReturnsAnotherExchange() throws Exception { > + CamelContext context = new DefaultCamelContext(); > + Exchange exchange = createExchangeWithBody(context, "body"); > + Exchange exchange2 = createExchangeWithBody(context, "body2"); > + UnmarshalProcessor processor = new UnmarshalProcessor(new > MyDataFormat(exchange2)); > + > + try { > + processor.process(exchange); > + fail("Should have thrown exception"); > + } catch (RuntimeCamelException e) { > + assertEquals("The returned exchange " + exchange2 + " is not the > same as " + exchange + " provided to the DataFormat", e.getMessage()); > + } > + } > + > + public void testDataFormatReturnsMessage() throws Exception { > + Exchange exchange = createExchangeWithBody(new > DefaultCamelContext(), "body"); > + Message out = new DefaultMessage(); > + out.setBody(new Object()); > + UnmarshalProcessor processor = new UnmarshalProcessor(new > MyDataFormat(out)); > + > + processor.process(exchange); > + assertEquals(out, exchange.getOut()); > + } > + > + public void testDataFormatReturnsBody() throws Exception { > + Exchange exchange = createExchangeWithBody(new > DefaultCamelContext(), "body"); > + Object unmarshalled = new Object(); > + UnmarshalProcessor processor = new UnmarshalProcessor(new > MyDataFormat(unmarshalled)); > + > + processor.process(exchange); > + assertEquals(unmarshalled, exchange.getOut().getBody()); > + } > + > + private static class MyDataFormat implements DataFormat { > + > + private final Object object; > + > + MyDataFormat(Exchange exchange) { > + object = exchange; > + } > + > + MyDataFormat(Message message) { > + object = message; > + } > + > + MyDataFormat(Object unmarshalled) { > + object = unmarshalled; > + } > + > + @Override > + public void marshal(Exchange exchange, Object graph, OutputStream > stream) throws Exception { > + throw new IllegalAccessException("This method is not expected to > be used by UnmarshalProcessor"); > + } > + > + @Override > + public Object unmarshal(Exchange exchange, InputStream stream) > throws Exception { > + return object; > + } > + } > +} > > Propchange: > camel/trunk/camel-core/src/test/java/org/apache/camel/processor/UnmarshalProcessorTest.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > -- Claus Ibsen ----------------- FuseSource Email: cib...@fusesource.com Web: http://fusesource.com Twitter: davsclaus, fusenews Blog: http://davsclaus.blogspot.com/ Author of Camel in Action: http://www.manning.com/ibsen/