View Javadoc
1   package org.apache.turbine.util.uri;
2   
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one
6    * or more contributor license agreements.  See the NOTICE file
7    * distributed with this work for additional information
8    * regarding copyright ownership.  The ASF licenses this file
9    * to you under the Apache License, Version 2.0 (the
10   * "License"); you may not use this file except in compliance
11   * with the License.  You may obtain a copy of the License at
12   *
13   *   http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing,
16   * software distributed under the License is distributed on an
17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   * KIND, either express or implied.  See the License for the
19   * specific language governing permissions and limitations
20   * under the License.
21   */
22  
23  
24  import javax.servlet.http.HttpServletResponse;
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.Turbine;
32  import org.apache.turbine.TurbineConstants;
33  
34  import org.apache.turbine.util.RunData;
35  import org.apache.turbine.util.ServerData;
36  
37  /**
38   * This is the base class for all dynamic URIs in the Turbine System.
39   *
40   * All of the classes used for generating URIs are derived from this.
41   *
42   * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
43   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
44   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
45   * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
46   * @version $Id: BaseURI.java 1709648 2015-10-20 17:08:10Z tv $
47   */
48  
49  public abstract class BaseURI
50          implements URI,
51                     URIConstants
52  {
53      /** Logging */
54      private static Log log = LogFactory.getLog(BaseURI.class);
55  
56      /** ServerData Object for scheme, name, port etc. */
57      private ServerData serverData =
58              new ServerData(null, HTTP_PORT, HTTP, null, null);
59  
60      /** Whether we want to redirect or not. */
61      private boolean redirect = false;
62  
63      /** Servlet response interface. */
64      private HttpServletResponse response = null;
65  
66      /** Reference Anchor (#ref) */
67      private String reference = null;
68  
69      /*
70       * ========================================================================
71       *
72       * Constructors
73       *
74       * ========================================================================
75       *
76       */
77  
78      /**
79       * Empty C'tor. Uses Turbine.getDefaultServerData().
80       *
81       */
82      public BaseURI()
83      {
84          init(Turbine.getDefaultServerData());
85          setResponse(null);
86      }
87  
88      /**
89       * Constructor with a RunData object
90       *
91       * @param runData A RunData object
92       */
93      public BaseURI(RunData runData)
94      {
95          init(runData.getServerData());
96          setResponse(runData.getResponse());
97      }
98  
99      /**
100      * Constructor, set explicit redirection
101      *
102      * @param runData A RunData object
103      * @param redirect True if redirection allowed.
104      */
105     public BaseURI(RunData runData, boolean redirect)
106     {
107         init(runData.getServerData());
108         setResponse(runData.getResponse());
109         setRedirect(redirect);
110     }
111 
112     /**
113      * Constructor with a ServerData object
114      *
115      * @param serverData A ServerData object
116      */
117     public BaseURI(ServerData serverData)
118     {
119         init(serverData);
120         setResponse(null);
121     }
122 
123     /**
124      * Constructor, set explicit redirection
125      *
126      * @param serverData A ServerData object
127      * @param redirect True if redirection allowed.
128      */
129     public BaseURI(ServerData serverData, boolean redirect)
130     {
131         init(serverData);
132         setResponse(null);
133         setRedirect(redirect);
134     }
135 
136     /*
137      * ========================================================================
138      *
139      * Init
140      *
141      * ========================================================================
142      *
143      */
144 
145     /**
146      * Init with a ServerData object
147      *
148      * @param serverData A ServerData object
149      *
150      */
151     private void init(ServerData serverData)
152     {
153         log.debug("init(" + serverData + ")");
154 
155         if(serverData != null)
156         {
157             // We must clone this, because if BaseURI is used in a pull tool,
158             // then the fields might be changed. If we don't clone, this might pull
159             // through to the ServerData object saved at firstRequest() in the
160             // Turbine object.
161             this.serverData = (ServerData) serverData.clone();
162         }
163         else
164         {
165             log.error("Passed null ServerData object!");
166         }
167         reference = null;
168     }
169 
170     /*
171      * ========================================================================
172      *
173      * Getter / Setter
174      *
175      * ========================================================================
176      *
177      */
178 
179     /**
180      * Set the redirect Flag
181      *
182      * @param redirect The new value of the redirect flag.
183      */
184     public void setRedirect(boolean redirect)
185     {
186         this.redirect = redirect;
187     }
188 
189     /**
190      * Returns the current value of the Redirect flag
191      *
192      * @return True if Redirect is allowed
193      *
194      */
195     public boolean isRedirect()
196     {
197         return redirect;
198     }
199 
200     /**
201      * Gets the script name (/servlets/Turbine).
202      *
203      * @return A String with the script name.
204      */
205     public String getScriptName()
206     {
207         return serverData.getScriptName();
208     }
209 
210     /**
211      * Sets the script name (/servlets/Turbine).
212      *
213      * @param scriptName A String with the script name.
214      */
215     public void setScriptName(String scriptName)
216     {
217         serverData.setScriptName(scriptName);
218     }
219 
220     /**
221      * Gets the context path.
222      *
223      * @return A String with the context path.
224      */
225     public String getContextPath()
226     {
227         return serverData.getContextPath();
228     }
229 
230     /**
231      * Sets the context path.
232      *
233      * @param contextPath A String with the context path
234      */
235     public void setContextPath(String contextPath)
236     {
237         serverData.setContextPath(contextPath);
238     }
239 
240     /**
241      * Gets the server name.
242      *
243      * @return A String with the server name.
244      */
245     public String getServerName()
246     {
247         return serverData.getServerName();
248     }
249 
250     /**
251      * Sets the server name.
252      *
253      * @param serverName A String with the server name.
254      */
255     public void setServerName(String serverName)
256     {
257         serverData.setServerName(serverName);
258     }
259 
260     /**
261      * Gets the server port.
262      *
263      * @return A String with the server port.
264      */
265     public int getServerPort()
266     {
267         int serverPort = serverData.getServerPort();
268 
269         if (serverPort == 0)
270         {
271             if(getServerScheme().equals(HTTPS))
272             {
273                 serverPort = HTTPS_PORT;
274             }
275             else
276             {
277                 serverPort = HTTP_PORT;
278             }
279         }
280         return serverPort;
281     }
282 
283     /**
284      * Sets the server port.
285      *
286      * @param serverPort An int with the port.
287      */
288     public void setServerPort(int serverPort)
289     {
290         serverData.setServerPort(serverPort);
291     }
292 
293     /**
294      * Method to specify that a URI should use SSL. The default port
295      * is used.
296      */
297     public void setSecure()
298     {
299         setSecure(HTTPS_PORT);
300     }
301 
302     /**
303      * Method to specify that a URI should use SSL.
304      * Whether or not it does is determined from Turbine.properties.
305      * If use.ssl in the Turbine.properties is set to false, then
306      * http is used in any case. (Default of use.ssl is true).
307      *
308      * @param port An int with the port number.
309      */
310     public void setSecure(int port)
311     {
312         boolean useSSL =
313                 Turbine.getConfiguration()
314                 .getBoolean(TurbineConstants.USE_SSL_KEY,
315                         TurbineConstants.USE_SSL_DEFAULT);
316 
317         setServerScheme(useSSL ? HTTPS : HTTP);
318         setServerPort(port);
319     }
320 
321     /**
322      * Sets the scheme (HTTP or HTTPS).
323      *
324      * @param serverScheme A String with the scheme.
325      */
326     public void setServerScheme(String serverScheme)
327     {
328         serverData.setServerScheme(StringUtils.isNotEmpty(serverScheme)
329                 ? serverScheme : "");
330     }
331 
332     /**
333      * Returns the current Server Scheme
334      *
335      * @return The current Server scheme
336      *
337      */
338     public String getServerScheme()
339     {
340         String serverScheme = serverData.getServerScheme();
341 
342         return StringUtils.isNotEmpty(serverScheme) ? serverScheme : HTTP;
343     }
344 
345     /**
346      * Sets a reference anchor (#ref).
347      *
348      * @param reference A String containing the reference.
349      */
350     public void setReference(String reference)
351     {
352         this.reference = reference;
353     }
354 
355     /**
356      * Returns the current reference anchor.
357      *
358      * @return A String containing the reference.
359      */
360     public String getReference()
361     {
362         return hasReference() ? reference : "";
363     }
364 
365     /**
366      * Does this URI contain an anchor? (#ref)
367      *
368      * @return True if this URI contains an anchor.
369      */
370     public boolean hasReference()
371     {
372         return StringUtils.isNotEmpty(reference);
373     }
374 
375     /*
376      * ========================================================================
377      *
378      * Protected / Private Methods
379      *
380      * ========================================================================
381      *
382      */
383 
384     /**
385      * Set a Response Object to use when creating the
386      * response string.
387      *
388      */
389     protected void setResponse(HttpServletResponse response)
390     {
391         this.response = response;
392     }
393 
394     /**
395      * Returns the Response Object from the Servlet Container.
396      *
397      * @return The Servlet Response object or null
398      *
399      */
400     protected HttpServletResponse getResponse()
401     {
402         return response;
403     }
404 
405     /**
406      * Append the Context Path and Script Name to the passed
407      * String Buffer.
408      *
409      * <p>
410      * This is a convenience method to be
411      * used in the Link output routines of derived classes to
412      * easily append the correct path.
413      *
414      * @param sb The StringBuilder to store context path and script name.
415      */
416     protected void getContextAndScript(StringBuilder sb)
417     {
418         String context = getContextPath();
419 
420         if(StringUtils.isNotEmpty(context))
421         {
422             if(context.charAt(0) != '/')
423             {
424                 sb.append('/');
425             }
426             sb.append (context);
427         }
428 
429         // /servlet/turbine
430         String script = getScriptName();
431 
432         if(StringUtils.isNotEmpty(script))
433         {
434             if(script.charAt(0) != '/')
435             {
436                 sb.append('/');
437             }
438             sb.append (script);
439         }
440     }
441 
442     /**
443      * Appends Scheme, Server and optionally the port to the
444      * supplied String Buffer.
445      *
446      * <p>
447      * This is a convenience method to be
448      * used in the Link output routines of derived classes to
449      * easily append the correct server scheme.
450      *
451      * @param sb The StringBuilder to store the scheme and port information.
452      */
453     protected void getSchemeAndPort(StringBuilder sb)
454     {
455         // http(s)://<servername>
456         sb.append(getServerScheme());
457         sb.append(URIConstants.URI_SCHEME_SEPARATOR);
458         sb.append(getServerName());
459 
460         // (:<port>)
461         if ((getServerScheme().equals(HTTP)
462                     && getServerPort() != HTTP_PORT)
463                 || (getServerScheme().equals(HTTPS)
464                         && getServerPort() != HTTPS_PORT))
465         {
466             sb.append(':');
467             sb.append(getServerPort());
468         }
469     }
470 
471     /**
472      * Encodes a Response Uri according to the Servlet Container.
473      * This might add a Java session identifier or do redirection.
474      * The resulting String can be used in a page or template.
475      *
476      * @param uri The Uri to encode
477      *
478      * @return An Uri encoded by the container.
479      */
480     protected String encodeResponse(String uri)
481     {
482         String res = uri;
483 
484         HttpServletResponse response = getResponse();
485 
486         if(response == null)
487         {
488             log.debug("No Response Object!");
489         }
490         else
491         {
492             try
493             {
494                 if(isRedirect())
495                 {
496                     log.debug("Should Redirect");
497                     res = response.encodeRedirectURL(uri);
498                 }
499                 else
500                 {
501                     res = response.encodeURL(uri);
502                 }
503             }
504             catch(Exception e)
505             {
506                 log.error("response" + response + ", uri: " + uri);
507                 log.error("While trying to encode the URI: ", e);
508             }
509         }
510 
511         log.debug("encodeResponse():  " + res);
512         return res;
513     }
514 }