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 static org.easymock.EasyMock.anyObject;
19  import static org.easymock.EasyMock.createNiceMock;
20  import static org.easymock.EasyMock.expect;
21  import static org.easymock.EasyMock.expectLastCall;
22  import static org.easymock.EasyMock.getCurrentArguments;
23  import static org.easymock.EasyMock.replay;
24  import static org.junit.Assert.assertNotSame;
25  import static org.junit.Assert.assertSame;
26  import static org.junit.Assert.assertTrue;
27  import static org.junit.Assert.fail;
28  
29  import java.io.IOException;
30  import java.util.Enumeration;
31  import java.util.Hashtable;
32  import java.util.Vector;
33  
34  import javax.servlet.FilterChain;
35  import javax.servlet.FilterConfig;
36  import javax.servlet.ServletContext;
37  import javax.servlet.ServletContextEvent;
38  import javax.servlet.ServletException;
39  import javax.servlet.ServletRequest;
40  import javax.servlet.ServletResponse;
41  import javax.servlet.http.HttpServletRequest;
42  import javax.servlet.http.HttpServletResponse;
43  
44  import org.apache.commons.fileupload.FileUpload;
45  import org.easymock.IAnswer;
46  import org.junit.Test;
47  import org.seasar.cubby.action.ActionClass;
48  import org.seasar.cubby.action.ActionResult;
49  import org.seasar.cubby.converter.impl.BigDecimalConverter;
50  import org.seasar.cubby.internal.controller.ThreadContext;
51  import org.seasar.cubby.internal.controller.ThreadContext.Command;
52  import org.seasar.cubby.plugin.PluginRegistry;
53  import org.seasar.cubby.routing.PathResolver;
54  import org.seasar.cubby.routing.PathTemplateParser;
55  import org.seasar.cubby.spi.ContainerProvider;
56  import org.seasar.cubby.spi.ConverterProvider;
57  import org.seasar.cubby.spi.PathResolverProvider;
58  import org.seasar.cubby.spi.ProviderFactory;
59  import org.seasar.cubby.spi.container.Container;
60  
61  import com.google.inject.AbstractModule;
62  import com.google.inject.ConfigurationException;
63  import com.google.inject.Inject;
64  import com.google.inject.Injector;
65  import com.google.inject.Singleton;
66  import com.google.inject.servlet.GuiceFilter;
67  import com.google.inject.servlet.RequestScoped;
68  import com.google.inject.servlet.ServletModule;
69  import com.google.inject.util.Modules;
70  
71  public class CubbyModuleTest {
72  
73  	@Test
74  	public void configure() throws Exception {
75  		final HttpServletRequest request = createNiceMock(HttpServletRequest.class);
76  		final HttpServletResponse response = createNiceMock(HttpServletResponse.class);
77  		final ServletContext servletContext = createNiceMock(ServletContext.class);
78  		expect(servletContext.getInitParameter("cubby.guice.module"))
79  				.andStubReturn(TestModule.class.getName());
80  		final Hashtable<String, Object> attributes = new Hashtable<String, Object>();
81  		expect(servletContext.getAttribute((String) anyObject()))
82  				.andStubAnswer(new IAnswer<Object>() {
83  
84  					public Object answer() throws Throwable {
85  						return attributes.get(getCurrentArguments()[0]);
86  					}
87  
88  				});
89  		servletContext.setAttribute((String) anyObject(), anyObject());
90  		expectLastCall().andAnswer(new IAnswer<Void>() {
91  
92  			public Void answer() throws Throwable {
93  				attributes.put((String) getCurrentArguments()[0],
94  						getCurrentArguments()[1]);
95  				return null;
96  			}
97  
98  		});
99  		replay(servletContext);
100 
101 		final CubbyGuiceServletContextListener cubbyGuiceServletContextListener = new CubbyGuiceServletContextListener();
102 		cubbyGuiceServletContextListener.contextInitialized(new ServletContextEvent(servletContext));
103 
104 		final GuiceFilter guiceFilter = new GuiceFilter();
105 		guiceFilter.init(new FilterConfig() {
106 
107 			public String getFilterName() {
108 				return "guice";
109 			}
110 
111 			public String getInitParameter(final String name) {
112 				return null;
113 			}
114 
115 			@SuppressWarnings("unchecked")
116 			public Enumeration getInitParameterNames() {
117 				return new Vector<String>().elements();
118 			}
119 
120 			public ServletContext getServletContext() {
121 				return servletContext;
122 			}
123 
124 		});
125 
126 		final FilterChain chain = new FilterChain() {
127 
128 			public void doFilter(final ServletRequest request,
129 					final ServletResponse response) throws IOException,
130 					ServletException {
131 				final PluginRegistry pluginRegistry = PluginRegistry
132 						.getInstance();
133 				final GuicePlugin guicePlugin = new GuicePlugin();
134 				try {
135 					guicePlugin.initialize(servletContext);
136 					guicePlugin.ready();
137 					pluginRegistry.register(guicePlugin);
138 				} catch (final Exception e) {
139 					throw new ServletException(e);
140 				}
141 
142 				final Injector injector = guicePlugin.getInjector();
143 				System.out.println(injector);
144 
145 				final PathResolverProvider pathResolverProvider = ProviderFactory
146 						.get(PathResolverProvider.class);
147 				final PathResolver pathResolver = pathResolverProvider
148 						.getPathResolver();
149 				System.out.println(pathResolver);
150 
151 				final PathTemplateParser pathTemplateParser = injector
152 						.getInstance(PathTemplateParser.class);
153 				System.out.println(pathTemplateParser);
154 				assertTrue(pathTemplateParser instanceof MyPathTemplateParser);
155 
156 				final ContainerProvider containerProvider = ProviderFactory
157 						.get(ContainerProvider.class);
158 				final Container container = containerProvider.getContainer();
159 				final Foo foo = container.lookup(Foo.class);
160 				System.out.println(foo);
161 				System.out.println(foo.pathResolver);
162 
163 				assertSame(pathResolver, foo.pathResolver);
164 
165 				try {
166 					final Baz baz = injector.getInstance(Baz.class);
167 					System.out.println(baz);
168 					fail();
169 				} catch (final ConfigurationException e) {
170 					// ok
171 				}
172 				try {
173 					ThreadContext.runInContext((HttpServletRequest) request,
174 							(HttpServletResponse) response, new Command() {
175 
176 								public void execute(
177 										final HttpServletRequest request,
178 										final HttpServletResponse response)
179 										throws Exception {
180 									final ConverterProvider converterProvider = ProviderFactory
181 											.get(ConverterProvider.class);
182 									System.out.println(converterProvider);
183 									System.out
184 											.println(converterProvider
185 													.getConverter(BigDecimalConverter.class));
186 
187 									final FileUpload fileUpload1 = injector
188 											.getInstance(FileUpload.class);
189 									System.out.println(fileUpload1);
190 									System.out.println(fileUpload1
191 											.getFileItemFactory());
192 
193 									final FileUpload fileUpload2 = injector
194 											.getInstance(FileUpload.class);
195 									System.out.println(fileUpload2);
196 									System.out.println(fileUpload2
197 											.getFileItemFactory());
198 
199 									assertNotSame(fileUpload1, fileUpload2);
200 									assertNotSame(fileUpload1
201 											.getFileItemFactory(), fileUpload2
202 											.getFileItemFactory());
203 								}
204 
205 							});
206 				} catch (final Exception e) {
207 					throw new ServletException(e);
208 				}
209 			}
210 
211 		};
212 		guiceFilter.doFilter(request, response, chain);
213 		cubbyGuiceServletContextListener.contextDestroyed(new ServletContextEvent(servletContext));
214 	}
215 
216 	public static class TestModule extends AbstractModule {
217 
218 		@Override
219 		protected void configure() {
220 			install(new ServletModule());
221 			// install(new AbstractCubbyModule());
222 			install(Modules.override(new CubbyModule(), new FileUploadModule())
223 					.with(new AbstractModule() {
224 
225 						@Override
226 						protected void configure() {
227 							bind(PathTemplateParser.class).to(
228 									MyPathTemplateParser.class).in(
229 									Singleton.class);
230 						}
231 
232 					}));
233 			bind(BarAction.class);
234 
235 			// {
236 			// @Override
237 			// protected PathResolver getPathResolver() {
238 			// return new PathResolverImpl(new PathTemplateParserImpl());
239 			// }
240 			// });
241 		}
242 
243 	}
244 
245 	public static class MyPathTemplateParser implements PathTemplateParser {
246 
247 		public String parse(final String template, final Handler handler) {
248 			return "mytemplateparser";
249 		}
250 
251 	}
252 
253 	public static class Foo {
254 		@Inject
255 		public PathResolver pathResolver;
256 	}
257 
258 	@ActionClass
259 	@RequestScoped
260 	public static class BarAction {
261 		public ActionResult index() {
262 			return null;
263 		}
264 	}
265 
266 	public interface Baz {
267 
268 	}
269 }