001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: *
021: * $Id: RegistrationEventGateway.java,v 1.1 2006-09-11 12:30:36 sinisa Exp $
022: */
023: package barracudaDiscRack.presentation.personMgmt;
024:
025: import java.io.*;
026: import java.util.*;
027: import java.net.*;
028: import javax.servlet.*;
029: import javax.servlet.http.*;
030:
031: import org.w3c.dom.*;
032: import org.w3c.dom.html.*;
033:
034: import org.enhydra.xml.xmlc.*;
035:
036: import org.barracudamvc.core.comp.*;
037: import org.barracudamvc.core.event.*;
038: import org.barracudamvc.core.event.helper.*;
039: import org.barracudamvc.core.forms.*;
040: import org.barracudamvc.core.forms.validators.*;
041: import org.barracudamvc.core.util.dom.*;
042: import org.barracudamvc.plankton.data.CollectionsUtil;
043:
044: import org.apache.log4j.*;
045:
046: // import disc rack specifics
047: import barracudaDiscRack.presentation.*;
048: import barracudaDiscRack.business.*;
049: import barracudaDiscRack.business.person.*;
050: import barracudaDiscRack.presentation.events.*;
051: import barracudaDiscRack.presentation.personMgmt.events.*;
052:
053: /**
054: * Event handlers (both Controller and View) for the
055: * Registration screen
056: *
057: * <p>We handle the following Control events:
058: * <ul>
059: * <li>GetRegister - uses an EventForwardingFactory to
060: * automatically fire a RenderRegister event</li>
061: * <li>DoRegister - create the registration form, map the request
062: * to the form and then validate it. If there weren't any errors,
063: * store the Person record, log the user into the session, and
064: * then fire a GetLogin event (which will cause them to be auto-
065: * logged in). Otherwise, fire a GetRegister event (saving the
066: * form and any validation errors in the event context so that
067: * the RenderLogin can update the screen correctly.</li>
068: * </ul>
069: *
070: * <p>We handle the following View events:
071: * <ul>
072: * <li>RenderRegister - Generate the Registration screen. If the event context
073: * contains a RegistrationForm, we repopulate the screen from the form.
074: * If the context contains login errs, we will show those as well</li>
075: * </ul>
076: *
077: * <p>We define the following Forms:
078: * <ul>
079: * <li>RegistrationForm - contains 5 elements: FIRST_NAME, LAST_NAME,
080: * USER, PASSWORD, and REPASSWORD, all of which are Strings and
081: * take NotNullValidators. In addition, registration form uses
082: * RegistrationValidator, which validates the form by making sure
083: * that the passwords match and the person record is not already
084: * on file.</li>
085: * </ul>
086: *
087: * <p>You can <a href="sm_barracudaDiscRack_registration.gif">click here to see a diagram...</a>
088: */
089: public class RegistrationEventGateway extends BaseDiscRackEventGateway {
090:
091: //public constants
092: protected static Logger logger = Logger
093: .getLogger(RegistrationEventGateway.class.getName());
094:
095: //private constants
096: private static final String REGISTRATION_FORM = RegistrationEventGateway.class
097: .getName()
098: + ".RegistrationForm"; //RegistrationForm
099: private static final String REGISTRATION_ERR = RegistrationEventGateway.class
100: .getName()
101: + ".RegistrationErr"; //ValidationException
102:
103: //this defines the various event handlers
104: private ListenerFactory getRegisterFactory = new EventForwardingFactory(
105: new RenderRegister());
106: private ListenerFactory renderRegisterFactory = new DefaultListenerFactory() {
107: public BaseEventListener getInstance() {
108: return new RenderRegisterHandler();
109: }
110:
111: public String getListenerID() {
112: return getID(RenderRegisterHandler.class);
113: }
114: };
115: private ListenerFactory doRegisterFactory = new DefaultListenerFactory() {
116: public BaseEventListener getInstance() {
117: return new DoRegisterHandler();
118: }
119:
120: public String getListenerID() {
121: return getID(DoRegisterHandler.class);
122: }
123: };
124:
125: //private vars
126:
127: //-------------------- DefaultEventGateway -------------------
128: /**
129: * Public constructor
130: */
131: public RegistrationEventGateway() {
132: //specify who's interested in what
133: specifyLocalEventInterests(getRegisterFactory,
134: GetRegister.class);
135: specifyLocalEventInterests(renderRegisterFactory,
136: RenderRegister.class);
137: specifyLocalEventInterests(doRegisterFactory, DoRegister.class);
138: }
139:
140: //------------------------------------------------------------
141: // Model 2 - Controller Event Handlers
142: //------------------------------------------------------------
143: /**
144: * DoRegisterHandler - this is where we handle any attempt to
145: * register.
146: */
147: class DoRegisterHandler extends DefaultBaseEventListener {
148: public void handleControlEvent(ControlEventContext context)
149: throws EventException, ServletException, IOException {
150: // MUST DO FIRST - initialize things from the context
151: initUsingContext(context);
152:
153: //unpack the necessary entities from the context
154: HttpServletRequest req = context.getRequest();
155:
156: //map, validate the registration form
157: if (logger.isDebugEnabled())
158: logger.debug("Creating registration form");
159: RegistrationForm rf = new RegistrationForm();
160: ValidationException ve = null;
161: try {
162: //map/validate the form
163: if (logger.isDebugEnabled())
164: logger
165: .debug("Mapping/Validating registration form");
166: rf.map(req).validate(true);
167:
168: //actually store the user
169: if (logger.isDebugEnabled())
170: logger.debug("Creating user account");
171: HttpSession session = getComms().session
172: .getHttpSession();
173: try {
174: Person person = new Person();
175: person.setLogin(rf
176: .getVal(RegistrationForm.USER, "")
177: .toString());
178: person.setPassword(rf.getVal(
179: RegistrationForm.PASSWORD, "").toString());
180: person
181: .setFirstname(rf.getVal(
182: RegistrationForm.FIRST_NAME, "")
183: .toString());
184: person.setLastname(rf.getVal(
185: RegistrationForm.LAST_NAME, "").toString());
186: person.save();
187: if (logger.isDebugEnabled())
188: logger.debug("Logging user in");
189: setUser(person);
190: } catch (DiscRackBusinessException e) {
191: //if we get an error here, it's because it was valid when we
192: //validated, but by the time we stored it it wasn't any longer
193: if (logger.isDebugEnabled())
194: logger.debug("Biz err:" + e
195: + " Make sure user is Logged out");
196: removeUserFromSession();
197: throw new ValidationException(
198: this ,
199: "Error creating account: "
200: + e.getMessage()
201: + " Please try again. If the problem persists contact your system administrator.",
202: e);
203: } catch (DiscRackPresentationException e) {
204: if (logger.isDebugEnabled())
205: logger.debug("Biz err:" + e
206: + " Make sure user is Logged out");
207: removeUserFromSession();
208: throw new ValidationException(
209: this ,
210: "Error creating account: "
211: + e.getMessage()
212: + " Please try again. If the problem persists contact your system administrator.",
213: e);
214: }
215: } catch (ValidationException e) {
216: if (logger.isDebugEnabled())
217: logger.debug("Validation Exception: " + e);
218:
219: if (logger.isDebugEnabled())
220: CollectionsUtil.printStackTrace(e
221: .getExceptionList(), 0, logger, null);
222:
223: ve = e;
224: }
225:
226: //store a copy of the form and any errors in the queue
227: if (logger.isDebugEnabled())
228: logger.debug("Saving form, errors");
229: context.putState(REGISTRATION_FORM, rf);
230: context.putState(REGISTRATION_ERR, ve);
231:
232: //redirect appropriately: if it's valid, update the session
233: //and head for the login screen. Otherwise, return to the
234: //Registration screen...
235: if (ve == null) {
236: if (logger.isDebugEnabled())
237: logger.debug("Redirecting to GetLogin");
238: throw new ClientSideRedirectException(new GetLogin());
239: } else {
240: if (logger.isDebugEnabled())
241: logger.debug("InterruptDispatch to GetRegister");
242: throw new InterruptDispatchException(new GetRegister());
243: }
244: }
245: }
246:
247: //------------------------------------------------------------
248: // Model 2 - View Event Handlers
249: //------------------------------------------------------------
250: /**
251: * RenderRegisterHandler - this is where we render the registration screen
252: */
253: class RenderRegisterHandler extends DefaultBaseEventListener {
254: public void handleViewEvent(ViewEventContext context)
255: throws EventException, ServletException, IOException {
256: // MUST DO FIRST - initialize things from the context
257: initUsingContext(context);
258:
259: //get the XMLC object
260: RegisterHTML page = (RegisterHTML) getComms().xmlcFactory
261: .create(RegisterHTML.class);
262:
263: //create a template component and render it
264: if (logger.isDebugEnabled())
265: logger.debug("Creating template component");
266: Node node = page.getDocument().getElementById(
267: "RegistrationForm");
268:
269: TemplateView tv = new DefaultTemplateView(node);
270: TemplateModel tm = new RegistrationModel(context);
271: BTemplate templateComp = new BTemplate(tm);
272: templateComp.setView(tv);
273:
274: try {
275: templateComp.render(new DefaultViewContext(context));
276: } catch (RenderException re) {
277: logger.warn("Render err:" + re);
278: }
279:
280: //now actually render it (the DOMWriter will take care of actually
281: //setting the content type)
282: if (logger.isDebugEnabled())
283: logger.debug("Rendering document");
284: new DefaultDOMWriter().write(page, context.getResponse());
285: }
286: }
287:
288: //------------------------------------------------------------
289: // Template Models
290: //------------------------------------------------------------
291: /**
292: * RegistrationModel
293: */
294: class RegistrationModel extends AbstractTemplateModel {
295:
296: RegistrationForm fm = null;
297: ValidationException ve = null;
298:
299: //constructor (extract form, exception from context)
300: public RegistrationModel(EventContext ec) {
301: fm = (RegistrationForm) ec.getState(REGISTRATION_FORM);
302: ve = (ValidationException) ec.getState(REGISTRATION_ERR);
303: }
304:
305: //register the model by name
306: public String getName() {
307: return "Registration";
308: }
309:
310: //provide items by key
311: public Object getItem(String key) {
312: if (key.equals("FirstName")) {
313: return (fm != null ? fm.getVal(
314: RegistrationForm.FIRST_NAME, "") : "");
315: } else if (key.equals("LastName")) {
316: return (fm != null ? fm.getVal(
317: RegistrationForm.LAST_NAME, "") : "");
318: } else if (key.equals("Username")) {
319: return (fm != null ? fm.getVal(RegistrationForm.USER,
320: "") : "");
321: } else if (key.equals("Password")) {
322: return (fm != null ? fm.getVal(
323: RegistrationForm.PASSWORD, "") : "");
324: } else if (key.equals("Repassword")) {
325: return (fm != null ? fm.getVal(
326: RegistrationForm.REPASSWORD, "") : "");
327: } else if (key.equals("Errors")) {
328: if (ve == null)
329: return "";
330: List errlist = ve.getExceptionList();
331: StringBuffer sb = new StringBuffer(
332: errlist.size() > 1 ? "There were several errors:"
333: : "");
334: Iterator it = errlist.iterator();
335: while (it.hasNext()) {
336: sb.append(" "
337: + ((ValidationException) it.next())
338: .getMessage());
339: }
340: return sb.toString();
341: } else
342: return super .getItem(key);
343: }
344:
345: }
346:
347: //------------------------------------------------------------
348: // HTML Form Mappings, Validators
349: //------------------------------------------------------------
350: /**
351: * Registration form - define the registration form
352: */
353: class RegistrationForm extends DefaultFormMap {
354: //registration form constants (these values correspond to the HTML params)
355: static final String FIRST_NAME = "firstname";
356: static final String LAST_NAME = "lastname";
357: static final String USER = "login";
358: static final String PASSWORD = "password";
359: static final String REPASSWORD = "repassword";
360:
361: public RegistrationForm() {
362: //define the elements
363: if (logger.isDebugEnabled())
364: logger.debug("Defining Registration form elements");
365: this .defineElement(new DefaultFormElement(FIRST_NAME,
366: FormType.STRING, null, new NotNullValidator(
367: "You must enter a First name.")));
368: this .defineElement(new DefaultFormElement(LAST_NAME,
369: FormType.STRING, null, new NotNullValidator(
370: "You must enter a Last name.")));
371: this .defineElement(new DefaultFormElement(USER,
372: FormType.STRING, null, new NotNullValidator(
373: "You must enter a Login.")));
374: this .defineElement(new DefaultFormElement(PASSWORD,
375: FormType.STRING, null, new NotNullValidator(
376: "You must enter a Password.")));
377: this .defineElement(new DefaultFormElement(REPASSWORD,
378: FormType.STRING, null, new NotNullValidator(
379: "You must Confirm your password.")));
380:
381: //define a form validator
382: if (logger.isDebugEnabled())
383: logger.debug("Defining Registration form validator");
384: this .defineValidator(new RegistrationValidator());
385: }
386: }
387:
388: /**
389: * Registration validator - define a custom form validator
390: */
391: class RegistrationValidator extends DefaultFormValidator {
392: public void validateForm(FormMap imap, boolean deferExceptions)
393: throws ValidationException {
394: if (logger.isDebugEnabled())
395: logger.debug("Validating registration form");
396:
397: //make sure the passwords match
398: if (logger.isDebugEnabled())
399: logger.debug("Make sure passwords match");
400: RegistrationForm map = (RegistrationForm) imap;
401: String password = map.getVal(RegistrationForm.PASSWORD, "")
402: .toString();
403: String repassword = map.getVal(RegistrationForm.REPASSWORD,
404: "").toString();
405: if (!password.equals(repassword))
406: throw new ValidationException(map
407: .getElement(RegistrationForm.PASSWORD),
408: "Passwords do not match. Please re-enter.");
409:
410: //validate the login information
411: if (logger.isDebugEnabled())
412: logger.debug("Make sure the login isn't taken");
413: String user = map.getVal(RegistrationForm.USER, "")
414: .toString();
415: try {
416: if (PersonFactory.findPerson(user) != null)
417: throw new ValidationException(map
418: .getElement(RegistrationForm.USER),
419: "This login already taken. Please select another.");
420: } catch (DiscRackBusinessException e) {
421: throw new ValidationException(
422: map.getElement(RegistrationForm.USER),
423: "Error checking login against database. Please try again. If the problem persists, contact your system administrator.",
424: e);
425: }
426: }
427: }
428: }
|