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 }