001: /*
002: * Copyright (c) 1999-2001 Lutris Technologies, Inc. All Rights
003: * Reserved.
004: *
005: * This source code file is distributed by Lutris Technologies, Inc. for
006: * use only by licensed users of product(s) that include this source
007: * file. Use of this source file or the software that uses it is covered
008: * by the terms and conditions of the Lutris Enhydra Development License
009: * Agreement included with this product.
010: *
011: * This Software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
012: * ANY KIND, either express or implied. See the License for the specific terms
013: * governing rights and limitations under the License.
014: *
015: * Contributor(s):
016: *
017: * $Id: BasePO.java,v 1.1 2006-09-11 12:29:11 sinisa Exp $
018: */
019:
020: package com.lutris.airsent.presentation;
021:
022: import com.lutris.airsent.spec.address.*;
023: import com.lutris.airsent.spec.address.*;
024:
025: import com.lutris.airsent.*;
026:
027: import com.lutris.appserver.server.StandardAppUtil;
028: import org.enhydra.xml.xmlc.XMLObject;
029: import com.lutris.appserver.server.httpPresentation.*;
030: import com.lutris.appserver.server.session.*;
031: import com.lutris.appserver.server.Enhydra; //import com.lutris.xml.xmlc.*;
032: //import com.lutris.xml.xmlc.html.*;
033: import com.lutris.logging.*;
034: import com.lutris.util.KeywordValueException;
035: import com.lutris.appserver.server.user.User;
036: import org.w3c.dom.*;
037: import org.w3c.dom.html.HTMLElement;
038: import java.lang.reflect.*;
039: import java.util.*;
040:
041: /**
042: * This is the parent Presentaion object. All presentation objects
043: * should extend this class.
044: *
045: * The run method looks for an event parameter and then calls
046: * handle<EventName>. If the "event" Parameter is not defined then
047: * the handleDefault() method is called in your child class.
048: *
049: * @author
050: * @version
051: */
052: public abstract class BasePO implements HttpPresentation {
053: private static String EVENT = "event";
054: private static String STANDARD_METHOD_PREFIX = "handle";
055:
056: /**
057: * This is the procedure that is called if there is no "event"
058: * HTTP parameter found. It must be overriden by the subclass to
059: * do default processing or error checking/handling.
060: *
061: * @return String The String representation of the HTML or (other format)
062: * of the document to be displayed. This method would need to be changed
063: * if you wanted to return binary data as well. It returns a String
064: * for simplicity right now.
065: */
066: public abstract XMLObject handleDefault()
067: throws HttpPresentationException;
068:
069: /**
070: * This method should be implemented in the subclass so that it returns
071: * the authorization level necessary to access the po.
072: */
073: abstract protected int getRequiredAuthLevel();
074:
075: /**
076: * Saved input and output context, and session data
077: */
078: protected HttpPresentationComms myComms = null;
079: protected AirSentSessionData mySessionData = null;
080:
081: /**
082: * Gets HttpPresentation object
083: *
084: * @return The saved comms objects
085: * to whichever subclass needs it
086: */
087: public HttpPresentationComms getComms() {
088: return this .myComms;
089: }
090:
091: /**
092: * Gets the session data
093: *
094: * @return session data
095: */
096: public AirSentSessionData getSessionData() {
097: return this .mySessionData;
098: }
099:
100: /**
101: * This implements the run method in HttpPresentation.
102: *
103: * @param HttpPresentationComms
104: * @exception Exception
105: */
106: public void run(HttpPresentationComms comms) throws Exception {
107:
108: // Reroute based on content.
109: rerouteForContent(comms);
110:
111: // Initialize new or get the existing session data
112: initSessionData(comms);
113:
114: // Check if the user can access the given page.
115: checkAuthLevel();
116:
117: try {
118:
119: // Handle the incoming event request
120: handleEvent(comms);
121: } catch (Exception e) {
122: System.err.println("EXCEPTION: " + e);
123: throw new Exception("Exception in run " + e);
124: }
125: }
126:
127: /**
128: * Method that determines which content to output based on
129: * the accept type.
130: * Current types:
131: * text/html
132: * text/xml
133: * text/vnd.wap.wml
134: *
135: *
136: */
137: protected void rerouteForContent(HttpPresentationComms comms)
138: throws AirSentPresentationException {
139: DeviceUtils.rerouteForContent(comms);
140: }
141:
142: /**
143: * Method to get or create the AirSentSessionData object from the user session
144: * This object is saved in the AirSentPresentation object
145: *
146: * @param HttpPresentationComms
147: * @exception Exception
148: */
149: protected void initSessionData(HttpPresentationComms comms)
150: throws AirSentPresentationException {
151:
152: this .myComms = comms;
153: try {
154: Object obj = comms.sessionData
155: .get(AirSentSessionData.SESSION_KEY);
156:
157: // If we found the session data, save it in a private data member
158: if (obj != null) {
159: this .mySessionData = (AirSentSessionData) obj;
160: } else {
161: // If no session data was found, create a new session data instance
162: this .mySessionData = new AirSentSessionData();
163: comms.sessionData.set(AirSentSessionData.SESSION_KEY,
164: this .mySessionData);
165: }
166: } catch (KeywordValueException ex) {
167: throw new AirSentPresentationException(
168: "Trouble initializing user", ex);
169: }
170: }
171:
172: /**
173: * Checks the session data for a Student, if not there then redirects to the login page
174: * return the current authorization level (set during login)
175: *
176: * @return an int equal to the current authorization level.
177: */
178: protected int getCurrentAuthLevel()
179: throws ClientPageRedirectException,
180: AirSentPresentationException {
181: int accessLevel = 0;
182:
183: try {
184: accessLevel = getSessionData().getUserAuth();
185: } catch (Exception ex) {
186: throw new AirSentPresentationException(
187: "Trouble getting current authorization level", ex);
188: }
189:
190: return accessLevel;
191: }
192:
193: /**
194: * Checks the session data to see if the user has the authorization to
195: * access the given page. Authorization levels include:
196: * UNAUTH_USER (0) -- login not required.
197: * CUSTOMER_USER (1) -- login as customer required.
198: * MESSENGER_USER (2) -- login as messenger required.
199: * ADMIN_USER (3) -- login as administrator required.
200: *
201: * SIDE EFFECTS: redirects to login page if user not authorized to access page.
202: */
203: protected void checkAuthLevel() throws ClientPageRedirectException,
204: AirSentPresentationException {
205: int currentAuth = getCurrentAuthLevel();
206:
207: try {
208: //We need to allow AirSent_pres to be functional , so if the requested url is /AirSent_pres/ we allow user to acsses to page
209:
210: String uri = myComms.request.getRequestURI();
211: boolean is = uri.startsWith("/AirSent_pres");
212:
213: if (!is) {
214:
215: if (currentAuth < getRequiredAuthLevel()) {
216: if (currentAuth > AirSentConstants.CUSTOMER_USER) {
217: throw new ClientPageRedirectException(
218: AirSentConstants.ADMIN_LOGIN_PAGE);
219: }
220:
221: throw new ClientPageRedirectException("/"
222: + AirSentConstants.HTML_PAGE);
223: }
224:
225: }
226: } catch (Exception ex) {
227: throw new AirSentPresentationException(
228: "Trouble checking for user login status", ex);
229: }
230: }
231:
232: /**
233: * Method to call the proper method for the incoming event
234: *
235: * @param HttpPresentationComms
236: * @exception Exception
237: */
238: public void handleEvent(HttpPresentationComms comms)
239: throws Exception {
240: String event = comms.request.getParameter(EVENT);
241: XMLObject returnDoc = null;
242: try {
243: if (event == null || event.length() == 0) {
244: returnDoc = handleDefault();
245: } else {
246: returnDoc = getPage(event);
247: }
248: comms.response.writeDOM(returnDoc);
249: } catch (Exception e) {
250: throw new Exception("Exception writing dom:" + e);
251: }
252: }
253:
254: /**
255: * this logs out a user from the session. it first grabs
256: * an instance of the sessionData associated with the request
257: * and then sets the user to null in the session data.
258: *
259: * @param HttpServletRequest request - this is the request that
260: * the session data is extracted from.
261: *
262: * @exception AirSentPresentationException when an error occurs or if
263: * the session data for the request is null.
264: */
265: public XMLObject handleLogout() throws AirSentPresentationException {
266: try {
267: mySessionData = null;
268: SessionManager sessionManager = myComms.session
269: .getSessionManager();
270: sessionManager.deleteSession(myComms.session);
271: throw new ClientPageRedirectException(
272: AirSentConstants.HTML_PAGE);
273: } catch (Exception e) {
274: throw new AirSentPresentationException(
275: "Trouble logging out user", e);
276: }
277: }
278:
279: /**
280: * If an event parameter is defined then this invokes the method that
281: * handles that event.
282: *
283: * @param event, the incoming event name
284: * @exception Exception
285: */
286: public XMLObject getPage(String event) throws Exception {
287: try {
288: Method method = this .getClass().getMethod(
289: toMethodName(event), null);
290: XMLObject thePage = (XMLObject) method.invoke(this , null);
291:
292: return thePage;
293: } catch (InvocationTargetException ex) {
294:
295: // Rethrow the originating exception if as it should be propagated as is
296: // It could be a page redirect exception, etc.
297: if (ex.getTargetException() instanceof Exception) {
298: throw (Exception) ex.getTargetException();
299: } else if (ex.getTargetException() instanceof Error) {
300: throw (Error) ex.getTargetException();
301: } else {
302: throw ex;
303: }
304: } catch (NoSuchMethodException ex) {
305:
306: // The method to handle the event does not exist.
307: throw new AirSentPresentationException(
308: "NO EVENT HANDLER FOUND FOR EVENT: " + event, ex);
309: } catch (IllegalAccessException ex) {
310:
311: // The method to handle the event does not exist.
312: throw new AirSentPresentationException(
313: "ILLEGAL ACCESS TO EVENT HANDLER (is it public?): "
314: + event, ex);
315: }
316: }
317:
318: /**
319: * Gets the URI prefix. Special because some devices incorrectly
320: * handle this.
321: *
322: */
323: protected String getURIPrefix() throws AirSentPresentationException {
324: try {
325: String scheme = myComms.request.getScheme();
326: String serverName = myComms.request.getServerName();
327: int serverPort = myComms.request.getServerPort();
328: String applicationPath = myComms.request
329: .getApplicationPath();
330:
331: // don't include default port in the full path
332: if (serverPort == 80) {
333: return scheme + "://" + serverName + applicationPath;
334: } else {
335: return scheme + "://" + serverName + ":" + serverPort
336: + applicationPath;
337: }
338: } catch (Exception ex) {
339: throw new AirSentPresentationException(
340: "Can't get Server Root Name " + "Config file.", ex);
341: }
342: }
343:
344: /**
345: * This sets the first letter of the event parameter value in order
346: * to adhere to Java method naming conventions.
347: *
348: * @param String event the incoming name of the event
349: * @return String the properly capitalized name
350: */
351: private String toMethodName(String event) {
352: StringBuffer methodName = new StringBuffer(
353: STANDARD_METHOD_PREFIX);
354:
355: methodName.append(Character.toUpperCase(event.charAt(0)));
356:
357: if (event.length() > 1) {
358: methodName.append(event.substring(1));
359: }
360:
361: return methodName.toString();
362: }
363:
364: /**
365: * Returns the application object associated with the
366: * current request.
367: *
368: * @return the application object.
369: */
370: public AirSent getApplication() {
371: return (AirSent) Enhydra.getApplication();
372: }
373:
374: /**
375: * Method to write a debugging message to the debug log
376: * channel when the DEBUG flag is turned on
377: *
378: * @param msg The message to write to the DEBUG log channel
379: */
380: public static void writeDebugMsg(String msg) {
381: Enhydra.getLogChannel().write(Logger.DEBUG, msg);
382: }
383:
384: /**
385: * Returns true if the given string is null, empty, or contains
386: * only white space.
387: */
388: protected static boolean isNullField(String field) {
389: if (field == null) {
390: return true;
391: }
392:
393: if (field.trim().equals("")) {
394: return true;
395: }
396:
397: return false;
398: }
399:
400: /**
401: * Returns true if the given string is null, empty, or contains
402: * only white space.
403: */
404: protected static boolean checkField(String field, int size) {
405: if (field == null || field.equals("")) {
406: return false;
407: }
408: if (field.length() <= size) {
409: return true;
410: }
411: return false;
412: }
413:
414: /**
415: *
416: */
417: public static void dumpHeaders(HttpPresentationComms comms) {
418: System.out.println("DUMP HEADERS:");
419: try {
420: HttpPresentationRequest req = comms.request;
421: Enumeration e = req.getHeaderNames();
422: while (e.hasMoreElements()) {
423: String k = (String) e.nextElement();
424: String p = req.getHeader(k);
425: System.out.println(" NAME: " + k + "; VALUE: " + p);
426: }
427: } catch (Exception ex) {
428: System.err.println("ERROR: " + ex);
429: }
430: }
431:
432: /**
433: *
434: */
435: public static void dump(HttpPresentationComms comms) {
436: System.out.println("DUMP PARAMETERS:");
437: try {
438: HttpPresentationRequest req = comms.request;
439: Enumeration e = req.getParameterNames();
440: while (e.hasMoreElements()) {
441: String k = (String) e.nextElement();
442: String p = req.getParameter(k);
443: System.out.println(" NAME: " + k + "; VALUE: " + p);
444: }
445: } catch (Exception ex) {
446: System.err.println("ERROR: " + ex);
447: }
448: }
449: }
|