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 }