To follow up with an old post about handling continuation ids as request
parameters and how that could cause caching problems:

I wrote a quick set of changes to add the continuation id as a cookie in
the setup method of one of my generators as follows:

                WebContinuation m_kont = FlowHelper.getWebContinuation(
objectModel );
                if ( m_kont != null )
                {
                    String id = m_kont.getContinuation(0).getId();
                    if ( id != null )
                    {
                        Response response = (Response)objectModel.get(
ObjectModelHelper.RESPONSE_OBJECT );
                        Cookie cookie = response.createCookie(
CONTINUATION_ID, id );
                        cookie.setMaxAge( -1 );         // Save in
memory only
                        cookie.setPath( "/" );
                        cookie.setVersion( 0 );
                        response.addCookie( cookie );
                        response.addHeader( "expires", "0" );
                        objectModel.put(
ObjectModelHelper.RESPONSE_OBJECT, response );
                    }
                }

I then wrote a CookieValueModule as an input module to get the value of
a cookie:

public class CookieValueModule extends AbstractInputModule implements
ThreadSafe {

    public Object getAttribute( String name, Configuration modeConf, Map
objectModel ) throws ConfigurationException {

        String pname = (String) this.settings.get("parameter", name);
        if ( modeConf != null ) {
            pname = modeConf.getAttribute( "parameter", pname );
            // preferred
            pname = modeConf.getChild("parameter").getValue(pname);
        }
        Map cookies =
ObjectModelHelper.getRequest(objectModel).getCookieMap();
        Cookie cookie = (Cookie)cookies.get( pname );
        if ( cookie != null )
        {
            return cookie.getValue( );
        }
        return null;
    }

    public Iterator getAttributeNames( Configuration modeConf, Map
objectModel ) throws ConfigurationException {
        Map cookies =
ObjectModelHelper.getRequest(objectModel).getCookieMap();
        if ( cookies != null )
            return cookies.keySet().iterator();
        return null;
    }

    public Object[] getAttributeValues( String name, Configuration
modeConf, Map objectModel )
        throws ConfigurationException {

        Map cookies =
ObjectModelHelper.getRequest(objectModel).getCookieMap();
        String pname = (String) this.settings.get("parameter", name);
        Cookie cookie = (Cookie)cookies.get( pname );
        if ( cookie != null )
        {
            Vector ret = new Vector();
            ret.add( cookie.getValue( ) );
            return ret.toArray();
        }
        return null;
    }
}

I added this module to my Cocoon.xconf (with the name "cookie-value")
and then in the sitemap I can do:

           <map:match pattern="*/**">
                <map:select type="request-method">
                    <map:when test="POST">
                        <map:call
continuation="{cookie-value:continuation-id}"/>
                    </map:when>
                    <map:otherwise>
                        <map:call function="main">
                            <map:parameter name="p1" value="{1}"/>  <!--
this will get mapped to the 1st param of the main function -->
                            <map:parameter name="p2" value="{2}"/>  <!--
this will get mapped to the 2nd param of the main function -->
                        </map:call>
                    </map:otherwise>
                </map:select>
            </map:match>
 
This removes the need to manage continuation ids completely from any of
the XSLTs.

I think that it might make sense for Cocoon to do this automatically in
the setup method of the AbstractGenerator?  (I think a cookie can only
be added once? If not, we'd need a way to only add it once...)
Certainly a generic CookieValue Module might help.  In any case, if
anyone needs this and can't figure it out from the above let me know.

Peter Hunsberger


Reply via email to