View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.plugins.guice;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import javax.servlet.ServletContext;
22  
23  import org.seasar.cubby.plugin.AbstractPlugin;
24  import org.seasar.cubby.spi.BeanDescProvider;
25  import org.seasar.cubby.spi.ContainerProvider;
26  import org.seasar.cubby.spi.ConverterProvider;
27  import org.seasar.cubby.spi.PathResolverProvider;
28  import org.seasar.cubby.spi.Provider;
29  import org.seasar.cubby.spi.RequestParserProvider;
30  
31  import com.google.inject.Guice;
32  import com.google.inject.Injector;
33  import com.google.inject.Module;
34  
35  /**
36   * Cubby を <a href="http://code.google.com/p/google-guice/">Google Guice</a>
37   * に統合するためのプラグインです。
38   * <p>
39   * アプリケーションが使用するモジュールのクラス名を WEB 配備記述子の初期化パラメータ {@value #MODULE_INIT_PARAM_NAME}
40   * に指定してください。
41   * </p>
42   * <p>
43   * 例
44   * 
45   * <pre>
46   * &lt;context-param&gt;
47   *   &lt;param-name&gt;{@value #MODULE_INIT_PARAM_NAME}&lt;/paanm-name&gt;
48   *   &lt;param-value&gt;com.example.ApplicationModule&lt;/param-value&gt;
49   * &lt;/context-param&gt;
50   * </pre>
51   * 
52   * </p>
53   * <p>
54   * このプラグインが提供するプロバイダは以下の通りです。
55   * <ul>
56   * <li>{@link BeanDescProvider}</li>
57   * <li>{@link ContainerProvider}</li>
58   * <li>{@link RequestParserProvider}</li>
59   * <li>{@link PathResolverProvider}</li>
60   * <li>{@link ConverterProvider}</li>
61   * </ul>
62   * </p>
63   * 
64   * @see <a href="http://code.google.com/p/google-guice/">Google&nbsp;Guice</a>
65   * @author baba
66   */
67  public class GuicePlugin extends AbstractPlugin {
68  
69  	/** モジュールの WEB 配備記述子の初期化パラメータ名 */
70  	public static final String MODULE_INIT_PARAM_NAME = "cubby.guice.module";
71  
72  	/** インジェクタ。 */
73  	private Injector injector;
74  
75  	/**
76  	 * インスタンス化します。
77  	 */
78  	public GuicePlugin() {
79  		support(BeanDescProvider.class);
80  		support(ContainerProvider.class);
81  		support(RequestParserProvider.class);
82  		support(PathResolverProvider.class);
83  		support(ConverterProvider.class);
84  	}
85  
86  	/**
87  	 * {@inheritDoc}
88  	 */
89  	@Override
90  	public void initialize(final ServletContext servletContext)
91  			throws Exception {
92  		super.initialize(servletContext);
93  		final String moduleClassNames = servletContext
94  				.getInitParameter(MODULE_INIT_PARAM_NAME);
95  		if (moduleClassNames == null) {
96  			throw new IllegalModuleException("No context parameter \""
97  					+ MODULE_INIT_PARAM_NAME + "\", please set Module FQCN");
98  		}
99  
100 		final List<Module> modules = new ArrayList<Module>();
101 		for (final String moduleClassName : moduleClassNames.split(",")) {
102 			final Module module = createModule(moduleClassName.trim());
103 			modules.add(module);
104 		}
105 		this.injector = Guice.createInjector(modules);
106 	}
107 
108 	/**
109 	 * {@inheritDoc}
110 	 */
111 	public <S extends Provider> S getProvider(final Class<S> service) {
112 		if (this.isSupport(service)) {
113 			return service.cast(injector.getInstance(service));
114 		} else {
115 			return null;
116 		}
117 	}
118 
119 	/**
120 	 * 指定されたクラス名のモジュールを生成します。
121 	 * 
122 	 * @param moduleClassName
123 	 *            モジュールのクラス名
124 	 * @return インジェクタ
125 	 */
126 	protected Module createModule(final String moduleClassName) {
127 		final ClassLoader loader = Thread.currentThread()
128 				.getContextClassLoader();
129 		try {
130 			final Class<?> clazz = Class.forName(moduleClassName, true, loader);
131 			final Module module = Module.class.cast(clazz.newInstance());
132 			return module;
133 		} catch (final ClassNotFoundException e) {
134 			throw new IllegalArgumentException("Illegal module "
135 					+ moduleClassName, e);
136 		} catch (final InstantiationException e) {
137 			throw new IllegalArgumentException("Illegal module "
138 					+ moduleClassName, e);
139 		} catch (final IllegalAccessException e) {
140 			throw new IllegalArgumentException("Illegal module "
141 					+ moduleClassName, e);
142 		}
143 	}
144 
145 	/**
146 	 * インジェクタを取得します。
147 	 * 
148 	 * @return インジェクタ
149 	 */
150 	public Injector getInjector() {
151 		return injector;
152 	}
153 
154 }