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