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