001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: *
021: * $Id: HttpCookieManager.java,v 1.3 2007-10-19 10:05:39 sinisa Exp $
022: */
023:
024: package com.lutris.http;
025:
026: import java.util.Enumeration;
027: import java.util.Vector;
028:
029: import javax.servlet.http.Cookie;
030:
031: /**
032: * This object manages cookies defined in http request and
033: * response headers.
034: *
035: * @author Kyle Clark
036: * @version $Revision: 1.3 $
037: * @since Harmony2.0
038: */
039: public class HttpCookieManager {
040:
041: /**
042: * The set of cookies managed by this object.
043: */
044: private Vector cookies;
045:
046: /**
047: * Constructs a new cookie manager.
048: */
049: public HttpCookieManager() {
050: cookies = new Vector();
051: }
052:
053: /**
054: * Returns the string representation of all the cookies being managed
055: * by this object as an http cookie request header.
056: * The format of the header is:
057: * <pre>
058: * NAME1=VALUE1; NAME2=VALUE2; ....
059: * </pre>
060: *
061: * @return the "Cookie" header as it would appear in an http request header.
062: */
063: public String getRequestHeader() {
064: return getRequestHeader(null, null);
065: }
066:
067: /**
068: * Returns the string representation of the cookies being managed
069: * by this object as an http cookie request header
070: * The format of the header is:
071: * <pre>
072: * NAME1=VALUE1; NAME2=VALUE2; ....
073: * </pre>
074: *
075: * @param path
076: * Only return the cookies that are valid in the specified
077: * path. If path is null then path is ignored.
078: * @param domain
079: * Only return the cookies that are valid in the specified
080: * domain. If null, the domain is ignored.
081: * @return the "Cookie" header as it would appear in an http request
082: * or null if this object contains no cookies that apply
083: * to the path and domain contraints.
084: */
085: public String getRequestHeader(String path, String domain) {
086: // FIX: use string buffer
087: // String header = null;
088: StringBuffer headerBuffer = null;
089: Enumeration e = cookies.elements();
090: while (e.hasMoreElements()) {
091: Cookie c = (Cookie) e.nextElement();
092: boolean matchPath = true;
093: boolean matchDomain = true;
094: if (path != null) {
095: if (c.getPath() != null)
096: matchPath = c.getPath().startsWith(path);
097: else
098: matchPath = true;
099: }
100: if (domain != null) {
101: // FIX: read spec, need to do this correctly
102: if (c.getDomain() != null)
103: matchDomain = c.getDomain().endsWith(domain);
104: else
105: matchDomain = true;
106: }
107: if (matchPath && matchDomain) {
108: /*if (header == null)
109: header = c.getName() + "=" + c.getValue();
110: else
111: header += "; " + c.getName() + "=" + c.getValue();*/
112: if (headerBuffer == null)
113: headerBuffer = new StringBuffer(c.getName() + "="
114: + c.getValue());
115: else
116: headerBuffer.append("; " + c.getName() + "="
117: + c.getValue());
118: }
119: }
120: if (headerBuffer != null)
121: return headerBuffer.toString();
122: else
123: return null;
124: }
125:
126: /**
127: * Returns the string representation of the cookies being managed
128: * by this object as an http cookie response ("Set-Cookie")
129: * header. The format of the header is a comma (,) separated
130: * list of:
131: * <pre>
132: * name=value [;EXPIRES=dateValue] [;DOMAIN=domainName]
133: * [;PATH=path] [;SECURE]
134: * </pre>
135: *
136: * @return the string representation of the cookies being managed
137: * by this object as an http cookie response header ("Set-Cookie").
138: * null is returned if there aren't any cookies
139: * being managed by this cookie manager.
140: */
141: public String getResponseHeader() {
142: StringBuffer headerBuffer = null;
143: Enumeration e = cookies.elements();
144: while (e.hasMoreElements()) {
145: Cookie c = (Cookie) e.nextElement();
146: if (headerBuffer == null)
147: headerBuffer = new StringBuffer(c.toString());
148: else
149: headerBuffer.append(", " + c.toString());
150: }
151: if (headerBuffer != null)
152: return headerBuffer.toString();
153: else
154: return null;
155: }
156:
157: /**
158: * Merges the cookies contained in the specified http response header
159: * into the set of cookies being managed by this object.
160: *
161: * @param header the Set-Cookie http response header to merge.
162: */
163: public synchronized void mergeHeader(String header) {
164: if (header == null) {
165: return;
166: }
167: Vector newCookies = HttpCookieParser
168: .parseResponseHeader(header);
169: Cookie[] merge = new Cookie[cookies.size()];
170: Cookie[] mergeNew = new Cookie[newCookies.size()];
171: cookies.copyInto(merge);
172: newCookies.copyInto(mergeNew);
173:
174: //
175: // Remove from the original set any cookies that are
176: // redefined in the new set.
177: //
178: for (int idx = 0; idx < merge.length; idx++) {
179: for (int idxNew = 0; idxNew < mergeNew.length; idxNew++) {
180: if (testEquality(merge[idx], mergeNew[idxNew])) {
181: merge[idx] = null;
182: break;
183: }
184: }
185: }
186:
187: //
188: // Reconstruct the cookie set.
189: //
190: cookies = new Vector();
191: for (int idx = 0; idx < merge.length; idx++) {
192: if (merge[idx] != null)
193: cookies.addElement(merge[idx]);
194: }
195: for (int idx = 0; idx < mergeNew.length; idx++) {
196: cookies.addElement(mergeNew[idx]);
197: }
198: }
199:
200: /**
201: * Returns an array of the cookies being managed.
202: *
203: * @return enumeration of javax.servlet.http.Cookie
204: * objects.
205: * @see javax.servlet.http.Cookie
206: */
207: public Cookie[] getCookies() {
208: Cookie[] cookieTab = new Cookie[cookies.size()];
209: cookies.copyInto(cookieTab);
210: return cookieTab;
211: }
212:
213: /**
214: * Removes all cookies from this manager.
215: */
216: public synchronized void clear() {
217: cookies.setSize(0);
218: }
219:
220: /**
221: * Returns the string representation of the headers/cookies being managed
222: * by this object as an http cookie response header (i.e. Set-Cookie
223: * header).
224: *
225: * @return the string representation of the cookies being managed
226: * by this object as an http cookie response header (i.e. Set-Cookie
227: * header).
228: */
229: public String toString() {
230: return getResponseHeader();
231: }
232:
233: /**
234: * Compares two cookies. If the name, path, and domain are the
235: * same then the cookies are equal equal.
236: *
237: * @return true if the cookies are equal.
238: */
239:
240: private boolean testEquality(Cookie c1, Cookie c2) {
241: String name1 = c1.getName();
242: String name2 = c2.getName();
243: if ((name1 == null) && (name2 != null))
244: return false;
245: if ((name1 != null) && (name2 == null))
246: return false;
247: if ((name1 != null) && (name2 != null) && !name1.equals(name2))
248: return false;
249:
250: String path1 = c1.getPath();
251: String path2 = c2.getPath();
252: if ((path1 == null) && (path2 != null))
253: return false;
254: if ((path1 != null) && (path2 == null))
255: return false;
256: if ((path1 != null) && (path2 != null) && !path1.equals(path2))
257: return false;
258:
259: String domain1 = c1.getDomain();
260: String domain2 = c2.getDomain();
261: if ((domain1 == null) && (domain2 != null))
262: return false;
263: if ((domain1 != null) && (domain2 == null))
264: return false;
265: if ((domain1 != null) && (domain2 != null)
266: && !domain1.equals(domain2))
267: return false;
268:
269: return true;
270: }
271: }
|