##### Coverage Report - org.apache.turbine.util.uri.TurbineURI

Classes in this File | Line Coverage | Branch Coverage | Complexity
TurbineURI |
41% | 76/182
57% | 29/50
| 1.4210526315789473;1,421

1 |  |
     package org.apache.turbine.util.uri;
2 |  |
3 |  |
     /*
4 |  |
      * Licensed to the Apache Software Foundation (ASF) under one
5 |  |
      * or more contributor license agreements.  See the NOTICE file
6 |  |
      * distributed with this work for additional information
7 |  |
      * regarding copyright ownership.  The ASF licenses this file
8 |  |
      * to you under the Apache License, Version 2.0 (the
9 |  |
      * "License"); you may not use this file except in compliance
10 |  |
      * with the License.  You may obtain a copy of the License at
11 |  |
      *
12 |  |
      *   http://www.apache.org/licenses/LICENSE-2.0
13 |  |
      *
14 |  |
      * Unless required by applicable law or agreed to in writing,
15 |  |
      * software distributed under the License is distributed on an
16 |  |
      * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 |  |
      * KIND, either express or implied.  See the License for the
18 |  |
      * specific language governing permissions and limitations
19 |  |
      * under the License.
20 |  |
      */
21 |  |
22 |  |
     import java.io.UnsupportedEncodingException;
23 |  |
     import java.net.URLEncoder;
24 |  |
     import java.util.ArrayList;
25 |  |
     import java.util.Collection;
26 |  |
     import java.util.Iterator;
27 |  |
     import java.util.List;
28 |  |
29 |  |
     import org.apache.commons.lang.StringUtils;
30 |  |
     import org.apache.commons.logging.Log;
31 |  |
     import org.apache.commons.logging.LogFactory;
32 |  |
     import org.apache.fulcrum.parser.ParameterParser;
33 |  |
     import org.apache.fulcrum.parser.ParserService;
34 |  |
     import org.apache.turbine.services.TurbineServices;
35 |  |
     import org.apache.turbine.util.RunData;
36 |  |
     import org.apache.turbine.util.ServerData;
37 |  |
38 |  |
     /**
39 |  |
      * This class allows you to keep all the information needed for a single
40 |  |
      * link at one place. It keeps your query data, path info, the server
41 |  |
      * scheme, name, port and the script path.
42 |  |
      *
43 |  |
      * If you must generate a Turbine Link, use this class.
44 |  |
      *
45 |  |
      * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
46 |  |
      * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
47 |  |
      * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
48 |  |
      * @version $Id: TurbineURI.java 1078552 2011-03-06 19:58:46Z tv $
49 |  |
      */
50 |  |
51 |  |
     public class TurbineURI
52 |  |
             extends BaseURI
53 |  |
     {
54 |  |
         /** Logging */
55 | 8 |
         private static Log log = LogFactory.getLog(TurbineURI.class);
56 |  |
57 |  |
         /** Contains the PathInfo and QueryData vectors */
58 | 26 |
         private List<URIParam> [] dataVectors = null;
59 |  |
60 |  |
         /** Local reference to the parser service for URI parameter folding */
61 |  |
         private ParserService parserService;
62 |  |
63 |  |
         /*
64 |  |
          * ========================================================================
65 |  |
          *
66 |  |
          * Constructors
67 |  |
          *
68 |  |
          * ========================================================================
69 |  |
          *
70 |  |
          */
71 |  |
72 |  |
         /**
73 |  |
          * Empty C'tor. Uses Turbine.getDefaultServerData().
74 |  |
          */
75 |  |
         public TurbineURI()
76 |  |
         {
77 | 0 |
             super();
78 | 0 |
             init();
79 | 0 |
         }
80 |  |
81 |  |
         /**
82 |  |
          * Constructor with a RunData object.
83 |  |
          *
84 |  |
          * @param runData A RunData object
85 |  |
          */
86 |  |
         public TurbineURI(RunData runData)
87 |  |
         {
88 | 16 |
             super(runData);
89 | 16 |
             init();
90 | 16 |
         }
91 |  |
92 |  |
         /**
93 |  |
          * Constructor, set explicit redirection.
94 |  |
          *
95 |  |
          * @param runData A RunData object
96 |  |
          * @param redirect True if redirection allowed.
97 |  |
          */
98 |  |
         public TurbineURI(RunData runData, boolean redirect)
99 |  |
         {
100 | 0 |
             super(runData, redirect);
101 | 0 |
             init();
102 | 0 |
         }
103 |  |
104 |  |
         /**
105 |  |
          * Constructor, set Screen.
106 |  |
          *
107 |  |
          * @param runData A RunData object
108 |  |
          * @param screen A Screen Name
109 |  |
          */
110 |  |
         public TurbineURI(RunData runData, String screen)
111 |  |
         {
112 | 0 |
             this(runData);
113 | 0 |
             setScreen(screen);
114 | 0 |
         }
115 |  |
116 |  |
         /**
117 |  |
          * Constructor, set Screen, set explicit redirection.
118 |  |
          *
119 |  |
          * @param runData A RunData object
120 |  |
          * @param screen A Screen Name
121 |  |
          * @param redirect True if redirection allowed.
122 |  |
          */
123 |  |
         public TurbineURI(RunData runData, String screen, boolean redirect)
124 |  |
         {
125 | 0 |
             this(runData, redirect);
126 | 0 |
             setScreen(screen);
127 | 0 |
         }
128 |  |
129 |  |
         /**
130 |  |
          * Constructor, set Screen and Action.
131 |  |
          *
132 |  |
          * @param runData A RunData object
133 |  |
          * @param screen A Screen Name
134 |  |
          * @param action An Action Name
135 |  |
          */
136 |  |
         public TurbineURI(RunData runData, String screen, String action)
137 |  |
         {
138 | 0 |
             this(runData, screen);
139 | 0 |
             setAction(action);
140 | 0 |
         }
141 |  |
142 |  |
         /**
143 |  |
          * Constructor, set Screen and Action, set explicit redirection.
144 |  |
          *
145 |  |
          * @param runData A RunData object
146 |  |
          * @param screen A Screen Name
147 |  |
          * @param action An Action Name
148 |  |
          * @param redirect True if redirection allowed.
149 |  |
          */
150 |  |
         public TurbineURI(RunData runData, String screen, String action, boolean redirect)
151 |  |
         {
152 | 0 |
             this(runData, screen, redirect);
153 | 0 |
             setAction(action);
154 | 0 |
         }
155 |  |
156 |  |
         /**
157 |  |
          * Constructor with a ServerData object.
158 |  |
          *
159 |  |
          * @param serverData A ServerData object
160 |  |
          */
161 |  |
         public TurbineURI(ServerData serverData)
162 |  |
         {
163 | 10 |
             super(serverData);
164 | 10 |
             init();
165 | 10 |
         }
166 |  |
167 |  |
         /**
168 |  |
          * Constructor, set explicit redirection.
169 |  |
          *
170 |  |
          * @param serverData A ServerData object
171 |  |
          * @param redirect True if redirection allowed.
172 |  |
          */
173 |  |
         public TurbineURI(ServerData serverData, boolean redirect)
174 |  |
         {
175 | 0 |
             super(serverData, redirect);
176 | 0 |
             init();
177 | 0 |
         }
178 |  |
179 |  |
         /**
180 |  |
          * Constructor, set Screen.
181 |  |
          *
182 |  |
          * @param serverData A ServerData object
183 |  |
          * @param screen A Screen Name
184 |  |
          */
185 |  |
         public TurbineURI(ServerData serverData, String screen)
186 |  |
         {
187 | 0 |
             this(serverData);
188 | 0 |
             setScreen(screen);
189 | 0 |
         }
190 |  |
191 |  |
         /**
192 |  |
          * Constructor, set Screen, set explicit redirection.
193 |  |
          *
194 |  |
          * @param serverData A ServerData object
195 |  |
          * @param screen A Screen Name
196 |  |
          * @param redirect True if redirection allowed.
197 |  |
          */
198 |  |
         public TurbineURI(ServerData serverData, String screen, boolean redirect)
199 |  |
         {
200 | 0 |
             this(serverData, redirect);
201 | 0 |
             setScreen(screen);
202 | 0 |
         }
203 |  |
204 |  |
         /**
205 |  |
          * Constructor, set Screen and Action.
206 |  |
          *
207 |  |
          * @param serverData A ServerData object
208 |  |
          * @param screen A Screen Name
209 |  |
          * @param action An Action Name
210 |  |
          */
211 |  |
         public TurbineURI(ServerData serverData, String screen, String action)
212 |  |
         {
213 | 0 |
             this(serverData, screen);
214 | 0 |
             setAction(action);
215 | 0 |
         }
216 |  |
217 |  |
         /**
218 |  |
          * Constructor, set Screen and Action, set explicit redirection.
219 |  |
          *
220 |  |
          * @param serverData A ServerData object
221 |  |
          * @param screen A Screen Name
222 |  |
          * @param action An Action Name
223 |  |
          * @param redirect True if redirection allowed.
224 |  |
          */
225 |  |
         public TurbineURI(ServerData serverData, String screen, String action,
226 |  |
                           boolean redirect)
227 |  |
         {
228 | 0 |
             this(serverData, screen, redirect);
229 | 0 |
             setAction(action);
230 | 0 |
         }
231 |  |
232 |  |
         /**
233 |  |
          * Constructor, user Turbine.getDefaultServerData(), set Screen and Action.
234 |  |
          *
235 |  |
          * @param screen A Screen Name
236 |  |
          * @param action An Action Name
237 |  |
          */
238 |  |
         public TurbineURI(String screen, String action)
239 |  |
         {
240 | 0 |
             this();
241 | 0 |
             setScreen(screen);
242 | 0 |
             setAction(action);
243 | 0 |
         }
244 |  |
245 |  |
         /*
246 |  |
          * ========================================================================
247 |  |
          *
248 |  |
          * Init
249 |  |
          *
250 |  |
          * ========================================================================
251 |  |
          *
252 |  |
          */
253 |  |
254 |  |
         /**
255 |  |
          * Init the TurbineURI.
256 |  |
          */
257 |  |
         @SuppressWarnings("unchecked")
258 |  |
         private void init()
259 |  |
         {
260 | 26 |
             dataVectors = new List[2];
261 | 26 |
             dataVectors[PATH_INFO]  = new ArrayList<URIParam>();
262 | 26 |
             dataVectors[QUERY_DATA] = new ArrayList<URIParam>();
263 | 26 |
             parserService = (ParserService)TurbineServices.getInstance().getService(ParserService.ROLE);
264 | 26 |
         }
265 |  |
266 |  |
         /**
267 |  |
          * Sets the action= value for this URL.
268 |  |
          *
269 |  |
          * By default it adds the information to the path_info instead
270 |  |
          * of the query data. An empty value (null or "") cleans out
271 |  |
          * an existing value.
272 |  |
          *
273 |  |
          * @param action A String with the action value.
274 |  |
          */
275 |  |
         public void setAction(String action)
276 |  |
         {
277 | 0 |
             if(StringUtils.isNotEmpty(action))
278 |  |
             {
279 | 0 |
                 add(PATH_INFO, CGI_ACTION_PARAM, action);
280 |  |
             }
281 |  |
             else
282 |  |
             {
283 | 0 |
                 clearAction();
284 |  |
             }
285 | 0 |
         }
286 |  |
287 |  |
         /**
288 |  |
          * Sets the fired eventSubmit= value for this URL.
289 |  |
          *
290 |  |
          * @param event The event to fire.
291 |  |
          *
292 |  |
          */
293 |  |
         public void setEvent(String event)
294 |  |
         {
295 | 0 |
             add(PATH_INFO, EVENT_PREFIX + event, event);
296 | 0 |
         }
297 |  |
298 |  |
         /**
299 |  |
          * Sets the action= and eventSubmit= values for this URL.
300 |  |
          *
301 |  |
          * By default it adds the information to the path_info instead
302 |  |
          * of the query data. An empty value (null or "") for the action cleans out
303 |  |
          * an existing value.  An empty value (null or "") for the event has no
304 |  |
          * effect.
305 |  |
          *
306 |  |
          * @param action A String with the action value.
307 |  |
          * @param event A string with the event name.
308 |  |
          */
309 |  |
         public void setActionEvent(String action, String event)
310 |  |
         {
311 | 0 |
             setAction(action);
312 | 0 |
             if(StringUtils.isNotEmpty(event))
313 |  |
             {
314 | 0 |
                 setEvent(event);
315 |  |
             }
316 | 0 |
         }
317 |  |
318 |  |
         /**
319 |  |
          * Clears the action= value for this URL.
320 |  |
          */
321 |  |
         public void clearAction()
322 |  |
         {
323 | 0 |
             removePathInfo(CGI_ACTION_PARAM);
324 | 0 |
         }
325 |  |
326 |  |
         /**
327 |  |
          * Sets the screen= value for this URL.
328 |  |
          *
329 |  |
          * By default it adds the information to the path_info instead
330 |  |
          * of the query data. An empty value (null or "") cleans out
331 |  |
          * an existing value.
332 |  |
          *
333 |  |
          * @param screen A String with the screen value.
334 |  |
          */
335 |  |
         public void setScreen(String screen)
336 |  |
         {
337 | 0 |
             if(StringUtils.isNotEmpty(screen))
338 |  |
             {
339 | 0 |
                 add(PATH_INFO, CGI_SCREEN_PARAM, screen);
340 |  |
             }
341 |  |
             else
342 |  |
             {
343 | 0 |
                 clearScreen();
344 |  |
             }
345 | 0 |
         }
346 |  |
347 |  |
         /**
348 |  |
          * Clears the screen= value for this URL.
349 |  |
          */
350 |  |
         public void clearScreen()
351 |  |
         {
352 | 0 |
             removePathInfo(CGI_SCREEN_PARAM);
353 | 0 |
         }
354 |  |
355 |  |
         /*
356 |  |
          * ========================================================================
357 |  |
          *
358 |  |
          * Adding and removing Data from the Path Info and Query Data
359 |  |
          *
360 |  |
          * ========================================================================
361 |  |
          */
362 |  |
363 |  |
364 |  |
         /**
365 |  |
          * Adds a name=value pair for every entry in a ParameterParser
366 |  |
          * object to the path_info string.
367 |  |
          *
368 |  |
          * @param pp A ParameterParser.
369 |  |
          */
370 |  |
         public void addPathInfo(ParameterParser pp)
371 |  |
         {
372 | 0 |
             add(PATH_INFO, pp);
373 | 0 |
         }
374 |  |
375 |  |
         /**
376 |  |
          * Adds an existing List of URIParam objects to
377 |  |
          * the path_info string.
378 |  |
          *
379 |  |
          * @param list A list with URIParam objects.
380 |  |
          */
381 |  |
         public void addPathInfo(List<URIParam> list)
382 |  |
         {
383 | 0 |
             add(PATH_INFO, list);
384 | 0 |
         }
385 |  |
386 |  |
         /**
387 |  |
          * Adds a name=value pair to the path_info string.
388 |  |
          *
389 |  |
          * @param name A String with the name to add.
390 |  |
          * @param value An Object with the value to add.
391 |  |
          */
392 |  |
         public void addPathInfo(String name, Object value)
393 |  |
         {
394 | 0 |
             add(PATH_INFO, name, null == value ? null : value.toString());
395 | 0 |
         }
396 |  |
397 |  |
         /**
398 |  |
          * Adds a name=value pair to the path_info string.
399 |  |
          *
400 |  |
          * @param name A String with the name to add.
401 |  |
          * @param value A String with the value to add.
402 |  |
          */
403 |  |
         public void addPathInfo(String name, String value)
404 |  |
         {
405 | 6 |
             add(PATH_INFO, name, value);
406 | 6 |
         }
407 |  |
408 |  |
         /**
409 |  |
          * Adds a name=value pair to the path_info string.
410 |  |
          *
411 |  |
          * @param name A String with the name to add.
412 |  |
          * @param value A double with the value to add.
413 |  |
          */
414 |  |
         public void addPathInfo(String name, double value)
415 |  |
         {
416 | 0 |
             add(PATH_INFO, name, Double.toString(value));
417 | 0 |
         }
418 |  |
419 |  |
         /**
420 |  |
          * Adds a name=value pair to the path_info string.
421 |  |
          *
422 |  |
          * @param name A String with the name to add.
423 |  |
          * @param value An int with the value to add.
424 |  |
          */
425 |  |
         public void addPathInfo(String name, int value)
426 |  |
         {
427 | 0 |
             add(PATH_INFO, name, Integer.toString(value));
428 | 0 |
         }
429 |  |
430 |  |
         /**
431 |  |
          * Adds a name=value pair to the path_info string.
432 |  |
          *
433 |  |
          * @param name A String with the name to add.
434 |  |
          * @param value A long with the value to add.
435 |  |
          */
436 |  |
         public void addPathInfo(String name, long value)
437 |  |
         {
438 | 0 |
             add(PATH_INFO, name, Long.toString(value));
439 | 0 |
         }
440 |  |
441 |  |
         /**
442 |  |
          * Adds a name=value pair to the query string.
443 |  |
          *
444 |  |
          * @param name A String with the name to add.
445 |  |
          * @param value An Object with the value to add.
446 |  |
          */
447 |  |
         public void addQueryData(String name, Object value)
448 |  |
         {
449 | 0 |
             add(QUERY_DATA, name, null == value ? null : value.toString());
450 | 0 |
         }
451 |  |
452 |  |
         /**
453 |  |
          * Adds a name=value pair to the query string.
454 |  |
          *
455 |  |
          * @param name A String with the name to add.
456 |  |
          * @param value A String with the value to add.
457 |  |
          */
458 |  |
         public void addQueryData(String name, String value)
459 |  |
         {
460 | 6 |
             add(QUERY_DATA, name, value);
461 | 6 |
         }
462 |  |
463 |  |
         /**
464 |  |
          * Adds a name=value pair to the query string.
465 |  |
          *
466 |  |
          * @param name A String with the name to add.
467 |  |
          * @param value A double with the value to add.
468 |  |
          */
469 |  |
         public void addQueryData(String name, double value)
470 |  |
         {
471 | 0 |
             add(QUERY_DATA, name, Double.toString(value));
472 | 0 |
         }
473 |  |
474 |  |
         /**
475 |  |
          * Adds a name=value pair to the query string.
476 |  |
          *
477 |  |
          * @param name A String with the name to add.
478 |  |
          * @param value An int with the value to add.
479 |  |
          */
480 |  |
         public void addQueryData(String name, int value)
481 |  |
         {
482 | 0 |
             add(QUERY_DATA, name, Integer.toString(value));
483 | 0 |
         }
484 |  |
485 |  |
         /**
486 |  |
          * Adds a name=value pair to the query string.
487 |  |
          *
488 |  |
          * @param name A String with the name to add.
489 |  |
          * @param value A long with the value to add.
490 |  |
          */
491 |  |
         public void addQueryData(String name, long value)
492 |  |
         {
493 | 0 |
             add(QUERY_DATA, name, Long.toString(value));
494 | 0 |
         }
495 |  |
496 |  |
         /**
497 |  |
          * Adds a name=value pair for every entry in a ParameterParser
498 |  |
          * object to the query string.
499 |  |
          *
500 |  |
          * @param pp A ParameterParser.
501 |  |
          */
502 |  |
         public void addQueryData(ParameterParser pp)
503 |  |
         {
504 | 0 |
             add(QUERY_DATA, pp);
505 | 0 |
         }
506 |  |
507 |  |
         /**
508 |  |
          * Adds an existing List of URIParam objects to the query data.
509 |  |
          *
510 |  |
          * @param list A list with URIParam objects.
511 |  |
          */
512 |  |
         public void addQueryData(List<URIParam> list)
513 |  |
         {
514 | 0 |
             add(QUERY_DATA, list);
515 | 0 |
         }
516 |  |
517 |  |
         /**
518 |  |
          * Is Path Info data set in this URI?
519 |  |
          *
520 |  |
          * @return true if Path Info has values
521 |  |
          */
522 |  |
         public boolean hasPathInfo()
523 |  |
         {
524 | 40 |
             return !dataVectors[PATH_INFO].isEmpty();
525 |  |
         }
526 |  |
527 |  |
         /**
528 |  |
          * Removes all the path info elements.
529 |  |
          */
530 |  |
         public void removePathInfo()
531 |  |
         {
532 | 0 |
             dataVectors[PATH_INFO].clear();
533 | 0 |
         }
534 |  |
535 |  |
         /**
536 |  |
          * Removes a name=value pair from the path info.
537 |  |
          *
538 |  |
          * @param name A String with the name to be removed.
539 |  |
          */
540 |  |
         public void removePathInfo(String name)
541 |  |
         {
542 | 6 |
             remove(PATH_INFO, name);
543 | 6 |
         }
544 |  |
545 |  |
         /**
546 |  |
          * Is Query data set in this URI?
547 |  |
          *
548 |  |
          * @return true if Query data has values
549 |  |
          */
550 |  |
         public boolean hasQueryData()
551 |  |
         {
552 | 40 |
             return !dataVectors[QUERY_DATA].isEmpty();
553 |  |
         }
554 |  |
555 |  |
         /**
556 |  |
          * Removes all the query string elements.
557 |  |
          */
558 |  |
         public void removeQueryData()
559 |  |
         {
560 | 0 |
             dataVectors[QUERY_DATA].clear();
561 | 0 |
         }
562 |  |
563 |  |
         /**
564 |  |
          * Removes a name=value pair from the query string.
565 |  |
          *
566 |  |
          * @param name A String with the name to be removed.
567 |  |
          */
568 |  |
         public void removeQueryData(String name)
569 |  |
         {
570 | 10 |
             remove (QUERY_DATA, name);
571 | 10 |
         }
572 |  |
573 |  |
         /**
574 |  |
          * Template Link and friends want to be able to turn the encoding
575 |  |
          * of the servlet container off. After calling this method,
576 |  |
          * the no encoding will happen any longer. If you think, that you
577 |  |
          * need this outside a template context, think again.
578 |  |
          */
579 |  |
         public void clearResponse()
580 |  |
         {
581 | 0 |
             setResponse(null);
582 | 0 |
         }
583 |  |
584 |  |
585 |  |
         /**
586 |  |
          * Builds the URL with all of the data URL-encoded as well as
587 |  |
          * encoded using HttpServletResponse.encodeUrl(). The resulting
588 |  |
          * URL is absolute; it starts with http/https...
589 |  |
          *
590 |  |
          * <p>
591 |  |
          * <code><pre>
592 |  |
          * TurbineURI tui = new TurbineURI (data, "UserScreen");
593 |  |
          * tui.addPathInfo("user","jon");
594 |  |
          * tui.getAbsoluteLink();
595 |  |
          * </pre></code>
596 |  |
          *
597 |  |
          *  The above call to absoluteLink() would return the String:
598 |  |
          *
599 |  |
          * <p>
600 |  |
          * http://www.server.com/servlets/Turbine/screen/UserScreen/user/jon
601 |  |
          *
602 |  |
          * @return A String with the built URL.
603 |  |
          */
604 |  |
         public String getAbsoluteLink()
605 |  |
         {
606 | 0 |
             StringBuffer output = new StringBuffer();
607 |  |
608 | 0 |
             getSchemeAndPort(output);
609 |  |
610 | 0 |
             buildRelativeLink(output);
611 |  |
612 |  |
             //
613 |  |
             // Encode Response does all the fixup for the Servlet Container
614 |  |
             //
615 | 0 |
             return encodeResponse(output.toString());
616 |  |
         }
617 |  |
618 |  |
         /**
619 |  |
          * Builds the URL with all of the data URL-encoded as well as
620 |  |
          * encoded using HttpServletResponse.encodeUrl(). The resulting
621 |  |
          * URL is relative to the webserver root.
622 |  |
          *
623 |  |
          * <p>
624 |  |
          * <code><pre>
625 |  |
          * TurbineURI tui = new TurbineURI (data, "UserScreen");
626 |  |
          * tui.addPathInfo("user","jon");
627 |  |
          * tui.getRelativeLink();
628 |  |
          * </pre></code>
629 |  |
          *
630 |  |
          *  The above call to relativeLink() would return the String:
631 |  |
          *
632 |  |
          * <p>
633 |  |
          * /servlets/Turbine/screen/UserScreen/user/jon
634 |  |
          *
635 |  |
          * @return A String with the built URL.
636 |  |
          */
637 |  |
         public String getRelativeLink()
638 |  |
         {
639 | 28 |
             StringBuffer output = new StringBuffer();
640 |  |
641 | 28 |
             buildRelativeLink(output);
642 |  |
643 |  |
             //
644 |  |
             // Encode Response does all the fixup for the Servlet Container
645 |  |
             //
646 | 28 |
             return encodeResponse(output.toString());
647 |  |
         }
648 |  |
649 |  |
         /**
650 |  |
          * Add everything needed for a relative link to the passed StringBuffer.
651 |  |
          *
652 |  |
          * @param output A Stringbuffer
653 |  |
          */
654 |  |
         private void buildRelativeLink(StringBuffer output)
655 |  |
         {
656 | 28 |
             getContextAndScript(output);
657 |  |
658 | 28 |
             if (hasPathInfo())
659 |  |
             {
660 | 4 |
                 output.append('/');
661 | 4 |
                 getPathInfoAsString(output);
662 |  |
             }
663 |  |
664 | 28 |
             if (hasReference())
665 |  |
             {
666 | 0 |
                 output.append('#');
667 | 0 |
                 output.append(getReference());
668 |  |
             }
669 |  |
670 | 28 |
             if (hasQueryData())
671 |  |
             {
672 | 6 |
                 output.append('?');
673 | 6 |
                 getQueryDataAsString(output);
674 |  |
             }
675 | 28 |
         }
676 |  |
677 |  |
         /**
678 |  |
          * Gets the current Query Data List.
679 |  |
          *
680 |  |
          * @return A List which contains all query data keys. The keys
681 |  |
          * are URIParam objects.
682 |  |
          */
683 |  |
         public List<URIParam> getPathInfo()
684 |  |
         {
685 | 0 |
             return dataVectors[PATH_INFO];
686 |  |
         }
687 |  |
688 |  |
         /**
689 |  |
          * Sets the Query Data List. Replaces the current query data list
690 |  |
          * with the one supplied. The list must contain only URIParam
691 |  |
          * objects!
692 |  |
          *
693 |  |
          * @param pathInfo A List with new param objects.
694 |  |
          */
695 |  |
696 |  |
         public void setPathInfo(List<URIParam> pathInfo)
697 |  |
         {
698 | 0 |
             dataVectors[PATH_INFO] = pathInfo;
699 | 0 |
         }
700 |  |
701 |  |
         /**
702 |  |
          * Gets the current Query Data List.
703 |  |
          *
704 |  |
          * @return A List which contains all query data keys. The keys
705 |  |
          * are URIParam objects.
706 |  |
          */
707 |  |
         public List<URIParam> getQueryData()
708 |  |
         {
709 | 0 |
             return dataVectors[QUERY_DATA];
710 |  |
         }
711 |  |
712 |  |
         /**
713 |  |
          * Sets the Query Data List. Replaces the current query data list
714 |  |
          * with the one supplied. The list must contain only URIParam
715 |  |
          * objects!
716 |  |
          *
717 |  |
          * @param queryData A List with new param objects.
718 |  |
          */
719 |  |
720 |  |
         public void setQueryData(List<URIParam> queryData)
721 |  |
         {
722 | 0 |
             dataVectors[QUERY_DATA] = queryData;
723 | 0 |
         }
724 |  |
725 |  |
         /**
726 |  |
          * Simply calls getAbsoluteLink(). You should not use this in your
727 |  |
          * code unless you have to. Use getAbsoluteLink.
728 |  |
          *
729 |  |
          * @return This URI as a String
730 |  |
          *
731 |  |
          */
732 |  |
         @Override
733 |  |
         public String toString()
734 |  |
         {
735 | 0 |
             return getAbsoluteLink();
736 |  |
         }
737 |  |
738 |  |
         /*
739 |  |
          * ========================================================================
740 |  |
          *
741 |  |
          * Protected / Private Methods
742 |  |
          *
743 |  |
          * ========================================================================
744 |  |
          *
745 |  |
          */
746 |  |
747 |  |
         /**
748 |  |
          * Returns the Path Info data as a String.
749 |  |
          *
750 |  |
          * @param output The StringBuffer that should hold the path info.
751 |  |
          */
752 |  |
         private void getPathInfoAsString(StringBuffer output)
753 |  |
         {
754 | 4 |
             doEncode(output, dataVectors[PATH_INFO], '/', '/');
755 | 4 |
         }
756 |  |
757 |  |
         /**
758 |  |
          * Returns the Query data as a String.
759 |  |
          *
760 |  |
          * @param output The StringBuffer that should hold the query data.
761 |  |
          */
762 |  |
         private void getQueryDataAsString(StringBuffer output)
763 |  |
         {
764 | 6 |
             doEncode(output, dataVectors[QUERY_DATA], '&', '=');
765 | 6 |
         }
766 |  |
767 |  |
         /**
768 |  |
          * Does the actual encoding for pathInfoAsString and queryDataAsString.
769 |  |
          *
770 |  |
          * @param output The Stringbuffer that should contain the information.
771 |  |
          * @param list A Collection
772 |  |
          * @param fieldDelim A char which is used to separate key/value pairs
773 |  |
          * @param valueDelim A char which is used to separate key and value
774 |  |
          */
775 |  |
         private void doEncode(StringBuffer output, Collection<URIParam> list, char fieldDelim, char valueDelim)
776 |  |
         {
777 | 10 |
             if(!list.isEmpty())
778 |  |
             {
779 | 10 |
                     String encoding = parserService.getParameterEncoding();
780 |  |
781 | 10 |
                 for(Iterator<URIParam> it = list.iterator(); it.hasNext();)
782 |  |
                 {
783 |  |
                         try
784 |  |
                         {
785 | 10 |
                                             URIParam uriParam = it.next();
786 | 10 |
                                             String key = URLEncoder.encode(uriParam.getKey(), encoding);
787 | 10 |
                                             String val = null == uriParam.getValue()
788 |  |
                                                     ? null : String.valueOf(uriParam.getValue());
789 |  |
790 | 10 |
                                             output.append(key);
791 | 10 |
                                             output.append(valueDelim);
792 |  |
793 | 10 |
                                             if(StringUtils.isEmpty(val))
794 |  |
                                             {
795 | 10 |
                                                 if (val == null)
796 |  |
                                                 {
797 | 4 |
                                                     if (log.isWarnEnabled())
798 |  |
                                                     {
799 | 4 |
                                                         log.warn("Found a null value for " + key);
800 |  |
                                                     }
801 |  |
                                                     // For backwards compatibility:
802 | 4 |
                                                     val = "null";
803 |  |
                                                 }
804 | 10 |
                                                 output.append(val);
805 |  |
                                             }
806 |  |
                                             else
807 |  |
                                             {
808 | 0 |
                                                 output.append(URLEncoder.encode(val, encoding));
809 |  |
                                             }
810 |  |
811 | 10 |
                                             if (it.hasNext())
812 |  |
                                             {
813 | 0 |
                                                 output.append(fieldDelim);
814 |  |
                                             }
815 |  |
                                     }
816 | 0 |
                         catch (UnsupportedEncodingException e)
817 |  |
                         {
818 | 0 |
                                 log.warn("Unsupported encoding " + encoding);
819 | 10 |
                                     }
820 |  |
                 }
821 |  |
             }
822 | 10 |
         }
823 |  |
824 |  |
         /**
825 |  |
          * If the type is PATH_INFO, then add name/value to the pathInfo
826 |  |
          * hashtable.
827 |  |
          * <p>
828 |  |
          * If the type is QUERY_DATA, then add name/value to the queryData
829 |  |
          * hashtable.
830 |  |
          *
831 |  |
          * @param type Type (PATH_INFO or QUERY_DATA) of insertion.
832 |  |
          * @param name A String with the name to add.
833 |  |
          * @param value A String with the value to add.
834 |  |
          */
835 |  |
         protected void add(int type,
836 |  |
                 String name,
837 |  |
                 String value)
838 |  |
         {
839 | 14 |
             URIParam uriParam = new URIParam(parserService.convertAndTrim(name), value);
840 |  |
841 | 14 |
             dataVectors[type].add(uriParam); // Code so clean you can eat from...
842 | 14 |
         }
843 |  |
844 |  |
         /**
845 |  |
          * Method for a quick way to add all the parameters in a
846 |  |
          * ParameterParser.
847 |  |
          *
848 |  |
          * <p>If the type is P (0), then add name/value to the pathInfo
849 |  |
          * hashtable.
850 |  |
          *
851 |  |
          * <p>If the type is Q (1), then add name/value to the queryData
852 |  |
          * hashtable.
853 |  |
          *
854 |  |
          * @param type Type of insertion (@see #add(char type, String name, String value))
855 |  |
          * @param pp A ParameterParser.
856 |  |
          */
857 |  |
         protected void add(int type,
858 |  |
                 ParameterParser pp)
859 |  |
         {
860 | 6 |
             for(Iterator<?> it = pp.keySet().iterator(); it.hasNext();)
861 |  |
             {
862 | 2 |
                 String key = (String) it.next();
863 |  |
864 | 2 |
                 if (!key.equalsIgnoreCase(CGI_ACTION_PARAM) &&
865 |  |
                         !key.equalsIgnoreCase(CGI_SCREEN_PARAM))
866 |  |
                 {
867 | 2 |
                     String[] values = pp.getStrings(key);
868 | 2 |
                     if(values != null)
869 |  |
                     {
870 | 4 |
                         for (int i = 0; i < values.length; i++)
871 |  |
                         {
872 | 2 |
                             add(type, key, values[i]);
873 |  |
                         }
874 |  |
                     }
875 |  |
                     else
876 |  |
                     {
877 | 0 |
                         add(type, key, "");
878 |  |
                     }
879 |  |
                 }
880 | 2 |
             }
881 | 6 |
         }
882 |  |
883 |  |
         /**
884 |  |
          * Method for a quick way to add all the parameters in a
885 |  |
          * List with URIParam objects.
886 |  |
          *
887 |  |
          * <p>If the type is P (0), then add name/value to the pathInfo
888 |  |
          * hashtable.
889 |  |
          *
890 |  |
          * <p>If the type is Q (1), then add name/value to the queryData
891 |  |
          * hashtable.
892 |  |
          *
893 |  |
          * @param type Type of insertion (@see #add(char type, String name, String value))
894 |  |
          * @param list A List of URIParam objects
895 |  |
          */
896 |  |
         protected void add(int type, List<URIParam> list)
897 |  |
         {
898 | 0 |
             for (URIParam uriParam : list)
899 |  |
             {
900 | 0 |
                 dataVectors[type].add(uriParam);
901 |  |
             }
902 | 0 |
         }
903 |  |
904 |  |
         /**
905 |  |
          * If the type is P (0), then remove name/value from the
906 |  |
          * pathInfo hashtable.
907 |  |
          *
908 |  |
          * <p>If the type is Q (1), then remove name/value from the
909 |  |
          * queryData hashtable.
910 |  |
          *
911 |  |
          * @param type Type (P or Q) of removal.
912 |  |
          * @param name A String with the name to be removed.
913 |  |
          */
914 |  |
         protected void remove (int type, String name)
915 |  |
         {
916 | 16 |
             Collection<URIParam> c = dataVectors[type];
917 | 16 |
             String key = parserService.convertAndTrim(name);
918 |  |
919 | 16 |
             for (Iterator<URIParam> it = c.iterator(); it.hasNext();)
920 |  |
             {
921 | 14 |
                 URIParam uriParam = it.next();
922 |  |
923 | 14 |
                 if (key.equals(uriParam.getKey()))
924 |  |
                 {
925 | 14 |
                     it.remove();
926 |  |
                 }
927 | 14 |
             }
928 | 16 |
         }
929 |  |
     }