##### Coverage Report - org.seasar.cubby.filter.SendErrorFilter

Classes in this File | Line Coverage | Branch Coverage | Complexity
SendErrorFilter |
100% | 29/29
100% | 12/12
| 2.75;2.75

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.Matcher;
23 |  |
     import java.util.regex.Pattern;
24 |  |
25 |  |
     import javax.servlet.Filter;
26 |  |
     import javax.servlet.FilterChain;
27 |  |
     import javax.servlet.FilterConfig;
28 |  |
     import javax.servlet.ServletException;
29 |  |
     import javax.servlet.ServletRequest;
30 |  |
     import javax.servlet.ServletResponse;
31 |  |
     import javax.servlet.http.HttpServletRequest;
32 |  |
     import javax.servlet.http.HttpServletResponse;
33 |  |
34 |  |
     import org.seasar.cubby.internal.util.StringUtils;
35 |  |
36 |  |
     /**
37 |  |
      * 適用された要求に対して、異常系の HTTP ステータスコードを返す {@link Filter} です。
38 |  |
      *
39 |  |
      * @author baba
40 |  |
      */
41 | 5 |
     public class SendErrorFilter implements Filter {
42 |  |
43 |  |
             /** 応答の HTTP ステータスコードの初期パラメータ名。 */
44 |  |
             public static final String STATUS_CODE = "statusCode";
45 |  |
46 |  |
             /** 対象外とするパスの初期パラメータ名。 */
47 |  |
             public static final String IGNORE_PATH_PATTERN = "ignorePathPattern";
48 |  |
49 |  |
             /** 応答の HTTP ステータスコード (デフォルトは 403 Forbidden)。 */
50 | 5 |
             private int statusCode = HttpServletResponse.SC_FORBIDDEN;
51 |  |
52 |  |
             /** 対象外とするパスの正規表現パターンのリスト。 */
53 | 5 |
             private final List<Pattern> ignorePathPatterns = new ArrayList<Pattern>();
54 |  |
55 |  |
             /**
56 |  |
              * このフィルタを初期化します。
57 |  |
              * <p>
58 |  |
              * <table>
59 |  |
              * <caption>使用可能な初期化パラメータ</caption> <thead>
60 |  |
              * <th>初期化パラメータ名</th>
61 |  |
              * <th>初期化パラメータの値</th>
62 |  |
              * <th>例</th>
63 |  |
              * </thead> <thead>
64 |  |
              * <tr>
65 |  |
              * <td>{@link #STATUS_CODE}</td>
66 |  |
              * <td>応答の HTTP ステータスコードを指定します。指定しなかった場合は
67 |  |
              * {@link HttpServletResponse#SC_FORBIDDEN} を返します。</td>
68 |  |
              * <td></td>
69 |  |
              * <tr>
70 |  |
              * <td>{@link #IGNORE_PATH_PATTERN}</td>
71 |  |
              * <td>対象外とするパスの正規表現をカンマ区切りで指定します。 filter-mapping の url-pattern
72 |  |
              * で指定する、このフィルタを適用する URL のうち、適用を除外したいパスを指定してください。</td>
73 |  |
              * <td>
74 |  |
              *
75 |  |
              * <pre>
76 |  |
              * &lt;filter&gt;
77 |  |
              *   &lt;filter-name&gt;sendErrorFilter&lt;/filter-name&gt;
78 |  |
              *   &lt;filter-class&gt;org.seasar.cubby.filter.SendErrorFilter&lt;/filter-class&gt;
79 |  |
              *   &lt;init-param&gt;
80 |  |
              *     &lt;param-name&gt;statusCode;&lt;/param-name&gt;
81 |  |
              *     &lt;param-value&gt;404&lt;param-name&gt;
82 |  |
              *   &lt;/init-param&gt;
83 |  |
              *   &lt;init-param&gt;
84 |  |
              *     &lt;param-name&gt;ignorePathPattern&lt;/param-name&gt;
85 |  |
              *     &lt;param-value&gt;/index.jsp&lt;param-name&gt;
86 |  |
              *   &lt;/init-param&gt;
87 |  |
              * &lt;/filter&gt;
88 |  |
              *
89 |  |
              * &lt;filter-mapping&gt;
90 |  |
              *   &lt;filter-name&gt;sendErrorFilter&lt;filter-name&gt;
91 |  |
              *   &lt;url-pattern&gt;*.jsp&lt;url-pattern&gt;
92 |  |
              *   &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
93 |  |
              * &lt;/filter-mapping&gt;
94 |  |
              * </pre>
95 |  |
              *
96 |  |
              * この例では、 /index.jsp を除く *.jsp に要求があった場合に HTTP ステータスコード 404 (Not Found)
97 |  |
              * を返します。</td>
98 |  |
              * </tr>
99 |  |
              * </thead>
100 |  |
              * </p>
101 |  |
              *
102 |  |
              * @param config
103 |  |
              *            Filter 設定のためのオブジェクト
104 |  |
              * @exception ServletException
105 |  |
              *                初期化処理で例外が発生した場合
106 |  |
              */
107 |  |
             public void init(final FilterConfig config) throws ServletException {
108 | 5 |
                     final String statusCodeString = config.getInitParameter(STATUS_CODE);
109 | 5 |
                     if (statusCodeString != null) {
110 | 4 |
                             statusCode = Integer.parseInt(statusCodeString);
111 |  |
                     }
112 | 5 |
                     final String ignorePathPatternString = config
113 |  |
                                     .getInitParameter(IGNORE_PATH_PATTERN);
114 | 5 |
                     if (!StringUtils.isEmpty(ignorePathPatternString)) {
115 |  |
116 | 3 |
                             for (final StringTokenizer tokenizer = new StringTokenizer(
117 | 9 |
                                             ignorePathPatternString, ","); tokenizer.hasMoreTokens();) {
118 | 6 |
                                     final String token = tokenizer.nextToken();
119 | 6 |
                                     final Pattern pattern = Pattern.compile(token);
120 | 6 |
                                     ignorePathPatterns.add(pattern);
121 | 6 |
                             }
122 |  |
                     }
123 | 5 |
             }
124 |  |
125 |  |
             /**
126 |  |
              * {@inheritDoc}
127 |  |
              */
128 |  |
             public void destroy() {
129 | 5 |
             }
130 |  |
131 |  |
             /**
132 |  |
              * {@link HttpServletResponse#sendError(int)} によって、異常系の HTTP ステータスコードを返します。
133 |  |
              *
134 |  |
              * @param req
135 |  |
              *            要求
136 |  |
              * @param res
137 |  |
              *            応答
138 |  |
              * @param chain
139 |  |
              *            フィルターチェーン
140 |  |
              * @throws IOException
141 |  |
              *             要求の転送や要求のチェーンがこの例外をスローする場合
142 |  |
              * @throws ServletException
143 |  |
              *             要求の転送や要求のチェーンがこの例外をスローする場合
144 |  |
              */
145 |  |
             public void doFilter(final ServletRequest req, final ServletResponse res,
146 |  |
                             final FilterChain chain) throws IOException, ServletException {
147 |  |
148 | 5 |
                     final HttpServletRequest request = (HttpServletRequest) req;
149 | 5 |
                     final HttpServletResponse response = (HttpServletResponse) res;
150 |  |
151 | 5 |
                     if (isIgnore(request)) {
152 | 2 |
                             chain.doFilter(request, response);
153 |  |
                     } else {
154 | 3 |
                             response.sendError(statusCode);
155 |  |
                     }
156 | 5 |
             }
157 |  |
158 |  |
             /**
159 |  |
              * 指定された要求がこのフィルタの対象外であるかを示します。
160 |  |
              *
161 |  |
              * @param request
162 |  |
              *            要求
163 |  |
              * @return 指定された要求がこのフィルタの対象外である場合は <code>true</code>、そうでない場合は
164 |  |
              *         <code>false</code>
165 |  |
              */
166 |  |
             private boolean isIgnore(final HttpServletRequest request) {
167 | 5 |
                     final String servletPath = request.getServletPath();
168 | 5 |
                     for (final Pattern ignorePattern : ignorePathPatterns) {
169 | 6 |
                             final Matcher matcher = ignorePattern.matcher(servletPath);
170 | 6 |
                             if (matcher.matches()) {
171 | 2 |
                                     return true;
172 |  |
                             }
173 | 4 |
                     }
174 | 3 |
                     return false;
175 |  |
             }
176 |  |
177 |  |
     }