001: /*
002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/ApplicationHttpRequest.java,v 1.12 2002/05/23 07:13:45 remm Exp $
003: * $Revision: 1.12 $
004: * $Date: 2002/05/23 07:13:45 $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 1999 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: * [Additional notices, if required by prior licensing conditions]
061: *
062: */
063:
064: package org.apache.catalina.core;
065:
066: import java.io.IOException;
067: import java.util.ArrayList;
068: import java.util.Enumeration;
069: import java.util.HashMap;
070: import java.util.Iterator;
071: import java.util.Map;
072: import javax.servlet.http.HttpServletRequest;
073: import javax.servlet.http.HttpServletRequestWrapper;
074: import org.apache.catalina.Globals;
075: import org.apache.catalina.HttpRequest;
076: import org.apache.catalina.util.Enumerator;
077: import org.apache.catalina.util.RequestUtil;
078: import org.apache.catalina.util.StringManager;
079:
080: /**
081: * Wrapper around a <code>javax.servlet.http.HttpServletRequest</code>
082: * that transforms an application request object (which might be the original
083: * one passed to a servlet, or might be based on the 2.3
084: * <code>javax.servlet.http.HttpServletRequestWrapper</code> class)
085: * back into an internal <code>org.apache.catalina.HttpRequest</code>.
086: * <p>
087: * <strong>WARNING</strong>: Due to Java's lack of support for multiple
088: * inheritance, all of the logic in <code>ApplicationRequest</code> is
089: * duplicated in <code>ApplicationHttpRequest</code>. Make sure that you
090: * keep these two classes in synchronization when making changes!
091: *
092: * @author Craig R. McClanahan
093: * @version $Revision: 1.12 $ $Date: 2002/05/23 07:13:45 $
094: */
095:
096: class ApplicationHttpRequest extends HttpServletRequestWrapper {
097:
098: // ------------------------------------------------------- Static Variables
099:
100: /**
101: * The set of attribute names that are special for request dispatchers.
102: */
103: protected static final String specials[] = {
104: Globals.REQUEST_URI_ATTR, Globals.CONTEXT_PATH_ATTR,
105: Globals.SERVLET_PATH_ATTR, Globals.PATH_INFO_ATTR,
106: Globals.QUERY_STRING_ATTR };
107:
108: // ----------------------------------------------------------- Constructors
109:
110: /**
111: * Construct a new wrapped request around the specified servlet request.
112: *
113: * @param request The servlet request being wrapped
114: */
115: public ApplicationHttpRequest(HttpServletRequest request) {
116:
117: super (request);
118: setRequest(request);
119:
120: }
121:
122: // ----------------------------------------------------- Instance Variables
123:
124: /**
125: * The request attributes for this request. This is initialized from the
126: * wrapped request, but updates are allowed.
127: */
128: protected HashMap attributes = new HashMap();
129:
130: /**
131: * The context path for this request.
132: */
133: protected String contextPath = null;
134:
135: /**
136: * Descriptive information about this implementation.
137: */
138: protected static final String info = "org.apache.catalina.core.ApplicationHttpRequest/1.0";
139:
140: /**
141: * The request parameters for this request. This is initialized from the
142: * wrapped request, but updates are allowed.
143: */
144: protected Map parameters = new HashMap();
145:
146: /**
147: * The path information for this request.
148: */
149: protected String pathInfo = null;
150:
151: /**
152: * The query string for this request.
153: */
154: protected String queryString = null;
155:
156: /**
157: * The request URI for this request.
158: */
159: protected String requestURI = null;
160:
161: /**
162: * The servlet path for this request.
163: */
164: protected String servletPath = null;
165:
166: /**
167: * The string manager for this package.
168: */
169: protected static StringManager sm = StringManager
170: .getManager(Constants.Package);
171:
172: // ------------------------------------------------- ServletRequest Methods
173:
174: /**
175: * Override the <code>getAttribute()</code> method of the wrapped request.
176: *
177: * @param name Name of the attribute to retrieve
178: */
179: public Object getAttribute(String name) {
180:
181: synchronized (attributes) {
182: return (attributes.get(name));
183: }
184:
185: }
186:
187: /**
188: * Override the <code>getAttributeNames()</code> method of the wrapped
189: * request.
190: */
191: public Enumeration getAttributeNames() {
192:
193: synchronized (attributes) {
194: return (new Enumerator(attributes.keySet()));
195: }
196:
197: }
198:
199: /**
200: * Override the <code>removeAttribute()</code> method of the
201: * wrapped request.
202: *
203: * @param name Name of the attribute to remove
204: */
205: public void removeAttribute(String name) {
206:
207: synchronized (attributes) {
208: attributes.remove(name);
209: if (!isSpecial(name))
210: getRequest().removeAttribute(name);
211: }
212:
213: }
214:
215: /**
216: * Override the <code>setAttribute()</code> method of the
217: * wrapped request.
218: *
219: * @param name Name of the attribute to set
220: * @param value Value of the attribute to set
221: */
222: public void setAttribute(String name, Object value) {
223:
224: synchronized (attributes) {
225: attributes.put(name, value);
226: if (!isSpecial(name))
227: getRequest().setAttribute(name, value);
228: }
229:
230: }
231:
232: // --------------------------------------------- HttpServletRequest Methods
233:
234: /**
235: * Override the <code>getContextPath()</code> method of the wrapped
236: * request.
237: */
238: public String getContextPath() {
239:
240: return (this .contextPath);
241:
242: }
243:
244: /**
245: * Override the <code>getParameter()</code> method of the wrapped request.
246: *
247: * @param name Name of the requested parameter
248: */
249: public String getParameter(String name) {
250:
251: synchronized (parameters) {
252: Object value = parameters.get(name);
253: if (value == null)
254: return (null);
255: else if (value instanceof String[])
256: return (((String[]) value)[0]);
257: else if (value instanceof String)
258: return ((String) value);
259: else
260: return (value.toString());
261: }
262:
263: }
264:
265: /**
266: * Override the <code>getParameterMap()</code> method of the
267: * wrapped request.
268: */
269: public Map getParameterMap() {
270:
271: return (parameters);
272:
273: }
274:
275: /**
276: * Override the <code>getParameterNames()</code> method of the
277: * wrapped request.
278: */
279: public Enumeration getParameterNames() {
280:
281: synchronized (parameters) {
282: return (new Enumerator(parameters.keySet()));
283: }
284:
285: }
286:
287: /**
288: * Override the <code>getParameterValues()</code> method of the
289: * wrapped request.
290: *
291: * @param name Name of the requested parameter
292: */
293: public String[] getParameterValues(String name) {
294:
295: synchronized (parameters) {
296: Object value = parameters.get(name);
297: if (value == null)
298: return ((String[]) null);
299: else if (value instanceof String[])
300: return ((String[]) value);
301: else if (value instanceof String) {
302: String values[] = new String[1];
303: values[0] = (String) value;
304: return (values);
305: } else {
306: String values[] = new String[1];
307: values[0] = value.toString();
308: return (values);
309: }
310: }
311:
312: }
313:
314: /**
315: * Override the <code>getPathInfo()</code> method of the wrapped request.
316: */
317: public String getPathInfo() {
318:
319: return (this .pathInfo);
320:
321: }
322:
323: /**
324: * Override the <code>getQueryString()</code> method of the wrapped
325: * request.
326: */
327: public String getQueryString() {
328:
329: return (this .queryString);
330:
331: }
332:
333: /**
334: * Override the <code>getRequestURI()</code> method of the wrapped
335: * request.
336: */
337: public String getRequestURI() {
338:
339: return (this .requestURI);
340:
341: }
342:
343: /**
344: * Override the <code>getServletPath()</code> method of the wrapped
345: * request.
346: */
347: public String getServletPath() {
348:
349: return (this .servletPath);
350:
351: }
352:
353: // -------------------------------------------------------- Package Methods
354:
355: /**
356: * Return descriptive information about this implementation.
357: */
358: public String getInfo() {
359:
360: return (this .info);
361:
362: }
363:
364: /**
365: * Perform a shallow copy of the specified Map, and return the result.
366: *
367: * @param orig Origin Map to be copied
368: */
369: Map copyMap(Map orig) {
370:
371: if (orig == null)
372: return (new HashMap());
373: HashMap dest = new HashMap();
374: synchronized (orig) {
375: Iterator keys = orig.keySet().iterator();
376: while (keys.hasNext()) {
377: String key = (String) keys.next();
378: dest.put(key, orig.get(key));
379: }
380: }
381: return (dest);
382:
383: }
384:
385: /**
386: * Merge the parameters from the specified query string (if any), and
387: * the parameters already present on this request (if any), such that
388: * the parameter values from the query string show up first if there are
389: * duplicate parameter names.
390: *
391: * @param queryString The query string containing parameters to be merged
392: */
393: void mergeParameters(String queryString) {
394:
395: if ((queryString == null) || (queryString.length() < 1))
396: return;
397:
398: HashMap queryParameters = new HashMap();
399: String encoding = getCharacterEncoding();
400: if (encoding == null)
401: encoding = "ISO-8859-1";
402: try {
403: RequestUtil.parseParameters(queryParameters, queryString,
404: encoding);
405: } catch (Exception e) {
406: ;
407: }
408: synchronized (parameters) {
409: Iterator keys = parameters.keySet().iterator();
410: while (keys.hasNext()) {
411: String key = (String) keys.next();
412: Object value = queryParameters.get(key);
413: if (value == null) {
414: queryParameters.put(key, parameters.get(key));
415: continue;
416: }
417: queryParameters.put(key, mergeValues(value, parameters
418: .get(key)));
419: }
420: parameters = queryParameters;
421: }
422:
423: }
424:
425: /**
426: * Set the context path for this request.
427: *
428: * @param contextPath The new context path
429: */
430: void setContextPath(String contextPath) {
431:
432: this .contextPath = contextPath;
433:
434: }
435:
436: /**
437: * Set the path information for this request.
438: *
439: * @param pathInfo The new path info
440: */
441: void setPathInfo(String pathInfo) {
442:
443: this .pathInfo = pathInfo;
444:
445: }
446:
447: /**
448: * Set the query string for this request.
449: *
450: * @param queryString The new query string
451: */
452: void setQueryString(String queryString) {
453:
454: this .queryString = queryString;
455:
456: }
457:
458: /**
459: * Set the request that we are wrapping.
460: *
461: * @param request The new wrapped request
462: */
463: void setRequest(HttpServletRequest request) {
464:
465: super .setRequest(request);
466:
467: // Initialize the attributes for this request
468: synchronized (attributes) {
469: attributes.clear();
470: Enumeration names = request.getAttributeNames();
471: while (names.hasMoreElements()) {
472: String name = (String) names.nextElement();
473: if (!(Globals.REQUEST_URI_ATTR.equals(name) || Globals.SERVLET_PATH_ATTR
474: .equals(name))) {
475: Object value = request.getAttribute(name);
476: attributes.put(name, value);
477: }
478: }
479: }
480:
481: // Initialize the parameters for this request
482: synchronized (parameters) {
483: parameters = copyMap(request.getParameterMap());
484: }
485:
486: // Initialize the path elements for this request
487: contextPath = request.getContextPath();
488: pathInfo = request.getPathInfo();
489: queryString = request.getQueryString();
490: requestURI = request.getRequestURI();
491: servletPath = request.getServletPath();
492:
493: }
494:
495: /**
496: * Set the request URI for this request.
497: *
498: * @param requestURI The new request URI
499: */
500: void setRequestURI(String requestURI) {
501:
502: this .requestURI = requestURI;
503:
504: }
505:
506: /**
507: * Set the servlet path for this request.
508: *
509: * @param servletPath The new servlet path
510: */
511: void setServletPath(String servletPath) {
512:
513: this .servletPath = servletPath;
514:
515: }
516:
517: // ------------------------------------------------------ Protected Methods
518:
519: /**
520: * Is this attribute name one of the special ones that is added only for
521: * included servlets?
522: *
523: * @param name Attribute name to be tested
524: */
525: protected boolean isSpecial(String name) {
526:
527: for (int i = 0; i < specials.length; i++) {
528: if (specials[i].equals(name))
529: return (true);
530: }
531: return (false);
532:
533: }
534:
535: /**
536: * Merge the two sets of parameter values into a single String array.
537: *
538: * @param values1 First set of values
539: * @param values2 Second set of values
540: */
541: protected String[] mergeValues(Object values1, Object values2) {
542:
543: ArrayList results = new ArrayList();
544:
545: if (values1 == null)
546: ;
547: else if (values1 instanceof String)
548: results.add(values1);
549: else if (values1 instanceof String[]) {
550: String values[] = (String[]) values1;
551: for (int i = 0; i < values.length; i++)
552: results.add(values[i]);
553: } else
554: results.add(values1.toString());
555:
556: if (values2 == null)
557: ;
558: else if (values2 instanceof String)
559: results.add(values2);
560: else if (values2 instanceof String[]) {
561: String values[] = (String[]) values2;
562: for (int i = 0; i < values.length; i++)
563: results.add(values[i]);
564: } else
565: results.add(values2.toString());
566:
567: String values[] = new String[results.size()];
568: return ((String[]) results.toArray(values));
569:
570: }
571:
572: }
|