View Javadoc

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.filter;
17  
18  import static org.seasar.cubby.CubbyConstants.ATTR_ACTION_CLASS_NAME;
19  import static org.seasar.cubby.CubbyConstants.ATTR_METHOD_NAME;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.List;
25  import java.util.StringTokenizer;
26  import java.util.regex.Matcher;
27  import java.util.regex.Pattern;
28  
29  import javax.servlet.Filter;
30  import javax.servlet.FilterChain;
31  import javax.servlet.FilterConfig;
32  import javax.servlet.RequestDispatcher;
33  import javax.servlet.ServletException;
34  import javax.servlet.ServletRequest;
35  import javax.servlet.ServletResponse;
36  import javax.servlet.http.HttpServletRequest;
37  import javax.servlet.http.HttpServletResponse;
38  
39  import org.seasar.cubby.convention.ForwardInfo;
40  import org.seasar.cubby.convention.PathResolver;
41  import org.seasar.cubby.util.CubbyUtils;
42  import org.seasar.framework.container.S2Container;
43  import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
44  import org.seasar.framework.log.Logger;
45  import org.seasar.framework.util.StringUtil;
46  
47  /**
48   * リクエストされたURLを適切なアクションに振り分けるフィルタ。
49   * <p>
50   * {@link PathResolver} によって {@link ForwardInfo} を抽出し、そこに保持された情報をもとにフォワードします。
51   * </p>
52   * 
53   * @author baba
54   */
55  public class RequestRoutingFilter implements Filter {
56  
57  	private static final Logger logger = Logger
58  			.getLogger(RequestRoutingFilter.class);
59  
60  	private static final Router router = new Router();
61  
62  	private final List<Pattern> ignorePathPatterns = new ArrayList<Pattern>();
63  
64  	public void init(final FilterConfig config) throws ServletException {
65  		final String ignorePathPatternString = config
66  				.getInitParameter("ignorePathPattern");
67  		if (!StringUtil.isEmpty(ignorePathPatternString)) {
68  
69  			for (final StringTokenizer tokenizer = new StringTokenizer(
70  					ignorePathPatternString, ","); tokenizer.hasMoreTokens();) {
71  				final String token = tokenizer.nextToken();
72  				final Pattern pattern = Pattern.compile(token);
73  				ignorePathPatterns.add(pattern);
74  			}
75  		}
76  	}
77  
78  	public void destroy() {
79  	}
80  
81  	public void doFilter(final ServletRequest request,
82  			final ServletResponse response, final FilterChain chain)
83  			throws IOException, ServletException {
84  
85  		final String forwardPath = router.routing((HttpServletRequest) request,
86  				(HttpServletResponse) response, ignorePathPatterns);
87  		if (!StringUtil.isEmpty(forwardPath)) {
88  			if (logger.isDebugEnabled()) {
89  				logger.log("DCUB0001", new Object[] { forwardPath });
90  			}
91  			final RequestDispatcher requestDispatcher = request
92  					.getRequestDispatcher(forwardPath);
93  			requestDispatcher.forward(request, response);
94  		} else {
95  			chain.doFilter(request, response);
96  		}
97  	}
98  
99  	public static class Router {
100 
101 		private static final List<Pattern> EMPTY_IGNORE_PATH_PATTERNS = Collections
102 				.emptyList();
103 
104 		public String routing(final HttpServletRequest request,
105 				final HttpServletResponse response) {
106 			return routing(request, response, EMPTY_IGNORE_PATH_PATTERNS);
107 		}
108 
109 		public String routing(final HttpServletRequest request,
110 				final HttpServletResponse response, List<Pattern> ignorePattern) {
111 			final String path = CubbyUtils.getPath(request);
112 
113 			if (isIgnorePath(path, ignorePattern)) {
114 				return null;
115 			}
116 
117 			final S2Container container = SingletonS2ContainerFactory
118 					.getContainer();
119 			final PathResolver pathResolver = (PathResolver) container
120 					.getComponent(PathResolver.class);
121 
122 			final String forwardPath;
123 			final ForwardInfo forwardInfo = pathResolver.getForwardInfo(path);
124 			if (forwardInfo != null) {
125 				request.setAttribute(ATTR_ACTION_CLASS_NAME, forwardInfo
126 						.getActionClassName());
127 				request.setAttribute(ATTR_METHOD_NAME, forwardInfo
128 						.getMethodName());
129 				forwardPath = forwardInfo.getForwardPath();
130 			} else {
131 				forwardPath = null;
132 			}
133 			return forwardPath;
134 		}
135 
136 		private boolean isIgnorePath(final String path,
137 				List<Pattern> ignorePathPatterns) {
138 			for (final Pattern pattern : ignorePathPatterns) {
139 				final Matcher matcher = pattern.matcher(path);
140 				if (matcher.matches()) {
141 					return true;
142 				}
143 			}
144 			return false;
145 		}
146 
147 	}
148 
149 }