KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > turbine > util > uri > TurbineURI


1 package org.apache.turbine.util.uri;
2
3 /*
4  * Copyright 2001-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 import java.net.URLEncoder JavaDoc;
20
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import org.apache.commons.lang.StringUtils;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import org.apache.turbine.util.RunData;
32 import org.apache.turbine.util.ServerData;
33 import org.apache.turbine.util.parser.ParameterParser;
34 import org.apache.turbine.util.parser.ParserUtils;
35
36 /**
37  * This class allows you to keep all the information needed for a single
38  * link at one place. It keeps your query data, path info, the server
39  * scheme, name, port and the script path.
40  *
41  * If you must generate a Turbine Link, use this class.
42  *
43  * @author <a HREF="mailto:jon@clearink.com">Jon S. Stevens</a>
44  * @author <a HREF="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
45  * @author <a HREF="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
46  * @version $Id: TurbineURI.java,v 1.8.2.3 2004/10/08 12:20:42 henning Exp $
47  */

48
49 public class TurbineURI
50         extends BaseURI
51 {
52     /** Logging */
53     private static Log log = LogFactory.getLog(TurbineURI.class);
54
55     /** Contains the PathInfo and QueryData vectors */
56     private List JavaDoc [] dataVectors = null;
57
58     /*
59      * ========================================================================
60      *
61      * Constructors
62      *
63      * ========================================================================
64      *
65      */

66
67     /**
68      * Empty C'tor. Uses Turbine.getDefaultServerData().
69      */

70     public TurbineURI()
71     {
72         super();
73         init();
74     }
75
76     /**
77      * Constructor with a RunData object.
78      *
79      * @param runData A RunData object
80      */

81     public TurbineURI(RunData runData)
82     {
83         super(runData);
84         init();
85     }
86
87     /**
88      * Constructor, set explicit redirection.
89      *
90      * @param runData A RunData object
91      * @param redirect True if redirection allowed.
92      */

93     public TurbineURI(RunData runData, boolean redirect)
94     {
95         super(runData, redirect);
96         init();
97     }
98
99     /**
100      * Constructor, set Screen.
101      *
102      * @param runData A RunData object
103      * @param screen A Screen Name
104      */

105     public TurbineURI(RunData runData, String JavaDoc screen)
106     {
107         this(runData);
108         setScreen(screen);
109     }
110
111     /**
112      * Constructor, set Screen, set explicit redirection.
113      *
114      * @param runData A RunData object
115      * @param screen A Screen Name
116      * @param redirect True if redirection allowed.
117      */

118     public TurbineURI(RunData runData, String JavaDoc screen, boolean redirect)
119     {
120         this(runData, redirect);
121         setScreen(screen);
122     }
123
124     /**
125      * Constructor, set Screen and Action.
126      *
127      * @param runData A RunData object
128      * @param screen A Screen Name
129      * @param action An Action Name
130      */

131     public TurbineURI(RunData runData, String JavaDoc screen, String JavaDoc action)
132     {
133         this(runData, screen);
134         setAction(action);
135     }
136
137     /**
138      * Constructor, set Screen and Action, set explicit redirection.
139      *
140      * @param runData A RunData object
141      * @param screen A Screen Name
142      * @param action An Action Name
143      * @param redirect True if redirection allowed.
144      */

145     public TurbineURI(RunData runData, String JavaDoc screen, String JavaDoc action, boolean redirect)
146     {
147         this(runData, screen, redirect);
148         setAction(action);
149     }
150
151     /**
152      * Constructor with a ServerData object.
153      *
154      * @param serverData A ServerData object
155      */

156     public TurbineURI(ServerData serverData)
157     {
158         super(serverData);
159         init();
160     }
161
162     /**
163      * Constructor, set explicit redirection.
164      *
165      * @param serverData A ServerData object
166      * @param redirect True if redirection allowed.
167      */

168     public TurbineURI(ServerData serverData, boolean redirect)
169     {
170         super(serverData, redirect);
171         init();
172     }
173
174     /**
175      * Constructor, set Screen.
176      *
177      * @param serverData A ServerData object
178      * @param screen A Screen Name
179      */

180     public TurbineURI(ServerData serverData, String JavaDoc screen)
181     {
182         this(serverData);
183         setScreen(screen);
184     }
185
186     /**
187      * Constructor, set Screen, set explicit redirection.
188      *
189      * @param serverData A ServerData object
190      * @param screen A Screen Name
191      * @param redirect True if redirection allowed.
192      */

193     public TurbineURI(ServerData serverData, String JavaDoc screen, boolean redirect)
194     {
195         this(serverData, redirect);
196         setScreen(screen);
197     }
198
199     /**
200      * Constructor, set Screen and Action.
201      *
202      * @param serverData A ServerData object
203      * @param screen A Screen Name
204      * @param action An Action Name
205      */

206     public TurbineURI(ServerData serverData, String JavaDoc screen, String JavaDoc action)
207     {
208         this(serverData, screen);
209         setAction(action);
210     }
211
212     /**
213      * Constructor, set Screen and Action, set explicit redirection.
214      *
215      * @param serverData A ServerData object
216      * @param screen A Screen Name
217      * @param action An Action Name
218      * @param redirect True if redirection allowed.
219      */

220     public TurbineURI(ServerData serverData, String JavaDoc screen, String JavaDoc action,
221                       boolean redirect)
222     {
223         this(serverData, screen, redirect);
224         setAction(action);
225     }
226
227     /**
228      * Constructor, user Turbine.getDefaultServerData(), set Screen and Action.
229      *
230      * @param screen A Screen Name
231      * @param action An Action Name
232      */

233     public TurbineURI(String JavaDoc screen, String JavaDoc action)
234     {
235         this();
236         setScreen(screen);
237         setAction(action);
238     }
239
240     /*
241      * ========================================================================
242      *
243      * Init
244      *
245      * ========================================================================
246      *
247      */

248
249     /**
250      * Init the TurbineURI.
251      */

252     private void init()
253     {
254         dataVectors = new List JavaDoc[2];
255         dataVectors[PATH_INFO] = new ArrayList JavaDoc();
256         dataVectors[QUERY_DATA] = new ArrayList JavaDoc();
257     }
258
259     /**
260      * Sets the action= value for this URL.
261      *
262      * By default it adds the information to the path_info instead
263      * of the query data. An empty value (null or "") cleans out
264      * an existing value.
265      *
266      * @param action A String with the action value.
267      */

268     public void setAction(String JavaDoc action)
269     {
270         if(StringUtils.isNotEmpty(action))
271         {
272             add(PATH_INFO, CGI_ACTION_PARAM, action);
273         }
274         else
275         {
276             clearAction();
277         }
278     }
279
280     /**
281      * Sets the fired eventSubmit= value for this URL.
282      *
283      * @param event The event to fire.
284      *
285      */

286     public void setEvent(String JavaDoc event)
287     {
288         add(PATH_INFO, EVENT_PREFIX + event, event);
289     }
290
291     /**
292      * Sets the action= and eventSubmit= values for this URL.
293      *
294      * By default it adds the information to the path_info instead
295      * of the query data. An empty value (null or "") for the action cleans out
296      * an existing value. An empty value (null or "") for the event has no
297      * effect.
298      *
299      * @param action A String with the action value.
300      * @param event A string with the event name.
301      */

302     public void setActionEvent(String JavaDoc action, String JavaDoc event)
303     {
304         setAction(action);
305         if(StringUtils.isNotEmpty(event))
306         {
307             setEvent(event);
308         }
309     }
310
311     /**
312      * Clears the action= value for this URL.
313      */

314     public void clearAction()
315     {
316         removePathInfo(CGI_ACTION_PARAM);
317     }
318
319     /**
320      * Sets the screen= value for this URL.
321      *
322      * By default it adds the information to the path_info instead
323      * of the query data. An empty value (null or "") cleans out
324      * an existing value.
325      *
326      * @param screen A String with the screen value.
327      */

328     public void setScreen(String JavaDoc screen)
329     {
330         if(StringUtils.isNotEmpty(screen))
331         {
332             add(PATH_INFO, CGI_SCREEN_PARAM, screen);
333         }
334         else
335         {
336             clearScreen();
337         }
338     }
339
340     /**
341      * Clears the screen= value for this URL.
342      */

343     public void clearScreen()
344     {
345         removePathInfo(CGI_SCREEN_PARAM);
346     }
347
348     /*
349      * ========================================================================
350      *
351      * Adding and removing Data from the Path Info and Query Data
352      *
353      * ========================================================================
354      */

355
356
357     /**
358      * Adds a name=value pair for every entry in a ParameterParser
359      * object to the path_info string.
360      *
361      * @param pp A ParameterParser.
362      */

363     public void addPathInfo(ParameterParser pp)
364     {
365         add(PATH_INFO, pp);
366     }
367
368     /**
369      * Adds an existing List of URIParam objects to
370      * the path_info string.
371      *
372      * @param list A list with URIParam objects.
373      */

374     public void addPathInfo(List JavaDoc list)
375     {
376         add(PATH_INFO, list);
377     }
378
379     /**
380      * Adds a name=value pair to the path_info string.
381      *
382      * @param name A String with the name to add.
383      * @param value An Object with the value to add.
384      */

385     public void addPathInfo(String JavaDoc name, Object JavaDoc value)
386     {
387         add(PATH_INFO, name, value.toString());
388     }
389
390     /**
391      * Adds a name=value pair to the path_info string.
392      *
393      * @param name A String with the name to add.
394      * @param value A String with the value to add.
395      */

396     public void addPathInfo(String JavaDoc name, String JavaDoc value)
397     {
398         add(PATH_INFO, name, value);
399     }
400
401     /**
402      * Adds a name=value pair to the path_info string.
403      *
404      * @param name A String with the name to add.
405      * @param value A double with the value to add.
406      */

407     public void addPathInfo(String JavaDoc name, double value)
408     {
409         add(PATH_INFO, name, Double.toString(value));
410     }
411
412     /**
413      * Adds a name=value pair to the path_info string.
414      *
415      * @param name A String with the name to add.
416      * @param value An int with the value to add.
417      */

418     public void addPathInfo(String JavaDoc name, int value)
419     {
420         add(PATH_INFO, name, Integer.toString(value));
421     }
422
423     /**
424      * Adds a name=value pair to the path_info string.
425      *
426      * @param name A String with the name to add.
427      * @param value A long with the value to add.
428      */

429     public void addPathInfo(String JavaDoc name, long value)
430     {
431         add(PATH_INFO, name, Long.toString(value));
432     }
433
434     /**
435      * Adds a name=value pair to the query string.
436      *
437      * @param name A String with the name to add.
438      * @param value An Object with the value to add.
439      */

440     public void addQueryData(String JavaDoc name, Object JavaDoc value)
441     {
442         add(QUERY_DATA, name, value.toString());
443     }
444
445     /**
446      * Adds a name=value pair to the query string.
447      *
448      * @param name A String with the name to add.
449      * @param value A String with the value to add.
450      */

451     public void addQueryData(String JavaDoc name, String JavaDoc value)
452     {
453         add(QUERY_DATA, name, value);
454     }
455
456     /**
457      * Adds a name=value pair to the query string.
458      *
459      * @param name A String with the name to add.
460      * @param value A double with the value to add.
461      */

462     public void addQueryData(String JavaDoc name, double value)
463     {
464         add(QUERY_DATA, name, Double.toString(value));
465     }
466
467     /**
468      * Adds a name=value pair to the query string.
469      *
470      * @param name A String with the name to add.
471      * @param value An int with the value to add.
472      */

473     public void addQueryData(String JavaDoc name, int value)
474     {
475         add(QUERY_DATA, name, Integer.toString(value));
476     }
477
478     /**
479      * Adds a name=value pair to the query string.
480      *
481      * @param name A String with the name to add.
482      * @param value A long with the value to add.
483      */

484     public void addQueryData(String JavaDoc name, long value)
485     {
486         add(QUERY_DATA, name, Long.toString(value));
487     }
488
489     /**
490      * Adds a name=value pair for every entry in a ParameterParser
491      * object to the query string.
492      *
493      * @param pp A ParameterParser.
494      */

495     public void addQueryData(ParameterParser pp)
496     {
497         add(QUERY_DATA, pp);
498     }
499
500     /**
501      * Adds an existing List of URIParam objects to the query data.
502      *
503      * @param list A list with URIParam objects.
504      */

505     public void addQueryData(List JavaDoc list)
506     {
507         add(QUERY_DATA, list);
508     }
509
510     /**
511      * Is Path Info data set in this URI?
512      *
513      * @return true if Path Info has values
514      */

515     public boolean hasPathInfo()
516     {
517         return !dataVectors[PATH_INFO].isEmpty();
518     }
519
520     /**
521      * Removes all the path info elements.
522      */

523     public void removePathInfo()
524     {
525         dataVectors[PATH_INFO].clear();
526     }
527
528     /**
529      * Removes a name=value pair from the path info.
530      *
531      * @param name A String with the name to be removed.
532      */

533     public void removePathInfo(String JavaDoc name)
534     {
535         remove(PATH_INFO, name);
536     }
537
538     /**
539      * Is Query data set in this URI?
540      *
541      * @return true if Query data has values
542      */

543     public boolean hasQueryData()
544     {
545         return !dataVectors[QUERY_DATA].isEmpty();
546     }
547
548     /**
549      * Removes all the query string elements.
550      */

551     public void removeQueryData()
552     {
553         dataVectors[QUERY_DATA].clear();
554     }
555
556     /**
557      * Removes a name=value pair from the query string.
558      *
559      * @param name A String with the name to be removed.
560      */

561     public void removeQueryData(String JavaDoc name)
562     {
563         remove (QUERY_DATA, name);
564     }
565
566     /**
567      * Template Link and friends want to be able to turn the encoding
568      * of the servlet container off. After calling this method,
569      * the no encoding will happen any longer. If you think, that you
570      * need this outside a template context, think again.
571      */

572     public void clearResponse()
573     {
574         setResponse(null);
575     }
576
577
578     /**
579      * Builds the URL with all of the data URL-encoded as well as
580      * encoded using HttpServletResponse.encodeUrl(). The resulting
581      * URL is absolute; it starts with http/https...
582      *
583      * <p>
584      * <code><pre>
585      * TurbineURI tui = new TurbineURI (data, "UserScreen");
586      * tui.addPathInfo("user","jon");
587      * tui.getAbsoluteLink();
588      * </pre></code>
589      *
590      * The above call to absoluteLink() would return the String:
591      *
592      * <p>
593      * http://www.server.com/servlets/Turbine/screen/UserScreen/user/jon
594      *
595      * @return A String with the built URL.
596      */

597     public String JavaDoc getAbsoluteLink()
598     {
599         StringBuffer JavaDoc output = new StringBuffer JavaDoc();
600
601         getSchemeAndPort(output);
602
603         buildRelativeLink(output);
604
605         //
606
// Encode Response does all the fixup for the Servlet Container
607
//
608
return encodeResponse(output.toString());
609     }
610
611     /**
612      * Builds the URL with all of the data URL-encoded as well as
613      * encoded using HttpServletResponse.encodeUrl(). The resulting
614      * URL is relative to the webserver root.
615      *
616      * <p>
617      * <code><pre>
618      * TurbineURI tui = new TurbineURI (data, "UserScreen");
619      * tui.addPathInfo("user","jon");
620      * tui.getRelativeLink();
621      * </pre></code>
622      *
623      * The above call to relativeLink() would return the String:
624      *
625      * <p>
626      * /servlets/Turbine/screen/UserScreen/user/jon
627      *
628      * @return A String with the built URL.
629      */

630     public String JavaDoc getRelativeLink()
631     {
632         StringBuffer JavaDoc output = new StringBuffer JavaDoc();
633
634         buildRelativeLink(output);
635
636         //
637
// Encode Response does all the fixup for the Servlet Container
638
//
639
return encodeResponse(output.toString());
640     }
641
642     /**
643      * Add everything needed for a relative link to the passed StringBuffer.
644      *
645      * @param output A Stringbuffer
646      */

647     private void buildRelativeLink(StringBuffer JavaDoc output)
648     {
649         getContextAndScript(output);
650
651         if (hasPathInfo())
652         {
653             output.append('/');
654             getPathInfoAsString(output);
655         }
656
657         if (hasReference())
658         {
659             output.append('#');
660             output.append(getReference());
661         }
662
663         if (hasQueryData())
664         {
665             output.append('?');
666             getQueryDataAsString(output);
667         }
668     }
669
670     /**
671      * Gets the current Query Data List.
672      *
673      * @return A List which contains all query data keys. The keys
674      * are URIParam objects.
675      */

676     public List JavaDoc getPathInfo()
677     {
678         return dataVectors[PATH_INFO];
679     }
680
681     /**
682      * Sets the Query Data List. Replaces the current query data list
683      * with the one supplied. The list must contain only URIParam
684      * objects!
685      *
686      * @param pathInfo A List with new param objects.
687      */

688
689     public void setPathInfo(List JavaDoc pathInfo)
690     {
691         dataVectors[PATH_INFO] = pathInfo;
692     }
693
694     /**
695      * Gets the current Query Data List.
696      *
697      * @return A List which contains all query data keys. The keys
698      * are URIParam objects.
699      */

700     public List JavaDoc getQueryData()
701     {
702         return dataVectors[QUERY_DATA];
703     }
704
705     /**
706      * Sets the Query Data List. Replaces the current query data list
707      * with the one supplied. The list must contain only URIParam
708      * objects!
709      *
710      * @param queryData A List with new param objects.
711      */

712
713     public void setQueryData(List JavaDoc queryData)
714     {
715         dataVectors[QUERY_DATA] = queryData;
716     }
717
718     /**
719      * Simply calls getAbsoluteLink(). You should not use this in your
720      * code unless you have to. Use getAbsoluteLink.
721      *
722      * @return This URI as a String
723      *
724      */

725     public String JavaDoc toString()
726     {
727         return getAbsoluteLink();
728     }
729
730     /*
731      * ========================================================================
732      *
733      * Protected / Private Methods
734      *
735      * ========================================================================
736      *
737      */

738
739     /**
740      * Returns the Path Info data as a String.
741      *
742      * @param output The StringBuffer that should hold the path info.
743      */

744     private void getPathInfoAsString(StringBuffer JavaDoc output)
745     {
746         doEncode(output, dataVectors[PATH_INFO], '/', '/');
747     }
748
749     /**
750      * Returns the Query data as a String.
751      *
752      * @param output The StringBuffer that should hold the query data.
753      */

754     private void getQueryDataAsString(StringBuffer JavaDoc output)
755     {
756         doEncode(output, dataVectors[QUERY_DATA], '&', '=');
757     }
758
759     /**
760      * Does the actual encoding for pathInfoAsString and queryDataAsString.
761      *
762      * @param output The Stringbuffer that should contain the information.
763      * @param list A Collection
764      * @param fieldDelim A char which is used to separate key/value pairs
765      * @param valueDelim A char which is used to separate key and value
766      */

767     private void doEncode(StringBuffer JavaDoc output, Collection JavaDoc list, char fieldDelim, char valueDelim)
768     {
769         if(!list.isEmpty())
770         {
771             for(Iterator JavaDoc it = list.iterator(); it.hasNext();)
772             {
773                 URIParam uriParam = (URIParam) it.next();
774                 String JavaDoc key = URLEncoder.encode(uriParam.getKey());
775                 String JavaDoc val = String.valueOf(uriParam.getValue());
776
777                 output.append(key);
778                 output.append(valueDelim);
779
780                 if(StringUtils.isEmpty(val))
781                 {
782                     // Fixme?
783
log.debug("Found a null value for " + key);
784                     output.append("null");
785                 }
786                 else
787                 {
788                     output.append(URLEncoder.encode(val));
789                 }
790
791                 if (it.hasNext())
792                 {
793                     output.append(fieldDelim);
794                 }
795             }
796         }
797     }
798
799     /**
800      * If the type is PATH_INFO, then add name/value to the pathInfo
801      * hashtable.
802      * <p>
803      * If the type is QUERY_DATA, then add name/value to the queryData
804      * hashtable.
805      *
806      * @param type Type (PATH_INFO or QUERY_DATA) of insertion.
807      * @param name A String with the name to add.
808      * @param value A String with the value to add.
809      */

810     protected void add(int type,
811             String JavaDoc name,
812             String JavaDoc value)
813     {
814         URIParam uriParam = new URIParam(ParserUtils.convertAndTrim(name), value);
815
816         dataVectors[type].add(uriParam); // Code so clean you can eat from...
817
}
818
819     /**
820      * Method for a quick way to add all the parameters in a
821      * ParameterParser.
822      *
823      * <p>If the type is P (0), then add name/value to the pathInfo
824      * hashtable.
825      *
826      * <p>If the type is Q (1), then add name/value to the queryData
827      * hashtable.
828      *
829      * @param type Type of insertion (@see #add(char type, String name, String value))
830      * @param pp A ParameterParser.
831      */

832     protected void add(int type,
833             ParameterParser pp)
834     {
835         for(Iterator JavaDoc it = pp.keySet().iterator(); it.hasNext();)
836         {
837             String JavaDoc key = (String JavaDoc) it.next();
838
839             if (!key.equalsIgnoreCase(CGI_ACTION_PARAM) &&
840                     !key.equalsIgnoreCase(CGI_SCREEN_PARAM))
841             {
842                 String JavaDoc[] values = pp.getStrings(key);
843                 for (int i = 0; i < values.length; i++)
844                 {
845                     add(type, key, values[i]);
846                 }
847             }
848         }
849     }
850
851     /**
852      * Method for a quick way to add all the parameters in a
853      * List with URIParam objects.
854      *
855      * <p>If the type is P (0), then add name/value to the pathInfo
856      * hashtable.
857      *
858      * <p>If the type is Q (1), then add name/value to the queryData
859      * hashtable.
860      *
861      * @param type Type of insertion (@see #add(char type, String name, String value))
862      * @param list A List of URIParam objects
863      */

864     protected void add(int type,
865             List JavaDoc list)
866     {
867         for (Iterator JavaDoc it = list.iterator(); it.hasNext();)
868         {
869             // Strictly spoken we don't need this cast. But if we do,
870
// we get class cast right here is someone tries to put
871
// a list with wrong objects into this method.
872
URIParam uriParam = (URIParam) it.next();
873             dataVectors[type].add(uriParam);
874         }
875     }
876
877     /**
878      * If the type is P (0), then remove name/value from the
879      * pathInfo hashtable.
880      *
881      * <p>If the type is Q (1), then remove name/value from the
882      * queryData hashtable.
883      *
884      * @param type Type (P or Q) of removal.
885      * @param name A String with the name to be removed.
886      */

887     protected void remove (int type,
888             String JavaDoc name)
889     {
890         Collection JavaDoc c = dataVectors[type];
891         String JavaDoc key = ParserUtils.convertAndTrim(name);
892
893         for (Iterator JavaDoc it = c.iterator(); it.hasNext();)
894         {
895             URIParam uriParam = (URIParam) it.next();
896
897             if (key.equals(uriParam.getKey()))
898             {
899                 it.remove();
900             }
901         }
902     }
903 }
904
Popular Tags