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.impl;
018    
019    import java.util.HashMap;
020    import java.util.Map;
021    
022    import org.apache.camel.CamelContext;
023    import org.apache.camel.Exchange;
024    import org.apache.camel.Message;
025    import org.apache.camel.util.UuidGenerator;
026    
027    /**
028     * A default implementation of {@link Exchange}
029     * 
030     * @version $Revision: 564677 $
031     */
032    public class DefaultExchange implements Exchange {
033        private static final UuidGenerator DEFAULT_ID_GENERATOR = new UuidGenerator();
034        protected final CamelContext context;
035        private Map<String, Object> properties;
036        private Message in;
037        private Message out;
038        private Message fault;
039        private Throwable exception;
040        private String exchangeId = DefaultExchange.DEFAULT_ID_GENERATOR.generateId();
041    
042        public DefaultExchange(CamelContext context) {
043            this.context = context;
044        }
045    
046        @Override
047        public String toString() {
048            return "Exchange[" + in + "]";
049        }
050    
051        public Exchange copy() {
052            Exchange exchange = newInstance();
053            exchange.copyFrom(this);
054            return exchange;
055        }
056    
057        public void copyFrom(Exchange exchange) {
058            if (exchange == this) {
059                return;
060            }
061            setProperties(safeCopy(exchange.getProperties()));
062    
063            // this can cause strangeness if we copy, say, a FileMessage onto an FtpExchange with overloaded getExchange() methods etc.
064    
065            safeCopy(getIn(), exchange, exchange.getIn());
066            Message copyOut = exchange.getOut();
067            if (copyOut != null) {
068                safeCopy(getOut(true), exchange, copyOut);
069            }
070            Message copyFault = exchange.getFault();
071            if (copyFault != null) {
072                safeCopy(getFault(), exchange, copyFault);
073            }
074    
075    /*
076            setIn(safeCopy(exchange, exchange.getIn()));
077            setOut(safeCopy(exchange, exchange.getOut()));
078            setFault(safeCopy(exchange, exchange.getFault()));
079    */
080            setException(exchange.getException());
081        }
082    
083        private static void safeCopy(Message message, Exchange exchange, Message that) {
084            if (message != null) {
085                message.copyFrom(that);
086            }
087        }
088    
089        private static Map<String, Object> safeCopy(Map<String, Object> properties) {
090            if (properties == null) {
091                return null;
092            }
093            return new HashMap<String, Object>(properties);
094        }
095    
096        private static Message safeCopy(Exchange exchange, Message message) {
097            if (message == null) {
098                return null;
099            }
100            Message answer = message.copy();
101            if (answer instanceof MessageSupport) {
102                MessageSupport messageSupport = (MessageSupport) answer;
103                messageSupport.setExchange(exchange);
104            }
105            return answer;
106        }
107    
108        public Exchange newInstance() {
109            return new DefaultExchange(context);
110        }
111    
112        public CamelContext getContext() {
113            return context;
114        }
115    
116        public Object getProperty(String name) {
117            if (properties != null) {
118                return properties.get(name);
119            }
120            return null;
121        }
122    
123        public <T> T getProperty(String name, Class<T> type) {
124            Object value = getProperty(name);
125            return getContext().getTypeConverter().convertTo(type, value);
126        }
127    
128        public void setProperty(String name, Object value) {
129            getProperties().put(name, value);
130        }
131    
132        public Map<String, Object> getProperties() {
133            if (properties == null) {
134                properties = new HashMap<String, Object>();
135            }
136            return properties;
137        }
138    
139        public void setProperties(Map<String, Object> properties) {
140            this.properties = properties;
141        }
142    
143        public Message getIn() {
144            if (in == null) {
145                in = createInMessage();
146                configureMessage(in);
147            }
148            return in;
149        }
150    
151        public void setIn(Message in) {
152            this.in = in;
153            configureMessage(in);
154        }
155    
156        public Message getOut() {
157            return getOut(true);
158        }
159    
160        public Message getOut(boolean lazyCreate) {
161            if (out == null && lazyCreate) {
162                out = createOutMessage();
163                configureMessage(out);
164            }
165            return out;
166        }
167    
168        public void setOut(Message out) {
169            this.out = out;
170            configureMessage(out);
171        }
172    
173        public Throwable getException() {
174            return exception;
175        }
176    
177        public void setException(Throwable exception) {
178            this.exception = exception;
179        }
180    
181        public Message getFault() {
182            return fault;
183        }
184    
185        public void setFault(Message fault) {
186            this.fault = fault;
187            configureMessage(fault);
188        }
189    
190        public String getExchangeId() {
191            return exchangeId;
192        }
193    
194        public void setExchangeId(String id) {
195            this.exchangeId = id;
196        }
197    
198        /**
199         * Factory method used to lazily create the IN message
200         */
201        protected Message createInMessage() {
202            return new DefaultMessage();
203        }
204    
205        /**
206         * Factory method to lazily create the OUT message
207         */
208        protected Message createOutMessage() {
209            return new DefaultMessage();
210        }
211    
212        /**
213         * Configures the message after it has been set on the exchange
214         */
215        protected void configureMessage(Message message) {
216            if (message instanceof MessageSupport) {
217                MessageSupport messageSupport = (MessageSupport)message;
218                messageSupport.setExchange(this);
219            }
220        }
221    }