1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
30
31
32
33 public class ActionErrorsImpl implements ActionErrors {
34
35
36
37
38 private final List<String> all = new ArrayList<String>();
39
40
41
42
43 private final Map<String, List<String>> fields = new NotNullHashMap<String, List<String>>(
44 new MessageListEmptyValueFactory());
45
46
47
48
49 private final Map<String, Map<Integer, List<String>>> indexedFields = new NotNullHashMap<String, Map<Integer, List<String>>>(
50 new IndexMapEmptyValueFactory());
51
52
53
54
55 private final List<String> others = new ArrayList<String>();
56
57
58
59
60
61
62 public List<String> getAll() {
63 return all;
64 }
65
66
67
68
69
70
71 public Map<String, List<String>> getFields() {
72 return fields;
73 }
74
75
76
77
78
79
80 public Map<String, Map<Integer, List<String>>> getIndexedFields() {
81 return indexedFields;
82 }
83
84
85
86
87
88
89 public List<String> getOthers() {
90 return others;
91 }
92
93
94
95
96
97
98 public boolean isEmpty() {
99 return all.isEmpty();
100 }
101
102
103
104
105
106
107
108 public void add(final String message) {
109 this.add(message, new FieldInfo[0]);
110 }
111
112
113
114
115
116
117
118
119
120 public void add(final String message, final String... fieldNames) {
121 final FieldInfo[] fieldInfos = new FieldInfo[fieldNames.length];
122 for (int i = 0 ; i < fieldNames.length; i++) {
123 fieldInfos[i] = new FieldInfo(fieldNames[i]);
124 }
125 this.add(message, fieldInfos);
126 }
127
128
129
130
131
132
133
134
135
136 public void add(final String message, final FieldInfo... fieldInfos) {
137 if (fieldInfos == null || fieldInfos.length == 0) {
138 others.add(message);
139 } else {
140 for (final FieldInfo fieldInfo : fieldInfos) {
141 addFields(message, fieldInfo);
142 }
143 }
144 this.all.add(message);
145 }
146
147 private void addFields(final String message, final FieldInfo fieldInfo) {
148 final String name = fieldInfo == null ? null : fieldInfo.getName();
149 final Integer index = fieldInfo == null ? null : fieldInfo.getIndex();
150
151 final List<String> messages = this.fields.get(name);
152 messages.add(message);
153
154 final List<String> indexedMessages = this.indexedFields.get(name).get(
155 index);
156 indexedMessages.add(message);
157 }
158
159 private static class NotNullHashMap<K, V> extends HashMap<K, V> {
160
161 private static final long serialVersionUID = 1L;
162
163 private final EmptyValueFactory<V> emptyValueFactory;
164
165 private NotNullHashMap(EmptyValueFactory<V> emptyValueFactory) {
166 this.emptyValueFactory = emptyValueFactory;
167 }
168
169
170
171
172 @SuppressWarnings("unchecked")
173 @Override
174 public V get(final Object key) {
175 final V value = super.get(key);
176 if (value != null) {
177 return value;
178 }
179
180 final V emptyValue = emptyValueFactory.create();
181 this.put((K) key, emptyValue);
182 return emptyValue;
183 }
184
185 }
186
187 private interface EmptyValueFactory<T> {
188
189
190
191
192
193 T create();
194 }
195
196 private static class MessageListEmptyValueFactory implements
197 EmptyValueFactory<List<String>> {
198
199
200
201
202 public List<String> create() {
203 return new ArrayList<String>();
204 }
205
206 }
207
208 private static class IndexMapEmptyValueFactory implements
209 EmptyValueFactory<Map<Integer, List<String>>> {
210
211
212
213
214 public Map<Integer, List<String>> create() {
215 return new NotNullHashMap<Integer, List<String>>(
216 new MessageListEmptyValueFactory());
217 }
218
219 }
220
221
222
223
224 public void clear() {
225 this.all.clear();
226 this.fields.clear();
227 this.indexedFields.clear();
228 this.others.clear();
229 }
230
231 }