001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.camel.impl; 018 019 import java.io.IOException; 020 import java.util.ArrayList; 021 import java.util.Collection; 022 import java.util.HashMap; 023 import java.util.List; 024 import java.util.Map; 025 import java.util.concurrent.Callable; 026 027 import javax.naming.Context; 028 029 import org.apache.camel.CamelContext; 030 import org.apache.camel.Component; 031 import org.apache.camel.Endpoint; 032 import org.apache.camel.Exchange; 033 import org.apache.camel.Processor; 034 import org.apache.camel.ProducerTemplate; 035 import org.apache.camel.ResolveEndpointFailedException; 036 import org.apache.camel.Route; 037 import org.apache.camel.Routes; 038 import org.apache.camel.RuntimeCamelException; 039 import org.apache.camel.Service; 040 import org.apache.camel.TypeConverter; 041 import org.apache.camel.builder.ErrorHandlerBuilder; 042 import org.apache.camel.impl.converter.DefaultTypeConverter; 043 import org.apache.camel.management.InstrumentationLifecycleStrategy; 044 import org.apache.camel.management.JmxSystemPropertyKeys; 045 import org.apache.camel.model.RouteType; 046 import org.apache.camel.model.dataformat.DataFormatType; 047 import org.apache.camel.processor.interceptor.Delayer; 048 import org.apache.camel.processor.interceptor.TraceFormatter; 049 import org.apache.camel.processor.interceptor.Tracer; 050 import org.apache.camel.spi.ComponentResolver; 051 import org.apache.camel.spi.ExchangeConverter; 052 import org.apache.camel.spi.Injector; 053 import org.apache.camel.spi.InterceptStrategy; 054 import org.apache.camel.spi.Language; 055 import org.apache.camel.spi.LanguageResolver; 056 import org.apache.camel.spi.LifecycleStrategy; 057 import org.apache.camel.spi.Registry; 058 import org.apache.camel.util.CamelContextHelper; 059 import org.apache.camel.util.FactoryFinder; 060 import org.apache.camel.util.NoFactoryAvailableException; 061 import org.apache.camel.util.ObjectHelper; 062 import org.apache.camel.util.ReflectionInjector; 063 import org.apache.camel.util.SystemHelper; 064 import org.apache.commons.logging.Log; 065 import org.apache.commons.logging.LogFactory; 066 067 import static org.apache.camel.util.ServiceHelper.startServices; 068 import static org.apache.camel.util.ServiceHelper.stopServices; 069 070 071 /** 072 * Represents the context used to configure routes and the policies to use. 073 * 074 * @version $Revision: 63392 $ 075 */ 076 public class DefaultCamelContext extends ServiceSupport implements CamelContext, Service { 077 private static final transient Log LOG = LogFactory.getLog(DefaultCamelContext.class); 078 private static final String NAME_PREFIX = "camel-"; 079 private static int nameSuffix; 080 081 private String name; 082 private final Map<String, Endpoint> endpoints = new HashMap<String, Endpoint>(); 083 private final Map<String, Component> components = new HashMap<String, Component>(); 084 private List<Route> routes; 085 private List<Service> servicesToClose = new ArrayList<Service>(); 086 private TypeConverter typeConverter; 087 private ExchangeConverter exchangeConverter; 088 private Injector injector; 089 private ComponentResolver componentResolver; 090 private boolean autoCreateComponents = true; 091 private LanguageResolver languageResolver = new DefaultLanguageResolver(); 092 private Registry registry; 093 private LifecycleStrategy lifecycleStrategy; 094 private List<RouteType> routeDefinitions = new ArrayList<RouteType>(); 095 private List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>(); 096 private Boolean trace; 097 private Long delay; 098 private ErrorHandlerBuilder errorHandlerBuilder; 099 private Map<String, DataFormatType> dataFormats = new HashMap<String, DataFormatType>(); 100 101 public DefaultCamelContext() { 102 name = NAME_PREFIX + ++nameSuffix; 103 104 if (Boolean.getBoolean(JmxSystemPropertyKeys.DISABLED)) { 105 LOG.info("JMX is disabled. Using DefaultLifecycleStrategy."); 106 lifecycleStrategy = new DefaultLifecycleStrategy(); 107 } else { 108 try { 109 LOG.info("JMX enabled. Using InstrumentationLifecycleStrategy."); 110 lifecycleStrategy = new InstrumentationLifecycleStrategy(); 111 } catch (NoClassDefFoundError e) { 112 // if we can't instantiate the JMX enabled strategy then fallback to default 113 // could be because of missing .jars on the classpath 114 LOG.warn("Could not find needed classes for JMX lifecycle strategy." 115 + " Needed class is in spring-context.jar using Spring 2.5 or newer (" 116 + " spring-jmx.jar using Spring 2.0.x)." 117 + " NoClassDefFoundError: " + e.getMessage()); 118 } catch (Exception e) { 119 LOG.warn("Could not create JMX lifecycle strategy, caused by: " + e.getMessage()); 120 } 121 // if not created then fallback to default 122 if (lifecycleStrategy == null) { 123 LOG.warn("Not possible to use JMX lifecycle strategy. Using DefaultLifecycleStrategy instead."); 124 lifecycleStrategy = new DefaultLifecycleStrategy(); 125 } 126 } 127 } 128 129 /** 130 * Creates the {@link CamelContext} using the given JNDI context as the 131 * registry 132 */ 133 public DefaultCamelContext(Context jndiContext) { 134 this(); 135 setJndiContext(jndiContext); 136 } 137 138 /** 139 * Creates the {@link CamelContext} using the given registry 140 */ 141 public DefaultCamelContext(Registry registry) { 142 this(); 143 this.registry = registry; 144 } 145 146 public String getName() { 147 return name; 148 } 149 150 /** 151 * Sets the name of the this context. 152 */ 153 public void setName(String name) { 154 this.name = name; 155 } 156 157 public void addComponent(String componentName, final Component component) { 158 if (component == null) { 159 throw new IllegalArgumentException("Component cannot be null"); 160 } 161 synchronized (components) { 162 if (components.containsKey(componentName)) { 163 throw new IllegalArgumentException("Component previously added: " + componentName); 164 } 165 component.setCamelContext(this); 166 components.put(componentName, component); 167 } 168 } 169 170 public Component getComponent(String name) { 171 // synchronize the look up and auto create so that 2 threads can't 172 // concurrently auto create the same component. 173 synchronized (components) { 174 Component component = components.get(name); 175 if (component == null && autoCreateComponents) { 176 try { 177 component = getComponentResolver().resolveComponent(name, this); 178 if (component != null) { 179 addComponent(name, component); 180 if (isStarted()) { 181 // If the component is looked up after the context 182 // is started, 183 // lets start it up. 184 startServices(component); 185 } 186 } 187 } catch (Exception e) { 188 throw new RuntimeCamelException("Could not auto create component: " + name, e); 189 } 190 } 191 return component; 192 } 193 } 194 195 public <T extends Component> T getComponent(String name, Class<T> componentType) { 196 Component component = getComponent(name); 197 if (componentType.isInstance(component)) { 198 return componentType.cast(component); 199 } else { 200 throw new IllegalArgumentException("The component is not of type: " + componentType + " but is: " 201 + component); 202 } 203 } 204 205 public Component removeComponent(String componentName) { 206 synchronized (components) { 207 return components.remove(componentName); 208 } 209 } 210 211 public Component getOrCreateComponent(String componentName, Callable<Component> factory) { 212 synchronized (components) { 213 Component component = components.get(componentName); 214 if (component == null) { 215 try { 216 component = factory.call(); 217 if (component == null) { 218 throw new RuntimeCamelException("Factory failed to create the " + componentName 219 + " component, it returned null."); 220 } 221 components.put(componentName, component); 222 component.setCamelContext(this); 223 } catch (Exception e) { 224 throw new RuntimeCamelException("Factory failed to create the " + componentName 225 + " component", e); 226 } 227 } 228 return component; 229 } 230 } 231 232 // Endpoint Management Methods 233 // ----------------------------------------------------------------------- 234 235 public Collection<Endpoint> getEndpoints() { 236 synchronized (endpoints) { 237 return new ArrayList<Endpoint>(endpoints.values()); 238 } 239 } 240 241 public Collection<Endpoint> getEndpoints(String uri) { 242 Collection<Endpoint> answer = new ArrayList<Endpoint>(); 243 Collection<Endpoint> coll; 244 synchronized (endpoints) { 245 Endpoint ep = endpoints.get(uri); 246 if (ep != null) { 247 answer.add(ep); 248 return answer; 249 } 250 coll = new ArrayList<Endpoint>(endpoints.values()); 251 } 252 for (Endpoint ep : coll) { 253 if (!ep.isSingleton() && uri.equals(ep.getEndpointUri())) { 254 answer.add(ep); 255 } 256 } 257 return answer; 258 } 259 260 public Collection<Endpoint> getSingletonEndpoints() { 261 Collection<Endpoint> answer = new ArrayList<Endpoint>(); 262 Collection<Endpoint> coll = getEndpoints(); 263 for (Endpoint ep : coll) { 264 if (ep.isSingleton()) { 265 answer.add(ep); 266 } 267 } 268 return answer; 269 } 270 271 public Endpoint addEndpoint(String uri, Endpoint endpoint) throws Exception { 272 Endpoint oldEndpoint; 273 synchronized (endpoints) { 274 startServices(endpoint); 275 oldEndpoint = endpoints.remove(uri); 276 endpoints.put(CamelContextHelper.getEndpointKey(uri, endpoint), endpoint); 277 if (oldEndpoint != null) { 278 stopServices(oldEndpoint); 279 } 280 } 281 return oldEndpoint; 282 } 283 284 public Collection<Endpoint> removeEndpoints(String uri) throws Exception { 285 Collection<Endpoint> answer = new ArrayList<Endpoint>(); 286 synchronized (endpoints) { 287 Endpoint oldEndpoint = endpoints.remove(uri); 288 if (oldEndpoint != null) { 289 answer.add(oldEndpoint); 290 stopServices(oldEndpoint); 291 } else { 292 for (Map.Entry entry : endpoints.entrySet()) { 293 oldEndpoint = (Endpoint)entry.getValue(); 294 if (!oldEndpoint.isSingleton() && uri.equals(oldEndpoint.getEndpointUri())) { 295 answer.add(oldEndpoint); 296 stopServices(oldEndpoint); 297 endpoints.remove(entry.getKey()); 298 } 299 } 300 } 301 } 302 return answer; 303 } 304 305 public Endpoint addSingletonEndpoint(String uri, Endpoint endpoint) throws Exception { 306 return addEndpoint(uri, endpoint); 307 } 308 309 public Endpoint removeSingletonEndpoint(String uri) throws Exception { 310 Collection<Endpoint> answer = removeEndpoints(uri); 311 return (Endpoint) (answer.size() > 0 ? answer.toArray()[0] : null); 312 } 313 314 public Endpoint getEndpoint(String uri) { 315 Endpoint<?> answer; 316 synchronized (endpoints) { 317 answer = endpoints.get(uri); 318 if (answer == null) { 319 try { 320 321 // Use the URI prefix to find the component. 322 String splitURI[] = ObjectHelper.splitOnCharacter(uri, ":", 2); 323 if (splitURI[1] != null) { 324 String scheme = splitURI[0]; 325 Component<?> component = getComponent(scheme); 326 327 // Ask the component to resolve the endpoint. 328 if (component != null) { 329 // Have the component create the endpoint if it can. 330 answer = component.createEndpoint(uri); 331 332 if (answer != null && LOG.isDebugEnabled()) { 333 LOG.debug(uri + " converted to endpoint: " + answer + " by component: " + component); 334 } 335 } 336 } 337 if (answer == null) { 338 answer = createEndpoint(uri); 339 } 340 341 // If it's a singleton then auto register it. 342 if (answer != null) { 343 addService(answer); 344 345 endpoints.put(CamelContextHelper.getEndpointKey(uri, answer), answer); 346 lifecycleStrategy.onEndpointAdd(answer); 347 } 348 } catch (Exception e) { 349 LOG.debug("Failed to resolve endpoint " + uri + ". Reason: " + e, e); 350 throw new ResolveEndpointFailedException(uri, e); 351 } 352 } 353 } 354 return answer; 355 } 356 357 public <T extends Endpoint> T getEndpoint(String name, Class<T> endpointType) { 358 Endpoint endpoint = getEndpoint(name); 359 if (endpointType.isInstance(endpoint)) { 360 return endpointType.cast(endpoint); 361 } else { 362 throw new IllegalArgumentException("The endpoint is not of type: " + endpointType + " but is: " 363 + endpoint); 364 } 365 } 366 367 // Route Management Methods 368 // ----------------------------------------------------------------------- 369 public List<Route> getRoutes() { 370 if (routes == null) { 371 routes = new ArrayList<Route>(); 372 } 373 return routes; 374 } 375 376 public void setRoutes(List<Route> routes) { 377 this.routes = routes; 378 throw new UnsupportedOperationException("overriding existing routes is not supported yet, use addRoutes instead"); 379 } 380 381 public void addRoutes(Collection<Route> routes) throws Exception { 382 if (this.routes == null) { 383 this.routes = new ArrayList<Route>(); 384 } 385 386 if (routes != null) { 387 this.routes.addAll(routes); 388 389 lifecycleStrategy.onRoutesAdd(routes); 390 if (shouldStartRoutes()) { 391 startRoutes(routes); 392 } 393 } 394 } 395 396 public void addRoutes(Routes builder) throws Exception { 397 // lets now add the routes from the builder 398 builder.setContext(this); 399 List<Route> routeList = builder.getRouteList(); 400 if (LOG.isDebugEnabled()) { 401 LOG.debug("Adding routes from: " + builder + " routes: " + routeList); 402 } 403 addRoutes(routeList); 404 } 405 406 public void addRouteDefinitions(Collection<RouteType> routeDefinitions) throws Exception { 407 this.routeDefinitions.addAll(routeDefinitions); 408 if (shouldStartRoutes()) { 409 startRouteDefinitions(routeDefinitions); 410 } 411 412 } 413 414 /** 415 * Adds a service, starting it so that it will be stopped with this context 416 */ 417 public void addService(Object object) throws Exception { 418 if (object instanceof Service) { 419 Service service = (Service) object; 420 getLifecycleStrategy().onServiceAdd(this, service); 421 service.start(); 422 servicesToClose.add(service); 423 } 424 } 425 426 // Helper methods 427 // ----------------------------------------------------------------------- 428 429 public Language resolveLanguage(String language) { 430 return getLanguageResolver().resolveLanguage(language, this); 431 } 432 433 // Properties 434 // ----------------------------------------------------------------------- 435 public ExchangeConverter getExchangeConverter() { 436 if (exchangeConverter == null) { 437 exchangeConverter = createExchangeConverter(); 438 } 439 return exchangeConverter; 440 } 441 442 public void setExchangeConverter(ExchangeConverter exchangeConverter) { 443 this.exchangeConverter = exchangeConverter; 444 } 445 446 public TypeConverter getTypeConverter() { 447 if (typeConverter == null) { 448 typeConverter = createTypeConverter(); 449 } 450 return typeConverter; 451 } 452 453 public void setTypeConverter(TypeConverter typeConverter) { 454 this.typeConverter = typeConverter; 455 } 456 457 public Injector getInjector() { 458 if (injector == null) { 459 injector = createInjector(); 460 } 461 return injector; 462 } 463 464 public void setInjector(Injector injector) { 465 this.injector = injector; 466 } 467 468 public ComponentResolver getComponentResolver() { 469 if (componentResolver == null) { 470 componentResolver = createComponentResolver(); 471 } 472 return componentResolver; 473 } 474 475 public void setComponentResolver(ComponentResolver componentResolver) { 476 this.componentResolver = componentResolver; 477 } 478 479 public LanguageResolver getLanguageResolver() { 480 return languageResolver; 481 } 482 483 public void setLanguageResolver(LanguageResolver languageResolver) { 484 this.languageResolver = languageResolver; 485 } 486 487 public boolean isAutoCreateComponents() { 488 return autoCreateComponents; 489 } 490 491 public void setAutoCreateComponents(boolean autoCreateComponents) { 492 this.autoCreateComponents = autoCreateComponents; 493 } 494 495 public Registry getRegistry() { 496 if (registry == null) { 497 registry = createRegistry(); 498 } 499 return registry; 500 } 501 502 /** 503 * Sets the registry to the given JNDI context 504 * 505 * @param jndiContext is the JNDI context to use as the registry 506 * 507 * @see #setRegistry(org.apache.camel.spi.Registry) 508 */ 509 public void setJndiContext(Context jndiContext) { 510 setRegistry(new JndiRegistry(jndiContext)); 511 } 512 513 public void setRegistry(Registry registry) { 514 this.registry = registry; 515 } 516 517 public LifecycleStrategy getLifecycleStrategy() { 518 return lifecycleStrategy; 519 } 520 521 public void setLifecycleStrategy(LifecycleStrategy lifecycleStrategy) { 522 this.lifecycleStrategy = lifecycleStrategy; 523 } 524 525 public List<RouteType> getRouteDefinitions() { 526 return routeDefinitions; 527 } 528 529 public List<InterceptStrategy> getInterceptStrategies() { 530 return interceptStrategies; 531 } 532 533 public void setInterceptStrategies(List<InterceptStrategy> interceptStrategies) { 534 this.interceptStrategies = interceptStrategies; 535 } 536 537 public void addInterceptStrategy(InterceptStrategy interceptStrategy) { 538 getInterceptStrategies().add(interceptStrategy); 539 } 540 541 /** 542 * Returns true if tracing has been enabled or disabled via the {@link #setTrace(Boolean)} method 543 * or it has not been specified then default to the <b>camel.trace</b> system property 544 */ 545 public boolean getTrace() { 546 final Boolean value = getTracing(); 547 if (value != null) { 548 return value; 549 } else { 550 return SystemHelper.isSystemProperty("camel.trace"); 551 } 552 } 553 554 public Boolean getTracing() { 555 return trace; 556 } 557 558 public void setTrace(Boolean trace) { 559 this.trace = trace; 560 } 561 562 /** 563 * Returns the delay in millis if delaying has been enabled or disabled via the {@link #setDelay(Long)} method 564 * or it has not been specified then default to the <b>camel.delay</b> system property 565 */ 566 public long getDelay() { 567 final Long value = getDelaying(); 568 if (value != null) { 569 return value; 570 } else { 571 String prop = SystemHelper.getSystemProperty("camel.delay"); 572 return prop != null ? Long.getLong(prop) : 0; 573 } 574 } 575 576 public Long getDelaying() { 577 return delay; 578 } 579 580 public void setDelay(Long delay) { 581 this.delay = delay; 582 } 583 584 public <E extends Exchange> ProducerTemplate<E> createProducerTemplate() { 585 return new DefaultProducerTemplate<E>(this); 586 } 587 588 public ErrorHandlerBuilder getErrorHandlerBuilder() { 589 return errorHandlerBuilder; 590 } 591 592 /** 593 * Sets the default error handler builder which is inherited by the routes 594 */ 595 public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) { 596 this.errorHandlerBuilder = errorHandlerBuilder; 597 } 598 599 // Implementation methods 600 // ----------------------------------------------------------------------- 601 602 protected void doStart() throws Exception { 603 LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") is starting"); 604 605 if (getTrace()) { 606 // only add a new tracer if not already configued 607 if (Tracer.getTracer(this) == null) { 608 Tracer tracer = new Tracer(); 609 // lets see if we have a formatter if so use it 610 TraceFormatter formatter = this.getRegistry().lookup("traceFormatter", TraceFormatter.class); 611 if (formatter != null) { 612 tracer.setFormatter(formatter); 613 } 614 addInterceptStrategy(tracer); 615 } 616 } 617 618 if (getDelay() > 0) { 619 // only add a new delayer if not already configued 620 if (Delayer.getDelayer(this) == null) { 621 addInterceptStrategy(new Delayer(getDelay())); 622 } 623 } 624 625 lifecycleStrategy.onContextStart(this); 626 627 forceLazyInitialization(); 628 if (components != null) { 629 for (Component component : components.values()) { 630 startServices(component); 631 } 632 } 633 startRouteDefinitions(routeDefinitions); 634 startRoutes(routes); 635 636 LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") started"); 637 } 638 639 protected void startRouteDefinitions(Collection<RouteType> list) throws Exception { 640 if (list != null) { 641 Collection<Route> routes = new ArrayList<Route>(); 642 for (RouteType route : list) { 643 route.addRoutes(this, routes); 644 } 645 addRoutes(routes); 646 } 647 } 648 649 protected void doStop() throws Exception { 650 stopServices(servicesToClose); 651 if (components != null) { 652 for (Component component : components.values()) { 653 stopServices(component); 654 } 655 } 656 } 657 658 protected void startRoutes(Collection<Route> routeList) throws Exception { 659 if (routeList != null) { 660 for (Route<Exchange> route : routeList) { 661 List<Service> services = route.getServicesForRoute(); 662 for (Service service : services) { 663 addService(service); 664 } 665 } 666 } 667 } 668 669 /** 670 * Lets force some lazy initialization to occur upfront before we start any 671 * components and create routes 672 */ 673 protected void forceLazyInitialization() { 674 getExchangeConverter(); 675 getInjector(); 676 getLanguageResolver(); 677 getTypeConverter(); 678 } 679 680 /** 681 * Lazily create a default implementation 682 */ 683 protected ExchangeConverter createExchangeConverter() { 684 return new DefaultExchangeConverter(); 685 } 686 687 /** 688 * Lazily create a default implementation 689 */ 690 protected TypeConverter createTypeConverter() { 691 return new DefaultTypeConverter(getInjector()); 692 } 693 694 /** 695 * Lazily create a default implementation 696 */ 697 protected Injector createInjector() { 698 FactoryFinder finder = new FactoryFinder(); 699 try { 700 return (Injector) finder.newInstance("Injector"); 701 } catch (NoFactoryAvailableException e) { 702 // lets use the default 703 return new ReflectionInjector(); 704 } catch (IllegalAccessException e) { 705 throw new RuntimeCamelException(e); 706 } catch (InstantiationException e) { 707 throw new RuntimeCamelException(e); 708 } catch (IOException e) { 709 throw new RuntimeCamelException(e); 710 } catch (ClassNotFoundException e) { 711 throw new RuntimeCamelException(e); 712 } 713 } 714 715 /** 716 * Lazily create a default implementation 717 */ 718 protected ComponentResolver createComponentResolver() { 719 return new DefaultComponentResolver(); 720 } 721 722 /** 723 * Lazily create a default implementation 724 */ 725 protected Registry createRegistry() { 726 return new JndiRegistry(); 727 } 728 729 /** 730 * A pluggable strategy to allow an endpoint to be created without requiring 731 * a component to be its factory, such as for looking up the URI inside some 732 * {@link Registry} 733 * 734 * @param uri the uri for the endpoint to be created 735 * @return the newly created endpoint or null if it could not be resolved 736 */ 737 protected Endpoint createEndpoint(String uri) { 738 Object value = getRegistry().lookup(uri); 739 if (value instanceof Endpoint) { 740 return (Endpoint) value; 741 } else if (value instanceof Processor) { 742 return new ProcessorEndpoint(uri, this, (Processor) value); 743 } else if (value != null) { 744 return convertBeanToEndpoint(uri, value); 745 } 746 return null; 747 } 748 749 /** 750 * Attempt to convert the bean from a {@link Registry} to an endpoint using 751 * some kind of transformation or wrapper 752 * 753 * @param uri the uri for the endpoint (and name in the registry) 754 * @param bean the bean to be converted to an endpoint, which will be not null 755 * @return a new endpoint 756 */ 757 protected Endpoint convertBeanToEndpoint(String uri, Object bean) { 758 throw new IllegalArgumentException("uri: " + uri + " bean: " + bean 759 + " could not be converted to an Endpoint"); 760 } 761 762 /** 763 * Should we start newly added routes? 764 */ 765 protected boolean shouldStartRoutes() { 766 return isStarted() && !isStarting(); 767 } 768 769 public void setDataFormats(Map<String, DataFormatType> dataFormats) { 770 this.dataFormats = dataFormats; 771 } 772 773 public Map<String, DataFormatType> getDataFormats() { 774 return dataFormats; 775 } 776 }