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.validator;
17  
18  import java.util.ArrayList;
19  import java.util.Arrays;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  import org.seasar.cubby.action.ActionResult;
27  import org.seasar.cubby.action.Forward;
28  import org.seasar.cubby.exception.ActionRuntimeException;
29  
30  /**
31   * 入力検証を保持するクラスです。
32   * 
33   * @author agata
34   * @author baba
35   * @since 1.0.0
36   */
37  public abstract class DefaultValidationRules implements ValidationRules {
38  
39  	/** データ型を検証するフェーズ。 */
40  	public static final ValidationPhase DATA_TYPE = new ValidationPhase();
41  
42  	/** データ上の制約を検証するフェーズ。 */
43  	public static final ValidationPhase DATA_CONSTRAINT = new ValidationPhase();
44  
45  	/** 空の {@link ValidationRule} のリスト。 */
46  	private static final List<ValidationRule> EMPTY_VALIDATION_RULES = Collections
47  			.emptyList();
48  
49  	/** 入力検証のフェーズとそれに対応する入力検証ルールのリスト。 */
50  	private final Map<ValidationPhase, List<ValidationRule>> phaseValidationRulesMap = new HashMap<ValidationPhase, List<ValidationRule>>();
51  
52  	/** メッセージキーのプリフィックス。 */
53  	private final String resourceKeyPrefix;
54  
55  	/** 入力検証のフェーズ。 */
56  	private static final List<ValidationPhase> VALIDATION_PHASES = Arrays
57  			.asList(new ValidationPhase[] { DATA_TYPE, DATA_CONSTRAINT });
58  
59  	/**
60  	 * メッセージキーのプリフィックスなしのコンストラクタ。
61  	 */
62  	public DefaultValidationRules() {
63  		this(null);
64  	}
65  
66  	/**
67  	 * メッセージキーのプリフィックス付きのコンストラクタ。
68  	 * 
69  	 * @param resourceKeyPrefix
70  	 *            メッセージキーのプリフィックス
71  	 */
72  	public DefaultValidationRules(final String resourceKeyPrefix) {
73  		this.resourceKeyPrefix = resourceKeyPrefix;
74  		initialize();
75  	}
76  
77  	/**
78  	 * 初期化メソッド。
79  	 * <p>
80  	 * このメソッドをサブクラスでオーバーライドして各項目の入力検証ルールを追加します。
81  	 * </p>
82  	 */
83  	protected abstract void initialize();
84  
85  	/**
86  	 * 入力検証ルールを追加します。
87  	 * 
88  	 * @param validationPhase
89  	 *            指定された入力検証ルールを実行するフェーズ
90  	 * @param validationRule
91  	 *            入力検証ルール
92  	 */
93  	protected void add(final ValidationPhase validationPhase,
94  			final ValidationRule validationRule) {
95  		if (!this.phaseValidationRulesMap.containsKey(validationPhase)) {
96  			this.phaseValidationRulesMap.put(validationPhase,
97  					new ArrayList<ValidationRule>());
98  		}
99  		final List<ValidationRule> validationRules = this.phaseValidationRulesMap
100 				.get(validationPhase);
101 		validationRules.add(validationRule);
102 	}
103 
104 	/**
105 	 * 項目ごとの入力検証を行うフェーズを返します。
106 	 * 
107 	 * @return {@link #DATA_TYPE}
108 	 * @see #add(ValidationRule)
109 	 * @see #add(String, Validator...)
110 	 * @since 1.1.1
111 	 */
112 	protected ValidationPhase getDefaultValidationPhase() {
113 		return DATA_TYPE;
114 	}
115 
116 	/**
117 	 * {@link #getDefaultValidationPhase()} のフェーズに入力検証ルールを追加します。
118 	 * 
119 	 * @param validationRule
120 	 *            入力検証ルール
121 	 */
122 	protected void add(final ValidationRule validationRule) {
123 		this.add(getDefaultValidationPhase(), validationRule);
124 	}
125 
126 	/**
127 	 * {@link #getDefaultValidationPhase()} のフェーズに入力検証を追加します。
128 	 * <p>
129 	 * 項目名のメッセージキーとしてパラメータ名が使用されます。
130 	 * </p>
131 	 * 
132 	 * @param paramName
133 	 *            パラメータ名
134 	 * @param validators
135 	 *            入力検証
136 	 */
137 	protected void add(final String paramName, final Validator... validators) {
138 		this.add(paramName, paramName, validators);
139 	}
140 
141 	/**
142 	 * 項目名のリソースキーを指定して、最初のフェーズに入力検証を追加します。
143 	 * 
144 	 * @param paramName
145 	 *            パラメータ名
146 	 * @param paramNameResourceKey
147 	 *            項目名のメッセージキー
148 	 * @param validators
149 	 *            入力検証
150 	 */
151 	protected void add(final String paramName,
152 			final String paramNameResourceKey, final Validator... validators) {
153 		this.add(getDefaultValidationPhase(), new FieldValidationRule(
154 				paramName, addResourceKeyPrefixTo(paramNameResourceKey),
155 				validators));
156 	}
157 
158 	/**
159 	 * 指定された {@link ValidationRules} に定義された入力検証ルールをすべて追加します。
160 	 * 
161 	 * @param validationRules
162 	 *            追加する入力検証ルールの集合
163 	 */
164 	protected void addAll(final ValidationRules validationRules) {
165 		for (final ValidationPhase validationPhase : validationRules
166 				.getValidationPhases()) {
167 			final Collection<ValidationRule> phaseValidationRules = validationRules
168 					.getPhaseValidationRules(validationPhase);
169 			for (final ValidationRule validationRule : phaseValidationRules) {
170 				this.add(validationPhase, validationRule);
171 			}
172 		}
173 	}
174 
175 	/**
176 	 * 指定されたリソースキーにこのオブジェクトに設定されているプレフィックスを追加します。
177 	 * 
178 	 * @param resourceKey
179 	 *            リソースキー
180 	 * @return プレフィックスが付加されたリソースキー
181 	 * @since 1.1.1
182 	 */
183 	protected String addResourceKeyPrefixTo(final String resourceKey) {
184 		if (this.resourceKeyPrefix == null) {
185 			return resourceKey;
186 		} else {
187 			return this.resourceKeyPrefix + resourceKey;
188 		}
189 	}
190 
191 	/**
192 	 * {@inheritDoc}
193 	 * <p>
194 	 * 指定されたエラーページへ遷移する {@link Forward} を返します。
195 	 * </p>
196 	 */
197 	public ActionResult fail(final String errorPage) {
198 		if (errorPage == null || errorPage.length() == 0) {
199 			throw new ActionRuntimeException("ECUB0106");
200 		}
201 		return new Forward(errorPage);
202 	}
203 
204 	/**
205 	 * {@inheritDoc}
206 	 * <p>
207 	 * デフォルトでは以下の順序です。
208 	 * <ul>
209 	 * <li>{@link #RESOURCE}</li>
210 	 * <li>{@link #DATA_TYPE}</li>
211 	 * <li>{@link #DATA_CONSTRAINT}</li>
212 	 * </ul>
213 	 * これを変更してフェーズの追加などをしたい場合はこのメソッドをオーバーライドしてください。
214 	 * </p>
215 	 */
216 	public List<ValidationPhase> getValidationPhases() {
217 		return VALIDATION_PHASES;
218 	}
219 
220 	/**
221 	 * {@inheritDoc}
222 	 */
223 	public Collection<ValidationRule> getPhaseValidationRules(
224 			final ValidationPhase validationPhase) {
225 		final Collection<ValidationRule> phaseValidationRules;
226 		if (this.phaseValidationRulesMap.containsKey(validationPhase)) {
227 			phaseValidationRules = this.phaseValidationRulesMap
228 					.get(validationPhase);
229 		} else {
230 			phaseValidationRules = EMPTY_VALIDATION_RULES;
231 		}
232 		return phaseValidationRules;
233 	}
234 
235 	/**
236 	 * {@inheritDoc}
237 	 * 
238 	 * @deprecated {@link #addAll(ValidationRules)} を使用してください。
239 	 */
240 	@Deprecated
241 	public List<ValidationRule> getRules() {
242 		return phaseValidationRulesMap.get(getDefaultValidationPhase());
243 	}
244 
245 }