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 }