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 }