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