2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.usecases.rolodex;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.SortedSet;
26 import java.util.TreeSet;
27
28 import javax.faces.model.SelectItem;
29
30 import org.apache.commons.digester.Digester;
31 import org.xml.sax.InputSource;
32 import org.xml.sax.SAXException;
33
34 /***
35 * <p>
36 * Data Access Object for the roledex use case.
37 * </p>
38 */
39 public class RolodexDao {
40
41 /***
42 * <p>
43 * Mock datastore.
44 * </p>
45 */
46 private Collection entityDataStore = null;
47
48 private Collection stateDataStore = null;
49
50 private Collection countryDataStore = null;
51
52 /***
53 * <p>
54 * The constructor loads some default data.
55 * </p>
56 */
57 public RolodexDao() {
58 GenericComparator comparator = new GenericComparator();
59 comparator.setSortBy("sortName, name");
60
61 entityDataStore = new TreeSet(comparator);
62
63 comparator = new GenericComparator();
64 comparator.setSortBy("value");
65
66 stateDataStore = new TreeSet(comparator);
67 countryDataStore = new TreeSet(comparator);
68 loadStates();
69 }
70
71 /***
72 * <p>
73 * Tab indexes for the rolodex. Each sub array represents the starting and
74 * ending character index.
75 * </p>
76 */
77 public final static char[][] TAB_INDEX = { { 'A', 'B' }, { 'C', 'D' },
78 { 'E', 'F' }, { 'G', 'H' }, { 'I', 'J' }, { 'K', 'L' },
79 { 'M', 'N' }, { 'O', 'P' }, { 'Q', 'Z' } };
80
81 /***
82 * <p>
83 * Returns a list of <code>SelectItem</code> that will be used to build
84 * the links.
85 * </p>
86 */
87 public List getTabs() {
88 List tabs = new ArrayList();
89 SelectItem tab = null;
90
91 for (int i = 0; i < TAB_INDEX.length; i++) {
92 tab = new SelectItem();
93 tab.setLabel(TAB_INDEX[i][0] + "-" + TAB_INDEX[i][1]);
94 tab.setValue(new Integer(i));
95 tabs.add(tab);
96 }
97
98 return tabs;
99 }
100
101 /***
102 * <p>
103 * Saves a {@link Contact} to the mock data store.
104 * </p>
105 */
106 public int saveContact(Contact entity) {
107 entityDataStore.add(entity);
108 return findTabForContact(entity);
109 }
110
111 /***
112 * <p>This function will find the tabIndex that the {@link Contact}
113 * will be located on. It will default to the first page.</p>
114 */
115 public int findTabForContact(Contact contact) {
116 for (int i = 0; i < TAB_INDEX.length; i++) {
117 if ((contact.getTabIndex() >= TAB_INDEX[i][0]) &&
118 (contact.getTabIndex() <= TAB_INDEX[i][1]))
119 return i;
120 }
121
122 return 0;
123 }
124
125
126 /***
127 * <p>
128 * Retuns a subset of contacts within the <code>index</code> of a a tab
129 * defined by <code>TAB_INDEX</code> from the mock data store. If this was
130 * a RDBMS data store, the contacts returned might be a "ghost" object
131 * meaning that maybe only the <code>name</code> attribute would be
132 * populated.
133 * </p>
134 */
135 public List findContactsForTab(int index) {
136 List contacts = new ArrayList();
137
138 Contact low = new Contact();
139 Contact high = new Contact();
140
141 StringBuffer key = new StringBuffer();
142
143 key.append(TAB_INDEX[index][0]);
144 low.setName(key.toString());
145
146 key.setLength(0);
147 key.append(TAB_INDEX[index][1]);
148 for (int i = 0; i < 50; i++)
149 key.append('z');
150
151 high.setName(key.toString());
152
153 SortedSet subSet = ((SortedSet) entityDataStore).subSet(low, high);
154 Iterator si = subSet.iterator();
155 while (si.hasNext())
156 contacts.add(si.next());
157
158 return contacts;
159 }
160
161 /***
162 * <p>
163 * Removes the contact from the mock data store.
164 * </p>
165 */
166 public void deleteContact(Contact entity) {
167 entityDataStore.remove(entity);
168 }
169
170 /***
171 * <p>
172 * Loads the {@link State} codes and contacts from an XML data source. The
173 * <code>stateDataStore</code> set will hold the states where the
174 * <code>countryDataStore</code> set will hold the countries. The target type of
175 * these collections will be SelectItem. The contacts are held in the
176 * <code>entityDataStore</code> set.
177 * </p>
178 */
179 public void loadStates() {
180
181 Object config = new Object() {
182 public void addState(State state) {
183 SelectItem item = null;
184
185 if (stateDataStore.size() == 0) {
186 item = new SelectItem();
187 item.setLabel("");
188 item.setValue("");
189 stateDataStore.add(item);
190 }
191
192 item = new SelectItem();
193 item.setLabel(state.getState());
194 item.setValue(state.getAbbrState());
195 stateDataStore.add(item);
196
197 item = new SelectItem();
198 item.setLabel(state.getCountry());
199 item.setValue(state.getAbbrCountry());
200 countryDataStore.add(item);
201 }
202
203 public void addContact(Contact contact) {
204 saveContact(contact);
205 }
206 };
207
208 Digester digester = new Digester();
209 digester.setValidating(false);
210 digester.setUseContextClassLoader(true);
211
212 digester.addObjectCreate("dex/states/state",
213 org.apache.shale.usecases.rolodex.State.class);
214 digester.addSetProperties("dex/states/state");
215 digester.addSetNext("dex/states/state", "addState",
216 "org.apache.shale.usecases.rolodex.State");
217
218 digester.addObjectCreate("dex/contacts/contact/residentialAddress",
219 org.apache.shale.usecases.rolodex.Address.class);
220 digester.addCallMethod(
221 "dex/contacts/contact/residentialAddress/street1",
222 "setStreet1", 0);
223 digester.addCallMethod(
224 "dex/contacts/contact/residentialAddress/street2",
225 "setStreet2", 0);
226 digester.addCallMethod("dex/contacts/contact/residentialAddress/city",
227 "setCity", 0);
228 digester.addCallMethod("dex/contacts/contact/residentialAddress/state",
229 "setState", 0);
230 digester.addCallMethod("dex/contacts/contact/residentialAddress/zip",
231 "setZipAsString", 0);
232 digester.addCallMethod(
233 "dex/contacts/contact/residentialAddress/province",
234 "setProvince", 0);
235 digester.addCallMethod(
236 "dex/contacts/contact/residentialAddress/country",
237 "setCountry", 0);
238 digester.addSetNext("dex/contacts/contact/residentialAddress",
239 "setResidentialAddress",
240 "org.apache.shale.usecases.rolodex.Address");
241
242 digester.addObjectCreate("dex/contacts/contact/businessAddress",
243 org.apache.shale.usecases.rolodex.Address.class);
244 digester.addCallMethod("dex/contacts/contact/businessAddress/street1",
245 "setStreet1", 0);
246 digester.addCallMethod("dex/contacts/contact/businessAddress/street2",
247 "setStreet2", 0);
248 digester.addCallMethod("dex/contacts/contact/businessAddress/city",
249 "setCity", 0);
250 digester.addCallMethod("dex/contacts/contact/businessAddress/state",
251 "setState", 0);
252 digester.addCallMethod("dex/contacts/contact/businessAddress/zip",
253 "setZipAsString", 0);
254 digester.addCallMethod("dex/contacts/contact/businessAddress/province",
255 "setProvince", 0);
256 digester.addCallMethod("dex/contacts/contact/businessAddress/country",
257 "setCountry", 0);
258 digester.addSetNext("dex/contacts/contact/businessAddress",
259 "setBusinessAddress",
260 "org.apache.shale.usecases.rolodex.Address");
261
262 digester.addObjectCreate("dex/contacts/contact",
263 org.apache.shale.usecases.rolodex.Contact.class);
264 digester.addCallMethod("dex/contacts/contact/name", "setName", 0);
265 digester.addCallMethod("dex/contacts/contact/email", "setEmail", 0);
266 digester.addCallMethod("dex/contacts/contact/residentialPhone",
267 "setResidentialPhone", 0);
268 digester.addCallMethod("dex/contacts/contact/businessPhone",
269 "setBusinessPhone", 0);
270 digester.addSetNext("dex/contacts/contact", "addContact",
271 "org.apache.shale.usecases.rolodex.Contact");
272
273 digester.push(config);
274
275 ClassLoader classloader = Thread.currentThread()
276 .getContextClassLoader();
277 if (classloader == null)
278 classloader = config.getClass().getClassLoader();
279
280 InputSource in = new InputSource(
281 classloader
282 .getResourceAsStream("org/apache/shale/usecases/rolodex/dex.xml"));
283
284 try {
285 digester.parse(in);
286 } catch (IOException e) {
287 e.printStackTrace();
288 } catch (SAXException e) {
289 e.printStackTrace();
290 }
291
292 }
293
294 /***
295 * <p>
296 * Returns an array of states used to populate a select list. The target
297 * type is an array of SelectItem.
298 * </p>
299 */
300 public SelectItem[] getStates() {
301 SelectItem[] states = new SelectItem[stateDataStore.size()];
302 stateDataStore.toArray(states);
303 return states;
304 }
305
306 /***
307 * <p>
308 * Returns an array of countries used to populate a select list. The target
309 * type is an array of SelectItem.
310 * </p>
311 */
312 public SelectItem[] getCountries() {
313 SelectItem[] countries = new SelectItem[countryDataStore.size()];
314 countryDataStore.toArray(countries);
315 return countries;
316 }
317
318 /***
319 * <p>
320 * Returns the latest copy of the {@link Contact} by primary key.
321 * </p>
322 *
323 * @param name
324 * contact name that uniquely identifies a Contact.
325 * @return the target, fully populated {@link Contact}
326 */
327 public Contact findContact(String name) {
328 Contact sarg = new Contact();
329 sarg.setName(name);
330 SortedSet subSet = ((TreeSet) entityDataStore).tailSet(sarg);
331 return (Contact) subSet.first();
332 }
333
334 }