1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.cubby.internal.routing.impl;
17
18 import static org.seasar.cubby.CubbyConstants.ATTR_ROUTING;
19 import static org.seasar.cubby.internal.util.LogMessages.format;
20
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30
31 import org.seasar.cubby.internal.routing.Router;
32 import org.seasar.cubby.internal.util.RequestUtils;
33 import org.seasar.cubby.plugin.Plugin;
34 import org.seasar.cubby.plugin.PluginRegistry;
35 import org.seasar.cubby.plugin.RoutingInvocation;
36 import org.seasar.cubby.routing.PathInfo;
37 import org.seasar.cubby.routing.PathResolver;
38 import org.seasar.cubby.routing.Routing;
39 import org.seasar.cubby.spi.PathResolverProvider;
40 import org.seasar.cubby.spi.ProviderFactory;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49 public class RouterImpl implements Router {
50
51
52 private static final Logger logger = LoggerFactory
53 .getLogger(RouterImpl.class);
54
55
56 private static final List<Pattern> EMPTY_IGNORE_PATH_PATTERNS = Collections
57 .emptyList();
58
59
60
61
62 public PathInfo routing(final HttpServletRequest request,
63 final HttpServletResponse response) {
64 return routing(request, response, EMPTY_IGNORE_PATH_PATTERNS);
65 }
66
67
68
69
70 public PathInfo routing(final HttpServletRequest request,
71 final HttpServletResponse response,
72 final List<Pattern> ignorePathPatterns) {
73 final String path = RequestUtils.getPath(request);
74 if (logger.isDebugEnabled()) {
75 logger.debug(format("DCUB0006", path));
76 }
77
78 final Routing routing = RequestUtils
79 .getAttribute(request, ATTR_ROUTING);
80 if (routing != null) {
81 request.removeAttribute(ATTR_ROUTING);
82 final PathInfo pathInfo = new ForwardFromActionPathInfo(routing);
83 return pathInfo;
84 }
85
86 if (isIgnorePath(path, ignorePathPatterns)) {
87 return null;
88 }
89
90 final PathResolverProvider pathResolverProvider = ProviderFactory
91 .get(PathResolverProvider.class);
92 final PathResolver pathResolver = pathResolverProvider
93 .getPathResolver();
94 final RoutingInvocation routingInvocation = new RoutingInvocationImpl(
95 path, pathResolver, request, response);
96 try {
97 return routingInvocation.proceed();
98 } catch (final Exception e) {
99 logger.warn("routing failed.", e);
100 return null;
101 }
102 }
103
104
105
106
107
108
109 static class RoutingInvocationImpl implements RoutingInvocation {
110
111
112 private final String path;
113
114
115 private final PathResolver pathResolver;
116
117
118 private final HttpServletRequest request;
119
120
121 private final HttpServletResponse response;
122
123
124 private final Iterator<Plugin> pluginsIterator;
125
126
127
128
129
130
131
132
133
134
135
136
137
138 public RoutingInvocationImpl(final String path,
139 final PathResolver pathResolver,
140 final HttpServletRequest request,
141 final HttpServletResponse response) {
142 this.path = path;
143 this.pathResolver = pathResolver;
144 this.request = request;
145 this.response = response;
146
147 final PluginRegistry pluginRegistry = PluginRegistry.getInstance();
148 this.pluginsIterator = pluginRegistry.getPlugins().iterator();
149 }
150
151
152
153
154 public PathInfo proceed() throws Exception {
155 if (pluginsIterator.hasNext()) {
156 final Plugin plugin = pluginsIterator.next();
157 return plugin.invokeRouting(this);
158 } else {
159 final PathInfo pathInfo = pathResolver.getPathInfo(path,
160 request.getMethod(), request.getCharacterEncoding());
161 return pathInfo;
162 }
163 }
164
165
166
167
168 public String getPath() {
169 return path;
170 }
171
172
173
174
175 public PathResolver getPathResolver() {
176 return pathResolver;
177 }
178
179
180
181
182 public HttpServletRequest getRequest() {
183 return request;
184 }
185
186
187
188
189 public HttpServletResponse getResponse() {
190 return response;
191 }
192
193 }
194
195
196
197
198
199
200
201
202
203
204
205 private boolean isIgnorePath(final String path,
206 final List<Pattern> ignorePathPatterns) {
207 for (final Pattern pattern : ignorePathPatterns) {
208 final Matcher matcher = pattern.matcher(path);
209 if (matcher.matches()) {
210 return true;
211 }
212 }
213 return false;
214 }
215
216 static class ForwardFromActionPathInfo implements PathInfo {
217
218 private final Routing routing;
219
220 private final Map<String, String[]> uriParameters = Collections
221 .emptyMap();
222
223 public ForwardFromActionPathInfo(final Routing routing) {
224 this.routing = routing;
225 }
226
227 public Map<String, String[]> getURIParameters() {
228 return uriParameters;
229 }
230
231 public Routing dispatch(final Map<String, Object[]> parameterMap) {
232 return routing;
233 }
234
235 }
236
237 }