001// Copyright 2006, 2007, 2008, 2010, 2011 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007// http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry5;
016
017import org.apache.commons.codec.net.URLCodec;
018import org.apache.tapestry5.internal.services.LinkSecurity;
019import org.apache.tapestry5.services.BaseURLSource;
020import org.apache.tapestry5.services.ContextPathEncoder;
021import org.apache.tapestry5.services.Request;
022
023import java.util.List;
024
025/**
026 * A link is the Tapestry representation of a URL or URI that triggers dynamic behavior. This link is in three parts: a
027 * path portion, an optional anchor, and a set of query parameters. A request for a link will ultimately be recognized
028 * by a {@link org.apache.tapestry5.services.Dispatcher}.
029 * <p/>
030 * Query parameter values are kept separate from the path portion to support encoding those values into hidden form
031 * fields (where appropriate).
032 */
033public interface Link
034{
035    /**
036     * Returns the names of any additional query parameters for the URI. Query parameters store less regular or less
037     * often used values that can not be expressed in the path. They also are used to store, or link to, persistent
038     * state.
039     *
040     * @return list of query parameter names, is alphabetical order
041     */
042    List<String> getParameterNames();
043
044    /**
045     * Returns the value of a specifically named query parameter, or <tt>null</tt> if no such query parameter is stored
046     * in the link.
047     *
048     * <p>Use this method only when you are sure the parameter has only one value. If the parameter might have more than
049     * one value, use {@link #getParameterValues}.
050     *
051     * <p>If you use this method with a multivalued parameter, the value returned is equal to the first value in the
052     * array returned by <code>getParameterValues</code>.
053     *
054     * @return a string representing the single value of the named parameter
055     */
056    String getParameterValue(String name);
057
058    /**
059     * Adds a parameter value. The value will be added, as is, to the URL. In many cases, the value should be URL
060     * encoded via {@link URLCodec}.
061     *
062     * @param parameterName the name of the parameter to store
063     * @param value         the value to store, a null or blank value is allowed (as of Tapestry 5.3)
064     */
065    void addParameter(String parameterName, String value);
066
067    /**
068     * Adds a parameter value as a value object; the value object is converted to a string via
069     * {@link ContextPathEncoder#encodeValue(Object)} and the result is added via {@link #addParameter(String, String)}.
070     * The Link object is returned for further configuration.
071     *
072     * @since 5.2.2
073     */
074    Link addParameterValue(String parameterName, Object value);
075
076    /**
077     * Removes a parameter value, which is occasionally useful when transforming a parameter into a portion of
078     * the path.
079     *
080     * @since 5.2.0
081     */
082    void removeParameter(String parameterName);
083
084    /**
085     * Returns the completely unadorned base path. Other methods (such as {@link #toURI()}), may append
086     * an anchor or query parameters.
087     *
088     * @since 5.2.0
089     */
090    String getBasePath();
091
092    /**
093     * Creates a copy of this link that has the same parameters, anchor, and other attributes, but a different
094     * {@linkplain #getBasePath() base path}.
095     *
096     * @since 5.2.0
097     */
098    Link copyWithBasePath(String basePath);
099
100    /**
101     * Returns the URI portion of the link. When the link is created for a form, this will not include query parameters.
102     * This is the same value returned from toString().
103     *
104     * @return the URI, ready to be added as an element attribute
105     */
106    String toURI();
107
108    /**
109     * Returns the link as a redirect URI. The URI includes any query parameters.
110     */
111    String toRedirectURI();
112
113    /**
114     * Returns the link anchor. If this link does not have an anchor, this method returns <tt>null</tt>.
115     *
116     * @return the link anchor
117     */
118    String getAnchor();
119
120    /**
121     * Sets the link anchor. Null and empty anchors will be ignored when building the link URI.
122     *
123     * @param anchor the link anchor
124     */
125    void setAnchor(String anchor);
126
127    /**
128     * Returns the absolute URL, which includes the scheme, hostname and possibly port (as per
129     * {@link BaseURLSource#getBaseURL(boolean)}).
130     * By default, the scheme is chosen to match the current {@linkplain Request#isSecure() requests security}.
131     * <p/>
132     * Note: the semantics of this method changed between Tapestry 5.1 and 5.2. Most code should use toString() or
133     * {@link #toURI()} (which are equivalent) instead.
134     *
135     * @return the complete, qualified URL, including query parameters.
136     */
137    String toAbsoluteURI();
138
139    /**
140     * Returns either the secure or insecure URL, with complete scheme, hostname and possibly port (as per
141     * {@link BaseURLSource#getBaseURL(boolean)}).
142     *
143     * @return the complete, qualified URL, including query parameters.
144     * @since 5.2.2
145     */
146    String toAbsoluteURI(boolean secure);
147
148    /**
149     * Changes the link's security, which can be useful to force a link to be either secure or insecure
150     * when normally it might not be.
151     *
152     * @param newSecurity new security value, not null, typically {@link LinkSecurity#FORCE_SECURE} or {@link LinkSecurity#FORCE_INSECURE}
153     * @since 5.3
154     */
155    void setSecurity(LinkSecurity newSecurity);
156
157    /**
158     * Returns the current security for this link, which reflects whether the targetted page is itself secure or insecure.
159     *
160     * @since 5.3
161     */
162    LinkSecurity getSecurity();
163
164    /**
165     * Returns the parameter values for the given name. Returns null if no such parameter is stored in the link.
166     */
167    String[] getParameterValues(String parameterName);
168
169}