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.impl;
018    
019    import java.io.IOException;
020    import java.lang.reflect.Constructor;
021    import java.util.ArrayList;
022    import java.util.Collection;
023    import java.util.HashMap;
024    import java.util.List;
025    import java.util.Map;
026    import java.util.concurrent.Callable;
027    
028    import javax.naming.Context;
029    
030    import org.apache.camel.CamelContext;
031    import org.apache.camel.Component;
032    import org.apache.camel.Endpoint;
033    import org.apache.camel.Exchange;
034    import org.apache.camel.Processor;
035    import org.apache.camel.ProducerTemplate;
036    import org.apache.camel.ResolveEndpointFailedException;
037    import org.apache.camel.Route;
038    import org.apache.camel.Routes;
039    import org.apache.camel.RuntimeCamelException;
040    import org.apache.camel.Service;
041    import org.apache.camel.TypeConverter;
042    import org.apache.camel.builder.ErrorHandlerBuilder;
043    import org.apache.camel.impl.converter.DefaultTypeConverter;
044    import org.apache.camel.management.InstrumentationLifecycleStrategy;
045    import org.apache.camel.management.JmxSystemPropertyKeys;
046    import org.apache.camel.model.RouteType;
047    import org.apache.camel.model.dataformat.DataFormatType;
048    import org.apache.camel.processor.interceptor.Delayer;
049    import org.apache.camel.processor.interceptor.TraceFormatter;
050    import org.apache.camel.processor.interceptor.Tracer;
051    import org.apache.camel.spi.ComponentResolver;
052    import org.apache.camel.spi.ExchangeConverter;
053    import org.apache.camel.spi.Injector;
054    import org.apache.camel.spi.InterceptStrategy;
055    import org.apache.camel.spi.Language;
056    import org.apache.camel.spi.LanguageResolver;
057    import org.apache.camel.spi.LifecycleStrategy;
058    import org.apache.camel.spi.Registry;
059    import org.apache.camel.util.CamelContextHelper;
060    import org.apache.camel.util.FactoryFinder;
061    import org.apache.camel.util.NoFactoryAvailableException;
062    import org.apache.camel.util.ObjectHelper;
063    import org.apache.camel.util.ReflectionInjector;
064    import org.apache.camel.util.SystemHelper;
065    import org.apache.commons.logging.Log;
066    import org.apache.commons.logging.LogFactory;
067    
068    import static org.apache.camel.util.ServiceHelper.startServices;
069    import static org.apache.camel.util.ServiceHelper.stopServices;
070    
071    /**
072     * Represents the context used to configure routes and the policies to use.
073     *
074     * @version $Revision: 732209 $
075     */
076    public class DefaultCamelContext extends ServiceSupport implements CamelContext, Service {
077        private static final transient Log LOG = LogFactory.getLog(DefaultCamelContext.class);
078        private static final String NAME_PREFIX = "camel-";
079        private static int nameSuffix;
080    
081        private String name;
082        private final Map<String, Endpoint> endpoints = new HashMap<String, Endpoint>();
083        private final Map<String, Component> components = new HashMap<String, Component>();
084        private List<Route> routes;
085        private List<Service> servicesToClose = new ArrayList<Service>();
086        private TypeConverter typeConverter;
087        private ExchangeConverter exchangeConverter;
088        private Injector injector;
089        private ComponentResolver componentResolver;
090        private boolean autoCreateComponents = true;
091        private LanguageResolver languageResolver = new DefaultLanguageResolver();
092        private Registry registry;
093        private LifecycleStrategy lifecycleStrategy;
094        private List<RouteType> routeDefinitions = new ArrayList<RouteType>();
095        private List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
096        private Boolean trace;
097        private Long delay;
098        private ErrorHandlerBuilder errorHandlerBuilder;
099        private Map<String, DataFormatType> dataFormats = new HashMap<String, DataFormatType>();
100        private Class<? extends FactoryFinder> factoryFinderClass = FactoryFinder.class;
101    
102        public DefaultCamelContext() {
103            name = NAME_PREFIX + ++nameSuffix;
104    
105            if (Boolean.getBoolean(JmxSystemPropertyKeys.DISABLED)) {
106                LOG.info("JMX is disabled. Using DefaultLifecycleStrategy.");
107                lifecycleStrategy = new DefaultLifecycleStrategy();
108            } else {
109                try {
110                    LOG.info("JMX enabled. Using InstrumentationLifecycleStrategy.");
111                    lifecycleStrategy = new InstrumentationLifecycleStrategy();
112                } catch (NoClassDefFoundError e) {
113                    // if we can't instantiate the JMX enabled strategy then fallback to default
114                    // could be because of missing .jars on the classpath
115                    LOG.warn("Could not find needed classes for JMX lifecycle strategy."
116                        + " Needed class is in spring-context.jar using Spring 2.5 or newer ("
117                        + " spring-jmx.jar using Spring 2.0.x)."
118                        + " NoClassDefFoundError: " + e.getMessage());
119                } catch (Exception e) {
120                    LOG.warn("Could not create JMX lifecycle strategy, caused by: " + e.getMessage());
121                }
122                // if not created then fallback to default
123                if (lifecycleStrategy == null) {
124                    LOG.warn("Not possible to use JMX lifecycle strategy. Using DefaultLifecycleStrategy instead.");
125                    lifecycleStrategy = new DefaultLifecycleStrategy();
126                }
127            }
128        }
129    
130        /**
131         * Creates the {@link CamelContext} using the given JNDI context as the
132         * registry
133         */
134        public DefaultCamelContext(Context jndiContext) {
135            this();
136            setJndiContext(jndiContext);
137        }
138    
139        /**
140         * Creates the {@link CamelContext} using the given registry
141         */
142        public DefaultCamelContext(Registry registry) {
143            this();
144            this.registry = registry;
145        }
146    
147        public String getName() {
148            return name;
149        }
150    
151        /**
152         * Sets the name of the this context.
153         */
154        public void setName(String name) {
155            this.name = name;
156        }
157    
158        public void addComponent(String componentName, final Component component) {
159            if (component == null) {
160                throw new IllegalArgumentException("Component cannot be null");
161            }
162            synchronized (components) {
163                if (components.containsKey(componentName)) {
164                    throw new IllegalArgumentException("Component previously added: " + componentName);
165                }
166                component.setCamelContext(this);
167                components.put(componentName, component);
168            }
169        }
170    
171        public Component getComponent(String name) {
172            // synchronize the look up and auto create so that 2 threads can't
173            // concurrently auto create the same component.
174            synchronized (components) {
175                Component component = components.get(name);
176                if (component == null && autoCreateComponents) {
177                    try {
178                        component = getComponentResolver().resolveComponent(name, this);
179                        if (component != null) {
180                            addComponent(name, component);
181                            if (isStarted()) {
182                                // If the component is looked up after the context
183                                // is started,
184                                // lets start it up.
185                                startServices(component);
186                            }
187                        }
188                    } catch (Exception e) {
189                        throw new RuntimeCamelException("Could not auto create component: " + name, e);
190                    }
191                }
192                return component;
193            }
194        }
195    
196        public <T extends Component> T getComponent(String name, Class<T> componentType) {
197            Component component = getComponent(name);
198            if (componentType.isInstance(component)) {
199                return componentType.cast(component);
200            } else {
201                throw new IllegalArgumentException("The component is not of type: " + componentType + " but is: "
202                        + component);
203            }
204        }
205    
206        public Component removeComponent(String componentName) {
207            synchronized (components) {
208                return components.remove(componentName);
209            }
210        }
211    
212        public Component getOrCreateComponent(String componentName, Callable<Component> factory) {
213            synchronized (components) {
214                Component component = components.get(componentName);
215                if (component == null) {
216                    try {
217                        component = factory.call();
218                        if (component == null) {
219                            throw new RuntimeCamelException("Factory failed to create the " + componentName
220                                    + " component, it returned null.");
221                        }
222                        components.put(componentName, component);
223                        component.setCamelContext(this);
224                    } catch (Exception e) {
225                        throw new RuntimeCamelException("Factory failed to create the " + componentName
226                                + " component", e);
227                    }
228                }
229                return component;
230            }
231        }
232    
233        // Endpoint Management Methods
234        // -----------------------------------------------------------------------
235    
236        public Collection<Endpoint> getEndpoints() {
237            synchronized (endpoints) {
238                return new ArrayList<Endpoint>(endpoints.values());
239            }
240        }
241    
242        public Collection<Endpoint> getEndpoints(String uri) {
243            Collection<Endpoint> answer = new ArrayList<Endpoint>();
244            Collection<Endpoint> coll;
245            synchronized (endpoints) {
246                Endpoint ep = endpoints.get(uri);
247                if (ep != null) {
248                    answer.add(ep);
249                    return answer;
250                }
251                coll = new ArrayList<Endpoint>(endpoints.values());
252            }
253            for (Endpoint ep : coll) {
254                if (!ep.isSingleton() && uri.equals(ep.getEndpointUri())) {
255                    answer.add(ep);
256                }
257            }
258            return answer;
259        }
260    
261        public Collection<Endpoint> getSingletonEndpoints() {
262            Collection<Endpoint> answer = new ArrayList<Endpoint>();
263            Collection<Endpoint> coll = getEndpoints();
264            for (Endpoint ep : coll) {
265                if (ep.isSingleton()) {
266                    answer.add(ep);
267                }
268            }
269            return answer;
270        }
271    
272        public Endpoint addEndpoint(String uri, Endpoint endpoint) throws Exception {
273            Endpoint oldEndpoint;
274            synchronized (endpoints) {
275                startServices(endpoint);
276                oldEndpoint = endpoints.remove(uri);
277                endpoints.put(CamelContextHelper.getEndpointKey(uri, endpoint), endpoint);
278                if (oldEndpoint != null) {
279                    stopServices(oldEndpoint);
280                }
281            }
282            return oldEndpoint;
283        }
284    
285        public Collection<Endpoint> removeEndpoints(String uri) throws Exception {
286            Collection<Endpoint> answer = new ArrayList<Endpoint>();
287            synchronized (endpoints) {
288                Endpoint oldEndpoint = endpoints.remove(uri);
289                if (oldEndpoint != null) {
290                    answer.add(oldEndpoint);
291                    stopServices(oldEndpoint);
292                } else {
293                    for (Map.Entry entry : endpoints.entrySet()) {
294                        oldEndpoint = (Endpoint)entry.getValue();
295                        if (!oldEndpoint.isSingleton() && uri.equals(oldEndpoint.getEndpointUri())) {
296                            answer.add(oldEndpoint);
297                            stopServices(oldEndpoint);
298                            endpoints.remove(entry.getKey());
299                        }
300                    }
301                }
302            }
303            return answer;
304        }
305    
306        public Endpoint addSingletonEndpoint(String uri, Endpoint endpoint) throws Exception {
307            return addEndpoint(uri, endpoint);
308        }
309    
310        public Endpoint removeSingletonEndpoint(String uri) throws Exception {
311            Collection<Endpoint> answer = removeEndpoints(uri);
312            return (Endpoint) (answer.size() > 0 ? answer.toArray()[0] : null);
313        }
314    
315        public Endpoint getEndpoint(String uri) {
316            Endpoint<?> answer;
317            synchronized (endpoints) {
318                answer = endpoints.get(uri);
319                if (answer == null) {
320                    try {
321    
322                        // Use the URI prefix to find the component.
323                        String splitURI[] = ObjectHelper.splitOnCharacter(uri, ":", 2);
324                        if (splitURI[1] != null) {
325                            String scheme = splitURI[0];
326                            Component<?> component = getComponent(scheme);
327    
328                            // Ask the component to resolve the endpoint.
329                            if (component != null) {
330                                // Have the component create the endpoint if it can.
331                                answer = component.createEndpoint(uri);
332    
333                                if (answer != null && LOG.isDebugEnabled()) {
334                                    LOG.debug(uri + " converted to endpoint: " + answer + " by component: " + component);
335                                }
336                            }
337                        }
338                        if (answer == null) {
339                            answer = createEndpoint(uri);
340                        }
341    
342                        // If it's a singleton then auto register it.
343                        if (answer != null) {
344                            addService(answer);
345    
346                            endpoints.put(CamelContextHelper.getEndpointKey(uri, answer), answer);
347                            lifecycleStrategy.onEndpointAdd(answer);
348                        }
349                    } catch (Exception e) {
350                        LOG.debug("Failed to resolve endpoint " + uri + ". Reason: " + e, e);
351                        throw new ResolveEndpointFailedException(uri, e);
352                    }
353                }
354            }
355            return answer;
356        }
357    
358        public <T extends Endpoint> T getEndpoint(String name, Class<T> endpointType) {
359            Endpoint endpoint = getEndpoint(name);
360            if (endpointType.isInstance(endpoint)) {
361                return endpointType.cast(endpoint);
362            } else {
363                throw new IllegalArgumentException("The endpoint is not of type: " + endpointType + " but is: "
364                        + endpoint);
365            }
366        }
367    
368        // Route Management Methods
369        // -----------------------------------------------------------------------
370        public List<Route> getRoutes() {
371            if (routes == null) {
372                routes = new ArrayList<Route>();
373            }
374            return routes;
375        }
376    
377        public void setRoutes(List<Route> routes) {
378            this.routes = routes;
379            throw new UnsupportedOperationException("overriding existing routes is not supported yet, use addRoutes instead");
380        }
381    
382        public void addRoutes(Collection<Route> routes) throws Exception {
383            if (this.routes == null) {
384                this.routes = new ArrayList<Route>();
385            }
386    
387            if (routes != null) {
388                this.routes.addAll(routes);
389    
390                lifecycleStrategy.onRoutesAdd(routes);
391                if (shouldStartRoutes()) {
392                    startRoutes(routes);
393                }
394            }
395        }
396    
397        public void addRoutes(Routes builder) throws Exception {
398            // lets now add the routes from the builder
399            builder.setContext(this);
400            List<Route> routeList = builder.getRouteList();
401            if (LOG.isDebugEnabled()) {
402                LOG.debug("Adding routes from: " + builder + " routes: " + routeList);
403            }
404            addRoutes(routeList);
405        }
406    
407        public void addRouteDefinitions(Collection<RouteType> routeDefinitions) throws Exception {
408            this.routeDefinitions.addAll(routeDefinitions);
409            if (shouldStartRoutes()) {
410                startRouteDefinitions(routeDefinitions);
411            }
412    
413        }
414    
415        /**
416         * Adds a service, starting it so that it will be stopped with this context
417         */
418        public void addService(Object object) throws Exception {
419            if (object instanceof Service) {
420                Service service = (Service) object;
421                getLifecycleStrategy().onServiceAdd(this, service);
422                service.start();
423                servicesToClose.add(service);
424            }
425        }
426    
427        // Helper methods
428        // -----------------------------------------------------------------------
429    
430        public Language resolveLanguage(String language) {
431            return getLanguageResolver().resolveLanguage(language, this);
432        }
433    
434        // Properties
435        // -----------------------------------------------------------------------
436        public ExchangeConverter getExchangeConverter() {
437            if (exchangeConverter == null) {
438                exchangeConverter = createExchangeConverter();
439            }
440            return exchangeConverter;
441        }
442    
443        public void setExchangeConverter(ExchangeConverter exchangeConverter) {
444            this.exchangeConverter = exchangeConverter;
445        }
446    
447        public TypeConverter getTypeConverter() {
448            if (typeConverter == null) {
449                typeConverter = createTypeConverter();
450            }
451            return typeConverter;
452        }
453    
454        public void setTypeConverter(TypeConverter typeConverter) {
455            this.typeConverter = typeConverter;
456        }
457    
458        public Injector getInjector() {
459            if (injector == null) {
460                injector = createInjector();
461            }
462            return injector;
463        }
464    
465        public void setInjector(Injector injector) {
466            this.injector = injector;
467        }
468    
469        public ComponentResolver getComponentResolver() {
470            if (componentResolver == null) {
471                componentResolver = createComponentResolver();
472            }
473            return componentResolver;
474        }
475    
476        public void setComponentResolver(ComponentResolver componentResolver) {
477            this.componentResolver = componentResolver;
478        }
479    
480        public LanguageResolver getLanguageResolver() {
481            return languageResolver;
482        }
483    
484        public void setLanguageResolver(LanguageResolver languageResolver) {
485            this.languageResolver = languageResolver;
486        }
487    
488        public boolean isAutoCreateComponents() {
489            return autoCreateComponents;
490        }
491    
492        public void setAutoCreateComponents(boolean autoCreateComponents) {
493            this.autoCreateComponents = autoCreateComponents;
494        }
495    
496        public Registry getRegistry() {
497            if (registry == null) {
498                registry = createRegistry();
499            }
500            return registry;
501        }
502    
503        /**
504         * Sets the registry to the given JNDI context
505         *
506         * @param jndiContext is the JNDI context to use as the registry
507         *
508         * @see #setRegistry(org.apache.camel.spi.Registry)
509         */
510        public void setJndiContext(Context jndiContext) {
511            setRegistry(new JndiRegistry(jndiContext));
512        }
513    
514        public void setRegistry(Registry registry) {
515            this.registry = registry;
516        }
517    
518        public LifecycleStrategy getLifecycleStrategy() {
519            return lifecycleStrategy;
520        }
521    
522        public void setLifecycleStrategy(LifecycleStrategy lifecycleStrategy) {
523            this.lifecycleStrategy = lifecycleStrategy;
524        }
525    
526        public List<RouteType> getRouteDefinitions() {
527            return routeDefinitions;
528        }
529    
530        public List<InterceptStrategy> getInterceptStrategies() {
531            return interceptStrategies;
532        }
533    
534        public void setInterceptStrategies(List<InterceptStrategy> interceptStrategies) {
535            this.interceptStrategies = interceptStrategies;
536        }
537    
538        public void addInterceptStrategy(InterceptStrategy interceptStrategy) {
539            getInterceptStrategies().add(interceptStrategy);
540        }
541    
542        /**
543         * Returns true if tracing has been enabled or disabled via the {@link #setTrace(Boolean)} method
544         * or it has not been specified then default to the <b>camel.trace</b> system property
545         */
546        public boolean getTrace() {
547            final Boolean value = getTracing();
548            if (value != null) {
549                return value;
550            } else {
551                return SystemHelper.isSystemProperty("camel.trace");
552            }
553        }
554    
555        public Boolean getTracing() {
556            return trace;
557        }
558    
559        public void setTrace(Boolean trace) {
560            this.trace = trace;
561        }
562    
563        /**
564         * Returns the delay in millis if delaying has been enabled or disabled via the {@link #setDelay(Long)} method
565         * or it has not been specified then default to the <b>camel.delay</b> system property
566         */
567        public long getDelay() {
568            final Long value = getDelaying();
569            if (value != null) {
570                return value;
571            } else {
572                String prop = SystemHelper.getSystemProperty("camel.delay");
573                return prop != null ? Long.getLong(prop) : 0;
574            }
575        }
576    
577        public Long getDelaying() {
578            return delay;
579        }
580    
581        public void setDelay(Long delay) {
582            this.delay = delay;
583        }
584    
585        public <E extends Exchange> ProducerTemplate<E> createProducerTemplate() {
586            return new DefaultProducerTemplate<E>(this);
587        }
588    
589        public ErrorHandlerBuilder getErrorHandlerBuilder() {
590            return errorHandlerBuilder;
591        }
592    
593        /**
594         * Sets the default error handler builder which is inherited by the routes
595         */
596        public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) {
597            this.errorHandlerBuilder = errorHandlerBuilder;
598        }
599    
600        // Implementation methods
601        // -----------------------------------------------------------------------
602    
603        protected void doStart() throws Exception {
604            LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") is starting");
605    
606            if (getTrace()) {
607                // only add a new tracer if not already configued
608                if (Tracer.getTracer(this) == null) {
609                    Tracer tracer = new Tracer();
610                    // lets see if we have a formatter if so use it
611                    TraceFormatter formatter = this.getRegistry().lookup("traceFormatter", TraceFormatter.class);
612                    if (formatter != null) {
613                        tracer.setFormatter(formatter);
614                    }
615                    addInterceptStrategy(tracer);
616                }
617            }
618    
619            if (getDelay() > 0) {
620                // only add a new delayer if not already configued
621                if (Delayer.getDelayer(this) == null) {
622                    addInterceptStrategy(new Delayer(getDelay()));
623                }
624            }
625    
626            lifecycleStrategy.onContextStart(this);
627    
628            forceLazyInitialization();
629            if (components != null) {
630                for (Component component : components.values()) {
631                    startServices(component);
632                }
633            }
634            startRouteDefinitions(routeDefinitions);
635            startRoutes(routes);
636            
637            LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") started");
638        }
639    
640        protected void startRouteDefinitions(Collection<RouteType> list) throws Exception {
641            if (list != null) {
642                Collection<Route> routes = new ArrayList<Route>();
643                for (RouteType route : list) {
644                    route.addRoutes(this, routes);
645                }
646                addRoutes(routes);
647            }
648        }
649    
650        protected void doStop() throws Exception {
651            stopServices(servicesToClose);
652            if (components != null) {
653                for (Component component : components.values()) {
654                    stopServices(component);
655                }
656            }
657        }
658    
659        protected void startRoutes(Collection<Route> routeList) throws Exception {
660            if (routeList != null) {
661                for (Route<Exchange> route : routeList) {
662                    List<Service> services = route.getServicesForRoute();
663                    for (Service service : services) {
664                        addService(service);
665                    }
666                }
667            }
668        }
669    
670        /**
671         * Lets force some lazy initialization to occur upfront before we start any
672         * components and create routes
673         */
674        protected void forceLazyInitialization() {
675            getExchangeConverter();
676            getInjector();
677            getLanguageResolver();
678            getTypeConverter();
679        }
680    
681        /**
682         * Lazily create a default implementation
683         */
684        protected ExchangeConverter createExchangeConverter() {
685            return new DefaultExchangeConverter();
686        }
687    
688        /**
689         * Lazily create a default implementation
690         */
691        protected TypeConverter createTypeConverter() {
692            return new DefaultTypeConverter(getInjector());
693        }
694    
695        /**
696         * Lazily create a default implementation
697         */
698        protected Injector createInjector() {
699            FactoryFinder finder = createFactoryFinder();
700            try {
701                return (Injector) finder.newInstance("Injector");
702            } catch (NoFactoryAvailableException e) {
703                // lets use the default
704                return new ReflectionInjector();
705            } catch (IllegalAccessException e) {
706                throw new RuntimeCamelException(e);
707            } catch (InstantiationException e) {
708                throw new RuntimeCamelException(e);
709            } catch (IOException e) {
710                throw new RuntimeCamelException(e);
711            } catch (ClassNotFoundException e) {
712                throw new RuntimeCamelException(e);
713            }
714        }
715    
716        /**
717         * Lazily create a default implementation
718         */
719        protected ComponentResolver createComponentResolver() {
720            return new DefaultComponentResolver();
721        }
722    
723        /**
724         * Lazily create a default implementation
725         */
726        protected Registry createRegistry() {
727            return new JndiRegistry();
728        }
729    
730        /**
731         * A pluggable strategy to allow an endpoint to be created without requiring
732         * a component to be its factory, such as for looking up the URI inside some
733         * {@link Registry}
734         *
735         * @param uri the uri for the endpoint to be created
736         * @return the newly created endpoint or null if it could not be resolved
737         */
738        protected Endpoint createEndpoint(String uri) {
739            Object value = getRegistry().lookup(uri);
740            if (value instanceof Endpoint) {
741                return (Endpoint) value;
742            } else if (value instanceof Processor) {
743                return new ProcessorEndpoint(uri, this, (Processor) value);
744            } else if (value != null) {
745                return convertBeanToEndpoint(uri, value);
746            }
747            return null;
748        }
749    
750        /**
751         * Attempt to convert the bean from a {@link Registry} to an endpoint using
752         * some kind of transformation or wrapper
753         *
754         * @param uri  the uri for the endpoint (and name in the registry)
755         * @param bean the bean to be converted to an endpoint, which will be not null
756         * @return a new endpoint
757         */
758        protected Endpoint convertBeanToEndpoint(String uri, Object bean) {
759            throw new IllegalArgumentException("uri: " + uri + " bean: " + bean
760                    + " could not be converted to an Endpoint");
761        }
762    
763        /**
764         * Should we start newly added routes?
765         */
766        protected boolean shouldStartRoutes() {
767            return isStarted() && !isStarting();
768        }
769    
770        public void setDataFormats(Map<String, DataFormatType> dataFormats) {
771            this.dataFormats = dataFormats;
772        }
773    
774        public Map<String, DataFormatType> getDataFormats() {
775            return dataFormats;
776        }
777        
778        public void setFactoryFinderClass(Class<? extends FactoryFinder> finderClass) {
779            factoryFinderClass = finderClass;
780        }
781    
782        public FactoryFinder createFactoryFinder() {
783            try {
784                return factoryFinderClass.newInstance();
785            } catch (Exception e) {
786                throw new RuntimeCamelException(e);
787            }
788        }
789    
790        public FactoryFinder createFactoryFinder(String path) {
791            try {
792                Constructor<? extends FactoryFinder> constructor;
793                constructor = factoryFinderClass.getConstructor(String.class);
794                return constructor.newInstance(path);
795            } catch (Exception e) {
796                throw new RuntimeCamelException(e);
797            }
798            
799        }
800    }