/*==========================================================================*\ | $Id: DualAction.java,v 1.2 2010/10/11 18:31:11 aallowat Exp $ |*-------------------------------------------------------------------------*| | Copyright (C) 2009 Virginia Tech | | This file is part of Web-CAT. | | Web-CAT is free software; you can redistribute it and/or modify | it under the terms of the GNU Affero General Public License as published | by the Free Software Foundation; either version 3 of the License, or | (at your option) any later version. | | Web-CAT is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU Affero General Public License | along with Web-CAT; if not, see <http://www.gnu.org/licenses/>. \*==========================================================================*/ package org.webcat.core; import com.webobjects.appserver.WOActionResults; import com.webobjects.appserver.WOComponent; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WORequest; import com.webobjects.appserver.WOResponse; import er.ajax.AjaxUtils; import er.extensions.appserver.ERXWOContext; //------------------------------------------------------------------------- /** * <p> * A wrapper that eases the creation of component actions that can operate both * as remote (Ajax) actions and full page load actions. The easiest way to use * this is to create a new anonymous instance of the class inside your action * method, overriding the {@link #performRemoteAction()} and * {@link #performStandardAction()} methods to provide the appropriate * behavior. For example: * </p><p> * <pre> * public WOActionResults myAction() * { * return new DualAction(this) * { * protected WOActionResults performRemoteAction() * { * JavascriptGenerator g = new JavascriptGenerator(); * // use g to manipulate the elements on the current page * return g; * } * * protected WOActionResults performStandardAction() * { * SomeNewPage page = pageWithName(SomeNewPage.class); * // initialize values on page * return page; * } * }; * } * </pre> * </p><p> * NOTE: This class, and any of its subclasses, are intended to be * <b>stateless</b>. Note that in the above example, the <code>myAction()</code> * method will be called <b>twice</b>: once for the remote action invocation, * and again for the standard action invocation. This means that two separate * instances of the inner class will be created. It is easier to maintain any * state that you need in the surrounding component class; if you want to * include state in the action class, you must pull it out of the method and * into a named inner class, then ensure that the instance gets created once * and only once. * </p> * * @author Tony Allevato * @version $Id: DualAction.java,v 1.2 2010/10/11 18:31:11 aallowat Exp $ */ public abstract class DualAction implements WOActionResults { //~ Constructors .......................................................... // ---------------------------------------------------------- /** * Initializes a new instance of the DualAction class, with the specified * owning component. * * @param component the owning component, which will be used as the return * value if {@code performStandardAction} returns null */ public DualAction(WOComponent component) { this.component = component; } //~ Methods ............................................................... // ---------------------------------------------------------- /** * Generates the appropriate response for the action depending on whether * the request is an Ajax request or a standard request. * * @return the action response */ public final WOResponse generateResponse() { context = ERXWOContext.currentContext(); WORequest request = context.request(); boolean isRemote = AjaxUtils.isAjaxRequest(request); WOActionResults results = null; if (isRemote) { results = performRemoteAction(); if (results == null) { return AjaxUtils.createResponse(request, context); } } else { results = performStandardAction(); if (results == null) { return component.generateResponse(); } } context = null; return results.generateResponse(); } // ---------------------------------------------------------- /** * Anonymous instances should override this to provide the logic for the * action that will be executed when invoked as a remote (Ajax) request. * * @return the results of the action */ protected abstract WOActionResults performRemoteAction(); // ---------------------------------------------------------- /** * <p> * Anonymous instances should override this to provide the logic for the * action that will be executed when invoked as a standard page load * request. * </p><p> * As with regular action methods, this method can return <code>null</code>, * which will be interpreted as returning the same instance of the * component on which this action was invoked. * </p> * * @return the results of the action */ protected abstract WOActionResults performStandardAction(); // ---------------------------------------------------------- /** * Gets the component on which this action was invoked. * * @return the component */ protected final WOComponent component() { return component; } // ---------------------------------------------------------- /** * Gets the context under which this action has been invoked. This method * is intended to be used only inside the {@code performRemoteAction} and * {@code performStandardAction} methods. * * @return the context */ protected final WOContext context() { return context; } //~ Static/instance variables ............................................. private WOComponent component; private WOContext context; }