KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > form > ListEditMap


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.tapestry.form;
16
17 import java.util.ArrayList JavaDoc;
18 import java.util.Collections JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import org.apache.tapestry.Tapestry;
26
27 /**
28  * A utility class often used with the {@link org.apache.tapestry.form.ListEdit} component. A
29  * ListEditMap is loaded with data objects before the ListEdit renders, and again before the
30  * ListEdit rewinds. This streamlines the synchronization of the form against data on the server. It
31  * is most useful when the set of objects is of a manageable size (say, no more than a few hundred
32  * objects).
33  * <p>
34  * The map stores a list of keys, and relates each key to a value. It also tracks a deleted flag for
35  * each key.
36  * <p>
37  * Usage: <br>
38  * The page or component should implement {@link org.apache.tapestry.event.PageBeginRenderListener}
39  * and implement
40  * {@link org.apache.tapestry.event.PageBeginRenderListener#pageBeginRender(org.apache.tapestry.event.PageEvent)}
41  * to initialize the map.
42  * <p>
43  * The external data (from which keys and values are obtained) is queried, and each key/value pair
44  * is {@link #add(Object, Object) added} to the map, in the order that items should be presented.
45  * <p>
46  * The {@link org.apache.tapestry.form.ListEdit}'s source parameter should be bound to the map's
47  * {@link #getKeys() keys} property. The value parameter should be bound to the map's
48  * {@link #setKey(Object) key} property.
49  * <p>
50  * The {@link org.apache.tapestry.form.ListEdit}'s listener parameter should be bound to a listener
51  * method to synchronize a property of the component from the map. <code>
52  * public void synchronize()
53  * {
54  * ListEditMap map = ...;
55  * <i>Type</i> object = (<i>Type</i>)map.getValue();
56  *
57  * if (object == null)
58  * ...
59  *
60  * set<i>Property</i>(object);
61  * }
62  * </code>
63  * <p>
64  * You may also connect a {@link org.apache.tapestry.form.Checkbox}'s selected parameter to the
65  * map's {@link #isDeleted() deleted} property.
66  * <p>
67  * You may track inclusion in other sets by subclassing ListEditMap and implementing new boolean
68  * properties. The accessor method should be a call to {@link #checkSet(Set)} and the mutator method
69  * should be a call to {@link #updateSet(Set, boolean)}.
70  *
71  * @author Howard Lewis Ship
72  * @since 3.0
73  */

74
75 public class ListEditMap
76 {
77     private Map JavaDoc _map = new HashMap JavaDoc();
78
79     private List JavaDoc _keys = new ArrayList JavaDoc();
80
81     private Set JavaDoc _deletedKeys;
82
83     private Object JavaDoc _currentKey;
84
85     /**
86      * Records the key and value into this map. The keys may be obtained, in the order in which they
87      * are added, using {@link #getKeys()}. This also sets the current key (so that you may invoke
88      * {@link #setDeleted(boolean)}, for example).
89      */

90
91     public void add(Object JavaDoc key, Object JavaDoc value)
92     {
93         _currentKey = key;
94
95         _keys.add(_currentKey);
96         _map.put(_currentKey, value);
97     }
98
99     /**
100      * Returns a List of keys, in the order that keys were added to the map (using
101      * {@link #add(Object, Object)}. The caller must not modify the List.
102      */

103
104     public List JavaDoc getKeys()
105     {
106         return _keys;
107     }
108
109     /**
110      * Sets the key for the map. This defines the key used with the other methods:
111      * {@link #getValue()}, {@link #isDeleted()}, {@link #setDeleted(boolean)}.
112      */

113
114     public void setKey(Object JavaDoc key)
115     {
116         _currentKey = key;
117     }
118
119     /**
120      * Returns the current key within the map.
121      */

122
123     public Object JavaDoc getKey()
124     {
125         return _currentKey;
126     }
127
128     /**
129      * Returns the value for the key (set using {@link #setKey(Object)}). May return null if no
130      * such key has been added (this can occur if a data object is deleted between the time a form
131      * is rendered and the time a form is submitted).
132      */

133
134     public Object JavaDoc getValue()
135     {
136         return _map.get(_currentKey);
137     }
138
139     /**
140      * Returns true if the {@link #setKey(Object) current key} is in the set of deleted keys.
141      */

142
143     public boolean isDeleted()
144     {
145         return checkSet(_deletedKeys);
146     }
147
148     /**
149      * Returns true if the set contains the {@link #getKey() current key}. Returns false is the set
150      * is null, or doesn't contain the current key.
151      */

152
153     protected boolean checkSet(Set JavaDoc set)
154     {
155         if (set == null)
156             return false;
157
158         return set.contains(_currentKey);
159     }
160
161     /**
162      * Adds or removes the {@link #setKey(Object) current key} from the set of deleted keys.
163      */

164
165     public void setDeleted(boolean value)
166     {
167         _deletedKeys = updateSet(_deletedKeys, value);
168     }
169
170     /**
171      * Updates the set, adding or removing the {@link #getKey() current key} from it. Returns the
172      * set passed in. If the value is true and the set is null, an new instance of {@link HashSet}
173      * is created and returned.
174      */

175
176     protected Set JavaDoc updateSet(Set JavaDoc set, boolean value)
177     {
178         if (value)
179         {
180             if (set == null)
181                 set = new HashSet JavaDoc();
182
183             set.add(_currentKey);
184         }
185         else
186         {
187             if (set != null)
188                 set.remove(_currentKey);
189         }
190
191         return set;
192     }
193
194     /**
195      * Returns the deleted keys in an unspecified order. Returns a List, which may be empty if no
196      * keys have been deleted.
197      */

198
199     public List JavaDoc getDeletedKeys()
200     {
201         return convertSetToList(_deletedKeys);
202     }
203
204     /**
205      * Removes keys and values that are in the set of deleted keys, then clears the set of deleted
206      * keys. After invoking this method, {@link #getValues()} and {@link #getAllValues()} will
207      * return equivalent lists and {@link #getKeys()} will no longer show any of the deleted keys.
208      * Note that this method <em>does not</em> change the current key. Subclasses that track
209      * additional key sets may want to override this method to remove deleted keys from those key
210      * sets.
211      */

212
213     public void purgeDeletedKeys()
214     {
215         if (_deletedKeys == null)
216             return;
217
218         _map.keySet().removeAll(_deletedKeys);
219         _keys.removeAll(_deletedKeys);
220
221         _deletedKeys = null;
222     }
223
224     /**
225      * Invoked to convert a set into a List.
226      *
227      * @param set
228      * a set (which may be empty or null)
229      * @return a list (possibly empty) of the items in the set
230      */

231
232     protected List JavaDoc convertSetToList(Set JavaDoc set)
233     {
234         if (Tapestry.isEmpty(set))
235             return Collections.EMPTY_LIST;
236
237         return new ArrayList JavaDoc(set);
238     }
239
240     /**
241      * Returns all the values stored in the map, in the order in which values were added to the map
242      * using {@link #add(Object, Object)}.
243      */

244
245     public List JavaDoc getAllValues()
246     {
247         int count = _keys.size();
248         List JavaDoc result = new ArrayList JavaDoc(count);
249
250         for (int i = 0; i < count; i++)
251         {
252             Object JavaDoc key = _keys.get(i);
253             Object JavaDoc value = _map.get(key);
254
255             result.add(value);
256         }
257
258         return result;
259     }
260
261     /**
262      * Returns all the values stored in the map, excluding those whose id has been marked deleted,
263      * in the order in which values were added to the map using {@link #add(Object, Object)}.
264      */

265
266     public List JavaDoc getValues()
267     {
268         int deletedCount = Tapestry.size(_deletedKeys);
269
270         if (deletedCount == 0)
271             return getAllValues();
272
273         int count = _keys.size();
274
275         List JavaDoc result = new ArrayList JavaDoc(count - deletedCount);
276
277         for (int i = 0; i < count; i++)
278         {
279             Object JavaDoc key = _keys.get(i);
280
281             if (_deletedKeys.contains(key))
282                 continue;
283
284             Object JavaDoc value = _map.get(key);
285             result.add(value);
286         }
287
288         return result;
289     }
290
291 }
292
Popular Tags