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