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