View Javadoc

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