/* * Created on 12 Apr 2008 * * @author nicholas[dot] krul _at_ gmail com * */ package fr.chantier.tapestry.base; import static org.apache.tapestry5.ioc.internal.util.Defense.notBlank; import org.apache.tapestry5.services.Request; import org.apache.tapestry5.services.RequestGlobals; import org.apache.tapestry5.services.PersistentFieldStrategy; import org.apache.tapestry5.services.PersistentFieldChange; import org.apache.tapestry5.internal.services.PersistentFieldChangeImpl; import javax.servlet.http.Cookie; import fr.chantier.tools.EncoderBase64; import java.util.Collection; import java.util.ArrayList; import java.util.List; 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); } }