View Javadoc

1   /*
2    * $Id: GuiceConfigurationBuilder.java 22231 2011-06-21 09:55:51Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  package org.mule.module.guice;
11  
12  import org.mule.api.MuleContext;
13  import org.mule.api.config.ConfigurationException;
14  import org.mule.config.builders.AbstractConfigurationBuilder;
15  import org.mule.config.i18n.CoreMessages;
16  import org.mule.util.ClassUtils;
17  import org.mule.util.scan.ClasspathScanner;
18  
19  import com.google.inject.Guice;
20  import com.google.inject.Injector;
21  import com.google.inject.Module;
22  import com.google.inject.Stage;
23  
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.List;
27  import java.util.Set;
28  
29  import org.guiceyfruit.mule.MuleModule;
30  
31  
32  /**
33   * Provides the configuration entry point for loading Guice modules into Mule.  Users can pass in an array of
34   * {@link Module} into this builder or provide a base search path that Mule will use to search the
35   * classpath for any modules that implement {@link Module}. The basepath is a path on the classpath.
36   * Note for better performance, any basepath set should be qualified to your application. For example, if your application
37   * has a package com.mycompany.app, its better to set the base path to 'com/mycompany/app' over 'com/' or '/' since they will
38   * search everything on the classpath that matches the specified package.
39   */
40  public class GuiceConfigurationBuilder extends AbstractConfigurationBuilder
41  {
42      public static final String DEFAULT_PACKAGE = "";
43  
44      protected String basepath = DEFAULT_PACKAGE;
45  
46      protected Module[] modules = null;
47  
48      protected Stage stage;
49  
50      protected ClassLoader classLoader;
51  
52      public GuiceConfigurationBuilder()
53      {
54          super();
55          classLoader = Thread.currentThread().getContextClassLoader();
56      }
57  
58      public GuiceConfigurationBuilder(ClassLoader classLoader)
59      {
60          this.classLoader = classLoader;
61      }
62  
63      public GuiceConfigurationBuilder(String basepath)
64      {
65          this();
66          this.basepath = basepath;
67      }
68  
69      public GuiceConfigurationBuilder(String basepath, ClassLoader classLoader)
70      {
71          this.basepath = basepath;
72          this.classLoader = classLoader;
73      }
74  
75      public GuiceConfigurationBuilder(Module... modules)
76      {
77          this.modules = modules;
78      }
79  
80      public GuiceConfigurationBuilder(Stage stage, Module... modules)
81      {
82          this.stage = stage;
83          this.modules = modules;
84      }
85  
86      @Override
87      protected void doConfigure(MuleContext muleContext) throws Exception
88      {
89  
90          List<Module> allModules = getSystemModules(muleContext);
91  
92          Injector injector;
93          if (basepath != null && basepath.startsWith("/"))
94          {
95              basepath = basepath.substring(1);
96          }
97  
98          //No modules were set explicitly on this ConfigurationBuilder so we now try and discover
99          //modules and {@link GuiceModuleFactory} instances on the classpath
100         if (modules == null)
101         {
102             ClasspathScanner scanner = new ClasspathScanner(classLoader, basepath);
103             Set<Class<Module>> classes = scanner.scanFor(Module.class);
104             Set<Class<GuiceModuleFactory>> factories = scanner.scanFor(GuiceModuleFactory.class);
105 
106             if (classes.size() == 0 && factories.size() == 0)
107             {
108                 try
109                 {
110                     basepath = getClass().getClassLoader().getResources(basepath).toString();
111                 }
112                 catch (Exception e)
113                 {
114                     basepath = (basepath.equals("") ? "/" : basepath);
115                 }
116                 //lets just log a noticeable exception as a warning since the Guice build can compliment other configuration builders
117                 logger.warn(new ConfigurationException(CoreMessages.createStaticMessage("There are no Guice modules or module factories on the classpath under: " + basepath)));
118                 return;
119             }
120 
121             for (Class<Module> moduleClass : classes)
122             {
123                 allModules.add(ClassUtils.instanciateClass(moduleClass, ClassUtils.NO_ARGS));
124             }
125             for (Class<GuiceModuleFactory> factoryClass : factories)
126             {
127                 GuiceModuleFactory factory = ClassUtils.instanciateClass(factoryClass, ClassUtils.NO_ARGS);
128                 allModules.add(factory.createModule());
129             }
130         }
131         else
132         {
133             allModules.addAll(Arrays.asList(modules));
134         }
135 
136         for (Module module : allModules)
137         {
138             if (module instanceof AbstractMuleGuiceModule)
139             {
140                 ((AbstractMuleGuiceModule) module).setMuleContext(muleContext);
141             }
142         }
143 
144         if (stage != null)
145         {
146             injector = Guice.createInjector(stage, allModules);
147         }
148         else
149         {
150             injector = Guice.createInjector(allModules);
151         }
152         
153         GuiceRegistry registry = new GuiceRegistry(injector, muleContext);
154         registry.initialise();
155         muleContext.addRegistry(registry);
156     }
157 
158     protected List<Module> getSystemModules(MuleContext muleContext)
159     {
160         List<Module> systemModules = new ArrayList<Module>();
161         //JSR-250 lifecycle and @Resource annotation support & Mule lifecycle support
162         systemModules.add(new MuleModule());
163         systemModules.add(new MuleSupportModule(muleContext));
164         return systemModules;
165     }
166 }