View Javadoc

1   package org.apache.turbine.util;
2   
3   /*
4    * Copyright 2001-2005 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;
20  
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import javax.servlet.http.HttpServletRequest;
26  import javax.servlet.http.HttpServletResponse;
27  
28  import org.apache.commons.lang.StringUtils;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  
33  import org.apache.ecs.html.A;
34  
35  import org.apache.turbine.Turbine;
36  import org.apache.turbine.TurbineConstants;
37  import org.apache.turbine.util.parser.ParameterParser;
38  import org.apache.turbine.util.parser.ParserUtils;
39  import org.apache.turbine.util.uri.URI;
40  import org.apache.turbine.util.uri.URIConstants;
41  
42  /***
43   * This creates a Dynamic URI for use within the Turbine system
44   *
45   * <p>If you use this class to generate all of your href tags as well
46   * as all of your URI's, then you will not need to worry about having
47   * session data setup for you or using HttpServletRequest.encodeUrl()
48   * since this class does everything for you.
49   *
50   * <code><pre>
51   * DynamicURI dui = new DynamicURI (data, "UserScreen" );
52   * dui.setName("Click Here").addPathInfo("user","jon");
53   * dui.getA();
54   * </pre></code>
55   *
56   * The above call to getA() would return the String:
57   *
58   * &lt;A HREF="http://www.server.com:80/servlets/Turbine/screen=UserScreen&amp;amp;user=jon"&gt;Click Here&lt;/A&gt;
59   *
60   * @todo Add support for returning the correct URI when mod_rewrite is
61   *       being used.
62   *
63   * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
64   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
65   * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
66   * @version $Id: DynamicURI.java 264148 2005-08-29 14:21:04Z henning $
67   * @deprecated Use {@link org.apache.turbine.util.uri.TurbineURI} instead.
68   */
69  public class DynamicURI
70          implements URI
71  {
72      /*** @deprecated Use URIConstants.HTTP */
73      public static final String HTTP = URIConstants.HTTP;
74  
75      /*** @deprecated Use URIConstants.HTTPS */
76      public static final String HTTPS = URIConstants.HTTPS;
77  
78      /*** Logging */
79      private static Log log = LogFactory.getLog(DynamicURI.class);
80  
81      /*** The ServerData object. */
82      protected ServerData sd = null;
83  
84      /*** The RunData object. */
85      protected RunData data = null;
86  
87      /*** #ref */
88      protected String reference = null;
89  
90      // Used with RunData constructors to provide a way around a JServ
91      // 1.0 bug.
92  
93      /*** Servlet response interface. */
94      public HttpServletResponse res = null;
95  
96      /*** A List that contains all the path info if any. */
97      protected List pathInfo = null;
98  
99      /*** A List that contains all the query data if any. */
100     protected List queryData = null;
101 
102     /*** Fast shortcut to determine if there is any data in the path info. */
103     protected boolean hasPathInfo = false;
104 
105     /*** Fast shortcut to determine if there is any data in the query data. */
106     protected boolean hasQueryData = false;
107 
108     /*** Whether we want to redirect or not. */
109     protected boolean redirect = false;
110 
111     /*** P = 0 for path info. */
112     protected static final int PATH_INFO = 0;
113 
114     /*** Q = 1 for query data. */
115     protected static final int QUERY_DATA = 1;
116 
117     /*** Has the object been initialized? */
118     private boolean initialized = false;
119 
120     /***
121      * Constructor sets up some variables.
122      *
123      * @param data A Turbine RunData object.
124      */
125     public DynamicURI(RunData data)
126     {
127         init(data);
128     }
129 
130     /***
131      * Default constructor - one of the init methods must be called
132      * before use.
133      */
134     public DynamicURI()
135     {
136     }
137 
138     /***
139      * Constructor sets up some variables.
140      *
141      * @param data A Turbine RunData object.
142      * @param screen A String with the name of a screen.
143      */
144     public DynamicURI(RunData data, String screen)
145     {
146         this(data);
147         setScreen(screen);
148     }
149 
150     /***
151      * Constructor sets up some variables.
152      *
153      * @param data A Turbine RunData object.
154      * @param screen A String with the name of a screen.
155      * @param action A String with the name of an action.
156      */
157     public DynamicURI(RunData data, String screen, String action)
158     {
159         this(data, screen);
160         setAction(action);
161     }
162 
163     /***
164      * Constructor sets up some variables.
165      *
166      * @param data A Turbine RunData object.
167      * @param screen A String with the name of a screen.
168      * @param action A String with the name of an action.
169      * @param redirect True if it should redirect.
170      */
171     public DynamicURI(RunData data,String screen,
172                       String action,boolean redirect)
173     {
174         this(data, screen, action);
175         this.redirect = redirect;
176     }
177 
178     /***
179      * Constructor sets up some variables.
180      *
181      * @param data A Turbine RunData object.
182      * @param screen A String with the name of a screen.
183      * @param redirect True if it should redirect.
184      */
185     public DynamicURI(RunData data, String screen, boolean redirect)
186     {
187         this(data, screen);
188         this.redirect = redirect;
189     }
190 
191     /***
192      * Constructor sets up some variables.
193      *
194      * @param data A Turbine RunData object.
195      * @param redirect True if it should redirect.
196      */
197     public DynamicURI(RunData data, boolean redirect)
198     {
199         this(data);
200         this.redirect = redirect;
201     }
202 
203     /***
204      * Main constructor for DynamicURI.  Uses ServerData.
205      *
206      * @param sd A ServerData.
207      */
208     public DynamicURI(ServerData sd)
209     {
210         init(sd);
211     }
212 
213     /***
214      * Main constructor for DynamicURI.  Uses ServerData.
215      *
216      * @param sd A ServerData.
217      * @param screen A String with the name of a screen.
218      */
219     public DynamicURI(ServerData sd, String screen)
220     {
221         this(sd);
222         setScreen(screen);
223     }
224 
225     /***
226      * Main constructor for DynamicURI.  Uses ServerData.
227      *
228      * @param sd A ServerData.
229      * @param screen A String with the name of a screen.
230      * @param action A String with the name of an action.
231      */
232     public DynamicURI(ServerData sd, String screen, String action)
233     {
234         this(sd, screen);
235         setAction(action);
236     }
237 
238     /***
239      * Main constructor for DynamicURI.  Uses ServerData.
240      *
241      * @param sd A ServerData.
242      * @param screen A String with the name of a screen.
243      * @param action A String with the name of an action.
244      * @param redirect True if it should redirect.
245      */
246     public DynamicURI(ServerData sd, String screen,
247                       String action, boolean redirect)
248     {
249         this(sd, screen, action);
250         this.redirect = redirect;
251     }
252 
253     /***
254      * Main constructor for DynamicURI.  Uses ServerData.
255      *
256      * @param serverData A ServerData.
257      * @param screen A String with the name of a screen.
258      * @param redirect True if it should redirect.
259      */
260     public DynamicURI(ServerData serverData, String screen, boolean redirect)
261     {
262         this(serverData, screen);
263         this.redirect = redirect;
264     }
265 
266     /***
267      * Main constructor for DynamicURI.  Uses ServerData.
268      *
269      * @param serverData A ServerData.
270      * @param redirect True if it should redirect.
271      */
272     public DynamicURI(ServerData serverData, boolean redirect)
273     {
274         this(serverData);
275         this.redirect = redirect;
276         this.initialized = true;
277     }
278 
279     /***
280      * Initialize with a RunData object
281      *
282      * @param data RunData instance
283      */
284     public void init(RunData data)
285     {
286         init(data.getServerData());
287         this.data = data;
288         this.res = data.getResponse();
289     }
290 
291     /***
292      * Initialize with a ServerData object.
293      *
294      * @param serverData
295      */
296     public void init(ServerData serverData)
297     {
298         this.sd = (ServerData) serverData.clone();
299         this.pathInfo = new ArrayList();
300         this.queryData = new ArrayList();
301         this.reference = null;
302         this.initialized = true;
303     }
304 
305     /***
306      * If the type is {@link #PATH_INFO}, then add name/value to the
307      * pathInfo.
308      * <p>
309      * If the type is {@link #QUERY_DATA}, then add name/value to the
310      * queryData.
311      *
312      * @param type Type of insertion.
313      * @param name A String with the name to add.
314      * @param value A String with the value to add.
315      */
316     protected void add(int type, String name, String value)
317     {
318         assertInitialized();
319         Object[] tmp = new Object[2];
320         tmp[0] = ParserUtils.convertAndTrim(name);
321         tmp[1] = value;
322         switch (type)
323         {
324             case PATH_INFO:
325                 this.pathInfo.add(tmp);
326                 this.hasPathInfo = true;
327                 break;
328             case QUERY_DATA:
329                 this.queryData.add(tmp);
330                 this.hasQueryData = true;
331                 break;
332         }
333     }
334 
335     /***
336      * Method for a quick way to add all the parameters in a
337      * ParameterParser.
338      * <p>
339      * If the type is {@link #PATH_INFO}, then add name/value to the
340      * pathInfo.
341      * <p>
342      * If the type is {@link #QUERY_DATA}, then add name/value to the
343      * queryData.
344      *
345      * @param type Type of insertion.
346      * @param pp A ParameterParser.
347      */
348     protected void add(int type, ParameterParser pp)
349     {
350         for( Iterator iter = pp.keySet().iterator(); iter.hasNext(); )
351         {
352             String key = (String) iter.next();
353             if (!key.equalsIgnoreCase(URIConstants.CGI_ACTION_PARAM) &&
354                     !key.equalsIgnoreCase(URIConstants.CGI_SCREEN_PARAM) &&
355                     !key.equalsIgnoreCase(URIConstants.CGI_TEMPLATE_PARAM))
356             {
357                 String[] values = pp.getStrings(key);
358                 for (int i = 0; i < values.length; i++)
359                 {
360                     add(type, key, values[i]);
361                 }
362             }
363         }
364     }
365 
366     /***
367      * Adds a name=value pair to the path_info string.
368      *
369      * @param name A String with the name to add.
370      * @param value An Object with the value to add.
371      * @return A DynamicURI (self).
372      */
373     public DynamicURI addPathInfo(String name, Object value)
374     {
375         add(PATH_INFO, name, value.toString());
376         return this;
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 A String with the value to add.
384      * @return A DynamicURI (self).
385      */
386     public DynamicURI addPathInfo(String name, String value)
387     {
388         add(PATH_INFO, name, value);
389         return this;
390     }
391 
392     /***
393      * Adds a name=value pair to the path_info string.
394      *
395      * @param name A String with the name to add.
396      * @param value A double with the value to add.
397      * @return A DynamicURI (self).
398      */
399     public DynamicURI addPathInfo(String name, double value)
400     {
401         add(PATH_INFO, name, Double.toString(value));
402         return this;
403     }
404 
405     /***
406      * Adds a name=value pair to the path_info string.
407      *
408      * @param name A String with the name to add.
409      * @param value An int with the value to add.
410      * @return A DynamicURI (self).
411      */
412     public DynamicURI addPathInfo(String name, int value)
413     {
414         add(PATH_INFO, name, String.valueOf(value));
415         return this;
416     }
417 
418     /***
419      * Adds a name=value pair to the path_info string.
420      *
421      * @param name A String with the name to add.
422      * @param value A long with the value to add.
423      * @return A DynamicURI (self).
424      */
425     public DynamicURI addPathInfo(String name, long value)
426     {
427         add(PATH_INFO, name, String.valueOf(value));
428         return this;
429     }
430 
431     /***
432      * Adds a name=value pair for every entry in a ParameterParser
433      * object to the path_info string.
434      *
435      * @param pp A ParameterParser.
436      * @return A DynamicURI (self).
437      */
438     public DynamicURI addPathInfo(ParameterParser pp)
439     {
440         add(PATH_INFO, pp);
441         return this;
442     }
443 
444     /***
445      * Adds a name=value pair to the query string.
446      *
447      * @param name A String with the name to add.
448      * @param value An Object with the value to add.
449      * @return A DynamicURI (self).
450      */
451     public DynamicURI addQueryData(String name, Object value)
452     {
453         add(QUERY_DATA, name, value.toString());
454         return this;
455     }
456 
457     /***
458      * Adds a name=value pair to the query string.
459      *
460      * @param name A String with the name to add.
461      * @param value A String with the value to add.
462      * @return A DynamicURI (self).
463      */
464     public DynamicURI addQueryData(String name, String value)
465     {
466         add(QUERY_DATA, name, value);
467         return this;
468     }
469 
470     /***
471      * Adds a name=value pair to the query string.
472      *
473      * @param name A String with the name to add.
474      * @param value A double with the value to add.
475      * @return A DynamicURI (self).
476      */
477     public DynamicURI addQueryData(String name, double value)
478     {
479         add(QUERY_DATA, name, Double.toString(value));
480         return this;
481     }
482 
483     /***
484      * Adds a name=value pair to the query string.
485      *
486      * @param name A String with the name to add.
487      * @param value An int with the value to add.
488      * @return A DynamicURI (self).
489      */
490     public DynamicURI addQueryData(String name, int value)
491     {
492         add(QUERY_DATA, name, String.valueOf(value));
493         return this;
494     }
495 
496     /***
497      * Adds a name=value pair to the query string.
498      *
499      * @param name A String with the name to add.
500      * @param value A long with the value to add.
501      * @return A DynamicURI (self).
502      */
503     public DynamicURI addQueryData(String name, long value)
504     {
505         add(QUERY_DATA, name, String.valueOf(value));
506         return this;
507     }
508 
509     /***
510      * Adds a name=value pair for every entry in a ParameterParser
511      * object to the query string.
512      *
513      * @param pp A ParameterParser.
514      * @return A DynamicURI (self).
515      */
516     public DynamicURI addQueryData(ParameterParser pp)
517     {
518         add(QUERY_DATA, pp);
519         return this;
520     }
521 
522     /***
523      * Create an anchor object.  This call to getA():
524      *
525      * <code><pre>
526      * DynamicURI dui = new DynamicURI (data, "UserScreen" );
527      * dui.setName("Click Here").addPathInfo("user","jon");
528      * dui.getA();
529      * </pre></code>
530      *
531      * would return the String:
532      *
533      * <p>&lt;A HREF="http://www.server.com:80/servlets/Turbine/screen=UserScreen&amp;amp;user=jon"&gt;Click Here&lt;/A&gt;
534      *
535      * @param name A String with the name for the anchor.
536      * @return The anchor as a &lt;A HREF=""&gt;name&lt;/A&gt;.
537      */
538     public String getA(String name)
539     {
540         return new A(this.toString(), name).toString();
541     }
542 
543     /***
544      * Gets the script name (/servlets/Turbine).
545      *
546      * @return A String with the script name.
547      */
548     public String getScriptName()
549     {
550         String result = getServerData().getScriptName();
551         return (StringUtils.isEmpty(result) ? "" : result);
552     }
553 
554     /***
555      * Gets the context path
556      *
557      * @return A String with the servlet context path
558      */
559     public String getContextPath()
560     {
561         String result = getServerData().getContextPath();
562         return (StringUtils.isEmpty(result) ? "" : result);
563     }
564 
565     /***
566      * Gets the reference (#ref).
567      *
568      * @return A String containing the reference.
569      */
570     public String getReference()
571     {
572         assertInitialized();
573         return (StringUtils.isEmpty(this.reference) ? "" : this.reference);
574     }
575 
576     /***
577      * Gets the server name.
578      *
579      * @return A String with the server name.
580      */
581     public String getServerName()
582     {
583         String result = getServerData().getServerName();
584         return (StringUtils.isEmpty(result) ? "" : result);
585     }
586 
587     /***
588      * Gets the server port.
589      *
590      * @return A String with the server port.
591      */
592     public int getServerPort()
593     {
594         int result = getServerData().getServerPort();
595         return (result==0 ? URIConstants.HTTP_PORT : result);
596     }
597 
598     /***
599      * Gets the server scheme (HTTP or HTTPS).
600      *
601      * @return A String with the server scheme.
602      */
603     public String getServerScheme()
604     {
605         String result = getServerData().getServerScheme();
606         return (StringUtils.isEmpty(result) ? "" : result);
607     }
608 
609     /***
610      * <p>If the type is {@link #PATH_INFO}, then remove name/value from the
611      * pathInfo.
612      *
613      * <p>If the type is {@link #QUERY_DATA}, then remove name/value from the
614      * queryData.
615      *
616      * @param type Type of removal.
617      * @param name A String with the name to be removed.
618      */
619     protected void remove(int type, String name)
620     {
621         assertInitialized();
622         try
623         {
624             switch (type)
625             {
626                 case PATH_INFO:
627                     for (Iterator iter = this.pathInfo.iterator();
628                          iter.hasNext();)
629                     {
630                         Object[] tmp = (Object[]) iter.next();
631                         if (ParserUtils.convertAndTrim(name)
632                                 .equals((String) tmp[0]))
633                         {
634                             iter.remove();
635                         }
636                     }
637                     if (hasPathInfo && this.pathInfo.size() == 0)
638                     {
639                         this.hasPathInfo = false;
640                     }
641                     break;
642                 case QUERY_DATA:
643                     for (Iterator iter = this.pathInfo.iterator();
644                          iter.hasNext();)
645                     {
646                         Object[] tmp = (Object[]) iter.next();
647                         if (ParserUtils.convertAndTrim(name)
648                                 .equals((String) tmp[0]))
649                         {
650                             iter.remove();
651                         }
652                     }
653                     if (hasQueryData && this.queryData.size() == 0)
654                     {
655                         this.hasQueryData = false;
656                     }
657                     break;
658             }
659         }
660         catch (Exception e)
661         {
662             log.error("Could not remove "+name, e);
663         }
664     }
665 
666     /***
667      * Removes all the path info elements.
668      */
669     public void removePathInfo()
670     {
671         assertInitialized();
672         this.pathInfo.clear();
673         this.hasPathInfo = false;
674     }
675 
676     /***
677      * Removes a name=value pair from the path info.
678      *
679      * @param name A String with the name to be removed.
680      */
681     public void removePathInfo(String name)
682     {
683         remove(PATH_INFO, name);
684     }
685 
686     /***
687      * Removes all the query string elements.
688      */
689     public void removeQueryData()
690     {
691         assertInitialized();
692         this.queryData.clear();
693         this.hasQueryData = false;
694     }
695 
696     /***
697      * Removes a name=value pair from the query string.
698      *
699      * @param name A String with the name to be removed.
700      */
701     public void removeQueryData(String name)
702     {
703         remove(QUERY_DATA, name);
704     }
705 
706     /***
707      * This method takes a List of key/value arrays and converts it
708      * into a URL encoded querystring format.
709      *
710      * @param data A List of key/value arrays.
711      * @return A String with the URL encoded data.
712      */
713     protected String renderPathInfo(List data)
714     {
715         String key = null;
716         String value = null;
717         String tmp = null;
718         StringBuffer out = new StringBuffer();
719         for( Iterator iter = data.iterator(); iter.hasNext(); )
720         {
721             Object[] stuff = (Object[]) iter.next();
722             key = URLEncoder.encode((String) stuff[0]);
723             tmp = (String) stuff[1];
724             if (tmp == null || tmp.length() == 0)
725             {
726                 value = "null";
727             }
728             else
729             {
730                 value = URLEncoder.encode(tmp);
731             }
732 
733             if (out.length() > 0)
734             {
735                 out.append("/");
736             }
737             out.append(key);
738             out.append("/");
739             out.append(value);
740         }
741         return out.toString();
742     }
743 
744     /***
745      * This method takes a List of key/value arrays and converts it
746      * into a URL encoded querystring format.
747      *
748      * @param data A List of key/value arrays.
749      * @return A String with the URL encoded data.
750      */
751     protected String renderQueryString(List data)
752     {
753         String key = null;
754         String value = null;
755         String tmp = null;
756         StringBuffer out = new StringBuffer();
757         for( Iterator iter = data.iterator(); iter.hasNext(); )
758         {
759             Object[] stuff = (Object[]) iter.next();
760             key = URLEncoder.encode((String) stuff[0]);
761             tmp = (String) stuff[1];
762             if (tmp == null || tmp.length() == 0)
763             {
764                 value = "null";
765             }
766             else
767             {
768                 value = URLEncoder.encode(tmp);
769             }
770 
771             if (out.length() > 0)
772             {
773                 out.append("&");
774             }
775             out.append(key);
776             out.append("=");
777             out.append(value);
778         }
779         return out.toString();
780     }
781 
782     /***
783      * Sets the action= value for this URL.
784      *
785      * <p>By default it adds the information to the path_info instead
786      * of the query data.
787      *
788      * @param action A String with the action value.
789      * @return A DynamicURI (self).
790      */
791     public DynamicURI setAction(String action)
792     {
793         add(PATH_INFO, URIConstants.CGI_ACTION_PARAM, action);
794         return this;
795     }
796 
797     /***
798      * Sets the action= value for this URL and added eventSubmit_[eventName]
799      * to the path_info.  The value of eventSubmit_[eventName] will be
800      * [eventName].
801      *
802      * @param actionName name of the action to call
803      * @param eventName name of the event.
804      * @return A DynamicURI (self).
805      */
806     public DynamicURI setActionEvent(String actionName, String eventName)
807     {
808         setAction(actionName).addPathInfo(
809                 "eventSubmit_" + eventName, eventName);
810         return this;
811     }
812 
813     /***
814      * Sets the screen= value for this URL.
815      *
816      * <p>By default it adds the information to the path_info instead
817      * of the query data.
818      *
819      * @param screen A String with the screen value.
820      * @return A DynamicURI (self).
821      */
822     public DynamicURI setScreen(String screen)
823     {
824         add(PATH_INFO, URIConstants.CGI_SCREEN_PARAM, screen);
825         return this;
826     }
827 
828     /***
829      * Sets the script name (/servlets/Turbine).
830      *
831      * @param name A String with the script name.
832      * @return A DynamicURI (self).
833      */
834     public DynamicURI setScriptName(String name)
835     {
836         getServerData().setScriptName(name);
837         return this;
838     }
839 
840     /***
841      * Sets the context path
842      *
843      * @param contextPath A String with the servlet context path
844      * @return A DynamicURI (self).
845      */
846     public DynamicURI setContextPath(String contextPath)
847     {
848         getServerData().setContextPath(contextPath);
849         return this;
850     }
851 
852     /***
853      * Sets the reference  (#ref).
854      *
855      * @param reference A String containing the reference.
856      * @return A DynamicURI (self).
857      */
858     public DynamicURI setReference(String reference)
859     {
860         this.reference = reference;
861         return this;
862     }
863 
864     /***
865      * Sets the server name.
866      *
867      * @param name A String with the server name.
868      * @return A DynamicURI (self).
869      */
870     public DynamicURI setServerName(String name)
871     {
872         getServerData().setServerName(name);
873         return this;
874     }
875 
876     /***
877      * Sets the server port.
878      *
879      * @param port An int with the port.
880      * @return A DynamicURI (self).
881      */
882     public DynamicURI setServerPort(int port)
883     {
884         getServerData().setServerPort(port);
885         return this;
886     }
887 
888     /***
889      * Method to specify that a URI should use SSL.  Whether or not it
890      * does is determined from TurbineResources.properties.  Port
891      * number is 443.
892      *
893      * @return A DynamicURI (self).
894      */
895     public DynamicURI setSecure()
896     {
897         return setSecure(443);
898     }
899 
900     /***
901      * Method to specify that a URI should use SSL.  Whether or not it
902      * does is determined from TurbineResources.properties.
903      *
904      * @param port An int with the port number.
905      * @return A DynamicURI (self).
906      */
907     public DynamicURI setSecure(int port)
908     {
909         boolean useSSL =
910             Turbine.getConfiguration()
911             .getBoolean(TurbineConstants.USE_SSL_KEY,
912                         TurbineConstants.USE_SSL_DEFAULT);
913 
914         setServerScheme(useSSL ? URIConstants.HTTPS : URIConstants.HTTP);
915         setServerPort(port);
916 
917         return this;
918     }
919 
920     /***
921      * Sets the scheme (HTTP or HTTPS).
922      *
923      * @param scheme A String with the scheme.
924      * @return A DynamicURI (self).
925      */
926     public DynamicURI setServerScheme(String scheme)
927     {
928         getServerData().setServerScheme(scheme);
929         return this;
930     }
931 
932     /***
933      * Builds the URL with all of the data URL-encoded as well as
934      * encoded using HttpServletResponse.encodeUrl().
935      *
936      * <p>
937      * <code><pre>
938      * DynamicURI dui = new DynamicURI (data, "UserScreen" );
939      * dui.addPathInfo("user","jon");
940      * dui.toString();
941      * </pre></code>
942      *
943      *  The above call to toString() would return the String:
944      *
945      * <p>
946      * http://www.server.com/servlets/Turbine/screen/UserScreen/user/jon
947      *
948      * @return A String with the built URL.
949      */
950     public String toString()
951     {
952         assertInitialized();
953         StringBuffer output = new StringBuffer();
954         output.append(getServerScheme());
955         output.append(URIConstants.URI_SCHEME_SEPARATOR);
956         output.append(getServerName());
957         if ((getServerScheme().equals(URIConstants.HTTP)
958                     && getServerPort() != URIConstants.HTTP_PORT)
959                 || (getServerScheme().equals(URIConstants.HTTPS)
960                     && getServerPort() != URIConstants.HTTPS_PORT)
961         )
962         {
963             output.append(":");
964             output.append(getServerPort());
965         }
966         output.append(getContextPath());
967         output.append(getScriptName());
968         if (this.hasPathInfo)
969         {
970             output.append("/");
971             output.append(renderPathInfo(this.pathInfo));
972         }
973         if (this.hasQueryData)
974         {
975             output.append("?");
976             output.append(renderQueryString(this.queryData));
977         }
978         if (this.reference != null)
979         {
980             output.append("#");
981             output.append(this.getReference());
982         }
983 
984         // There seems to be a bug in Apache JServ 1.0 where the
985         // session id is not appended to the end of the url when a
986         // cookie has not been set.
987         if (this.res != null)
988         {
989             if (this.redirect)
990                 return res.encodeRedirectURL(output.toString());
991             else
992                 return res.encodeURL(output.toString());
993         }
994         else
995         {
996             return output.toString();
997         }
998     }
999 
1000     /***
1001      * Given a RunData object, get a URI for the request.  This is
1002      * necessary sometimes when you want the exact URL and don't want
1003      * DynamicURI to be too smart and remove actions, screens, etc.
1004      * This also returns the Query Data where DynamicURI normally
1005      * would not.
1006      *
1007      * @param data A Turbine RunData object.
1008      * @return A String with the URL representing the RunData.
1009      */
1010     public static String toString(RunData data)
1011     {
1012         StringBuffer output = new StringBuffer();
1013         HttpServletRequest request = data.getRequest();
1014 
1015         output.append(data.getServerScheme());
1016         output.append(URIConstants.URI_SCHEME_SEPARATOR);
1017         output.append(data.getServerName());
1018 
1019         if ((data.getServerScheme().equals(URIConstants.HTTP) &&
1020                 data.getServerPort() != URIConstants.HTTP_PORT) ||
1021                 (data.getServerScheme().equals(URIConstants.HTTPS) &&
1022                 data.getServerPort() != URIConstants.HTTPS_PORT))
1023         {
1024             output.append(":");
1025             output.append(data.getServerPort());
1026         }
1027 
1028         output.append(data.getServerData().getContextPath());
1029 
1030         output.append(data.getServerData().getScriptName());
1031 
1032         if (request.getPathInfo() != null)
1033         {
1034             output.append(request.getPathInfo());
1035         }
1036 
1037         if (request.getQueryString() != null)
1038         {
1039             output.append("?");
1040             output.append(request.getQueryString());
1041         }
1042         return output.toString();
1043     }
1044 
1045     /***
1046      * Returns the ServerData used to initialize this DynamicURI.
1047      *
1048      * @return A ServerData used to initialize this DynamicURI.
1049      */
1050     public ServerData getServerData()
1051     {
1052         assertInitialized();
1053         return this.sd;
1054     }
1055 
1056     /***
1057      * Sets the ServerData used to initialize this DynamicURI.
1058      *
1059      * @param serverData A ServerData used to initialize this DynamicURI.
1060      * @deprecated no replacement.  This value is set during initialization
1061      *             and should not be changed.
1062      */
1063     public void setServerData(ServerData serverData)
1064     {
1065         this.sd = serverData;
1066     }
1067 
1068     /***
1069      * Verifies that one of the init() methods has been called
1070      */
1071     protected void assertInitialized()
1072     {
1073         if (!this.initialized)
1074         {
1075             throw new IllegalStateException("Not initialized");
1076         }
1077     }
1078 }