1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.Action;
28 import org.seasar.cubby.action.ActionResult;
29 import org.seasar.cubby.action.RequestMethod;
30 import org.seasar.cubby.controller.ClassDetector;
31 import org.seasar.cubby.exception.IllegalRoutingRuntimeException;
32 import org.seasar.cubby.routing.InternalForwardInfo;
33 import org.seasar.cubby.routing.Routing;
34 import org.seasar.extension.unit.S2TestCase;
35 import org.seasar.framework.util.ClassUtil;
36
37 public class PathResolverImplTest extends S2TestCase {
38
39 private PathResolverImpl pathResolver;
40
41 @Override
42 protected void setUp() throws Exception {
43 super.setUp();
44 include(this.getClass().getName().replaceAll("\\.", "/") + ".dicon");
45 }
46
47 public void testGetRoutings() {
48 List<Routing> routings = new ArrayList<Routing>(pathResolver
49 .getRoutings());
50 assertEquals(25, routings.size());
51 }
52
53 public void testAdd() {
54 pathResolver.add("/wiki/edit/{name,.+}", MockAction.class, "update");
55 pathResolver.add("/wiki/{name,.+}", MockAction.class, "update2",
56 RequestMethod.POST);
57 pathResolver.add("/wiki/{name,.+}", MockAction.class, "name",
58 RequestMethod.PUT);
59
60 List<Routing> routings = new ArrayList<Routing>(pathResolver
61 .getRoutings());
62 assertEquals(29, routings.size());
63
64 Iterator<Routing> iterator = routings.iterator();
65
66 Routing routing1 = iterator.next();
67 assertEquals("^/wiki/edit/(.+)$", routing1.getPattern().pattern());
68 assertEquals(RequestMethod.GET, routing1.getRequestMethod());
69 assertEquals(0, routing1.getPriority());
70
71 Routing routing2 = iterator.next();
72 assertEquals("^/wiki/edit/(.+)$", routing2.getPattern().pattern());
73 assertEquals(RequestMethod.POST, routing2.getRequestMethod());
74 assertEquals(1, routing2.getPriority());
75
76 Routing routing3 = iterator.next();
77 assertEquals("^/wiki/(.+)$", routing3.getPattern().pattern());
78 assertEquals(RequestMethod.POST, routing3.getRequestMethod());
79 assertEquals(2, routing3.getPriority());
80
81 Routing routing4 = iterator.next();
82 assertEquals("^/wiki/(.+)$", routing4.getPattern().pattern());
83 assertEquals(RequestMethod.PUT, routing4.getRequestMethod());
84 assertEquals(3, routing4.getPriority());
85
86 Routing routing5 = iterator.next();
87 assertEquals("^/mockPriority/update$", routing5.getPattern().pattern());
88 assertEquals(100, routing5.getPriority());
89 assertEquals(RequestMethod.PUT, routing5.getRequestMethod());
90 }
91
92 public void testRoot1() {
93 InternalForwardInfo info = pathResolver.getInternalForwardInfo("/",
94 "GET", "UTF-8");
95 assertNotNull(info);
96 assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, info
97 .getInternalForwardPath());
98 Map<String, Routing> routings = info.getOnSubmitRoutings();
99 assertNotNull(routings);
100 assertEquals(1, routings.size());
101 Routing routing = routings.get(null);
102 assertEquals(MockRootAction.class, routing.getActionClass());
103 assertEquals(ClassUtil.getMethod(MockRootAction.class, "index",
104 new Class[0]), routing.getMethod());
105 assertEquals(0, routing.getUriParameterNames().size());
106 }
107
108 public void testRoot2() {
109 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
110 "/dummy1", "GET", "UTF-8");
111 assertNotNull(info);
112 assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, info
113 .getInternalForwardPath());
114 Map<String, Routing> routings = info.getOnSubmitRoutings();
115 assertNotNull(routings);
116 assertEquals(1, routings.size());
117 Routing routing = routings.get(null);
118 assertEquals(MockRootAction.class, routing.getActionClass());
119 assertEquals(ClassUtil.getMethod(MockRootAction.class, "dummy1",
120 new Class[0]), routing.getMethod());
121 assertEquals(0, routing.getUriParameterNames().size());
122 }
123
124 public void testDefault1() {
125 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
126 "/mock/update", "GET", "UTF-8");
127 assertNotNull(info);
128 assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, info
129 .getInternalForwardPath());
130 Map<String, Routing> routings = info.getOnSubmitRoutings();
131 assertNotNull(routings);
132 assertEquals(1, routings.size());
133 Routing routing = routings.get(null);
134 assertEquals(MockAction.class, routing.getActionClass());
135 assertEquals(ClassUtil.getMethod(MockAction.class, "update",
136 new Class[0]), routing.getMethod());
137 assertEquals(0, routing.getUriParameterNames().size());
138 }
139
140 public void testDefault2() {
141 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
142 "/mock/create", "GET", "UTF-8");
143 assertNotNull(info);
144 assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, info
145 .getInternalForwardPath());
146 Map<String, Routing> routings = info.getOnSubmitRoutings();
147 assertNotNull(routings);
148 assertEquals(1, routings.size());
149 Routing routing = routings.get(null);
150 assertEquals(MockAction.class, routing.getActionClass());
151 assertEquals(ClassUtil.getMethod(MockAction.class, "insert",
152 new Class[0]), routing.getMethod());
153 assertEquals(0, routing.getUriParameterNames().size());
154 }
155
156 public void testDefault3() {
157 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
158 "/mock/delete/10", "GET", "UTF-8");
159 assertNotNull(info);
160 assertTrue(info.getInternalForwardPath().startsWith(
161 CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
162 Map<String, Routing> routings = info.getOnSubmitRoutings();
163 assertNotNull(routings);
164 assertEquals(1, routings.size());
165 Routing routing = routings.get(null);
166 assertEquals(MockAction.class, routing.getActionClass());
167 assertEquals(ClassUtil.getMethod(MockAction.class, "delete",
168 new Class[0]), routing.getMethod());
169 assertEquals(1, routing.getUriParameterNames().size());
170 Query query = new Query(info.getInternalForwardPath());
171 assertEquals(1, query.getParameterSize());
172 assertEquals(1, query.getParam("value").size());
173 assertEquals("10", query.getParam("value").get(0));
174 }
175
176 public void testDefault4() {
177 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
178 "/mock/delete/a", "GET", "UTF-8");
179 assertNull(info);
180 }
181
182 public void testDefault5() {
183 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
184 "/mock/cubby", "GET", "UTf-8");
185 assertNotNull(info);
186 assertTrue(info.getInternalForwardPath().startsWith(
187 CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
188 Map<String, Routing> routings = info.getOnSubmitRoutings();
189 assertNotNull(routings);
190 assertEquals(1, routings.size());
191 Routing routing = routings.get(null);
192 assertEquals(MockAction.class, routing.getActionClass());
193 assertEquals(ClassUtil
194 .getMethod(MockAction.class, "name", new Class[0]), routing
195 .getMethod());
196 assertEquals(1, routing.getUriParameterNames().size());
197 Query query = new Query(info.getInternalForwardPath());
198 assertEquals(1, query.getParam("name").size());
199 assertEquals("cubby", query.getParam("name").get(0));
200 }
201
202 public void testPath1() {
203 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
204 "/foo/4/update", "GET", "UTF-8");
205 assertNotNull(info);
206 assertTrue(info.getInternalForwardPath().startsWith(
207 CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
208 Map<String, Routing> routings = info.getOnSubmitRoutings();
209 assertNotNull(routings);
210 assertEquals(1, routings.size());
211 Routing routing = routings.get(null);
212 assertEquals(MockPathAction.class, routing.getActionClass());
213 assertEquals(ClassUtil.getMethod(MockPathAction.class, "update",
214 new Class[0]), routing.getMethod());
215 assertEquals(1, routing.getUriParameterNames().size());
216 Query query = new Query(info.getInternalForwardPath());
217 assertEquals(1, query.getParameterSize());
218 assertEquals(1, query.getParam("id").size());
219 assertEquals("4", query.getParam("id").get(0));
220 }
221
222 public void testPath2() {
223 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
224 "/foo/4/create", "GET", "UTF-8");
225 assertNotNull(info);
226 assertTrue(info.getInternalForwardPath().startsWith(
227 CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
228 Map<String, Routing> routings = info.getOnSubmitRoutings();
229 assertNotNull(routings);
230 assertEquals(1, routings.size());
231 Routing routing = routings.get(null);
232 assertEquals(MockPathAction.class, routing.getActionClass());
233 assertEquals(ClassUtil.getMethod(MockPathAction.class, "insert",
234 new Class[0]), routing.getMethod());
235 assertEquals(1, routing.getUriParameterNames().size());
236 Query query = new Query(info.getInternalForwardPath());
237 assertEquals(1, query.getParameterSize());
238 assertEquals(1, query.getParam("id").size());
239 assertEquals("4", query.getParam("id").get(0));
240 }
241
242 public void testPath3() {
243 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
244 "/foo/4/delete/10", "GET", "UTF-8");
245 assertNotNull(info);
246 assertTrue(info.getInternalForwardPath().startsWith(
247 CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
248 Map<String, Routing> routings = info.getOnSubmitRoutings();
249 assertNotNull(routings);
250 assertEquals(1, routings.size());
251 Routing routing = routings.get(null);
252 assertEquals(MockPathAction.class, routing.getActionClass());
253 assertEquals(ClassUtil.getMethod(MockPathAction.class, "delete",
254 new Class[0]), routing.getMethod());
255 assertEquals(2, routing.getUriParameterNames().size());
256 Query query = new Query(info.getInternalForwardPath());
257 assertEquals(2, query.getParameterSize());
258 assertEquals(1, query.getParam("id").size());
259 assertEquals("4", query.getParam("id").get(0));
260 assertEquals(1, query.getParam("value").size());
261 assertEquals("10", query.getParam("value").get(0));
262 }
263
264 public void testPath4() {
265 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
266 "/foo/4/delete/a", "GET", "UTF-8");
267 assertNull(info);
268 }
269
270 public void testPath5() {
271 InternalForwardInfo info = pathResolver.getInternalForwardInfo(
272 "/foo/4/cubby", "GET", "UTF-8");
273 assertNotNull(info);
274 assertTrue(info.getInternalForwardPath().startsWith(
275 CubbyConstants.INTERNAL_FORWARD_DIRECTORY));
276 Map<String, Routing> routings = info.getOnSubmitRoutings();
277 assertNotNull(routings);
278 assertEquals(1, routings.size());
279 Routing routing = routings.get(null);
280 assertEquals(MockPathAction.class, routing.getActionClass());
281 assertEquals(ClassUtil.getMethod(MockPathAction.class, "name",
282 new Class[0]), routing.getMethod());
283 assertEquals(2, routing.getUriParameterNames().size());
284 Query query = new Query(info.getInternalForwardPath());
285 assertEquals(1, query.getParam("id").size());
286 assertEquals("4", query.getParam("id").get(0));
287 assertEquals(1, query.getParam("name").size());
288 assertEquals("cubby", query.getParam("name").get(0));
289 }
290
291 public void testAddAbstractClass() throws Exception {
292 pathResolver.setClassDetector(new ClassDetector() { public void detect() {} });
293
294 try {
295 pathResolver.add("/parent/m1", ParentAction.class, "m1");
296 fail();
297 } catch (IllegalRoutingRuntimeException e) {
298 assertEquals("アクションクラスではないクラスを登録するとエラー(抽象クラス)", "ECUB0002", e.getMessageCode());
299 }
300 try {
301 pathResolver.add("/child/m3", ChildAction.class, "m3");
302 fail();
303 } catch (IllegalRoutingRuntimeException e) {
304 assertEquals("アクションメソッドではないメソッドを登録するとエラー(戻り値がObject)", "ECUB0003", e.getMessageCode());
305 }
306 pathResolver.add("/child/m1", ChildAction.class, "m1");
307 pathResolver.add("/child/m2", ChildAction.class, "m2");
308 assertEquals("正常に登録できたルーティング情報の数", 4, pathResolver.getRoutings().size());
309 assertRouting(pathResolver.getRoutings().get(0), "/child/m1", RequestMethod.GET, ChildAction.class, "m1");
310 assertRouting(pathResolver.getRoutings().get(1), "/child/m1", RequestMethod.POST, ChildAction.class, "m1");
311 assertRouting(pathResolver.getRoutings().get(2), "/child/m2", RequestMethod.GET, ChildAction.class, "m2");
312 assertRouting(pathResolver.getRoutings().get(3), "/child/m2", RequestMethod.POST, ChildAction.class, "m2");
313 }
314
315 private void assertRouting(Routing routing, String path,
316 RequestMethod requestMethod, Class<? extends Action> actionClass, String actionMethod) {
317 assertEquals(path, routing.getActionPath());
318 assertEquals(requestMethod, routing.getRequestMethod());
319 assertEquals(actionClass, routing.getActionClass());
320 assertEquals(actionMethod, routing.getMethod().getName());
321 }
322
323 public abstract class ParentAction extends Action {
324 public ActionResult m1() { return null; }
325 }
326
327 public class ChildAction extends ParentAction {
328 public ActionResult m2() { return null; }
329 public Object m3() { return null; }
330 }
331
332 class Query {
333 private String path;
334 private Map<String, List<String>> params;
335
336 public Query(String path) {
337 String[] tokens = path.split("\\?", 2);
338 switch (tokens.length) {
339 case 1:
340 this.path = tokens[0];
341 this.params = new HashMap<String, List<String>>();
342 break;
343 case 2:
344 this.path = tokens[0];
345 this.params = parseQueryString(tokens[1]);
346
347 break;
348 default:
349 Assert.fail("illegal path " + path);
350 break;
351 }
352 }
353
354 private Map<String, List<String>> parseQueryString(String queryString) {
355 Map<String, List<String>> params = new HashMap<String, List<String>>();
356 String[] tokens = queryString.split("&");
357 for (String token : tokens) {
358 String[] param = parseQueryParameter(token);
359 String name = param[0];
360 String value = param[1];
361 List<String> values;
362 if (params.containsKey(name)) {
363 values = params.get(name);
364 } else {
365 values = new ArrayList<String>();
366 params.put(name, values);
367 }
368 values.add(value);
369 }
370 return params;
371 }
372
373 private String[] parseQueryParameter(String token) {
374 return token.split("=");
375 }
376
377 public String getPath() {
378 return path;
379 }
380
381 public List<String> getParam(String name) {
382 return params.get(name);
383 }
384
385 public boolean isEmptyParameter() {
386 return params.isEmpty();
387 }
388
389 public int getParameterSize() {
390 return params.size();
391 }
392 }
393
394 }