KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > base > util > UtilHttp


1 /*
2  * $Id: UtilHttp.java 7099 2006-03-28 23:02:54Z jonesde $
3  *
4  * Copyright (c) 2001-2005 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24 package org.ofbiz.base.util;
25
26 import java.io.BufferedInputStream JavaDoc;
27 import java.io.BufferedOutputStream JavaDoc;
28 import java.io.ByteArrayInputStream JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.InputStream JavaDoc;
31 import java.io.OutputStream JavaDoc;
32 import java.io.UnsupportedEncodingException JavaDoc;
33 import java.net.FileNameMap JavaDoc;
34 import java.net.URLConnection JavaDoc;
35 import java.net.URLEncoder JavaDoc;
36 import java.sql.Timestamp JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.Arrays JavaDoc;
39 import java.util.Calendar JavaDoc;
40 import java.util.Collection JavaDoc;
41 import java.util.Currency JavaDoc;
42 import java.util.Enumeration JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.util.HashSet JavaDoc;
45 import java.util.Iterator JavaDoc;
46 import java.util.List JavaDoc;
47 import java.util.Locale JavaDoc;
48 import java.util.Map JavaDoc;
49 import java.util.Set JavaDoc;
50 import java.util.StringTokenizer JavaDoc;
51
52 import javax.servlet.http.HttpServletRequest JavaDoc;
53 import javax.servlet.http.HttpServletResponse JavaDoc;
54 import javax.servlet.http.HttpSession JavaDoc;
55
56 import javolution.util.FastList;
57 import javolution.util.FastMap;
58
59 /**
60  * HttpUtil - Misc TTP Utility Functions
61  *
62  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
63  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
64  * @version $Rev: 7099 $
65  * @since 2.1
66  */

67 public class UtilHttp {
68
69     public static final String JavaDoc module = UtilHttp.class.getName();
70
71     public static final String JavaDoc MULTI_ROW_DELIMITER = "_o_";
72     public static final String JavaDoc ROW_SUBMIT_PREFIX = "_rowSubmit_o_";
73     public static final String JavaDoc COMPOSITE_DELIMITER = "_c_";
74     public static final int MULTI_ROW_DELIMITER_LENGTH = MULTI_ROW_DELIMITER.length();
75     public static final int ROW_SUBMIT_PREFIX_LENGTH = ROW_SUBMIT_PREFIX.length();
76     public static final int COMPOSITE_DELIMITER_LENGTH = COMPOSITE_DELIMITER.length();
77     
78
79     /**
80      * Create a map from an HttpServletRequest object
81      * @return The resulting Map
82      */

83     public static Map JavaDoc getParameterMap(HttpServletRequest JavaDoc request) {
84         Map JavaDoc paramMap = FastMap.newInstance();
85
86         // add all the actual HTTP request parameters
87
Enumeration JavaDoc e = request.getParameterNames();
88         while (e.hasMoreElements()) {
89             String JavaDoc name = (String JavaDoc) e.nextElement();
90             Object JavaDoc value = null;
91             String JavaDoc[] paramArr = request.getParameterValues(name);
92             if (paramArr != null) {
93                 if (paramArr.length > 1) {
94                     value = Arrays.asList(paramArr);
95                 } else {
96                     value = paramArr[0];
97                     // does the same thing basically, nothing better about it as far as I can see: value = request.getParameter(name);
98
}
99             }
100             paramMap.put(name, value);
101         }
102
103         // now add in all path info parameters /~name1=value1/~name2=value2/
104
// note that if a parameter with a given name already exists it will be put into a list with all values
105
String JavaDoc pathInfoStr = request.getPathInfo();
106
107         if (pathInfoStr != null && pathInfoStr.length() > 0) {
108             // make sure string ends with a trailing '/' so we get all values
109
if (!pathInfoStr.endsWith("/")) pathInfoStr += "/";
110
111             int current = pathInfoStr.indexOf('/');
112             int last = current;
113             while ((current = pathInfoStr.indexOf('/', last + 1)) != -1) {
114                 String JavaDoc element = pathInfoStr.substring(last + 1, current);
115                 last = current;
116                 if (element.charAt(0) == '~' && element.indexOf('=') > -1) {
117                     String JavaDoc name = element.substring(1, element.indexOf('='));
118                     String JavaDoc value = element.substring(element.indexOf('=') + 1);
119                     Object JavaDoc curValue = paramMap.get(name);
120                     if (curValue != null) {
121                         List JavaDoc paramList = null;
122                         if (curValue instanceof List JavaDoc) {
123                             paramList = (List JavaDoc) curValue;
124                             paramList.add(value);
125                         } else {
126                             String JavaDoc paramString = (String JavaDoc) curValue;
127                             paramList = FastList.newInstance();
128                             paramList.add(paramString);
129                             paramList.add(value);
130                         }
131                         paramMap.put(name, paramList);
132                     } else {
133                         paramMap.put(name, value);
134                     }
135                 }
136             }
137         }
138
139         if (paramMap.size() == 0) {
140             // nothing found in the parameters; maybe we read the stream instead
141
Map JavaDoc multiPartMap = (Map JavaDoc) request.getAttribute("multiPartMap");
142             if (multiPartMap != null && multiPartMap.size() > 0) {
143                 paramMap.putAll(multiPartMap);
144             }
145         }
146         
147         //Debug.logInfo("Made parameterMap: \n" + UtilMisc.printMap(paramMap), module);
148
if (Debug.verboseOn()) {
149             Debug.logVerbose("Made Request Parameter Map with [" + paramMap.size() + "] Entries", module);
150             Iterator JavaDoc entryIter = paramMap.entrySet().iterator();
151             while (entryIter.hasNext()) {
152                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entryIter.next();
153                 Debug.logVerbose("Request Parameter Map Entry: [" + entry.getKey() + "] --> " + entry.getValue(), module);
154             }
155         }
156         
157         return paramMap;
158     }
159
160     public static Map JavaDoc makeParamMapWithPrefix(HttpServletRequest JavaDoc request, String JavaDoc prefix, String JavaDoc suffix) {
161         return makeParamMapWithPrefix(request, null, prefix, suffix);
162     }
163
164     public static Map JavaDoc makeParamMapWithPrefix(HttpServletRequest JavaDoc request, Map JavaDoc additionalFields, String JavaDoc prefix, String JavaDoc suffix) {
165         Map JavaDoc paramMap = new HashMap JavaDoc();
166         Enumeration JavaDoc parameterNames = request.getParameterNames();
167         while (parameterNames.hasMoreElements()) {
168             String JavaDoc parameterName = (String JavaDoc) parameterNames.nextElement();
169             if (parameterName.startsWith(prefix)) {
170                 if (suffix != null && suffix.length() > 0) {
171                     if (parameterName.endsWith(suffix)) {
172                         String JavaDoc key = parameterName.substring(prefix.length(), parameterName.length() - (suffix.length()));
173                         String JavaDoc value = request.getParameter(parameterName);
174                         paramMap.put(key, value);
175                     }
176                 } else {
177                     String JavaDoc key = parameterName.substring(prefix.length());
178                     String JavaDoc value = request.getParameter(parameterName);
179                     paramMap.put(key, value);
180                 }
181             }
182         }
183         if (additionalFields != null) {
184             Iterator JavaDoc i = additionalFields.keySet().iterator();
185             while (i.hasNext()) {
186                 String JavaDoc fieldName = (String JavaDoc) i.next();
187                 if (fieldName.startsWith(prefix)) {
188                     if (suffix != null && suffix.length() > 0) {
189                         if (fieldName.endsWith(suffix)) {
190                             String JavaDoc key = fieldName.substring(prefix.length(), fieldName.length() - (suffix.length() - 1));
191                             Object JavaDoc value = additionalFields.get(fieldName);
192                             paramMap.put(key, value);
193
194                             // check for image upload data
195
if (!(value instanceof String JavaDoc)) {
196                                 String JavaDoc nameKey = "_" + key + "_fileName";
197                                 Object JavaDoc nameVal = additionalFields.get("_" + fieldName + "_fileName");
198                                 if (nameVal != null) {
199                                     paramMap.put(nameKey, nameVal);
200                                 }
201
202                                 String JavaDoc typeKey = "_" + key + "_contentType";
203                                 Object JavaDoc typeVal = additionalFields.get("_" + fieldName + "_contentType");
204                                 if (typeVal != null) {
205                                     paramMap.put(typeKey, typeVal);
206                                 }
207
208                                 String JavaDoc sizeKey = "_" + key + "_size";
209                                 Object JavaDoc sizeVal = additionalFields.get("_" + fieldName + "_size");
210                                 if (sizeVal != null) {
211                                     paramMap.put(sizeKey, sizeVal);
212                                 }
213                             }
214                         }
215                     } else {
216                         String JavaDoc key = fieldName.substring(prefix.length());
217                         Object JavaDoc value = additionalFields.get(fieldName);
218                         paramMap.put(key, value);
219
220                         // check for image upload data
221
if (!(value instanceof String JavaDoc)) {
222                             String JavaDoc nameKey = "_" + key + "_fileName";
223                             Object JavaDoc nameVal = additionalFields.get("_" + fieldName + "_fileName");
224                             if (nameVal != null) {
225                                 paramMap.put(nameKey, nameVal);
226                             }
227
228                             String JavaDoc typeKey = "_" + key + "_contentType";
229                             Object JavaDoc typeVal = additionalFields.get("_" + fieldName + "_contentType");
230                             if (typeVal != null) {
231                                 paramMap.put(typeKey, typeVal);
232                             }
233
234                             String JavaDoc sizeKey = "_" + key + "_size";
235                             Object JavaDoc sizeVal = additionalFields.get("_" + fieldName + "_size");
236                             if (sizeVal != null) {
237                                 paramMap.put(sizeKey, sizeVal);
238                             }
239                         }
240                     }
241                 }
242             }
243         }
244         return paramMap;
245     }
246
247     public static List JavaDoc makeParamListWithSuffix(HttpServletRequest JavaDoc request, String JavaDoc suffix, String JavaDoc prefix) {
248         return makeParamListWithSuffix(request, null, suffix, prefix);
249     }
250
251     public static List JavaDoc makeParamListWithSuffix(HttpServletRequest JavaDoc request, Map JavaDoc additionalFields, String JavaDoc suffix, String JavaDoc prefix) {
252         List JavaDoc paramList = new ArrayList JavaDoc();
253         Enumeration JavaDoc parameterNames = request.getParameterNames();
254         while (parameterNames.hasMoreElements()) {
255             String JavaDoc parameterName = (String JavaDoc) parameterNames.nextElement();
256             if (parameterName.endsWith(suffix)) {
257                 if (prefix != null && prefix.length() > 0) {
258                     if (parameterName.startsWith(prefix)) {
259                         String JavaDoc value = request.getParameter(parameterName);
260                         paramList.add(value);
261                     }
262                 } else {
263                     String JavaDoc value = request.getParameter(parameterName);
264                     paramList.add(value);
265                 }
266             }
267         }
268         if (additionalFields != null) {
269             Iterator JavaDoc i = additionalFields.keySet().iterator();
270             while (i.hasNext()) {
271                 String JavaDoc fieldName = (String JavaDoc) i.next();
272                 if (fieldName.endsWith(suffix)) {
273                     if (prefix != null && prefix.length() > 0) {
274                         if (fieldName.startsWith(prefix)) {
275                             Object JavaDoc value = additionalFields.get(fieldName);
276                             paramList.add(value);
277                         }
278                     } else {
279                         Object JavaDoc value = additionalFields.get(fieldName);
280                         paramList.add(value);
281                     }
282                 }
283             }
284         }
285         return paramList;
286     }
287
288     /**
289      * Given a request, returns the application name or "root" if deployed on root
290      * @param request An HttpServletRequest to get the name info from
291      * @return String
292      */

293     public static String JavaDoc getApplicationName(HttpServletRequest JavaDoc request) {
294         String JavaDoc appName = "root";
295         if (request.getContextPath().length() > 1) {
296             appName = request.getContextPath().substring(1);
297         }
298         return appName;
299     }
300
301     /**
302      * Put request parameters in request object as attributes.
303      * @param request
304      */

305     public static void parametersToAttributes(HttpServletRequest JavaDoc request) {
306         java.util.Enumeration JavaDoc e = request.getParameterNames();
307         while (e.hasMoreElements()) {
308             String JavaDoc name = (String JavaDoc) e.nextElement();
309             request.setAttribute(name, request.getParameter(name));
310         }
311     }
312
313     public static StringBuffer JavaDoc getServerRootUrl(HttpServletRequest JavaDoc request) {
314         StringBuffer JavaDoc requestUrl = new StringBuffer JavaDoc();
315         requestUrl.append(request.getScheme());
316         requestUrl.append("://" + request.getServerName());
317         if (request.getServerPort() != 80 && request.getServerPort() != 443)
318             requestUrl.append(":" + request.getServerPort());
319         return requestUrl;
320     }
321
322     public static StringBuffer JavaDoc getFullRequestUrl(HttpServletRequest JavaDoc request) {
323         StringBuffer JavaDoc requestUrl = UtilHttp.getServerRootUrl(request);
324         requestUrl.append(request.getRequestURI());
325         if (request.getQueryString() != null) {
326             requestUrl.append("?" + request.getQueryString());
327         }
328         return requestUrl;
329     }
330
331     private static Locale JavaDoc getLocale(HttpServletRequest JavaDoc request, HttpSession JavaDoc session) {
332         // check session first, should override all if anything set there
333
Object JavaDoc localeObject = localeObject = session != null ? session.getAttribute("locale") : null;
334
335         // next see if the userLogin has a value
336
if (localeObject == null) {
337             Map JavaDoc userLogin = (Map JavaDoc) session.getAttribute("userLogin");
338             if (userLogin == null) {
339                 userLogin = (Map JavaDoc) session.getAttribute("autoUserLogin");
340             }
341
342             if (userLogin != null) {
343                 localeObject = userLogin.get("lastLocale");
344             }
345         }
346
347         // finally request (w/ a fall back to default)
348
if (localeObject == null) {
349             localeObject = request != null ? request.getLocale() : null;
350         }
351
352         return UtilMisc.ensureLocale(localeObject);
353     }
354
355     /**
356      * Get the Locale object from a session variable; if not found use the browser's default
357      * @param request HttpServletRequest object to use for lookup
358      * @return Locale The current Locale to use
359      */

360     public static Locale JavaDoc getLocale(HttpServletRequest JavaDoc request) {
361         if (request == null) return Locale.getDefault();
362         return UtilHttp.getLocale(request, request.getSession());
363     }
364
365     /**
366      * Get the Locale object from a session variable; if not found use the system's default.
367      * NOTE: This method is not recommended because it ignores the Locale from the browser not having the request object.
368      * @param session HttpSession object to use for lookup
369      * @return Locale The current Locale to use
370      */

371     public static Locale JavaDoc getLocale(HttpSession JavaDoc session) {
372         if (session == null) return Locale.getDefault();
373         return UtilHttp.getLocale(null, session);
374     }
375
376     public static void setLocale(HttpServletRequest JavaDoc request, String JavaDoc localeString) {
377         UtilHttp.setLocale(request.getSession(), UtilMisc.parseLocale(localeString));
378     }
379
380     public static void setLocale(HttpSession JavaDoc session, Locale JavaDoc locale) {
381         session.setAttribute("locale", locale);
382     }
383
384     public static void setLocaleIfNone(HttpSession JavaDoc session, String JavaDoc localeString) {
385         if (UtilValidate.isNotEmpty(localeString) && session.getAttribute("locale") == null) {
386             UtilHttp.setLocale(session, UtilMisc.parseLocale(localeString));
387         }
388     }
389
390     /**
391      * Get the currency string from the session.
392      * @param session HttpSession object to use for lookup
393      * @return String The ISO currency code
394      */

395     public static String JavaDoc getCurrencyUom(HttpSession JavaDoc session) {
396         // session, should override all if set there
397
String JavaDoc iso = (String JavaDoc) session.getAttribute("currencyUom");
398
399         // check userLogin next, ie if nothing to override in the session
400
if (iso == null) {
401             Map JavaDoc userLogin = (Map JavaDoc) session.getAttribute("userLogin");
402             if (userLogin == null) {
403                 userLogin = (Map JavaDoc) session.getAttribute("autoUserLogin");
404             }
405
406             if (userLogin != null) {
407                 iso = (String JavaDoc) userLogin.get("lastCurrencyUom");
408             }
409         }
410
411         // if none is set we will use the configured default
412
if (iso == null) {
413             try {
414                 iso = UtilProperties.getPropertyValue("general", "currency.uom.id.default", "USD");
415             } catch (Exception JavaDoc e) {
416                 Debug.logWarning("Error getting the general:currency.uom.id.default value: " + e.toString(), module);
417             }
418         }
419
420
421         // if still none we will use the default for whatever locale we can get...
422
if (iso == null) {
423             Currency JavaDoc cur = Currency.getInstance(getLocale(session));
424             iso = cur.getCurrencyCode();
425         }
426
427         return iso;
428     }
429
430     /**
431      * Get the currency string from the session.
432      * @param request HttpServletRequest object to use for lookup
433      * @return String The ISO currency code
434      */

435     public static String JavaDoc getCurrencyUom(HttpServletRequest JavaDoc request) {
436         return getCurrencyUom(request.getSession());
437     }
438
439     /** Simple event to set the users per-session currency uom value */
440     public static void setCurrencyUom(HttpSession JavaDoc session, String JavaDoc currencyUom) {
441         session.setAttribute("currencyUom", currencyUom);
442     }
443
444     public static void setCurrencyUomIfNone(HttpSession JavaDoc session, String JavaDoc currencyUom) {
445         if (UtilValidate.isNotEmpty(currencyUom) && session.getAttribute("currencyUom") == null) {
446             session.setAttribute("currencyUom", currencyUom);
447         }
448     }
449
450     /** URL Encodes a Map of arguements */
451     public static String JavaDoc urlEncodeArgs(Map JavaDoc args) {
452         return urlEncodeArgs(args, true);
453     }
454
455     /** URL Encodes a Map of arguements */
456     public static String JavaDoc urlEncodeArgs(Map JavaDoc args, boolean useExpandedEntites) {
457         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
458         if (args != null) {
459             Iterator JavaDoc i = args.entrySet().iterator();
460             while (i.hasNext()) {
461                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
462                 String JavaDoc name = (String JavaDoc) entry.getKey();
463                 Object JavaDoc value = entry.getValue();
464                 String JavaDoc valueStr = null;
465                 if (name != null && value != null) {
466                     if (value instanceof String JavaDoc) {
467                         valueStr = (String JavaDoc) value;
468                     } else {
469                         valueStr = value.toString();
470                     }
471
472                     if (valueStr != null && valueStr.length() > 0) {
473                         if (buf.length() > 0) {
474                             if (useExpandedEntites) {
475                                 buf.append("&amp;");
476                             } else {
477                                 buf.append("&");
478                             }
479                         }
480                         try {
481                             buf.append(URLEncoder.encode(name, "UTF-8"));
482                         } catch (UnsupportedEncodingException JavaDoc e) {
483                             Debug.logError(e, module);
484                         }
485                         buf.append('=');
486                         try {
487                             buf.append(URLEncoder.encode(valueStr, "UTF-8"));
488                         } catch (UnsupportedEncodingException JavaDoc e) {
489                             Debug.logError(e, module);
490                         }
491                     }
492                 }
493             }
494         }
495         return buf.toString();
496     }
497
498     public static String JavaDoc encodeAmpersands(String JavaDoc htmlString) {
499         StringBuffer JavaDoc htmlBuffer = new StringBuffer JavaDoc(htmlString);
500         int ampLoc = -1;
501         while ((ampLoc = htmlBuffer.indexOf("&", ampLoc + 1)) != -1) {
502             //NOTE: this should work fine, but if it doesn't could try making sure all characters between & and ; are letters, that would qualify as an entity
503

504             // found ampersand, is it already and entity? if not change it to &amp;
505
int semiLoc = htmlBuffer.indexOf(";", ampLoc);
506             if (semiLoc != -1) {
507                 // found a semi colon, if it has another & or an = before it, don't count it as an entity, otherwise it may be an entity, so skip it
508
int eqLoc = htmlBuffer.indexOf("=", ampLoc);
509                 int amp2Loc = htmlBuffer.indexOf("&", ampLoc + 1);
510                 if ((eqLoc == -1 || eqLoc > semiLoc) && (amp2Loc == -1 || amp2Loc > semiLoc)) {
511                     continue;
512                 }
513             }
514
515             // at this point not an entity, no substitute with a &amp;
516
htmlBuffer.insert(ampLoc + 1, "amp;");
517         }
518         return htmlBuffer.toString();
519     }
520
521     public static String JavaDoc encodeBlanks(String JavaDoc htmlString) {
522         return htmlString.replaceAll(" ", "%20");
523     }
524
525     public static String JavaDoc setResponseBrowserProxyNoCache(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
526         setResponseBrowserProxyNoCache(response);
527         return "success";
528     }
529
530     public static void setResponseBrowserProxyNoCache(HttpServletResponse JavaDoc response) {
531         long nowMillis = System.currentTimeMillis();
532         response.setDateHeader("Expires", nowMillis);
533         response.setDateHeader("Last-Modified", nowMillis); // always modified
534
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); // HTTP/1.1
535
response.addHeader("Cache-Control", "post-check=0, pre-check=0, false");
536         response.setHeader("Pragma", "no-cache"); // HTTP/1.0
537
}
538
539     public static String JavaDoc getContentTypeByFileName(String JavaDoc fileName) {
540         FileNameMap JavaDoc mime = URLConnection.getFileNameMap();
541         return mime.getContentTypeFor(fileName);
542     }
543
544     /**
545      * Stream an array of bytes to the browser
546      * This method will close the ServletOutputStream when finished
547      *
548      * @param response HttpServletResponse object to get OutputStream from
549      * @param bytes Byte array of content to stream
550      * @param contentType The content type to pass to the browser
551      * @throws IOException
552      */

553     public static void streamContentToBrowser(HttpServletResponse JavaDoc response, byte[] bytes, String JavaDoc contentType) throws IOException JavaDoc {
554         // tell the browser not the cache
555
setResponseBrowserProxyNoCache(response);
556
557         // set the response info
558
response.setContentLength(bytes.length);
559         if (contentType != null) {
560             response.setContentType(contentType);
561         }
562
563         // create the streams
564
OutputStream JavaDoc out = response.getOutputStream();
565         InputStream JavaDoc in = new ByteArrayInputStream JavaDoc(bytes);
566
567         // stream the content
568
try {
569             streamContent(out, in, bytes.length);
570         } catch (IOException JavaDoc e) {
571             in.close();
572             out.close(); // should we close the ServletOutputStream on error??
573
throw e;
574         }
575
576         // close the input stream
577
in.close();
578
579         // close the servlet output stream
580
out.flush();
581         out.close();
582     }
583
584     /**
585      * Streams content from InputStream to the ServletOutputStream
586      * This method will close the ServletOutputStream when finished
587      * This method does not close the InputSteam passed
588      *
589      * @param response HttpServletResponse object to get OutputStream from
590      * @param in InputStream of the actual content
591      * @param length Size (in bytes) of the content
592      * @param contentType The content type to pass to the browser
593      * @throws IOException
594      */

595     public static void streamContentToBrowser(HttpServletResponse JavaDoc response, InputStream JavaDoc in, int length, String JavaDoc contentType) throws IOException JavaDoc {
596         // tell the browser not the cache
597
setResponseBrowserProxyNoCache(response);
598
599         // set the response info
600
response.setContentLength(length);
601         if (contentType != null) {
602             response.setContentType(contentType);
603         }
604
605         // stream the content
606
OutputStream JavaDoc out = response.getOutputStream();
607         try {
608             streamContent(out, in, length);
609         } catch (IOException JavaDoc e) {
610             out.close();
611             throw e;
612         }
613
614         // close the servlet output stream
615
out.flush();
616         out.close();
617     }
618
619     /**
620      * Stream binary content from InputStream to OutputStream
621      * This method does not close the streams passed
622      *
623      * @param out OutputStream content should go to
624      * @param in InputStream of the actual content
625      * @param length Size (in bytes) of the content
626      * @throws IOException
627      */

628     public static void streamContent(OutputStream JavaDoc out, InputStream JavaDoc in, int length) throws IOException JavaDoc {
629         int bufferSize = 512; // same as the default buffer size; change as needed
630

631         // make sure we have something to write to
632
if (out == null) {
633             throw new IOException JavaDoc("Attempt to write to null output stream");
634         }
635
636         // make sure we have something to read from
637
if (in == null) {
638             throw new IOException JavaDoc("Attempt to read from null input stream");
639         }
640
641         // make sure we have some content
642
if (length == 0) {
643             throw new IOException JavaDoc("Attempt to write 0 bytes of content to output stream");
644         }
645
646         // initialize the buffered streams
647
BufferedOutputStream JavaDoc bos = new BufferedOutputStream JavaDoc(out, bufferSize);
648         BufferedInputStream JavaDoc bis = new BufferedInputStream JavaDoc(in, bufferSize);
649
650         byte[] buffer = new byte[length];
651         int read = 0;
652         try {
653             while ((read = bis.read(buffer, 0, buffer.length)) != -1) {
654                 bos.write(buffer, 0, read);
655             }
656         } catch (IOException JavaDoc e) {
657             Debug.logError(e, "Problem reading/writing buffers", module);
658             bis.close();
659             bos.close();
660             throw e;
661         } finally {
662             if (bis != null) {
663                 bis.close();
664             }
665             if (bos != null) {
666                 bos.flush();
667                 bos.close();
668             }
669         }
670     }
671
672     public static String JavaDoc stripViewParamsFromQueryString(String JavaDoc queryString) {
673         Set JavaDoc paramNames = new HashSet JavaDoc();
674         paramNames.add("VIEW_INDEX");
675         paramNames.add("VIEW_SIZE");
676         paramNames.add("viewIndex");
677         paramNames.add("viewSize");
678         return stripNamedParamsFromQueryString(queryString, paramNames);
679     }
680     
681     public static String JavaDoc stripNamedParamsFromQueryString(String JavaDoc queryString, Collection JavaDoc paramNames) {
682         String JavaDoc retStr = null;
683         if (UtilValidate.isNotEmpty(queryString)) {
684             StringTokenizer JavaDoc queryTokens = new StringTokenizer JavaDoc(queryString, "&");
685             StringBuffer JavaDoc cleanQuery = new StringBuffer JavaDoc();
686             while (queryTokens.hasMoreTokens()) {
687                 String JavaDoc token = queryTokens.nextToken();
688                 if (token.startsWith("amp;")) {
689                     token = token.substring(4);
690                 }
691                 int equalsIndex = token.indexOf("=");
692                 String JavaDoc name = token;
693                 if (equalsIndex > 0) {
694                     name = token.substring(0, equalsIndex);
695                 }
696                 if (!paramNames.contains(name)) {
697                     cleanQuery.append(token);
698                     if(queryTokens.hasMoreTokens()){
699                         cleanQuery.append("&");
700                     }
701                 }
702             }
703             retStr = cleanQuery.toString();
704         }
705         return retStr;
706     }
707
708     /**
709      * Given multi form data with the ${param}_o_N notation, creates a Collection
710      * of Maps for the submitted rows. Each Map contains the key/value pairs
711      * of a particular row. The keys will be stripped of the _o_N suffix.
712      * There is an additionaly key "row" for each Map that holds the
713      * index of the row.
714      */

715     public static Collection JavaDoc parseMultiFormData(Map JavaDoc parameters) {
716         FastMap rows = new FastMap(); // stores the rows keyed by row number
717

718         // first loop through all the keys and create a hashmap for each ${ROW_SUBMIT_PREFIX}${N} = Y
719
Iterator JavaDoc keys = parameters.keySet().iterator();
720         while (keys.hasNext()) {
721             String JavaDoc key = (String JavaDoc) keys.next();
722
723             // skip everything that is not ${ROW_SUBMIT_PREFIX}N
724
if (key == null || key.length() <= ROW_SUBMIT_PREFIX_LENGTH) continue;
725             if (key.indexOf(MULTI_ROW_DELIMITER) <= 0) continue;
726             if (!key.substring(0, ROW_SUBMIT_PREFIX_LENGTH).equals(ROW_SUBMIT_PREFIX)) continue;
727             if (!parameters.get(key).equals("Y")) continue;
728
729             // decode the value of N and create a new map for it
730
Integer JavaDoc n = Integer.decode(key.substring(ROW_SUBMIT_PREFIX_LENGTH, key.length()));
731             Map JavaDoc m = new FastMap();
732             m.put("row", n); // special "row" = N tuple
733
rows.put(n, m); // key it to N
734
}
735
736         // next put all parameters with matching N in the right map
737
keys = parameters.keySet().iterator();
738         while (keys.hasNext()) {
739             String JavaDoc key = (String JavaDoc) keys.next();
740
741             // skip keys without DELIMITER and skip ROW_SUBMIT_PREFIX
742
if (key == null) continue;
743             int index = key.indexOf(MULTI_ROW_DELIMITER);
744             if (index <= 0) continue;
745             if (key.length() > ROW_SUBMIT_PREFIX_LENGTH && key.substring(0, ROW_SUBMIT_PREFIX_LENGTH).equals(ROW_SUBMIT_PREFIX)) continue;
746
747             // get the map with index N
748
Integer JavaDoc n = Integer.decode(key.substring(index + MULTI_ROW_DELIMITER_LENGTH, key.length())); // N from ${param}${DELIMITER}${N}
749
Map JavaDoc map = (Map JavaDoc) rows.get(n);
750             if (map == null) continue;
751
752             // get the key without the <DELIMITER>N suffix and store it and its value
753
String JavaDoc newKey = key.substring(0, index);
754             map.put(newKey, parameters.get(key));
755         }
756         // return only the values, which is the list of maps
757
return rows.values();
758     }
759
760     /**
761      * Returns a new map containing all the parameters from the input map except for the
762      * multi form parameters (usually named according to the ${param}_o_N notation).
763      */

764     public static Map JavaDoc removeMultiFormParameters(Map JavaDoc parameters) {
765         FastMap filteredParameters = new FastMap();
766         Iterator JavaDoc keys = parameters.keySet().iterator();
767         while (keys.hasNext()) {
768             String JavaDoc key = (String JavaDoc) keys.next();
769
770             if (key != null && (key.indexOf(MULTI_ROW_DELIMITER) != -1 || key.indexOf("_useRowSubmit") != -1 || key.indexOf("_rowCount") != -1)) {
771                 continue;
772             }
773
774             filteredParameters.put(key, parameters.get(key));
775         }
776         return filteredParameters;
777     }
778
779     /**
780      * Utility to make a composite parameter from the given prefix and suffix.
781      * The prefix should be a regular paramter name such as meetingDate. The
782      * suffix is the composite field, such as the hour of the meeting. The
783      * result would be meetingDate_${COMPOSITE_DELIMITER}_hour.
784      *
785      * @param paramName
786      * @param compositeName
787      * @return
788      */

789     public static String JavaDoc makeCompositeParam(String JavaDoc prefix, String JavaDoc suffix) {
790         return prefix + COMPOSITE_DELIMITER + suffix;
791     }
792
793     /**
794      * Given the prefix of a composite parameter, recomposes a single Object from
795      * the composite according to compositeType. For example, consider the following
796      * form widget field,
797      *
798      * <field name="meetingDate">
799      * <date-time type="timestamp" input-method="time-dropdown">
800      * </field>
801      *
802      * The result in HTML is three input boxes to input the date, hour and minutes separately.
803      * The parameter names are named meetingDate_c_date, meetingDate_c_hour, meetingDate_c_minutes.
804      * Additionally, there will be a field named meetingDate_c_compositeType with a value of "Timestamp".
805      * where _c_ is the COMPOSITE_DELIMITER. These parameters will then be recomposed into a Timestamp
806      * object from the composite fields.
807      *
808      * @param request
809      * @param prefix
810      * @return Composite object from data or nulll if not supported or a parsing error occured.
811      */

812     public static Object JavaDoc makeParamValueFromComposite(HttpServletRequest JavaDoc request, String JavaDoc prefix, Locale JavaDoc locale) {
813         String JavaDoc compositeType = request.getParameter(makeCompositeParam(prefix, "compositeType"));
814         if (compositeType == null || compositeType.length() == 0) return null;
815
816         // collect the composite fields into a map
817
Map JavaDoc data = FastMap.newInstance();
818         for (Enumeration JavaDoc names = request.getParameterNames(); names.hasMoreElements(); ) {
819             String JavaDoc name = (String JavaDoc) names.nextElement();
820             if (!name.startsWith(prefix + COMPOSITE_DELIMITER)) continue;
821
822             // extract the suffix of the composite name
823
String JavaDoc suffix = name.substring(name.indexOf(COMPOSITE_DELIMITER) + COMPOSITE_DELIMITER_LENGTH);
824
825             // and the value of this parameter
826
Object JavaDoc value = request.getParameter(name);
827
828             // key = suffix, value = parameter data
829
data.put(suffix, value);
830         }
831         if (Debug.verboseOn()) { Debug.logVerbose("Creating composite type with parameter data: " + data.toString(), module); }
832
833         // handle recomposition of data into the compositeType
834
if ("Timestamp".equals(compositeType)) {
835             String JavaDoc date = (String JavaDoc) data.get("date");
836             String JavaDoc hour = (String JavaDoc) data.get("hour");
837             String JavaDoc minutes = (String JavaDoc) data.get("minutes");
838             String JavaDoc ampm = (String JavaDoc) data.get("ampm");
839             if (date == null || date.length() < 10) return null;
840             if (hour == null || hour.length() == 0) return null;
841             if (minutes == null || minutes.length() == 0) return null;
842             boolean isTwelveHour = ((ampm == null || ampm.length() == 0) ? false : true);
843
844             // create the timestamp from the data
845
try {
846                 int h = Integer.parseInt(hour);
847                 Timestamp JavaDoc timestamp = Timestamp.valueOf(date.substring(0, 10) + " 00:00:00.000");
848                 Calendar JavaDoc cal = Calendar.getInstance(locale);
849                 cal.setTime(timestamp);
850                 if (isTwelveHour) {
851                     boolean isAM = ("AM".equals(ampm) ? true : false);
852                     if (isAM && h == 12) h = 0;
853                     if (!isAM && h < 12) h += 12;
854                 }
855                 cal.set(Calendar.HOUR_OF_DAY, h);
856                 cal.set(Calendar.MINUTE, Integer.parseInt(minutes));
857                 return new Timestamp JavaDoc(cal.getTimeInMillis());
858             } catch (IllegalArgumentException JavaDoc e) {
859                 Debug.logWarning("User input for composite timestamp was invalid: " + e.getMessage(), module);
860                 return null;
861             }
862         }
863
864         // we don't support any other compositeTypes (yet)
865
return null;
866     }
867 }
868
Popular Tags