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 org.apache.camel.CamelContext;
020    import org.apache.camel.Exchange;
021    import org.apache.camel.Message;
022    import org.apache.camel.util.UuidGenerator;
023    
024    import java.util.HashMap;
025    import java.util.Map;
026    
027    /**
028     * A default implementation of {@link Exchange}
029     *
030     * @version $Revision: 550760 $
031     */
032    public class DefaultExchange implements Exchange {
033        private static final UuidGenerator defaultIdGenerator = new UuidGenerator();
034        protected final CamelContext context;
035        private Map<String, Object> headers;
036        private Message in;
037        private Message out;
038        private Message fault;
039        private Throwable exception;
040        private String exchangeId = DefaultExchange.defaultIdGenerator.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            setHeaders(safeCopy(exchange.getProperties()));
062            setIn(safeCopy(exchange.getIn()));
063            setOut(safeCopy(exchange.getOut()));
064            setFault(safeCopy(exchange.getFault()));        
065            setException(exchange.getException());
066        }
067    
068        static private Map<String, Object> safeCopy(Map<String, Object> properties) {
069                    if(properties == null)
070                            return null;
071                    return new HashMap<String, Object>(properties);
072            }
073    
074            static private Message safeCopy(Message message) {
075            if( message == null)
076                    return null;
077            return message.copy();
078            }
079    
080            public Exchange newInstance() {
081            return new DefaultExchange(context);
082        }
083    
084        public CamelContext getContext() {
085            return context;
086        }
087    
088        public Object getProperty(String name) {
089            if (headers != null) {
090                return headers.get(name);
091            }
092            return null;
093        }
094    
095        public <T> T getProperty(String name, Class<T> type) {
096            Object value = getProperty(name);
097            return getContext().getTypeConverter().convertTo(type, value);
098        }
099    
100        public void setProperty(String name, Object value) {
101            getProperties().put(name, value);
102        }
103    
104        public Map<String, Object> getProperties() {
105            if (headers == null) {
106                headers = new HashMap<String, Object>();
107            }
108            return headers;
109        }
110    
111        public void setHeaders(Map<String, Object> headers) {
112            this.headers = headers;
113        }
114    
115        public Message getIn() {
116            if (in == null) {
117                in = createInMessage();
118                configureMessage(in);
119            }
120            return in;
121        }
122    
123        public void setIn(Message in) {
124            this.in = in;
125            configureMessage(in);
126        }
127    
128        public Message getOut() {
129            return getOut(true);
130        }
131    
132        public Message getOut(boolean lazyCreate) {
133            if (out == null && lazyCreate) {
134                out = createOutMessage();
135                configureMessage(out);
136            }
137            return out;
138        }
139    
140        public void setOut(Message out) {
141            this.out = out;
142            configureMessage(out);
143        }
144    
145        public Throwable getException() {
146            return exception;
147        }
148    
149        public void setException(Throwable exception) {
150            this.exception = exception;
151        }
152    
153        public Message getFault() {
154            return fault;
155        }
156    
157        public void setFault(Message fault) {
158            this.fault = fault;
159            configureMessage(fault);
160        }
161    
162        public String getExchangeId() {
163            return exchangeId;
164        }
165    
166        public void setExchangeId(String id) {
167            this.exchangeId = id;
168        }
169    
170        /**
171         * Factory method used to lazily create the IN message
172         */
173        protected Message createInMessage() {
174            return new DefaultMessage();
175        }
176    
177        /**
178         * Factory method to lazily create the OUT message
179         */
180        protected Message createOutMessage() {
181            return new DefaultMessage();
182        }
183    
184        /**
185         * Configures the message after it has been set on the exchange
186         */
187        protected void configureMessage(Message message) {
188            if (message instanceof MessageSupport) {
189                MessageSupport messageSupport = (MessageSupport) message;
190                messageSupport.setExchange(this);
191            }
192        }
193    }