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 }