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.interceptor;
17  
18  import static org.seasar.cubby.CubbyConstants.ATTR_PARAMS;
19  import static org.seasar.cubby.CubbyConstants.ATTR_VALIDATION_FAIL;
20  
21  import java.util.Map;
22  
23  import javax.servlet.http.HttpServletRequest;
24  
25  import org.aopalliance.intercept.MethodInterceptor;
26  import org.aopalliance.intercept.MethodInvocation;
27  import org.seasar.cubby.CubbyConstants;
28  import org.seasar.cubby.action.Action;
29  import org.seasar.cubby.action.ActionErrors;
30  import org.seasar.cubby.action.Forward;
31  import org.seasar.cubby.action.Validation;
32  import org.seasar.cubby.controller.ActionContext;
33  import org.seasar.cubby.validator.ValidationProcessor;
34  import org.seasar.cubby.validator.ValidationRules;
35  import org.seasar.framework.beans.BeanDesc;
36  import org.seasar.framework.beans.PropertyDesc;
37  import org.seasar.framework.beans.factory.BeanDescFactory;
38  
39  /**
40   * 入力検証を行います。
41   * <p>
42   * 入力検証が失敗した場合
43   * <ul>
44   * <li>またリクエスト中の入力検証エラーフラグを <code>true</code> に設定します。</li>
45   * <li>アクションメソッドに設定された{@link Validation#errorPage()}へフォワードします。</li>
46   * </ul>
47   * </p>
48   * 
49   * @see CubbyConstants#ATTR_VALIDATION_FAIL 入力検証エラーフラグの属性名
50   * @author agata
51   * @author baba
52   * @since 1.0.0
53   */
54  public class ValidationInterceptor implements MethodInterceptor {
55  
56  	/** 入力検証を行うクラス。 */
57  	private ValidationProcessor validationProcessor;
58  
59  	/** リクエスト。 */
60  	private HttpServletRequest request;
61  
62  	/** アクションメソッドの実行時コンテキスト。 */
63  	private ActionContext context;
64  
65  	/**
66  	 * インスタンス化します。
67  	 */
68  	public ValidationInterceptor() {
69  	}
70  
71  	/**
72  	 * 入力検証を行うクラスを設定します。
73  	 * 
74  	 * @param validationProcessor
75  	 *            入力検証を行うクラス
76  	 */
77  	public void setValidationProcessor(
78  			final ValidationProcessor validationProcessor) {
79  		this.validationProcessor = validationProcessor;
80  	}
81  
82  	/**
83  	 * リクエストを設定します。
84  	 * 
85  	 * @param request
86  	 *            リクエスト
87  	 */
88  	public void setRequest(final HttpServletRequest request) {
89  		this.request = request;
90  	}
91  
92  	/**
93  	 * アクションメソッド実行時のコンテキストを設定します。
94  	 * 
95  	 * @param context
96  	 *            アクションメソッド実行時のコンテキスト
97  	 */
98  	public void setActionContext(final ActionContext context) {
99  		this.context = context;
100 	}
101 
102 	/**
103 	 * {@inheritDoc}
104 	 * <p>
105 	 * アクションメソッドの実行前に入力検証を実行し、入力にエラーがあった場合はエラーページへ遷移するための{@link Forward}を返します。
106 	 * </p>
107 	 */
108 	public Object invoke(final MethodInvocation invocation) throws Throwable {
109 		final Validation validation = context.getValidation();
110 		final boolean success;
111 		if (validation == null) {
112 			success = true;
113 		} else {
114 			final Map<String, Object[]> params = getAttribute(request,
115 					ATTR_PARAMS);
116 			final Object form = context.getFormBean();
117 			final ActionErrors errors = context.getAction().getErrors();
118 			final ValidationRules rules = getValidationRules(context);
119 			success = validationProcessor.process(errors, params, form, rules);
120 		}
121 
122 		final Object result;
123 		if (success) {
124 			result = invocation.proceed();
125 		} else {
126 			request.setAttribute(ATTR_VALIDATION_FAIL, true);
127 			final String path = validation.errorPage();
128 			result = new Forward(path);
129 		}
130 
131 		return result;
132 	}
133 
134 	/**
135 	 * 実行しているアクションメソッドの入力検証ルールの集合を取得します。
136 	 * 
137 	 * @param context
138 	 *            アクションメソッド実行時のコンテキスト
139 	 * @return アクションメソッドの入力検証ルールの集合
140 	 */
141 	private ValidationRules getValidationRules(final ActionContext context) {
142 		final Validation validation = context.getValidation();
143 		final Action action = context.getAction();
144 		final BeanDesc beanDesc = BeanDescFactory
145 				.getBeanDesc(action.getClass());
146 		final PropertyDesc propertyDesc = beanDesc.getPropertyDesc(validation
147 				.rules());
148 		final ValidationRules rules = (ValidationRules) propertyDesc
149 				.getValue(action);
150 		return rules;
151 	}
152 
153 	/**
154 	 * リクエストから属性を取得します。
155 	 * 
156 	 * @param <T>
157 	 *            取得する属性の型
158 	 * @param request
159 	 *            リクエスト
160 	 * @param name
161 	 *            属性名
162 	 * @return 属性
163 	 */
164 	@SuppressWarnings("unchecked")
165 	private static <T> T getAttribute(final HttpServletRequest request,
166 			final String name) {
167 		return (T) request.getAttribute(name);
168 	}
169 
170 }