View Javadoc

1   /*
2    * $Id: GuiceConfigurationBuilder.java 20321 2010-11-24 15:21:24Z dfeist $
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      protected void doConfigure(MuleContext muleContext) throws Exception
87      {
88  
89          List<Module> allModules = getSystemModules(muleContext);
90  
91          Injector injector;
92          if (basepath != null && basepath.startsWith("/"))
93          {
94              basepath = basepath.substring(1);
95          }
96  
97          //No modules were set explicitly on this ConfigurationBuilder so we now try and discover
98          //modules and {@link GuiceModuleFactory} instances on the classpath
99          if (modules == null)
100         {
101             ClasspathScanner scanner = new ClasspathScanner(classLoader, basepath);
102             Set<Class> classes = scanner.scanFor(Module.class);
103             Set<Class> factories = scanner.scanFor(GuiceModuleFactory.class);
104 
105             if (classes.size() == 0 && factories.size() == 0)
106             {
107                 try
108                 {
109                     basepath = getClass().getClassLoader().getResources(basepath).toString();
110                 }
111                 catch (Exception e)
112                 {
113                     basepath = (basepath.equals("") ? "/" : basepath);
114                 }
115                 //lets just log a noticeable exception as a warning since the Guice build can compliment other configuration builders
116                 logger.warn(new ConfigurationException(CoreMessages.createStaticMessage("There are no Guice modules or module factories on the classpath under: " + basepath)));
117                 return;
118             }
119 
120             for (Class moduleClass : classes)
121             {
122                 allModules.add((Module) ClassUtils.instanciateClass(moduleClass, ClassUtils.NO_ARGS));
123             }
124             for (Class factoryClass : factories)
125             {
126                 GuiceModuleFactory factory = (GuiceModuleFactory) ClassUtils.instanciateClass(factoryClass, ClassUtils.NO_ARGS);
127                 allModules.add(factory.createModule());
128             }
129         }
130         else
131         {
132             allModules.addAll(Arrays.asList(modules));
133         }
134 
135         for (Module module : allModules)
136         {
137             if (module instanceof AbstractMuleGuiceModule)
138             {
139                 ((AbstractMuleGuiceModule) module).setMuleContext(muleContext);
140             }
141         }
142 
143         if (stage != null)
144         {
145             injector = Guice.createInjector(stage, allModules);
146         }
147         else
148         {
149             injector = Guice.createInjector(allModules);
150         }
151         
152         GuiceRegistry registry = new GuiceRegistry(injector, muleContext);
153         registry.initialise();
154         muleContext.addRegistry(registry);
155     }
156 
157     protected List<Module> getSystemModules(MuleContext muleContext)
158     {
159         List<Module> modules = new ArrayList<Module>();
160         //JSR-250 lifecycle and @Resource annotation support & Mule lifecycle support
161         modules.add(new MuleModule());
162         modules.add(new MuleSupportModule(muleContext));
163         return modules;
164     }
165 }