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 }