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.TreeMap; 027 import java.util.concurrent.Callable; 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.IsSingleton; 034 import org.apache.camel.NoFactoryAvailableException; 035 import org.apache.camel.Processor; 036 import org.apache.camel.ProducerTemplate; 037 import org.apache.camel.ResolveEndpointFailedException; 038 import org.apache.camel.Route; 039 import org.apache.camel.Routes; 040 import org.apache.camel.RuntimeCamelException; 041 import org.apache.camel.Service; 042 import org.apache.camel.ServiceStatus; 043 import org.apache.camel.TypeConverter; 044 import org.apache.camel.builder.ErrorHandlerBuilder; 045 import org.apache.camel.impl.converter.DefaultTypeConverter; 046 import org.apache.camel.management.InstrumentationLifecycleStrategy; 047 import org.apache.camel.management.JmxSystemPropertyKeys; 048 import org.apache.camel.model.RouteDefinition; 049 import org.apache.camel.model.dataformat.DataFormatDefinition; 050 import org.apache.camel.processor.interceptor.Delayer; 051 import org.apache.camel.processor.interceptor.TraceFormatter; 052 import org.apache.camel.processor.interceptor.Tracer; 053 import org.apache.camel.spi.ClassResolver; 054 import org.apache.camel.spi.ComponentResolver; 055 import org.apache.camel.spi.ExchangeConverter; 056 import org.apache.camel.spi.Injector; 057 import org.apache.camel.spi.InterceptStrategy; 058 import org.apache.camel.spi.Language; 059 import org.apache.camel.spi.LanguageResolver; 060 import org.apache.camel.spi.LifecycleStrategy; 061 import org.apache.camel.spi.PackageScanClassResolver; 062 import org.apache.camel.spi.Registry; 063 import org.apache.camel.spi.RouteContext; 064 import org.apache.camel.spi.TypeConverterRegistry; 065 import org.apache.camel.util.FactoryFinder; 066 import org.apache.camel.util.ObjectHelper; 067 import org.apache.camel.util.ReflectionInjector; 068 import org.apache.camel.util.SystemHelper; 069 import org.apache.commons.logging.Log; 070 import org.apache.commons.logging.LogFactory; 071 072 import static org.apache.camel.util.ServiceHelper.startServices; 073 import static org.apache.camel.util.ServiceHelper.stopServices; 074 075 /** 076 * Represents the context used to configure routes and the policies to use. 077 * 078 * @version $Revision: 752893 $ 079 */ 080 public class DefaultCamelContext extends ServiceSupport implements CamelContext, Service { 081 private static final transient Log LOG = LogFactory.getLog(DefaultCamelContext.class); 082 private static final String NAME_PREFIX = "camel-"; 083 private static int nameSuffix; 084 085 private String name; 086 private final Map<String, Endpoint> endpoints = new HashMap<String, Endpoint>(); 087 private final Map<String, Component> components = new HashMap<String, Component>(); 088 private List<Route> routes; 089 private final List<Service> servicesToClose = new ArrayList<Service>(); 090 private TypeConverter typeConverter; 091 private TypeConverterRegistry typeConverterRegistry; 092 private ExchangeConverter exchangeConverter; 093 private Injector injector; 094 private ComponentResolver componentResolver; 095 private boolean autoCreateComponents = true; 096 private LanguageResolver languageResolver = new DefaultLanguageResolver(); 097 private final Map<String, Language> languages = new HashMap<String, Language>(); 098 private Registry registry; 099 private LifecycleStrategy lifecycleStrategy; 100 private final List<RouteDefinition> routeDefinitions = new ArrayList<RouteDefinition>(); 101 private List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>(); 102 private Boolean trace; 103 private Long delay; 104 private ErrorHandlerBuilder errorHandlerBuilder; 105 private Map<String, DataFormatDefinition> dataFormats = new HashMap<String, DataFormatDefinition>(); 106 private Map<String, String> properties = new HashMap<String, String>(); 107 private Class<? extends FactoryFinder> factoryFinderClass = FactoryFinder.class; 108 private final Map<String, RouteService> routeServices = new HashMap<String, RouteService>(); 109 private ClassResolver classResolver; 110 private PackageScanClassResolver packageScanClassResolver; 111 112 public DefaultCamelContext() { 113 name = NAME_PREFIX + ++nameSuffix; 114 115 if (Boolean.getBoolean(JmxSystemPropertyKeys.DISABLED)) { 116 LOG.info("JMX is disabled. Using DefaultLifecycleStrategy."); 117 lifecycleStrategy = new DefaultLifecycleStrategy(); 118 } else { 119 try { 120 LOG.info("JMX enabled. Using InstrumentationLifecycleStrategy."); 121 lifecycleStrategy = new InstrumentationLifecycleStrategy(); 122 } catch (NoClassDefFoundError e) { 123 // if we can't instantiate the JMX enabled strategy then fallback to default 124 // could be because of missing .jars on the classpath 125 LOG.warn("Could not find needed classes for JMX lifecycle strategy." 126 + " Needed class is in spring-context.jar using Spring 2.5 or newer (" 127 + " spring-jmx.jar using Spring 2.0.x)." 128 + " NoClassDefFoundError: " + e.getMessage()); 129 } catch (Exception e) { 130 LOG.warn("Could not create JMX lifecycle strategy, caused by: " + e.getMessage()); 131 } 132 // if not created then fallback to default 133 if (lifecycleStrategy == null) { 134 LOG.warn("Cannot use JMX lifecycle strategy. Using DefaultLifecycleStrategy instead."); 135 lifecycleStrategy = new DefaultLifecycleStrategy(); 136 } 137 } 138 139 if (classResolver == null) { 140 classResolver = new DefaultClassResolver(); 141 } 142 143 if (packageScanClassResolver == null) { 144 // use WebSphere specific resolver if running on WebSphere 145 if (WebSpherePacakageScanClassResolver.isWebSphereClassLoader(this.getClass().getClassLoader())) { 146 LOG.info("Using WebSphere specific PackageScanClassResolver"); 147 packageScanClassResolver = new WebSpherePacakageScanClassResolver("META-INF/services/org/apache/camel/TypeConverter"); 148 } else { 149 packageScanClassResolver = new DefaultPackageScanClassResolver(); 150 } 151 152 } 153 } 154 155 /** 156 * Creates the {@link CamelContext} using the given JNDI context as the 157 * registry 158 */ 159 public DefaultCamelContext(Context jndiContext) { 160 this(); 161 setJndiContext(jndiContext); 162 } 163 164 /** 165 * Creates the {@link CamelContext} using the given registry 166 */ 167 public DefaultCamelContext(Registry registry) { 168 this(); 169 this.registry = registry; 170 } 171 172 public String getName() { 173 return name; 174 } 175 176 /** 177 * Sets the name of the this context. 178 */ 179 public void setName(String name) { 180 this.name = name; 181 } 182 183 public void addComponent(String componentName, final Component component) { 184 ObjectHelper.notNull(component, "component"); 185 synchronized (components) { 186 if (components.containsKey(componentName)) { 187 throw new IllegalArgumentException("Cannot add component as its already previously added: " + componentName); 188 } 189 component.setCamelContext(this); 190 components.put(componentName, component); 191 } 192 } 193 194 public Component getComponent(String name) { 195 // synchronize the look up and auto create so that 2 threads can't 196 // concurrently auto create the same component. 197 synchronized (components) { 198 Component component = components.get(name); 199 if (component == null && autoCreateComponents) { 200 try { 201 component = getComponentResolver().resolveComponent(name, this); 202 if (component != null) { 203 addComponent(name, component); 204 if (isStarted()) { 205 // If the component is looked up after the context is started, 206 // lets start it up. 207 startServices(component); 208 } 209 } 210 } catch (Exception e) { 211 throw new RuntimeCamelException("Could not auto create component: " + name, e); 212 } 213 } 214 return component; 215 } 216 } 217 218 public <T extends Component> T getComponent(String name, Class<T> componentType) { 219 Component component = getComponent(name); 220 if (componentType.isInstance(component)) { 221 return componentType.cast(component); 222 } else { 223 throw new IllegalArgumentException("The component is not of type: " + componentType + " but is: " 224 + component); 225 } 226 } 227 228 public Component removeComponent(String componentName) { 229 synchronized (components) { 230 return components.remove(componentName); 231 } 232 } 233 234 public Component getOrCreateComponent(String componentName, Callable<Component> factory) { 235 synchronized (components) { 236 Component component = components.get(componentName); 237 if (component == null) { 238 try { 239 component = factory.call(); 240 if (component == null) { 241 throw new RuntimeCamelException("Factory failed to create the " + componentName 242 + " component, it returned null."); 243 } 244 components.put(componentName, component); 245 component.setCamelContext(this); 246 } catch (Exception e) { 247 throw new RuntimeCamelException("Factory failed to create the " + componentName 248 + " component", e); 249 } 250 } 251 return component; 252 } 253 } 254 255 // Endpoint Management Methods 256 // ----------------------------------------------------------------------- 257 258 public Collection<Endpoint> getEndpoints() { 259 synchronized (endpoints) { 260 return new ArrayList<Endpoint>(endpoints.values()); 261 } 262 } 263 264 public Map<String, Endpoint> getEndpointMap() { 265 synchronized (endpoints) { 266 return new TreeMap<String, Endpoint>(endpoints); 267 } 268 } 269 270 public Collection<Endpoint> getEndpoints(String uri) { 271 Collection<Endpoint> answer = new ArrayList<Endpoint>(); 272 Collection<Endpoint> coll; 273 synchronized (endpoints) { 274 Endpoint ep = endpoints.get(uri); 275 if (ep != null) { 276 answer.add(ep); 277 return answer; 278 } 279 coll = new ArrayList<Endpoint>(endpoints.values()); 280 } 281 for (Endpoint ep : coll) { 282 if (!ep.isSingleton() && uri.equals(ep.getEndpointUri())) { 283 answer.add(ep); 284 } 285 } 286 return answer; 287 } 288 289 public Collection<Endpoint> getSingletonEndpoints() { 290 Collection<Endpoint> answer = new ArrayList<Endpoint>(); 291 Collection<Endpoint> coll = getEndpoints(); 292 for (Endpoint ep : coll) { 293 if (ep.isSingleton()) { 294 answer.add(ep); 295 } 296 } 297 return answer; 298 } 299 300 public Endpoint addEndpoint(String uri, Endpoint endpoint) throws Exception { 301 Endpoint oldEndpoint; 302 synchronized (endpoints) { 303 startServices(endpoint); 304 oldEndpoint = endpoints.remove(uri); 305 endpoints.put(getEndpointKey(uri, endpoint), endpoint); 306 if (oldEndpoint != null) { 307 stopServices(oldEndpoint); 308 } 309 } 310 return oldEndpoint; 311 } 312 313 public Collection<Endpoint> removeEndpoints(String uri) throws Exception { 314 Collection<Endpoint> answer = new ArrayList<Endpoint>(); 315 synchronized (endpoints) { 316 Endpoint oldEndpoint = endpoints.remove(uri); 317 if (oldEndpoint != null) { 318 answer.add(oldEndpoint); 319 stopServices(oldEndpoint); 320 } else { 321 for (Map.Entry entry : endpoints.entrySet()) { 322 oldEndpoint = (Endpoint) entry.getValue(); 323 if (!oldEndpoint.isSingleton() && uri.equals(oldEndpoint.getEndpointUri())) { 324 answer.add(oldEndpoint); 325 stopServices(oldEndpoint); 326 endpoints.remove(entry.getKey()); 327 } 328 } 329 } 330 } 331 return answer; 332 } 333 334 public Endpoint addSingletonEndpoint(String uri, Endpoint endpoint) throws Exception { 335 return addEndpoint(uri, endpoint); 336 } 337 338 public Endpoint removeSingletonEndpoint(String uri) throws Exception { 339 Collection<Endpoint> answer = removeEndpoints(uri); 340 return (Endpoint) (answer.size() > 0 ? answer.toArray()[0] : null); 341 } 342 343 public Endpoint getEndpoint(String uri) { 344 Endpoint answer; 345 synchronized (endpoints) { 346 answer = endpoints.get(uri); 347 if (answer == null) { 348 try { 349 350 // Use the URI prefix to find the component. 351 String splitURI[] = ObjectHelper.splitOnCharacter(uri, ":", 2); 352 if (splitURI[1] != null) { 353 String scheme = splitURI[0]; 354 Component component = getComponent(scheme); 355 356 // Ask the component to resolve the endpoint. 357 if (component != null) { 358 // Have the component create the endpoint if it can. 359 answer = component.createEndpoint(uri); 360 361 if (answer != null && LOG.isDebugEnabled()) { 362 LOG.debug(uri + " converted to endpoint: " + answer + " by component: " + component); 363 } 364 } 365 } 366 if (answer == null) { 367 answer = createEndpoint(uri); 368 } 369 370 // If it's a singleton then auto register it. 371 if (answer != null) { 372 addService(answer); 373 374 endpoints.put(getEndpointKey(uri, answer), answer); 375 lifecycleStrategy.onEndpointAdd(answer); 376 } 377 } catch (Exception e) { 378 throw new ResolveEndpointFailedException(uri, e); 379 } 380 } 381 } 382 return answer; 383 } 384 385 public <T extends Endpoint> T getEndpoint(String name, Class<T> endpointType) { 386 Endpoint endpoint = getEndpoint(name); 387 if (endpointType.isInstance(endpoint)) { 388 return endpointType.cast(endpoint); 389 } else { 390 throw new IllegalArgumentException("The endpoint is not of type: " + endpointType + " but is: " 391 + endpoint.getClass().getCanonicalName()); 392 } 393 } 394 395 // Route Management Methods 396 // ----------------------------------------------------------------------- 397 public synchronized List<Route> getRoutes() { 398 if (routes == null) { 399 routes = new ArrayList<Route>(); 400 } 401 402 // lets return a copy of the collection as objects are removed later 403 // when services are stopped 404 return new ArrayList<Route>(routes); 405 } 406 407 public void setRoutes(List<Route> routes) { 408 this.routes = routes; 409 throw new UnsupportedOperationException("Overriding existing routes is not supported yet, use addRoutes instead"); 410 } 411 412 synchronized void removeRouteCollection(Collection<Route> routes) { 413 if (this.routes != null) { 414 this.routes.removeAll(routes); 415 } 416 } 417 418 synchronized void addRouteCollection(Collection<Route> routes) throws Exception { 419 if (this.routes == null) { 420 this.routes = new ArrayList<Route>(); 421 } 422 423 if (routes != null) { 424 this.routes.addAll(routes); 425 /* 426 TODO we should have notified the lifecycle strategy via the RouteService 427 428 lifecycleStrategy.onRoutesAdd(routes); 429 if (shouldStartRoutes()) { 430 startRoutes(routes); 431 } 432 */ 433 } 434 } 435 436 public void addRoutes(Routes builder) throws Exception { 437 // lets now add the routes from the builder 438 builder.setContext(this); 439 List<Route> routeList = builder.getRouteList(); 440 if (LOG.isDebugEnabled()) { 441 LOG.debug("Adding routes from: " + builder + " routes: " + routeList); 442 } 443 //addRouteCollection(routeList); 444 } 445 446 public void addRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { 447 for (RouteDefinition routeDefinition : routeDefinitions) { 448 routeDefinition.setCamelContext(this); 449 } 450 this.routeDefinitions.addAll(routeDefinitions); 451 if (shouldStartRoutes()) { 452 startRouteDefinitions(routeDefinitions); 453 } 454 } 455 456 public void removeRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { 457 this.routeDefinitions.removeAll(routeDefinitions); 458 for (RouteDefinition routeDefinition : routeDefinitions) { 459 stopRoute(routeDefinition); 460 } 461 462 } 463 464 public ServiceStatus getRouteStatus(RouteDefinition route) { 465 return getRouteStatus(route.idOrCreate()); 466 } 467 468 /** 469 * Returns the status of the service of the given ID or null if there is no service created yet 470 */ 471 public ServiceStatus getRouteStatus(String key) { 472 RouteService routeService = routeServices.get(key); 473 if (routeService != null) { 474 return routeService.getStatus(); 475 } 476 return null; 477 } 478 479 public void startRoute(RouteDefinition route) throws Exception { 480 Collection<Route> routes = new ArrayList<Route>(); 481 List<RouteContext> routeContexts = route.addRoutes(this, routes); 482 RouteService routeService = new RouteService(this, route, routeContexts, routes); 483 startRouteService(routeService); 484 } 485 486 487 public void stopRoute(RouteDefinition route) throws Exception { 488 stopRoute(route.idOrCreate()); 489 } 490 491 /** 492 * Stops the route denoted by the given RouteType id 493 */ 494 public synchronized void stopRoute(String key) throws Exception { 495 RouteService routeService = routeServices.remove(key); 496 if (routeService != null) { 497 routeService.stop(); 498 } 499 } 500 501 502 503 /** 504 * Adds a service, starting it so that it will be stopped with this context 505 */ 506 public void addService(Object object) throws Exception { 507 if (object instanceof Service) { 508 Service service = (Service) object; 509 getLifecycleStrategy().onServiceAdd(this, service); 510 service.start(); 511 servicesToClose.add(service); 512 } 513 } 514 515 // Helper methods 516 // ----------------------------------------------------------------------- 517 518 public Language resolveLanguage(String language) { 519 Language answer; 520 synchronized (languages) { 521 answer = languages.get(language); 522 523 // check if the language is singleton, if so return the shared instance 524 if (answer != null && answer instanceof IsSingleton) { 525 boolean singleton = ((IsSingleton)answer).isSingleton(); 526 if (singleton) { 527 return answer; 528 } 529 } 530 531 // language not known or not singleton, then use resolver 532 answer = getLanguageResolver().resolveLanguage(language, this); 533 if (answer != null) { 534 languages.put(language, answer); 535 } 536 } 537 538 // no language resolved 539 return answer; 540 } 541 542 // Properties 543 // ----------------------------------------------------------------------- 544 public ExchangeConverter getExchangeConverter() { 545 if (exchangeConverter == null) { 546 exchangeConverter = createExchangeConverter(); 547 } 548 return exchangeConverter; 549 } 550 551 public void setExchangeConverter(ExchangeConverter exchangeConverter) { 552 this.exchangeConverter = exchangeConverter; 553 } 554 555 public TypeConverter getTypeConverter() { 556 if (typeConverter == null) { 557 typeConverter = createTypeConverter(); 558 } 559 return typeConverter; 560 } 561 562 public void setTypeConverter(TypeConverter typeConverter) { 563 this.typeConverter = typeConverter; 564 } 565 566 public TypeConverterRegistry getTypeConverterRegistry() { 567 if (typeConverterRegistry == null) { 568 // init type converter as its lazy 569 if (typeConverter == null) { 570 getTypeConverter(); 571 } 572 // type converter is usually the default one that also is the registry 573 if (typeConverter instanceof DefaultTypeConverter) { 574 typeConverterRegistry = (DefaultTypeConverter) typeConverter; 575 } 576 } 577 return typeConverterRegistry; 578 } 579 580 public void setTypeConverterRegistry(TypeConverterRegistry typeConverterRegistry) { 581 this.typeConverterRegistry = typeConverterRegistry; 582 } 583 584 public Injector getInjector() { 585 if (injector == null) { 586 injector = createInjector(); 587 } 588 return injector; 589 } 590 591 public void setInjector(Injector injector) { 592 this.injector = injector; 593 } 594 595 public ComponentResolver getComponentResolver() { 596 if (componentResolver == null) { 597 componentResolver = createComponentResolver(); 598 } 599 return componentResolver; 600 } 601 602 public void setComponentResolver(ComponentResolver componentResolver) { 603 this.componentResolver = componentResolver; 604 } 605 606 public LanguageResolver getLanguageResolver() { 607 return languageResolver; 608 } 609 610 public void setLanguageResolver(LanguageResolver languageResolver) { 611 this.languageResolver = languageResolver; 612 } 613 614 public boolean isAutoCreateComponents() { 615 return autoCreateComponents; 616 } 617 618 public void setAutoCreateComponents(boolean autoCreateComponents) { 619 this.autoCreateComponents = autoCreateComponents; 620 } 621 622 public Registry getRegistry() { 623 if (registry == null) { 624 registry = createRegistry(); 625 } 626 return registry; 627 } 628 629 /** 630 * Sets the registry to the given JNDI context 631 * 632 * @param jndiContext is the JNDI context to use as the registry 633 * @see #setRegistry(org.apache.camel.spi.Registry) 634 */ 635 public void setJndiContext(Context jndiContext) { 636 setRegistry(new JndiRegistry(jndiContext)); 637 } 638 639 public void setRegistry(Registry registry) { 640 this.registry = registry; 641 } 642 643 public LifecycleStrategy getLifecycleStrategy() { 644 return lifecycleStrategy; 645 } 646 647 public void setLifecycleStrategy(LifecycleStrategy lifecycleStrategy) { 648 this.lifecycleStrategy = lifecycleStrategy; 649 } 650 651 public List<RouteDefinition> getRouteDefinitions() { 652 return routeDefinitions; 653 } 654 655 public List<InterceptStrategy> getInterceptStrategies() { 656 return interceptStrategies; 657 } 658 659 public void setInterceptStrategies(List<InterceptStrategy> interceptStrategies) { 660 this.interceptStrategies = interceptStrategies; 661 } 662 663 public void addInterceptStrategy(InterceptStrategy interceptStrategy) { 664 getInterceptStrategies().add(interceptStrategy); 665 } 666 667 /** 668 * Returns true if tracing has been enabled or disabled via the {@link #setTrace(Boolean)} method 669 * or it has not been specified then default to the <b>camel.trace</b> system property 670 */ 671 public boolean getTrace() { 672 final Boolean value = getTracing(); 673 if (value != null) { 674 return value; 675 } else { 676 return SystemHelper.isSystemProperty("camel.trace"); 677 } 678 } 679 680 public Boolean getTracing() { 681 return trace; 682 } 683 684 public void setTrace(Boolean trace) { 685 this.trace = trace; 686 } 687 688 /** 689 * Returns the delay in millis if delaying has been enabled or disabled via the {@link #setDelay(Long)} method 690 * or it has not been specified then default to the <b>camel.delay</b> system property 691 */ 692 public long getDelay() { 693 final Long value = getDelaying(); 694 if (value != null) { 695 return value; 696 } else { 697 String prop = SystemHelper.getSystemProperty("camel.delay"); 698 return prop != null ? Long.getLong(prop) : 0; 699 } 700 } 701 702 public Long getDelaying() { 703 return delay; 704 } 705 706 public void setDelay(Long delay) { 707 this.delay = delay; 708 } 709 710 public ProducerTemplate createProducerTemplate() { 711 return new DefaultProducerTemplate(this); 712 } 713 714 public ErrorHandlerBuilder getErrorHandlerBuilder() { 715 return errorHandlerBuilder; 716 } 717 718 /** 719 * Sets the default error handler builder which is inherited by the routes 720 */ 721 public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) { 722 this.errorHandlerBuilder = errorHandlerBuilder; 723 } 724 725 // Implementation methods 726 // ----------------------------------------------------------------------- 727 728 protected void doStart() throws Exception { 729 LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") is starting"); 730 731 if (getTrace()) { 732 // only add a new tracer if not already configured 733 if (Tracer.getTracer(this) == null) { 734 Tracer tracer = new Tracer(); 735 // lets see if we have a formatter if so use it 736 TraceFormatter formatter = this.getRegistry().lookup("traceFormatter", TraceFormatter.class); 737 if (formatter != null) { 738 tracer.setFormatter(formatter); 739 } 740 addInterceptStrategy(tracer); 741 } 742 } 743 744 if (getDelay() > 0) { 745 // only add a new delayer if not already configured 746 if (Delayer.getDelayer(this) == null) { 747 addInterceptStrategy(new Delayer(getDelay())); 748 } 749 } 750 751 lifecycleStrategy.onContextStart(this); 752 753 forceLazyInitialization(); 754 if (components != null) { 755 for (Component component : components.values()) { 756 startServices(component); 757 } 758 } 759 startRouteDefinitions(routeDefinitions); 760 761 // lets clear the starting flag as we are now started and we really do start up these services 762 notStarting(); 763 764 synchronized (this) { 765 for (RouteService routeService : routeServices.values()) { 766 routeService.start(); 767 } 768 } 769 //startRoutes(routes); 770 771 LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") started"); 772 } 773 774 protected void startRouteDefinitions(Collection<RouteDefinition> list) throws Exception { 775 if (list != null) { 776 for (RouteDefinition route : list) { 777 startRoute(route); 778 } 779 } 780 } 781 782 /* 783 protected void startRoutes(Collection<Route> routeList) throws Exception { 784 if (routeList != null) { 785 for (Route route : routeList) { 786 List<Service> services = route.getServicesForRoute(); 787 for (Service service : services) { 788 addService(service); 789 } 790 } 791 } 792 } 793 794 */ 795 796 797 /** 798 * Starts the given route service 799 */ 800 protected synchronized void startRouteService(RouteService routeService) throws Exception { 801 String key = routeService.getId(); 802 stopRoute(key); 803 routeServices.put(key, routeService); 804 if (shouldStartRoutes()) { 805 routeService.start(); 806 } 807 } 808 809 protected synchronized void doStop() throws Exception { 810 LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") is stopping"); 811 stopServices(routeServices.values()); 812 813 stopServices(servicesToClose); 814 if (components != null) { 815 for (Component component : components.values()) { 816 stopServices(component); 817 } 818 } 819 LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") stopped"); 820 } 821 822 /** 823 * Lets force some lazy initialization to occur upfront before we start any 824 * components and create routes 825 */ 826 protected void forceLazyInitialization() { 827 getExchangeConverter(); 828 getInjector(); 829 getLanguageResolver(); 830 getTypeConverter(); 831 } 832 833 /** 834 * Lazily create a default implementation 835 */ 836 protected ExchangeConverter createExchangeConverter() { 837 return new DefaultExchangeConverter(); 838 } 839 840 /** 841 * Lazily create a default implementation 842 */ 843 protected TypeConverter createTypeConverter() { 844 DefaultTypeConverter answer = new DefaultTypeConverter(packageScanClassResolver, getInjector()); 845 typeConverterRegistry = answer; 846 return answer; 847 } 848 849 /** 850 * Lazily create a default implementation 851 */ 852 protected Injector createInjector() { 853 FactoryFinder finder = createFactoryFinder(); 854 try { 855 return (Injector) finder.newInstance("Injector"); 856 } catch (NoFactoryAvailableException e) { 857 // lets use the default 858 return new ReflectionInjector(); 859 } catch (IllegalAccessException e) { 860 throw new RuntimeCamelException(e); 861 } catch (InstantiationException e) { 862 throw new RuntimeCamelException(e); 863 } catch (IOException e) { 864 throw new RuntimeCamelException(e); 865 } catch (ClassNotFoundException e) { 866 throw new RuntimeCamelException(e); 867 } 868 } 869 870 /** 871 * Lazily create a default implementation 872 */ 873 protected ComponentResolver createComponentResolver() { 874 return new DefaultComponentResolver(); 875 } 876 877 /** 878 * Lazily create a default implementation 879 */ 880 protected Registry createRegistry() { 881 return new JndiRegistry(); 882 } 883 884 /** 885 * A pluggable strategy to allow an endpoint to be created without requiring 886 * a component to be its factory, such as for looking up the URI inside some 887 * {@link Registry} 888 * 889 * @param uri the uri for the endpoint to be created 890 * @return the newly created endpoint or null if it could not be resolved 891 */ 892 protected Endpoint createEndpoint(String uri) { 893 Object value = getRegistry().lookup(uri); 894 if (value instanceof Endpoint) { 895 return (Endpoint) value; 896 } else if (value instanceof Processor) { 897 return new ProcessorEndpoint(uri, this, (Processor) value); 898 } else if (value != null) { 899 return convertBeanToEndpoint(uri, value); 900 } 901 return null; 902 } 903 904 /** 905 * Strategy method for attempting to convert the bean from a {@link Registry} to an endpoint using 906 * some kind of transformation or wrapper 907 * 908 * @param uri the uri for the endpoint (and name in the registry) 909 * @param bean the bean to be converted to an endpoint, which will be not null 910 * @return a new endpoint 911 */ 912 protected Endpoint convertBeanToEndpoint(String uri, Object bean) { 913 throw new IllegalArgumentException("uri: " + uri + " bean: " + bean 914 + " could not be converted to an Endpoint"); 915 } 916 917 /** 918 * Should we start newly added routes? 919 */ 920 protected boolean shouldStartRoutes() { 921 return isStarted() && !isStarting(); 922 } 923 924 public void setDataFormats(Map<String, DataFormatDefinition> dataFormats) { 925 this.dataFormats = dataFormats; 926 } 927 928 public Map<String, DataFormatDefinition> getDataFormats() { 929 return dataFormats; 930 } 931 932 public void setFactoryFinderClass(Class<? extends FactoryFinder> finderClass) { 933 factoryFinderClass = finderClass; 934 } 935 936 public Map<String, String> getProperties() { 937 return properties; 938 } 939 940 public void setProperties(Map<String, String> properties) { 941 this.properties = properties; 942 } 943 944 public FactoryFinder createFactoryFinder() { 945 try { 946 return factoryFinderClass.newInstance(); 947 } catch (Exception e) { 948 throw new RuntimeCamelException(e); 949 } 950 } 951 952 public FactoryFinder createFactoryFinder(String path) { 953 try { 954 Constructor<? extends FactoryFinder> constructor; 955 constructor = factoryFinderClass.getConstructor(String.class); 956 return constructor.newInstance(path); 957 } catch (Exception e) { 958 throw new RuntimeCamelException(e); 959 } 960 } 961 962 public ClassResolver getClassResolver() { 963 return classResolver; 964 } 965 966 public void setClassResolver(ClassResolver classResolver) { 967 this.classResolver = classResolver; 968 } 969 970 public PackageScanClassResolver getPackageScanClassResolver() { 971 return packageScanClassResolver; 972 } 973 974 public void setPackageScanClassResolver(PackageScanClassResolver packageScanClassResolver) { 975 this.packageScanClassResolver = packageScanClassResolver; 976 } 977 978 public List<String> getComponentNames() { 979 synchronized (components) { 980 List<String> answer = new ArrayList<String>(); 981 for (String name : components.keySet()) { 982 answer.add(name); 983 } 984 return answer; 985 } 986 } 987 988 public List<String> getLanguageNames() { 989 synchronized (languages) { 990 List<String> answer = new ArrayList<String>(); 991 for (String name : languages.keySet()) { 992 answer.add(name); 993 } 994 return answer; 995 } 996 } 997 998 protected synchronized String getEndpointKey(String uri, Endpoint endpoint) { 999 if (endpoint.isSingleton()) { 1000 return uri; 1001 } else { 1002 // lets try find the first endpoint key which is free 1003 for (int counter = 0; true; counter++) { 1004 String key = (counter > 0) ? uri + ":" + counter : uri; 1005 if (!endpoints.containsKey(key)) { 1006 return key; 1007 } 1008 } 1009 } 1010 } 1011 1012 }