View Javadoc

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 }