View Javadoc

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