Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ServletRequestImpl |
|
| 1.6666666666666667;1.667 |
1 | /* | |
2 | * Copyright 1999,2004 The Apache Software Foundation. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | ||
18 | package org.apache.commons.messagelet.impl; | |
19 | ||
20 | ||
21 | import java.io.BufferedReader; | |
22 | import java.io.IOException; | |
23 | import java.io.InputStream; | |
24 | import java.io.InputStreamReader; | |
25 | import java.io.UnsupportedEncodingException; | |
26 | import java.util.ArrayList; | |
27 | import java.util.Enumeration; | |
28 | import java.util.HashMap; | |
29 | import java.util.Locale; | |
30 | import java.util.Map; | |
31 | ||
32 | import javax.servlet.RequestDispatcher; | |
33 | import javax.servlet.ServletContext; | |
34 | import javax.servlet.ServletInputStream; | |
35 | import javax.servlet.ServletRequest; | |
36 | ||
37 | import org.apache.commons.collections.iterators.IteratorEnumeration; | |
38 | import org.apache.commons.collections.iterators.SingletonIterator; | |
39 | ||
40 | /** | |
41 | * Based on the RequestBase code from Catalina. | |
42 | * | |
43 | * @author Craig R. McClanahan | |
44 | * @author James Strachan | |
45 | * @version $Revision: 155459 $ $Date: 2005-02-26 13:24:44 +0000 (Sat, 26 Feb 2005) $ | |
46 | */ | |
47 | ||
48 | public class ServletRequestImpl implements ServletRequest { | |
49 | ||
50 | ||
51 | // ----------------------------------------------------- Instance Variables | |
52 | ||
53 | ||
54 | /** | |
55 | * The attributes associated with this Request, keyed by attribute name. | |
56 | */ | |
57 | 0 | protected HashMap attributes = new HashMap(); |
58 | ||
59 | ||
60 | /** | |
61 | * The authorization credentials sent with this Request. | |
62 | */ | |
63 | 0 | protected String authorization = null; |
64 | ||
65 | ||
66 | /** | |
67 | * The character encoding for this Request. | |
68 | */ | |
69 | 0 | protected String characterEncoding = null; |
70 | ||
71 | ||
72 | ||
73 | /** | |
74 | * The content length associated with this request. | |
75 | */ | |
76 | 0 | protected int contentLength = -1; |
77 | ||
78 | ||
79 | /** | |
80 | * The content type associated with this request. | |
81 | */ | |
82 | 0 | protected String contentType = null; |
83 | ||
84 | ||
85 | /** | |
86 | * The default Locale if none are specified. | |
87 | */ | |
88 | 0 | protected static Locale defaultLocale = Locale.getDefault(); |
89 | ||
90 | ||
91 | /** | |
92 | * The input stream associated with this Request. | |
93 | */ | |
94 | 0 | protected InputStream input = null; |
95 | ||
96 | ||
97 | /** | |
98 | * The preferred Locales assocaited with this Request. | |
99 | */ | |
100 | 0 | protected ArrayList locales = new ArrayList(); |
101 | ||
102 | ||
103 | ||
104 | /** | |
105 | * The protocol name and version associated with this Request. | |
106 | */ | |
107 | 0 | protected String protocol = null; |
108 | ||
109 | ||
110 | /** | |
111 | * The reader that has been returned by <code>getReader</code>, if any. | |
112 | */ | |
113 | 0 | protected BufferedReader reader = null; |
114 | ||
115 | ||
116 | /** | |
117 | * The remote address associated with this request. | |
118 | */ | |
119 | 0 | protected String remoteAddr = null; |
120 | ||
121 | ||
122 | /** | |
123 | * The fully qualified name of the remote host. | |
124 | */ | |
125 | 0 | protected String remoteHost = null; |
126 | ||
127 | ||
128 | ||
129 | /** | |
130 | * The scheme associated with this Request. | |
131 | */ | |
132 | 0 | protected String scheme = null; |
133 | ||
134 | ||
135 | /** | |
136 | * Was this request received on a secure connection? | |
137 | */ | |
138 | 0 | protected boolean secure = false; |
139 | ||
140 | ||
141 | /** | |
142 | * The server name associated with this Request. | |
143 | */ | |
144 | 0 | protected String serverName = null; |
145 | ||
146 | ||
147 | /** | |
148 | * The server port associated with this Request. | |
149 | */ | |
150 | 0 | protected int serverPort = -1; |
151 | ||
152 | ||
153 | /** | |
154 | * The ServletInputStream that has been returned by | |
155 | * <code>getInputStream()</code>, if any. | |
156 | */ | |
157 | 0 | protected ServletInputStream stream = null; |
158 | ||
159 | ||
160 | /** | |
161 | * The ServletContext which is used to dispatch further requests | |
162 | */ | |
163 | protected ServletContext servletContext; | |
164 | ||
165 | ||
166 | ||
167 | 0 | public ServletRequestImpl(ServletContext servletContext) { |
168 | 0 | this.servletContext = servletContext; |
169 | 0 | } |
170 | ||
171 | // ------------------------------------------------------------- Properties | |
172 | ||
173 | ||
174 | ||
175 | /** | |
176 | * Return the input stream associated with this Request. | |
177 | */ | |
178 | public InputStream getStream() { | |
179 | ||
180 | 0 | return (this.input); |
181 | ||
182 | } | |
183 | ||
184 | ||
185 | /** | |
186 | * Set the input stream associated with this Request. | |
187 | * | |
188 | * @param input The new input stream | |
189 | */ | |
190 | public void setStream(InputStream input) { | |
191 | ||
192 | 0 | this.input = input; |
193 | ||
194 | 0 | } |
195 | ||
196 | ||
197 | ||
198 | // --------------------------------------------------------- Public Methods | |
199 | ||
200 | ||
201 | /** | |
202 | * Add a Locale to the set of preferred Locales for this Request. The | |
203 | * first added Locale will be the first one returned by getLocales(). | |
204 | * | |
205 | * @param locale The new preferred Locale | |
206 | */ | |
207 | public void addLocale(Locale locale) { | |
208 | ||
209 | 0 | synchronized (locales) { |
210 | 0 | locales.add(locale); |
211 | 0 | } |
212 | ||
213 | 0 | } |
214 | ||
215 | ||
216 | /** | |
217 | * Create and return a ServletInputStream to read the content | |
218 | * associated with this Request. The default implementation creates an | |
219 | * instance of RequestStream associated with this request, but this can | |
220 | * be overridden if necessary. | |
221 | * | |
222 | * @exception IOException if an input/output error occurs | |
223 | */ | |
224 | public ServletInputStream createInputStream() throws IOException { | |
225 | ||
226 | //return (new RequestStream(this)); | |
227 | 0 | return null; |
228 | ||
229 | } | |
230 | ||
231 | ||
232 | /** | |
233 | * Perform whatever actions are required to flush and close the input | |
234 | * stream or reader, in a single operation. | |
235 | * | |
236 | * @exception IOException if an input/output error occurs | |
237 | */ | |
238 | public void finishRequest() throws IOException { | |
239 | ||
240 | // If a Reader has been acquired, close it | |
241 | 0 | if (reader != null) { |
242 | try { | |
243 | 0 | reader.close(); |
244 | 0 | } catch (IOException e) { |
245 | ; | |
246 | 0 | } |
247 | } | |
248 | ||
249 | // If a ServletInputStream has been acquired, close it | |
250 | 0 | if (stream != null) { |
251 | try { | |
252 | 0 | stream.close(); |
253 | 0 | } catch (IOException e) { |
254 | ; | |
255 | 0 | } |
256 | } | |
257 | ||
258 | // The underlying input stream (perhaps from a socket) | |
259 | // is not our responsibility | |
260 | ||
261 | 0 | } |
262 | ||
263 | ||
264 | /** | |
265 | * Set the content length associated with this Request. | |
266 | * | |
267 | * @param length The new content length | |
268 | */ | |
269 | public void setContentLength(int length) { | |
270 | ||
271 | 0 | this.contentLength = length; |
272 | ||
273 | 0 | } |
274 | ||
275 | ||
276 | /** | |
277 | * Set the content type (and optionally the character encoding) | |
278 | * associated with this Request. For example, | |
279 | * <code>text/html; charset=ISO-8859-4</code>. | |
280 | * | |
281 | * @param type The new content type | |
282 | */ | |
283 | public void setContentType(String type) { | |
284 | ||
285 | 0 | this.contentType = type; |
286 | 0 | if (type.indexOf(';') >= 0) { |
287 | //characterEncoding = RequestUtil.parseCharacterEncoding(type); | |
288 | } | |
289 | ||
290 | 0 | } |
291 | ||
292 | ||
293 | ||
294 | /** | |
295 | * Set the protocol name and version associated with this Request. | |
296 | * | |
297 | * @param protocol Protocol name and version | |
298 | */ | |
299 | public void setProtocol(String protocol) { | |
300 | ||
301 | 0 | this.protocol = protocol; |
302 | ||
303 | 0 | } |
304 | ||
305 | ||
306 | /** | |
307 | * Set the IP address of the remote client associated with this Request. | |
308 | * | |
309 | * @param remoteAddr The remote IP address | |
310 | */ | |
311 | public void setRemoteAddr(String remoteAddr) { | |
312 | ||
313 | 0 | this.remoteAddr = remoteAddr; |
314 | ||
315 | 0 | } |
316 | ||
317 | ||
318 | /** | |
319 | * Set the fully qualified name of the remote client associated with this | |
320 | * Request. | |
321 | * | |
322 | * @param remoteHost The remote host name | |
323 | */ | |
324 | public void setRemoteHost(String remoteHost) { | |
325 | ||
326 | 0 | this.remoteHost = remoteHost; |
327 | ||
328 | 0 | } |
329 | ||
330 | ||
331 | /** | |
332 | * Set the name of the scheme associated with this request. Typical values | |
333 | * are <code>http</code>, <code>https</code>, and <code>ftp</code>. | |
334 | * | |
335 | * @param scheme The scheme | |
336 | */ | |
337 | public void setScheme(String scheme) { | |
338 | ||
339 | 0 | this.scheme = scheme; |
340 | ||
341 | 0 | } |
342 | ||
343 | ||
344 | /** | |
345 | * Set the value to be returned by <code>isSecure()</code> | |
346 | * for this Request. | |
347 | * | |
348 | * @param secure The new isSecure value | |
349 | */ | |
350 | public void setSecure(boolean secure) { | |
351 | ||
352 | 0 | this.secure = secure; |
353 | ||
354 | 0 | } |
355 | ||
356 | ||
357 | /** | |
358 | * Set the name of the server (virtual host) to process this request. | |
359 | * | |
360 | * @param name The server name | |
361 | */ | |
362 | public void setServerName(String name) { | |
363 | ||
364 | 0 | this.serverName = name; |
365 | ||
366 | 0 | } |
367 | ||
368 | ||
369 | /** | |
370 | * Set the port number of the server to process this request. | |
371 | * | |
372 | * @param port The server port | |
373 | */ | |
374 | public void setServerPort(int port) { | |
375 | ||
376 | 0 | this.serverPort = port; |
377 | ||
378 | 0 | } |
379 | ||
380 | ||
381 | // ------------------------------------------------- ServletRequest Methods | |
382 | ||
383 | ||
384 | /** | |
385 | * Return the specified request attribute if it exists; otherwise, return | |
386 | * <code>null</code>. | |
387 | * | |
388 | * @param name Name of the request attribute to return | |
389 | */ | |
390 | public Object getAttribute(String name) { | |
391 | ||
392 | 0 | synchronized (attributes) { |
393 | 0 | return (attributes.get(name)); |
394 | 0 | } |
395 | ||
396 | } | |
397 | ||
398 | ||
399 | /** | |
400 | * Return the names of all request attributes for this Request, or an | |
401 | * empty <code>Enumeration</code> if there are none. | |
402 | */ | |
403 | public Enumeration getAttributeNames() { | |
404 | ||
405 | 0 | synchronized (attributes) { |
406 | 0 | return new IteratorEnumeration(attributes.keySet().iterator()); |
407 | 0 | } |
408 | ||
409 | } | |
410 | ||
411 | ||
412 | /** | |
413 | * Return the character encoding for this Request. | |
414 | */ | |
415 | public String getCharacterEncoding() { | |
416 | ||
417 | 0 | if (characterEncoding== null) { |
418 | 0 | characterEncoding= "ISO-8859-1"; |
419 | } | |
420 | 0 | return (this.characterEncoding); |
421 | } | |
422 | ||
423 | ||
424 | /** | |
425 | * Return the content length for this Request. | |
426 | */ | |
427 | public int getContentLength() { | |
428 | ||
429 | 0 | return (this.contentLength); |
430 | ||
431 | } | |
432 | ||
433 | ||
434 | /** | |
435 | * Return the content type for this Request. | |
436 | */ | |
437 | public String getContentType() { | |
438 | ||
439 | 0 | return (contentType); |
440 | ||
441 | } | |
442 | ||
443 | ||
444 | /** | |
445 | * Return the servlet input stream for this Request. The default | |
446 | * implementation returns a servlet input stream created by | |
447 | * <code>createInputStream()</code>. | |
448 | * | |
449 | * @exception IllegalStateException if <code>getReader()</code> has | |
450 | * already been called for this request | |
451 | * @exception IOException if an input/output error occurs | |
452 | */ | |
453 | public ServletInputStream getInputStream() throws IOException { | |
454 | ||
455 | 0 | if (reader != null) { |
456 | 0 | throw new IllegalStateException( "getReader() has already been called" ); |
457 | } | |
458 | ||
459 | 0 | if (stream == null) |
460 | 0 | stream = createInputStream(); |
461 | 0 | return (stream); |
462 | ||
463 | } | |
464 | ||
465 | ||
466 | /** | |
467 | * Return the preferred Locale that the client will accept content in, | |
468 | * based on the value for the first <code>Accept-Language</code> header | |
469 | * that was encountered. If the request did not specify a preferred | |
470 | * language, the server's default Locale is returned. | |
471 | */ | |
472 | public Locale getLocale() { | |
473 | ||
474 | 0 | synchronized (locales) { |
475 | 0 | if (locales.size() > 0) |
476 | 0 | return ((Locale) locales.get(0)); |
477 | else | |
478 | 0 | return (defaultLocale); |
479 | 0 | } |
480 | ||
481 | } | |
482 | ||
483 | ||
484 | /** | |
485 | * Return the set of preferred Locales that the client will accept | |
486 | * content in, based on the values for any <code>Accept-Language</code> | |
487 | * headers that were encountered. If the request did not specify a | |
488 | * preferred language, the server's default Locale is returned. | |
489 | */ | |
490 | public Enumeration getLocales() { | |
491 | ||
492 | 0 | synchronized (locales) { |
493 | 0 | if (locales.size() > 0) { |
494 | 0 | return new IteratorEnumeration( locales.iterator() ); |
495 | } | |
496 | 0 | } |
497 | 0 | return new IteratorEnumeration( new SingletonIterator( defaultLocale ) ); |
498 | ||
499 | } | |
500 | ||
501 | ||
502 | /** | |
503 | * Return the value of the specified request parameter, if any; otherwise, | |
504 | * return <code>null</code>. If there is more than one value defined, | |
505 | * return only the first one. | |
506 | * | |
507 | * @param name Name of the desired request parameter | |
508 | */ | |
509 | public String getParameter(String name) { | |
510 | 0 | String values[] = (String[]) getParameterMap().get(name); |
511 | 0 | if (values != null) |
512 | 0 | return (values[0]); |
513 | else | |
514 | 0 | return (null); |
515 | ||
516 | } | |
517 | ||
518 | ||
519 | /** | |
520 | * Return the defined values for the specified request parameter, if any; | |
521 | * otherwise, return <code>null</code>. | |
522 | * | |
523 | * @param name Name of the desired request parameter | |
524 | */ | |
525 | public String[] getParameterValues(String name) { | |
526 | 0 | String values[] = (String[]) getParameterMap().get(name); |
527 | 0 | if (values != null) |
528 | 0 | return (values); |
529 | else | |
530 | 0 | return (null); |
531 | } | |
532 | ||
533 | ||
534 | /** | |
535 | * Returns a <code>Map</code> of the parameters of this request. | |
536 | * Request parameters are extra information sent with the request. | |
537 | * For HTTP servlets, parameters are contained in the query string | |
538 | * or posted form data. | |
539 | * | |
540 | * @return A <code>Map</code> containing parameter names as keys | |
541 | * and parameter values as map values. | |
542 | */ | |
543 | public Map getParameterMap() { | |
544 | 0 | return new HashMap(); |
545 | } | |
546 | ||
547 | ||
548 | /** | |
549 | * Return the names of all defined request parameters for this request. | |
550 | */ | |
551 | public Enumeration getParameterNames() { | |
552 | 0 | return new IteratorEnumeration(getParameterMap().keySet().iterator()); |
553 | } | |
554 | ||
555 | ||
556 | /** | |
557 | * Return the protocol and version used to make this Request. | |
558 | */ | |
559 | public String getProtocol() { | |
560 | ||
561 | 0 | return (this.protocol); |
562 | ||
563 | } | |
564 | ||
565 | ||
566 | /** | |
567 | * Read the Reader wrapping the input stream for this Request. The | |
568 | * default implementation wraps a <code>BufferedReader</code> around the | |
569 | * servlet input stream returned by <code>createInputStream()</code>. | |
570 | * | |
571 | * @exception IllegalStateException if <code>getInputStream()</code> | |
572 | * has already been called for this request | |
573 | * @exception IOException if an input/output error occurs | |
574 | */ | |
575 | public BufferedReader getReader() throws IOException { | |
576 | ||
577 | 0 | if (stream != null) { |
578 | 0 | throw new IllegalStateException( "getInputStream() has already been called" ); |
579 | } | |
580 | ||
581 | 0 | if (reader == null) { |
582 | 0 | String encoding = getCharacterEncoding(); |
583 | 0 | InputStreamReader isr = |
584 | new InputStreamReader(createInputStream(), encoding); | |
585 | 0 | reader = new BufferedReader(isr); |
586 | } | |
587 | 0 | return (reader); |
588 | ||
589 | } | |
590 | ||
591 | ||
592 | /** | |
593 | * Return the real path of the specified virtual path. | |
594 | * | |
595 | * @param path Path to be translated | |
596 | * | |
597 | * @deprecated As of version 2.1 of the Java Servlet API, use | |
598 | * <code>ServletContext.getRealPath()</code>. | |
599 | */ | |
600 | public String getRealPath(String path) { | |
601 | ||
602 | 0 | if (servletContext == null) |
603 | 0 | return (null); |
604 | else { | |
605 | try { | |
606 | 0 | return (servletContext.getRealPath(path)); |
607 | 0 | } catch (IllegalArgumentException e) { |
608 | 0 | return (null); |
609 | } | |
610 | } | |
611 | ||
612 | } | |
613 | ||
614 | ||
615 | /** | |
616 | * Return the remote IP address making this Request. | |
617 | */ | |
618 | public String getRemoteAddr() { | |
619 | ||
620 | 0 | return (this.remoteAddr); |
621 | ||
622 | } | |
623 | ||
624 | ||
625 | /** | |
626 | * Return the remote host name making this Request. | |
627 | */ | |
628 | public String getRemoteHost() { | |
629 | ||
630 | 0 | return (this.remoteHost); |
631 | ||
632 | } | |
633 | ||
634 | ||
635 | /** | |
636 | * Return a RequestDispatcher that wraps the resource at the specified | |
637 | * path, which may be interpreted as relative to the current request path. | |
638 | * | |
639 | * @param path Path of the resource to be wrapped | |
640 | */ | |
641 | public RequestDispatcher getRequestDispatcher(String path) { | |
642 | 0 | return servletContext.getRequestDispatcher(path); |
643 | } | |
644 | ||
645 | ||
646 | /** | |
647 | * Return the scheme used to make this Request. | |
648 | */ | |
649 | public String getScheme() { | |
650 | ||
651 | 0 | return (this.scheme); |
652 | ||
653 | } | |
654 | ||
655 | ||
656 | /** | |
657 | * Return the server name responding to this Request. | |
658 | */ | |
659 | public String getServerName() { | |
660 | ||
661 | 0 | return (this.serverName); |
662 | ||
663 | } | |
664 | ||
665 | ||
666 | /** | |
667 | * Return the server port responding to this Request. | |
668 | */ | |
669 | public int getServerPort() { | |
670 | ||
671 | 0 | return (this.serverPort); |
672 | ||
673 | } | |
674 | ||
675 | ||
676 | /** | |
677 | * Was this request received on a secure connection? | |
678 | */ | |
679 | public boolean isSecure() { | |
680 | ||
681 | 0 | return (this.secure); |
682 | ||
683 | } | |
684 | ||
685 | ||
686 | /** | |
687 | * Remove the specified request attribute if it exists. | |
688 | * | |
689 | * @param name Name of the request attribute to remove | |
690 | */ | |
691 | public void removeAttribute(String name) { | |
692 | ||
693 | 0 | synchronized (attributes) { |
694 | 0 | attributes.remove(name); |
695 | 0 | } |
696 | ||
697 | 0 | } |
698 | ||
699 | ||
700 | /** | |
701 | * Set the specified request attribute to the specified value. | |
702 | * | |
703 | * @param name Name of the request attribute to set | |
704 | * @param value The associated value | |
705 | */ | |
706 | public void setAttribute(String name, Object value) { | |
707 | ||
708 | // Name cannot be null | |
709 | 0 | if (name == null) { |
710 | 0 | throw new IllegalArgumentException( "Attribute name cannot be null" ); |
711 | } | |
712 | ||
713 | // Null value is the same as removeAttribute() | |
714 | 0 | if (value == null) { |
715 | 0 | removeAttribute(name); |
716 | 0 | return; |
717 | } | |
718 | ||
719 | 0 | synchronized (attributes) { |
720 | 0 | attributes.put(name, value); |
721 | 0 | } |
722 | ||
723 | 0 | } |
724 | ||
725 | ||
726 | /** | |
727 | * Overrides the name of the character encoding used in the body of | |
728 | * this request. This method must be called prior to reading request | |
729 | * parameters or reading input using <code>getReader()</code>. | |
730 | * | |
731 | * @param enc The character encoding to be used | |
732 | * | |
733 | * @exception UnsupportedEncodingException if the specified encoding | |
734 | * is not supported | |
735 | * | |
736 | * @since Servlet 2.3 | |
737 | */ | |
738 | public void setCharacterEncoding(String enc) | |
739 | throws UnsupportedEncodingException { | |
740 | ||
741 | // Ensure that the specified encoding is valid | |
742 | 0 | byte buffer[] = new byte[1]; |
743 | 0 | buffer[0] = (byte) 'a'; |
744 | 0 | String dummy = new String(buffer, enc); |
745 | ||
746 | // Save the validated encoding | |
747 | 0 | this.characterEncoding = enc; |
748 | 0 | } |
749 | ||
750 | /** | |
751 | * Log a message to the current ServletContext | |
752 | * | |
753 | * @param message Message to be logged | |
754 | */ | |
755 | protected void log(String message) { | |
756 | ||
757 | 0 | servletContext.log(message); |
758 | ||
759 | 0 | } |
760 | ||
761 | ||
762 | /** | |
763 | * Log a message to the current ServletContext | |
764 | * | |
765 | * @param message Message to be logged | |
766 | * @param throwable Associated exception | |
767 | */ | |
768 | protected void log(String message, Throwable throwable) { | |
769 | ||
770 | 0 | servletContext.log(message, throwable); |
771 | ||
772 | 0 | } |
773 | ||
774 | } |