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.action.impl;
    17
    18  import java.util.ArrayList;
    19  import java.util.HashMap;
    20  import java.util.List;
    21  import java.util.Map;
    22
    23  import org.seasar.cubby.action.ActionErrors;
    24  import org.seasar.cubby.action.FieldInfo;
    25
    26  /**
    27   * アクションエラーの実装クラス
    28   *
    29   * @author agata
    30   * @author baba
    31   */
    32  public class ActionErrorsImpl implements ActionErrors {
    33
    34  	/**
    35  	 * 全てのエラーの一覧。
    36  	 */
    37  	private final List<String> all = new ArrayList<String>();
    38
    39  	/**
    40  	 * フィールドで発生したエラーの一覧。
    41  	 */
    42  	private final Map<String, List<String>> fields = new NotNullHashMap<String, List<String>>(
    43  			new MessageListEmptyValueFactory());
    44
    45  	/**
    46  	 * インデックス付きフィールドで発生したエラーの一覧。
    47  	 */
    48  	private final Map<String, Map<Integer, List<String>>> indexedFields = new NotNullHashMap<String, Map<Integer, List<String>>>(
    49  			new IndexMapEmptyValueFactory());
    50
    51  	/**
    52  	 * フィールド以外で発生したエラーの一覧。
    53  	 */
    54  	private final List<String> others = new ArrayList<String>();
    55
    56  	/**
    57  	 * アクションで発生した全てのエラーの一覧を取得します。
    58  	 *
    59  	 * @return アクションで発生した全てエラーの一覧
    60  	 */
    61  	public List<String> getAll() {
    62  		return all;
    63  	}
    64
    65  	/**
    66  	 * フィールドで発生したエラーの一覧を取得します。
    67  	 *
    68  	 * @return フィールドで発生したエラーの一覧
    69  	 */
    70  	public Map<String, List<String>> getFields() {
    71  		return fields;
    72  	}
    73
    74  	/**
    75  	 * インデックス付きフィールドで発生したエラーの一覧を取得します。
    76  	 *
    77  	 * @return インデックス付きフィールドで発生したエラーの一覧
    78  	 */
    79  	public Map<String, Map<Integer, List<String>>> getIndexedFields() {
    80  		return indexedFields;
    81  	}
    82
    83  	/**
    84  	 * フィールド以外で発生したエラーの一覧を取得します。
    85  	 *
    86  	 * @return フィールド以外で発生したエラーの一覧
    87  	 */
    88  	public List<String> getOthers() {
    89  		return others;
    90  	}
    91
    92  	/**
    93  	 * エラーが存在しないかどうかを判定します。
    94  	 *
    95  	 * @return エラーが存在しなければtrue
    96  	 */
    97  	public boolean isEmpty() {
    98  		return all.isEmpty();
    99  	}
    100
    101 	/**
    102 	 * エラーメッセージを追加します。
    103 	 *
    104 	 * @param message
    105 	 *            メッセージ
    106 	 */
    107 	public void add(final String message) {
    108 		this.add(message, new FieldInfo[0]);
    109 	}
    110
    111 	/**
    112 	 * エラーメッセージを追加します。
    113 	 *
    114 	 * @param message
    115 	 *            メッセージ
    116 	 * @param fieldNames
    117 	 *            フィールド名
    118 	 */
    119 	public void add(final String message, final String... fieldNames) {
    120 		final FieldInfo[] fieldInfos = new FieldInfo[fieldNames.length];
    121 		for (int i = 0; i < fieldNames.length; i++) {
    122 			fieldInfos[i] = new FieldInfo(fieldNames[i]);
    123 		}
    124 		this.add(message, fieldInfos);
    125 	}
    126
    127 	/**
    128 	 * エラーメッセージを追加します。
    129 	 *
    130 	 * @param message
    131 	 *            メッセージ
    132 	 * @param fieldInfos
    133 	 *            フィールド情報
    134 	 */
    135 	public void add(final String message, final FieldInfo... fieldInfos) {
    136 		if (fieldInfos == null || fieldInfos.length == 0) {
    137 			others.add(message);
    138 		} else {
    139 			for (final FieldInfo fieldInfo : fieldInfos) {
    140 				addFields(message, fieldInfo);
    141 			}
    142 		}
    143 		this.all.add(message);
    144 	}
    145
    146 	private void addFields(final String message, final FieldInfo fieldInfo) {
    147 		final String name;
    148 		final Integer index;
    149 		if (fieldInfo == null) {
    150 			name = null;
    151 			index = null;
    152 		} else {
    153 			name = fieldInfo.getName();
    154 			index = fieldInfo.getIndex();
    155 		}
    156
    157 		final List<String> messages = this.fields.get(name);
    158 		messages.add(message);
    159
    160 		final List<String> indexedMessages = this.indexedFields.get(name).get(
    161 				index);
    162 		indexedMessages.add(message);
    163 	}
    164
    165 	private static class NotNullHashMap<K, V> extends HashMap<K, V> {
    166
    167 		private static final long serialVersionUID = 1L;
    168
    169 		private transient final EmptyValueFactory<V> emptyValueFactory;
    170
    171 		private NotNullHashMap(final EmptyValueFactory<V> emptyValueFactory) {
    172 			this.emptyValueFactory = emptyValueFactory;
    173 		}
    174
    175 		/**
    176 		 * {@inheritDoc}
    177 		 */
    178 		@SuppressWarnings("unchecked")
    179 		@Override
    180 		public V get(final Object key) {
    181 			final V value = super.get(key);
    182 			if (value != null) {
    183 				return value;
    184 			}
    185
    186 			final V emptyValue = emptyValueFactory.create();
    187 			this.put((K) key, emptyValue);
    188 			return emptyValue;
    189 		}
    190
    191 	}
    192
    193 	private interface EmptyValueFactory<T> {
    194 		/**
    195 		 * 空のオブジェクトを生成します。
    196 		 *
    197 		 * @return 空のオブジェクト
    198 		 */
    199 		T create();
    200 	}
    201
    202 	private static class MessageListEmptyValueFactory implements
    203 			EmptyValueFactory<List<String>> {
    204
    205 		/**
    206 		 * {@inheritDoc}
    207 		 */
    208 		public List<String> create() {
    209 			return new ArrayList<String>();
    210 		}
    211
    212 	}
    213
    214 	private static class IndexMapEmptyValueFactory implements
    215 			EmptyValueFactory<Map<Integer, List<String>>> {
    216
    217 		/**
    218 		 * {@inheritDoc}
    219 		 */
    220 		public Map<Integer, List<String>> create() {
    221 			return new NotNullHashMap<Integer, List<String>>(
    222 					new MessageListEmptyValueFactory());
    223 		}
    224
    225 	}
    226
    227 	/**
    228 	 * エラーをクリアします。
    229 	 */
    230 	public void clear() {
    231 		this.all.clear();
    232 		this.fields.clear();
    233 		this.indexedFields.clear();
    234 		this.others.clear();
    235 	}
    236
    237 }