Coverage Report - org.apache.camel.impl.DefaultCamelContext
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultCamelContext
61% 
90% 
0
 
 1  
 /**
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.camel.impl;
 18  
 
 19  
 import java.io.IOException;
 20  
 import java.util.ArrayList;
 21  
 import java.util.Collection;
 22  
 import java.util.HashMap;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 import java.util.concurrent.Callable;
 26  
 
 27  
 import javax.naming.Context;
 28  
 
 29  
 import org.apache.camel.CamelContext;
 30  
 import org.apache.camel.Component;
 31  
 import org.apache.camel.Endpoint;
 32  
 import org.apache.camel.Exchange;
 33  
 import org.apache.camel.LifecycleStrategy;
 34  
 import org.apache.camel.Processor;
 35  
 import org.apache.camel.ResolveEndpointFailedException;
 36  
 import org.apache.camel.Route;
 37  
 import org.apache.camel.RuntimeCamelException;
 38  
 import org.apache.camel.Service;
 39  
 import org.apache.camel.TypeConverter;
 40  
 import org.apache.camel.builder.RouteBuilder;
 41  
 import org.apache.camel.impl.converter.DefaultTypeConverter;
 42  
 import org.apache.camel.spi.ComponentResolver;
 43  
 import org.apache.camel.spi.ExchangeConverter;
 44  
 import org.apache.camel.spi.Injector;
 45  
 import org.apache.camel.spi.Language;
 46  
 import org.apache.camel.spi.LanguageResolver;
 47  
 import org.apache.camel.spi.Registry;
 48  
 import org.apache.camel.util.FactoryFinder;
 49  
 import org.apache.camel.util.NoFactoryAvailableException;
 50  
 import org.apache.camel.util.ObjectHelper;
 51  
 
 52  
 import static org.apache.camel.util.ServiceHelper.startServices;
 53  
 import static org.apache.camel.util.ServiceHelper.stopServices;
 54  
 
 55  
 /**
 56  
  * Represents the context used to configure routes and the policies to use.
 57  
  * 
 58  
  * @version $Revision: 520517 $
 59  
  * @org.apache.xbean.XBean element="container" rootElement="true"
 60  
  */
 61  
 public class DefaultCamelContext extends ServiceSupport implements CamelContext, Service {
 62  363
     private Map<String, Endpoint> endpoints = new HashMap<String, Endpoint>();
 63  363
     private Map<String, Component> components = new HashMap<String, Component>();
 64  
     private List<Route> routes;
 65  363
     private List<Service> servicesToClose = new ArrayList<Service>();
 66  
     private TypeConverter typeConverter;
 67  
     private ExchangeConverter exchangeConverter;
 68  
     private Injector injector;
 69  
     private ComponentResolver componentResolver;
 70  363
     private boolean autoCreateComponents = true;
 71  363
     private LanguageResolver languageResolver = new DefaultLanguageResolver();
 72  
     private Registry registry;
 73  363
         private LifecycleStrategy lifecycleStrategy = new DefaultLifecycleStrategy();
 74  
 
 75  150
     public DefaultCamelContext() {
 76  150
     }
 77  
 
 78  
     /**
 79  
      * Creates the {@link CamelContext} using the given JNDI context as the
 80  
      * registry
 81  
      * 
 82  
      * @param jndiContext
 83  
      */
 84  
     public DefaultCamelContext(Context jndiContext) {
 85  6
         this(new JndiRegistry(jndiContext));
 86  6
     }
 87  
 
 88  
     /**
 89  
      * Creates the {@link CamelContext} using the given registry
 90  
      */
 91  213
     public DefaultCamelContext(Registry registry) {
 92  213
         this.registry = registry;
 93  213
     }
 94  
 
 95  
     /**
 96  
      * Adds a component to the container.
 97  
      */
 98  
     public void addComponent(String componentName, final Component component) {
 99  411
         if (component == null) {
 100  0
             throw new IllegalArgumentException("Component cannot be null");
 101  
         }
 102  411
         synchronized (components) {
 103  411
             if (components.containsKey(componentName)) {
 104  0
                 throw new IllegalArgumentException("Component previously added: " + componentName);
 105  
             }
 106  411
             component.setCamelContext(this);
 107  411
             components.put(componentName, component);
 108  411
         }
 109  411
     }
 110  
 
 111  
     public Component getComponent(String name) {
 112  
         // synchronize the look up and auto create so that 2 threads can't
 113  
         // concurrently auto create the same component.
 114  588
         synchronized (components) {
 115  588
             Component component = components.get(name);
 116  588
             if (component == null && autoCreateComponents) {
 117  
                 try {
 118  411
                     component = getComponentResolver().resolveComponent(name, this);
 119  411
                     if (component != null) {
 120  411
                         addComponent(name, component);
 121  411
                         if (isStarted()) {
 122  
                             // If the component is looked up after the context
 123  
                             // is started,
 124  
                             // lets start it up.
 125  24
                             startServices(component);
 126  
                         }
 127  
                     }
 128  0
                 } catch (Exception e) {
 129  0
                     throw new RuntimeCamelException("Could not auto create component: " + name, e);
 130  411
                 }
 131  
             }
 132  588
             return component;
 133  0
         }
 134  
     }
 135  
 
 136  
     public <T extends Component> T getComponent(String name, Class<T> componentType) {
 137  0
         Component component = getComponent(name);
 138  0
         if (componentType.isInstance(component)) {
 139  0
             return componentType.cast(component);
 140  
         } else {
 141  0
             throw new IllegalArgumentException("The component is not of type: " + componentType + " but is: "
 142  
                                                + component);
 143  
         }
 144  
     }
 145  
 
 146  
     /**
 147  
      * Removes a previously added component.
 148  
      * 
 149  
      * @param componentName
 150  
      * @return the previously added component or null if it had not been
 151  
      *         previously added.
 152  
      */
 153  
     public Component removeComponent(String componentName) {
 154  0
         synchronized (components) {
 155  0
             return components.remove(componentName);
 156  0
         }
 157  
     }
 158  
 
 159  
     /**
 160  
      * Gets the a previously added component by name or lazily creates the
 161  
      * component using the factory Callback.
 162  
      * 
 163  
      * @param componentName
 164  
      * @param factory used to create a new component instance if the component
 165  
      *                was not previously added.
 166  
      * @return
 167  
      */
 168  
     public Component getOrCreateComponent(String componentName, Callable<Component> factory) {
 169  0
         synchronized (components) {
 170  0
             Component component = components.get(componentName);
 171  0
             if (component == null) {
 172  
                 try {
 173  0
                     component = factory.call();
 174  0
                     if (component == null) {
 175  0
                         throw new RuntimeCamelException("Factory failed to create the " + componentName
 176  
                                                         + " component, it returned null.");
 177  
                     }
 178  0
                     components.put(componentName, component);
 179  0
                     component.setCamelContext(this);
 180  0
                 } catch (Exception e) {
 181  0
                     throw new RuntimeCamelException("Factory failed to create the " + componentName
 182  
                                                     + " component", e);
 183  0
                 }
 184  
             }
 185  0
             return component;
 186  0
         }
 187  
     }
 188  
 
 189  
     // Endpoint Management Methods
 190  
     // -----------------------------------------------------------------------
 191  
 
 192  
     public Collection<Endpoint> getSingletonEndpoints() {
 193  0
         synchronized (endpoints) {
 194  0
             return new ArrayList<Endpoint>(endpoints.values());
 195  0
         }
 196  
     }
 197  
 
 198  
     public Endpoint addSingletonEndpoint(String uri, Endpoint endpoint) throws Exception {
 199  
         Endpoint oldEndpoint;
 200  0
         synchronized (endpoints) {
 201  0
             startServices(endpoint);
 202  0
             oldEndpoint = endpoints.remove(uri);
 203  0
             endpoints.put(uri, endpoint);
 204  0
             stopServices(oldEndpoint);
 205  0
         }
 206  0
         return oldEndpoint;
 207  
     }
 208  
 
 209  
     public Endpoint removeSingletonEndpoint(String uri) throws Exception {
 210  
         Endpoint oldEndpoint;
 211  0
         synchronized (endpoints) {
 212  0
             oldEndpoint = endpoints.remove(uri);
 213  0
             stopServices(oldEndpoint);
 214  0
         }
 215  0
         return oldEndpoint;
 216  
     }
 217  
 
 218  
     /**
 219  
      * Resolves the given URI to an endpoint
 220  
      */
 221  
     public Endpoint getEndpoint(String uri) {
 222  
         Endpoint answer;
 223  1071
         synchronized (endpoints) {
 224  1071
             answer = endpoints.get(uri);
 225  1071
             if (answer == null) {
 226  
                 try {
 227  
 
 228  
                     // Use the URI prefix to find the component.
 229  588
                     String splitURI[] = ObjectHelper.splitOnCharacter(uri, ":", 2);
 230  588
                     if (splitURI[1] != null) {
 231  582
                         String scheme = splitURI[0];
 232  582
                         Component component = getComponent(scheme);
 233  
 
 234  
                         // Ask the component to resolve the endpoint.
 235  582
                         if (component != null) {
 236  
                             // Have the component create the endpoint if it can.
 237  582
                             answer = component.createEndpoint(uri);
 238  
                         }
 239  
                     }
 240  585
                     if (answer == null) {
 241  6
                         answer = createEndpoint(uri);
 242  
                     }
 243  
 
 244  
                     // If it's a singleton then auto register it.
 245  585
                     if (answer != null && answer.isSingleton()) {
 246  579
                         startServices(answer);
 247  579
                         endpoints.put(uri, answer);
 248  579
                             lifecycleStrategy.onEndpointAdd(answer);
 249  
                     }
 250  3
                 } catch (Exception e) {
 251  3
                     throw new ResolveEndpointFailedException(uri, e);
 252  585
                 }
 253  
             }
 254  1068
         }
 255  1068
         return answer;
 256  
     }
 257  
 
 258  
     public <T extends Endpoint> T getEndpoint(String name, Class<T> endpointType) {
 259  111
         Endpoint endpoint = getEndpoint(name);
 260  111
         if (endpointType.isInstance(endpoint)) {
 261  111
             return endpointType.cast(endpoint);
 262  
         } else {
 263  0
             throw new IllegalArgumentException("The endpoint is not of type: " + endpointType + " but is: "
 264  
                                                + endpoint);
 265  
         }
 266  
     }
 267  
 
 268  
     // Route Management Methods
 269  
     // -----------------------------------------------------------------------
 270  
     public List<Route> getRoutes() {
 271  204
         return routes;
 272  
     }
 273  
 
 274  
     public void setRoutes(List<Route> routes) {
 275  0
         this.routes = routes;
 276  0
     }
 277  
 
 278  
     public void addRoutes(Collection<Route> routes) throws Exception {
 279  228
         if (this.routes == null) {
 280  228
             this.routes = new ArrayList<Route>(routes);
 281  228
         } else {
 282  0
             this.routes.addAll(routes);
 283  
         }
 284  228
         lifecycleStrategy.onRoutesAdd(routes);
 285  228
         if (isStarted()) {
 286  0
             startRoutes(routes);
 287  
         }
 288  228
     }
 289  
 
 290  
     public void addRoutes(RouteBuilder builder) throws Exception {
 291  
         // lets now add the routes from the builder
 292  231
         builder.setContext(this);
 293  231
         addRoutes(builder.getRouteList());
 294  228
     }
 295  
 
 296  
     // Helper methods
 297  
     // -----------------------------------------------------------------------
 298  
 
 299  
     /**
 300  
      * Resolves a language for creating expressions
 301  
      */
 302  
     public Language resolveLanguage(String language) {
 303  39
         return getLanguageResolver().resolveLanguage(language, this);
 304  
     }
 305  
 
 306  
     // Properties
 307  
     // -----------------------------------------------------------------------
 308  
     public ExchangeConverter getExchangeConverter() {
 309  228
         if (exchangeConverter == null) {
 310  228
             exchangeConverter = createExchangeConverter();
 311  
         }
 312  228
         return exchangeConverter;
 313  
     }
 314  
 
 315  
     public void setExchangeConverter(ExchangeConverter exchangeConverter) {
 316  0
         this.exchangeConverter = exchangeConverter;
 317  0
     }
 318  
 
 319  
     public TypeConverter getTypeConverter() {
 320  759
         if (typeConverter == null) {
 321  279
             typeConverter = createTypeConverter();
 322  
         }
 323  759
         return typeConverter;
 324  
     }
 325  
 
 326  
     public void setTypeConverter(TypeConverter typeConverter) {
 327  0
         this.typeConverter = typeConverter;
 328  0
     }
 329  
 
 330  
     public Injector getInjector() {
 331  960
         if (injector == null) {
 332  324
             injector = createInjector();
 333  
         }
 334  960
         return injector;
 335  
     }
 336  
 
 337  
     public void setInjector(Injector injector) {
 338  0
         this.injector = injector;
 339  0
     }
 340  
 
 341  
     public ComponentResolver getComponentResolver() {
 342  411
         if (componentResolver == null) {
 343  243
             componentResolver = createComponentResolver();
 344  
         }
 345  411
         return componentResolver;
 346  
     }
 347  
 
 348  
     public void setComponentResolver(ComponentResolver componentResolver) {
 349  0
         this.componentResolver = componentResolver;
 350  0
     }
 351  
 
 352  
     public LanguageResolver getLanguageResolver() {
 353  267
         return languageResolver;
 354  
     }
 355  
 
 356  
     public void setLanguageResolver(LanguageResolver languageResolver) {
 357  0
         this.languageResolver = languageResolver;
 358  0
     }
 359  
 
 360  
     public boolean isAutoCreateComponents() {
 361  0
         return autoCreateComponents;
 362  
     }
 363  
 
 364  
     public void setAutoCreateComponents(boolean autoCreateComponents) {
 365  3
         this.autoCreateComponents = autoCreateComponents;
 366  3
     }
 367  
 
 368  
     public Registry getRegistry() {
 369  18
         if (registry == null) {
 370  0
             registry = createRegistry();
 371  
         }
 372  18
         return registry;
 373  
     }
 374  
 
 375  
     public void setRegistry(Registry registry) {
 376  0
         this.registry = registry;
 377  0
     }
 378  
 
 379  
     public LifecycleStrategy getLifecycleStrategy() {
 380  0
         return lifecycleStrategy;
 381  
     }
 382  
 
 383  
     public void setLifecycleStrategy(LifecycleStrategy lifecycleStrategy) {
 384  0
         this.lifecycleStrategy = lifecycleStrategy;
 385  0
     }
 386  
 
 387  
     // Implementation methods
 388  
     // -----------------------------------------------------------------------
 389  
 
 390  
     protected void doStart() throws Exception {
 391  228
         forceLazyInitialization();
 392  228
         if (components != null) {
 393  228
             for (Component component : components.values()) {
 394  345
                 startServices(component);
 395  345
             }
 396  
         }
 397  228
         startRoutes(routes);
 398  228
     }
 399  
 
 400  
     protected void doStop() throws Exception {
 401  225
         stopServices(servicesToClose);
 402  225
         if (components != null) {
 403  225
             for (Component component : components.values()) {
 404  366
                 stopServices(component);
 405  366
             }
 406  
         }
 407  225
     }
 408  
 
 409  
     protected void startRoutes(Collection<Route> routeList) throws Exception {
 410  228
         if (routeList != null) {
 411  228
             for (Route<Exchange> route : routeList) {
 412  225
                 List<Service> services = route.getServicesForRoute();
 413  225
                 servicesToClose.addAll(services);
 414  225
                 startServices(services);
 415  225
             }
 416  
         }
 417  228
     }
 418  
 
 419  
     /**
 420  
      * Lets force some lazy initialization to occur upfront before we start any
 421  
      * components and create routes
 422  
      */
 423  
     protected void forceLazyInitialization() {
 424  228
         getExchangeConverter();
 425  228
         getInjector();
 426  228
         getLanguageResolver();
 427  228
         getTypeConverter();
 428  228
     }
 429  
 
 430  
     /**
 431  
      * Lazily create a default implementation
 432  
      */
 433  
     protected ExchangeConverter createExchangeConverter() {
 434  228
         return new DefaultExchangeConverter();
 435  
     }
 436  
 
 437  
     /**
 438  
      * Lazily create a default implementation
 439  
      */
 440  
     protected TypeConverter createTypeConverter() {
 441  279
         return new DefaultTypeConverter(getInjector());
 442  
     }
 443  
 
 444  
     /**
 445  
      * Lazily create a default implementation
 446  
      */
 447  
     protected Injector createInjector() {
 448  324
         FactoryFinder finder = new FactoryFinder();
 449  
         try {
 450  324
             return (Injector)finder.newInstance("Injector");
 451  324
         } catch (NoFactoryAvailableException e) {
 452  
             // lets use the default
 453  324
             return new ReflectionInjector();
 454  0
         } catch (IllegalAccessException e) {
 455  0
             throw new RuntimeCamelException(e);
 456  0
         } catch (InstantiationException e) {
 457  0
             throw new RuntimeCamelException(e);
 458  0
         } catch (IOException e) {
 459  0
             throw new RuntimeCamelException(e);
 460  0
         } catch (ClassNotFoundException e) {
 461  0
             throw new RuntimeCamelException(e);
 462  
         }
 463  
     }
 464  
 
 465  
     /**
 466  
      * Lazily create a default implementation
 467  
      */
 468  
     protected ComponentResolver createComponentResolver() {
 469  243
         return new DefaultComponentResolver();
 470  
     }
 471  
 
 472  
     /**
 473  
      * Lazily create a default implementation
 474  
      */
 475  
     protected Registry createRegistry() {
 476  0
         return new JndiRegistry();
 477  
     }
 478  
 
 479  
     /**
 480  
      * A pluggable strategy to allow an endpoint to be created without requiring
 481  
      * a component to be its factory, such as for looking up the URI inside some
 482  
      * {@link Registry}
 483  
      * 
 484  
      * @param uri the uri for the endpoint to be created
 485  
      * @return the newly created endpoint or null if it could not be resolved
 486  
      */
 487  
     protected Endpoint createEndpoint(String uri) {
 488  6
         Object value = getRegistry().lookup(uri);
 489  6
         if (value instanceof Endpoint) {
 490  0
             return (Endpoint)value;
 491  6
         } else if (value instanceof Processor) {
 492  0
             return new ProcessorEndpoint(uri, this, (Processor)value);
 493  6
         } else if (value != null) {
 494  0
             return convertBeanToEndpoint(uri, value);
 495  
         }
 496  6
         return null;
 497  
     }
 498  
 
 499  
     /**
 500  
      * Attempt to convert the bean from a {@link Registry} to an endpoint using
 501  
      * some kind of transformation or wrapper
 502  
      * 
 503  
      * @param uri the uri for the endpoint (and name in the registry)
 504  
      * @param bean the bean to be converted to an endpoint, which will be not
 505  
      *                null
 506  
      * @return a new endpoint
 507  
      */
 508  
     protected Endpoint convertBeanToEndpoint(String uri, Object bean) {
 509  0
         throw new IllegalArgumentException("uri: " + uri + " bean: " + bean
 510  
                                            + " could not be converted to an Endpoint");
 511  
     }
 512  
 
 513  
 }