0001: /*
0002: * Copyright (c) 2001 - 2005 ivata limited.
0003: * All rights reserved.
0004: * -----------------------------------------------------------------------------
0005: * ivata masks may be redistributed under the GNU General Public
0006: * License as published by the Free Software Foundation;
0007: * version 2 of the License.
0008: *
0009: * These programs are free software; you can redistribute them and/or
0010: * modify them under the terms of the GNU General Public License
0011: * as published by the Free Software Foundation; version 2 of the License.
0012: *
0013: * These programs are distributed in the hope that they will be useful,
0014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0016: *
0017: * See the GNU General Public License in the file LICENSE.txt for more
0018: * details.
0019: *
0020: * If you would like a copy of the GNU General Public License write to
0021: *
0022: * Free Software Foundation, Inc.
0023: * 59 Temple Place - Suite 330
0024: * Boston, MA 02111-1307, USA.
0025: *
0026: *
0027: * To arrange commercial support and licensing, contact ivata at
0028: * http://www.ivata.com/contact.jsp
0029: * -----------------------------------------------------------------------------
0030: * $Log: MaskAction.java,v $
0031: * Revision 1.18 2005/10/17 18:23:09 colinmacleod
0032: * Added STOP_POPULATE_ATTRIBUTE to simplify chained action processing.
0033: *
0034: * Revision 1.17 2005/10/11 18:54:06 colinmacleod
0035: * Fixed some checkstyle and javadoc issues.
0036: *
0037: * Revision 1.16 2005/10/03 10:17:25 colinmacleod
0038: * Fixed some style and javadoc issues.
0039: *
0040: * Revision 1.15 2005/10/02 14:06:34 colinmacleod
0041: * Added/improved log4j logging.
0042: *
0043: * Revision 1.14 2005/09/16 13:40:56 colinmacleod
0044: * Added onDeleteWarn so you can override the default behavior.
0045: *
0046: * Revision 1.13 2005/09/14 12:58:19 colinmacleod
0047: * Added suffix for request names used
0048: * to confirm buttons.
0049: *
0050: * Revision 1.12 2005/05/01 08:54:50 colinmacleod
0051: * Final changes for 0.6.1.
0052: *
0053: * Revision 1.11 2005/04/29 16:34:13 colinmacleod
0054: * Cleared deleteWarn after it is used the first
0055: * time.
0056: *
0057: * Revision 1.10 2005/04/09 18:04:18 colinmacleod
0058: * Changed copyright text to GPL v2 explicitly.
0059: *
0060: * Revision 1.9 2005/03/10 10:41:09 colinmacleod
0061: * Added default forwards.
0062: *
0063: * Revision 1.8 2005/01/19 13:14:02 colinmacleod
0064: * Renamed CausedByException to SystemException.
0065: *
0066: * Revision 1.7 2005/01/07 13:11:03 colinmacleod
0067: * Corrected setting of default list mask.
0068: * (It was set to the input mask instead of list.)
0069: *
0070: * Revision 1.6 2005/01/07 08:43:30 colinmacleod
0071: * Added missing javadoc for getAuthenticator and getMaskFactory.
0072: *
0073: * Revision 1.5 2005/01/07 08:08:24 colinmacleod
0074: * Moved up a version number.
0075: * Changed copyright notices to 2005.
0076: * Updated the documentation:
0077: * - started working on multiproject:site docu.
0078: * - changed the logo.
0079: * Added checkstyle and fixed LOADS of style issues.
0080: * Added separate thirdparty subproject.
0081: * Added struts (in web), util and webgui (in webtheme) from ivata op.
0082: *
0083: * Revision 1.4 2004/12/23 21:28:32 colinmacleod
0084: * Modifications to add ivata op compatibility.
0085: *
0086: * Revision 1.3 2004/11/12 15:10:42 colinmacleod
0087: * Moved persistence classes from ivata op as a replacement for
0088: * ValueObjectLocator.
0089: *
0090: * Revision 1.2 2004/05/18 22:06:37 colinmacleod
0091: * Fixed isCancelled by re-implementing it.
0092: *
0093: * Revision 1.1.1.1 2004/05/16 20:40:33 colinmacleod
0094: * Ready for 0.1 release
0095: *
0096: * Revision 1.3 2004/03/21 21:16:08 colinmacleod
0097: * Shortened name to ivata op.
0098: *
0099: * Revision 1.2 2004/02/01 22:00:33 colinmacleod
0100: * Added full names to author tags
0101: *
0102: * Revision 1.1.1.1 2004/01/27 20:57:55 colinmacleod
0103: * Moved ivata op to SourceForge.
0104: *
0105: * Revision 1.3 2003/11/13 16:03:16 jano
0106: * Worked on bugs in login stage - basic fixes so application is running.
0107: *
0108: * Revision 1.2 2003/10/17 12:36:13 jano
0109: * fixing problems with building
0110: * converting intranet -> portal
0111: * Eclipse building
0112: *
0113: * Revision 1.1.1.1 2003/10/13 20:50:01 colin
0114: * Restructured portal into subprojects
0115: *
0116: * Revision 1.11 2003/08/14 08:15:38 peter
0117: * getRemote updated
0118: *
0119: * Revision 1.10 2003/08/04 11:38:58 peter
0120: * added getRemote, re-added flushCache
0121: *
0122: * Revision 1.9 2003/06/10 10:29:06 peter
0123: * flushing automatically prefixes the pattern given with context path
0124: *
0125: * Revision 1.8 2003/06/09 06:17:06 peter
0126: * added flushCache method
0127: *
0128: * Revision 1.7 2003/03/04 00:25:04 colin
0129: * added execute after clear, with a newly initialized form
0130: *
0131: * Revision 1.6 2003/02/24 19:08:16 colin
0132: * *** empty log message ***
0133: *
0134: * Revision 1.5 2003/02/18 11:12:08 colin
0135: * made more flexible by using PropertyUtils - now works with
0136: * DynaForms too
0137: *
0138: * Revision 1.4 2003/02/04 17:37:37 colin
0139: * new interface
0140: * added onConfirm, onDelete and clear
0141: *
0142: * Revision 1.3 2003/01/27 08:35:42 colin
0143: * simplified login procedure
0144: *
0145: * Revision 1.4 2003/01/18 20:50:26 colin
0146: * extended PortalAction and consolidated login checking
0147: * (userName in session?)
0148: * implemented JavaScript checking at login and help
0149: * functionality
0150: *
0151: * Revision 1.2 2003/01/10 10:34:13 colin
0152: * added drive.cat, drive.sub
0153: *
0154: * Revision 1.1 2002/11/12 12:01:57 colin
0155: * new business package incorporates business logic
0156: *
0157: * Revision 1.1 2002/11/12 10:38:11 colin
0158: * first version. doesn't do much yet - just initializes the
0159: * logger.
0160: * -----------------------------------------------------------------------------
0161: */
0162: package com.ivata.mask.web.struts;
0163:
0164: import java.beans.PropertyDescriptor;
0165: import java.lang.reflect.InvocationTargetException;
0166:
0167: import javax.naming.OperationNotSupportedException;
0168: import javax.servlet.http.HttpServletRequest;
0169: import javax.servlet.http.HttpServletResponse;
0170: import javax.servlet.http.HttpSession;
0171:
0172: import org.apache.commons.beanutils.PropertyUtils;
0173: import org.apache.log4j.Logger;
0174: import org.apache.struts.action.Action;
0175: import org.apache.struts.action.ActionForm;
0176: import org.apache.struts.action.ActionForward;
0177: import org.apache.struts.action.ActionMapping;
0178: import org.apache.struts.taglib.html.Constants;
0179: import org.sourceforge.clientsession.ClientSession;
0180: import org.sourceforge.clientsession.SessionManager;
0181:
0182: import com.ivata.mask.MaskFactory;
0183: import com.ivata.mask.util.StringHandling;
0184: import com.ivata.mask.util.SystemException;
0185: import com.ivata.mask.web.tag.html.ClientSessionConstants;
0186:
0187: /**
0188: * <p>
0189: * Every <code>Action</code> in the system derives from this class, making it
0190: * possible to centralize logging instantiation, and check we have a valid
0191: * intranet session.
0192: * </p>
0193: *
0194: * @since ivata masks 0.4 (2002-11-10)
0195: * @author Colin MacLeod
0196: * <a href='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
0197: * @version $Revision: 1.18 $
0198: */
0199: public abstract class MaskAction extends Action {
0200: /**
0201: * Request attribute flag which indicates we have performed the
0202: * cancellation.
0203: */
0204: private static final String CANCEL_COMPLETE = "MASK_CANEL_COMPLETE";
0205: /**
0206: * <p>
0207: * This log provides tracing and debugging information.
0208: * </p>
0209: */
0210: private static final Logger logger = Logger
0211: .getLogger(MaskAction.class);
0212: /**
0213: * This is appended to form button names when reading them from the request
0214: * parameters directly. This is to ensure the request parameter was
0215: * specifically set.
0216: */
0217: private static final String REQUEST_BUTTON_SUFFIX = "_button";
0218: /**
0219: * <p>
0220: * This mask authenticator will be used to confirm whether or not the user
0221: * should be allowed to continue.
0222: * </p>
0223: */
0224: private MaskAuthenticator authenticator;
0225: /**
0226: * <p>
0227: * Set to <code>true</code> by <code>LoginAction</code> to indicate the
0228: * user name should not be checked.
0229: * </p>
0230: */
0231: private boolean login = false;
0232: /**
0233: * <p>
0234: * This factory is needed to access the masks and groups of masks.
0235: * </p>
0236: */
0237: private MaskFactory maskFactory;
0238:
0239: /**
0240: * <p>
0241: * Construct a mask action, with the given authenticator.
0242: * </p>
0243: *
0244: * @param maskFactoryParam
0245: * This factory is needed to access the masks and groups of
0246: * masks.
0247: * @param authenticatorParam
0248: * used to confirm whether or not the user should be allowed to
0249: * continue, in the <code>execute</code> method.
0250: */
0251: public MaskAction(final MaskFactory maskFactoryParam,
0252: final MaskAuthenticator authenticatorParam) {
0253: this .maskFactory = maskFactoryParam;
0254: this .authenticator = authenticatorParam;
0255: }
0256:
0257: /**
0258: * <p>
0259: * Called when the clear button is pressed, or after an ok or delete button,
0260: * where the session should be restored to its default state.
0261: * </p>
0262: *
0263: * @param mapping
0264: * The ActionMapping used to select this instance.
0265: * @param form
0266: * optional ActionForm bean for this request (if any)
0267: * @param request
0268: * non-HTTP request we are processing
0269: * @param response
0270: * The non-HTTP response we are creating
0271: * @param session
0272: * returned from the <code>request</code> parameter.
0273: * @param clientSession This client session is stored by the form tag,
0274: * and returned via a request parameter. You can use it to store a number
0275: * of attributes, specific to the request.
0276: * @throws SystemException
0277: * if there is any problem which prevents processing. It will
0278: * result in the webapp being forwarded to the standard error
0279: * page.
0280: */
0281: public void clear(final ActionMapping mapping,
0282: final ActionForm form, final HttpServletRequest request,
0283: final HttpServletResponse response,
0284: final HttpSession session, final ClientSession clientSession)
0285: throws SystemException {
0286: if (logger.isDebugEnabled()) {
0287: logger.debug("clear(ActionMapping mapping = " + mapping
0288: + ", ActionForm form = " + form
0289: + ", HttpServletRequest request = " + request
0290: + ", HttpServletResponse response = " + response
0291: + ", HttpSession session = " + session
0292: + ", ClientSession clientSession = "
0293: + clientSession + ") - start");
0294: }
0295:
0296: if (form instanceof MaskForm) {
0297: MaskForm maskForm = (MaskForm) form;
0298: try {
0299: maskForm.clear();
0300: } catch (OperationNotSupportedException e) {
0301: logger
0302: .error(
0303: "clear(ActionMapping, ActionErrors, "
0304: + "ActionForm, HttpServletRequest, "
0305: + "HttpServletResponse, HttpSession, ClientSession)",
0306: e);
0307:
0308: throw new SystemException(e);
0309: }
0310: }
0311:
0312: if (logger.isDebugEnabled()) {
0313: logger
0314: .debug("clear(ActionMapping, ActionErrors, ActionForm, "
0315: + "HttpServletRequest, HttpServletResponse, HttpSession, "
0316: + "ClientSession) - end");
0317: }
0318: }
0319:
0320: /**
0321: * <p>
0322: * Called from the other <code>execute</code> method, this can be
0323: * overridden by each subclass to provide the <i>ivata </i>-specific
0324: * processing required.
0325: * </p>
0326: *
0327: * @param mapping
0328: * The ActionMapping used to select this instance.
0329: * @param form
0330: * optional ActionForm bean for this request (if any)
0331: * @param request
0332: * non-HTTP request we are processing
0333: * @param response
0334: * The non-HTTP response we are creating
0335: * @param session
0336: * returned from the <code>request</code> parameter.
0337: * @param clientSession TODO
0338: * @throws SystemException
0339: * if there is any problem which prevents processing. It will
0340: * result in the webapp being forwarded to the standard error
0341: * page.
0342: * @return this method returns the string used to identify the correct
0343: * <strong>Struts </strong> <code>ActionForward</code> which
0344: * should follow this page, or <code>null</code> if it should
0345: * return to the input.
0346: */
0347: public String execute(final ActionMapping mapping,
0348: final ActionForm form, final HttpServletRequest request,
0349: final HttpServletResponse response,
0350: final HttpSession session, final ClientSession clientSession)
0351: throws SystemException {
0352: if (logger.isDebugEnabled()) {
0353: logger.debug("execute(ActionMapping mapping = " + mapping
0354: + ", ActionForm form = " + form
0355: + ", HttpServletRequest request = " + request
0356: + ", HttpServletResponse response = " + response
0357: + ", HttpSession session = " + session
0358: + ", ClientSession clientSession = "
0359: + clientSession + ") - start");
0360: }
0361:
0362: // default implementation just does nothing
0363:
0364: if (logger.isDebugEnabled()) {
0365: logger
0366: .debug("execute(ActionMapping, ActionErrors, ActionForm, "
0367: + "HttpServletRequest, HttpServletResponse, HttpSession, "
0368: + "ClientSession) - end - return value = "
0369: + null);
0370: }
0371: return null;
0372: }
0373:
0374: /**
0375: * Check that we are authorized to proceed.
0376: *
0377: * @param session Current session we are processing (from request).
0378: * @param request Current request we are processing.
0379: * @param mapping Action mapping for this action (from Struts config).
0380: * @return <code>null</code> if we should continue, otherwise the action
0381: * forward to pass control.
0382: * @throws SystemException Thrown by
0383: * <code>MaskAuthenticator.authenticate</code>.
0384: */
0385: private ActionForward checkAuthentication(
0386: final HttpSession session,
0387: final HttpServletRequest request,
0388: final ActionMapping mapping) throws SystemException {
0389: String authenticateForwardName = authenticator.authenticate(
0390: session, request, servlet.getServletContext(), login);
0391: if (authenticateForwardName != null) {
0392: ActionForward authenticateForward = mapping
0393: .findForward(authenticateForwardName);
0394: // only forward if we are not already there!
0395: if (!authenticateForward.getPath().startsWith(
0396: mapping.getPath())) {
0397: logger
0398: .info("Authenticator for class "
0399: + getClass().getName()
0400: + " returned specific forward -> forwarding to '"
0401: + authenticateForwardName + "'.");
0402: return authenticateForward;
0403: }
0404: }
0405: return null;
0406: }
0407:
0408: /**
0409: * Called when the request has been cancelled by the user.
0410: *
0411: * @param mapping Action mapping for this action (from Struts config).
0412: * @param form The optional ActionForm bean for this request (if any)
0413: * @param request Current request we are processing.
0414: * @param response Current response we are processing.
0415: * @param clientSession Client session for the current request.
0416: * @return Action forward to pass control. Defined by the name
0417: * "cancel" in the Struts configuration.
0418: * @throws SystemException Thrown by the business logic of the subclass
0419: * <code>clear</code> method.
0420: */
0421: private ActionForward cancel(final ActionMapping mapping,
0422: final ActionForm form, final HttpServletRequest request,
0423: final HttpServletResponse response,
0424: final ClientSession clientSession) throws SystemException {
0425: if (logger.isDebugEnabled()) {
0426: logger.debug("cancelRequest(ActionMapping mapping = "
0427: + mapping + ", ActionForm form = " + form
0428: + ", HttpServletRequest request = " + request
0429: + ", HttpServletResponse response = " + response
0430: + ", ClientSession clientSession = "
0431: + clientSession + ") - start");
0432: }
0433: clear(mapping, form, request, response, (HttpSession) request
0434: .getSession(), clientSession);
0435: request.setAttribute(CANCEL_COMPLETE, "true");
0436: ActionForward returnActionForward = mapping
0437: .findForward("cancel");
0438:
0439: if (logger.isDebugEnabled()) {
0440: logger
0441: .debug("cancelRequest(ActionMapping, ActionForm, "
0442: + "HttpServletRequest, HttpServletResponse, "
0443: + "ClientSession, ActionErrors) - end - return value = "
0444: + returnActionForward);
0445: }
0446: return returnActionForward;
0447: }
0448:
0449: /**
0450: * Called when the OK or Apply button is pressed.
0451: *
0452: * @param mapping Action mapping for this action (from Struts config).
0453: * @param form The optional ActionForm bean for this request (if any)
0454: * @param request Current request we are processing.
0455: * @param response Current response we are processing.
0456: * @param clientSession Client session for the current request.
0457: * @param isOk <code>true</code> if the OK button was pressed, otherwise
0458: * the Apply button.
0459: * @return Action forward to pass control. Defined by the name
0460: * "cancel" in the Struts configuration.
0461: * @throws SystemException Thrown by the business logic of the subclass
0462: * <code>onConfirm</code> method.
0463: */
0464: private String confirm(final ActionMapping mapping,
0465: final ActionForm form, final HttpServletRequest request,
0466: final HttpServletResponse response,
0467: final ClientSession clientSession, final boolean isOk)
0468: throws SystemException {
0469: HttpSession session = request.getSession();
0470: String defaultForwardApply = getFromRequestOrForm(
0471: "defaultForwardApply", request, form, "apply");
0472: String defaultForwardOk = getFromRequestOrForm(
0473: "defaultForwardOk", request, form, "ok");
0474:
0475: String defaultForward;
0476: if (isOk) {
0477: defaultForward = defaultForwardOk;
0478: } else {
0479: defaultForward = defaultForwardApply;
0480: }
0481: String forward = onConfirm(mapping, form, request, response,
0482: session, clientSession, defaultForward);
0483: // this stops us going round in circles!
0484: try {
0485: PropertyUtils.setProperty(form, "ok", "");
0486: } catch (IllegalAccessException e) {
0487: logger.error("Error (" + e.getClass().getName()
0488: + ") setting the form OK property.", e);
0489: } catch (InvocationTargetException e) {
0490: logger.error("Error (" + e.getClass().getName()
0491: + ") setting the form OK property.", e);
0492: } catch (NoSuchMethodException e) {
0493: logger.error("Error (" + e.getClass().getName()
0494: + ") setting the form OK property.", e);
0495: }
0496: try {
0497: PropertyUtils.setProperty(form, "apply", "");
0498: } catch (IllegalAccessException e) {
0499: logger.error("Error (" + e.getClass().getName()
0500: + ") setting the form Apply property.", e);
0501: } catch (InvocationTargetException e) {
0502: logger.error("Error (" + e.getClass().getName()
0503: + ") setting the form Apply property.", e);
0504: } catch (NoSuchMethodException e) {
0505: logger.error("Error (" + e.getClass().getName()
0506: + ") setting the form Apply property.", e);
0507: }
0508: // after ok, we clear - ok should mean the window gets
0509: // closed
0510: if (isOk) {
0511: clear(mapping, form, request, response, session,
0512: clientSession);
0513: }
0514: // otherwise the subclass will have to work out for itself
0515: // what to do!
0516: return forward;
0517: }
0518:
0519: /**
0520: * <p>
0521: * Generic method called by the <strong>Struts </strong> interface.
0522: * </p>
0523: *
0524: * <p>
0525: * Process the specified HTTP request, and create the corresponding HTTP
0526: * response. Return an {@link ActionForward}instance describing where and
0527: * how control should be forwarded, or <code>null</code> if the response
0528: * has already been completed.
0529: * </p>
0530: *
0531: * @param mapping Action mapping for this action (from Struts config).
0532: * @param form The optional ActionForm bean for this request (if any)
0533: * @param request Current request we are processing.
0534: * @param response Current response we are processing.
0535: * @exception Exception If the application business logic throws an
0536: * exception.
0537: * @return this method returns a <code>"success"</code>
0538: * <code>ActionForward</code>
0539: * if the compose session is cancelled or successfully sent,
0540: * otherwise a <code>"failure"</code>
0541: * <code>ActionForward</code>.
0542: * @throws SystemException
0543: */
0544: public ActionForward execute(final ActionMapping mapping,
0545: final ActionForm form, final HttpServletRequest request,
0546: final HttpServletResponse response) throws Exception {
0547: if (logger.isDebugEnabled()) {
0548: logger.debug("execute(ActionMapping mapping = " + mapping
0549: + ", ActionForm form = " + form
0550: + ", HttpServletRequest request = " + request
0551: + ", HttpServletResponse response = " + response
0552: + ") - start");
0553: }
0554:
0555: // first get the session - we'll need that everywhere :-)
0556: HttpSession session = request.getSession();
0557: ClientSession clientSession = (ClientSession) request
0558: .getAttribute(ClientSessionConstants.CLIENT_SESSION_NAME);
0559: assert (clientSession != null) : "No client session found in mask action.";
0560: SessionManager sm = (SessionManager) servlet
0561: .getServletContext().getAttribute(
0562: ClientSessionConstants.SESSION_MANAGER_NAME);
0563: sm.marshall(clientSession);
0564:
0565: // if we're missing security session, get out now
0566: ActionForward checkAuthentication = checkAuthentication(
0567: session, request, mapping);
0568: if (checkAuthentication != null) {
0569: return checkAuthentication;
0570: }
0571:
0572: try {
0573: String forward = null;
0574: // in the following sections, if there is no such method, we just
0575: // ignore it - maybe we don't need this button in a DynaForm
0576: String apply = getFromRequestOrForm("apply", request, form);
0577: String clear = getFromRequestOrForm("clear", request, form);
0578: String deleteConfirm = getFromRequestOrForm(
0579: "deleteConfirm", request, form);
0580: String deleteWarn = getFromRequestOrForm("deleteWarn",
0581: request, form);
0582: String ok = getFromRequestOrForm("ok", request, form);
0583: String defaultForwardDelete = getFromRequestOrForm(
0584: "defaultForwardDelete", request, form, "delete");
0585:
0586: // Was this transaction cancelled?
0587: if (isCancelled(request)) {
0588: return cancel(mapping, form, request, response,
0589: clientSession);
0590: }
0591: // if the person is being warned about delete, just go back
0592: if (!StringHandling.isNullOrEmpty(deleteWarn)) {
0593: try {
0594: PropertyUtils.setProperty(form, "deleteWarn", "");
0595: } catch (Exception e) {
0596: if (logger.isDebugEnabled()) {
0597: logger.debug(
0598: "Exception re-setting deleteWarn.", e);
0599: }
0600: }
0601: forward = onDeleteWarn(mapping, form, request,
0602: response, session, defaultForwardDelete);
0603: }
0604: // first was the clear button pressed?
0605: boolean isOk;
0606: if (!StringHandling.isNullOrEmpty(clear)) {
0607: clear(mapping, form, request, response, session,
0608: clientSession);
0609: if (form instanceof MaskForm) {
0610: DialogForm dialogForm = (DialogForm) form;
0611: dialogForm.clear();
0612: }
0613: forward = execute(mapping, form, request, response,
0614: session, clientSession);
0615: // was the delete confirmation button pressed?
0616: } else if (!StringHandling.isNullOrEmpty(deleteConfirm)) {
0617: forward = onDelete(mapping, form, request, response,
0618: session, clientSession, defaultForwardDelete);
0619: // this stops us going round in circles!
0620: PropertyDescriptor descriptor = PropertyUtils
0621: .getPropertyDescriptor(form, "delete");
0622: if ((descriptor != null)
0623: && (descriptor.getWriteMethod() != null)) {
0624: PropertyUtils.setProperty(form, "delete", "");
0625: }
0626: clear(mapping, form, request, response, session,
0627: clientSession);
0628: // was ok or apply pressed?
0629: } else if ((isOk = !StringHandling.isNullOrEmpty(ok))
0630: || !StringHandling.isNullOrEmpty(apply)) {
0631: forward = confirm(mapping, form, request, response,
0632: clientSession, isOk);
0633: } else {
0634: forward = execute(mapping, form, request, response,
0635: session, clientSession);
0636: }
0637: // tell the request processor we've already populated our form
0638: request.setAttribute(STOP_POPULATE_ATTRIBUTE, "true");
0639:
0640: // if the forward is null, return control to the input screen
0641: if (forward == null) {
0642: ActionForward returnActionForward = mapping
0643: .getInputForward();
0644: if (logger.isDebugEnabled()) {
0645: logger
0646: .debug("execute(ActionMapping, ActionForm, "
0647: + "HttpServletRequest, HttpServletResponse) - end "
0648: + "- return value = "
0649: + returnActionForward);
0650: }
0651: return returnActionForward;
0652: }
0653: // if the action forward is not defined, also return to the input
0654: ActionForward actionForward = mapping.findForward(forward);
0655: if (actionForward == null) {
0656: ActionForward returnActionForward = mapping
0657: .getInputForward();
0658: if (logger.isDebugEnabled()) {
0659: logger
0660: .debug("execute(ActionMapping, ActionForm, "
0661: + "HttpServletRequest, HttpServletResponse) - end "
0662: + "- return value = "
0663: + returnActionForward);
0664: }
0665: return returnActionForward;
0666: }
0667:
0668: if (logger.isDebugEnabled()) {
0669: logger
0670: .debug("execute(ActionMapping, ActionForm, "
0671: + "HttpServletRequest, HttpServletResponse) - end "
0672: + "- return value = " + actionForward);
0673: }
0674: return actionForward;
0675: } catch (Exception e) {
0676: logger.error("execute(ActionMapping, ActionForm, "
0677: + "HttpServletRequest, HttpServletResponse)", e);
0678:
0679: // save this exception for the standard error page
0680: request.setAttribute("exception", e);
0681: ActionForward returnActionForward = mapping
0682: .findForward("error");
0683: if (logger.isDebugEnabled()) {
0684: logger
0685: .debug("execute(ActionMapping, ActionForm, "
0686: + "HttpServletRequest, HttpServletResponse) - end "
0687: + "- return value = "
0688: + returnActionForward);
0689: }
0690: return returnActionForward;
0691: }
0692: }
0693:
0694: /**
0695: * This is a request attribute flag we use to tell the request processor not
0696: * to populate the form from the request. We do this so we can forward from
0697: * one request to the next without the form being submitted on the chained
0698: * action too.
0699: */
0700: public static final String STOP_POPULATE_ATTRIBUTE = "stopPopulate";
0701:
0702: /**
0703: * <p>
0704: * This mask authenticator will be used to confirm whether or not the user
0705: * should be allowed to continue.
0706: * </p>
0707: *
0708: * @return Returns the authenticator.
0709: */
0710: protected MaskAuthenticator getAuthenticator() {
0711: if (logger.isDebugEnabled()) {
0712: logger.debug("getAuthenticator() - start");
0713: }
0714:
0715: if (logger.isDebugEnabled()) {
0716: logger.debug("getAuthenticator() - end - return value = "
0717: + authenticator);
0718: }
0719: return authenticator;
0720: }
0721:
0722: /**
0723: * <p>
0724: * Helper method to see if the parameter with the given name is set in the
0725: * request and, if not, if it is set in the form provided.
0726: * </p>
0727: *
0728: * @param name
0729: * the name of the parameter to look for.
0730: * @param request
0731: * servlet request to look for the parameter in.
0732: * @param form
0733: * the form to search for the parameter, if it is not found in
0734: * the request.
0735: * @return value from the request parameter with the name given. If that is
0736: * null, then the value of the form attribute is returned, or
0737: * <code>null</code> if there is no parameter or form attribute
0738: * with the given name.
0739: * @throws SystemException
0740: * if there is an <code>InvocationTargetException</code> or an
0741: * <code>IllegalAccessException</code> accessing the
0742: * parameter.
0743: */
0744: protected final String getFromRequestOrForm(final String name,
0745: final HttpServletRequest request, final ActionForm form)
0746: throws SystemException {
0747: if (logger.isDebugEnabled()) {
0748: logger.debug("getFromRequestOrForm(String name = " + name
0749: + ", HttpServletRequest request = " + request
0750: + ", ActionForm form = " + form + ") - start");
0751: }
0752:
0753: String returnString = getFromRequestOrForm(name, request, form,
0754: null);
0755: if (logger.isDebugEnabled()) {
0756: logger
0757: .debug("getFromRequestOrForm(String, HttpServletRequest, "
0758: + "ActionForm) - end - return value = "
0759: + returnString);
0760: }
0761: return returnString;
0762: }
0763:
0764: /**
0765: * <p>
0766: * Helper method to see if the parameter with the given name is set in the
0767: * request and, if not, if it is set in the form provided.
0768: * </p>
0769: *
0770: * @param name
0771: * the name of the parameter to look for.
0772: * @param request
0773: * servlet request to look for the parameter in.
0774: * @param form
0775: * the form to search for the parameter, if it is not found in
0776: * the request.
0777: * @param defaultValue If the value cannot be found in either form or
0778: * request, then this value is used.
0779: * @return The value from the request parameter with the name given. If
0780: * that is null, then the value of the form attribute is returned, or
0781: * <code>defaultValue</code> if there is no parameter or form
0782: * attribute with the given name.
0783: * @throws SystemException
0784: * if there is an <code>InvocationTargetException</code> or an
0785: * <code>IllegalAccessException</code> accessing the
0786: * parameter.
0787: */
0788: protected final String getFromRequestOrForm(final String name,
0789: final HttpServletRequest request, final ActionForm form,
0790: final String defaultValue) throws SystemException {
0791: if (logger.isDebugEnabled()) {
0792: logger.debug("getFromRequestOrForm(String name = " + name
0793: + ", HttpServletRequest request = " + request
0794: + ", ActionForm form = " + form
0795: + ", String defaultValue = " + defaultValue
0796: + ") - start");
0797: }
0798:
0799: String value = request.getParameter(name
0800: + REQUEST_BUTTON_SUFFIX);
0801: // if it was in the request, we need go no further
0802: if (value != null) {
0803: if (logger.isDebugEnabled()) {
0804: logger
0805: .debug("getFromRequestOrForm(String, "
0806: + "HttpServletRequest, ActionForm, String) - end "
0807: + "- return value = " + value);
0808: }
0809: return value;
0810: }
0811: // if there is no form, just return null
0812: if (form == null) {
0813: if (logger.isDebugEnabled()) {
0814: logger
0815: .debug("getFromRequestOrForm(String, HttpServletRequest,"
0816: + " ActionForm, String) - end - return value = "
0817: + defaultValue);
0818: }
0819: return defaultValue;
0820: }
0821: // try to get it from the form
0822: try {
0823: value = (String) PropertyUtils
0824: .getSimpleProperty(form, name);
0825: } catch (NoSuchMethodException e) {
0826: if (logger.isDebugEnabled()) {
0827: logger.debug("No property called '" + name
0828: + "', defaulting value to '" + defaultValue
0829: + "'.", e);
0830: }
0831:
0832: // well if there is no method in the form, it will just have to be
0833: // null
0834: value = defaultValue;
0835: } catch (InvocationTargetException e) {
0836: logger.error(
0837: "getFromRequestOrForm(String, HttpServletRequest,"
0838: + " ActionForm, String)", e);
0839:
0840: throw new SystemException(e);
0841: } catch (IllegalAccessException e) {
0842: logger.error(
0843: "getFromRequestOrForm(String, HttpServletRequest,"
0844: + " ActionForm, String)", e);
0845:
0846: throw new SystemException(e);
0847: }
0848:
0849: if (logger.isDebugEnabled()) {
0850: logger
0851: .debug("getFromRequestOrForm(String, HttpServletRequest, "
0852: + "ActionForm, String) - end - return value = "
0853: + value);
0854: }
0855: return value;
0856: }
0857:
0858: /**
0859: * <p>
0860: * This method ascertains the correct input mask to use. First it looks for
0861: * an override in the request, then it looks for a parameter in the current
0862: * form before finally using the default.
0863: * </p>
0864: *
0865: * @param request
0866: * servlet request we are processing. A request parameter will be
0867: * first checked here.
0868: * @param form
0869: * the form currently being processed. If there is no request
0870: * parameter, the property "inputMask" is read from the
0871: * form.
0872: * @return string representing the action to perform for the current input
0873: * mask.
0874: * @throws SystemException
0875: * if the input mask cannot be retrieved.
0876: */
0877: protected final String getInputMask(
0878: final HttpServletRequest request, final Object form)
0879: throws SystemException {
0880: if (logger.isDebugEnabled()) {
0881: logger
0882: .debug("getInputMask(HttpServletRequest request = "
0883: + request + ", Object form = " + form
0884: + ") - start");
0885: }
0886:
0887: String inputMask = request.getParameter("inputMask");
0888: if ((inputMask == null) && (form != null)) {
0889: try {
0890: inputMask = (String) PropertyUtils.getProperty(form,
0891: "inputMask");
0892: } catch (IllegalAccessException e) {
0893: logger.error(
0894: "getInputMask(HttpServletRequest, Object)", e);
0895:
0896: e.printStackTrace();
0897: throw new SystemException(e);
0898: } catch (InvocationTargetException e) {
0899: logger.error(
0900: "getInputMask(HttpServletRequest, Object)", e);
0901:
0902: e.printStackTrace();
0903: throw new SystemException(e);
0904: } catch (NoSuchMethodException e) {
0905: // this is ok - just means the form didn't have this property
0906: if (logger.isDebugEnabled()) {
0907: logger.debug(
0908: "NoSuchMethodException found looking for property '"
0909: + "inputMask'", e);
0910: }
0911: }
0912: }
0913: if (inputMask == null) {
0914: inputMask = maskFactory.getDefaultInputMask();
0915: }
0916:
0917: if (logger.isDebugEnabled()) {
0918: logger
0919: .debug("getInputMask(HttpServletRequest, Object) - end "
0920: + "- return value = " + inputMask);
0921: }
0922: return inputMask;
0923: }
0924:
0925: /**
0926: * <p>
0927: * This method ascertains the correct list mask to use. First it looks for
0928: * an override in the request, then it looks for a parameter in the current
0929: * form before finally using the default.
0930: * </p>
0931: *
0932: * @param request
0933: * servlet request we are processing. A request parameter will be
0934: * first checked here.
0935: * @param form
0936: * the form currently being processed. If there is no request
0937: * parameter, the property "listMask" is read from the
0938: * form.
0939: * @return string representing the action to perform for the current list
0940: * mask.
0941: * @throws SystemException
0942: * if the list mask cannot be retrieved.
0943: */
0944: protected final String getListMask(
0945: final HttpServletRequest request, final Object form)
0946: throws SystemException {
0947: if (logger.isDebugEnabled()) {
0948: logger
0949: .debug("getListMask(HttpServletRequest request = "
0950: + request + ", Object form = " + form
0951: + ") - start");
0952: }
0953:
0954: String listMask = request.getParameter("listMask");
0955: if ((listMask == null) && (form != null)) {
0956: try {
0957: listMask = (String) PropertyUtils.getProperty(form,
0958: "listMask");
0959: } catch (IllegalAccessException e) {
0960: logger.error("getListMask(HttpServletRequest, Object)",
0961: e);
0962:
0963: e.printStackTrace();
0964: throw new SystemException(e);
0965: } catch (InvocationTargetException e) {
0966: logger.error("getListMask(HttpServletRequest, Object)",
0967: e);
0968:
0969: e.printStackTrace();
0970: throw new SystemException(e);
0971: } catch (NoSuchMethodException e) {
0972: // this is ok - just means the form didn't have this property
0973: logger.debug("NoSuchMethodException found looking for "
0974: + "property '" + "listMask' in form '"
0975: + form.toString() + "'; (this is normally ok)",
0976: e);
0977: }
0978: }
0979: if (listMask == null) {
0980: listMask = maskFactory.getDefaultListMask();
0981: }
0982:
0983: if (logger.isDebugEnabled()) {
0984: logger
0985: .debug("getListMask(HttpServletRequest, Object) - end "
0986: + "- return value = " + listMask);
0987: }
0988: return listMask;
0989: }
0990:
0991: /**
0992: * <p>
0993: * This factory is needed to access the masks and groups of masks.
0994: * </p>
0995: *
0996: * @return Returns the maskFactory, used to access masks and groups of
0997: * masks.
0998: */
0999: protected MaskFactory getMaskFactory() {
1000: if (logger.isDebugEnabled()) {
1001: logger.debug("getMaskFactory() - start");
1002: }
1003:
1004: if (logger.isDebugEnabled()) {
1005: logger.debug("getMaskFactory() - end - return value = "
1006: + maskFactory);
1007: }
1008: return maskFactory;
1009: }
1010:
1011: /**
1012: * Not sure why I needed to override this!
1013: *
1014: * {@inheritDoc}
1015: *
1016: * @param request {@inheritDoc}
1017: * @return {@inheritDoc}
1018: */
1019: protected final boolean isCancelled(final HttpServletRequest request) {
1020: if (logger.isDebugEnabled()) {
1021: logger.debug("isCancelled(HttpServletRequest request = "
1022: + request + ") - start");
1023: }
1024:
1025: boolean returnboolean = (!"true".equals(request
1026: .getAttribute(CANCEL_COMPLETE)))
1027: && ((request.getParameter("cancel") != null)
1028: || (request
1029: .getParameter(Constants.CANCEL_PROPERTY) != null) || (request
1030: .getParameter(Constants.CANCEL_PROPERTY_X) != null));
1031: if (logger.isDebugEnabled()) {
1032: logger.debug("isCancelled(HttpServletRequest) - end "
1033: + "- return value = " + returnboolean);
1034: }
1035: return returnboolean;
1036: }
1037:
1038: /**
1039: * <p>
1040: * This method is called if the ok or apply buttons are pressed.
1041: * </p>
1042: *
1043: * @param mapping
1044: * The ActionMapping used to select this instance.
1045: * @param form
1046: * optional ActionForm bean for this request (if any)
1047: * @param request
1048: * non-HTTP request we are processing
1049: * @param response
1050: * The non-HTTP response we are creating
1051: * @param session
1052: * returned from the <code>request</code> parameter.
1053: * @param clientSession TODO
1054: * @param defaultForward "ok" if the <code>Ok</code> button
1055: * was pressed, otherwise "apply" if the <code>Apply</code> button
1056: * was pressed.
1057: * @throws SystemException
1058: * if there is any problem which prevents processing. It will
1059: * result in the webapp being forwarded to the standard error
1060: * page.
1061: * @return this method returns the string used to identify the correct
1062: * <strong>Struts </strong> <code>ActionForward</code> which
1063: * should follow this page, or <code>null</code> if it should
1064: * return to the input.
1065: */
1066: public String onConfirm(final ActionMapping mapping,
1067: final ActionForm form, final HttpServletRequest request,
1068: final HttpServletResponse response,
1069: final HttpSession session,
1070: final ClientSession clientSession,
1071: final String defaultForward) throws SystemException {
1072: if (logger.isDebugEnabled()) {
1073: logger.debug("onConfirm(ActionMapping mapping = " + mapping
1074: + ", ActionForm form = " + form
1075: + ", HttpServletRequest request = " + request
1076: + ", HttpServletResponse response = " + response
1077: + ", HttpSession session = " + session
1078: + ", ClientSession clientSession = "
1079: + clientSession + ", String defaultForward = "
1080: + defaultForward + ") - start");
1081: }
1082:
1083: // default implementation just goes back to standard execute routine
1084: execute(mapping, form, request, response, session,
1085: clientSession);
1086:
1087: if (logger.isDebugEnabled()) {
1088: logger.debug("onConfirm - end - return value = "
1089: + defaultForward);
1090: }
1091: return defaultForward;
1092: }
1093:
1094: /**
1095: * <p>
1096: * This method is called if the delete (confirm, not warn) button is
1097: * pressed.
1098: * </p>
1099: * @param mapping
1100: * The ActionMapping used to select this instance.
1101: * @param form
1102: * optional ActionForm bean for this request (if any)
1103: * @param request
1104: * non-HTTP request we are processing
1105: * @param response
1106: * The non-HTTP response we are creating
1107: * @param session
1108: * returned from the <code>request</code> parameter.
1109: * @param clientSession TODO
1110: * @param defaultForward usually "delete". This is the forward
1111: * it is suggested you use, if everything is ok.
1112: * @exception SystemException
1113: * if there is any problem which prevents processing. It will
1114: * result in the webapp being forwarded to the standard error
1115: * page.
1116: * @return this method returns the string used to identify the correct
1117: * <strong>Struts </strong> <code>ActionForward</code> which
1118: * should follow this page, or <code>null</code> if it should
1119: * return to the input.
1120: */
1121: public String onDelete(final ActionMapping mapping,
1122: final ActionForm form, final HttpServletRequest request,
1123: final HttpServletResponse response,
1124: final HttpSession session,
1125: final ClientSession clientSession,
1126: final String defaultForward) throws SystemException {
1127: if (logger.isDebugEnabled()) {
1128: logger.debug("onDelete(ActionMapping mapping = " + mapping
1129: + ", ActionForm form = " + form
1130: + ", HttpServletRequest request = " + request
1131: + ", HttpServletResponse response = " + response
1132: + ", HttpSession session = " + session
1133: + ", ClientSession clientSession = "
1134: + clientSession + ", String defaultForward = "
1135: + defaultForward + ") - start");
1136: }
1137:
1138: // default implementation just goes back to standard execute routine
1139: execute(mapping, form, request, response, session,
1140: clientSession);
1141:
1142: if (logger.isDebugEnabled()) {
1143: logger.debug("onDelete - end - return value = "
1144: + defaultForward);
1145: }
1146: return defaultForward;
1147: }
1148:
1149: /**
1150: * <p>
1151: * This method is called if the delete warning button is
1152: * pressed. It allows you to perform processing before the user is asked to
1153: * confirm the deletion.
1154: * </p>
1155: * @param mapping
1156: * The ActionMapping used to select this instance.
1157: * @param form
1158: * optional ActionForm bean for this request (if any)
1159: * @param request
1160: * non-HTTP request we are processing
1161: * @param response
1162: * The non-HTTP response we are creating
1163: * @param session
1164: * returned from the <code>request</code> parameter.
1165: * @param defaultForward usually "delete". This is the forward
1166: * it is suggested you use, if everything is ok.
1167: * @exception SystemException
1168: * if there is any problem which prevents processing. It will
1169: * result in the webapp being forwarded to the standard error
1170: * page.
1171: * @return this method returns the string used to identify the correct
1172: * <strong>Struts </strong> <code>ActionForward</code> which
1173: * should follow this page, or <code>null</code> if it should
1174: * return to the input.
1175: */
1176: public String onDeleteWarn(final ActionMapping mapping,
1177: final ActionForm form, final HttpServletRequest request,
1178: final HttpServletResponse response,
1179: final HttpSession session, final String defaultForward)
1180: throws SystemException {
1181: if (logger.isDebugEnabled()) {
1182: logger.debug("onDeleteWarn(ActionMapping mapping = "
1183: + mapping + ", ActionForm form = " + form
1184: + ", HttpServletRequest request = " + request
1185: + ", HttpServletResponse response = " + response
1186: + ", HttpSession session = " + session
1187: + ", String defaultForward = " + defaultForward
1188: + ") - start");
1189: }
1190:
1191: if (logger.isDebugEnabled()) {
1192: logger.debug("onDeleteWarn - end - return value = " + null);
1193: }
1194: return null;
1195: }
1196:
1197: /**
1198: * <p>
1199: * Set to <code>true</code> by <code>LoginAction</code> to indicate the
1200: * user name should not be checked.
1201: * </p>
1202: *
1203: * @param loginParam
1204: * the new value of login.
1205: */
1206: public final void setLogin(final boolean loginParam) {
1207: if (logger.isDebugEnabled()) {
1208: logger.debug("setLogin(boolean loginParam = " + loginParam
1209: + ") - start");
1210: }
1211:
1212: this .login = loginParam;
1213:
1214: if (logger.isDebugEnabled()) {
1215: logger.debug("setLogin(boolean) - end");
1216: }
1217: }
1218: }
|