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