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.util; 018 019 import java.util.HashMap; 020 import java.util.Map; 021 022 import org.apache.camel.Endpoint; 023 import org.apache.camel.Exchange; 024 import org.apache.camel.ExchangePattern; 025 import org.apache.camel.InvalidPayloadException; 026 import org.apache.camel.InvalidTypeException; 027 import org.apache.camel.Message; 028 import org.apache.camel.NoSuchBeanException; 029 import org.apache.camel.NoSuchEndpointException; 030 import org.apache.camel.NoSuchHeaderException; 031 import org.apache.camel.NoSuchPropertyException; 032 import org.apache.camel.NoTypeConversionAvailableException; 033 034 /** 035 * Some helper methods for working with {@link Exchange} objects 036 * 037 * @version $Revision: 2184 $ 038 */ 039 public final class ExchangeHelper { 040 041 /** 042 * Utility classes should not have a public constructor. 043 */ 044 private ExchangeHelper() { 045 } 046 047 /** 048 * Extracts the exchange property of the given name and type; if it is not present then the 049 * default value will be used 050 * 051 * @param exchange the message exchange 052 * @param propertyName the name of the property on the exchange 053 * @param type the expected type of the property 054 * @param defaultValue the default value to be used if the property name does not exist or could not be 055 * converted to the given type 056 * @return the property value as the given type or the defaultValue if it could not be found or converted 057 */ 058 public static <T> T getExchangeProperty(Exchange exchange, String propertyName, Class<T> type, T defaultValue) { 059 T answer = exchange.getProperty(propertyName, type); 060 if (answer == null) { 061 return defaultValue; 062 } 063 return answer; 064 } 065 066 067 /** 068 * Attempts to resolve the endpoint for the given value 069 * 070 * @param exchange the message exchange being processed 071 * @param value the value which can be an {@link Endpoint} or an object 072 * which provides a String representation of an endpoint via 073 * {@link #toString()} 074 * 075 * @return the endpoint 076 * @throws NoSuchEndpointException if the endpoint cannot be resolved 077 */ 078 @SuppressWarnings({"unchecked" }) 079 public static <E extends Exchange> Endpoint<E> resolveEndpoint(E exchange, Object value) 080 throws NoSuchEndpointException { 081 Endpoint<E> endpoint; 082 if (value instanceof Endpoint) { 083 endpoint = (Endpoint<E>)value; 084 } else { 085 String uri = value.toString(); 086 endpoint = CamelContextHelper.getMandatoryEndpoint(exchange.getContext(), uri); 087 } 088 return endpoint; 089 } 090 091 public static <T> T getMandatoryProperty(Exchange exchange, String propertyName, Class<T> type) 092 throws NoSuchPropertyException { 093 try { 094 T result = exchange.getProperty(propertyName, type); 095 if (result != null) { 096 return result; 097 } 098 } catch (NoTypeConversionAvailableException ex) { 099 // will throw NoSuchPropertyException below 100 } 101 throw new NoSuchPropertyException(exchange, propertyName, type); 102 } 103 104 public static <T> T getMandatoryHeader(Exchange exchange, String propertyName, Class<T> type) 105 throws NoSuchHeaderException { 106 T answer = exchange.getIn().getHeader(propertyName, type); 107 if (answer == null) { 108 throw new NoSuchHeaderException(exchange, propertyName, type); 109 } 110 return answer; 111 } 112 113 /** 114 * Returns the mandatory inbound message body of the correct type or throws 115 * an exception if it is not present 116 */ 117 public static Object getMandatoryInBody(Exchange exchange) throws InvalidPayloadException { 118 Object answer = exchange.getIn().getBody(); 119 if (answer == null) { 120 throw new InvalidPayloadException(exchange, Object.class); 121 } 122 return answer; 123 } 124 125 /** 126 * Returns the mandatory inbound message body of the correct type or throws 127 * an exception if it is not present 128 */ 129 public static <T> T getMandatoryInBody(Exchange exchange, Class<T> type) throws InvalidPayloadException { 130 T answer = exchange.getIn().getBody(type); 131 if (answer == null) { 132 throw new InvalidPayloadException(exchange, type); 133 } 134 return answer; 135 } 136 137 /** 138 * Returns the mandatory outbound message body of the correct type or throws 139 * an exception if it is not present 140 */ 141 public static Object getMandatoryOutBody(Exchange exchange) throws InvalidPayloadException { 142 Message out = exchange.getOut(); 143 Object answer = out.getBody(); 144 if (answer == null) { 145 throw new InvalidPayloadException(exchange, Object.class, out); 146 } 147 return answer; 148 } 149 150 /** 151 * Returns the mandatory outbound message body of the correct type or throws 152 * an exception if it is not present 153 */ 154 public static <T> T getMandatoryOutBody(Exchange exchange, Class<T> type) throws InvalidPayloadException { 155 Message out = exchange.getOut(); 156 T answer = out.getBody(type); 157 if (answer == null) { 158 throw new InvalidPayloadException(exchange, type, out); 159 } 160 return answer; 161 } 162 163 /** 164 * Converts the value to the given expected type or throws an exception 165 */ 166 public static <T> T convertToMandatoryType(Exchange exchange, Class<T> type, Object value) 167 throws InvalidTypeException { 168 T answer = convertToType(exchange, type, value); 169 if (answer == null) { 170 throw new InvalidTypeException(exchange, value, type); 171 } 172 return answer; 173 } 174 175 /** 176 * Converts the value to the given expected type returning null if it could 177 * not be converted 178 */ 179 public static <T> T convertToType(Exchange exchange, Class<T> type, Object value) { 180 return exchange.getContext().getTypeConverter().convertTo(type, exchange, value); 181 } 182 183 /** 184 * Copies the results of a message exchange from the source exchange to the result exchange 185 * which will copy the out and fault message contents and the exception 186 * 187 * @param result the result exchange which will have the output and error state added 188 * @param source the source exchange which is not modified 189 */ 190 public static void copyResults(Exchange result, Exchange source) { 191 if (result != source) { 192 result.setException(source.getException()); 193 Message fault = source.getFault(false); 194 if (fault != null) { 195 result.getFault(true).copyFrom(fault); 196 } 197 198 Message out = source.getOut(false); 199 if (out != null) { 200 result.getOut(true).copyFrom(out); 201 } else { 202 // no results so lets copy the last input 203 // as the final processor on a pipeline might not 204 // have created any OUT; such as a mock:endpoint 205 // so lets assume the last IN is the OUT 206 if (result.getPattern().isOutCapable()) { 207 // only set OUT if its OUT capable 208 result.getOut(true).copyFrom(source.getIn()); 209 } else { 210 // if not replace IN instead to keep the MEP 211 result.getIn().copyFrom(source.getIn()); 212 } 213 } 214 result.getProperties().clear(); 215 result.getProperties().putAll(source.getProperties()); 216 } 217 } 218 219 /** 220 * Returns true if the given exchange pattern (if defined) can support IN messagea 221 * 222 * @param exchange the exchange to interrogate 223 * @return true if the exchange is defined as an {@link ExchangePattern} which supports 224 * IN messages 225 */ 226 public static boolean isInCapable(Exchange exchange) { 227 ExchangePattern pattern = exchange.getPattern(); 228 return pattern != null && pattern.isInCapable(); 229 } 230 231 /** 232 * Returns true if the given exchange pattern (if defined) can support OUT messagea 233 * 234 * @param exchange the exchange to interrogate 235 * @return true if the exchange is defined as an {@link ExchangePattern} which supports 236 * OUT messages 237 */ 238 public static boolean isOutCapable(Exchange exchange) { 239 ExchangePattern pattern = exchange.getPattern(); 240 return pattern != null && pattern.isOutCapable(); 241 } 242 243 /** 244 * Creates a new instance of the given type from the injector 245 */ 246 public static <T> T newInstance(Exchange exchange, Class<T> type) { 247 return exchange.getContext().getInjector().newInstance(type); 248 } 249 250 /** 251 * Creates a Map of the variables which are made available to a script or template 252 * 253 * @param exchange the exchange to make available 254 * @return a Map populated with the require dvariables 255 */ 256 public static Map createVariableMap(Exchange exchange) { 257 Map answer = new HashMap(); 258 populateVariableMap(exchange, answer); 259 return answer; 260 } 261 262 /** 263 * Populates the Map with the variables which are made available to a script or template 264 * 265 * @param exchange the exchange to make available 266 * @param map the map to populate 267 */ 268 public static void populateVariableMap(Exchange exchange, Map map) { 269 map.put("exchange", exchange); 270 Message in = exchange.getIn(); 271 map.put("in", in); 272 map.put("request", in); 273 map.put("headers", in.getHeaders()); 274 map.put("body", in.getBody()); 275 if (isOutCapable(exchange)) { 276 Message out = exchange.getOut(true); 277 map.put("out", out); 278 map.put("response", out); 279 } 280 map.put("camelContext", exchange.getContext()); 281 } 282 283 /** 284 * Returns the MIME content type on the input message or null if one is not defined 285 */ 286 public static String getContentType(Exchange exchange) { 287 return exchange.getIn().getHeader("Content-Type", String.class); 288 } 289 290 /** 291 * Performs a lookup in the registry of the mandatory bean name and throws an exception if it could not be found 292 */ 293 public static Object lookupMandatoryBean(Exchange exchange, String name) { 294 Object value = lookupBean(exchange, name); 295 if (value == null) { 296 throw new NoSuchBeanException(name); 297 } 298 return value; 299 } 300 301 /** 302 * Performs a lookup in the registry of the mandatory bean name and throws an exception if it could not be found 303 */ 304 public static <T> T lookupMandatoryBean(Exchange exchange, String name, Class<T> type) { 305 T value = lookupBean(exchange, name, type); 306 if (value == null) { 307 throw new NoSuchBeanException(name); 308 } 309 return value; 310 } 311 312 /** 313 * Performs a lookup in the registry of the bean name 314 */ 315 public static Object lookupBean(Exchange exchange, String name) { 316 return exchange.getContext().getRegistry().lookup(name); 317 } 318 319 /** 320 * Performs a lookup in the registry of the bean name and type 321 */ 322 public static <T> T lookupBean(Exchange exchange, String name, Class<T> type) { 323 return exchange.getContext().getRegistry().lookup(name, type); 324 } 325 }