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: BasePO.java,v 1.1 2006-09-11 12:47:00 sinisa Exp $
022: */
023:
024: package transactionsDiscRack.presentation;
025:
026: import com.lutris.appserver.server.httpPresentation.*;
027: import com.lutris.appserver.server.sql.DBTransaction;
028: import com.lutris.appserver.server.sql.DatabaseManagerException;
029: import com.lutris.appserver.server.Enhydra;
030: import com.lutris.logging.*;
031: import com.lutris.util.KeywordValueException;
032:
033: import org.enhydra.dods.DODS;
034: import org.enhydra.xml.xmlc.XMLObject;
035:
036: import java.lang.reflect.*;
037: import java.sql.SQLException;
038:
039: import transactionsDiscRack.spec.*;
040: import transactionsDiscRack.*;
041:
042: /**
043: * This is the parent Presentaion object. All presentation objects should extend
044: * this class.
045: *
046: * The run method looks for an event parameter and then calls handle<EventName>.
047: * If the "event" Parameter is not defined then the handleDefault() method is
048: * called in your child class.
049: *
050: *
051: */
052: public abstract class BasePO implements HttpPresentation {
053:
054: protected static final String USER_KEY = "DiscRackPerson";
055:
056: protected static String LOGIN_PAGE = "personMgmt/Login.po";
057:
058: protected static String DISC_CATALOG_PAGE = "discMgmt/DiscCatalog.po";
059:
060: private static String EVENT = "event";
061:
062: private static String STANDARD_METHOD_PREFIX = "handle";
063:
064: /**
065: * This is the procedure that is called if there is no "event" HTTP
066: * parameter found. It must be overriden by the subclass to do default
067: * processing or error checking/handling.
068: *
069: * @return String The String representation of the HTML or (other format) of
070: * the document to be displayed. This method would need to be
071: * changed if you wanted to return binary data as well. It returns a
072: * String for simplicity right now.
073: */
074: public abstract XMLObject handleDefault()
075: throws HttpPresentationException;
076:
077: /**
078: * This method should be implemented in the subclass so that it returns true
079: * if this particular request requires the user to be logged in, otherwise
080: * false.
081: */
082: protected abstract boolean loggedInUserRequired();
083:
084: /**
085: * Saved input and output context, and session data
086: */
087: protected HttpPresentationComms myComms = null;
088:
089: /**
090: * Session Data object reference
091: */
092: protected TransactionsDiscRackSessionData mySessionData = null;
093:
094: /**
095: * Transaction object reference
096: */
097: protected DBTransaction transaction = null;
098:
099: /**
100: * Gets HttpPresentation object
101: *
102: * @return The saved comms objects to whichever subclass needs it
103: */
104: public HttpPresentationComms getComms() {
105: return this .myComms;
106: }
107:
108: /**
109: * Gets the session data
110: *
111: * @return session data
112: */
113: public TransactionsDiscRackSessionData getSessionData() {
114: return this .mySessionData;
115: }
116:
117: /**
118: * Sets the user into the session
119: *
120: * @param thePerson
121: * the person to be set in the session
122: * @exception DiscRackPresentationException
123: */
124: public void setUser(Person thePerson)
125: throws TransactionsDiscRackPresentationException {
126: this .getSessionData().setUser(thePerson);
127: }
128:
129: /**
130: * Gets the user from the session
131: *
132: * @return the person object in the session
133: */
134: public String getUserHandle() {
135: return this .getSessionData().getUserHandle();
136: }
137:
138: /**
139: * Method to remove the current user from the session
140: */
141: public void removeUserFromSession() {
142: this .getSessionData().removeUser();
143: }
144:
145: /**
146: * This implements the run method in HttpPresentation.
147: *
148: * @param comms
149: * HttpPresentationComms
150: * @exception Exception
151: */
152: public void run(HttpPresentationComms comms) throws Exception {
153: boolean doCommit = true;
154: try {
155: // Initialize new or get the existing session data
156: initSessionData(comms);
157:
158: initTransaction();
159:
160: // Check if the user needs to be logged in for this request.
161: if (this .loggedInUserRequired()) {
162: checkForUserLogin();
163: }
164: // Handle the incoming event request
165: handleEvent(comms);
166: } catch (Exception ex) {
167: doCommit = false;
168: throw new Exception(ex);
169: } finally {
170: if (doCommit) {
171: commitTransaction();
172: } else {
173: rollbackTransaction();
174: }
175: }
176: }
177:
178: /**
179: * Method to get or create the AgSessionData object from the user session
180: * This object is saved in the EbrokerPresentation object
181: *
182: * @param comms
183: * HttpPresentationComms
184: * @exception Exception
185: */
186: protected void initSessionData(HttpPresentationComms comms)
187: throws TransactionsDiscRackPresentationException {
188: this .myComms = comms;
189:
190: try {
191: Object obj = comms.sessionData
192: .get(TransactionsDiscRackSessionData.SESSION_KEY);
193: // If we found the session data, save it in a private data member
194: if (null != obj) {
195: this .mySessionData = (TransactionsDiscRackSessionData) obj;
196: } else {
197: // If no session data was found, create a new session data
198: // instance
199: this .mySessionData = new TransactionsDiscRackSessionData();
200: comms.sessionData.set(
201: TransactionsDiscRackSessionData.SESSION_KEY,
202: this .mySessionData);
203: }
204: } catch (KeywordValueException ex) {
205: writeDebugMsg("Problem getting session data from session: "
206: + ex.getMessage());
207: }
208: }
209:
210: /**
211: * Method initializes DB transation instance
212: */
213: protected void initTransaction()
214: throws TransactionsDiscRackPresentationException {
215: try {
216: this .transaction = DODS.getDatabaseManager()
217: .createTransaction();
218: } catch (DatabaseManagerException ex) {
219: writeDebugMsg("Problem getting transaction from Database Manager: "
220: + ex.getMessage());
221: } catch (SQLException ex) {
222: writeDebugMsg("Problem getting transaction from Database Manager: "
223: + ex.getMessage());
224: }
225:
226: }
227:
228: /**
229: * Method commits DB transation instance
230: */
231: protected void commitTransaction()
232: throws TransactionsDiscRackPresentationException {
233: try {
234: this .transaction.write();
235: this .transaction.commit();
236: } catch (SQLException ex) {
237: writeDebugMsg("Problem commiting transaction: "
238: + ex.getMessage());
239: try {
240: this .transaction.rollback();
241: } catch (SQLException erl) {
242: }
243: } finally {
244: this .transaction.release();
245: }
246:
247: }
248:
249: private void rollbackTransaction() {
250: try {
251: this .transaction.rollback();
252: } catch (SQLException ex) {
253: }
254: this .transaction.release();
255: }
256:
257: /**
258: * Checks the session data for a User, if not there then redirects to the
259: * login page
260: */
261: protected void checkForUserLogin()
262: throws ClientPageRedirectException,
263: TransactionsDiscRackPresentationException {
264:
265: try {
266: String userHandle = getUserHandle();
267:
268: if (null == userHandle || "".equals(userHandle)) {
269: writeDebugMsg("USER NOT FOUND IN SESSION");
270: // send to LoginPage if a logged in user is required.
271: writeDebugMsg("REDIRECTING TO LOGIN PAGE");
272: throw new ClientPageRedirectException(
273: getComms().request.getApplicationPath()
274: + LOGIN_PAGE);
275: }
276: } catch (Exception ex) {
277: throw new TransactionsDiscRackPresentationException(
278: "Trouble checking for user login status", ex);
279: }
280: }
281:
282: /**
283: * Method to call the proper method for the incoming event
284: *
285: * @param comms
286: * HttpPresentationComms
287: * @exception Exception
288: */
289: public void handleEvent(HttpPresentationComms comms)
290: throws Exception {
291: String event = comms.request.getParameter(EVENT);
292:
293: XMLObject returnHTML = null;
294:
295: if (event == null || event.length() == 0) {
296: returnHTML = handleDefault();
297: } else {
298: returnHTML = getPageContentForEvent(event);
299: }
300: comms.response.writeDOM(returnHTML);
301: }
302:
303: /**
304: * If an event parameter is defined then this invokes the method that
305: * handles that event.
306: *
307: * @param event
308: * the incoming event name
309: * @exception Exception
310: */
311: public XMLObject getPageContentForEvent(String event)
312: throws Exception {
313: try {
314: Method method = this .getClass().getMethod(
315: toMethodName(event), null);
316: XMLObject thePage = (XMLObject) method.invoke(this , null);
317: return thePage;
318:
319: } catch (InvocationTargetException ex) {
320: // Rethrow the originating exception if as it should be propagated
321: // as is
322: // It could be a page redirect exception, etc.
323: if (ex.getTargetException() instanceof Exception) {
324: throw (Exception) ex.getTargetException();
325: } else if (ex.getTargetException() instanceof Error) {
326: throw (Error) ex.getTargetException();
327: } else {
328: throw ex;
329: }
330: } catch (NoSuchMethodException ex) {
331: // The method to handle the event does not exist.
332: throw new TransactionsDiscRackPresentationException(
333: "NO EVENT HANDLER FOUND FOR EVENT: " + event, ex);
334: } catch (IllegalAccessException ex) {
335: // The method to handle the event does not exist.
336: throw new TransactionsDiscRackPresentationException(
337: "ILLEGAL ACCESS TO EVENT HANDLER (is it public?): "
338: + event, ex);
339: }
340: }
341:
342: /**
343: * This sets the first letter of the event parameter value in order to
344: * adhere to Java method naming conventions.
345: *
346: * @param event
347: * the incoming name of the event
348: * @return String the properly capitalized name
349: */
350: private String toMethodName(String event) {
351: StringBuffer methodName = new StringBuffer(
352: STANDARD_METHOD_PREFIX);
353: methodName.append(Character.toUpperCase(event.charAt(0)));
354:
355: if (event.length() > 1) {
356: methodName.append(event.substring(1));
357: }
358:
359: return methodName.toString();
360: }
361:
362: /**
363: * Returns the application object associated with the current request.
364: *
365: * @return the application object.
366: */
367: public TransactionsDiscRack getApplication() {
368: return (TransactionsDiscRack) Enhydra.getApplication();
369: }
370:
371: /**
372: * Method to write a debugging message to the debug log channel when the
373: * DEBUG flag is turned on
374: *
375: * @param msg
376: * The message to write to the DEBUG log channel
377: */
378: public static void writeDebugMsg(String msg) {
379: Enhydra.getLogChannel().write(Logger.DEBUG, msg);
380: }
381: }
|