View Javadoc

1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/oac.hc3x/trunk/src/java/org/apache/commons/httpclient/cookie/CookiePolicy.java $
3    * $Revision: 1425331 $
4    * $Date: 2012-12-22 19:29:41 +0100 (Sat, 22 Dec 2012) $
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 {
107         CookiePolicy.registerCookieSpec(DEFAULT, RFC2109Spec.class);
108         CookiePolicy.registerCookieSpec(RFC_2109, RFC2109Spec.class);
109         CookiePolicy.registerCookieSpec(RFC_2965, RFC2965Spec.class);
110         CookiePolicy.registerCookieSpec(BROWSER_COMPATIBILITY, CookieSpecBase.class);
111         CookiePolicy.registerCookieSpec(NETSCAPE, NetscapeDraftSpec.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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
334     public static String[] getRegisteredCookieSpecs(){
335             return (String[]) SPECS.keySet().toArray(new String [SPECS.size()]); 
336     }
337     
338 }