Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
BasicMessageList |
|
| 1.375;1.375 | ||||
BasicMessageList$1 |
|
| 1.375;1.375 | ||||
BasicMessageList$MessageItem |
|
| 1.375;1.375 |
1 | /* | |
2 | * $Id: BasicMessageList.java 366395 2006-01-06 02:42:19Z niallp $ | |
3 | * $Revision: 366395 $ | |
4 | * $Date: 2006-01-06 02:42:19 +0000 (Fri, 06 Jan 2006) $ | |
5 | * | |
6 | * ==================================================================== | |
7 | * | |
8 | * Copyright 2003-2006 The Apache Software Foundation | |
9 | * | |
10 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
11 | * you may not use this file except in compliance with the License. | |
12 | * You may obtain a copy of the License at | |
13 | * | |
14 | * http://www.apache.org/licenses/LICENSE-2.0 | |
15 | * | |
16 | * Unless required by applicable law or agreed to in writing, software | |
17 | * distributed under the License is distributed on an "AS IS" BASIS, | |
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
19 | * See the License for the specific language governing permissions and | |
20 | * limitations under the License. | |
21 | * | |
22 | */ | |
23 | ||
24 | package org.apache.commons.resources.impl; | |
25 | ||
26 | import java.io.Serializable; | |
27 | import java.util.ArrayList; | |
28 | import java.util.Collections; | |
29 | import java.util.Comparator; | |
30 | import java.util.HashMap; | |
31 | import java.util.Iterator; | |
32 | import java.util.List; | |
33 | import java.util.Map; | |
34 | ||
35 | import org.apache.commons.resources.Message; | |
36 | import org.apache.commons.resources.MessageList; | |
37 | ||
38 | /** | |
39 | * A basic implementation of a MessageList. | |
40 | * <p> | |
41 | * Orginally based on org.apache.struts.action.ActionMessages, Revision 49670. | |
42 | */ | |
43 | public class BasicMessageList implements Serializable, MessageList { | |
44 | ||
45 | /** | |
46 | * Compares MessageItems. | |
47 | */ | |
48 | 0 | private static final Comparator ACTION_ITEM_COMPARATOR = new Comparator() { |
49 | public int compare(Object o1, Object o2) { | |
50 | 0 | return ((MessageItem) o1).getOrder() - ((MessageItem) o2).getOrder(); |
51 | } | |
52 | }; | |
53 | ||
54 | /** | |
55 | * Have the messages been retrieved from this object? | |
56 | */ | |
57 | 0 | private boolean accessed = false; |
58 | ||
59 | /** | |
60 | * The accumulated set of <code>Message</code> objects (represented | |
61 | * as a List) for each property, keyed by property name. | |
62 | */ | |
63 | 0 | private Map messages = new HashMap(); |
64 | ||
65 | /** | |
66 | * The current number of the property/key being added. This is used | |
67 | * to maintain the order messages are added. | |
68 | */ | |
69 | 0 | private int count = 0; |
70 | ||
71 | // --------------------------------------------------------- Public Methods | |
72 | ||
73 | /** | |
74 | * Create an empty <code>MessageList</code> object. | |
75 | */ | |
76 | public BasicMessageList() { | |
77 | 0 | super(); |
78 | 0 | } |
79 | ||
80 | /** | |
81 | * Create an <code>MessageList</code> object initialized to use | |
82 | * the given value for the "global" message key. | |
83 | * | |
84 | * @param globalMessageKey The new default global message key | |
85 | */ | |
86 | public BasicMessageList(String globalMessageKey) { | |
87 | 0 | super(); |
88 | 0 | this.setGlobalMessageKey(globalMessageKey); |
89 | 0 | } |
90 | ||
91 | /** | |
92 | * Create an <code>MessageList</code> object initialized with the given | |
93 | * messages. | |
94 | * | |
95 | * @param messages The messages to be initially added to this object. | |
96 | */ | |
97 | public BasicMessageList(MessageList messages) { | |
98 | 0 | super(); |
99 | 0 | this.add(messages); |
100 | 0 | } |
101 | ||
102 | /** | |
103 | * Create an <code>MessageList</code> object initialized with the given | |
104 | * messages and the given global message key. | |
105 | * | |
106 | * @param globalMessageKey The new default global message key | |
107 | * @param messages The messages to be initially added to this object. | |
108 | * | |
109 | */ | |
110 | public BasicMessageList(String globalMessageKey, MessageList messages) { | |
111 | 0 | super(); |
112 | 0 | this.setGlobalMessageKey(globalMessageKey); |
113 | 0 | this.add(messages); |
114 | 0 | } |
115 | ||
116 | /** | |
117 | * The "global" message key for this MessageList | |
118 | * [GLOBAL_MESSAGE_KEY]. | |
119 | */ | |
120 | 0 | private String globalMessageKey = GLOBAL_MESSAGE_KEY; |
121 | ||
122 | /** | |
123 | * @return The default global message key | |
124 | */ | |
125 | public String getGlobalMessageKey() { | |
126 | 0 | return this.globalMessageKey; |
127 | } | |
128 | ||
129 | /** | |
130 | * @param globalMessageKey The new default global message key | |
131 | */ | |
132 | public void setGlobalMessageKey(String globalMessageKey) { | |
133 | 0 | this.globalMessageKey = globalMessageKey; |
134 | 0 | } |
135 | ||
136 | /** | |
137 | * Add a message to the set of messages for the specified property. An | |
138 | * order of the property/key is maintained based on the initial addition | |
139 | * of the property/key. | |
140 | * | |
141 | * @param property Property name (or MessageList.GLOBAL_MESSAGE_KEY) | |
142 | * @param message The message to be added | |
143 | */ | |
144 | public void add(String property, Message message) { | |
145 | ||
146 | 0 | MessageItem item = (MessageItem) messages.get(property); |
147 | 0 | List list = null; |
148 | ||
149 | 0 | if (item == null) { |
150 | 0 | list = new ArrayList(); |
151 | 0 | item = new MessageItem(list, this.count++); |
152 | ||
153 | 0 | messages.put(property, item); |
154 | } else { | |
155 | 0 | list = item.getList(); |
156 | } | |
157 | ||
158 | 0 | list.add(message); |
159 | ||
160 | 0 | } |
161 | ||
162 | /** | |
163 | * Add a message to the set of messages for the "global" property. An | |
164 | * order of the property/key is maintained based on the initial addition | |
165 | * of the property/key. | |
166 | * | |
167 | * @param message The message to be added | |
168 | */ | |
169 | public void add(Message message) { | |
170 | 0 | this.add(getGlobalMessageKey(), message); |
171 | 0 | } |
172 | ||
173 | /** | |
174 | * Adds the messages from the given <code>MessageList</code> object to | |
175 | * this set of messages. The messages are added in the order they are returned from | |
176 | * the properties() method. If a message's property is already in the current | |
177 | * <code>MessageList</code> object it is added to the end of the list for that | |
178 | * property. If a message's property is not in the current list it is added to the end | |
179 | * of the properties. | |
180 | * | |
181 | * @param messageList The <code>MessageList</code> object to be added. | |
182 | */ | |
183 | public void add(MessageList messageList) { | |
184 | // loop over properties | |
185 | 0 | Iterator props = messageList.properties(); |
186 | 0 | while (props.hasNext()) { |
187 | 0 | String property = (String) props.next(); |
188 | ||
189 | // loop over messages for each property | |
190 | 0 | Iterator msgs = messageList.get(property); |
191 | 0 | while (msgs.hasNext()) { |
192 | 0 | Message msg = (Message) msgs.next(); |
193 | 0 | this.add(property, msg); |
194 | 0 | } |
195 | ||
196 | 0 | } |
197 | 0 | } |
198 | ||
199 | /** | |
200 | * Clear all messages recorded by this object. | |
201 | */ | |
202 | public void clear() { | |
203 | 0 | this.messages.clear(); |
204 | 0 | } |
205 | ||
206 | /** | |
207 | * Determines if the MessageList's messages have been accessed one or more | |
208 | * times. Returns <code>true</code> if the <code>get()</code> or | |
209 | * <code>get(String)</code> methods are called. | |
210 | * @return <code>true</code> if the messages have been accessed one or more | |
211 | * times. | |
212 | */ | |
213 | public boolean isAccessed() { | |
214 | 0 | return this.accessed; |
215 | } | |
216 | ||
217 | /** | |
218 | * @return Return <code>true</code> if there are no messages recorded | |
219 | * in this collection, or <code>false</code> otherwise. | |
220 | */ | |
221 | public boolean isEmpty() { | |
222 | 0 | return messages.isEmpty(); |
223 | } | |
224 | ||
225 | /** | |
226 | * Return the set of all recorded messages, without distinction | |
227 | * by which property the messages are associated with. If there are | |
228 | * no messages recorded, an empty enumeration is returned. | |
229 | * | |
230 | * @return All messages. | |
231 | */ | |
232 | public Iterator get() { | |
233 | 0 | this.accessed = true; |
234 | ||
235 | 0 | if (messages.isEmpty()) { |
236 | 0 | return Collections.EMPTY_LIST.iterator(); |
237 | } | |
238 | ||
239 | 0 | ArrayList results = new ArrayList(); |
240 | 0 | ArrayList actionItems = new ArrayList(); |
241 | ||
242 | 0 | for (Iterator i = messages.values().iterator(); i.hasNext();) { |
243 | 0 | actionItems.add(i.next()); |
244 | } | |
245 | ||
246 | // Sort MessageItems based on the initial order the | |
247 | // property/key was added to MessageList. | |
248 | 0 | Collections.sort(actionItems, ACTION_ITEM_COMPARATOR); |
249 | ||
250 | 0 | for (Iterator i = actionItems.iterator(); i.hasNext();) { |
251 | 0 | MessageItem ami = (MessageItem) i.next(); |
252 | ||
253 | 0 | for (Iterator msgs = ami.getList().iterator(); msgs.hasNext();) { |
254 | 0 | results.add(msgs.next()); |
255 | } | |
256 | 0 | } |
257 | ||
258 | 0 | return results.iterator(); |
259 | } | |
260 | ||
261 | /** | |
262 | * Return the set of messages related to a specific property. | |
263 | * If there are no such messages, an empty enumeration is returned. | |
264 | * | |
265 | * @param property Property name | |
266 | * @return Messages related to a specific property. | |
267 | */ | |
268 | public Iterator get(String property) { | |
269 | 0 | this.accessed = true; |
270 | ||
271 | 0 | MessageItem item = (MessageItem) messages.get(property); |
272 | ||
273 | 0 | return (item == null) |
274 | ? Collections.EMPTY_LIST.iterator() | |
275 | : item.getList().iterator(); | |
276 | } | |
277 | ||
278 | /** | |
279 | * Return the set of property names for which at least one message has | |
280 | * been recorded. If there are no messages, an empty Iterator is returned. | |
281 | * If you have recorded global messages, the String value of | |
282 | * <code>MessageList.GLOBAL_MESSAGE</code> will be one of the returned | |
283 | * property names. | |
284 | * | |
285 | * @return The property names. | |
286 | */ | |
287 | public Iterator properties() { | |
288 | 0 | return messages.keySet().iterator(); |
289 | } | |
290 | ||
291 | /** | |
292 | * Return the number of messages recorded for all properties (including | |
293 | * global messages). <strong>NOTE</strong> - it is more efficient to call | |
294 | * <code>isEmpty()</code> if all you care about is whether or not there are | |
295 | * any messages at all. | |
296 | * | |
297 | * @return The number of messages. | |
298 | */ | |
299 | public int size() { | |
300 | ||
301 | 0 | int total = 0; |
302 | ||
303 | 0 | for (Iterator i = messages.values().iterator(); i.hasNext();) { |
304 | 0 | MessageItem ami = (MessageItem) i.next(); |
305 | 0 | total += ami.getList().size(); |
306 | 0 | } |
307 | ||
308 | 0 | return total; |
309 | } | |
310 | ||
311 | /** | |
312 | * Return the number of messages associated with the specified property. | |
313 | * | |
314 | * @param property Property name (or MessageList.GLOBAL_MESSAGE_KEY | |
315 | * @return The number of messages for a specific property. | |
316 | */ | |
317 | public int size(String property) { | |
318 | ||
319 | 0 | MessageItem ami = (MessageItem) messages.get(property); |
320 | ||
321 | 0 | return (ami == null) ? 0 : ami.getList().size(); |
322 | } | |
323 | ||
324 | /** | |
325 | * Returns a String representation of this MessageList's | |
326 | * [property name]=[message list] mapping. | |
327 | * @see java.lang.Object#toString() | |
328 | */ | |
329 | public String toString() { | |
330 | 0 | return this.messages.toString(); |
331 | } | |
332 | ||
333 | /** | |
334 | * Holds messages for a specified property. | |
335 | */ | |
336 | protected static class MessageItem implements Serializable { | |
337 | ||
338 | /** | |
339 | * The list of <code>Message</code>s. | |
340 | */ | |
341 | 0 | private List list = null; |
342 | ||
343 | /** | |
344 | * The position in the list of messages. | |
345 | */ | |
346 | 0 | private int order = 0; |
347 | ||
348 | /** | |
349 | * Construct a MessageItem with a list of messages | |
350 | * and specified order. | |
351 | * @param list List of Messages. | |
352 | * @param order Order. | |
353 | */ | |
354 | 0 | public MessageItem(List list, int order) { |
355 | 0 | this.list = list; |
356 | 0 | this.order = order; |
357 | 0 | } |
358 | ||
359 | /** | |
360 | * @return The list of messsages. | |
361 | */ | |
362 | public List getList() { | |
363 | 0 | return list; |
364 | } | |
365 | ||
366 | /** | |
367 | * @param list The list of messsages. | |
368 | */ | |
369 | public void setList(List list) { | |
370 | 0 | this.list = list; |
371 | 0 | } |
372 | ||
373 | /** | |
374 | * @return The order. | |
375 | */ | |
376 | public int getOrder() { | |
377 | 0 | return order; |
378 | } | |
379 | ||
380 | /** | |
381 | * @param order The order. | |
382 | */ | |
383 | public void setOrder(int order) { | |
384 | 0 | this.order = order; |
385 | 0 | } |
386 | ||
387 | } | |
388 | ||
389 | } |