Stephane Bailliez wrote:

%<------------------------------%<


> 
> I have been doing this too by I have some problems since I need to pass
> quite some parameters to the 'next' or 'cancel' or whatever page. My URL is
> giving me the navigation state (ie what module are you browsing, which
> business object are you viewing, in which folder and which node and things
> like this).
> 
> This leads to heavy java and vm code :( so I think there is a flaw in my
> solution and I'd better use the next template as template + params. (sort of
> a the url encoded result of a parameter parser). I started naively and know
> I feel the pain.


I am including my base action class, is your approach similar? The 
'doRedirect' method can be used to convert the URL. Have a look at the 
'setParameterPair' method. You can specify which parameters should be 
removed from the URL. It also changes all the 'next' type of parameters 
to their 'current' equivalents. It *should* put the rest of the pathinfo 
and querydata parameters back the way it found it. ;).

Note that I am not advocating this approach, I am simply including the 
source to illustrate my question.

Hope this helps.
- Johnny


> 
> The problem is always 'where' to store the state though...
> 
> Interesting interview:
> http://www.theserverside.com/events/index.jsp
> Inderjeet Singh, J2EE Blueprints Architect, Sun
> 
> Stephane
> 
> --
> To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
> 


/*
 ******************************************************************************
 *                                                                            *
 *              (c) Copyright 2001 EPI-USE Systems                            *
 *                                                                            *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms of the GNU Lesser General Public License as published by   *
 * the Free Software Foundation; either version 2.1 of the License, or        *
 * (at your option) any later version.                                        *
 *                                                                            *
 * This program 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 Lesser General Public    *
 * License for more details.                                                  *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with this program; if not, write to the Free Software Foundation,    *
 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                              *
 *                                                                            *
 ******************************************************************************
 */

/*
 * IcosWebAction.java
 *
 * Created on August 10, 2001, 2:15 PM
 */

package org.icosphere.icosweb.core.actions.base;

import org.apache.turbine.services.pull.TurbinePull;
import org.apache.velocity.context.Context;
import org.icosphere.icosweb.core.util.IcosWebConstants;
import org.icosphere.icosweb.core.util.IcosWebLink;
import org.apache.turbine.services.velocity.TurbineVelocity;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.HashMap;
import org.apache.turbine.util.RunData;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.ParameterParser;
import org.apache.turbine.util.parser.DefaultParameterParser;
import javax.servlet.http.HttpUtils;
import org.icosphere.icosweb.core.tools.IcosWebRequestTool;
import org.apache.turbine.modules.actions.VelocityAction;

/**
 * Purpose: Base class for all action class implementations for icosWeb.
 *
 * <p>Description: Determines the current, next, and cancel templates as well
 * as the resource access mode and type each time an action is executed. Every
 * class inheriting from IcosWebAction must call super.doPerform() at the
 * beginning of each of it's action event methods so that the templates can
 * be determined.
 *
 * <p>Known bugs:
 *
 * <p>TODO:
 *
 * @author <a href="mailto:[EMAIL PROTECTED]";>Johnny Cass</a>
 * @version $Id: IcosWebAction.java,v 1.7 2001/12/04 10:22:49 jcass Exp $
 */

public abstract class IcosWebAction extends VelocityAction {
    
    /**
     * Tries to determine the current, next, and cancel template and the
     * the resource access mode and type using the RunData parameters. Each
     * of the template names default to the currently displayed template if
     * no corresponding values are found in the RunData parameters.
     *
     * The keys to use for finding the different templates are obtained from
     * IcosWebConstants.java.
     *
     * @param data RunData object for this request.
     * @param context Velocity context for this request.
     * @throws Exception Thrown by Turbine.
     */
    public void doPerform ( RunData data, Context context ) throws Exception {
        setNavigationParameters ( data );
    }
    
    /**
     * This manages clicking the Cancel button.
     *
     * @param data RunData object for this request.
     * @param context Velocity context for this request.
     * @throws Exception Thrown by Turbine.
     */
    public void doCancel ( RunData data, Context context ) throws Exception {
        setNavigationParameters ( data );
        
        data.setScreenTemplate ( this.cancelTemplate );
        
        data.getParameters ().add ( IcosWebConstants.RESOURCE_TYPE,
        this.cancelResourceType );
        
        data.getParameters ().add ( IcosWebConstants.RESOURCE_ACCESS_MODE,
        this.resourceAccessMode );
    }
    
    private void setNavigationParameters ( RunData data ) throws Exception {
        
        this.template = data.getParameters ()
        .getString ( IcosWebConstants.TEMPLATE, data.getScreenTemplate () );
        
        this.nextTemplate = data.getParameters ()
        .getString ( IcosWebConstants.NEXT_TEMPLATE, this.template );
        
        this.cancelTemplate = data.getParameters ()
        .getString ( IcosWebConstants.CANCEL_TEMPLATE, this.template );
        
        Log.debug ( "template is '" + this.template + "'" );
        Log.debug ( "nextTemplate is '" + this.nextTemplate + "'" );
        Log.debug ( "cancelTemplate is '" + this.cancelTemplate + "'" );
        
        this.resourceType = data.getParameters ()
        .getString ( IcosWebConstants.RESOURCE_TYPE, null );
        
        this.nextResourceType = data.getParameters ()
        .getString ( IcosWebConstants.NEXT_RESOURCE_TYPE, this.resourceType );
        
        this.cancelResourceType = data.getParameters ()
        .getString ( IcosWebConstants.CANCEL_RESOURCE_TYPE, this.resourceType );
        
        Log.debug ( "resourceType is '" + this.resourceType + "'" );
        Log.debug ( "nextResourceType is '" + this.nextResourceType + "'" );
        Log.debug ( "cancelResourceType is '" + this.cancelResourceType + "'" );
        
        this.resourceAccessMode = data.getParameters ()
        .getString ( IcosWebConstants.RESOURCE_ACCESS_MODE, null );
        
        this.nextResourceAccessMode = data.getParameters ()
        .getString ( IcosWebConstants.NEXT_RESOURCE_ACCESS_MODE,
        this.resourceAccessMode );
        
        this.cancelResourceAccessMode = data.getParameters ()
        .getString ( IcosWebConstants.CANCEL_RESOURCE_ACCESS_MODE,
        this.resourceAccessMode );
        
        Log.debug ( "resourceAccessMode is '" + this.resourceAccessMode + "'" );
        
        Log.debug ( "nextResourceAccessMode is '" +
        this.nextResourceAccessMode + "'" );
        Log.debug ( "cancelResourceAccessMode is '" +
        
        this.cancelResourceAccessMode + "'" );
        
    }
    
    /**
     * Performs a redirect on the response. This method can be used to ensure
     * that the URL for the request matches the rendered page for the response. This
     * is a workaround for the whole 'back button' issue. The problem arises from the
     * fact that the action determines which page to display next after the action
     * has been executed (using the next- and cancel- parameters) so that the
     * URL for the request does not neccesarily match the output of the page
     * (e.g. the 'template' or 'resource type' viewed do not match the parameters
     * in the URL). <br><br>
     *
     * Since we should probably not execute the action again if the user
     * presses the 'back' button, we need to redirect to a safe URL that
     * does not contain the action parameter. <br><br>
     *
     * @param data The RunData for this request.
     * @throws Exception Thrown by Turbine.
     */
    protected void doRedirect ( RunData data ) throws Exception {
        
        if ( data.getRequest ().getPathInfo () == null ) {
            return;
        }
        
        IcosWebLink redirectLink = new IcosWebLink ();
        
        redirectLink.init ( ( Object ) data );
        
        redirectLink.addPathInfo ( getSafePathInfo ( data ) );
        
        redirectLink.addQueryData ( getSafeQueryData ( data ) );
        
        // Make sure we use the most recent resource.
        IcosWebRequestTool icosWebR = ( IcosWebRequestTool ) TurbinePull
        .getTool ( TurbineVelocity.getContext ( data ), IcosWebConstants
        .ICOSWEB_REQUEST_TOOL );
        
        redirectLink.setResource ( icosWebR.getResource () );
        
        String redirectURL = redirectLink.toString ();
        
        Log.debug ( "Redirecting from '" + data.getRequest ().getRequestURI () +
        "' to '" + redirectURL + "'" );
        
        TurbinePull.releaseTools ( TurbineVelocity.getContext ( data ) );
        data.getResponse ().sendRedirect ( redirectURL );
        
    }
    
    private ParameterParser getSafePathInfo ( RunData data ) {
        
        ParameterParser parameterParser = new DefaultParameterParser ();
        
        String pathInfo = data.getRequest ().getPathInfo ();
        
        HashMap keys = new HashMap ();
        
        if ( pathInfo != null && !pathInfo.equals ( "" ) ) {
            
            StringTokenizer stringTokenizer = new StringTokenizer ( pathInfo, "/" );
            
            while ( stringTokenizer.hasMoreTokens () ) {
                
                String key = stringTokenizer.nextToken ();
                if ( !keys.containsKey ( key ) ) {
                    keys.put ( key, new Vector () );
                }
                
                Vector valuesVector = ( Vector ) keys.get ( key );
                valuesVector.add ( stringTokenizer.nextToken () );
                
                String[] valuesArray = new String[valuesVector.size ()];
                
                for ( int i=0; i<valuesArray.length; i++ ) {
                    valuesArray[i] = ( String ) valuesVector.get ( i );
                }
                
                setParameterPair ( parameterParser, key, valuesArray );
                
            }
        }
        
        return parameterParser;
    }
    
    private ParameterParser getSafeQueryData ( RunData data ) {
        
        ParameterParser parameterParser = new DefaultParameterParser ();
        
        String queryData = data.getRequest ().getQueryString ();
        
        if ( queryData != null && !queryData.equals ( "" ) ) {
            
            Hashtable queryDataTable = HttpUtils.parseQueryString ( queryData );
            Enumeration keys = queryDataTable.keys ();
            
            while ( keys.hasMoreElements () ) {
                
                String key = ( String ) keys.nextElement ();
                setParameterPair ( parameterParser, key, ( String [] )
                queryDataTable.get ( key ) );
                
            }
        }
        
        return parameterParser;
    }
    
    private void setParameterPair ( ParameterParser parameterParser, String key,
    String[] values ) {
        
        if ( key.equalsIgnoreCase ( IcosWebConstants.RESOURCE ) || key
        .equalsIgnoreCase ( "action" ) || key.startsWith ( "cancel" ) ||
        key.equalsIgnoreCase ( "_session_access_counter" ) ) {
            
            // Skip these key / value pairs.
            return;
        } else if ( key.equalsIgnoreCase ( IcosWebConstants.NEXT_TEMPLATE ) ) {
            
            key = IcosWebConstants.TEMPLATE;
            
        } else if ( key.equalsIgnoreCase ( IcosWebConstants.NEXT_RESOURCE_TYPE ) ) {
            
            key = IcosWebConstants.RESOURCE_TYPE;
            
        } else if ( key.equalsIgnoreCase ( IcosWebConstants.NEXT_RESOURCE_ACCESS_MODE 
) ) {
            key = IcosWebConstants.RESOURCE_ACCESS_MODE;
        }
        
        parameterParser.setStrings ( key, values );
    }
    
    protected String nextTemplate = null;
    protected String cancelTemplate = null;
    protected String template = null;
    
    protected String nextResourceType = null;
    protected String cancelResourceType = null;
    protected String resourceType = null;
    
    protected String nextResourceAccessMode = null;
    protected String cancelResourceAccessMode = null;
    protected String resourceAccessMode = null;
    
    
}

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to