Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for 
change notification.

The following page has been changed by ebolaz:
http://wiki.apache.org/tapestry/Tapestry5HowToUsePersistentFieldStrategy

The comment on the change is:
Initial

New page:
This example code creates a basic !PersistentFieldStrategy for "cookie" and 
"flashcookie" @Persist values[[BR]]
[[BR]]
[[BR]]
This code is a 'trimmed back' version of what I use... Everything is b64 
encoded. click here (one day) for a posting of my (hopefully) code with 
embedded !ValueEncoder s.[[BR]]
[[BR]]
[[BR]]
The reason that I wanted to do this was because none of the existing 
persistence strategies fitted my requirements.[[BR]]
The driving factor, as in so many web applications, was to aviod creating a 
session, and I '''really''' didn't like the large t:client:state cgi param. 
[[BR]]
[[BR]]
So, here you have it... my contribution to the tapestry corner. Enjoy![[BR]]
[[BR]]
First of all, a contribution had to made in !AppModule:
{{{
public void contributePersistentFieldManager(MappedConfiguration<String, 
PersistentFieldStrategy> configuration,
                RequestGlobals requestGlobals, Request request) {
        System.out.println("################## in 
contributePersistentFieldManager of " + PostbackModule.class.getName());
        configuration.add(CookiePersistentField.COOKIE, new 
CookiePersistentField(requestGlobals, request, CookiePersistentField.COOKIE));
        configuration.add(CookiePersistentField.FLASHCOOKIE, new 
CookiePersistentField(requestGlobals, request, 
CookiePersistentField.FLASHCOOKIE));
}
}}}

and the !CookiePersistentField source (simplified to use B64 _only_)
{{{
/*
 * Created on 12 Apr 2008
 * 
 * @author nicholas[dot] krul _at_ gmail com
 *
 */
package koncept.postback.base;

import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;

import java.util.*;

import javax.servlet.http.*;

import koncept.postback.base.encoders.*;

import org.apache.tapestry.internal.services.*;
import org.apache.tapestry.services.*;

public class CookiePersistentField implements PersistentFieldStrategy {
        public static final String COOKIE = "cookie";
        public static final String FLASHCOOKIE = "flashcookie";
        
        private String persistenceType;
        private static final String SEPERATOR = "|";

        private RequestGlobals requestGlobals;
        private Request request;

        private EncoderBase64 encoder;
        
        public CookiePersistentField(RequestGlobals requestGlobals, Request 
request, String persistenceType) {
                this.requestGlobals = requestGlobals;
                this.request = request;
                this.persistenceType = persistenceType;
                encoder = new EncoderBase64();
        }

        public void postChange(String pageName, String componentId, String 
fieldName, Object newValue) {
        notBlank(pageName, "pageName");
        notBlank(fieldName, "fieldName");

        StringBuilder builder = new StringBuilder(persistenceType);
        builder.append(SEPERATOR);
        builder.append(pageName);
        builder.append(SEPERATOR);

        if (componentId != null) builder.append(componentId);

        builder.append(SEPERATOR);
        builder.append(fieldName);

        String key = builder.toString();
        
        if (newValue != null) {
                String value = encoder.toClient(newValue); 
                createCookie(key, value);
        } else { //newValue == null
                deleteCookie(key);
        }
        }

         private PersistentFieldChange buildChange(Cookie cookie) {
                String value = cookie.getValue();
                if (value == null || value.isEmpty()) return null; //not needed
                
        String[] chunks = cookie.getName().split("\\" + SEPERATOR); //oops... 
regexp
        String componentId = chunks[2];
        String fieldName = chunks[3];
        
        Object attribute = encoder.toValue(value);
        return new PersistentFieldChangeImpl(componentId, fieldName, attribute);
    }
        
   public Collection<PersistentFieldChange> gatherFieldChanges(String pageName) 
{
           Collection<PersistentFieldChange> changes = new 
ArrayList<PersistentFieldChange>();
           String fullPrefix = persistenceType + SEPERATOR + pageName + 
SEPERATOR;
           for (Cookie cookie: getCookiesStartingWith(fullPrefix)) {
                   try {
                           PersistentFieldChange fieldChange = 
buildChange(cookie);
                           if (fieldChange != null) changes.add(fieldChange);
                           if (persistenceType.equals(FLASHCOOKIE)) 
deleteCookie(cookie.getName());
                   } catch (RuntimeException e) {
                           throw new RuntimeException("Error with cookie name: 
" + cookie.getName(),e);
                   }
           }
           return changes;
   }

   public void discardChanges(String pageName) {
       String fullPrefix = persistenceType + SEPERATOR + pageName + SEPERATOR;
       for (Cookie cookie: getCookiesStartingWith(fullPrefix)) {
           deleteCookie(cookie.getName());
       }
   }
        
    private List<Cookie> getCookiesStartingWith(String prefix) {
        List<Cookie> cookieList = new ArrayList<Cookie>();
        Cookie cookies[] = requestGlobals.getHTTPServletRequest().getCookies();
        if (cookies != null) for (int i = 0; i < cookies.length; i++) if 
(cookies[i].getName().startsWith(prefix)) cookieList.add(cookies[i]);
        return cookieList;
    }
    
    private void createCookie(String name, String value) {
        Cookie cookie = new Cookie(name, value);
        cookie.setPath(request.getContextPath());
        requestGlobals.getHTTPServletResponse().addCookie(cookie);
    }
    
    private void deleteCookie(String name) {
        Cookie cookie = new Cookie(name, "_"); //'empty values may cause 
problems'
        cookie.setMaxAge(0);
        cookie.setPath(request.getContextPath());
        requestGlobals.getHTTPServletResponse().addCookie(cookie);
    }
   
}
}}}
And the !EncoderBase64 class ... 
{{{
/*
 * Created on 13 Apr 2008
 *
 */
package koncept.postback.base.encoders;

import java.io.*;

import org.apache.tapestry.*;
import org.apache.tapestry.internal.util.*;
import org.apache.tapestry.ioc.internal.util.*;

public class EncoderBase64 implements ValueEncoder<Object> {

        public Object toValue(String clientValue) {
        Object value = null;
        ObjectInputStream in = null;
        try {
            in = new Base64ObjectInputStream(clientValue);
            value = in.readObject();

        } catch (Exception e) {
            throw new RuntimeException("client state corrupted", e);
        } finally {
            InternalUtils.close(in);
        }
        return value;
    }
            
         public String toClient(Object value) {
         Base64ObjectOutputStream os = null;
         try {
             os = new Base64ObjectOutputStream();
             os.writeObject(value);
         } catch (Exception ex) {
             throw new RuntimeException(ex.getMessage(), ex);
         } finally {
             InternalUtils.close(os);
         }
         return os.toBase64();
    }
        

}
}}}
There you go - an easy solution for {{{
@Persist("cookie")
@Persist("flashcookie")
}}} annotations.
[[BR]]
[[BR]]
--nK[[BR]]
--nicholas Krul

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

Reply via email to