001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.ui.savedrequest;
017:
018: import org.acegisecurity.util.PortResolver;
019: import org.acegisecurity.util.UrlUtils;
020: import org.apache.commons.logging.Log;
021: import org.apache.commons.logging.LogFactory;
022: import org.springframework.util.Assert;
023:
024: import javax.servlet.http.Cookie;
025: import javax.servlet.http.HttpServletRequest;
026: import java.util.ArrayList;
027: import java.util.Enumeration;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Locale;
031: import java.util.Map;
032: import java.util.TreeMap;
033:
034: /**
035: * Represents central information from a <code>HttpServletRequest</code>.<p>This class is used by {@link
036: * org.acegisecurity.ui.AbstractProcessingFilter} and {@link org.acegisecurity.wrapper.SavedRequestAwareWrapper} to
037: * reproduce the request after successful authentication. An instance of this class is stored at the time of an
038: * authentication exception by {@link org.acegisecurity.ui.ExceptionTranslationFilter}.</p>
039: * <p><em>IMPLEMENTATION NOTE</em>: It is assumed that this object is accessed only from the context of a single
040: * thread, so no synchronization around internal collection classes is performed.</p>
041: * <p>This class is based on code in Apache Tomcat.</p>
042: *
043: * @author Craig McClanahan
044: * @author Andrey Grebnev
045: * @author Ben Alex
046: * @version $Id: SavedRequest.java 1784 2007-02-24 21:00:24Z luke_t $
047: */
048: public class SavedRequest implements java.io.Serializable {
049: //~ Static fields/initializers =====================================================================================
050:
051: protected static final Log logger = LogFactory
052: .getLog(SavedRequest.class);
053:
054: //~ Instance fields ================================================================================================
055:
056: private ArrayList cookies = new ArrayList();
057: private ArrayList locales = new ArrayList();
058: private Map headers = new TreeMap(String.CASE_INSENSITIVE_ORDER);
059: private Map parameters = new TreeMap(String.CASE_INSENSITIVE_ORDER);
060: private String contextPath;
061: private String method;
062: private String pathInfo;
063: private String queryString;
064: private String requestURI;
065: private String requestURL;
066: private String scheme;
067: private String serverName;
068: private String servletPath;
069: private int serverPort;
070:
071: //~ Constructors ===================================================================================================
072:
073: public SavedRequest(HttpServletRequest request,
074: PortResolver portResolver) {
075: Assert.notNull(request, "Request required");
076: Assert.notNull(portResolver, "PortResolver required");
077:
078: // Cookies
079: Cookie[] cookies = request.getCookies();
080:
081: if (cookies != null) {
082: for (int i = 0; i < cookies.length; i++) {
083: this .addCookie(cookies[i]);
084: }
085: }
086:
087: // Headers
088: Enumeration names = request.getHeaderNames();
089:
090: while (names.hasMoreElements()) {
091: String name = (String) names.nextElement();
092: Enumeration values = request.getHeaders(name);
093:
094: while (values.hasMoreElements()) {
095: String value = (String) values.nextElement();
096: this .addHeader(name, value);
097: }
098: }
099:
100: // Locales
101: Enumeration locales = request.getLocales();
102:
103: while (locales.hasMoreElements()) {
104: Locale locale = (Locale) locales.nextElement();
105: this .addLocale(locale);
106: }
107:
108: // Parameters
109: Map parameters = request.getParameterMap();
110: Iterator paramNames = parameters.keySet().iterator();
111:
112: while (paramNames.hasNext()) {
113: String paramName = (String) paramNames.next();
114: Object o = parameters.get(paramName);
115: if (o instanceof String[]) {
116: String[] paramValues = (String[]) o;
117: this .addParameter(paramName, paramValues);
118: } else {
119: if (logger.isWarnEnabled()) {
120: logger
121: .warn("ServletRequest.getParameterMap() returned non-String array");
122: }
123: }
124: }
125:
126: // Primitives
127: this .method = request.getMethod();
128: this .pathInfo = request.getPathInfo();
129: this .queryString = request.getQueryString();
130: this .requestURI = request.getRequestURI();
131: this .serverPort = portResolver.getServerPort(request);
132: this .requestURL = request.getRequestURL().toString();
133: this .scheme = request.getScheme();
134: this .serverName = request.getServerName();
135: this .contextPath = request.getContextPath();
136: this .servletPath = request.getServletPath();
137: }
138:
139: //~ Methods ========================================================================================================
140:
141: private void addCookie(Cookie cookie) {
142: cookies.add(new SavedCookie(cookie));
143: }
144:
145: private void addHeader(String name, String value) {
146: ArrayList values = (ArrayList) headers.get(name);
147:
148: if (values == null) {
149: values = new ArrayList();
150: headers.put(name, values);
151: }
152:
153: values.add(value);
154: }
155:
156: private void addLocale(Locale locale) {
157: locales.add(locale);
158: }
159:
160: private void addParameter(String name, String[] values) {
161: parameters.put(name, values);
162: }
163:
164: /**
165: * Determines if the current request matches the <code>SavedRequest</code>. All URL arguments are
166: * considered, but <em>not</em> method (POST/GET), cookies, locales, headers or parameters.
167: *
168: * @param request DOCUMENT ME!
169: * @param portResolver DOCUMENT ME!
170: * @return DOCUMENT ME!
171: */
172: public boolean doesRequestMatch(HttpServletRequest request,
173: PortResolver portResolver) {
174: Assert.notNull(request, "Request required");
175: Assert.notNull(portResolver, "PortResolver required");
176:
177: if (!propertyEquals("pathInfo", this .pathInfo, request
178: .getPathInfo())) {
179: return false;
180: }
181:
182: if (!propertyEquals("queryString", this .queryString, request
183: .getQueryString())) {
184: return false;
185: }
186:
187: if (!propertyEquals("requestURI", this .requestURI, request
188: .getRequestURI())) {
189: return false;
190: }
191:
192: if (!propertyEquals("serverPort", new Integer(this .serverPort),
193: new Integer(portResolver.getServerPort(request)))) {
194: return false;
195: }
196:
197: if (!propertyEquals("requestURL", this .requestURL, request
198: .getRequestURL().toString())) {
199: return false;
200: }
201:
202: if (!propertyEquals("scheme", this .scheme, request.getScheme())) {
203: return false;
204: }
205:
206: if (!propertyEquals("serverName", this .serverName, request
207: .getServerName())) {
208: return false;
209: }
210:
211: if (!propertyEquals("contextPath", this .contextPath, request
212: .getContextPath())) {
213: return false;
214: }
215:
216: if (!propertyEquals("servletPath", this .servletPath, request
217: .getServletPath())) {
218: return false;
219: }
220:
221: return true;
222: }
223:
224: public String getContextPath() {
225: return contextPath;
226: }
227:
228: public List getCookies() {
229: List cookieList = new ArrayList(cookies.size());
230: for (Iterator iterator = cookies.iterator(); iterator.hasNext();) {
231: SavedCookie savedCookie = (SavedCookie) iterator.next();
232: cookieList.add(savedCookie.getCookie());
233: }
234: return cookieList;
235: }
236:
237: /**
238: * Indicates the URL that the user agent used for this request.
239: *
240: * @return the full URL of this request
241: */
242: public String getFullRequestUrl() {
243: return UrlUtils.getFullRequestUrl(this );
244: }
245:
246: public Iterator getHeaderNames() {
247: return (headers.keySet().iterator());
248: }
249:
250: public Iterator getHeaderValues(String name) {
251: ArrayList values = (ArrayList) headers.get(name);
252:
253: if (values == null) {
254: return ((new ArrayList()).iterator());
255: } else {
256: return (values.iterator());
257: }
258: }
259:
260: public Iterator getLocales() {
261: return (locales.iterator());
262: }
263:
264: public String getMethod() {
265: return (this .method);
266: }
267:
268: public Map getParameterMap() {
269: return parameters;
270: }
271:
272: public Iterator getParameterNames() {
273: return (parameters.keySet().iterator());
274: }
275:
276: public String[] getParameterValues(String name) {
277: return ((String[]) parameters.get(name));
278: }
279:
280: public String getPathInfo() {
281: return pathInfo;
282: }
283:
284: public String getQueryString() {
285: return (this .queryString);
286: }
287:
288: public String getRequestURI() {
289: return (this .requestURI);
290: }
291:
292: public String getRequestURL() {
293: return requestURL;
294: }
295:
296: /**
297: * Obtains the web application-specific fragment of the URL.
298: *
299: * @return the URL, excluding any server name, context path or servlet path
300: */
301: public String getRequestUrl() {
302: return UrlUtils.getRequestUrl(this );
303: }
304:
305: public String getScheme() {
306: return scheme;
307: }
308:
309: public String getServerName() {
310: return serverName;
311: }
312:
313: public int getServerPort() {
314: return serverPort;
315: }
316:
317: public String getServletPath() {
318: return servletPath;
319: }
320:
321: private boolean propertyEquals(String log, Object arg1, Object arg2) {
322: if ((arg1 == null) && (arg2 == null)) {
323: if (logger.isDebugEnabled()) {
324: logger.debug(log + ": both null (property equals)");
325: }
326:
327: return true;
328: }
329:
330: if (((arg1 == null) && (arg2 != null))
331: || ((arg1 != null) && (arg2 == null))) {
332: if (logger.isDebugEnabled()) {
333: logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2
334: + " (property not equals)");
335: }
336:
337: return false;
338: }
339:
340: if (arg1.equals(arg2)) {
341: if (logger.isDebugEnabled()) {
342: logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2
343: + " (property equals)");
344: }
345:
346: return true;
347: } else {
348: if (logger.isDebugEnabled()) {
349: logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2
350: + " (property not equals)");
351: }
352:
353: return false;
354: }
355: }
356:
357: public String toString() {
358: return "SavedRequest[" + getFullRequestUrl() + "]";
359: }
360: }
|