Eeee….

We can't just change API :)


On Mar 5, 2012, at 12:51 AM, Claus Ibsen wrote:

> 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/

Reply via email to