001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019: package de.schlund.pfixxml;
020:
021: import java.util.ArrayList;
022: import java.util.Enumeration;
023: import java.util.HashMap;
024: import java.util.HashSet;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Properties;
028:
029: import javax.servlet.http.Cookie;
030: import javax.servlet.http.HttpServletRequest;
031: import javax.servlet.http.HttpSession;
032:
033: import org.apache.log4j.Logger;
034:
035: import de.schlund.pfixxml.multipart.MultipartHandler;
036: import de.schlund.pfixxml.multipart.PartData;
037: import de.schlund.pfixxml.perflogging.PerfEvent;
038: import de.schlund.pfixxml.perflogging.PerfEventType;
039: import de.schlund.pfixxml.serverutil.SessionHelper;
040:
041: /**
042: * <p>This class is an abstraction of a servlet request. Is provides wrapper functions
043: * on a {@link javax.servlet.http.HttpServletRequest} but has also the possibility
044: * to update the request and to retrieve both the current and orginal data.
045: * Classes in the Pustefix system should use this class and not a
046: * <code>HttpServletRequest</code>.</p>
047: * <p>Note: All method with a 'getOrginal' prefix work on the orginal request,
048: * all others methods work on the currently set request, which may
049: * be the original request used when the instance was created, or
050: * any other request that has been set via <code>updateRequest()</code>.</p>
051: *
052: *
053: * Created: Tue May 7 23:55:50 2002
054: *
055: * @author <a href="mailto:jtl@schlund.de">Jens Lautenbacher</a>
056: */
057: public class PfixServletRequestImpl implements PfixServletRequest {
058:
059: //~ Instance/static variables ..................................................................
060:
061: private static final String SBMT_PREFIX = "__SBMT:";
062: private static final String SYNT_PREFIX = "__SYNT:";
063: private static final String PROP_TMPDIR = "pfixservletrequest.tmpdir";
064: private static final String PROP_MAXPARTSIZE = "pfixservletrequest.maxpartsize";
065: private static final String ATTR_LASTEXCEPTION = "REQ_LASTEXCEPTION";
066: private static final String DEF_MAXPARTSIZE = ""
067: + (10 * 1024 * 1024); // 10 MB
068: private HashMap<String, RequestParam[]> parameters = new HashMap<String, RequestParam[]>();
069: private Logger LOG = Logger.getLogger(this .getClass());
070: private List<Exception> multiPartExceptions = new ArrayList<Exception>();
071: private String servername;
072: private String querystring;
073: private String scheme;
074: private String uri;
075: private HttpSession session = null;
076: private int serverport;
077: private HttpServletRequest request;
078: private long starttime = 0;
079:
080: /* (non-Javadoc)
081: * @see de.schlund.pfixxml.PfixServletRequest#getCreationTimeStamp()
082: */
083: public long getCreationTimeStamp() {
084: return starttime;
085: }
086:
087: //~ Constructors ...............................................................................
088:
089: /**
090: * Constructor for creating a PfixServletRequest
091: * @param req the orginal servlet request
092: * @param properties
093: * @param cUtil
094: */
095: public PfixServletRequestImpl(HttpServletRequest req,
096: Properties properties) {
097: PerfEvent pe = new PerfEvent(
098: PerfEventType.PFIXSERVLETREQUEST_INIT);
099: pe.start();
100:
101: starttime = System.currentTimeMillis();
102: getRequestParams(req, properties);
103: servername = req.getServerName();
104: querystring = req.getQueryString();
105: scheme = req.getScheme();
106: uri = req.getRequestURI();
107: serverport = req.getServerPort();
108: request = req;
109: session = req.getSession(false);
110:
111: pe.setIdentfier(uri);
112: pe.save();
113: }
114:
115: //~ Methods ....................................................................................
116:
117: /* (non-Javadoc)
118: * @see de.schlund.pfixxml.PfixServletRequest#getLastException()
119: */
120: public Throwable getLastException() {
121: return (Throwable) request.getAttribute(ATTR_LASTEXCEPTION);
122: }
123:
124: /* (non-Javadoc)
125: * @see de.schlund.pfixxml.PfixServletRequest#setLastException(java.lang.Throwable)
126: */
127: public void setLastException(Throwable lastException) {
128: request.setAttribute(ATTR_LASTEXCEPTION, lastException);
129: }
130:
131: /* (non-Javadoc)
132: * @see de.schlund.pfixxml.PfixServletRequest#getOriginalServerName()
133: */
134: public String getOriginalServerName() {
135: return servername;
136: }
137:
138: /* (non-Javadoc)
139: * @see de.schlund.pfixxml.PfixServletRequest#getOriginalQueryString()
140: */
141: public String getOriginalQueryString() {
142: return querystring;
143: }
144:
145: /* (non-Javadoc)
146: * @see de.schlund.pfixxml.PfixServletRequest#getOriginalScheme()
147: */
148: public String getOriginalScheme() {
149: return scheme;
150: }
151:
152: /* (non-Javadoc)
153: * @see de.schlund.pfixxml.PfixServletRequest#getOriginalRequestURI()
154: */
155: public String getOriginalRequestURI() {
156: return uri;
157: }
158:
159: /* (non-Javadoc)
160: * @see de.schlund.pfixxml.PfixServletRequest#getOriginalServerPort()
161: */
162: public int getOriginalServerPort() {
163: return serverport;
164: }
165:
166: /* (non-Javadoc)
167: * @see de.schlund.pfixxml.PfixServletRequest#updateRequest(javax.servlet.http.HttpServletRequest)
168: */
169: public void updateRequest(HttpServletRequest req) {
170: this .request = req;
171: this .session = req.getSession(false);
172: }
173:
174: /* (non-Javadoc)
175: * @see de.schlund.pfixxml.PfixServletRequest#getRequest()
176: */
177: public HttpServletRequest getRequest() {
178: return request;
179: }
180:
181: /* (non-Javadoc)
182: * @see de.schlund.pfixxml.PfixServletRequest#errorHappened()
183: */
184: public boolean errorHappened() {
185: return !multiPartExceptions.isEmpty();
186: }
187:
188: /* (non-Javadoc)
189: * @see de.schlund.pfixxml.PfixServletRequest#getAllExceptions()
190: */
191: public List<Exception> getAllExceptions() {
192: return multiPartExceptions;
193: }
194:
195: // All these methods work on the currently set request, which may
196: // be the original request used when the instance was created, or
197: // any other request that has been set via updateRequest().
198: // Most are just called as the corresponding methods in HttpServletRequest.
199:
200: /* (non-Javadoc)
201: * @see de.schlund.pfixxml.PfixServletRequest#getCookies()
202: */
203: public Cookie[] getCookies() {
204: return request.getCookies();
205: }
206:
207: /* (non-Javadoc)
208: * @see de.schlund.pfixxml.PfixServletRequest#getPathInfo()
209: */
210: public String getPathInfo() {
211: return request.getPathInfo();
212: }
213:
214: /* (non-Javadoc)
215: * @see de.schlund.pfixxml.PfixServletRequest#getPathTranslated()
216: */
217: public String getPathTranslated() {
218: return request.getPathTranslated();
219: }
220:
221: /* (non-Javadoc)
222: * @see de.schlund.pfixxml.PfixServletRequest#getQueryString()
223: */
224: public String getQueryString() {
225: return request.getQueryString();
226: }
227:
228: /* (non-Javadoc)
229: * @see de.schlund.pfixxml.PfixServletRequest#getRequestedSessionId()
230: */
231: public String getRequestedSessionId() {
232: return request.getRequestedSessionId();
233: }
234:
235: /* (non-Javadoc)
236: * @see de.schlund.pfixxml.PfixServletRequest#getRequestURI()
237: */
238: public String getRequestURI() {
239: return SessionHelper.encodeURI(request);
240: }
241:
242: /* (non-Javadoc)
243: * @see de.schlund.pfixxml.PfixServletRequest#getContextPath()
244: */
245: public String getContextPath() {
246: return request.getContextPath();
247: }
248:
249: /* (non-Javadoc)
250: * @see de.schlund.pfixxml.PfixServletRequest#getServletPath()
251: */
252: public String getServletPath() {
253: return request.getServletPath();
254: }
255:
256: /* (non-Javadoc)
257: * @see de.schlund.pfixxml.PfixServletRequest#getSession(boolean)
258: */
259: public HttpSession getSession(boolean create) {
260: if (!create) {
261: return session;
262: } else {
263: return request.getSession(true);
264: }
265: }
266:
267: /* (non-Javadoc)
268: * @see de.schlund.pfixxml.PfixServletRequest#isRequestedSessionIdValid()
269: */
270: public boolean isRequestedSessionIdValid() {
271: return request.isRequestedSessionIdValid();
272: }
273:
274: /* (non-Javadoc)
275: * @see de.schlund.pfixxml.PfixServletRequest#getRemoteAddr()
276: */
277: public String getRemoteAddr() {
278: return request.getRemoteAddr();
279: }
280:
281: /* (non-Javadoc)
282: * @see de.schlund.pfixxml.PfixServletRequest#getRemoteHost()
283: */
284: public String getRemoteHost() {
285: return request.getRemoteHost();
286: }
287:
288: /* (non-Javadoc)
289: * @see de.schlund.pfixxml.PfixServletRequest#getScheme()
290: */
291: public String getScheme() {
292: return request.getScheme();
293: }
294:
295: /* (non-Javadoc)
296: * @see de.schlund.pfixxml.PfixServletRequest#getServerPort()
297: */
298: public int getServerPort() {
299: return request.getServerPort();
300: }
301:
302: /* (non-Javadoc)
303: * @see de.schlund.pfixxml.PfixServletRequest#getServerName()
304: */
305: public String getServerName() {
306: return request.getServerName();
307: }
308:
309: /* (non-Javadoc)
310: * @see de.schlund.pfixxml.PfixServletRequest#getServletName()
311: */
312: public String getServletName() {
313: return request.getServletPath();
314: }
315:
316: /* (non-Javadoc)
317: * @see de.schlund.pfixxml.PfixServletRequest#getRequestParam(java.lang.String)
318: */
319: public RequestParam getRequestParam(String name) {
320: RequestParam[] params = (RequestParam[]) parameters.get(name);
321: if (params != null && params.length > 0) {
322: return params[0];
323: } else {
324: return null;
325: }
326: }
327:
328: /* (non-Javadoc)
329: * @see de.schlund.pfixxml.PfixServletRequest#getAllRequestParams(java.lang.String)
330: */
331: public RequestParam[] getAllRequestParams(String name) {
332: RequestParam[] params = (RequestParam[]) parameters.get(name);
333: if (params != null) {
334: return params;
335: } else {
336: return null;
337: }
338: }
339:
340: // ---------------------------------- //
341:
342: /* (non-Javadoc)
343: * @see de.schlund.pfixxml.PfixServletRequest#getRequestParamNames()
344: */
345: public String[] getRequestParamNames() {
346: return (String[]) parameters.keySet().toArray(new String[] {});
347: }
348:
349: private void getRequestParams(HttpServletRequest req,
350: Properties properties) {
351: String type = req.getContentType();
352: HashSet<String> allnames = new HashSet<String>();
353: if (type != null
354: && type.toLowerCase().startsWith(
355: MultipartHandler.MULTI_FORM_DATA)) {
356: allnames.addAll(handleMulti(req, properties));
357: }
358: for (Enumeration<?> enm = req.getParameterNames(); enm
359: .hasMoreElements();) {
360: String key = (String) enm.nextElement();
361: allnames.add(key);
362: String[] data = req.getParameterValues(key);
363: LOG.debug("* [NORMAL] Found parameters for key '" + key
364: + "' count=" + data.length);
365: RequestParam[] multiparams = (RequestParam[]) parameters
366: .get(key);
367: RequestParam[] params;
368: if (multiparams == null) {
369: params = new RequestParam[data.length];
370: } else {
371: params = new RequestParam[data.length
372: + multiparams.length];
373: }
374: for (int i = 0; i < data.length; i++) {
375: RequestParam param = new SimpleRequestParam(data[i]);
376: LOG.debug(" " + i + ") Type: NORMAL Value: "
377: + param.getValue());
378: params[i] = param;
379: }
380: if (multiparams != null) {
381: LOG.debug(" **** MULTI is not null...");
382: for (int i = data.length; i < (data.length + multiparams.length); i++) {
383: PartData pdat = (PartData) multiparams[i
384: - data.length];
385: LOG.debug(" " + i + ") Type: "
386: + pdat.getType() + " Value: "
387: + pdat.getValue());
388: params[i] = multiparams[i - data.length];
389: }
390: }
391: parameters.put(key, params);
392: }
393: generateSynthetics(req, allnames);
394: }
395:
396: private HashSet<String> handleMulti(HttpServletRequest req,
397: Properties properties) {
398: String tmpdir = properties.getProperty(PROP_TMPDIR);
399: HashSet<String> names = new HashSet<String>();
400: if (tmpdir == null || tmpdir.equals("")) {
401: tmpdir = System
402: .getProperty(AbstractXMLServlet.DEF_PROP_TMPDIR);
403: }
404:
405: String maxsize = properties.getProperty(PROP_MAXPARTSIZE);
406: if (maxsize == null || maxsize.equals("")) {
407: maxsize = DEF_MAXPARTSIZE;
408: }
409: MultipartHandler multi = new MultipartHandler(req, tmpdir);
410: multi.setMaxPartSize((new Long(maxsize)).longValue());
411: try {
412: multi.parseRequest();
413: multiPartExceptions.addAll(multi.getExceptionList());
414: } catch (Exception e) {
415: multiPartExceptions.add(e);
416: }
417: for (Enumeration<String> enm = multi.getParameterNames(); enm
418: .hasMoreElements();) {
419: String key = (String) enm.nextElement();
420: names.add(key);
421: List<PartData> values = multi.getAllParameter(key);
422: PartData[] data = values.toArray(new PartData[] {});
423: LOG.debug("* [MULTI] Found parameters for key '" + key
424: + "' count=" + data.length);
425: for (int i = 0; i < data.length; i++) {
426: PartData tmp = data[i];
427: LOG.debug(" " + i + ") Type: " + tmp.getType()
428: + " Value: " + tmp.getValue());
429: }
430: parameters.put(key, data);
431: }
432: return names;
433: }
434:
435: private void generateSynthetics(HttpServletRequest req,
436: HashSet<String> allnames) {
437: HashSet<String> prefixes = new HashSet<String>();
438: for (Iterator<String> i = allnames.iterator(); i.hasNext();) {
439: String name = i.next();
440: if (name.startsWith(SBMT_PREFIX)) {
441: int start = SBMT_PREFIX.length();
442: int end = name.lastIndexOf(":");
443: if (end > start) {
444: String prefix = name.substring(start, end);
445: if (prefix != null && !prefix.equals("")) {
446: prefixes.add(prefix);
447: }
448: }
449: }
450: }
451: for (Iterator<String> i = prefixes.iterator(); i.hasNext();) {
452: String prefix = SYNT_PREFIX + i.next() + ":";
453: for (Iterator<String> j = allnames.iterator(); j.hasNext();) {
454: String name = j.next();
455: if (name.startsWith(prefix)
456: && (name.length() > prefix.length())) {
457: String key = name.substring(prefix.length());
458: RequestParam[] values = parameters.get(name);
459: LOG.debug(" * [EMB/" + name + "] >> Key is "
460: + key);
461: if (values != null && values.length > 0) {
462: RequestParam[] newvals = new RequestParam[values.length];
463: for (int k = 0; k < values.length; k++) {
464: LOG.debug(" Adding value: "
465: + values[k].getValue());
466: newvals[k] = new SimpleRequestParam(
467: values[k].getValue());
468: newvals[k].setSynthetic(true);
469: }
470: // Eeeek, how to concatenate arrays in an elegant way?
471: RequestParam[] oldvals = parameters.get(key);
472: RequestParam[] finvals = newvals;
473: if (oldvals != null && oldvals.length > 0) {
474: finvals = new RequestParam[oldvals.length
475: + newvals.length];
476: for (int k = 0; k < newvals.length; k++) {
477: finvals[k] = newvals[k];
478: }
479: for (int k = 0; k < oldvals.length; k++) {
480: finvals[k + newvals.length] = oldvals[k];
481: }
482: }
483: parameters.put(key, finvals);
484: }
485: }
486: }
487: }
488: }
489:
490: /* (non-Javadoc)
491: * @see de.schlund.pfixxml.PfixServletRequest#getPageName()
492: */
493: public String getPageName() {
494: String pagename = "";
495: String pathinfo = getPathInfo();
496: RequestParam name = getRequestParam(PAGEPARAM);
497: if (name != null && !name.getValue().equals("")) {
498: pagename = name.getValue();
499: } else if (pathinfo != null && !pathinfo.equals("")
500: && pathinfo.startsWith("/") && pathinfo.length() > 1) {
501: pagename = pathinfo.substring(1);
502: } else {
503: return null;
504: }
505: // We must remove any '::' that may have slipped in through the request
506: if (pagename.indexOf("::") > 0) {
507: pagename = pagename.substring(0, pagename.indexOf("::"));
508: }
509: if (pagename.length() > 0) {
510: return pagename;
511: } else {
512: return null;
513: }
514: }
515:
516: } // PfixServletRequest
|