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: 732393 $
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 }