KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > discRack > pres > screens > DiscScreen


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: DiscScreen.java,v 1.4 2004/02/05 10:24:50 slobodan Exp $
22  */

23 package org.enhydra.barracuda.discRack.pres.screens;
24
25 import java.io.*;
26 import java.util.*;
27 import java.net.*;
28 import javax.servlet.*;
29 import javax.servlet.http.*;
30
31 import org.w3c.dom.*;
32 import org.w3c.dom.html.*;
33
34 import com.lutris.appserver.server.Enhydra;
35 import com.lutris.logging.LogChannel;
36
37 import org.enhydra.xml.xmlc.*;
38
39 import org.enhydra.barracuda.core.comp.*;
40 import org.enhydra.barracuda.core.event.*;
41 import org.enhydra.barracuda.core.event.helper.*;
42 import org.enhydra.barracuda.core.forms.*;
43 import org.enhydra.barracuda.core.forms.validators.*;
44 import org.enhydra.barracuda.plankton.data.*;
45 import org.enhydra.barracuda.core.util.dom.*;
46 import org.enhydra.barracuda.core.util.http.*;
47 import org.apache.log4j.*;
48 import org.enhydra.barracuda.core.util.srv.*;
49
50 import org.enhydra.barracuda.discRack.biz.*;
51 import org.enhydra.barracuda.discRack.biz.person.*;
52 import org.enhydra.barracuda.discRack.biz.disc.*;
53 import org.enhydra.barracuda.discRack.pres.events.*;
54 import org.enhydra.barracuda.discRack.pres.services.*;
55 import org.enhydra.barracuda.discRack.pres.xmlc.*;
56
57 /**
58  * <p>Event handlers (both Controller and View) for the
59  * Disc screen. Note that we actually handle both the Catalog
60  * screen here AND the Disc Maintenance screens.
61  *
62  * <p>We handle the following Control events:
63  * <ul>
64  * <li>GetCatalog - uses an EventForwardingFactory to
65  * automatically fire a RenderCatalog event</li>
66  * <li>GetCatalogMaint - uses an EventForwardingFactory to
67  * automatically fire a RenderCatalogMaint event</li>
68  * <li>GetCatalogEdit - create the disc form, map the request to the
69  * form and then validate it. If there weren't any errors,
70  * then it creates an edit form and populates it from the
71  * currently selected disc record, and saves the edit form in
72  * the event context so that when the RenderCatalogMaint event
73  * is handled the screen can be populated with data. If the
74  * disc form is invalid (ie. user didn't select a disc) then
75  * fire a GetCatalog event.
76  * <li>DoCatalogMaint - this event handler handles both DoCatalogUpdate
77  * and DoCatalogDelete events. Instantiates the Edit form, figures out
78  * what the appropriate action should be (update or delete), does the
79  * deed, and then redirects to the GetCatalog or GetCatalogMaint event,
80  * depending on whether or not there were errors</li>
81  * </ul>
82  *
83  * <p>We handle the following View events:
84  * <ul>
85  * <li>RenderCatalog - Actually render the catalog screen</li>
86  * <li>RenderCatalogMaint - Actually render the edit screen. If the
87  * event context contains an EditForm, we repopulate the screen
88  * from the form. If the context contains edit errs, we will show
89  * those as well</li>
90  * </ul>
91  *
92  * <p>We define the following Forms:
93  * <ul>
94  * <li>DiscForm - contains only one form element: ID. This form
95  * is used primarily to ensure that the user selected a record
96  * on the catalog screen prior to pressing update or delete.</li>
97  * <li>EditForm - contains 5 elements: ID, ARTIST, TITLE, GENRE, and
98  * IS_LIKED, all of which are Strings and take NotNullValidators
99  * _except_ for IS_LIKED, which is a Boolean. In addition, the
100  * edit form uses an IDValidator to ensure that the ID is valid for
101  * given actions.</li>
102  * </ul>
103  *
104  * <p>You can <a HREF="sm_barracudaDiscRack_disc.gif">click here to see a diagram...</a>
105  */

106 public class DiscScreen extends DefaultEventGateway {
107
108     //public constants
109
protected static Logger logger = Logger.getLogger(DiscScreen.class.getName());
110
111     //disc actions
112
private static final int ADD = 0;
113     private static final int CHANGE = 1;
114     private static final int DELETE = 2;
115
116     //form map constants
117
private static final String JavaDoc ACTION = "Action"; //Integer
118
private static final String JavaDoc DISC = "Disc"; //Disc
119

120     //private constants
121
private static final String JavaDoc DISC_ERR = DiscScreen.class.getName()+".DiscErr"; //ValidationException
122
private static final String JavaDoc EDIT_FORM = DiscScreen.class.getName()+".EditForm"; //EditForm
123
private static final String JavaDoc EDIT_ERR = DiscScreen.class.getName()+".EditErr"; //ValidationException
124

125     //this defines the various event handlers
126
private ListenerFactory getCatalogFactory = new EventForwardingFactory(new RenderCatalog());
127     private ListenerFactory getCatalogEditFactory = new DefaultListenerFactory() {public BaseEventListener getInstance() {return new GetCatalogEditHandler();} public String JavaDoc getListenerID() {return getID(GetCatalogEditHandler.class);}};
128     private ListenerFactory getCatalogMaintFactory = new EventForwardingFactory(new RenderCatalogMaint());
129     private ListenerFactory doCatalogMaintFactory = new DefaultListenerFactory() {public BaseEventListener getInstance() {return new DoCatalogMaintHandler();} public String JavaDoc getListenerID() {return getID(DoCatalogMaintHandler.class);}};
130     private ListenerFactory renderCatalogFactory = new DefaultListenerFactory() {public BaseEventListener getInstance() {return new RenderCatalogHandler();} public String JavaDoc getListenerID() {return getID(RenderCatalogHandler.class);}};
131     private ListenerFactory renderCatalogMaintFactory = new DefaultListenerFactory() {public BaseEventListener getInstance() {return new RenderCatalogMaintHandler();} public String JavaDoc getListenerID() {return getID(RenderCatalogMaintHandler.class);}};
132     //private vars
133

134
135     //-------------------- DefaultEventGateway -------------------
136
/**
137      * Public constructor
138      */

139     public DiscScreen() {
140         //specify who's interested in what
141
specifyLocalEventInterests(getCatalogFactory, GetCatalog.class);
142         specifyLocalEventInterests(getCatalogEditFactory, GetCatalogEdit.class);
143         specifyLocalEventInterests(getCatalogMaintFactory, GetCatalogMaint.class);
144         specifyLocalEventInterests(doCatalogMaintFactory, DoCatalogMaint.class);
145         specifyLocalEventInterests(renderCatalogFactory, RenderCatalog.class);
146         specifyLocalEventInterests(renderCatalogMaintFactory, RenderCatalogMaint.class);
147
148         //specify aliases for events we're not explicitly registering an interest in
149
specifyLocalEventAliases(GetCatalogAdd.class);
150         specifyLocalEventAliases(DoCatalogUpdate.class);
151         specifyLocalEventAliases(DoCatalogDelete.class);
152     }
153
154
155     //------------------------------------------------------------
156
// Model 2 - Controller Event Handlers
157
//------------------------------------------------------------
158
/**
159      * GetCatalogEditHandler - this is where we handle a request to
160      * edit the disc record
161      */

162     class GetCatalogEditHandler extends DefaultBaseEventListener {
163         public void handleControlEvent(ControlEventContext context) throws EventException, ServletException, IOException {
164             //unpack the necessary entities from the context
165
HttpServletRequest req = context.getRequest();
166
167             //start by creating the form
168
if (logger.isDebugEnabled()) logger.debug("Creating id form");
169             DiscForm df = new DiscForm();
170             EditForm ef = null;
171
172             try {
173                 //map, validate the id form
174
if (logger.isDebugEnabled()) logger.debug("Mapping id form");
175
176                 df.map(req).validate(true);
177                 String JavaDoc id = df.getStringVal(DiscForm.ID);
178
179                 //get the Disc (the validator will have looked this up)
180
Disc disc = (Disc) df.getState(DISC);
181
182                 //now build the edit map by creating a statemap from the disc record
183
//and then mapping the edit form from that
184
if (logger.isDebugEnabled()) logger.debug("Mapping disc record to disc form");
185                 if (disc!=null) {
186                     StateMap sm = new DefaultStateMap();
187                     try {sm.putState(EditForm.ID, disc.getHandle());} catch (DiscRackBusinessException e) {}
188                     try {sm.putState(EditForm.ARTIST, disc.getArtist());} catch (DiscRackBusinessException e) {}
189                     try {sm.putState(EditForm.TITLE, disc.getTitle());} catch (DiscRackBusinessException e) {}
190                     try {sm.putState(EditForm.GENRE, disc.getGenre());} catch (DiscRackBusinessException e) {}
191                     try {sm.putState(EditForm.IS_LIKED, new Boolean JavaDoc(disc.isLiked()));} catch (DiscRackBusinessException e) {}
192                     ef = new EditForm();
193                     ef.map(sm);
194                 }
195             } catch (ValidationException e) {
196                 if (logger.isDebugEnabled()) logger.debug("Validation Exception: "+e);
197                 if (logger.isDebugEnabled()) CollectionsUtil.printStackTrace(e.getExceptionList(), 0, logger, null);
198                 context.putState(DISC_ERR, e);
199                 throw new InterruptDispatchException(new GetCatalog());
200             }
201
202             //save it in the queue for rendering
203
if (logger.isDebugEnabled()) logger.debug("Saving form, errors");
204             context.putState(EDIT_FORM, ef);
205             context.putState(EDIT_ERR, null);
206         }
207     }
208
209     /**
210      * DoCatalogMaintHandler - this is where we handle any attempt to
211      * actually update the disc
212      */

213     class DoCatalogMaintHandler extends DefaultBaseEventListener {
214         public void handleControlEvent(ControlEventContext context) throws EventException, ServletException, IOException {
215             //unpack the necessary entities from the context
216
BaseEvent event = context.getEvent();
217             HttpServletRequest req = context.getRequest();
218
219             //start by creating the form
220
if (logger.isDebugEnabled()) logger.debug("Creating edit form");
221             EditForm ef = new EditForm();
222
223             ValidationException ve = null;
224             int action = -1;
225             try {
226                 //map the form
227
if (logger.isDebugEnabled()) logger.debug("Mapping edit form");
228                 ef.map(req);
229                 String JavaDoc id = ef.getStringVal(EditForm.ID);
230
231                 //figure out what the underlying event actually was to
232
//determine what "mode" (add, change, delete) we're in.
233
//store this value in the form map (the validator will use it)
234
if (logger.isDebugEnabled()) logger.debug("Determining action: ");
235                 BaseEvent rootEvent = DefaultBaseEvent.getOriginalEvent(event);
236                 if (rootEvent instanceof DoCatalogUpdate) {
237                     if (id.equals(EditForm.INVALID_ID)) action = ADD;
238                     else action = CHANGE;
239                 } else if (rootEvent instanceof DoCatalogDelete) {
240                     action = DELETE;
241                 }
242                 ef.putState(ACTION, new Integer JavaDoc(action));
243
244                 //validate the form. If we're in delete mode, just validate the form
245
//otherwise, validate the whole thing
246
if (logger.isDebugEnabled()) logger.debug("Validating edit form (action="+action+")");
247                 if (action==DELETE) ef.validateForm(true);
248                 else ef.validate(true);
249
250                 //get the Disc (the validator will have looked this up)
251
Disc disc = (Disc) ef.getState(DISC);
252
253                 //update based on action
254
try {
255                     if (action==DELETE) {
256                         if (logger.isDebugEnabled()) logger.debug("Deleting Disc");
257                         if (disc!=null) disc.delete();
258                     } else {
259                         if (logger.isDebugEnabled()) logger.debug("Updating Disc");
260                         if (disc==null) disc = new Disc();
261                         disc.setArtist(ef.getStringVal(EditForm.ARTIST));
262                         disc.setTitle(ef.getStringVal(EditForm.TITLE));
263                         disc.setGenre(ef.getStringVal(EditForm.GENRE));
264                         disc.setLiked(ef.getBooleanVal(EditForm.IS_LIKED).booleanValue());
265                         disc.setOwner(LoginServices.getCurrentUser(SessionServices.getSession(req)));
266                         disc.save();
267                     }
268                 } catch (DiscRackBusinessException e) {
269                     throw new ValidationException(this, "Error updating disc: "+e.getMessage()+" Please try again. If the problem persists contact your system administrator.", e);
270                 }
271             } catch (ValidationException e) {
272                 if (logger.isDebugEnabled()) logger.debug("Validation Exception: "+e);
273                 if (logger.isDebugEnabled()) CollectionsUtil.printStackTrace(e.getExceptionList(), 0, logger, null);
274                 ve = e;
275             }
276
277             //store a copy of the form and any errors in the queue
278
if (logger.isDebugEnabled()) logger.debug("Saving form, errors");
279             context.putState(EDIT_FORM, ef);
280             context.putState(EDIT_ERR, ve);
281
282             //redirect appropriately: if it's valid, update the session
283
//and head for the catalog screen. Otherwise, return to the
284
//edit screen...
285
if (ve==null) {
286                 if (logger.isDebugEnabled()) logger.debug("Redirect to GetCatalog");
287                 throw new ClientSideRedirectException(new GetCatalog());
288             } else if (action==DELETE) {
289                 context.putState(DISC_ERR, ve);
290                 if (logger.isDebugEnabled()) logger.debug("Redirect Delete to GetCatalog");
291                 throw new ClientSideRedirectException(new GetCatalog());
292             } else {
293                 if (logger.isDebugEnabled()) logger.debug("Redirect to GetCatalogMaint");
294                 throw new ClientSideRedirectException(new GetCatalogMaint());
295             }
296         }
297     }
298
299
300     //------------------------------------------------------------
301
// Model 2 - View Event Handlers
302
//------------------------------------------------------------
303
/**
304      * RenderCatalogHandler -
305      */

306     class RenderCatalogHandler extends DefaultBaseEventListener {
307         public void handleViewEvent(ViewEventContext context) throws EventException, ServletException, IOException {
308             //unpack the necessary entities from the context
309
HttpServletRequest req = context.getRequest();
310
311             //get the XMLC object
312
// XMLCFactory factory = XMLCServices.getXMLCFactory(context.getConfig());
313
// DiscCatalogHTML page = (DiscCatalogHTML) factory.create(DiscCatalogHTML.class);
314
DiscCatalogHTML page = (DiscCatalogHTML) DefaultDOMLoader.getGlobalInstance().getDOM(DiscCatalogHTML.class);
315
316
317 // // Swap in our real run-time JavaScript to replace the storyboard JavaScript
318
// HTMLScriptElement script = new DiscCatalogScriptHTML().getElementRealScript();
319
// XMLCUtil.replaceNode(script, page.getElementDummyScript());
320

321 /*
322             //find out who we are logged in as
323             if (logger.isDebugEnabled()) logger.debug("Looking up Person record");
324             Person person = LoginServices.getCurrentUser(SessionServices.getSession(req));
325             try {
326                 page.setTextOwner(person.getFirstname()+" "+person.getLastname()+"'s Discs");
327             } catch (DiscRackBusinessException e) {
328                 page.setTextOwner("Error getting user info: "+e);
329                 Debug.println(this, 0, "Error getting user info: "+e);
330                 Debug.printStackTrace(e);
331             }
332
333             //check for errors
334             if (logger.isDebugEnabled()) logger.debug("Checking for errors");
335             ValidationException ve = (ValidationException) context.get(DISC_ERR);
336             if (ve==null) {
337                 if (showDebug>2) Debug.println (this, 2, "No errors found");
338                 page.getElementErrorText().getParentNode().removeChild(page.getElementErrorText());
339             } else {
340                 List errlist = ve.getExceptionList();
341                 if (showDebug>2) Debug.println (this, 2, errlist.size()+"error(s) found");
342                 StringBuffer sb = new StringBuffer(errlist.size()>1 ? "There were several errors:" : "");
343                 Iterator it = errlist.iterator();
344                 while (it.hasNext()) {
345                     sb.append(" "+((ValidationException) it.next()).getMessage());
346                 }
347                 page.setTextErrorText(sb.toString());
348             }
349
350             // Generate the person's Disc list and create the HTML template references
351             HTMLTableRowElement templateRow = page.getElementTemplateRow();
352             HTMLOptionElement templateOption = page.getElementTemplateOption();
353             Node discTable = templateRow.getParentNode();
354             Node discSelect = templateOption.getParentNode();
355
356             // Remove ids to prevent duplicates
357             templateRow.removeAttribute("id");
358             templateOption.removeAttribute("id");
359
360             // Remove id attributes from the cells in the template row
361             HTMLElement artistCellTemplate = page.getElementArtist();
362             HTMLElement titleCellTemplate = page.getElementTitle();
363             HTMLElement genreCellTemplate = page.getElementGenre();
364             HTMLElement likeThisDisc = page.getElementLikeThisDisc();
365
366             artistCellTemplate.removeAttribute("id");
367             titleCellTemplate.removeAttribute("id");
368             genreCellTemplate.removeAttribute("id");
369             likeThisDisc.removeAttribute("id");
370
371             // Remove the dummy storyboard text from the prototype HTML
372             templateOption.removeChild(templateOption.getFirstChild());
373
374             try {
375                 Disc[] discList = DiscFactory.findDiscsForPerson(person);
376
377                 // Get collection of Discs and loop through collection
378                 // to add each disc as a row in the table.
379                 for (int numDiscs=0; numDiscs<discList.length; numDiscs++) {
380
381                     // set text of new cells to values from string array
382                     Disc currentDisc = discList[numDiscs];
383                     page.setTextArtist(currentDisc.getArtist());
384                     page.setTextTitle(currentDisc.getTitle());
385                     page.setTextGenre(currentDisc.getGenre());
386                     page.setTextLikeThisDisc(currentDisc.isLiked() ? "Yes" : "No");
387
388                     // Add a deep clone of the row to the DOM
389                     Node clonedNode = templateRow.cloneNode(true);
390                     discTable.appendChild(clonedNode);
391                     // Alternative way to insert nodes below
392                     // insertBefore(newNode, oldNode);
393                     // discTable.insertBefore(clonedNode, templateRow);
394
395                     // Now populate the select list
396                     // This algorithm is obscure because options are not normal
397                     // HTML elements
398                     // First populate the option value (the disc database ID).
399                     // Then append a text child as the option
400                     // text, which is what is displayed as the text
401                     // in each row of the select box
402                     HTMLOptionElement clonedOption = (HTMLOptionElement) templateOption.cloneNode(true);
403                     clonedOption.setValue(currentDisc.getHandle());
404                     Node optionTextNode = clonedOption.getOwnerDocument().createTextNode(currentDisc.getArtist()+": "+currentDisc.getTitle());
405                     clonedOption.appendChild(optionTextNode);
406                     // Do only a shallow copy of the option as we don't want the text child
407                     // of the node option
408                     discSelect.appendChild(clonedOption);
409                     // Alternative way to insert nodes below
410                     // insertBefore(newNode, oldNode);
411                     // discSelect.insertBefore(clonedOption, templateOption);
412                 }
413             } catch(Exception e) {
414                 Debug.println(this, 1, "Error populating disc catalog: "+e);
415                 Debug.printStackTrace(e);
416             }
417
418             // Finally remove the template row and template select option
419             // from the page
420             templateRow.getParentNode().removeChild(templateRow);
421             templateOption.getParentNode().removeChild(templateOption);
422 */

423             //load the person, discs list info (we do this here since both models
424
//created below need the same info; might as well only load it once)
425
if (logger.isDebugEnabled()) logger.debug("Loading person, disc info");
426             Person person = LoginServices.getCurrentUser(SessionServices.getSession(context.getRequest()));
427             Disc[] discs = null;
428             try {discs = DiscFactory.findDiscsForPerson(person);}
429             catch (DiscRackBusinessException e) {if (logger.isDebugEnabled()) logger.debug("Err getting disc list:"+e);}
430             ValidationException ve = (ValidationException) context.getState(DISC_ERR);
431
432             //create a template component and render it
433
if (logger.isDebugEnabled()) logger.debug("Creating template component");
434             Node node = page.getDocument().getElementById("CatalogForm");
435             BTemplate templateComp = new BTemplate();
436             templateComp.setView(new DefaultTemplateView(node));
437             templateComp.addModel(new CatalogModel(person, discs, ve));
438             templateComp.addModel(new CatalogRowModel(person, discs, ve));
439             try {templateComp.render(new DefaultViewContext(context));}
440             catch (RenderException re) {if (logger.isDebugEnabled()) logger.debug("Render err:"+re);}
441
442             //now actually render it (the DOMWriter will take care of actually
443
//setting the content type)
444
if (logger.isDebugEnabled()) logger.debug("Rendering document");
445             new DefaultDOMWriter().write(page, context.getResponse());
446         }
447     }
448
449     /**
450      * RenderCatalogMaintHandler -
451      */

452     class RenderCatalogMaintHandler extends DefaultBaseEventListener {
453         public void handleViewEvent(ViewEventContext context) throws EventException, ServletException, IOException {
454             //get the XMLC object
455
// XMLCFactory factory = XMLCServices.getXMLCFactory(context.getConfig());
456
// EditHTML page = (EditHTML) factory.create(EditHTML.class);
457
EditHTML page = (EditHTML) DefaultDOMLoader.getGlobalInstance().getDOM(EditHTML.class);
458
459 /*
460             //repopulate the form if possible
461             EditForm ef = (EditForm) context.get(EDIT_FORM);
462             if (ef!=null) {
463                 String id = ef.getStringVal(EditForm.ID);
464                 page.getElementDiscID().setValue(id!=null && !id.equals(EditForm.INVALID_ID) ? id : "");
465                 page.getElementArtist().setValue(ef.getStringVal(EditForm.ARTIST));
466                 page.getElementTitle().setValue(ef.getStringVal(EditForm.TITLE));
467                 page.getElementGenre().setValue(ef.getStringVal(EditForm.GENRE));
468                 page.getElementLikeBox().setChecked(ef.getBooleanVal(EditForm.IS_LIKED).booleanValue());
469             }
470
471             //show any error messages
472             if (logger.isDebugEnabled()) logger.debug("Checking for errors");
473             ValidationException ve = (ValidationException) context.get(EDIT_ERR);
474             if (ve==null) {
475                 if (showDebug>2) Debug.println (this, 2, "No errors found");
476                 page.getElementErrorText().getParentNode().removeChild(page.getElementErrorText());
477             } else {
478                 List errlist = ve.getExceptionList();
479                 if (showDebug>2) Debug.println (this, 2, errlist.size()+"error(s) found");
480                 StringBuffer sb = new StringBuffer(errlist.size()>1 ? "There were several errors:" : "");
481                 Iterator it = errlist.iterator();
482                 while (it.hasNext()) {
483                     sb.append(" "+((ValidationException) it.next()).getMessage());
484                 }
485                 page.setTextErrorText(sb.toString());
486             }
487 */

488
489             //create a template component and render it
490
if (logger.isDebugEnabled()) logger.debug("Creating template component");
491             Node node = page.getDocument().getElementById("EditForm");
492             BTemplate templateComp = new BTemplate(new EditModel(context));
493             templateComp.setView(new DefaultTemplateView(node));
494             try {templateComp.render(new DefaultViewContext(context));}
495             catch (RenderException re) {if (logger.isDebugEnabled()) logger.debug("Render err:"+re);}
496
497             //now actually render it (the DOMWriter will take care of actually
498
//setting the content type)
499
if (logger.isDebugEnabled()) logger.debug("Rendering document");
500             new DefaultDOMWriter().write(page, context.getResponse());
501         }
502     }
503
504
505     //------------------------------------------------------------
506
// Template Models
507
//------------------------------------------------------------
508
/**
509      * CatalogModel
510      */

511     class CatalogModel extends AbstractTemplateModel {
512
513         Person person = null;
514         Disc[] discs = null;
515         ValidationException ve = null;
516
517         //constructor (extract stuff from context)
518
public CatalogModel(Person iperson, Disc[] idiscs, ValidationException ive) {
519             person = iperson;
520             discs = idiscs;
521             ve = ive;
522         }
523
524         //register the model by name
525
public String JavaDoc getName() {return "Catalog";}
526
527         //provide items by key
528
public Object JavaDoc getItem(String JavaDoc key) {
529             ViewContext vc = getViewContext();
530             try {
531                 if (key.equals("Owner")) {
532                     return person.getFirstname()+" "+person.getLastname()+"'s Discs";
533                 } else if (key.equals("AddMessage")) {
534                     if (discs==null || discs.length<1) return vc.getTemplateNode().cloneNode(true);
535                     else return "";
536                 } else if (key.equals("Selection")) {
537 // DefaultView dv = new DefaultView(vc.getTemplateNode().cloneNode(true));
538
DefaultListModel dlm = new DefaultListModel();
539                     dlm.add(new DefaultItemMap(EditForm.INVALID_ID, "Select One"));
540                     if (discs!=null) for (int i=0; i<discs.length; i++) {
541                         Disc d = discs[i];
542                         DefaultItemMap dim = new DefaultItemMap(d.getHandle(), d.getArtist()+": "+d.getTitle());
543                         dlm.add(dim);
544                     }
545 // BSelect bsComp = new BSelect(dlm, dv, vc);
546
BSelect bsComp = new BSelect(dlm);
547                     bsComp.setEnabled(discs!=null && discs.length>0);
548                     return bsComp;
549                 } else if (key.equals("AddButton")) {
550                     BAction baComp = new BAction(new GetCatalogAdd());
551                     baComp.setDisableBackButton(true);
552                     return baComp;
553                 } else if (key.equals("ChangeButton")) {
554                     BAction baComp = new BAction(new GetCatalogEdit());
555                     baComp.setDisableBackButton(true);
556                     baComp.setEnabled(discs!=null && discs.length>0);
557                     return baComp;
558                 } else if (key.equals("DeleteButton")) {
559                     BAction baComp = new BAction(new DoCatalogDelete());
560                     baComp.setDisableBackButton(true);
561                     baComp.setEnabled(discs!=null && discs.length>0);
562                     return baComp;
563                 } else if (key.equals("ExitButton")) {
564                     BAction baComp = new BAction(new DoLogout());
565                     baComp.setDisableBackButton(true);
566                     return baComp;
567 /*
568                 } else if (key.equals("ChangeButton") ||
569                            key.equals("DeleteButton")) {
570                     DefaultView dv = new DefaultView(vc.getTemplateNode().cloneNode(true));
571                     BInput biComp = new BInput(dv);
572                     biComp.setEnabled(discs!=null && discs.length>0);
573                     return biComp;
574 */

575                 } else if (key.equals("Errors")) {
576                     if (ve==null) return null;
577                     List errlist = ve.getExceptionList();
578                     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(errlist.size()>1 ? "There were several errors:" : "");
579                     Iterator it = errlist.iterator();
580                     while (it.hasNext()) {
581                         sb.append(" "+((ValidationException) it.next()).getMessage());
582                     }
583                     return sb.toString();
584                 } else {
585                     return super.getItem(key);
586                 }
587             } catch (DiscRackBusinessException e) {
588                 return "Disc Err:"+e;
589             }
590         }
591     }
592
593     /**
594      * CatalogRowModel
595      */

596     class CatalogRowModel extends AbstractTemplateModel implements IterativeModel {
597
598         Person person = null;
599         Disc[] discs = null;
600         Disc disc = null;
601         ValidationException ve = null;
602         int cntr = -1;
603
604         //constructor (extract stuff from context)
605
public CatalogRowModel(Person iperson, Disc[] idiscs, ValidationException ive) {
606             person = iperson;
607             discs = idiscs;
608             ve = ive;
609         }
610
611         //register the model by name
612
public String JavaDoc getName() {return "CatalogRow";}
613
614         //provide items by key
615
public Object JavaDoc getItem(String JavaDoc key) {
616             ViewContext vc = getViewContext();
617             try {
618                 if (key.equals("Artist")) {
619                     return (disc!=null ? disc.getArtist() : "??");
620                 } else if (key.equals("Title")) {
621                     return (disc!=null ? disc.getTitle() : "??");
622                 } else if (key.equals("Genre")) {
623                     return (disc!=null ? disc.getGenre() : "??");
624                 } else if (key.equals("LikeIt")) {
625                     return ((disc!=null && disc.isLiked()) ? "Yes sirree bob!" : "No way! Blech!");
626                 } else {
627                     return super.getItem(key);
628                 }
629             } catch (DiscRackBusinessException e) {
630                 return "Disc Err:"+e;
631             }
632         }
633
634         //prepare for iteration
635
public void preIterate() {
636             cntr = -1;
637         }
638
639         //return true if there are more rows in the data model
640
public boolean hasNext() {
641             return (discs!=null && cntr<(discs.length-1));
642         }
643
644         //load the next row in the model
645
public void loadNext() {
646             cntr++;
647             disc = discs[cntr];
648         }
649
650         //cleanup after iteration
651
public void postIterate() {}
652     }
653
654     /**
655      * EditModel
656      */

657     class EditModel extends AbstractTemplateModel {
658
659         ControlEventContext ec = null;
660         EditForm fm = null;
661         ValidationException ve = null;
662         int cntr = -1;
663
664         //constructor (extract stuff from context)
665
public EditModel(ControlEventContext iec) {
666             ec = iec;
667             fm = (EditForm) ec.getState(EDIT_FORM);
668             ve = (ValidationException) ec.getState(EDIT_ERR);
669         }
670
671         //register the model by name
672
public String JavaDoc getName() {return "Edit";}
673
674         //provide items by key
675
public Object JavaDoc getItem(String JavaDoc key) {
676             ViewContext vc = getViewContext();
677             if (key.equals("ID")) {
678                 String JavaDoc val = null;
679                 if (fm!=null) val = fm.getStringVal(EditForm.ID);
680                 if (val==null) val = EditForm.INVALID_ID;
681 // DefaultView dv = new DefaultView(vc.getTemplateNode().cloneNode(true));
682
// return new BInput(BInput.HIDDEN, null, val, dv, vc);
683
return new BInput(BInput.HIDDEN, null, val);
684             } else if (key.equals("Artist")) {
685                 return (fm!=null ? fm.getStringVal(EditForm.ARTIST, "") : "");
686             } else if (key.equals("Title")) {
687                 return (fm!=null ? fm.getStringVal(EditForm.TITLE, "") : "");
688             } else if (key.equals("Genre")) {
689                 return (fm!=null ? fm.getStringVal(EditForm.GENRE, "") : "");
690             } else if (key.equals("LikeIt")) {
691                 boolean sel = false;
692                 if (fm!=null) {
693                     try {sel = fm.getBooleanVal(EditForm.IS_LIKED).booleanValue();}
694                     catch (Exception JavaDoc e) {}
695                 }
696 // DefaultView dv = new DefaultView(vc.getTemplateNode().cloneNode(true));
697
// BToggleButton btbComp = new BToggleButton(null, null, null, sel, dv, vc);
698
BToggleButton btbComp = new BToggleButton(null, null, null, sel);
699                 return btbComp;
700             } else if (key.equals("SaveButton")) {
701                 BAction baComp = new BAction(new DoCatalogUpdate());
702                 baComp.setDisableBackButton(true);
703                 return baComp;
704             } else if (key.equals("CancelButton")) {
705                 BAction baComp = new BAction(new GetCatalog());
706                 baComp.setDisableBackButton(true);
707                 return baComp;
708             } else if (key.equals("Errors")) {
709                 if (ve==null) return "";
710                 List errlist = ve.getExceptionList();
711                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc(errlist.size()>1 ? "There were several errors:" : "");
712                 Iterator it = errlist.iterator();
713                 while (it.hasNext()) {
714                     sb.append(" "+((ValidationException) it.next()).getMessage());
715                 }
716                 return sb.toString();
717             } else {
718                 return super.getItem(key);
719             }
720         }
721     }
722
723
724     //------------------------------------------------------------
725
// HTML Form Mappings, Validators
726
//------------------------------------------------------------
727
/**
728      * Disc form - used to select a Disc record for change/delete
729      */

730     class DiscForm extends DefaultFormMap {
731         //edit form constants (these values correspond to the HTML params)
732
static final String JavaDoc ID = "discID";
733
734         //id values
735
static final String JavaDoc INVALID_ID = "invalidID";
736
737         public DiscForm() {
738             //define the elements
739
if (logger.isDebugEnabled()) logger.debug("Defining ID form elements");
740             this.defineElement(new DefaultFormElement(ID, FormType.STRING));
741
742             //define a form validator
743
if (logger.isDebugEnabled()) logger.debug("Defining ID form validator");
744             this.defineValidator(new IDValidator(ID, INVALID_ID));
745         }
746     }
747
748     /**
749      * Edit form - used to actually add/change/delete a disc record
750      */

751     class EditForm extends DefaultFormMap {
752         //edit form constants (these values correspond to the HTML params)
753
static final String JavaDoc ID = "discID";
754         static final String JavaDoc ARTIST = "artist";
755         static final String JavaDoc TITLE = "title";
756         static final String JavaDoc GENRE = "genre";
757         static final String JavaDoc IS_LIKED = "like";
758
759         //id values
760
static final String JavaDoc INVALID_ID = "invalidID";
761
762         public EditForm() {
763             //define the elements
764
if (logger.isDebugEnabled()) logger.debug("Defining Edit form elements");
765             this.defineElement(new DefaultFormElement(ID));
766             this.defineElement(new DefaultFormElement(ARTIST, FormType.STRING, null, new NotNullValidator("You must enter the Artist's name.")));
767             this.defineElement(new DefaultFormElement(TITLE, FormType.STRING, null, new NotNullValidator("You must enter a Title.")));
768             this.defineElement(new DefaultFormElement(GENRE, FormType.STRING, null, new NotNullValidator("You must enter a Genre.")));
769             this.defineElement(new DefaultFormElement(IS_LIKED, FormType.BOOLEAN, new Boolean JavaDoc(false)));
770
771             //define a form validator
772
if (logger.isDebugEnabled()) logger.debug("Defining Edit form validator");
773             this.defineValidator(new EditValidator());
774         }
775     }
776
777     /**
778      * Edit validator - validate an edit form request
779      * based on action (add, change, or delete a record)
780      */

781     class EditValidator extends DefaultFormValidator {
782         public void validateForm(FormMap map, boolean deferExceptions) throws ValidationException {
783             if (logger.isDebugEnabled()) logger.debug("Validating edit form");
784
785             //get the action from the map
786
Integer JavaDoc i = (Integer JavaDoc) map.getState(ACTION);
787             if (i!=null) {
788                 //make sure we're dealing with a valid action
789
int action = i.intValue();
790                 if (action!=ADD && action!=CHANGE && action!=DELETE) throw new ValidationException(new Integer JavaDoc(action), "Error Validating Edit Form: Invalid action encountered. Please try again. If the problem persists contact your system administrator.");
791
792                 //pass off request to ID validator
793
new IDValidator(EditForm.ID, EditForm.INVALID_ID).validateForm(action, map, deferExceptions);
794             }
795         }
796     }
797
798     /**
799      * ID validator - validate an id based on action, and load
800      * the Disc it refers to if possible. This validator is a little
801      * sneaky: we reuse it for two different scenarios.
802      *
803      * When someone requests to change/delete a record, we use it to
804      * validate the ID form. In this case, the main validateForm method
805      * is invoked and we just set the action to CHANGE (regardless of
806      * what it really is...it's either that or DELETE...in either case
807      * the action is the same: make sure the record exists and load it).
808      *
809      * In the second case, we use it as an additional validation step for
810      * when someone tries to update the Edit form. In this case the second
811      * validateForm method is invoked, and the real action (ADD, CHANGE, DELETE)
812      * is passed in.
813      *
814      * In both cases, if the record exists it'll be loaded and stored in the
815      * map structure so that methods using the maps don't have to reload the
816      * Disc structure.
817      */

818     class IDValidator extends DefaultFormValidator {
819         String JavaDoc idKey = null;
820         String JavaDoc invalidID = null;
821
822         public IDValidator(String JavaDoc iidKey, String JavaDoc iinvalidID) {
823             idKey = iidKey;
824             invalidID = iinvalidID;
825         }
826
827         public void validateForm(FormMap map, boolean deferExceptions) throws ValidationException {
828             validateForm (CHANGE, map, deferExceptions);
829         }
830
831         public void validateForm(int action, FormMap map, boolean deferExceptions) throws ValidationException {
832             if (logger.isDebugEnabled()) logger.debug("Validating ID form");
833
834             //make sure we've selected a valid entry
835
map.putState(DISC, null);
836             String JavaDoc id = ((DefaultFormMap) map).getStringVal(idKey);
837             if ((action!=ADD) &&
838                 (id==null || id.equals(invalidID))) throw new ValidationException(this, "You must first select a Disc! Please try again.");
839
840             //see if the id exists already
841
boolean exists = false;
842             try {
843                 Disc disc = DiscFactory.findDiscByID(id);
844                 exists = (disc!=null);
845                 map.putState(DISC, disc); //we do this so we don't have to look it up again when we get back
846
} catch(Exception JavaDoc ex) {}
847
848             //if action=ADD, make sure the ID doesn't already exist
849
if (action==ADD && exists) throw new ValidationException(new Integer JavaDoc(action), "Record already exists. Please try again.");
850
851             //if action!=ADD, make sure the ID still exists
852
if (action!=ADD && !exists) throw new ValidationException(new Integer JavaDoc(action), "Record no longer exists (someone else may have deleted it). Please try again.");
853         }
854     }
855 }
856
857
Popular Tags