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.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 * Represents the context used to configure routes and the policies to use.
072 *
073 * @version $Revision: 766635 $
074 */
075 public class DefaultCamelContext extends ServiceSupport implements CamelContext, Service {
076 private static final transient Log LOG = LogFactory.getLog(DefaultCamelContext.class);
077 private static final String NAME_PREFIX = "camel-";
078 private static int nameSuffix;
079 private boolean routeDefinitionInitiated;
080 private String name;
081 private final Map<String, Endpoint> endpoints = new HashMap<String, Endpoint>();
082 private final Map<String, Component> components = new HashMap<String, Component>();
083 private List<Route> routes;
084 private List<Service> servicesToClose = new ArrayList<Service>();
085 private TypeConverter typeConverter;
086 private ExchangeConverter exchangeConverter;
087 private Injector injector;
088 private ComponentResolver componentResolver;
089 private boolean autoCreateComponents = true;
090 private LanguageResolver languageResolver = new DefaultLanguageResolver();
091 private Registry registry;
092 private LifecycleStrategy lifecycleStrategy;
093 private List<RouteType> routeDefinitions = new ArrayList<RouteType>();
094 private List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
095 private Boolean trace;
096 private Long delay;
097 private ErrorHandlerBuilder errorHandlerBuilder;
098 private Map<String, DataFormatType> dataFormats = new HashMap<String, DataFormatType>();
099 private Map<String, String> properties = new HashMap<String, String>();
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() || isStarting()) {
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 Map<String, Endpoint> getEndpointMap() {
243 synchronized (endpoints) {
244 return new HashMap<String, Endpoint>(endpoints);
245 }
246 }
247
248 public Collection<Endpoint> getEndpoints(String uri) {
249 Collection<Endpoint> answer = new ArrayList<Endpoint>();
250 Collection<Endpoint> coll;
251 synchronized (endpoints) {
252 Endpoint ep = endpoints.get(uri);
253 if (ep != null) {
254 answer.add(ep);
255 return answer;
256 }
257 coll = new ArrayList<Endpoint>(endpoints.values());
258 }
259 for (Endpoint ep : coll) {
260 if (!ep.isSingleton() && uri.equals(ep.getEndpointUri())) {
261 answer.add(ep);
262 }
263 }
264 return answer;
265 }
266
267 public Collection<Endpoint> getSingletonEndpoints() {
268 Collection<Endpoint> answer = new ArrayList<Endpoint>();
269 Collection<Endpoint> coll = getEndpoints();
270 for (Endpoint ep : coll) {
271 if (ep.isSingleton()) {
272 answer.add(ep);
273 }
274 }
275 return answer;
276 }
277
278 public Endpoint addEndpoint(String uri, Endpoint endpoint) throws Exception {
279 Endpoint oldEndpoint;
280 synchronized (endpoints) {
281 startServices(endpoint);
282 oldEndpoint = endpoints.remove(uri);
283 endpoints.put(getEndpointKey(uri, endpoint), endpoint);
284 if (oldEndpoint != null) {
285 stopServices(oldEndpoint);
286 }
287 }
288 return oldEndpoint;
289 }
290
291 public Collection<Endpoint> removeEndpoints(String uri) throws Exception {
292 Collection<Endpoint> answer = new ArrayList<Endpoint>();
293 synchronized (endpoints) {
294 Endpoint oldEndpoint = endpoints.remove(uri);
295 if (oldEndpoint != null) {
296 answer.add(oldEndpoint);
297 stopServices(oldEndpoint);
298 } else {
299 for (Map.Entry entry : endpoints.entrySet()) {
300 oldEndpoint = (Endpoint)entry.getValue();
301 if (!oldEndpoint.isSingleton() && uri.equals(oldEndpoint.getEndpointUri())) {
302 answer.add(oldEndpoint);
303 stopServices(oldEndpoint);
304 endpoints.remove(entry.getKey());
305 }
306 }
307 }
308 }
309 return answer;
310 }
311
312 public Endpoint addSingletonEndpoint(String uri, Endpoint endpoint) throws Exception {
313 return addEndpoint(uri, endpoint);
314 }
315
316 public Endpoint removeSingletonEndpoint(String uri) throws Exception {
317 Collection<Endpoint> answer = removeEndpoints(uri);
318 return (Endpoint) (answer.size() > 0 ? answer.toArray()[0] : null);
319 }
320
321 public Endpoint getEndpoint(String uri) {
322 Endpoint<?> answer;
323 synchronized (endpoints) {
324 answer = endpoints.get(uri);
325 if (answer == null) {
326 try {
327
328 // Use the URI prefix to find the component.
329 String splitURI[] = ObjectHelper.splitOnCharacter(uri, ":", 2);
330 if (splitURI[1] != null) {
331 String scheme = splitURI[0];
332 Component<?> component = getComponent(scheme);
333
334 // Ask the component to resolve the endpoint.
335 if (component != null) {
336 // Have the component create the endpoint if it can.
337 answer = component.createEndpoint(uri);
338
339 if (answer != null && LOG.isDebugEnabled()) {
340 LOG.debug(uri + " converted to endpoint: " + answer + " by component: " + component);
341 }
342 }
343 }
344 if (answer == null) {
345 answer = createEndpoint(uri);
346 }
347
348 // If it's a singleton then auto register it.
349 if (answer != null) {
350 addService(answer);
351
352 endpoints.put(getEndpointKey(uri, answer), answer);
353 lifecycleStrategy.onEndpointAdd(answer);
354 }
355 } catch (Exception e) {
356 LOG.debug("Failed to resolve endpoint " + uri + ". Reason: " + e, e);
357 throw new ResolveEndpointFailedException(uri, e);
358 }
359 }
360 }
361 return answer;
362 }
363
364 public <T extends Endpoint> T getEndpoint(String name, Class<T> endpointType) {
365 Endpoint endpoint = getEndpoint(name);
366 if (endpointType.isInstance(endpoint)) {
367 return endpointType.cast(endpoint);
368 } else {
369 throw new IllegalArgumentException("The endpoint is not of type: " + endpointType + " but is: "
370 + endpoint);
371 }
372 }
373
374 // Route Management Methods
375 // -----------------------------------------------------------------------
376 public List<Route> getRoutes() {
377 if (routes == null) {
378 routes = new ArrayList<Route>();
379 }
380 return routes;
381 }
382
383 public void setRoutes(List<Route> routes) {
384 this.routes = routes;
385 throw new UnsupportedOperationException("overriding existing routes is not supported yet, use addRoutes instead");
386 }
387
388 public void addRoutes(Collection<Route> routes) throws Exception {
389 if (this.routes == null) {
390 this.routes = new ArrayList<Route>();
391 }
392
393 if (routes != null) {
394 this.routes.addAll(routes);
395 lifecycleStrategy.onRoutesAdd(routes);
396 if (shouldStartRoutes()) {
397 startRoutes(routes);
398 }
399 }
400 }
401
402 public void addRoutes(Routes builder) throws Exception {
403 // lets now add the routes from the builder
404 builder.setContext(this);
405 List<Route> routeList = builder.getRouteList();
406 if (LOG.isDebugEnabled()) {
407 LOG.debug("Adding routes from: " + builder + " routes: " + routeList);
408 }
409 addRoutes(routeList);
410 }
411
412 public void addRouteDefinitions(Collection<RouteType> routeDefinitions) throws Exception {
413 this.routeDefinitions.addAll(routeDefinitions);
414 if (shouldStartRoutes()) {
415 startRouteDefinitions(routeDefinitions);
416 }
417
418 }
419
420 /**
421 * Adds a service, starting it so that it will be stopped with this context
422 */
423 public void addService(Object object) throws Exception {
424 if (object instanceof Service) {
425 Service service = (Service) object;
426 getLifecycleStrategy().onServiceAdd(this, service);
427 service.start();
428 servicesToClose.add(service);
429 }
430 }
431
432 // Helper methods
433 // -----------------------------------------------------------------------
434
435 public Language resolveLanguage(String language) {
436 return getLanguageResolver().resolveLanguage(language, this);
437 }
438
439 // Properties
440 // -----------------------------------------------------------------------
441 public ExchangeConverter getExchangeConverter() {
442 if (exchangeConverter == null) {
443 exchangeConverter = createExchangeConverter();
444 }
445 return exchangeConverter;
446 }
447
448 public void setExchangeConverter(ExchangeConverter exchangeConverter) {
449 this.exchangeConverter = exchangeConverter;
450 }
451
452 public TypeConverter getTypeConverter() {
453 if (typeConverter == null) {
454 typeConverter = createTypeConverter();
455 }
456 return typeConverter;
457 }
458
459 public void setTypeConverter(TypeConverter typeConverter) {
460 this.typeConverter = typeConverter;
461 }
462
463 public Injector getInjector() {
464 if (injector == null) {
465 injector = createInjector();
466 }
467 return injector;
468 }
469
470 public void setInjector(Injector injector) {
471 this.injector = injector;
472 }
473
474 public ComponentResolver getComponentResolver() {
475 if (componentResolver == null) {
476 componentResolver = createComponentResolver();
477 }
478 return componentResolver;
479 }
480
481 public void setComponentResolver(ComponentResolver componentResolver) {
482 this.componentResolver = componentResolver;
483 }
484
485 public LanguageResolver getLanguageResolver() {
486 return languageResolver;
487 }
488
489 public void setLanguageResolver(LanguageResolver languageResolver) {
490 this.languageResolver = languageResolver;
491 }
492
493 public boolean isAutoCreateComponents() {
494 return autoCreateComponents;
495 }
496
497 public void setAutoCreateComponents(boolean autoCreateComponents) {
498 this.autoCreateComponents = autoCreateComponents;
499 }
500
501 public Registry getRegistry() {
502 if (registry == null) {
503 registry = createRegistry();
504 }
505 return registry;
506 }
507
508 /**
509 * Sets the registry to the given JNDI context
510 *
511 * @param jndiContext is the JNDI context to use as the registry
512 *
513 * @see #setRegistry(org.apache.camel.spi.Registry)
514 */
515 public void setJndiContext(Context jndiContext) {
516 setRegistry(new JndiRegistry(jndiContext));
517 }
518
519 public void setRegistry(Registry registry) {
520 this.registry = registry;
521 }
522
523 public LifecycleStrategy getLifecycleStrategy() {
524 return lifecycleStrategy;
525 }
526
527 public void setLifecycleStrategy(LifecycleStrategy lifecycleStrategy) {
528 this.lifecycleStrategy = lifecycleStrategy;
529 }
530
531 public List<RouteType> getRouteDefinitions() {
532 return routeDefinitions;
533 }
534
535 public List<InterceptStrategy> getInterceptStrategies() {
536 return interceptStrategies;
537 }
538
539 public void setInterceptStrategies(List<InterceptStrategy> interceptStrategies) {
540 this.interceptStrategies = interceptStrategies;
541 }
542
543 public void addInterceptStrategy(InterceptStrategy interceptStrategy) {
544 getInterceptStrategies().add(interceptStrategy);
545 }
546
547 /**
548 * Returns true if tracing has been enabled or disabled via the {@link #setTrace(Boolean)} method
549 * or it has not been specified then default to the <b>camel.trace</b> system property
550 */
551 public boolean getTrace() {
552 final Boolean value = getTracing();
553 if (value != null) {
554 return value;
555 } else {
556 return SystemHelper.isSystemProperty("camel.trace");
557 }
558 }
559
560 public Boolean getTracing() {
561 return trace;
562 }
563
564 public void setTrace(Boolean trace) {
565 this.trace = trace;
566 }
567
568 /**
569 * Returns the delay in millis if delaying has been enabled or disabled via the {@link #setDelay(Long)} method
570 * or it has not been specified then default to the <b>camel.delay</b> system property
571 */
572 public long getDelay() {
573 final Long value = getDelaying();
574 if (value != null) {
575 return value;
576 } else {
577 String prop = SystemHelper.getSystemProperty("camel.delay");
578 return prop != null ? Long.getLong(prop) : 0;
579 }
580 }
581
582 public Long getDelaying() {
583 return delay;
584 }
585
586 public void setDelay(Long delay) {
587 this.delay = delay;
588 }
589
590 public <E extends Exchange> ProducerTemplate<E> createProducerTemplate() {
591 return new DefaultProducerTemplate<E>(this);
592 }
593
594 public ErrorHandlerBuilder getErrorHandlerBuilder() {
595 return errorHandlerBuilder;
596 }
597
598 /**
599 * Sets the default error handler builder which is inherited by the routes
600 */
601 public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) {
602 this.errorHandlerBuilder = errorHandlerBuilder;
603 }
604
605 public void start() throws Exception {
606 super.start();
607
608 // the context is now considered started (i.e. isStarted() == true))
609 // starting routes is done after, not during context startup
610 synchronized (this) {
611 startRoutes(routes);
612 }
613
614 LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") started");
615 }
616
617 // Implementation methods
618 // -----------------------------------------------------------------------
619
620 protected void doStart() throws Exception {
621 LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") is starting");
622
623 if (getTrace()) {
624 // only add a new tracer if not already configued
625 if (Tracer.getTracer(this) == null) {
626 Tracer tracer = new Tracer();
627 // lets see if we have a formatter if so use it
628 TraceFormatter formatter = this.getRegistry().lookup("traceFormatter", TraceFormatter.class);
629 if (formatter != null) {
630 tracer.setFormatter(formatter);
631 }
632 addInterceptStrategy(tracer);
633 }
634 }
635
636 if (getDelay() > 0) {
637 // only add a new delayer if not already configued
638 if (Delayer.getDelayer(this) == null) {
639 addInterceptStrategy(new Delayer(getDelay()));
640 }
641 }
642
643 try {
644 lifecycleStrategy.onContextStart(this);
645 } catch (Exception e) {
646 // not all containers allow access to its MBeanServer (such as OC4j)
647 LOG.warn("Cannot start lifecycleStrategy: " + lifecycleStrategy + ". Cause: " + e.getMessage());
648 if (lifecycleStrategy instanceof InstrumentationLifecycleStrategy) {
649 // fallback to non JMX lifecycle to allow Camel to startup
650 LOG.warn("Will fallback to use default (non JMX) lifecycle strategy");
651 lifecycleStrategy = new DefaultLifecycleStrategy();
652 lifecycleStrategy.onContextStart(this);
653 }
654 }
655
656 forceLazyInitialization();
657 if (components != null) {
658 for (Component component : components.values()) {
659 startServices(component);
660 }
661 }
662 // To avoid initiating the routeDefinitions after stopping the camel context
663 if (!routeDefinitionInitiated) {
664 startRouteDefinitions(routeDefinitions);
665 routeDefinitionInitiated = true;
666 }
667 }
668
669 protected void startRouteDefinitions(Collection<RouteType> list) throws Exception {
670 if (list != null) {
671 Collection<Route> routes = new ArrayList<Route>();
672 for (RouteType route : list) {
673 route.addRoutes(this, routes);
674 }
675 addRoutes(routes);
676 }
677 }
678
679 protected void doStop() throws Exception {
680 stopServices(servicesToClose);
681 if (components != null) {
682 for (Component component : components.values()) {
683 stopServices(component);
684 }
685 }
686 servicesToClose.clear();
687 }
688
689 protected void startRoutes(Collection<Route> routeList) throws Exception {
690 if (routeList != null) {
691 for (Route<Exchange> route : routeList) {
692 List<Service> services = route.getServicesForRoute();
693 for (Service service : services) {
694 addService(service);
695 }
696 }
697 }
698 }
699
700 /**
701 * Lets force some lazy initialization to occur upfront before we start any
702 * components and create routes
703 */
704 protected void forceLazyInitialization() {
705 getExchangeConverter();
706 getInjector();
707 getLanguageResolver();
708 getTypeConverter();
709 }
710
711 /**
712 * Lazily create a default implementation
713 */
714 protected ExchangeConverter createExchangeConverter() {
715 return new DefaultExchangeConverter();
716 }
717
718 /**
719 * Lazily create a default implementation
720 */
721 protected TypeConverter createTypeConverter() {
722 return new DefaultTypeConverter(getInjector());
723 }
724
725 /**
726 * Lazily create a default implementation
727 */
728 protected Injector createInjector() {
729 FactoryFinder finder = createFactoryFinder();
730 try {
731 return (Injector) finder.newInstance("Injector");
732 } catch (NoFactoryAvailableException e) {
733 // lets use the default
734 return new ReflectionInjector();
735 } catch (IllegalAccessException e) {
736 throw new RuntimeCamelException(e);
737 } catch (InstantiationException e) {
738 throw new RuntimeCamelException(e);
739 } catch (IOException e) {
740 throw new RuntimeCamelException(e);
741 } catch (ClassNotFoundException e) {
742 throw new RuntimeCamelException(e);
743 }
744 }
745
746 /**
747 * Lazily create a default implementation
748 */
749 protected ComponentResolver createComponentResolver() {
750 return new DefaultComponentResolver();
751 }
752
753 /**
754 * Lazily create a default implementation
755 */
756 protected Registry createRegistry() {
757 return new JndiRegistry();
758 }
759
760 /**
761 * A pluggable strategy to allow an endpoint to be created without requiring
762 * a component to be its factory, such as for looking up the URI inside some
763 * {@link Registry}
764 *
765 * @param uri the uri for the endpoint to be created
766 * @return the newly created endpoint or null if it could not be resolved
767 */
768 protected Endpoint createEndpoint(String uri) {
769 Object value = getRegistry().lookup(uri);
770 if (value instanceof Endpoint) {
771 return (Endpoint) value;
772 } else if (value instanceof Processor) {
773 return new ProcessorEndpoint(uri, this, (Processor) value);
774 } else if (value != null) {
775 return convertBeanToEndpoint(uri, value);
776 }
777 return null;
778 }
779
780 /**
781 * Attempt to convert the bean from a {@link Registry} to an endpoint using
782 * some kind of transformation or wrapper
783 *
784 * @param uri the uri for the endpoint (and name in the registry)
785 * @param bean the bean to be converted to an endpoint, which will be not null
786 * @return a new endpoint
787 */
788 protected Endpoint convertBeanToEndpoint(String uri, Object bean) {
789 throw new IllegalArgumentException("uri: " + uri + " bean: " + bean
790 + " could not be converted to an Endpoint");
791 }
792
793 /**
794 * Should we start newly added routes?
795 */
796 protected boolean shouldStartRoutes() {
797 return isStarted() && !isStarting();
798 }
799
800 public void setDataFormats(Map<String, DataFormatType> dataFormats) {
801 this.dataFormats = dataFormats;
802 }
803
804 public Map<String, DataFormatType> getDataFormats() {
805 return dataFormats;
806 }
807
808 public void setFactoryFinderClass(Class<? extends FactoryFinder> finderClass) {
809 factoryFinderClass = finderClass;
810 }
811
812 public Map<String, String> getProperties() {
813 return properties;
814 }
815
816 public void setProperties(Map<String, String> properties) {
817 this.properties = properties;
818 }
819
820 public FactoryFinder createFactoryFinder() {
821 try {
822 return factoryFinderClass.newInstance();
823 } catch (Exception e) {
824 throw new RuntimeCamelException(e);
825 }
826 }
827
828 public FactoryFinder createFactoryFinder(String path) {
829 try {
830 Constructor<? extends FactoryFinder> constructor;
831 constructor = factoryFinderClass.getConstructor(String.class);
832 return constructor.newInstance(path);
833 } catch (Exception e) {
834 throw new RuntimeCamelException(e);
835 }
836
837 }
838
839
840 protected synchronized String getEndpointKey(String uri, Endpoint endpoint) {
841 if (endpoint.isSingleton()) {
842 return uri;
843 } else {
844 // lets try find the first endpoint key which is free
845 for (int counter = 0; true; counter++) {
846 String key = (counter > 0) ? uri + ":" + counter : uri;
847 if (!endpoints.containsKey(key)) {
848 return key;
849 }
850 }
851 }
852 }
853
854 }