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 1706239 2015-10-01 13:18:35Z 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 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 * <p>
483 * <code><pre>
484 * TemplateURI tui = new TemplateURI (data, "UserScreen");
485 * tui.addPathInfo("user","jon");
486 * tui.getAbsoluteLink();
487 * </pre></code>
488 *
489 * The above call to absoluteLink() would return the String:
490 *
491 * <p>
492 * http://www.server.com/servlets/Turbine/screen/UserScreen/user/jon
493 *
494 * <p>
495 * After rendering the URI, it clears the
496 * pathInfo and QueryString portions of the TemplateURI. So you can
497 * use the $link reference multiple times on a page and start over
498 * with a fresh object every time.
499 *
500 * @return A String with the built URL.
501 */
502 public String getAbsoluteLink()
503 {
504 String output = templateURI.getAbsoluteLink();
505
506 // This was added to use $link multiple times on a page and start
507 // over with a fresh set of data every time.
508 templateURI.removePathInfo();
509 templateURI.removeQueryData();
510
511 return output;
512 }
513
514
515 /**
516 * Builds the URL with all of the data URL-encoded as well as
517 * encoded using HttpServletResponse.encodeUrl(). The resulting
518 * URL is relative to the webserver root.
519 *
520 * <p>
521 * <code><pre>
522 * TemplateURI tui = new TemplateURI (data, "UserScreen");
523 * tui.addPathInfo("user","jon");
524 * tui.getRelativeLink();
525 * </pre></code>
526 *
527 * The above call to absoluteLink() would return the String:
528 *
529 * <p>
530 * /servlets/Turbine/screen/UserScreen/user/jon
531 *
532 * <p>
533 * After rendering the URI, it clears the
534 * pathInfo and QueryString portions of the TemplateURI. So you can
535 * use the $link reference multiple times on a page and start over
536 * with a fresh object every time.
537 *
538 * @return A String with the built URL.
539 */
540 public String getRelativeLink()
541 {
542 String output = templateURI.getRelativeLink();
543
544 // This was added to use $link multiple times on a page and start
545 // over with a fresh set of data every time.
546 templateURI.removePathInfo();
547 templateURI.removeQueryData();
548
549 return output;
550 }
551
552 /**
553 * Returns the URI. After rendering the URI, it clears the
554 * pathInfo and QueryString portions of the TemplateURI.
555 *
556 * @return A String with the URI in the form
557 * http://foo.com/Turbine/template/index.wm/hello/world
558 */
559 public String getLink()
560 {
561 return wantRelative ?
562 getRelativeLink() : getAbsoluteLink();
563 }
564
565 /**
566 * Returns the relative URI leaving the source intact. Use this
567 * if you need the path_info and query data multiple times.
568 * This is equivalent to $link.Link or just $link,
569 * but does not reset the path_info and query data.
570 *
571 * @return A String with the URI in the form
572 * http://foo.com/Turbine/template/index.wm/hello/world
573 */
574 public String getURI()
575 {
576 return wantRelative ?
577 templateURI.getRelativeLink() : templateURI.getAbsoluteLink();
578 }
579
580 /**
581 * Returns the absolute URI leaving the source intact. Use this
582 * if you need the path_info and query data multiple times.
583 * This is equivalent to $link.AbsoluteLink but does not reset
584 * the path_info and query data.
585 *
586 * @return A String with the URI in the form
587 * http://foo.com/Turbine/template/index.wm/hello/world
588 */
589 public String getAbsoluteURI()
590 {
591 return templateURI.getAbsoluteLink();
592 }
593
594 /**
595 * Returns the relative URI leaving the source intact. Use this
596 * if you need the path_info and query data multiple times.
597 * This is equivalent to $link.RelativeLink but does not reset
598 * the path_info and query data.
599 *
600 * @return A String with the URI in the form
601 * http://foo.com/Turbine/template/index.wm/hello/world
602 */
603 public String getRelativeURI()
604 {
605 return templateURI.getRelativeLink();
606 }
607
608 /**
609 * Same as getLink().
610 *
611 * @return A String with the URI represented by this object.
612 *
613 */
614 @Override
615 public String toString()
616 {
617 return getLink();
618 }
619 }