blob: 122226a5d8ee1a9de424cb3ce9324c30969ebd6b [file] [log] [blame]
package org.apache.turbine.services.pull.tools;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.commons.configuration2.Configuration;
import org.apache.fulcrum.parser.ParameterParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.turbine.Turbine;
import org.apache.turbine.pipeline.PipelineData;
import org.apache.turbine.services.pull.ApplicationTool;
import org.apache.turbine.util.RunData;
import org.apache.turbine.util.uri.TemplateURI;
/**
* This is a pull to to be used in Templates to convert links in
* Templates into the correct references.
*
* The pull service might insert this tool into the Context.
* in templates. Here's an example of its Velocity use:
*
* <p><code>
* $link.setPage("index.vm").addPathInfo("hello","world")
* This would return: http://foo.com/Turbine/template/index.vm/hello/world
* </code>
*
* <p>
*
* This is an application pull tool for the template system. You should <b>not</b>
* use it in a normal application!
*
* @author <a href="mbryson@mont.mindspring.com">Dave Bryson</a>
* @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
* @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
* @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
* @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
* @version $Id$
*/
public class TemplateLink
implements ApplicationTool
{
/** Prefix for Parameters for this tool */
public static final String TEMPLATE_LINK_PREFIX = "tool.link";
/** Should this tool return relative URIs or absolute? Default: Absolute. */
public static final String TEMPLATE_LINK_RELATIVE_KEY = "want.relative";
/** Default Value for TEMPLATE_LINK_RELATIVE_KEY */
public static final boolean TEMPLATE_LINK_RELATIVE_DEFAULT = false;
/** Do we want a relative link? */
protected boolean wantRelative = false;
/** cache of the template name for getPage() */
protected String template = null;
/** TemplateURI used as backend for this object */
protected TemplateURI templateURI = null;
/** Logging */
private static final Logger log = LogManager.getLogger(TemplateLink.class);
/**
* Default constructor
* <p>
* The init method must be called before use.
*/
public TemplateLink()
{
// empty
}
/*
* ========================================================================
*
* Application Tool Interface
*
* ========================================================================
*
*/
/**
* This will initialize a TemplateLink object that was
* constructed with the default constructor (ApplicationTool
* method).
*
* @param data assumed to be a PipelineData object
*/
@Override
public void init(Object data)
{
// we just blithely cast to RunData as if another object
// or null is passed in we'll throw an appropriate runtime
// exception.
if (data instanceof PipelineData)
{
PipelineData pipelineData = (PipelineData) data;
RunData runData = (RunData)pipelineData;
templateURI = new TemplateURI(runData);
}
else
{
templateURI = new TemplateURI((RunData) data);
}
Configuration conf =
Turbine.getConfiguration().subset(TEMPLATE_LINK_PREFIX);
if (conf != null)
{
wantRelative = conf.getBoolean(TEMPLATE_LINK_RELATIVE_KEY,
TEMPLATE_LINK_RELATIVE_DEFAULT);
}
}
/**
* Refresh method - does nothing
*/
@Override
public void refresh()
{
// empty
}
/*
* ========================================================================
*
* getter/setter
*
* All setter return "this" so you can "chain" them together in the Context
*
* ========================================================================
*/
/**
* This will turn off the execution of res.encodeURL()
* by making res == null. This is a hack for cases
* where you don't want to see the session information
*
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink setEncodeURLOff()
{
templateURI.clearResponse();
return this;
}
/**
* Sets the template variable used by the Template Service.
*
* @param template A String with the template name.
* @return A TemplateLink.
*/
public TemplateLink setPage(String template)
{
log.debug("setPage({})", template);
this.template = template;
templateURI.setTemplate(template);
return this;
}
/**
* Gets the template variable used by the Template Service.
* It is only available after setPage() has been called.
*
* @return The template name.
*/
public String getPage()
{
return template;
}
/**
* Sets the action= value for this URL.
*
* By default it adds the information to the path_info instead
* of the query data.
*
* @param action A String with the action value.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink setAction(String action)
{
log.debug("setAction({})", action);
templateURI.setAction(action);
return this;
}
/**
* Sets the action= and eventSubmit= values for this URL.
*
* By default it adds the information to the path_info instead
* of the query data.
*
* @param action A String with the action value.
* @param event A string with the event name.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink setActionEvent(String action, String event)
{
log.debug("setActionEvent({}, {})", action, event);
templateURI.setActionEvent(action, event);
return this;
}
/**
* Sets the screen= value for this URL.
*
* By default it adds the information to the path_info instead
* of the query data.
*
* @param screen A String with the screen value.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink setScreen(String screen)
{
log.debug("setScreen({})", screen);
templateURI.setScreen(screen);
return this;
}
/**
* Sets a reference anchor (#ref).
*
* @param reference A String containing the reference.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink setReference(String reference)
{
templateURI.setReference(reference);
return this;
}
/**
* Returns the current reference anchor.
*
* @return A String containing the reference.
*/
public String getReference()
{
return templateURI.getReference();
}
/*
* ========================================================================
*
* Adding and removing Data from the Path Info and Query Data
*
* ========================================================================
*/
/**
* Adds a name=value pair for every entry in a ParameterParser
* object to the path_info string.
*
* @param pp A ParameterParser.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addPathInfo(ParameterParser pp)
{
templateURI.addPathInfo(pp);
return this;
}
/**
* Adds a name=value pair to the path_info string.
*
* @param name A String with the name to add.
* @param value An Object with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addPathInfo(String name, Object value)
{
templateURI.addPathInfo(name, value);
return this;
}
/**
* Adds a name=value pair to the path_info string.
*
* @param name A String with the name to add.
* @param value A String with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addPathInfo(String name, String value)
{
templateURI.addPathInfo(name, value);
return this;
}
/**
* Adds a name=value pair to the path_info string.
*
* @param name A String with the name to add.
* @param value A double with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addPathInfo(String name, double value)
{
templateURI.addPathInfo(name, value);
return this;
}
/**
* Adds a name=value pair to the path_info string.
*
* @param name A String with the name to add.
* @param value An int with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addPathInfo(String name, int value)
{
templateURI.addPathInfo(name, value);
return this;
}
/**
* Adds a name=value pair to the path_info string.
*
* @param name A String with the name to add.
* @param value A long with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addPathInfo(String name, long value)
{
templateURI.addPathInfo(name, value);
return this;
}
/**
* Adds a name=value pair to the query string.
*
* @param name A String with the name to add.
* @param value An Object with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addQueryData(String name, Object value)
{
templateURI.addQueryData(name, value);
return this;
}
/**
* Adds a name=value pair to the query string.
*
* @param name A String with the name to add.
* @param value A String with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addQueryData(String name, String value)
{
templateURI.addQueryData(name, value);
return this;
}
/**
* Adds a name=value pair to the query string.
*
* @param name A String with the name to add.
* @param value A double with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addQueryData(String name, double value)
{
templateURI.addQueryData(name, value);
return this;
}
/**
* Adds a name=value pair to the query string.
*
* @param name A String with the name to add.
* @param value An int with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addQueryData(String name, int value)
{
templateURI.addQueryData(name, value);
return this;
}
/**
* Adds a name=value pair to the query string.
*
* @param name A String with the name to add.
* @param value A long with the value to add.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addQueryData(String name, long value)
{
templateURI.addQueryData(name, value);
return this;
}
/**
* Adds a name=value pair for every entry in a ParameterParser
* object to the query string.
*
* @param pp A ParameterParser.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink addQueryData(ParameterParser pp)
{
templateURI.addQueryData(pp);
return this;
}
/**
* Removes all the path info elements.
*
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink removePathInfo()
{
templateURI.removePathInfo();
return this;
}
/**
* Removes a name=value pair from the path info.
*
* @param name A String with the name to be removed.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink removePathInfo(String name)
{
templateURI.removePathInfo(name);
return this;
}
/**
* Removes all the query string elements.
*
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink removeQueryData()
{
templateURI.removeQueryData();
return this;
}
/**
* Removes a name=value pair from the query string.
*
* @param name A String with the name to be removed.
* @return A <code>TemplateLink</code> (self).
*/
public TemplateLink removeQueryData(String name)
{
templateURI.removeQueryData(name);
return this;
}
/**
* Builds the URL with all of the data URL-encoded as well as
* encoded using HttpServletResponse.encodeUrl(). The resulting
* URL is absolute; it starts with http/https...
*
* <pre>
* TemplateURI tui = new TemplateURI (data, "UserScreen");
* tui.addPathInfo("user","jon");
* tui.getAbsoluteLink();
* </pre>
*
* The above call to absoluteLink() would return the String:
* <p>
* http://www.server.com/servlets/Turbine/screen/UserScreen/user/jon
* <p>
* After rendering the URI, it clears the
* pathInfo and QueryString portions of the TemplateURI. So you can
* use the $link reference multiple times on a page and start over
* with a fresh object every time.
*
* @return A String with the built URL.
*/
public String getAbsoluteLink()
{
String output = templateURI.getAbsoluteLink();
// This was added to use $link multiple times on a page and start
// over with a fresh set of data every time.
templateURI.removePathInfo();
templateURI.removeQueryData();
return output;
}
/**
* Builds the URL with all of the data URL-encoded as well as
* encoded using HttpServletResponse.encodeUrl(). The resulting
* URL is relative to the webserver root.
*
* <pre>
* TemplateURI tui = new TemplateURI (data, "UserScreen");
* tui.addPathInfo("user","jon");
* tui.getRelativeLink();
* </pre>
*
* The above call to relativeLink() would return the String:
* <p>
* /servlets/Turbine/screen/UserScreen/user/jon
* <p>
* After rendering the URI, it clears the
* pathInfo and QueryString portions of the TemplateURI. So you can
* use the $link reference multiple times on a page and start over
* with a fresh object every time.
*
* @return A String with the built URL.
*/
public String getRelativeLink()
{
String output = templateURI.getRelativeLink();
// This was added to use $link multiple times on a page and start
// over with a fresh set of data every time.
templateURI.removePathInfo();
templateURI.removeQueryData();
return output;
}
/**
* Returns the URI. After rendering the URI, it clears the
* pathInfo and QueryString portions of the TemplateURI.
*
* @return A String with the URI in the form
* http://foo.com/Turbine/template/index.wm/hello/world
*/
public String getLink()
{
return wantRelative ?
getRelativeLink() : getAbsoluteLink();
}
/**
* Returns the relative URI leaving the source intact. Use this
* if you need the path_info and query data multiple times.
* This is equivalent to $link.Link or just $link,
* but does not reset the path_info and query data.
*
* @return A String with the URI in the form
* http://foo.com/Turbine/template/index.wm/hello/world
*/
public String getURI()
{
return wantRelative ?
templateURI.getRelativeLink() : templateURI.getAbsoluteLink();
}
/**
* Returns the absolute URI leaving the source intact. Use this
* if you need the path_info and query data multiple times.
* This is equivalent to $link.AbsoluteLink but does not reset
* the path_info and query data.
*
* @return A String with the URI in the form
* http://foo.com/Turbine/template/index.wm/hello/world
*/
public String getAbsoluteURI()
{
return templateURI.getAbsoluteLink();
}
/**
* Returns the relative URI leaving the source intact. Use this
* if you need the path_info and query data multiple times.
* This is equivalent to $link.RelativeLink but does not reset
* the path_info and query data.
*
* @return A String with the URI in the form
* http://foo.com/Turbine/template/index.wm/hello/world
*/
public String getRelativeURI()
{
return templateURI.getRelativeLink();
}
/**
* Same as getLink().
*
* @return A String with the URI represented by this object.
*
*/
@Override
public String toString()
{
return getLink();
}
}