1 /*
2  * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
3  * All rights reserved.
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 package javax.servlet;
20
21 import java.io.BufferedReader;
22 import java.io.IOException;
23 import java.io.UnsupportedEncodingException;
24 import java.util.Enumeration;
25 import java.util.Locale;
26 import java.util.Map;
27
28 /**
29  * Provides a convenient implementation of the ServletRequest interface that can be subclassed by developers wishing to
30  * adapt the request to a Servlet. This class implements the Wrapper or Decorator pattern. Methods default to calling
31  * through to the wrapped request object.
32  *
33  * @see javax.servlet.ServletRequest
34  *
35  * @since Servlet 2.3
36  */

37 public class ServletRequestWrapper implements ServletRequest {
38
39     private ServletRequest request;
40
41     /**
42      * Creates a ServletRequest adaptor wrapping the given request object.
43      *
44      * @param request the {@link ServletRequest} to be wrapped
45      *
46      * @throws java.lang.IllegalArgumentException if the request is null
47      */

48     public ServletRequestWrapper(ServletRequest request) {
49         if (request == null) {
50             throw new IllegalArgumentException("Request cannot be null");
51         }
52         this.request = request;
53     }
54
55     /**
56      * Return the wrapped request object.
57      *
58      * @return the wrapped {@link ServletRequest}
59      */

60     public ServletRequest getRequest() {
61         return this.request;
62     }
63
64     /**
65      * Sets the request object being wrapped.
66      *
67      * @param request the {@link ServletRequest} to be installed
68      *
69      * @throws java.lang.IllegalArgumentException if the request is null.
70      * 
71      */

72     public void setRequest(ServletRequest request) {
73         if (request == null) {
74             throw new IllegalArgumentException("Request cannot be null");
75         }
76         this.request = request;
77     }
78
79     /**
80      * The default behavior of this method is to call getAttribute(String name) on the wrapped request object.
81      */

82     @Override
83     public Object getAttribute(String name) {
84         return this.request.getAttribute(name);
85     }
86
87     /**
88      * The default behavior of this method is to return getAttributeNames() on the wrapped request object.
89      */

90     @Override
91     public Enumeration<String> getAttributeNames() {
92         return this.request.getAttributeNames();
93     }
94
95     /**
96      * The default behavior of this method is to return getCharacterEncoding() on the wrapped request object.
97      */

98     @Override
99     public String getCharacterEncoding() {
100         return this.request.getCharacterEncoding();
101     }
102
103     /**
104      * The default behavior of this method is to set the character encoding on the wrapped request object.
105      */

106     @Override
107     public void setCharacterEncoding(String enc) throws UnsupportedEncodingException {
108         this.request.setCharacterEncoding(enc);
109     }
110
111     /**
112      * The default behavior of this method is to return getContentLength() on the wrapped request object.
113      */

114     @Override
115     public int getContentLength() {
116         return this.request.getContentLength();
117     }
118
119     /**
120      * The default behavior of this method is to return getContentLengthLong() on the wrapped request object.
121      *
122      * @since Servlet 3.1
123      */

124     @Override
125     public long getContentLengthLong() {
126         return this.request.getContentLengthLong();
127     }
128
129     /**
130      * The default behavior of this method is to return getContentType() on the wrapped request object.
131      */

132     @Override
133     public String getContentType() {
134         return this.request.getContentType();
135     }
136
137     /**
138      * The default behavior of this method is to return getInputStream() on the wrapped request object.
139      */

140     @Override
141     public ServletInputStream getInputStream() throws IOException {
142         return this.request.getInputStream();
143     }
144
145     /**
146      * The default behavior of this method is to return getParameter(String name) on the wrapped request object.
147      */

148     @Override
149     public String getParameter(String name) {
150         return this.request.getParameter(name);
151     }
152
153     /**
154      * The default behavior of this method is to return getParameterMap() on the wrapped request object.
155      */

156     @Override
157     public Map<String, String[]> getParameterMap() {
158         return this.request.getParameterMap();
159     }
160
161     /**
162      * The default behavior of this method is to return getParameterNames() on the wrapped request object.
163      */

164     @Override
165     public Enumeration<String> getParameterNames() {
166         return this.request.getParameterNames();
167     }
168
169     /**
170      * The default behavior of this method is to return getParameterValues(String name) on the wrapped request object.
171      */

172     @Override
173     public String[] getParameterValues(String name) {
174         return this.request.getParameterValues(name);
175     }
176
177     /**
178      * The default behavior of this method is to return getProtocol() on the wrapped request object.
179      */

180     @Override
181     public String getProtocol() {
182         return this.request.getProtocol();
183     }
184
185     /**
186      * The default behavior of this method is to return getScheme() on the wrapped request object.
187      */

188     @Override
189     public String getScheme() {
190         return this.request.getScheme();
191     }
192
193     /**
194      * The default behavior of this method is to return getServerName() on the wrapped request object.
195      */

196     @Override
197     public String getServerName() {
198         return this.request.getServerName();
199     }
200
201     /**
202      * The default behavior of this method is to return getServerPort() on the wrapped request object.
203      */

204     @Override
205     public int getServerPort() {
206         return this.request.getServerPort();
207     }
208
209     /**
210      * The default behavior of this method is to return getReader() on the wrapped request object.
211      */

212     @Override
213     public BufferedReader getReader() throws IOException {
214         return this.request.getReader();
215     }
216
217     /**
218      * The default behavior of this method is to return getRemoteAddr() on the wrapped request object.
219      */

220     @Override
221     public String getRemoteAddr() {
222         return this.request.getRemoteAddr();
223     }
224
225     /**
226      * The default behavior of this method is to return getRemoteHost() on the wrapped request object.
227      */

228     @Override
229     public String getRemoteHost() {
230         return this.request.getRemoteHost();
231     }
232
233     /**
234      * The default behavior of this method is to return setAttribute(String name, Object o) on the wrapped request
235      * object.
236      */

237     @Override
238     public void setAttribute(String name, Object o) {
239         this.request.setAttribute(name, o);
240     }
241
242     /**
243      * The default behavior of this method is to call removeAttribute(String name) on the wrapped request object.
244      */

245     @Override
246     public void removeAttribute(String name) {
247         this.request.removeAttribute(name);
248     }
249
250     /**
251      * The default behavior of this method is to return getLocale() on the wrapped request object.
252      */

253     @Override
254     public Locale getLocale() {
255         return this.request.getLocale();
256     }
257
258     /**
259      * The default behavior of this method is to return getLocales() on the wrapped request object.
260      */

261     @Override
262     public Enumeration<Locale> getLocales() {
263         return this.request.getLocales();
264     }
265
266     /**
267      * The default behavior of this method is to return isSecure() on the wrapped request object.
268      */

269     @Override
270     public boolean isSecure() {
271         return this.request.isSecure();
272     }
273
274     /**
275      * The default behavior of this method is to return getRequestDispatcher(String path) on the wrapped request object.
276      */

277     @Override
278     public RequestDispatcher getRequestDispatcher(String path) {
279         return this.request.getRequestDispatcher(path);
280     }
281
282     /**
283      * The default behavior of this method is to return getRealPath(String path) on the wrapped request object.
284      *
285      * @deprecated As of Version 2.1 of the Java Servlet API, use {@link ServletContext#getRealPath} instead
286      */

287     @Override
288     @Deprecated
289     public String getRealPath(String path) {
290         return this.request.getRealPath(path);
291     }
292
293     /**
294      * The default behavior of this method is to return getRemotePort() on the wrapped request object.
295      *
296      * @since Servlet 2.4
297      */

298     @Override
299     public int getRemotePort() {
300         return this.request.getRemotePort();
301     }
302
303     /**
304      * The default behavior of this method is to return getLocalName() on the wrapped request object.
305      *
306      * @since Servlet 2.4
307      */

308     @Override
309     public String getLocalName() {
310         return this.request.getLocalName();
311     }
312
313     /**
314      * The default behavior of this method is to return getLocalAddr() on the wrapped request object.
315      *
316      * @since Servlet 2.4
317      */

318     @Override
319     public String getLocalAddr() {
320         return this.request.getLocalAddr();
321     }
322
323     /**
324      * The default behavior of this method is to return getLocalPort() on the wrapped request object.
325      *
326      * @since Servlet 2.4
327      */

328     @Override
329     public int getLocalPort() {
330         return this.request.getLocalPort();
331     }
332
333     /**
334      * Gets the servlet context to which the wrapped servlet request was last dispatched.
335      *
336      * @return the servlet context to which the wrapped servlet request was last dispatched
337      *
338      * @since Servlet 3.0
339      */

340     @Override
341     public ServletContext getServletContext() {
342         return request.getServletContext();
343     }
344
345     /**
346      * The default behavior of this method is to invoke {@link ServletRequest#startAsync} on the wrapped request object.
347      *
348      * @return the (re)initialized AsyncContext
349      * 
350      * @throws IllegalStateException if the request is within the scope of a filter or servlet that does not support
351      *                               asynchronous operations (that is, {@link #isAsyncSupported} returns false), or if
352      *                               this method is called again without any asynchronous dispatch (resulting from one
353      *                               of the {@link AsyncContext#dispatch} methods), is called outside the scope of any
354      *                               such dispatch, or is called again within the scope of the same dispatch, or if the
355      *                               response has already been closed
356      *
357      * @see ServletRequest#startAsync
358      *
359      * @since Servlet 3.0
360      */

361     @Override
362     public AsyncContext startAsync() throws IllegalStateException {
363         return request.startAsync();
364     }
365
366     /**
367      * The default behavior of this method is to invoke
368      * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)} on the wrapped request object.
369      *
370      * @param servletRequest  the ServletRequest used to initialize the AsyncContext
371      * @param servletResponse the ServletResponse used to initialize the AsyncContext
372      *
373      * @return the (re)initialized AsyncContext
374      *
375      * @throws IllegalStateException if the request is within the scope of a filter or servlet that does not support
376      *                               asynchronous operations (that is, {@link #isAsyncSupported} returns false), or if
377      *                               this method is called again without any asynchronous dispatch (resulting from one
378      *                               of the {@link AsyncContext#dispatch} methods), is called outside the scope of any
379      *                               such dispatch, or is called again within the scope of the same dispatch, or if the
380      *                               response has already been closed
381      *
382      * @see ServletRequest#startAsync(ServletRequest, ServletResponse)
383      *
384      * @since Servlet 3.0
385      */

386     @Override
387     public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
388             throws IllegalStateException {
389         return request.startAsync(servletRequest, servletResponse);
390     }
391
392     /**
393      * Checks if the wrapped request has been put into asynchronous mode.
394      *
395      * @return true if this request has been put into asynchronous mode, false otherwise
396      *
397      * @see ServletRequest#isAsyncStarted
398      *
399      * @since Servlet 3.0
400      */

401     @Override
402     public boolean isAsyncStarted() {
403         return request.isAsyncStarted();
404     }
405
406     /**
407      * Checks if the wrapped request supports asynchronous operation.
408      *
409      * @return true if this request supports asynchronous operation, false otherwise
410      *
411      * @see ServletRequest#isAsyncSupported
412      *
413      * @since Servlet 3.0
414      */

415     @Override
416     public boolean isAsyncSupported() {
417         return request.isAsyncSupported();
418     }
419
420     /**
421      * Gets the AsyncContext that was created or reinitialized by the most recent invocation of {@link #startAsync} or
422      * {@link #startAsync(ServletRequest,ServletResponse)} on the wrapped request.
423      *
424      * @return the AsyncContext that was created or reinitialized by the most recent invocation of {@link #startAsync}
425      *         or {@link #startAsync(ServletRequest,ServletResponse)} on the wrapped request
426      *
427      * @throws IllegalStateException if this request has not been put into asynchronous mode, i.e., if neither
428      *                               {@link #startAsync} nor {@link #startAsync(ServletRequest,ServletResponse)} has
429      *                               been called
430      *
431      * @see ServletRequest#getAsyncContext
432      *
433      * @since Servlet 3.0
434      */

435     @Override
436     public AsyncContext getAsyncContext() {
437         return request.getAsyncContext();
438     }
439
440     /**
441      * Checks (recursively) if this ServletRequestWrapper wraps the given {@link ServletRequest} instance.
442      *
443      * @param wrapped the ServletRequest instance to search for
444      *
445      * @return true if this ServletRequestWrapper wraps the given ServletRequest instance, false otherwise
446      *
447      * @since Servlet 3.0
448      */

449     public boolean isWrapperFor(ServletRequest wrapped) {
450         if (request == wrapped) {
451             return true;
452         } else if (request instanceof ServletRequestWrapper) {
453             return ((ServletRequestWrapper) request).isWrapperFor(wrapped);
454         } else {
455             return false;
456         }
457     }
458
459     /**
460      * Checks (recursively) if this ServletRequestWrapper wraps a {@link ServletRequest} of the given class type.
461      *
462      * @param wrappedType the ServletRequest class type to search for
463      *
464      * @return true if this ServletRequestWrapper wraps a ServletRequest of the given class type, false otherwise
465      *
466      * @throws IllegalArgumentException if the given class does not implement {@link ServletRequest}
467      *
468      * @since Servlet 3.0
469      */

470     public boolean isWrapperFor(Class<?> wrappedType) {
471         if (!ServletRequest.class.isAssignableFrom(wrappedType)) {
472             throw new IllegalArgumentException("Given class " + wrappedType.getName() + " not a subinterface of "
473                     + ServletRequest.class.getName());
474         }
475         if (wrappedType.isAssignableFrom(request.getClass())) {
476             return true;
477         } else if (request instanceof ServletRequestWrapper) {
478             return ((ServletRequestWrapper) request).isWrapperFor(wrappedType);
479         } else {
480             return false;
481         }
482     }
483
484     /**
485      * Gets the dispatcher type of the wrapped request.
486      *
487      * @return the dispatcher type of the wrapped request
488      * 
489      * @see ServletRequest#getDispatcherType
490      *
491      * @since Servlet 3.0
492      */

493     @Override
494     public DispatcherType getDispatcherType() {
495         return request.getDispatcherType();
496     }
497
498 }
499