1 package org.apache.turbine.services.pull.tools; 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 org.apache.commons.configuration.Configuration; 25 import org.apache.commons.logging.Log; 26 import org.apache.commons.logging.LogFactory; 27 import org.apache.fulcrum.parser.ParameterParser; 28 import org.apache.turbine.Turbine; 29 import org.apache.turbine.pipeline.PipelineData; 30 import org.apache.turbine.services.pull.ApplicationTool; 31 import org.apache.turbine.util.RunData; 32 import org.apache.turbine.util.uri.TemplateURI; 33 34 /** 35 * This is a pull to to be used in Templates to convert links in 36 * Templates into the correct references. 37 * 38 * The pull service might insert this tool into the Context. 39 * in templates. Here's an example of its Velocity use: 40 * 41 * <p><code> 42 * $link.setPage("index.vm").addPathInfo("hello","world") 43 * This would return: http://foo.com/Turbine/template/index.vm/hello/world 44 * </code> 45 * 46 * <p> 47 * 48 * This is an application pull tool for the template system. You should <b>not</b> 49 * use it in a normal application! 50 * 51 * @author <a href="mbryson@mont.mindspring.com">Dave Bryson</a> 52 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 53 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 54 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a> 55 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a> 56 * @version $Id: TemplateLink.java 1129102 2011-05-30 10:01:17Z tv $ 57 */ 58 59 public class TemplateLink 60 implements ApplicationTool 61 { 62 /** Prefix for Parameters for this tool */ 63 public static final String TEMPLATE_LINK_PREFIX = "tool.link"; 64 65 /** Should this tool return relative URIs or absolute? Default: Absolute. */ 66 public static final String TEMPLATE_LINK_RELATIVE_KEY = "want.relative"; 67 68 /** Default Value for TEMPLATE_LINK_RELATIVE_KEY */ 69 public static final boolean TEMPLATE_LINK_RELATIVE_DEFAULT = false; 70 71 72 /** Do we want a relative link? */ 73 protected boolean wantRelative = false; 74 75 /** cache of the template name for getPage() */ 76 protected String template = null; 77 78 /** TemplateURI used as backend for this object */ 79 protected TemplateURI templateURI = null; 80 81 /** Logging */ 82 private static Log log = LogFactory.getLog(TemplateLink.class); 83 84 /** 85 * Default constructor 86 * <p> 87 * The init method must be called before use. 88 */ 89 public TemplateLink() 90 { 91 // empty 92 } 93 94 /* 95 * ======================================================================== 96 * 97 * Application Tool Interface 98 * 99 * ======================================================================== 100 * 101 */ 102 103 /** 104 * This will initialise a TemplateLink object that was 105 * constructed with the default constructor (ApplicationTool 106 * method). 107 * 108 * @param data assumed to be a RunData object 109 */ 110 public void init(Object data) 111 { 112 // we just blithely cast to RunData as if another object 113 // or null is passed in we'll throw an appropriate runtime 114 // exception. 115 if (data instanceof PipelineData) 116 { 117 PipelineData pipelineData = (PipelineData) data; 118 RunData runData = (RunData)pipelineData; 119 templateURI = new TemplateURI(runData); 120 } 121 else 122 { 123 templateURI = new TemplateURI((RunData) data); 124 } 125 126 Configuration conf = 127 Turbine.getConfiguration().subset(TEMPLATE_LINK_PREFIX); 128 129 if (conf != null) 130 { 131 wantRelative = conf.getBoolean(TEMPLATE_LINK_RELATIVE_KEY, 132 TEMPLATE_LINK_RELATIVE_DEFAULT); 133 } 134 135 } 136 137 /** 138 * Refresh method - does nothing 139 */ 140 public void refresh() 141 { 142 // empty 143 } 144 145 /* 146 * ======================================================================== 147 * 148 * getter/setter 149 * 150 * All setter return "this" so you can "chain" them together in the Context 151 * 152 * ======================================================================== 153 */ 154 155 /** 156 * This will turn off the execution of res.encodeURL() 157 * by making res == null. This is a hack for cases 158 * where you don't want to see the session information 159 * 160 * @return A <code>TemplateLink</code> (self). 161 */ 162 public TemplateLink setEncodeURLOff() 163 { 164 templateURI.clearResponse(); 165 return this; 166 } 167 168 /** 169 * Sets the template variable used by the Template Service. 170 * 171 * @param template A String with the template name. 172 * @return A TemplateLink. 173 */ 174 public TemplateLink setPage(String template) 175 { 176 log.debug("setPage(" + template + ")"); 177 this.template = template; 178 templateURI.setTemplate(template); 179 return this; 180 } 181 182 /** 183 * Gets the template variable used by the Template Service. 184 * It is only available after setPage() has been called. 185 * 186 * @return The template name. 187 */ 188 public String getPage() 189 { 190 return template; 191 } 192 193 /** 194 * Sets the action= value for this URL. 195 * 196 * By default it adds the information to the path_info instead 197 * of the query data. 198 * 199 * @param action A String with the action value. 200 * @return A <code>TemplateLink</code> (self). 201 */ 202 public TemplateLink setAction(String action) 203 { 204 log.debug("setAction(" + action + ")"); 205 templateURI.setAction(action); 206 return this; 207 } 208 209 /** 210 * Sets the action= and eventSubmit= values for this URL. 211 * 212 * By default it adds the information to the path_info instead 213 * of the query data. 214 * 215 * @param action A String with the action value. 216 * @param event A string with the event name. 217 * @return A <code>TemplateLink</code> (self). 218 */ 219 public TemplateLink setActionEvent(String action, String event) 220 { 221 log.debug("setActionEvent(" + action + ", "+ event +")"); 222 templateURI.setActionEvent(action, event); 223 return this; 224 } 225 226 /** 227 * Sets the screen= value for this URL. 228 * 229 * By default it adds the information to the path_info instead 230 * of the query data. 231 * 232 * @param screen A String with the screen value. 233 * @return A <code>TemplateLink</code> (self). 234 */ 235 public TemplateLink setScreen(String screen) 236 { 237 log.debug("setScreen(" + screen + ")"); 238 templateURI.setScreen(screen); 239 return this; 240 } 241 242 /** 243 * Sets a reference anchor (#ref). 244 * 245 * @param reference A String containing the reference. 246 * @return A <code>TemplateLink</code> (self). 247 */ 248 public TemplateLink setReference(String reference) 249 { 250 templateURI.setReference(reference); 251 return this; 252 } 253 254 /** 255 * Returns the current reference anchor. 256 * 257 * @return A String containing the reference. 258 */ 259 public String getReference() 260 { 261 return templateURI.getReference(); 262 } 263 264 /* 265 * ======================================================================== 266 * 267 * Adding and removing Data from the Path Info and Query Data 268 * 269 * ======================================================================== 270 */ 271 272 273 /** 274 * Adds a name=value pair for every entry in a ParameterParser 275 * object to the path_info string. 276 * 277 * @param pp A ParameterParser. 278 * @return A <code>TemplateLink</code> (self). 279 */ 280 public TemplateLink addPathInfo(ParameterParser pp) 281 { 282 templateURI.addPathInfo(pp); 283 return this; 284 } 285 286 /** 287 * Adds a name=value pair to the path_info string. 288 * 289 * @param name A String with the name to add. 290 * @param value An Object with the value to add. 291 * @return A <code>TemplateLink</code> (self). 292 */ 293 public TemplateLink addPathInfo(String name, Object value) 294 { 295 templateURI.addPathInfo(name, value); 296 return this; 297 } 298 299 /** 300 * Adds a name=value pair to the path_info string. 301 * 302 * @param name A String with the name to add. 303 * @param value A String with the value to add. 304 * @return A <code>TemplateLink</code> (self). 305 */ 306 public TemplateLink addPathInfo(String name, String value) 307 { 308 templateURI.addPathInfo(name, value); 309 return this; 310 } 311 312 /** 313 * Adds a name=value pair to the path_info string. 314 * 315 * @param name A String with the name to add. 316 * @param value A double with the value to add. 317 * @return A <code>TemplateLink</code> (self). 318 */ 319 public TemplateLink addPathInfo(String name, double value) 320 { 321 templateURI.addPathInfo(name, value); 322 return this; 323 } 324 325 /** 326 * Adds a name=value pair to the path_info string. 327 * 328 * @param name A String with the name to add. 329 * @param value An int with the value to add. 330 * @return A <code>TemplateLink</code> (self). 331 */ 332 public TemplateLink addPathInfo(String name, int value) 333 { 334 templateURI.addPathInfo(name, value); 335 return this; 336 } 337 338 /** 339 * Adds a name=value pair to the path_info string. 340 * 341 * @param name A String with the name to add. 342 * @param value A long with the value to add. 343 * @return A <code>TemplateLink</code> (self). 344 */ 345 public TemplateLink addPathInfo(String name, long value) 346 { 347 templateURI.addPathInfo(name, value); 348 return this; 349 } 350 351 /** 352 * Adds a name=value pair to the query string. 353 * 354 * @param name A String with the name to add. 355 * @param value An Object with the value to add. 356 * @return A <code>TemplateLink</code> (self). 357 */ 358 public TemplateLink addQueryData(String name, Object value) 359 { 360 templateURI.addQueryData(name, value); 361 return this; 362 } 363 364 /** 365 * Adds a name=value pair to the query string. 366 * 367 * @param name A String with the name to add. 368 * @param value A String with the value to add. 369 * @return A <code>TemplateLink</code> (self). 370 */ 371 public TemplateLink addQueryData(String name, String value) 372 { 373 templateURI.addQueryData(name, value); 374 return this; 375 } 376 377 /** 378 * Adds a name=value pair to the query string. 379 * 380 * @param name A String with the name to add. 381 * @param value A double with the value to add. 382 * @return A <code>TemplateLink</code> (self). 383 */ 384 public TemplateLink addQueryData(String name, double value) 385 { 386 templateURI.addQueryData(name, value); 387 return this; 388 } 389 390 /** 391 * Adds a name=value pair to the query string. 392 * 393 * @param name A String with the name to add. 394 * @param value An int with the value to add. 395 * @return A <code>TemplateLink</code> (self). 396 */ 397 public TemplateLink addQueryData(String name, int value) 398 { 399 templateURI.addQueryData(name, value); 400 return this; 401 } 402 403 /** 404 * Adds a name=value pair to the query string. 405 * 406 * @param name A String with the name to add. 407 * @param value A long with the value to add. 408 * @return A <code>TemplateLink</code> (self). 409 */ 410 public TemplateLink addQueryData(String name, long value) 411 { 412 templateURI.addQueryData(name, value); 413 return this; 414 } 415 416 /** 417 * Adds a name=value pair for every entry in a ParameterParser 418 * object to the query string. 419 * 420 * @param pp A ParameterParser. 421 * @return A <code>TemplateLink</code> (self). 422 */ 423 public TemplateLink addQueryData(ParameterParser pp) 424 { 425 templateURI.addQueryData(pp); 426 return this; 427 } 428 429 /** 430 * Removes all the path info elements. 431 * 432 * @return A <code>TemplateLink</code> (self). 433 */ 434 public TemplateLink removePathInfo() 435 { 436 templateURI.removePathInfo(); 437 return this; 438 } 439 440 /** 441 * Removes a name=value pair from the path info. 442 * 443 * @param name A String with the name to be removed. 444 * @return A <code>TemplateLink</code> (self). 445 */ 446 public TemplateLink removePathInfo(String name) 447 { 448 templateURI.removePathInfo(name); 449 return this; 450 } 451 452 /** 453 * Removes all the query string elements. 454 * 455 * @return A <code>TemplateLink</code> (self). 456 */ 457 public TemplateLink removeQueryData() 458 { 459 templateURI.removeQueryData(); 460 return this; 461 } 462 463 /** 464 * Removes a name=value pair from the query string. 465 * 466 * @param name A String with the name to be removed. 467 * @return A <code>TemplateLink</code> (self). 468 */ 469 public TemplateLink removeQueryData(String name) 470 { 471 templateURI.removeQueryData(name); 472 return this; 473 } 474 475 /** 476 * Builds the URL with all of the data URL-encoded as well as 477 * encoded using HttpServletResponse.encodeUrl(). The resulting 478 * URL is absolute; it starts with http/https... 479 * 480 * <p> 481 * <code><pre> 482 * TemplateURI tui = new TemplateURI (data, "UserScreen"); 483 * tui.addPathInfo("user","jon"); 484 * tui.getAbsoluteLink(); 485 * </pre></code> 486 * 487 * The above call to absoluteLink() would return the String: 488 * 489 * <p> 490 * http://www.server.com/servlets/Turbine/screen/UserScreen/user/jon 491 * 492 * <p> 493 * After rendering the URI, it clears the 494 * pathInfo and QueryString portions of the TemplateURI. So you can 495 * use the $link reference multiple times on a page and start over 496 * with a fresh object every time. 497 * 498 * @return A String with the built URL. 499 */ 500 public String getAbsoluteLink() 501 { 502 String output = templateURI.getAbsoluteLink(); 503 504 // This was added to use $link multiple times on a page and start 505 // over with a fresh set of data every time. 506 templateURI.removePathInfo(); 507 templateURI.removeQueryData(); 508 509 return output; 510 } 511 512 513 /** 514 * Builds the URL with all of the data URL-encoded as well as 515 * encoded using HttpServletResponse.encodeUrl(). The resulting 516 * URL is relative to the webserver root. 517 * 518 * <p> 519 * <code><pre> 520 * TemplateURI tui = new TemplateURI (data, "UserScreen"); 521 * tui.addPathInfo("user","jon"); 522 * tui.getRelativeLink(); 523 * </pre></code> 524 * 525 * The above call to absoluteLink() would return the String: 526 * 527 * <p> 528 * /servlets/Turbine/screen/UserScreen/user/jon 529 * 530 * <p> 531 * After rendering the URI, it clears the 532 * pathInfo and QueryString portions of the TemplateURI. So you can 533 * use the $link reference multiple times on a page and start over 534 * with a fresh object every time. 535 * 536 * @return A String with the built URL. 537 */ 538 public String getRelativeLink() 539 { 540 String output = templateURI.getRelativeLink(); 541 542 // This was added to use $link multiple times on a page and start 543 // over with a fresh set of data every time. 544 templateURI.removePathInfo(); 545 templateURI.removeQueryData(); 546 547 return output; 548 } 549 550 /** 551 * Returns the URI. After rendering the URI, it clears the 552 * pathInfo and QueryString portions of the TemplateURI. 553 * 554 * @return A String with the URI in the form 555 * http://foo.com/Turbine/template/index.wm/hello/world 556 */ 557 public String getLink() 558 { 559 return wantRelative ? 560 getRelativeLink() : getAbsoluteLink(); 561 } 562 563 /** 564 * Returns the relative URI leaving the source intact. Use this 565 * if you need the path_info and query data multiple times. 566 * This is equivalent to $link.Link or just $link, 567 * but does not reset the path_info and query data. 568 * 569 * @return A String with the URI in the form 570 * http://foo.com/Turbine/template/index.wm/hello/world 571 */ 572 public String getURI() 573 { 574 return wantRelative ? 575 templateURI.getRelativeLink() : templateURI.getAbsoluteLink(); 576 } 577 578 /** 579 * Returns the absolute URI leaving the source intact. Use this 580 * if you need the path_info and query data multiple times. 581 * This is equivalent to $link.AbsoluteLink but does not reset 582 * the path_info and query data. 583 * 584 * @return A String with the URI in the form 585 * http://foo.com/Turbine/template/index.wm/hello/world 586 */ 587 public String getAbsoluteURI() 588 { 589 return templateURI.getAbsoluteLink(); 590 } 591 592 /** 593 * Returns the relative URI leaving the source intact. Use this 594 * if you need the path_info and query data multiple times. 595 * This is equivalent to $link.RelativeLink but does not reset 596 * the path_info and query data. 597 * 598 * @return A String with the URI in the form 599 * http://foo.com/Turbine/template/index.wm/hello/world 600 */ 601 public String getRelativeURI() 602 { 603 return templateURI.getRelativeLink(); 604 } 605 606 /** 607 * Same as getLink(). 608 * 609 * @return A String with the URI represented by this object. 610 * 611 */ 612 @Override 613 public String toString() 614 { 615 return getLink(); 616 } 617 }