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 }