View Javadoc

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