View Javadoc

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.filter;
17  
18  import java.io.IOException;
19  import java.util.ArrayList;
20  import java.util.List;
21  import java.util.StringTokenizer;
22  import java.util.regex.Pattern;
23  
24  import javax.servlet.Filter;
25  import javax.servlet.FilterChain;
26  import javax.servlet.FilterConfig;
27  import javax.servlet.ServletException;
28  import javax.servlet.ServletRequest;
29  import javax.servlet.ServletResponse;
30  import javax.servlet.http.HttpServletRequest;
31  import javax.servlet.http.HttpServletResponse;
32  
33  import org.seasar.cubby.internal.controller.RequestProcessor;
34  import org.seasar.cubby.internal.controller.impl.RequestProcessorImpl;
35  import org.seasar.cubby.internal.routing.Router;
36  import org.seasar.cubby.internal.routing.impl.RouterImpl;
37  import org.seasar.cubby.internal.util.StringUtils;
38  import org.seasar.cubby.routing.PathInfo;
39  
40  /**
41   * Cubby 用のフィルター。
42   * <p>
43   * 要求を解析し、対応するアクションが登録されている場合はアクションを実行します。
44   * </p>
45   * 
46   * @author agata
47   * @author baba
48   * @since 1.0.0
49   */
50  public class CubbyFilter implements Filter {
51  
52  	/** ルーティングの対象外とするパスの初期パラメータ名。 */
53  	public static final String IGNORE_PATH_PATTERN = "ignorePathPattern";
54  
55  	/** ルーティングの対象外とするパスの正規表現パターンのリスト。 */
56  	private final List<Pattern> ignorePathPatterns = new ArrayList<Pattern>();
57  
58  	/** ルーター。 */
59  	private final Router router = new RouterImpl();
60  
61  	/** 要求を処理します。 */
62  	private final RequestProcessor requestProcessor = new RequestProcessorImpl();
63  
64  	/**
65  	 * このフィルタを初期化します。
66  	 * <p>
67  	 * 使用可能な初期化パラメータ
68  	 * <table>
69  	 * <thead>
70  	 * <th>初期化パラメータ名</th>
71  	 * <th>初期化パラメータの値</th>
72  	 * <th>例</th>
73  	 * </thead> <thead>
74  	 * <tr>
75  	 * <td>{@link #IGNORE_PATH_PATTERN}</td>
76  	 * <td>ルーティングの対象外とするパスの正規表現をカンマ区切りで指定します。 HotDeploy
77  	 * 時のパフォーマンスにも影響するので、画像やスクリプトを特定のディレクトリに
78  	 * 格納していてアクションを実行するパスと明確に区別できる場合はできる限り指定するようにしてください。</td>
79  	 * <td>
80  	 * 
81  	 * <pre>
82  	 * &lt;param-name&gt;ignorePathPattern&amp;lt/param-name&gt;
83  	 * &lt;param-value&gt;/img/.*,/js/.*&lt;param-name&gt;
84  	 * </pre>
85  	 * 
86  	 * この例では /img と /js 以下のパスをルーティングの対象外にします。</td>
87  	 * </tr>
88  	 * </thead>
89  	 * </p>
90  	 * 
91  	 * @param config
92  	 *            フィルタ設定のためのオブジェクト
93  	 * @throws ServletException
94  	 *             初期化処理で例外が発生した場合
95  	 */
96  	public void init(final FilterConfig config) throws ServletException {
97  		final String ignorePathPatternString = config
98  				.getInitParameter(IGNORE_PATH_PATTERN);
99  		if (!StringUtils.isEmpty(ignorePathPatternString)) {
100 
101 			for (final StringTokenizer tokenizer = new StringTokenizer(
102 					ignorePathPatternString, ","); tokenizer.hasMoreTokens();) {
103 				final String token = tokenizer.nextToken();
104 				final Pattern pattern = Pattern.compile(token);
105 				ignorePathPatterns.add(pattern);
106 			}
107 		}
108 	}
109 
110 	/**
111 	 * {@inheritDoc}
112 	 */
113 	public void destroy() {
114 	}
115 
116 	/**
117 	 * フィルター処理を行います。
118 	 * <p>
119 	 * 要求された URI に対応する情報が {@link Router} から取得できた場合は、 {@link RequestProcessor}
120 	 * によってリクエストを処理します。URI に対応する情報が取得できなかった場合はフィルタチェインで次のフィルタに処理を委譲します。
121 	 * </p>
122 	 * 
123 	 * @param req
124 	 *            要求
125 	 * @param res
126 	 *            応答
127 	 * @param chain
128 	 *            フィルターチェーン
129 	 * @throws IOException
130 	 *             要求の転送や要求のチェーンがこの例外をスローする場合
131 	 * @throws ServletException
132 	 *             要求の転送や要求のチェーンがこの例外をスローする場合
133 	 * @see Router#routing(HttpServletRequest, HttpServletResponse, List)
134 	 * @see RequestProcessor#process(HttpServletRequest, HttpServletResponse,
135 	 *      PathInfo)
136 	 */
137 	public void doFilter(final ServletRequest req, final ServletResponse res,
138 			final FilterChain chain) throws IOException, ServletException {
139 		final HttpServletRequest request = (HttpServletRequest) req;
140 		final HttpServletResponse response = (HttpServletResponse) res;
141 		final PathInfo pathInfo = router.routing(request, response,
142 				ignorePathPatterns);
143 		if (pathInfo != null) {
144 			try {
145 				requestProcessor.process(request, response, pathInfo);
146 			} catch (final Exception e) {
147 				if (e instanceof IOException) {
148 					throw (IOException) e;
149 				} else if (e instanceof ServletException) {
150 					throw (ServletException) e;
151 				} else {
152 					throw new ServletException(e);
153 				}
154 			}
155 		} else {
156 			chain.doFilter(request, response);
157 		}
158 	}
159 
160 }