1 /*
2  * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/cookie/CookiePolicy.java,v 1.15 2004/09/14 20:11:31 olegk Exp $
3  * $Revision: 480424 $
4  * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
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 
31 package org.apache.commons.httpclient.cookie;
32 
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.Map;
36 
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 
40 /**
41  * Cookie management policy class. The cookie policy provides corresponding
42  * cookie management interfrace for a given type or version of cookie.
43  * <p>RFC 2109 specification is used per default. Other supported specification
44  * can be  chosen when appropriate or set default when desired
45  * <p>The following specifications are provided:
46  *  <ul>
47  *   <li><tt>BROWSER_COMPATIBILITY</tt>: compatible with the common cookie
48  *   management practices (even if they are not 100% standards compliant)
49  *   <li><tt>NETSCAPE</tt>: Netscape cookie draft compliant
50  *   <li><tt>RFC_2109</tt>: RFC2109 compliant (default)
51  *   <li><tt>IGNORE_COOKIES</tt>: do not automcatically process cookies
52  *  </ul>
53  *
54  * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
55  * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
56  *
57  * @since 2.0
58  */
59 public abstract class CookiePolicy {
60 
61     private static Map SPECS = Collections.synchronizedMap(new HashMap());
62 
63     /**
64      * The policy that provides high degree of compatibilty
65      * with common cookie management of popular HTTP agents.
66      *
67      * @since 3.0
68      */
69     public static final String BROWSER_COMPATIBILITY = "compatibility";
70 
71     /**
72      * The Netscape cookie draft compliant policy.
73      *
74      * @since 3.0
75      */
76     public static final String NETSCAPE = "netscape";
77 
78     /**
79      * The RFC 2109 compliant policy.
80      *
81      * @since 3.0
82      */
83     public static final String RFC_2109 = "rfc2109";
84 
85     /**
86      * The RFC 2965 compliant policy.
87      *
88      * @since 3.0
89      */
90     public static final String RFC_2965 = "rfc2965";
91 
92     /**
93      * The policy that ignores cookies.
94      *
95      * @since 3.0
96      */
97     public static final String IGNORE_COOKIES = "ignoreCookies";
98 
99     /**
100      * The default cookie policy.
101      *
102      * @since 3.0
103      */
104     public static final String DEFAULT = "default";
105 
106     static {
CookiePolicy.registerCookieSpec(DEFAULT, RFC2109Spec.class)107         CookiePolicy.registerCookieSpec(DEFAULT, RFC2109Spec.class);
CookiePolicy.registerCookieSpec(RFC_2109, RFC2109Spec.class)108         CookiePolicy.registerCookieSpec(RFC_2109, RFC2109Spec.class);
CookiePolicy.registerCookieSpec(RFC_2965, RFC2965Spec.class)109         CookiePolicy.registerCookieSpec(RFC_2965, RFC2965Spec.class);
CookiePolicy.registerCookieSpec(BROWSER_COMPATIBILITY, CookieSpecBase.class)110         CookiePolicy.registerCookieSpec(BROWSER_COMPATIBILITY, CookieSpecBase.class);
CookiePolicy.registerCookieSpec(NETSCAPE, NetscapeDraftSpec.class)111         CookiePolicy.registerCookieSpec(NETSCAPE, NetscapeDraftSpec.class);
CookiePolicy.registerCookieSpec(IGNORE_COOKIES, IgnoreCookiesSpec.class)112         CookiePolicy.registerCookieSpec(IGNORE_COOKIES, IgnoreCookiesSpec.class);
113     }
114 
115     /**
116      * The <tt>COMPATIBILITY</tt> policy provides high compatibilty
117      * with common cookie management of popular HTTP agents.
118      *
119      * @deprecated Use {@link #BROWSER_COMPATIBILITY}
120      */
121     public static final int COMPATIBILITY = 0;
122 
123     /**
124      * The <tt>NETSCAPE_DRAFT</tt> Netscape draft compliant policy.
125      *
126      * @deprecated Use {@link #NETSCAPE}
127      */
128     public static final int NETSCAPE_DRAFT = 1;
129 
130     /**
131      * The <tt>RFC2109</tt> RFC 2109 compliant policy.
132      *
133      * @deprecated Use {@link #RFC_2109}
134      */
135     public static final int RFC2109 = 2;
136 
137     /**
138      * The <tt>RFC2965</tt> RFC 2965 compliant policy.
139      *
140      * @deprecated Use {@link #RFC_2965}
141      */
142     public static final int RFC2965 = 3;
143 
144     /**
145      * The default cookie policy.
146      *
147      * @deprecated Use {@link #DEFAULT}
148      */
149     private static int defaultPolicy = RFC2109;
150 
151     /** Log object. */
152     protected static final Log LOG = LogFactory.getLog(CookiePolicy.class);
153 
154     /**
155      * Registers a new {@link CookieSpec cookie specification} with the given identifier.
156      * If a specification with the given ID already exists it will be overridden.
157      * This ID is the same one used to retrieve the {@link CookieSpec cookie specification}
158      * from {@link #getCookieSpec(String)}.
159      *
160      * @param id the identifier for this specification
161      * @param clazz the {@link CookieSpec cookie specification} class to register
162      *
163      * @see #getCookieSpec(String)
164      *
165      * @since 3.0
166      */
registerCookieSpec(final String id, final Class clazz)167     public static void registerCookieSpec(final String id, final Class clazz) {
168          if (id == null) {
169              throw new IllegalArgumentException("Id may not be null");
170          }
171         if (clazz == null) {
172             throw new IllegalArgumentException("Cookie spec class may not be null");
173         }
174         SPECS.put(id.toLowerCase(), clazz);
175     }
176 
177     /**
178      * Unregisters the {@link CookieSpec cookie specification} with the given ID.
179      *
180      * @param id the ID of the {@link CookieSpec cookie specification} to unregister
181      *
182      * @since 3.0
183      */
unregisterCookieSpec(final String id)184     public static void unregisterCookieSpec(final String id) {
185          if (id == null) {
186              throw new IllegalArgumentException("Id may not be null");
187          }
188          SPECS.remove(id.toLowerCase());
189     }
190 
191     /**
192      * Gets the {@link CookieSpec cookie specification} with the given ID.
193      *
194      * @param id the {@link CookieSpec cookie specification} ID
195      *
196      * @return {@link CookieSpec cookie specification}
197      *
198      * @throws IllegalStateException if a policy with the ID cannot be found
199      *
200      * @since 3.0
201      */
getCookieSpec(final String id)202     public static CookieSpec getCookieSpec(final String id)
203         throws IllegalStateException {
204 
205         if (id == null) {
206             throw new IllegalArgumentException("Id may not be null");
207         }
208         Class clazz = (Class)SPECS.get(id.toLowerCase());
209 
210         if (clazz != null) {
211             try {
212                 return (CookieSpec)clazz.newInstance();
213             } catch (Exception e) {
214                 LOG.error("Error initializing cookie spec: " + id, e);
215                 throw new IllegalStateException(id +
216                     " cookie spec implemented by " +
217                     clazz.getName() + " could not be initialized");
218             }
219         } else {
220             throw new IllegalStateException("Unsupported cookie spec " + id);
221         }
222     }
223 
224     /**
225      * @return default cookie policy
226      *
227      * @deprecated Use {@link #getDefaultSpec()}
228      *
229      * @see #getDefaultSpec()
230      */
getDefaultPolicy()231     public static int getDefaultPolicy() {
232         return defaultPolicy;
233     }
234 
235 
236     /**
237      * @param policy new default cookie policy
238      *
239      * @deprecated Use {@link CookiePolicy#registerCookieSpec(String, Class)}
240      * @see #DEFAULT
241      */
setDefaultPolicy(int policy)242     public static void setDefaultPolicy(int policy) {
243         defaultPolicy = policy;
244     }
245 
246     /**
247      * @param policy cookie policy to get the CookieSpec for
248      * @return cookie specification interface for the given policy
249      *
250      * @deprecated Use {@link CookiePolicy#getCookieSpec(String)}
251      */
getSpecByPolicy(int policy)252     public static CookieSpec getSpecByPolicy(int policy) {
253         switch(policy) {
254             case COMPATIBILITY:
255                 return new CookieSpecBase();
256             case NETSCAPE_DRAFT:
257                 return new NetscapeDraftSpec();
258             case RFC2109:
259                 return new RFC2109Spec();
260             case RFC2965:
261                 return new RFC2965Spec();
262             default:
263                 return getDefaultSpec();
264         }
265     }
266 
267 
268     /**
269      * Returns {@link CookieSpec cookie specification} registered as {@link #DEFAULT}.
270      * If no default {@link CookieSpec cookie specification} has been registered,
271      * {@link RFC2109Spec RFC2109 specification} is returned.
272      *
273      * @return default {@link CookieSpec cookie specification}
274      *
275      * @see #DEFAULT
276      */
getDefaultSpec()277     public static CookieSpec getDefaultSpec() {
278         try {
279             return getCookieSpec(DEFAULT);
280         } catch (IllegalStateException e) {
281             LOG.warn("Default cookie policy is not registered");
282             return new RFC2109Spec();
283         }
284     }
285 
286 
287     /**
288      * Gets the CookieSpec for a particular cookie version.
289      *
290      * <p>Supported versions:
291      * <ul>
292      *  <li><tt>version 0</tt> corresponds to the Netscape draft
293      *  <li><tt>version 1</tt> corresponds to the RFC 2109
294      *  <li>Any other cookie value coresponds to the default spec
295      * <ul>
296      *
297      * @param ver the cookie version to get the spec for
298      * @return cookie specification interface intended for processing
299      *  cookies with the given version
300      *
301      * @deprecated Use {@link CookiePolicy#getCookieSpec(String)}
302      */
getSpecByVersion(int ver)303     public static CookieSpec getSpecByVersion(int ver) {
304         switch(ver) {
305             case 0:
306                 return new NetscapeDraftSpec();
307             case 1:
308                 return new RFC2109Spec();
309             default:
310                 return getDefaultSpec();
311         }
312     }
313 
314     /**
315      * @return cookie specification interface that provides high compatibilty
316      * with common cookie management of popular HTTP agents
317      *
318      * @deprecated Use {@link CookiePolicy#getCookieSpec(String)}
319      */
getCompatibilitySpec()320     public static CookieSpec getCompatibilitySpec() {
321         return getSpecByPolicy(COMPATIBILITY);
322     }
323 
324     /**
325      * Obtains the currently registered cookie policy names.
326      *
327      * Note that the DEFAULT policy (if present) is likely to be the same
328      * as one of the other policies, but does not have to be.
329      *
330      * @return array of registered cookie policy names
331      *
332      * @since 3.1
333      */
getRegisteredCookieSpecs()334     public static String[] getRegisteredCookieSpecs(){
335             return (String[]) SPECS.keySet().toArray(new String [SPECS.size()]);
336     }
337 
338 }
339