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();
77  	}
78  
79  	/**
80  	 * 初期化メソッド。
81  	 * <p>
82  	 * このメソッドをサブクラスでオーバーライドして各項目の入力検証ルールを追加します。
83  	 * </p>
84  	 */
85  	protected abstract void initialize();
86  
87  	/**
88  	 * 入力検証ルールを追加します。
89  	 * 
90  	 * @param validationPhase
91  	 *            指定された入力検証ルールを実行するフェーズ
92  	 * @param validationRule
93  	 *            入力検証ルール
94  	 */
95  	protected void add(final ValidationPhase validationPhase,
96  			final ValidationRule validationRule) {
97  		if (!this.phaseValidationRulesMap.containsKey(validationPhase)) {
98  			this.phaseValidationRulesMap.put(validationPhase,
99  					new ArrayList<ValidationRule>());
100 		}
101 		final List<ValidationRule> validationRules = this.phaseValidationRulesMap
102 				.get(validationPhase);
103 		validationRules.add(validationRule);
104 	}
105 
106 	/**
107 	 * 項目ごとの入力検証を行うフェーズを返します。
108 	 * 
109 	 * @return {@link #DATA_TYPE}
110 	 * @see #add(ValidationRule)
111 	 * @see #add(String, Validator...)
112 	 * @since 1.1.1
113 	 */
114 	protected ValidationPhase getDefaultValidationPhase() {
115 		return DATA_TYPE;
116 	}
117 
118 	/**
119 	 * {@link #getDefaultValidationPhase()} のフェーズに入力検証ルールを追加します。
120 	 * 
121 	 * @param validationRule
122 	 *            入力検証ルール
123 	 */
124 	protected void add(final ValidationRule validationRule) {
125 		this.add(getDefaultValidationPhase(), validationRule);
126 	}
127 
128 	/**
129 	 * {@link #getDefaultValidationPhase()} のフェーズに入力検証を追加します。
130 	 * <p>
131 	 * 項目名のメッセージキーとしてパラメータ名が使用されます。
132 	 * </p>
133 	 * 
134 	 * @param paramName
135 	 *            パラメータ名
136 	 * @param validators
137 	 *            入力検証
138 	 */
139 	protected void add(final String paramName, final Validator... validators) {
140 		this.add(paramName, paramName, validators);
141 	}
142 
143 	/**
144 	 * 項目名のリソースキーを指定して、最初のフェーズに入力検証を追加します。
145 	 * 
146 	 * @param paramName
147 	 *            パラメータ名
148 	 * @param paramNameResourceKey
149 	 *            項目名のメッセージキー
150 	 * @param validators
151 	 *            入力検証
152 	 */
153 	protected void add(final String paramName,
154 			final String paramNameResourceKey, final Validator... validators) {
155 		this.add(getDefaultValidationPhase(), new FieldValidationRule(
156 				paramName, addResourceKeyPrefixTo(paramNameResourceKey),
157 				validators));
158 	}
159 
160 	/**
161 	 * 指定された {@link ValidationRules} に定義された入力検証ルールをすべて追加します。
162 	 * 
163 	 * @param validationRules
164 	 *            追加する入力検証ルールの集合
165 	 */
166 	protected void addAll(final ValidationRules validationRules) {
167 		for (final ValidationPhase validationPhase : validationRules
168 				.getValidationPhases()) {
169 			final Collection<ValidationRule> phaseValidationRules = validationRules
170 					.getPhaseValidationRules(validationPhase);
171 			for (final ValidationRule validationRule : phaseValidationRules) {
172 				this.add(validationPhase, validationRule);
173 			}
174 		}
175 	}
176 
177 	/**
178 	 * 指定されたリソースキーにこのオブジェクトに設定されているプレフィックスを追加します。
179 	 * 
180 	 * @param resourceKey
181 	 *            リソースキー
182 	 * @return プレフィックスが付加されたリソースキー
183 	 * @since 1.1.1
184 	 */
185 	protected String addResourceKeyPrefixTo(final String resourceKey) {
186 		if (this.resourceKeyPrefix == null) {
187 			return resourceKey;
188 		} else {
189 			return this.resourceKeyPrefix + resourceKey;
190 		}
191 	}
192 
193 	/**
194 	 * {@inheritDoc}
195 	 * <p>
196 	 * 指定されたエラーページへ遷移する {@link Forward} を返します。
197 	 * </p>
198 	 */
199 	public ActionResult fail(final String errorPage) {
200 		if (errorPage == null || errorPage.length() == 0) {
201 			throw new ActionException(format("ECUB0106"));
202 		}
203 		return new Forward(errorPage);
204 	}
205 
206 	/**
207 	 * {@inheritDoc}
208 	 * <p>
209 	 * デフォルトでは以下の順序です。
210 	 * <ul>
211 	 * <li>{@link #DATA_TYPE}</li>
212 	 * <li>{@link #DATA_CONSTRAINT}</li>
213 	 * </ul>
214 	 * これを変更してフェーズの追加などをしたい場合はこのメソッドをオーバーライドしてください。
215 	 * </p>
216 	 */
217 	public List<ValidationPhase> getValidationPhases() {
218 		return VALIDATION_PHASES;
219 	}
220 
221 	/**
222 	 * {@inheritDoc}
223 	 */
224 	public Collection<ValidationRule> getPhaseValidationRules(
225 			final ValidationPhase validationPhase) {
226 		final Collection<ValidationRule> phaseValidationRules;
227 		if (this.phaseValidationRulesMap.containsKey(validationPhase)) {
228 			phaseValidationRules = this.phaseValidationRulesMap
229 					.get(validationPhase);
230 		} else {
231 			phaseValidationRules = EMPTY_VALIDATION_RULES;
232 		}
233 		return phaseValidationRules;
234 	}
235 
236 }