1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 }