001: package net.matuschek.http.cookie;
002:
003: /*********************************************
004: Copyright (c) 2001 by Daniel Matuschek
005: *********************************************/
006:
007: import java.util.Vector;
008: import java.net.URL;
009:
010: /**
011: * This class is a container for storing cookies in
012: * the memory. It will automatically expire old cookies.
013: *
014: * @author Daniel Matuschek
015: * @version $Id $
016: */
017: public class MemoryCookieManager implements CookieManager {
018:
019: /**
020: * an internal thread that will be used to clean up old cookies
021: */
022: class CleanupThread extends Thread {
023: MemoryCookieManager cm = null;
024: boolean finished = false;
025:
026: public CleanupThread(MemoryCookieManager cm) {
027: this .cm = cm;
028: this .setDaemon(true);
029: }
030:
031: /** stop cleanup and finish this thread */
032: public void finish() {
033: this .finished = true;
034: }
035:
036: public void run() {
037: while (!finished) {
038: // cleanup every minute
039: try {
040: sleep(60000);
041: } catch (InterruptedException e) {
042: this .finished = true;
043: }
044: cm.cleanUpExpired();
045: }
046: }
047: }
048:
049: /** List of stored cookies */
050: private Vector<Cookie> cookies;
051:
052: /** The background thread for cookie expiration */
053: private CleanupThread ct = null;
054:
055: /**
056: * Default constructor, initializes a new CookieManager
057: * that has no cookies stored.
058: * It also starts a CleanUp thread that will periodically delete
059: * expired cookies.
060: */
061: public MemoryCookieManager() {
062: cookies = new Vector<Cookie>();
063:
064: /* Insiders BugFix
065: * This code fragment must be executed at the add(Cookie) method.
066: * If we do it here then dead threads will be created.
067: // start cleanup thread as a daemon
068: ct = new CleanupThread(this);
069: ct.start();
070: */
071: }
072:
073: /**
074: * Add this cookie. If there is already a cookie with the same name and
075: * path it will be owerwritten by the new cookie.
076: * @param cookie a Cookie that will be stored in this cookie manager
077: */
078: public void add(Cookie cookie) {
079: if (ct == null) {
080: synchronized (this ) {
081: if (ct == null) {
082: // start cleanup thread as a daemon
083: ct = new CleanupThread(this );
084: ct.start();
085: }
086: }
087: }
088: for (int i = 0; i < cookies.size(); i++) {
089: Cookie oldcookie = (Cookie) (cookies.elementAt(i));
090: if (cookie.overwrites(oldcookie)) {
091: cookies.removeElementAt(i);
092: i--;
093: }
094: }
095: cookies.add(cookie);
096: }
097:
098: /**
099: * How many cookies are currently stored in this CookieManager ?
100: * @return the number of stored Cookies
101: */
102: public int countCookies() {
103: return this .cookies.size();
104: }
105:
106: /**
107: * Get the cookie values for the given URL.
108: * @return a String containing a list of NAME=VALUE pairs (separated by
109: * semicolon) containing all cookie values that are valid for the
110: * given URL, <br/ >
111: * null if no cookies can be found for this URL
112: */
113: public String cookiesForURL(URL u) {
114: final String SEP = "; ";
115: StringBuffer sb = new StringBuffer();
116:
117: for (int i = 0; i < cookies.size(); i++) {
118: Cookie c = (Cookie) (cookies.elementAt(i));
119: if (c.isValid(u)) {
120: sb.append(c.getNameValuePair());
121: sb.append(SEP);
122: }
123: }
124:
125: if (sb.length() > 0) {
126: // ignore the last "; "
127: return sb.substring(0, sb.length() - SEP.length());
128: } else {
129: return null;
130: }
131: }
132:
133: /**
134: * Remove all stored cookies
135: */
136: public void clear() {
137: this .cookies.clear();
138: }
139:
140: /**
141: * Cleans up expired cookies
142: */
143: protected void cleanUpExpired() {
144: for (int i = 0; i < cookies.size(); i++) {
145: Cookie c = (Cookie) (cookies.elementAt(i));
146:
147: // if this cookie has expired, remove it
148: if (!c.isValid()) {
149: cookies.removeElementAt(i);
150: i--;
151: }
152: }
153: }
154:
155: /**
156: * <b>Insiders BugFix</b>
157: * This method finishes the CleanUpThread.
158: */
159: public void finish() {
160: if (ct != null) {
161: ct.finished = true;
162: ct.interrupt();
163: }
164: }
165:
166: /**
167: * Show all cookies
168: */
169: public String toString() {
170: StringBuffer sb = new StringBuffer();
171: for (int i = 0; i < cookies.size(); i++) {
172: sb.append(i + ": ");
173: sb.append(cookies.elementAt(i).toString());
174: sb.append("\n");
175: }
176: return sb.toString();
177: }
178:
179: }
|