1/*
2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/BasicCookieStore.java $
3 * $Revision: 653041 $
4 * $Date: 2008-05-03 03:39:28 -0700 (Sat, 03 May 2008) $
5 *
6 * ====================================================================
7 *
8 *  Licensed to the Apache Software Foundation (ASF) under one or more
9 *  contributor license agreements.  See the NOTICE file distributed with
10 *  this work for additional information regarding copyright ownership.
11 *  The ASF licenses this file to You under the Apache License, Version 2.0
12 *  (the "License"); you may not use this file except in compliance with
13 *  the License.  You may obtain a copy of the License at
14 *
15 *      http://www.apache.org/licenses/LICENSE-2.0
16 *
17 *  Unless required by applicable law or agreed to in writing, software
18 *  distributed under the License is distributed on an "AS IS" BASIS,
19 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 *  See the License for the specific language governing permissions and
21 *  limitations under the License.
22 * ====================================================================
23 *
24 * This software consists of voluntary contributions made by many
25 * individuals on behalf of the Apache Software Foundation.  For more
26 * information on the Apache Software Foundation, please see
27 * <http://www.apache.org/>.
28 *
29 */
30
31package org.apache.http.impl.client;
32
33import java.util.ArrayList;
34import java.util.Collections;
35import java.util.Comparator;
36import java.util.Date;
37import java.util.Iterator;
38import java.util.List;
39
40import org.apache.http.client.CookieStore;
41import org.apache.http.cookie.Cookie;
42import org.apache.http.cookie.CookieIdentityComparator;
43
44/**
45 * Default implementation of {@link CookieStore}
46 *
47 * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
48 * @author Rodney Waldhoff
49 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
50 * @author Sean C. Sullivan
51 * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
52 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
53 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
54 * @author <a href="mailto:adrian@intencha.com">Adrian Sutton</a>
55 *
56 * @since 4.0
57 */
58public class BasicCookieStore implements CookieStore {
59
60    private final ArrayList<Cookie> cookies;
61
62    private final Comparator<Cookie> cookieComparator;
63
64    // -------------------------------------------------------- Class Variables
65
66    /**
67     * Default constructor.
68     */
69    public BasicCookieStore() {
70        super();
71        this.cookies = new ArrayList<Cookie>();
72        this.cookieComparator = new CookieIdentityComparator();
73    }
74
75    /**
76     * Adds an {@link Cookie HTTP cookie}, replacing any existing equivalent cookies.
77     * If the given cookie has already expired it will not be added, but existing
78     * values will still be removed.
79     *
80     * @param cookie the {@link Cookie cookie} to be added
81     *
82     * @see #addCookies(Cookie[])
83     *
84     */
85    public synchronized void addCookie(Cookie cookie) {
86        if (cookie != null) {
87            // first remove any old cookie that is equivalent
88            for (Iterator<Cookie> it = cookies.iterator(); it.hasNext();) {
89                if (cookieComparator.compare(cookie, it.next()) == 0) {
90                    it.remove();
91                    break;
92                }
93            }
94            if (!cookie.isExpired(new Date())) {
95                cookies.add(cookie);
96            }
97        }
98    }
99
100    /**
101     * Adds an array of {@link Cookie HTTP cookies}. Cookies are added individually and
102     * in the given array order. If any of the given cookies has already expired it will
103     * not be added, but existing values will still be removed.
104     *
105     * @param cookies the {@link Cookie cookies} to be added
106     *
107     * @see #addCookie(Cookie)
108     *
109     */
110    public synchronized void addCookies(Cookie[] cookies) {
111        if (cookies != null) {
112            for (Cookie cooky : cookies) {
113                this.addCookie(cooky);
114            }
115        }
116    }
117
118    /**
119     * Returns an immutable array of {@link Cookie cookies} that this HTTP
120     * state currently contains.
121     *
122     * @return an array of {@link Cookie cookies}.
123     */
124    public synchronized List<Cookie> getCookies() {
125        return Collections.unmodifiableList(this.cookies);
126    }
127
128    /**
129     * Removes all of {@link Cookie cookies} in this HTTP state
130     * that have expired by the specified {@link java.util.Date date}.
131     *
132     * @return true if any cookies were purged.
133     *
134     * @see Cookie#isExpired(Date)
135     */
136    public synchronized boolean clearExpired(final Date date) {
137        if (date == null) {
138            return false;
139        }
140        boolean removed = false;
141        for (Iterator<Cookie> it = cookies.iterator(); it.hasNext();) {
142            if (it.next().isExpired(date)) {
143                it.remove();
144                removed = true;
145            }
146        }
147        return removed;
148    }
149
150    @Override
151    public String toString() {
152        return cookies.toString();
153    }
154
155    /**
156     * Clears all cookies.
157     */
158    public synchronized void clear() {
159        cookies.clear();
160    }
161
162}
163