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