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