001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027package org.apache.http.impl.client; 028 029import java.io.Serializable; 030import java.util.ArrayList; 031import java.util.Date; 032import java.util.Iterator; 033import java.util.List; 034import java.util.TreeSet; 035 036import org.apache.http.annotation.Contract; 037import org.apache.http.annotation.ThreadingBehavior; 038import org.apache.http.client.CookieStore; 039import org.apache.http.cookie.Cookie; 040import org.apache.http.cookie.CookieIdentityComparator; 041 042/** 043 * Default implementation of {@link CookieStore} 044 * 045 * 046 * @since 4.0 047 */ 048@Contract(threading = ThreadingBehavior.SAFE) 049public class BasicCookieStore implements CookieStore, Serializable { 050 051 private static final long serialVersionUID = -7581093305228232025L; 052 053 private final TreeSet<Cookie> cookies; 054 055 public BasicCookieStore() { 056 super(); 057 this.cookies = new TreeSet<Cookie>(new CookieIdentityComparator()); 058 } 059 060 /** 061 * Adds an {@link Cookie HTTP cookie}, replacing any existing equivalent cookies. 062 * If the given cookie has already expired it will not be added, but existing 063 * values will still be removed. 064 * 065 * @param cookie the {@link Cookie cookie} to be added 066 * 067 * @see #addCookies(Cookie[]) 068 * 069 */ 070 @Override 071 public synchronized void addCookie(final Cookie cookie) { 072 if (cookie != null) { 073 // first remove any old cookie that is equivalent 074 cookies.remove(cookie); 075 if (!cookie.isExpired(new Date())) { 076 cookies.add(cookie); 077 } 078 } 079 } 080 081 /** 082 * Adds an array of {@link Cookie HTTP cookies}. Cookies are added individually and 083 * in the given array order. If any of the given cookies has already expired it will 084 * not be added, but existing values will still be removed. 085 * 086 * @param cookies the {@link Cookie cookies} to be added 087 * 088 * @see #addCookie(Cookie) 089 * 090 */ 091 public synchronized void addCookies(final Cookie[] cookies) { 092 if (cookies != null) { 093 for (final Cookie cooky : cookies) { 094 this.addCookie(cooky); 095 } 096 } 097 } 098 099 /** 100 * Returns an immutable array of {@link Cookie cookies} that this HTTP 101 * state currently contains. 102 * 103 * @return an array of {@link Cookie cookies}. 104 */ 105 @Override 106 public synchronized List<Cookie> getCookies() { 107 //create defensive copy so it won't be concurrently modified 108 return new ArrayList<Cookie>(cookies); 109 } 110 111 /** 112 * Removes all of {@link Cookie cookies} in this HTTP state 113 * that have expired by the specified {@link java.util.Date date}. 114 * 115 * @return true if any cookies were purged. 116 * 117 * @see Cookie#isExpired(Date) 118 */ 119 @Override 120 public synchronized boolean clearExpired(final Date date) { 121 if (date == null) { 122 return false; 123 } 124 boolean removed = false; 125 for (final Iterator<Cookie> it = cookies.iterator(); it.hasNext();) { 126 if (it.next().isExpired(date)) { 127 it.remove(); 128 removed = true; 129 } 130 } 131 return removed; 132 } 133 134 /** 135 * Clears all cookies. 136 */ 137 @Override 138 public synchronized void clear() { 139 cookies.clear(); 140 } 141 142 @Override 143 public synchronized String toString() { 144 return cookies.toString(); 145 } 146 147}