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.Locale;
020    
021    import org.apache.camel.CamelContext;
022    import org.apache.camel.Endpoint;
023    import org.apache.camel.Exchange;
024    import org.apache.camel.NoSuchBeanException;
025    import org.apache.camel.NoSuchEndpointException;
026    
027    import static org.apache.camel.util.ObjectHelper.isEmpty;
028    import static org.apache.camel.util.ObjectHelper.isNotEmpty;
029    import static org.apache.camel.util.ObjectHelper.notNull;
030    
031    /**
032     * A number of helper methods
033     *
034     * @version 
035     */
036    public final class CamelContextHelper {
037    
038        /**
039         * Utility classes should not have a public constructor.
040         */
041        private CamelContextHelper() {
042        }
043    
044        /**
045         * Returns the mandatory endpoint for the given URI or the
046         * {@link org.apache.camel.NoSuchEndpointException} is thrown
047         */
048        public static Endpoint getMandatoryEndpoint(CamelContext camelContext, String uri)
049            throws NoSuchEndpointException {
050            Endpoint endpoint = camelContext.getEndpoint(uri);
051            if (endpoint == null) {
052                throw new NoSuchEndpointException(uri);
053            } else {
054                return endpoint;
055            }
056        }
057    
058        /**
059         * Returns the mandatory endpoint for the given URI and type or the
060         * {@link org.apache.camel.NoSuchEndpointException} is thrown
061         */
062        public static <T extends Endpoint> T getMandatoryEndpoint(CamelContext camelContext, String uri, Class<T> type) {
063            Endpoint endpoint = getMandatoryEndpoint(camelContext, uri);
064            return ObjectHelper.cast(type, endpoint);
065        }
066    
067        /**
068         * Converts the given value to the requested type
069         */
070        public static <T> T convertTo(CamelContext context, Class<T> type, Object value) {
071            notNull(context, "camelContext");
072            return context.getTypeConverter().convertTo(type, value);
073        }
074    
075        /**
076         * Converts the given value to the specified type throwing an {@link IllegalArgumentException}
077         * if the value could not be converted to a non null value
078         */
079        public static <T> T mandatoryConvertTo(CamelContext context, Class<T> type, Object value) {
080            T answer = convertTo(context, type, value);
081            if (answer == null) {
082                throw new IllegalArgumentException("Value " + value + " converted to " + type.getName() + " cannot be null");
083            }
084            return answer;
085        }
086    
087        /**
088         * Creates a new instance of the given type using the {@link org.apache.camel.spi.Injector} on the given
089         * {@link CamelContext}
090         */
091        public static <T> T newInstance(CamelContext context, Class<T> beanType) {
092            return context.getInjector().newInstance(beanType);
093        }
094    
095        /**
096         * Look up the given named bean in the {@link org.apache.camel.spi.Registry} on the
097         * {@link CamelContext}
098         */
099        public static Object lookup(CamelContext context, String name) {
100            return context.getRegistry().lookup(name);
101        }
102    
103        /**
104         * Look up the given named bean of the given type in the {@link org.apache.camel.spi.Registry} on the
105         * {@link CamelContext}
106         */
107        public static <T> T lookup(CamelContext context, String name, Class<T> beanType) {
108            return context.getRegistry().lookup(name, beanType);
109        }
110    
111        /**
112         * Look up the given named bean in the {@link org.apache.camel.spi.Registry} on the
113         * {@link CamelContext} or throws NoSuchBeanException if not found.
114         */
115        public static Object mandatoryLookup(CamelContext context, String name) {
116            Object answer = lookup(context, name);
117            if (answer == null) {
118                throw new NoSuchBeanException(name);
119            }
120            return answer;
121        }
122    
123        /**
124         * Look up the given named bean of the given type in the {@link org.apache.camel.spi.Registry} on the
125         * {@link CamelContext} or throws NoSuchBeanException if not found.
126         */
127        public static <T> T mandatoryLookup(CamelContext context, String name, Class<T> beanType) {
128            T answer = lookup(context, name, beanType);
129            if (answer == null) {
130                throw new NoSuchBeanException(name, beanType.getName());
131            }
132            return answer;
133        }
134    
135        /**
136         * Evaluates the @EndpointInject annotation using the given context
137         */
138        public static Endpoint getEndpointInjection(CamelContext camelContext, String uri, String ref, String injectionPointName, boolean mandatory) {
139            if (ObjectHelper.isNotEmpty(uri) && ObjectHelper.isNotEmpty(ref)) {
140                throw new IllegalArgumentException("Both uri and name is provided, only either one is allowed: uri=" + uri + ", ref=" + ref);
141            }
142    
143            Endpoint endpoint;
144            if (isNotEmpty(uri)) {
145                endpoint = camelContext.getEndpoint(uri);
146            } else {
147                // if a ref is given then it should be possible to lookup
148                // otherwise we do not catch situations where there is a typo etc
149                if (isNotEmpty(ref)) {
150                    endpoint = mandatoryLookup(camelContext, ref, Endpoint.class);
151                } else {
152                    if (isEmpty(ref)) {
153                        ref = injectionPointName;
154                    }
155                    if (mandatory) {
156                        endpoint = mandatoryLookup(camelContext, ref, Endpoint.class);
157                    } else {
158                        endpoint = lookup(camelContext, ref, Endpoint.class);
159                    }
160                }
161            }
162            return endpoint;
163        }
164    
165        /**
166         * Gets the maximum cache pool size.
167         * <p/>
168         * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_CACHE_POOL_SIZE}.
169         * If no property has been set, then it will fallback to return a size of 1000.
170         *
171         * @param camelContext the camel context
172         * @return the maximum cache size
173         * @throws IllegalArgumentException is thrown if the property is illegal
174         */
175        public static int getMaximumCachePoolSize(CamelContext camelContext) throws IllegalArgumentException {
176            if (camelContext != null) {
177                String s = camelContext.getProperties().get(Exchange.MAXIMUM_CACHE_POOL_SIZE);
178                if (s != null) {
179                    try {
180                        // we cannot use Camel type converters as they may not be ready this early
181                        Integer size = Integer.valueOf(s);
182                        if (size == null || size <= 0) {
183                            throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_CACHE_POOL_SIZE + " must be a positive number, was: " + s);
184                        }
185                        return size;
186                    } catch (NumberFormatException e) {
187                        throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_CACHE_POOL_SIZE + " must be a positive number, was: " + s, e);
188                    }
189                }
190            }
191    
192            // 1000 is the default fallback
193            return 1000;
194        }
195    
196        /**
197         * Gets the maximum endpoint cache size.
198         * <p/>
199         * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_ENDPOINT_CACHE_SIZE}.
200         * If no property has been set, then it will fallback to return a size of 1000.
201         *
202         * @param camelContext the camel context
203         * @return the maximum cache size
204         * @throws IllegalArgumentException is thrown if the property is illegal
205         */
206        public static int getMaximumEndpointCacheSize(CamelContext camelContext) throws IllegalArgumentException {
207            if (camelContext != null) {
208                String s = camelContext.getProperties().get(Exchange.MAXIMUM_ENDPOINT_CACHE_SIZE);
209                if (s != null) {
210                    // we cannot use Camel type converters as they may not be ready this early
211                    try {
212                        Integer size = Integer.valueOf(s);
213                        if (size == null || size <= 0) {
214                            throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_ENDPOINT_CACHE_SIZE + " must be a positive number, was: " + s);
215                        }
216                        return size;
217                    } catch (NumberFormatException e) {
218                        throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_ENDPOINT_CACHE_SIZE + " must be a positive number, was: " + s, e);
219                    }
220                }
221            }
222    
223            // 1000 is the default fallback
224            return 1000;
225        }
226    
227        /**
228         * Parses the given text and handling property placeholders as well
229         *
230         * @param camelContext the camel context
231         * @param text  the text
232         * @return the parsed text, or <tt>null</tt> if the text was <tt>null</tt>
233         * @throws Exception is thrown if illegal argument
234         */
235        public static String parseText(CamelContext camelContext, String text) throws Exception {
236            // ensure we support property placeholders
237            return camelContext.resolvePropertyPlaceholders(text);
238        }
239    
240        /**
241         * Parses the given text and converts it to an Integer and handling property placeholders as well
242         *
243         * @param camelContext the camel context
244         * @param text  the text
245         * @return the integer vale, or <tt>null</tt> if the text was <tt>null</tt>
246         * @throws Exception is thrown if illegal argument or type conversion not possible
247         */
248        public static Integer parseInteger(CamelContext camelContext, String text) throws Exception {
249            // ensure we support property placeholders
250            String s = camelContext.resolvePropertyPlaceholders(text);
251            if (s != null) {
252                try {
253                    return camelContext.getTypeConverter().mandatoryConvertTo(Integer.class, s);
254                } catch (NumberFormatException e) {
255                    if (s.equals(text)) {
256                        throw new IllegalArgumentException("Error parsing [" + s + "] as an Integer.", e);
257                    } else {
258                        throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as an Integer.", e);
259                    }
260                }
261            }
262            return null;
263        }
264    
265        /**
266         * Parses the given text and converts it to an Long and handling property placeholders as well
267         *
268         * @param camelContext the camel context
269         * @param text  the text
270         * @return the long vale, or <tt>null</tt> if the text was <tt>null</tt>
271         * @throws Exception is thrown if illegal argument or type conversion not possible
272         */
273        public static Long parseLong(CamelContext camelContext, String text) throws Exception {
274            // ensure we support property placeholders
275            String s = camelContext.resolvePropertyPlaceholders(text);
276            if (s != null) {
277                try {
278                    return camelContext.getTypeConverter().mandatoryConvertTo(Long.class, s);
279                } catch (NumberFormatException e) {
280                    if (s.equals(text)) {
281                        throw new IllegalArgumentException("Error parsing [" + s + "] as a Long.", e);
282                    } else {
283                        throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as a Long.", e);
284                    }
285                }
286            }
287            return null;
288        }
289    
290        /**
291         * Parses the given text and converts it to a Double and handling property placeholders as well
292         *
293         * @param camelContext the camel context
294         * @param text  the text
295         * @return the double vale, or <tt>null</tt> if the text was <tt>null</tt>
296         * @throws Exception is thrown if illegal argument or type conversion not possible
297         */
298        public static Double parseDouble(CamelContext camelContext, String text) throws Exception {
299            // ensure we support property placeholders
300            String s = camelContext.resolvePropertyPlaceholders(text);
301            if (s != null) {
302                try {
303                    return camelContext.getTypeConverter().mandatoryConvertTo(Double.class, s);
304                } catch (NumberFormatException e) {
305                    if (s.equals(text)) {
306                        throw new IllegalArgumentException("Error parsing [" + s + "] as an Integer.", e);
307                    } else {
308                        throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as an Integer.", e);
309                    }
310                }
311            }
312            return null;
313        }
314    
315        /**
316         * Parses the given text and converts it to an Boolean and handling property placeholders as well
317         *
318         * @param camelContext the camel context
319         * @param text  the text
320         * @return the boolean vale, or <tt>null</tt> if the text was <tt>null</tt>
321         * @throws Exception is thrown if illegal argument or type conversion not possible
322         */
323        public static Boolean parseBoolean(CamelContext camelContext, String text) throws Exception {
324            // ensure we support property placeholders
325            String s = camelContext.resolvePropertyPlaceholders(text);
326            if (s != null) {
327                s = s.trim().toLowerCase(Locale.ENGLISH);
328                if (s.equals("true") || s.equals("false")) {
329                    return "true".equals(s) ? Boolean.TRUE : Boolean.FALSE;
330                } else {
331                    if (s.equals(text)) {
332                        throw new IllegalArgumentException("Error parsing [" + s + "] as a Boolean.");
333                    } else {
334                        throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as a Boolean.");
335                    }
336                }
337            }
338            return null;
339        }
340    
341    }