001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.spring.integration.adapter;
018    
019    import org.apache.camel.CamelContext;
020    import org.apache.camel.Exchange;
021    import org.apache.camel.ExchangePattern;
022    import org.apache.camel.ProducerTemplate;
023    import org.apache.camel.component.spring.integration.SpringIntegrationBinding;
024    import org.apache.camel.impl.DefaultCamelContext;
025    import org.apache.camel.impl.DefaultExchange;
026    import org.springframework.integration.Message;
027    import org.springframework.integration.MessageChannel;
028    import org.springframework.integration.MessageDeliveryException;
029    import org.springframework.integration.MessageHeaders;
030    import org.springframework.integration.core.MessageHandler;
031    
032    /**
033     * CamelTargetAdapter will redirect the Spring Integration message to the Camel context.
034     * When we inject the camel context into it, we need also specify the Camel endpoint url
035     * we will route the Spring Integration message to the Camel context
036     *
037     * @version 
038     */
039    public class CamelTargetAdapter extends AbstractCamelAdapter implements MessageHandler {
040        private ProducerTemplate camelTemplate;
041        private MessageChannel replyChannel;
042    
043        public void setReplyChannel(MessageChannel channel) {
044            this.replyChannel = channel;
045        }
046    
047        public MessageChannel getReplyChannel() {
048            return replyChannel;
049        }
050    
051        public ProducerTemplate getCamelTemplate() throws Exception {
052            if (camelTemplate == null) {
053                CamelContext ctx = getCamelContext();
054                if (ctx == null) {
055                    // TODO: This doesnt look good to create a new CamelContext out of the blue
056                    ctx = new DefaultCamelContext();
057                }
058                camelTemplate = ctx.createProducerTemplate();
059            }
060            return camelTemplate;
061        }
062    
063        public boolean send(Message<?> message) throws Exception {
064            boolean result = false;
065    
066            ExchangePattern pattern;
067            if (isExpectReply()) {
068                pattern = ExchangePattern.InOut;
069            } else {
070                pattern = ExchangePattern.InOnly;
071            }
072    
073            Exchange inExchange = new DefaultExchange(getCamelContext(), pattern);
074            SpringIntegrationBinding.storeToCamelMessage(message, inExchange.getIn());
075            Exchange outExchange = getCamelTemplate().send(getCamelEndpointUri(), inExchange);
076            if (outExchange.getOut() != null && outExchange.getOut().isFault()) {
077                result = true;
078            }
079    
080            Message response;
081            if (isExpectReply()) {
082                //Check the message header for the return address
083                response = SpringIntegrationBinding.storeToSpringIntegrationMessage(outExchange.getOut());
084                if (replyChannel == null) {
085                    MessageChannel messageReplyChannel = (MessageChannel) message.getHeaders().get(MessageHeaders.REPLY_CHANNEL);
086                    if (messageReplyChannel != null) {
087                        result = messageReplyChannel.send(response);
088                    } else {
089                        throw new MessageDeliveryException(response, "Cannot resolve ReplyChannel from message: " + message);
090                    }
091                } else {
092                    result = replyChannel.send(response);
093                }
094            }
095    
096            return result;
097        }
098    
099        public void handleMessage(Message<?> message) throws MessageDeliveryException {
100            try {
101                send(message);
102            } catch (Exception e) {
103                throw new MessageDeliveryException(message, "Cannot send message", e);
104            }
105        }
106    
107    }