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: LoginEventGateway.java,v 1.1 2006-09-11 12:30:36 sinisa Exp $
022: */
023:
024: package barracudaDiscRack.presentation.personMgmt;
025:
026: // import disc rack specifics
027: import barracudaDiscRack.presentation.*;
028: import barracudaDiscRack.presentation.personMgmt.events.*;
029: import barracudaDiscRack.business.person.*;
030: import barracudaDiscRack.business.DiscRackBusinessException;
031:
032: // import barracuda specifics
033: import org.barracudamvc.core.event.*;
034: import org.barracudamvc.core.forms.*;
035: import org.barracudamvc.core.forms.validators.*;
036: import org.barracudamvc.core.comp.*;
037: import org.barracudamvc.core.util.dom.*;
038: import org.barracudamvc.plankton.data.CollectionsUtil;
039:
040: import org.apache.log4j.*;
041:
042: // import dom specifics
043: import org.w3c.dom.*;
044: import org.w3c.dom.html.*;
045:
046: // import java specifics
047: import javax.servlet.*;
048: import javax.servlet.http.*;
049: import java.io.*;
050: import java.util.List;
051: import java.util.Iterator;
052:
053: /**
054: * LoginEventGateway handles the login functionality of the DiscRack app.
055: *
056: * @author
057: * @version
058: */
059: public class LoginEventGateway extends BaseDiscRackEventGateway {
060:
061: public LoginEventGateway() {
062: //specify who's interested in what
063: specifyLocalEventInterests(getLoginFactory, GetLogin.class);
064: specifyLocalEventInterests(renderLoginFactory,
065: RenderLogin.class);
066: specifyLocalEventInterests(doLoginFactory, DoLogin.class);
067: }
068:
069: // setup the required listener factories
070: private ListenerFactory getLoginFactory = new DefaultListenerFactory() {
071: public BaseEventListener getInstance() {
072: return new GetLoginHandler();
073: }
074:
075: public String getListenerID() {
076: return getID(GetLoginHandler.class);
077: }
078: };
079:
080: private ListenerFactory renderLoginFactory = new DefaultListenerFactory() {
081: public BaseEventListener getInstance() {
082: return new RenderLoginHandler();
083: }
084:
085: public String getListenerID() {
086: return getID(RenderLoginHandler.class);
087: }
088: };
089:
090: private ListenerFactory doLoginFactory = new DefaultListenerFactory() {
091: public BaseEventListener getInstance() {
092: return new DoLoginHandler();
093: }
094:
095: public String getListenerID() {
096: return getID(DoLoginHandler.class);
097: }
098: };
099:
100: // setup a logger for the class
101: protected static Logger logger = Logger
102: .getLogger(LoginEventGateway.class.getName());
103:
104: //private constants
105: private static final String LOGIN_FORM = LoginEventGateway.class
106: .getName()
107: + ".LoginForm"; //LoginForm
108: private static final String LOGIN_ERR = LoginEventGateway.class
109: .getName()
110: + ".LoginErr"; //ValidationException
111:
112: //------------------------------------------------------------
113: // Model 2 - Controller Event Handlers
114: //------------------------------------------------------------
115: /**
116: * GetLoginHandler - this is where we handle any GetLogin event
117: * requests. If they are already logged in, just redirect on.
118: */
119: class GetLoginHandler extends DefaultBaseEventListener {
120: public void handleControlEvent(ControlEventContext context)
121: throws EventException, ServletException, IOException {
122: // MUST DO FIRST - initialize things from the context
123: initUsingContext(context);
124:
125: //unpack the necessary entities from the context
126: DispatchQueue queue = context.getQueue();
127:
128: // if it looks like we are already logged in, try and auto-login
129: // otherwise, just render the login screen
130: if (null != getUser()) {
131: if (logger.isDebugEnabled())
132: logger
133: .debug("Adding DoLogin to Queue (Auto-login)");
134: queue.addEvent(new DoLogin(context.getEvent()));
135: } else {
136: if (logger.isDebugEnabled())
137: logger.debug("Adding RenderLogin to Queue");
138: queue.addEvent(new RenderLogin(context.getEvent()));
139: }
140: }
141: }
142:
143: /**
144: * DoLoginHandler - this is where we handle any AttemptLogin
145: * events. Validate and then redirect accordingly.
146: */
147: class DoLoginHandler 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: //create the login form
157: ValidationException ve = null;
158: if (logger.isDebugEnabled())
159: logger.debug("Creating login form");
160: LoginForm lf = new LoginForm(getComms().session
161: .getHttpSession());
162: try {
163: //map/validate the form
164: if (logger.isDebugEnabled())
165: logger.debug("Mapping/Validating login form");
166: lf.map(req).validate(true);
167: } catch (ValidationException e) {
168: removeUserFromSession();
169: if (logger.isDebugEnabled())
170: logger.debug("Validation Exception: " + e);
171:
172: if (logger.isDebugEnabled())
173: CollectionsUtil.printStackTrace(e
174: .getExceptionList(), 0, logger, null);
175:
176: ve = e;
177: }
178:
179: //store a copy of the form and any errors in the queue
180: if (logger.isDebugEnabled())
181: logger.debug("Saving form, errors");
182: context.putState(LOGIN_FORM, lf);
183: context.putState(LOGIN_ERR, ve);
184:
185: //redirect to the Main screen
186: if (ve == null) {
187: if (logger.isDebugEnabled())
188: logger.debug("Redirecting to "
189: + BasePO.DISC_EVENT_CATALOG_PAGE);
190: throw new ClientSideRedirectException(
191: BasePO.DISC_EVENT_CATALOG_PAGE);
192: } else {
193: if (logger.isDebugEnabled())
194: logger.debug("InterruptDispatch to GetLogin");
195: throw new InterruptDispatchException(new GetLogin());
196: }
197: }
198: }
199:
200: //------------------------------------------------------------
201: // Model 2 - View Event Handlers
202: //------------------------------------------------------------
203: /**
204: * RenderLoginHandler -
205: */
206: class RenderLoginHandler extends DefaultBaseEventListener {
207: public void handleViewEvent(ViewEventContext context)
208: throws EventException, ServletException, IOException {
209: // MUST DO FIRST - initialize things from the context
210: initUsingContext(context);
211:
212: //unpack the necessary entities from the context
213: HttpServletRequest req = context.getRequest();
214:
215: //get the XMLC object
216: LoginHTML page = (LoginHTML) getComms().xmlcFactory
217: .create(LoginHTML.class);
218:
219: //create a template component and render it
220: if (logger.isDebugEnabled())
221: logger.debug("Creating template component");
222: Node node = page.getDocument().getElementById("LoginForm");
223: // BTemplate templateComp = new BTemplate(new LoginModel(context), new DefaultTemplateView(node));
224:
225: TemplateView tv = new DefaultTemplateView(node);
226: TemplateModel tm = new LoginModel(context);
227: BTemplate templateComp = new BTemplate(tm);
228: templateComp.setView(tv);
229:
230: try {
231: templateComp.render(new DefaultViewContext(context));
232: } catch (RenderException re) {
233: logger.warn("Render err:" + re);
234: }
235:
236: //now actually render the page (the DOMWriter will take care of actually
237: //setting the content type)
238: if (logger.isDebugEnabled())
239: logger.debug("Rendering document");
240: new DefaultDOMWriter().write(page, context.getResponse());
241: }
242: }
243:
244: //------------------------------------------------------------
245: // Template Models
246: //------------------------------------------------------------
247: /**
248: * LoginModel
249: */
250: class LoginModel extends AbstractTemplateModel {
251:
252: LoginForm fm = null;
253: ValidationException ve = null;
254:
255: //constructor (extract form, exception from context)
256: public LoginModel(EventContext ec) {
257: fm = (LoginForm) ec.getState(LOGIN_FORM);
258: ve = (ValidationException) ec.getState(LOGIN_ERR);
259: }
260:
261: //register the model by name
262: public String getName() {
263: return "Login";
264: }
265:
266: //provide items by key
267: public Object getItem(String key) {
268: ViewContext vc = getViewContext();
269: if (key.equals("Username")) {
270: return (fm != null ? fm.getVal(LoginForm.USER, "")
271: .toString() : "");
272: } else if (key.equals("Password")) {
273: return (fm != null ? fm.getVal(LoginForm.PASSWORD, "")
274: .toString() : "");
275: } else if (key.equals("Errors")) {
276: if (ve == null)
277: return "";
278: List errlist = ve.getExceptionList();
279: StringBuffer sb = new StringBuffer(
280: errlist.size() > 1 ? "There were several errors:"
281: : "");
282: Iterator it = errlist.iterator();
283: while (it.hasNext()) {
284: sb.append(" "
285: + ((ValidationException) it.next())
286: .getMessage());
287: }
288: return sb.toString();
289: } else
290: return super .getItem(key);
291: }
292:
293: }
294:
295: //------------------------------------------------------------
296: // HTML Form Mappings, Validators
297: //------------------------------------------------------------
298:
299: /**
300: * Login form - define the login form
301: */
302: class LoginForm extends DefaultFormMap {
303: //login form constants (these values correspond to the HTML param names)
304: static final String USER = "login";
305: static final String PASSWORD = "password";
306:
307: HttpSession session = null;
308:
309: public LoginForm(HttpSession isession) {
310: session = isession;
311:
312: //define the elements
313: if (logger.isDebugEnabled())
314: logger.debug("Defining Login form elements");
315: this .defineElement(new DefaultFormElement(USER,
316: FormType.STRING, null, new NotNullValidator(
317: "You must enter a Login.")));
318: this .defineElement(new DefaultFormElement(PASSWORD,
319: FormType.STRING, null, new NotNullValidator(
320: "You must enter a Password.")));
321:
322: //define a form validator
323: if (logger.isDebugEnabled())
324: logger.debug("Defining Registration form validator");
325: this .defineValidator(new LoginValidator(session));
326: }
327:
328: /**
329: * we override this method because instead of using the default validation
330: * process (validate elements, then form), we don't want to validate at all
331: * if they are already logged in...we just assume they're valid and return.
332: */
333: public FormMap validate(boolean deferExceptions)
334: throws ValidationException {
335: //see if they are already logged in. If so, just consider them valid
336: if (logger.isDebugEnabled())
337: logger
338: .debug("Checking to see if already logged in (prevalidated)");
339: Person p = getUser();
340: if (null != p) {
341: try {
342: String fuser = (String) this .getVal(LoginForm.USER);
343: String fpassword = (String) this
344: .getVal(LoginForm.PASSWORD);
345: if (fuser == null && fpassword == null)
346: return this ; //if user/pwd = null, just use the current settings
347: if (p.getLogin().equals(fuser)
348: && p.getPassword().equals(fpassword))
349: return this ; //if they're != null, make sure they match, otherwise, we'll want to force a complete revalidate
350: } catch (DiscRackBusinessException e) {
351: }
352: }
353:
354: //if not, go ahead and validate
355: return super .validate(deferExceptions);
356: }
357: }
358:
359: /**
360: * Login validator - define a custom form validator
361: */
362: class LoginValidator extends DefaultFormValidator {
363:
364: HttpSession session = null;
365:
366: public LoginValidator(HttpSession isession) {
367: session = isession;
368: }
369:
370: public void validateForm(FormMap imap, boolean deferExceptions)
371: throws ValidationException {
372: if (logger.isDebugEnabled())
373: logger.debug("Validating login form");
374:
375: //validate the login information
376: if (logger.isDebugEnabled())
377: logger.debug("Validate the user/pwd info");
378: LoginForm map = (LoginForm) imap;
379: String user = map.getVal(LoginForm.USER, "").toString();
380: String password = map.getVal(LoginForm.PASSWORD, "")
381: .toString();
382: String errMsg = "Invalid username or password. Please check your information and try again.";
383: try {
384: //make sure the login exists and the passwords match
385: Person person = PersonFactory.findPerson(user);
386: if (person == null)
387: throw new ValidationException(map
388: .getElement(LoginForm.USER), errMsg);
389: if (!person.getPassword().equals(password))
390: throw new ValidationException(map
391: .getElement(LoginForm.PASSWORD), errMsg);
392:
393: //log them in
394: setUser(person);
395: } catch (DiscRackBusinessException e) {
396: removeUserFromSession(); //just to be sure we don't get stuck in a loop
397: throw new ValidationException(
398: map.getElement(LoginForm.USER),
399: "System error finding user: "
400: + e.getMessage()
401: + ". Please try again. If the problem persists, contact your system administrator.",
402: e);
403: } catch (DiscRackPresentationException e) {
404: throw new ValidationException(
405: map.getElement(LoginForm.USER),
406: "System error setting user: "
407: + e.getMessage()
408: + ". Please try again. If the problem persists, contact your system administrator.",
409: e);
410: }
411: }
412: }
413: }
|