001package org.apache.turbine.util.uri; 002 003 004/* 005 * Licensed to the Apache Software Foundation (ASF) under one 006 * or more contributor license agreements. See the NOTICE file 007 * distributed with this work for additional information 008 * regarding copyright ownership. The ASF licenses this file 009 * to you under the Apache License, Version 2.0 (the 010 * "License"); you may not use this file except in compliance 011 * with the License. You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, 016 * software distributed under the License is distributed on an 017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 018 * KIND, either express or implied. See the License for the 019 * specific language governing permissions and limitations 020 * under the License. 021 */ 022 023 024import javax.servlet.http.HttpServletResponse; 025 026import org.apache.commons.lang3.StringUtils; 027import org.apache.logging.log4j.LogManager; 028import org.apache.logging.log4j.Logger; 029import org.apache.turbine.Turbine; 030import org.apache.turbine.TurbineConstants; 031import org.apache.turbine.util.RunData; 032import org.apache.turbine.util.ServerData; 033 034/** 035 * This is the base class for all dynamic URIs in the Turbine System. 036 * 037 * All of the classes used for generating URIs are derived from this. 038 * 039 * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a> 040 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a> 041 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 042 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a> 043 * @version $Id$ 044 */ 045 046public abstract class BaseURI 047 implements URI, 048 URIConstants 049{ 050 /** Logging */ 051 private static final Logger log = LogManager.getLogger(BaseURI.class); 052 053 /** ServerData Object for scheme, name, port etc. */ 054 private ServerData serverData = 055 new ServerData(null, HTTP_PORT, HTTP, null, null); 056 057 /** Whether we want to redirect or not. */ 058 private boolean redirect = false; 059 060 /** Servlet response interface. */ 061 private HttpServletResponse response = null; 062 063 /** Reference Anchor (#ref) */ 064 private String reference = null; 065 066 /* 067 * ======================================================================== 068 * 069 * Constructors 070 * 071 * ======================================================================== 072 * 073 */ 074 075 /** 076 * Empty C'tor. Uses Turbine.getDefaultServerData(). 077 * 078 */ 079 public BaseURI() 080 { 081 init(Turbine.getDefaultServerData()); 082 setResponse(null); 083 } 084 085 /** 086 * Constructor with a RunData object 087 * 088 * @param runData A RunData object 089 */ 090 public BaseURI(RunData runData) 091 { 092 init(runData.getServerData()); 093 setResponse(runData.getResponse()); 094 } 095 096 /** 097 * Constructor, set explicit redirection 098 * 099 * @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}