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.ExchangePattern; 025 import org.apache.camel.Message; 026 import org.apache.camel.RuntimeCamelException; 027 import org.apache.camel.spi.UnitOfWork; 028 import org.apache.camel.util.UuidGenerator; 029 030 /** 031 * A default implementation of {@link Exchange} 032 * 033 * @version $Revision: 41910 $ 034 */ 035 public class DefaultExchange implements Exchange { 036 private static final UuidGenerator DEFAULT_ID_GENERATOR = new UuidGenerator(); 037 protected final CamelContext context; 038 private Map<String, Object> properties; 039 private Message in; 040 private Message out; 041 private Message fault; 042 private Throwable exception; 043 private String exchangeId; 044 private UnitOfWork unitOfWork; 045 private ExchangePattern pattern; 046 047 public DefaultExchange(CamelContext context) { 048 this(context, ExchangePattern.InOnly); 049 } 050 051 public DefaultExchange(CamelContext context, ExchangePattern pattern) { 052 this.context = context; 053 this.pattern = pattern; 054 } 055 056 public DefaultExchange(DefaultExchange parent) { 057 this(parent.getContext(), parent.getPattern()); 058 this.unitOfWork = parent.getUnitOfWork(); 059 } 060 061 @Override 062 public String toString() { 063 return "Exchange[" + in + "]"; 064 } 065 066 public Exchange copy() { 067 Exchange exchange = newInstance(); 068 exchange.copyFrom(this); 069 return exchange; 070 } 071 072 public void copyFrom(Exchange exchange) { 073 if (exchange == this) { 074 return; 075 } 076 setProperties(safeCopy(exchange.getProperties())); 077 078 // this can cause strangeness if we copy, say, a FileMessage onto an FtpExchange with overloaded getExchange() methods etc. 079 safeCopy(getIn(), exchange, exchange.getIn()); 080 Message copyOut = exchange.getOut(false); 081 if (copyOut != null) { 082 safeCopy(getOut(true), exchange, copyOut); 083 } 084 Message copyFault = exchange.getFault(false); 085 if (copyFault != null) { 086 safeCopy(getFault(true), exchange, copyFault); 087 } 088 setException(exchange.getException()); 089 090 unitOfWork = exchange.getUnitOfWork(); 091 pattern = exchange.getPattern(); 092 } 093 094 private static void safeCopy(Message message, Exchange exchange, Message that) { 095 if (message != null) { 096 message.copyFrom(that); 097 } 098 } 099 100 private static Map<String, Object> safeCopy(Map<String, Object> properties) { 101 if (properties == null) { 102 return null; 103 } 104 return new HashMap<String, Object>(properties); 105 } 106 107 private static Message safeCopy(Exchange exchange, Message message) { 108 if (message == null) { 109 return null; 110 } 111 Message answer = message.copy(); 112 if (answer instanceof MessageSupport) { 113 MessageSupport messageSupport = (MessageSupport) answer; 114 messageSupport.setExchange(exchange); 115 } 116 return answer; 117 } 118 119 public Exchange newInstance() { 120 return new DefaultExchange(this); 121 } 122 123 public CamelContext getContext() { 124 return context; 125 } 126 127 public Object getProperty(String name) { 128 if (properties != null) { 129 return properties.get(name); 130 } 131 return null; 132 } 133 134 public <T> T getProperty(String name, Class<T> type) { 135 Object value = getProperty(name); 136 return getContext().getTypeConverter().convertTo(type, value); 137 } 138 139 public void setProperty(String name, Object value) { 140 getProperties().put(name, value); 141 } 142 143 public Object removeProperty(String name) { 144 return getProperties().remove(name); 145 } 146 147 public Map<String, Object> getProperties() { 148 if (properties == null) { 149 properties = new HashMap<String, Object>(); 150 } 151 return properties; 152 } 153 154 public void setProperties(Map<String, Object> properties) { 155 this.properties = properties; 156 } 157 158 public Message getIn() { 159 if (in == null) { 160 in = createInMessage(); 161 configureMessage(in); 162 } 163 return in; 164 } 165 166 public void setIn(Message in) { 167 this.in = in; 168 configureMessage(in); 169 } 170 171 public Message getOut() { 172 return getOut(true); 173 } 174 175 public Message getOut(boolean lazyCreate) { 176 if (out == null && lazyCreate) { 177 out = createOutMessage(); 178 configureMessage(out); 179 } 180 return out; 181 } 182 183 public void setOut(Message out) { 184 this.out = out; 185 configureMessage(out); 186 } 187 188 public Throwable getException() { 189 return exception; 190 } 191 192 public void setException(Throwable exception) { 193 this.exception = exception; 194 } 195 196 public ExchangePattern getPattern() { 197 return pattern; 198 } 199 200 public void setPattern(ExchangePattern pattern) { 201 this.pattern = pattern; 202 } 203 204 public void throwException() throws Exception { 205 if (exception == null) { 206 return; 207 } 208 if (exception instanceof RuntimeException) { 209 throw (RuntimeException)exception; 210 } 211 if (exception instanceof Exception) { 212 throw (Exception)exception; 213 } 214 throw new RuntimeCamelException(exception); 215 } 216 217 public Message getFault() { 218 return getFault(true); 219 } 220 221 public Message getFault(boolean lazyCreate) { 222 if (fault == null && lazyCreate) { 223 fault = createFaultMessage(); 224 configureMessage(fault); 225 } 226 return fault; 227 } 228 229 public void setFault(Message fault) { 230 this.fault = fault; 231 configureMessage(fault); 232 } 233 234 public String getExchangeId() { 235 if (exchangeId == null) { 236 exchangeId = DefaultExchange.DEFAULT_ID_GENERATOR.generateId(); 237 } 238 return exchangeId; 239 } 240 241 public void setExchangeId(String id) { 242 this.exchangeId = id; 243 } 244 245 public boolean isFailed() { 246 Message faultMessage = getFault(false); 247 if (faultMessage != null) { 248 Object faultBody = faultMessage.getBody(); 249 if (faultBody != null) { 250 return true; 251 } 252 } 253 return getException() != null; 254 } 255 256 public UnitOfWork getUnitOfWork() { 257 return unitOfWork; 258 } 259 260 public void setUnitOfWork(UnitOfWork unitOfWork) { 261 this.unitOfWork = unitOfWork; 262 } 263 264 /** 265 * Factory method used to lazily create the IN message 266 */ 267 protected Message createInMessage() { 268 return new DefaultMessage(); 269 } 270 271 /** 272 * Factory method to lazily create the OUT message 273 */ 274 protected Message createOutMessage() { 275 return new DefaultMessage(); 276 } 277 278 /** 279 * Factory method to lazily create the FAULT message 280 */ 281 protected Message createFaultMessage() { 282 return new DefaultMessage(); 283 } 284 285 /** 286 * Configures the message after it has been set on the exchange 287 */ 288 protected void configureMessage(Message message) { 289 if (message instanceof MessageSupport) { 290 MessageSupport messageSupport = (MessageSupport)message; 291 messageSupport.setExchange(this); 292 } 293 } 294 295 }