1   /*
2    * Copyright 2004-2008 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.routing.impl;
17  
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Map;
23  
24  import junit.framework.Assert;
25  
26  import org.seasar.cubby.CubbyConstants;
27  import org.seasar.cubby.action.RequestMethod;
28  import org.seasar.cubby.routing.InternalForwardInfo;
29  import org.seasar.cubby.routing.PathResolver;
30  import org.seasar.cubby.routing.Routing;
31  import org.seasar.extension.unit.S2TestCase;
32  import org.seasar.framework.util.ClassUtil;
33  
34  public class PathResolverImplTest extends S2TestCase {
35  
36  	private PathResolver pathResolver;
37  
38  	@Override
39  	protected void setUp() throws Exception {
40  		super.setUp();
41  		include(this.getClass().getName().replaceAll("\\.", "/") + ".dicon");
42  	}
43  
44  	public void testGetRoutings() {
45  		List<Routing> routings = new ArrayList<Routing>(pathResolver
46  				.getRoutings());
47  		assertEquals(25, routings.size());
48  	}
49  
50  	public void testAdd() {
51  		pathResolver.add("/wiki/edit/{name,.+}", MockAction.class, "update");
52  		pathResolver.add("/wiki/{name,.+}", MockAction.class, "update2",
53  				RequestMethod.POST);
54  		pathResolver.add("/wiki/{name,.+}", MockAction.class, "name",
55  				RequestMethod.PUT);
56  
57  		List<Routing> routings = new ArrayList<Routing>(pathResolver
58  				.getRoutings());
59  		assertEquals(29, routings.size());
60  
61  		Iterator<Routing> iterator = routings.iterator();
62  
63  		Routing routing1 = iterator.next();
64  		assertEquals("^/wiki/edit/(.+)$", routing1.getPattern().pattern());
65  		assertEquals(RequestMethod.GET, routing1.getRequestMethod());
66  		assertEquals(0, routing1.getPriority());
67  
68  		Routing routing2 = iterator.next();
69  		assertEquals("^/wiki/edit/(.+)$", routing2.getPattern().pattern());
70  		assertEquals(RequestMethod.POST, routing2.getRequestMethod());
71  		assertEquals(1, routing2.getPriority());
72  
73  		Routing routing3 = iterator.next();
74  		assertEquals("^/wiki/(.+)$", routing3.getPattern().pattern());
75  		assertEquals(RequestMethod.POST, routing3.getRequestMethod());
76  		assertEquals(2, routing3.getPriority());
77  
78  		Routing routing4 = iterator.next();
79  		assertEquals("^/wiki/(.+)$", routing4.getPattern().pattern());
80  		assertEquals(RequestMethod.PUT, routing4.getRequestMethod());
81  		assertEquals(3, routing4.getPriority());
82  
83  		Routing routing5 = iterator.next();
84  		assertEquals("^/mockPriority/update$", routing5.getPattern().pattern());
85  		assertEquals(100, routing5.getPriority());
86  		assertEquals(RequestMethod.PUT, routing5.getRequestMethod());
87  	}
88  
89  	public void testRoot1() {
90  		InternalForwardInfo info = pathResolver.getInternalForwardInfo("/",
91  				"GET");
92  		assertNotNull(info);
93  		assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, info
94  				.getInternalForwardPath());
95  		Map<String, Routing> routings = info.getOnSubmitRoutings();
96  		assertNotNull(routings);
97  		assertEquals(1, routings.size());
98  		Routing routing = routings.get(null);
99  		assertEquals(MockRootAction.class, routing.getActionClass());
100 		assertEquals(ClassUtil.getMethod(MockRootAction.class, "index",
101 				new Class[0]), routing.getMethod());
102 		assertEquals(0, routing.getUriParameterNames().size());
103 	}
104 
105 	public void testRoot2() {
106 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
107 				"/dummy1", "GET");
108 		assertNotNull(info);
109 		assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, info
110 				.getInternalForwardPath());
111 		Map<String, Routing> routings = info.getOnSubmitRoutings();
112 		assertNotNull(routings);
113 		assertEquals(1, routings.size());
114 		Routing routing = routings.get(null);
115 		assertEquals(MockRootAction.class, routing.getActionClass());
116 		assertEquals(ClassUtil.getMethod(MockRootAction.class, "dummy1",
117 				new Class[0]), routing.getMethod());
118 		assertEquals(0, routing.getUriParameterNames().size());
119 	}
120 
121 	public void testDefault1() {
122 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
123 				"/mock/update", "GET");
124 		assertNotNull(info);
125 		assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, info
126 				.getInternalForwardPath());
127 		Map<String, Routing> routings = info.getOnSubmitRoutings();
128 		assertNotNull(routings);
129 		assertEquals(1, routings.size());
130 		Routing routing = routings.get(null);
131 		assertEquals(MockAction.class, routing.getActionClass());
132 		assertEquals(ClassUtil.getMethod(MockAction.class, "update",
133 				new Class[0]), routing.getMethod());
134 		assertEquals(0, routing.getUriParameterNames().size());
135 	}
136 
137 	public void testDefault2() {
138 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
139 				"/mock/create", "GET");
140 		assertNotNull(info);
141 		assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, info
142 				.getInternalForwardPath());
143 		Map<String, Routing> routings = info.getOnSubmitRoutings();
144 		assertNotNull(routings);
145 		assertEquals(1, routings.size());
146 		Routing routing = routings.get(null);
147 		assertEquals(MockAction.class, routing.getActionClass());
148 		assertEquals(ClassUtil.getMethod(MockAction.class, "insert",
149 				new Class[0]), routing.getMethod());
150 		assertEquals(0, routing.getUriParameterNames().size());
151 	}
152 
153 	public void testDefault3() {
154 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
155 				"/mock/delete/10", "GET");
156 		assertNotNull(info);
157 		assertTrue(info.getInternalForwardPath().startsWith(
158 				CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
159 		Map<String, Routing> routings = info.getOnSubmitRoutings();
160 		assertNotNull(routings);
161 		assertEquals(1, routings.size());
162 		Routing routing = routings.get(null);
163 		assertEquals(MockAction.class, routing.getActionClass());
164 		assertEquals(ClassUtil.getMethod(MockAction.class, "delete",
165 				new Class[0]), routing.getMethod());
166 		assertEquals(1, routing.getUriParameterNames().size());
167 		Query query = new Query(info.getInternalForwardPath());
168 		assertEquals(1, query.getParameterSize());
169 		assertEquals(1, query.getParam("value").size());
170 		assertEquals("10", query.getParam("value").get(0));
171 	}
172 
173 	public void testDefault4() {
174 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
175 				"/mock/delete/a", "GET");
176 		assertNull(info);
177 	}
178 
179 	public void testDefault5() {
180 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
181 				"/mock/cubby", "GET");
182 		assertNotNull(info);
183 		assertTrue(info.getInternalForwardPath().startsWith(
184 				CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
185 		Map<String, Routing> routings = info.getOnSubmitRoutings();
186 		assertNotNull(routings);
187 		assertEquals(1, routings.size());
188 		Routing routing = routings.get(null);
189 		assertEquals(MockAction.class, routing.getActionClass());
190 		assertEquals(ClassUtil
191 				.getMethod(MockAction.class, "name", new Class[0]), routing
192 				.getMethod());
193 		assertEquals(1, routing.getUriParameterNames().size());
194 		Query query = new Query(info.getInternalForwardPath());
195 		assertEquals(1, query.getParam("name").size());
196 		assertEquals("cubby", query.getParam("name").get(0));
197 	}
198 
199 	public void testPath1() {
200 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
201 				"/foo/4/update", "GET");
202 		assertNotNull(info);
203 		assertTrue(info.getInternalForwardPath().startsWith(
204 				CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
205 		Map<String, Routing> routings = info.getOnSubmitRoutings();
206 		assertNotNull(routings);
207 		assertEquals(1, routings.size());
208 		Routing routing = routings.get(null);
209 		assertEquals(MockPathAction.class, routing.getActionClass());
210 		assertEquals(ClassUtil.getMethod(MockPathAction.class, "update",
211 				new Class[0]), routing.getMethod());
212 		assertEquals(1, routing.getUriParameterNames().size());
213 		Query query = new Query(info.getInternalForwardPath());
214 		assertEquals(1, query.getParameterSize());
215 		assertEquals(1, query.getParam("id").size());
216 		assertEquals("4", query.getParam("id").get(0));
217 	}
218 
219 	public void testPath2() {
220 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
221 				"/foo/4/create", "GET");
222 		assertNotNull(info);
223 		assertTrue(info.getInternalForwardPath().startsWith(
224 				CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
225 		Map<String, Routing> routings = info.getOnSubmitRoutings();
226 		assertNotNull(routings);
227 		assertEquals(1, routings.size());
228 		Routing routing = routings.get(null);
229 		assertEquals(MockPathAction.class, routing.getActionClass());
230 		assertEquals(ClassUtil.getMethod(MockPathAction.class, "insert",
231 				new Class[0]), routing.getMethod());
232 		assertEquals(1, routing.getUriParameterNames().size());
233 		Query query = new Query(info.getInternalForwardPath());
234 		assertEquals(1, query.getParameterSize());
235 		assertEquals(1, query.getParam("id").size());
236 		assertEquals("4", query.getParam("id").get(0));
237 	}
238 
239 	public void testPath3() {
240 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
241 				"/foo/4/delete/10", "GET");
242 		assertNotNull(info);
243 		assertTrue(info.getInternalForwardPath().startsWith(
244 				CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
245 		Map<String, Routing> routings = info.getOnSubmitRoutings();
246 		assertNotNull(routings);
247 		assertEquals(1, routings.size());
248 		Routing routing = routings.get(null);
249 		assertEquals(MockPathAction.class, routing.getActionClass());
250 		assertEquals(ClassUtil.getMethod(MockPathAction.class, "delete",
251 				new Class[0]), routing.getMethod());
252 		assertEquals(2, routing.getUriParameterNames().size());
253 		Query query = new Query(info.getInternalForwardPath());
254 		assertEquals(2, query.getParameterSize());
255 		assertEquals(1, query.getParam("id").size());
256 		assertEquals("4", query.getParam("id").get(0));
257 		assertEquals(1, query.getParam("value").size());
258 		assertEquals("10", query.getParam("value").get(0));
259 	}
260 
261 	public void testPath4() {
262 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
263 				"/foo/4/delete/a", "GET");
264 		assertNull(info);
265 	}
266 
267 	public void testPath5() {
268 		InternalForwardInfo info = pathResolver.getInternalForwardInfo(
269 				"/foo/4/cubby", "GET");
270 		assertNotNull(info);
271 		assertTrue(info.getInternalForwardPath().startsWith(
272 				CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
273 		Map<String, Routing> routings = info.getOnSubmitRoutings();
274 		assertNotNull(routings);
275 		assertEquals(1, routings.size());
276 		Routing routing = routings.get(null);
277 		assertEquals(MockPathAction.class, routing.getActionClass());
278 		assertEquals(ClassUtil.getMethod(MockPathAction.class, "name",
279 				new Class[0]), routing.getMethod());
280 		assertEquals(2, routing.getUriParameterNames().size());
281 		Query query = new Query(info.getInternalForwardPath());
282 		assertEquals(1, query.getParam("id").size());
283 		assertEquals("4", query.getParam("id").get(0));
284 		assertEquals(1, query.getParam("name").size());
285 		assertEquals("cubby", query.getParam("name").get(0));
286 	}
287 
288 	class Query {
289 		private String path;
290 		private Map<String, List<String>> params;
291 
292 		public Query(String path) {
293 			String[] tokens = path.split("\\?", 2);
294 			switch (tokens.length) {
295 			case 1:
296 				this.path = tokens[0];
297 				this.params = new HashMap<String, List<String>>();
298 				break;
299 			case 2:
300 				this.path = tokens[0];
301 				this.params = parseQueryString(tokens[1]);
302 
303 				break;
304 			default:
305 				Assert.fail("illegal path " + path);
306 				break;
307 			}
308 		}
309 
310 		private Map<String, List<String>> parseQueryString(String queryString) {
311 			Map<String, List<String>> params = new HashMap<String, List<String>>();
312 			String[] tokens = queryString.split("&");
313 			for (String token : tokens) {
314 				String[] param = parseQueryParameter(token);
315 				String name = param[0];
316 				String value = param[1];
317 				List<String> values;
318 				if (params.containsKey(name)) {
319 					values = params.get(name);
320 				} else {
321 					values = new ArrayList<String>();
322 					params.put(name, values);
323 				}
324 				values.add(value);
325 			}
326 			return params;
327 		}
328 
329 		private String[] parseQueryParameter(String token) {
330 			return token.split("=");
331 		}
332 
333 		public String getPath() {
334 			return path;
335 		}
336 
337 		public List<String> getParam(String name) {
338 			return params.get(name);
339 		}
340 
341 		public boolean isEmptyParameter() {
342 			return params.isEmpty();
343 		}
344 
345 		public int getParameterSize() {
346 			return params.size();
347 		}
348 	}
349 
350 }