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   * @see <a
66   *      href="http://docs.google.com/Doc?id=dd2fhx4z_5df5hw8">User's&nbsp;Guide<
67   *      / a >
68   * @author baba
69   */
70  public class GuicePlugin extends AbstractPlugin {
71  
72  	/** モジュールの WEB 配備記述子の初期化パラメータ名 */
73  	public static final String MODULE_INIT_PARAM_NAME = "cubby.guice.module";
74  
75  	/** インジェクタ。 */
76  	private Injector injector;
77  
78  	/**
79  	 * インスタンス化します。
80  	 */
81  	public GuicePlugin() {
82  		support(BeanDescProvider.class);
83  		support(ContainerProvider.class);
84  		support(RequestParserProvider.class);
85  		support(PathResolverProvider.class);
86  		support(ConverterProvider.class);
87  	}
88  
89  	/**
90  	 * {@inheritDoc}
91  	 */
92  	@Override
93  	public void initialize(final ServletContext servletContext) {
94  		final String moduleClassNames = servletContext
95  				.getInitParameter(MODULE_INIT_PARAM_NAME);
96  		if (moduleClassNames == null) {
97  			throw new IllegalModuleException("No context parameter \""
98  					+ MODULE_INIT_PARAM_NAME + "\", please set Module FQCN");
99  		}
100 
101 		final List<Module> modules = new ArrayList<Module>();
102 		for (final String moduleClassName : moduleClassNames.split(",")) {
103 			final Module module = createModule(moduleClassName.trim());
104 			modules.add(module);
105 		}
106 		this.injector = Guice.createInjector(modules.toArray(new Module[0]));
107 	}
108 
109 	/**
110 	 * {@inheritDoc}
111 	 */
112 	public <S extends Provider> S getProvider(final Class<S> service) {
113 		if (this.isSupport(service)) {
114 			return service.cast(injector.getInstance(service));
115 		} else {
116 			return null;
117 		}
118 	}
119 
120 	/**
121 	 * インジェクタを設定します。
122 	 * 
123 	 * @param injector
124 	 *            インジェクタ
125 	 */
126 	public void setInjector(final Injector injector) {
127 		this.injector = injector;
128 	}
129 
130 	/**
131 	 * 指定されたクラス名のモジュールを生成します。
132 	 * 
133 	 * @param moduleClassName
134 	 *            モジュールのクラス名
135 	 * @return インジェクタ
136 	 */
137 	protected Module createModule(final String moduleClassName) {
138 		final ClassLoader loader = Thread.currentThread()
139 				.getContextClassLoader();
140 		try {
141 			final Class<?> clazz = Class.forName(moduleClassName, true, loader);
142 			final Module module = Module.class.cast(clazz.newInstance());
143 			return module;
144 		} catch (final ClassNotFoundException e) {
145 			throw new IllegalArgumentException("Illegal module "
146 					+ moduleClassName, e);
147 		} catch (final InstantiationException e) {
148 			throw new IllegalArgumentException("Illegal module "
149 					+ moduleClassName, e);
150 		} catch (final IllegalAccessException e) {
151 			throw new IllegalArgumentException("Illegal module "
152 					+ moduleClassName, e);
153 		}
154 	}
155 
156 }