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   * @since 1.0.0
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 	 * @since 1.1.1
124 	 */
125 	protected ValidationPhase getDefaultValidationPhase() {
126 		return DATA_TYPE;
127 	}
128 
129 	/**
130 	 * {@link #getDefaultValidationPhase()} のフェーズに入力検証ルールを追加します。
131 	 * 
132 	 * @param validationRule
133 	 *            入力検証ルール
134 	 */
135 	protected void add(final ValidationRule validationRule) {
136 		this.add(getDefaultValidationPhase(), validationRule);
137 	}
138 
139 	/**
140 	 * {@link #getDefaultValidationPhase()} のフェーズに入力検証を追加します。
141 	 * <p>
142 	 * 項目名のメッセージキーとしてパラメータ名が使用されます。
143 	 * </p>
144 	 * 
145 	 * @param paramName
146 	 *            パラメータ名
147 	 * @param validators
148 	 *            入力検証
149 	 */
150 	protected void add(final String paramName, final Validator... validators) {
151 		this.add(paramName, paramName, validators);
152 	}
153 
154 	/**
155 	 * 項目名のリソースキーを指定して、最初のフェーズに入力検証を追加します。
156 	 * 
157 	 * @param paramName
158 	 *            パラメータ名
159 	 * @param paramNameResourceKey
160 	 *            項目名のメッセージキー
161 	 * @param validators
162 	 *            入力検証
163 	 */
164 	protected void add(final String paramName,
165 			final String paramNameResourceKey, final Validator... validators) {
166 		this.add(getDefaultValidationPhase(), new FieldValidationRule(
167 				paramName, addResourceKeyPrefixTo(paramNameResourceKey),
168 				validators));
169 	}
170 
171 	/**
172 	 * 指定された {@link ValidationRules} に定義された入力検証ルールをすべて追加します。
173 	 * 
174 	 * @param validationRules
175 	 *            追加する入力検証ルールの集合
176 	 */
177 	protected void addAll(final ValidationRules validationRules) {
178 		for (final ValidationPhase validationPhase : validationRules
179 				.getValidationPhases()) {
180 			final Collection<ValidationRule> phaseValidationRules = validationRules
181 					.getPhaseValidationRules(validationPhase);
182 			for (final ValidationRule validationRule : phaseValidationRules) {
183 				this.add(validationPhase, validationRule);
184 			}
185 		}
186 	}
187 
188 	/**
189 	 * 指定されたリソースキーにこのオブジェクトに設定されているプレフィックスを追加します。
190 	 * 
191 	 * @param resourceKey
192 	 *            リソースキー
193 	 * @return プレフィックスが付加されたリソースキー
194 	 * @since 1.1.1
195 	 */
196 	protected String addResourceKeyPrefixTo(final String resourceKey) {
197 		if (this.resourceKeyPrefix == null) {
198 			return resourceKey;
199 		} else {
200 			return this.resourceKeyPrefix + resourceKey;
201 		}
202 	}
203 
204 	/**
205 	 * {@inheritDoc}
206 	 * <p>
207 	 * 指定されたエラーページへ遷移する {@link Forward} を返します。
208 	 * </p>
209 	 */
210 	public ActionResult fail(final String errorPage) {
211 		if (errorPage == null || errorPage.length() == 0) {
212 			throw new ActionException(format("ECUB0106"));
213 		}
214 		return new Forward(errorPage);
215 	}
216 
217 	/**
218 	 * {@inheritDoc}
219 	 * <p>
220 	 * デフォルトでは以下の順序です。
221 	 * <ul>
222 	 * <li>{@link #DATA_TYPE}</li>
223 	 * <li>{@link #DATA_CONSTRAINT}</li>
224 	 * </ul>
225 	 * これを変更してフェーズの追加などをしたい場合はこのメソッドをオーバーライドしてください。
226 	 * </p>
227 	 */
228 	public List<ValidationPhase> getValidationPhases() {
229 		return VALIDATION_PHASES;
230 	}
231 
232 	/**
233 	 * {@inheritDoc}
234 	 */
235 	public Collection<ValidationRule> getPhaseValidationRules(
236 			final ValidationPhase validationPhase) {
237 		final Collection<ValidationRule> phaseValidationRules;
238 		if (this.phaseValidationRulesMap.containsKey(validationPhase)) {
239 			phaseValidationRules = this.phaseValidationRulesMap
240 					.get(validationPhase);
241 		} else {
242 			phaseValidationRules = EMPTY_VALIDATION_RULES;
243 		}
244 		return phaseValidationRules;
245 	}
246 
247 }