package com.openfeint.internal; import java.util.Date; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.impl.cookie.DateParseException; import android.os.Bundle; import com.openfeint.internal.OpenFeintInternal; public class CookieStore extends BasicCookieStore { static final String TAG = "CookieStore"; static final String COOKIE_PREFIX = "_of_cookie_"; static final int COOKIE_PREFIX_LEN = COOKIE_PREFIX.length(); static final String COOKIE_VALUE_TAG = "value"; static final int COOKIE_VALUE_TAG_LEN = COOKIE_VALUE_TAG.length(); SyncedStore mSharedPreferences; public synchronized void saveInstanceState(Bundle outState) { for (Cookie c : super.getCookies()) { cookieToBundle(c, outState); } } public synchronized void restoreInstanceState(Bundle inState) { for (String k : inState.keySet()) { if (k.startsWith(COOKIE_PREFIX) && k.endsWith(COOKIE_VALUE_TAG)) { String cookieName = k.substring(COOKIE_PREFIX_LEN, k.length() - COOKIE_VALUE_TAG_LEN); BasicClientCookie c = cookieFromBundle(inState, cookieName); super.addCookie(c); } } } public CookieStore(SyncedStore sp) { super(); mSharedPreferences = sp; SyncedStore.Reader r = mSharedPreferences.read(); try { for (String k : r.keySet()) { if (k.startsWith(COOKIE_PREFIX) && k.endsWith(COOKIE_VALUE_TAG)) { String cookieName = k.substring(COOKIE_PREFIX_LEN, k.length() - COOKIE_VALUE_TAG_LEN); BasicClientCookie c = cookieFromPrefs(r, cookieName); super.addCookie(c); } } } finally { r.complete(); } } private BasicClientCookie cookieFromBundle(Bundle b, String cookieName) { String prefix = COOKIE_PREFIX + cookieName; BasicClientCookie c = null; String cookieValue = b.getString(prefix + "value"); if (cookieValue == null) return null; String cookiePath = b.getString(prefix + "path"); String cookieDomain = b.getString(prefix + "domain"); String cookieExpiry = b.getString(prefix + "expiry"); c = new BasicClientCookie(cookieName, cookieValue); c.setPath(cookiePath); c.setDomain(cookieDomain); if (cookieExpiry != null) { c.setExpiryDate(dateFromString(cookieExpiry)); } return c; } private BasicClientCookie cookieFromPrefs(SyncedStore.Reader r, String cookieName) { String prefix = COOKIE_PREFIX + cookieName; BasicClientCookie c = null; String cookieValue = r.getString(prefix + "value", null); if (cookieValue == null) return null; String cookiePath = r.getString(prefix + "path", null); String cookieDomain = r.getString(prefix + "domain", null); String cookieExpiry = r.getString(prefix + "expiry", null); c = new BasicClientCookie(cookieName, cookieValue); c.setPath(cookiePath); c.setDomain(cookieDomain); c.setExpiryDate(dateFromString(cookieExpiry)); return c; } private void cookieToBundle(Cookie cookie, Bundle b) { final String name = cookie.getName(); b.putString(COOKIE_PREFIX + name + "value", cookie.getValue()); b.putString(COOKIE_PREFIX + name + "path", cookie.getPath()); b.putString(COOKIE_PREFIX + name + "domain", cookie.getDomain()); final Date expiryDate = cookie.getExpiryDate(); if (null != expiryDate) { b.putString(COOKIE_PREFIX + name + "expiry", stringFromDate(expiryDate)); } } private void cookieToPrefs(Cookie cookie, SyncedStore.Editor e) { final String name = cookie.getName(); e.putString(COOKIE_PREFIX + name + "value", cookie.getValue()); e.putString(COOKIE_PREFIX + name + "path", cookie.getPath()); e.putString(COOKIE_PREFIX + name + "domain", cookie.getDomain()); e.putString(COOKIE_PREFIX + name + "expiry", stringFromDate(cookie.getExpiryDate())); } @Override public synchronized void addCookie(Cookie cookie) { super.addCookie(cookie); String name = cookie.getName(); Cookie existing = null; SyncedStore.Reader r = mSharedPreferences.read(); try { existing = cookieFromPrefs(r, name); } finally { r.complete(); } if (existing == null || !existing.getValue().equals(cookie.getValue()) || !existing.getPath().equals(cookie.getPath()) || !existing.getDomain().equals(cookie.getDomain()) || !existing.getExpiryDate().equals(cookie.getExpiryDate())) { SyncedStore.Editor e = mSharedPreferences.edit(); try { // clear the existing cookie from prefs. String prefix = COOKIE_PREFIX + name; for (String k : e.keySet()) { if (k.startsWith(prefix)) { e.remove(k); } } // and then, if new cookie is persistent, then add it! if (cookie.getExpiryDate() != null) { cookieToPrefs(cookie, e); } } finally { e.commit(); } } } public synchronized void clearCookies(SyncedStore.Editor e) { for (String k : e.keySet()) { if (k.startsWith(COOKIE_PREFIX)) { e.remove(k); } } super.clear(); } private static final String stringFromDate(Date d) { return org.apache.http.impl.cookie.DateUtils.formatDate(d); } private static final Date dateFromString(String s) { try { return org.apache.http.impl.cookie.DateUtils.parseDate(s); } catch (DateParseException e) { OpenFeintInternal.log(TAG, "Couldn't parse date: '"+s+"'"); return null; } } }