Source code: com/sonalb/net/http/cookie/CookieJar.java
1 /*
2 * -*- mode: java; c-basic-indent: 4; indent-tabs-mode: nil -*-
3 * :indentSize=4:noTabs=true:tabSize=4:indentOnTab=true:indentOnEnter=true:mode=java:
4 * ex: set tabstop=4 expandtab:
5 *
6 * MrPostman - webmail <-> email gateway
7 * Copyright (C) 2002-2003 MrPostman Development Group
8 * Projectpage: http://mrbook.org/mrpostman/
9 *
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 * In particular, this implies that users are responsible for
21 * using MrPostman after reading the terms and conditions given
22 * by their web-mail provider.
23 *
24 * You should have received a copy of the GNU General Public License
25 * Named LICENSE in the base directory of this distribution,
26 * if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 */
29
30 package com.sonalb.net.http.cookie;
31
32 import com.sonalb.Utils;
33
34 import java.util.Collection;
35 import java.util.Iterator;
36 import java.util.Vector;
37 import java.util.logging.Level;
38 import java.util.logging.Logger;
39
40
41 /*
42
43 According to RFC2965, if Set-Cookie and set-cookie2 both describe the same cookie, then sc2 should be used.
44
45 This distinction has not been incorporated.
46
47
48
49 ADD function to getcookies by version
50
51 */
52
53 /**
54
55 * Container for <code>Cookie</code> objects. Each CookieJar is independent of any request.
56
57 * This means that a single CookieJar can hold all the cookies for a number of requests and servers.
58
59 * @author Sonal Bansal
60
61 */
62 public class CookieJar implements java.util.Collection, java.io.Serializable {
63 public static final String CVSID = "$Id: CookieJar.java,v 1.6 2003/02/09 23:38:11 lbruand Exp $";
64 private static Logger logger = Logger.getLogger("com.sonalb.net.http.cookie.CookieJar");
65 private Vector theJar;
66 private int iNumCookies;
67
68 /**
69
70 * Creates an empty CookieJar.
71
72 */
73 public CookieJar() {
74 theJar = new Vector();
75
76 iNumCookies = 0;
77 }
78
79 /**
80
81 * Creates a CookieJar, and populates it with Cookies from input Collection. All the objects in
82
83 * the input Collection NEED NOT be Cookie objects.
84
85 * @param c the input Collection
86
87 */
88 public CookieJar(Collection c) {
89 theJar = new Vector();
90
91 iNumCookies = 0;
92
93 addAll(c);
94 }
95
96 protected CookieJar(int initialCapacity, int growthStep) {
97 theJar = new Vector(initialCapacity, growthStep);
98
99 iNumCookies = 0;
100 }
101
102 public boolean add(Object o) {
103 if (o == null) {
104 throw new IllegalArgumentException("Null cookie.");
105 } else if (!(o instanceof Cookie)) {
106 throw new ClassCastException("Not a Cookie.");
107 }
108
109 Cookie cookie;
110
111 try {
112 cookie = (Cookie) ((Cookie) o).clone();
113 } catch (CloneNotSupportedException cnse) {
114 throw new IllegalArgumentException("Could not add. Object does not support Cloning.");
115 }
116
117 if (!cookie.isValid()) {
118 throw new IllegalArgumentException("Invalid cookie.");
119 }
120
121 int ind = getCookieIndex(cookie);
122
123 if (ind == -1) {
124 theJar.add(cookie);
125
126 iNumCookies++;
127 } else {
128 theJar.setElementAt(cookie, ind);
129 }
130
131 return (true);
132 }
133
134 public boolean addAll(Collection c) {
135 if (c == null) {
136 throw new IllegalArgumentException("Null Collection");
137 }
138
139 if (!c.isEmpty()) {
140 Iterator iter = c.iterator();
141
142 while (iter.hasNext()) {
143 try {
144 add(iter.next());
145 } catch (Exception e) {
146 logger.log(Level.SEVERE, "should not happen", e);
147 }
148 }
149 } else {
150 return (false);
151 }
152
153 return (true);
154 }
155
156 public Iterator iterator() {
157 return (theJar.iterator());
158 }
159
160 public boolean contains(Object o) {
161 if (o == null) {
162 throw new IllegalArgumentException("Null cookie");
163 } else if (!(o instanceof Cookie)) {
164 throw new ClassCastException("Not a cookie");
165 }
166
167 Cookie c = (Cookie) o;
168
169 if (!c.isValid()) {
170 throw new IllegalArgumentException("Invalid cookie.");
171 }
172
173 return (theJar.contains(c));
174 }
175
176 public boolean containsAll(Collection c) {
177 if (c != null) {
178 Iterator iter = c.iterator();
179
180 while (iter.hasNext()) {
181 if (!contains(iter.next())) {
182 return (false);
183 }
184 }
185 } else {
186 throw new IllegalArgumentException("Null collection");
187 }
188
189 return (true);
190 }
191
192 public Object[] toArray() {
193 return (theJar.toArray());
194 }
195
196 public Object[] toArray(Object[] array) {
197 if (array == null) {
198 throw new IllegalArgumentException("Null array.");
199 }
200
201 Cookie[] cookieArray = new Cookie[array.length];
202
203 try {
204 for (int i = 0; i < array.length; i++) {
205 cookieArray[i] = (Cookie) array[i];
206 }
207 } catch (ClassCastException cce) {
208 throw new ArrayStoreException("ClassCastException occurred.");
209 }
210
211 return (theJar.toArray(cookieArray));
212 }
213
214 public void clear() {
215 theJar.clear();
216
217 iNumCookies = 0;
218 }
219
220 public boolean removeAll(Collection c) {
221 if (c == null) {
222 throw new IllegalArgumentException("Null collection");
223 }
224
225 if (!c.isEmpty()) {
226 Iterator iter = c.iterator();
227
228 while (iter.hasNext()) {
229 remove(iter.next());
230 }
231 } else {
232 return (false);
233 }
234
235 return (true);
236 }
237
238 public boolean retainAll(Collection c) {
239 if (c == null) {
240 throw new IllegalArgumentException("Null collection");
241 }
242
243 if (!c.isEmpty()) {
244 Iterator iter = c.iterator();
245
246 Object o;
247
248 while (iter.hasNext()) {
249 o = iter.next();
250
251 if (!contains(o)) {
252 remove(o);
253 }
254 }
255 } else {
256 return (false);
257 }
258
259 return (true);
260 }
261
262 public boolean remove(Object o) {
263 if (o == null) {
264 throw new IllegalArgumentException("Null cookie.");
265 } else if (!(o instanceof Cookie)) {
266 throw new ClassCastException("Not a cookie.");
267 }
268
269 Cookie cookie = (Cookie) o;
270
271 if (!cookie.isValid()) {
272 throw new IllegalArgumentException("Invalid cookie.");
273 }
274
275 return (theJar.remove(cookie));
276 }
277
278 /**
279
280 * Removes all cookies that match the given CookieMatcher.
281
282 * @param cm the CookieMatcher
283
284 */
285 public void removeCookies(CookieMatcher cm) {
286 if (cm == null) {
287 throw new IllegalArgumentException("Null CookieMatcher");
288 }
289
290 Cookie c;
291
292 for (int i = 0; i < iNumCookies; i++) {
293 c = (Cookie) theJar.get(i);
294
295 if (cm.doMatch(c)) {
296 theJar.removeElementAt(i);
297
298 iNumCookies--;
299 }
300 }
301 }
302
303 protected int getCookieIndex(Cookie c) {
304 int retVal = -1;
305
306 for (int i = 0; i < iNumCookies; i++) {
307 if (c.equals(theJar.get(i))) {
308 retVal = i;
309
310 break;
311 }
312 }
313
314 return (retVal);
315 }
316
317 public int size() {
318 if (iNumCookies > Integer.MAX_VALUE) {
319 return (Integer.MAX_VALUE);
320 }
321
322 return (iNumCookies);
323 }
324
325 public boolean isEmpty() {
326 return (iNumCookies == 0);
327 }
328
329 /**
330
331 * Gets all Cookies that match the given CookieMatcher.
332
333 * @param cm the CookieMatcher
334
335 * @return the CookieJar with matching cookies; always non-null
336
337 */
338 public CookieJar getCookies(CookieMatcher cm) {
339 if (cm == null) {
340 throw new IllegalArgumentException("Invalid CookieMatcher");
341 }
342
343 CookieJar cj = new CookieJar();
344
345 Cookie c;
346
347 for (int i = 0; i < iNumCookies; i++) {
348 c = (Cookie) theJar.get(i);
349
350 if (cm.doMatch(c)) {
351 cj.add(c);
352 }
353 }
354
355 return (cj);
356 }
357
358 /**
359
360 * Gets all Cookies with the given name.
361
362 * @param cookieName the cookie name
363
364 * @return the CookieJar with matching cookies; always non-null
365
366 */
367 public CookieJar getCookies(String cookieName) {
368 if (Utils.isNullOrWhiteSpace(cookieName)) {
369 throw new IllegalArgumentException("Name cannot be empty");
370 }
371
372 CookieJar cj = new CookieJar();
373
374 Cookie c;
375
376 for (int i = 0; i < iNumCookies; i++) {
377 c = (Cookie) theJar.get(i);
378
379 if (cookieName.equalsIgnoreCase(c.getName())) {
380 cj.add(c);
381 }
382 }
383
384 return (cj);
385 }
386
387 /**
388
389 * Gets all Cookies having given version.
390
391 * @param ver the version
392
393 * @return the CookieJar with Cookies; always non-null
394
395 */
396 public CookieJar getVersionCookies(String ver) {
397 CookieJar cj = new CookieJar();
398
399 Cookie c;
400
401 for (int i = 0; i < iNumCookies; i++) {
402 c = (Cookie) theJar.get(i);
403
404 if (c.getVersion().equals(ver)) {
405 cj.add(c);
406 }
407 }
408
409 return (cj);
410 }
411
412 public String toString() {
413 if (isEmpty()) {
414 return ("{}");
415 }
416
417 StringBuffer sb = new StringBuffer();
418
419 sb.append("{");
420
421 for (int i = 0; i < iNumCookies; i++) {
422 sb.append(theJar.get(i).toString());
423
424 sb.append(",");
425 }
426
427 sb.deleteCharAt(sb.length() - 1);
428
429 sb.append("}");
430
431 return (sb.toString());
432 }
433 }