001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/enterprise/servlet/ServletRequestWrapper.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 037 package org.deegree.enterprise.servlet; 038 039 import static java.net.URLDecoder.decode; 040 041 import java.io.BufferedInputStream; 042 import java.io.BufferedReader; 043 import java.io.ByteArrayInputStream; 044 import java.io.ByteArrayOutputStream; 045 import java.io.IOException; 046 import java.io.InputStream; 047 import java.io.InputStreamReader; 048 import java.io.UnsupportedEncodingException; 049 import java.security.Principal; 050 import java.util.HashMap; 051 import java.util.Iterator; 052 import java.util.Map; 053 import java.util.ResourceBundle; 054 055 import javax.servlet.ServletInputStream; 056 import javax.servlet.http.HttpServletRequest; 057 import javax.servlet.http.HttpServletRequestWrapper; 058 059 import org.deegree.framework.log.ILogger; 060 import org.deegree.framework.log.LoggerFactory; 061 import org.deegree.framework.util.CharsetUtils; 062 import org.deegree.framework.util.StringTools; 063 064 /** 065 * TODO describe function and usage of the class here. 066 * 067 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 068 * @author last edited by: $Author: mays$ 069 * 070 * @version $Revision: 18195 $, $Date: 23.05.2007 18:09:52$ 071 */ 072 public class ServletRequestWrapper extends HttpServletRequestWrapper { 073 074 private static ILogger LOG = LoggerFactory.getLogger( ServletRequestWrapper.class ); 075 076 private static final String BUNDLE_NAME = "org.deegree.enterprise.servlet.ServletRequestWrapper"; 077 078 /** 079 * The resource to load the users from. 080 */ 081 static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME ); 082 083 private HttpServletRequest origReq = null; 084 085 private byte[] bytes = null; 086 087 private Map<String, String[]> paramMap; 088 089 private String queryString; 090 091 /** 092 * @param request 093 */ 094 public ServletRequestWrapper( HttpServletRequest request ) { 095 super( request ); 096 097 this.origReq = request; 098 099 ByteArrayOutputStream bos = new ByteArrayOutputStream( 10000 ); 100 try { 101 InputStream is = origReq.getInputStream(); 102 int c = 0; 103 while ( ( c = is.read() ) > -1 ) { 104 bos.write( c ); 105 } 106 bytes = bos.toByteArray(); 107 LOG.logDebug( "The constructor created a new bytearray in the HttpServletRequestWrapper" ); 108 } catch ( IOException ioe ) { 109 LOG.logError( 110 "An error occured while creating a byte-buffered inputstream from the HttpServletRequest inputstream because: " 111 + ioe.getMessage(), ioe ); 112 bytes = null; 113 } 114 queryString = request.getQueryString(); 115 } 116 117 // /** 118 // * creates a new ServletInputStream with a copy of the content of the original one 119 // * 120 // * @return 121 // * @throws IOException 122 // */ 123 // private ServletInputStream createInputStream() 124 // throws IOException { 125 // 126 // if ( bytes == null ) { 127 // LOG.logDebug( "Creating new bytearray in the HttpServletRequestWrapper" ); 128 // ByteArrayOutputStream bos = new ByteArrayOutputStream( 10000 ); 129 // InputStream is = origReq.getInputStream(); 130 // int c = 0; 131 // while ( ( c = is.read() ) > -1 ) { 132 // bos.write( c ); 133 // } 134 // bytes = bos.toByteArray(); 135 // } 136 // 137 // return new ProxyServletInputStream( new ByteArrayInputStream( bytes ), bytes.length ); 138 // } 139 140 @Override 141 public Map<String, String[]> getParameterMap() { 142 if ( paramMap == null ) { 143 paramMap = new HashMap<String, String[]>(); 144 145 // encoding heuristics for URL encoding 146 // if %c3 is found (a sign of UTF-8 encoding) parse it manually, setting the encoding right 147 if ( queryString != null && queryString.toLowerCase().indexOf( "%c3" ) != -1 ) { 148 try { 149 for ( String kv : queryString.split( "&" ) ) { 150 String[] pair = kv.split( "=", 2 ); 151 if ( pair.length == 2 ) { 152 paramMap.put( decode( pair[0], "UTF-8" ), decode( pair[1], "UTF-8" ).split( "," ) ); 153 } 154 } 155 } catch ( UnsupportedEncodingException e ) { 156 LOG.logError( "Unknown error", e ); 157 } 158 } else { 159 // according to javax.servlet.* documentation, the type is correct 160 paramMap = super.getParameterMap(); 161 162 } 163 } 164 165 return paramMap; 166 } 167 168 @Override 169 public String getParameter( String key ) { 170 if ( paramMap == null ) { 171 paramMap = getParameterMap(); 172 } 173 Object o = paramMap.get( key ); 174 String tmp = null; 175 if ( o != null && o.getClass() == String[].class ) { 176 tmp = StringTools.arrayToString( (String[]) o, ',' ); 177 } else { 178 tmp = (String) o; 179 } 180 return tmp; 181 } 182 183 @Override 184 public String[] getParameterValues( String arg0 ) { 185 if ( paramMap == null ) { 186 paramMap = getParameterMap(); 187 } 188 Object o = paramMap.get( arg0 ); 189 if ( o instanceof String ) { 190 return new String[] { (String) o }; 191 } 192 return (String[]) o; 193 } 194 195 /** 196 * 197 * @param param 198 */ 199 public void setParameter( Map<String, String> param ) { 200 this.paramMap = new HashMap<String, String[]>( param.size() ); 201 202 Iterator<String> iter = param.keySet().iterator(); 203 StringBuffer sb = new StringBuffer( 500 ); 204 while ( iter.hasNext() ) { 205 String key = iter.next(); 206 String value = param.get( key ); 207 sb.append( key ).append( '=' ).append( value ); 208 if ( iter.hasNext() ) { 209 sb.append( '&' ); 210 } 211 this.paramMap.put( key, StringTools.toArray( value, ",", false ) ); 212 } 213 this.queryString = sb.toString(); 214 } 215 216 @Override 217 public String getQueryString() { 218 return queryString; 219 } 220 221 /** 222 * sets the content of the inputstream returned by the 223 * 224 * @see #getReader() and the 225 * @see #getInputStream() method as a byte array. Calling this method will override the content that may has been 226 * read from the <code>HttpServletRequest</code> that has been passed to the constructor 227 * 228 * @param b 229 */ 230 public void setInputStreamAsByteArray( byte[] b ) { 231 LOG.logDebug( "ServletRequestWrapper: setting inputstream#byteArray to given bytearra" ); 232 this.bytes = b; 233 } 234 235 @Override 236 public BufferedReader getReader() 237 throws IOException { 238 return new BufferedReader( new InputStreamReader( getInputStream(), CharsetUtils.getSystemCharset() ) ); 239 } 240 241 /** 242 * @see javax.servlet.ServletRequest#getInputStream() 243 */ 244 @Override 245 public ServletInputStream getInputStream() 246 throws IOException { 247 if ( bytes == null ) { 248 LOG.logDebug( "Creating new bytearray in the HttpServletRequestWrapper#getInputStream" ); 249 ByteArrayOutputStream bos = new ByteArrayOutputStream( 10000 ); 250 InputStream is = origReq.getInputStream(); 251 int c = 0; 252 while ( ( c = is.read() ) > -1 ) { 253 bos.write( c ); 254 } 255 bytes = bos.toByteArray(); 256 } 257 258 return new ProxyServletInputStream( new ByteArrayInputStream( bytes ), bytes.length ); 259 } 260 261 @Override 262 public Principal getUserPrincipal() { 263 if ( origReq.getUserPrincipal() != null ) { 264 return origReq.getUserPrincipal(); 265 } 266 return new Principal() { 267 public String getName() { 268 return RESOURCE_BUNDLE.getString( "defaultuser" ); 269 } 270 }; 271 272 } 273 274 // /////////////////////////////////////////////////////////////////////// 275 // inner classes // 276 // /////////////////////////////////////////////////////////////////////// 277 278 /** 279 * @author Administrator 280 * 281 * TODO To change the template for this generated type comment go to Window - Preferences - Java - Code 282 * Style - Code Templates 283 */ 284 private class ProxyServletInputStream extends ServletInputStream { 285 286 private BufferedInputStream buffered; 287 288 /** 289 * @param in 290 * the InputStream which will be buffered. 291 * @param length 292 */ 293 public ProxyServletInputStream( InputStream in, int length ) { 294 if ( length > 0 ) 295 buffered = new BufferedInputStream( in, length ); 296 else 297 buffered = new BufferedInputStream( in ); 298 } 299 300 @Override 301 public synchronized int read() 302 throws IOException { 303 return buffered.read(); 304 } 305 306 @Override 307 public synchronized int read( byte b[], int off, int len ) 308 throws IOException { 309 return buffered.read( b, off, len ); 310 } 311 312 @Override 313 public synchronized long skip( long n ) 314 throws IOException { 315 return buffered.skip( n ); 316 } 317 318 @Override 319 public synchronized int available() 320 throws IOException { 321 return buffered.available(); 322 } 323 324 @Override 325 public synchronized void mark( int readlimit ) { 326 buffered.mark( readlimit ); 327 } 328 329 @Override 330 public synchronized void reset() 331 throws IOException { 332 buffered.reset(); 333 } 334 335 @Override 336 public boolean markSupported() { 337 return buffered.markSupported(); 338 } 339 340 @Override 341 public void close() 342 throws IOException { 343 buffered.close(); 344 } 345 } 346 347 }