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