    001package org.apache.turbine.util.uri;
    002
    003
    004/*
    005 * Licensed to the Apache Software Foundation (ASF) under one
    006 * or more contributor license agreements.  See the NOTICE file
    007 * distributed with this work for additional information
    008 * regarding copyright ownership.  The ASF licenses this file
    009 * to you under the Apache License, Version 2.0 (the
    010 * "License"); you may not use this file except in compliance
    011 * with the License.  You may obtain a copy of the License at
    012 *
    013 *   http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing,
    016 * software distributed under the License is distributed on an
    017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018 * KIND, either express or implied.  See the License for the
    019 * specific language governing permissions and limitations
    020 * under the License.
    021 */
    022
    023
    024import javax.servlet.http.HttpServletResponse;
    025
    026import org.apache.commons.lang.StringUtils;
    027
    028import org.apache.commons.logging.Log;
    029import org.apache.commons.logging.LogFactory;
    030
    031import org.apache.turbine.Turbine;
    032import org.apache.turbine.TurbineConstants;
    033
    034import org.apache.turbine.util.RunData;
    035import org.apache.turbine.util.ServerData;
    036
    037/**
    038 * This is the base class for all dynamic URIs in the Turbine System.
    039 *
    040 * All of the classes used for generating URIs are derived from this.
    041 *
    042 * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
    043 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
    044 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    045 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
    046 * @version $Id: BaseURI.java 1709648 2015-10-20 17:08:10Z tv $
    047 */
    048
    049public abstract class BaseURI
    050        implements URI,
    051                   URIConstants
    052{
    053    /** Logging */
    054    private static Log log = LogFactory.getLog(BaseURI.class);
    055
    056    /** ServerData Object for scheme, name, port etc. */
    057    private ServerData serverData =
    058            new ServerData(null, HTTP_PORT, HTTP, null, null);
    059
    060    /** Whether we want to redirect or not. */
    061    private boolean redirect = false;
    062
    063    /** Servlet response interface. */
    064    private HttpServletResponse response = null;
    065
    066    /** Reference Anchor (#ref) */
    067    private String reference = null;
    068
    069    /*
    070     * ========================================================================
    071     *
    072     * Constructors
    073     *
    074     * ========================================================================
    075     *
    076     */
    077
    078    /**
    079     * Empty C'tor. Uses Turbine.getDefaultServerData().
    080     *
    081     */
    082    public BaseURI()
    083    {
    084        init(Turbine.getDefaultServerData());
    085        setResponse(null);
    086    }
    087
    088    /**
    089     * Constructor with a RunData object
    090     *
    091     * @param runData A RunData object
    092     */
    093    public BaseURI(RunData runData)
    094    {
    095        init(runData.getServerData());
    096        setResponse(runData.getResponse());
    097    }
    098
    099    /**
    100     * Constructor, set explicit redirection
    101     *
    102     * @param runData A RunData object
    103     * @param redirect True if redirection allowed.
    104     */
    105    public BaseURI(RunData runData, boolean redirect)
    106    {
    107        init(runData.getServerData());
    108        setResponse(runData.getResponse());
    109        setRedirect(redirect);
    110    }
    111
    112    /**
    113     * Constructor with a ServerData object
    114     *
    115     * @param serverData A ServerData object
    116     */
    117    public BaseURI(ServerData serverData)
    118    {
    119        init(serverData);
    120        setResponse(null);
    121    }
    122
    123    /**
    124     * Constructor, set explicit redirection
    125     *
    126     * @param serverData A ServerData object
    127     * @param redirect True if redirection allowed.
    128     */
    129    public BaseURI(ServerData serverData, boolean redirect)
    130    {
    131        init(serverData);
    132        setResponse(null);
    133        setRedirect(redirect);
    134    }
    135
    136    /*
    137     * ========================================================================
    138     *
    139     * Init
    140     *
    141     * ========================================================================
    142     *
    143     */
    144
    145    /**
    146     * Init with a ServerData object
    147     *
    148     * @param serverData A ServerData object
    149     *
    150     */
    151    private void init(ServerData serverData)
    152    {
    153        log.debug("init(" + serverData + ")");
    154
    155        if(serverData != null)
    156        {
    157            // We must clone this, because if BaseURI is used in a pull tool,
    158            // then the fields might be changed. If we don't clone, this might pull
    159            // through to the ServerData object saved at firstRequest() in the
    160            // Turbine object.
    161            this.serverData = (ServerData) serverData.clone();
    162        }
    163        else
    164        {
    165            log.error("Passed null ServerData object!");
    166        }
    167        reference = null;
    168    }
    169
    170    /*
    171     * ========================================================================
    172     *
    173     * Getter / Setter
    174     *
    175     * ========================================================================
    176     *
    177     */
    178
    179    /**
    180     * Set the redirect Flag
    181     *
    182     * @param redirect The new value of the redirect flag.
    183     */
    184    public void setRedirect(boolean redirect)
    185    {
    186        this.redirect = redirect;
    187    }
    188
    189    /**
    190     * Returns the current value of the Redirect flag
    191     *
    192     * @return True if Redirect is allowed
    193     *
    194     */
    195    public boolean isRedirect()
    196    {
    197        return redirect;
    198    }
    199
    200    /**
    201     * Gets the script name (/servlets/Turbine).
    202     *
    203     * @return A String with the script name.
    204     */
    205    public String getScriptName()
    206    {
    207        return serverData.getScriptName();
    208    }
    209
    210    /**
    211     * Sets the script name (/servlets/Turbine).
    212     *
    213     * @param scriptName A String with the script name.
    214     */
    215    public void setScriptName(String scriptName)
    216    {
    217        serverData.setScriptName(scriptName);
    218    }
    219
    220    /**
    221     * Gets the context path.
    222     *
    223     * @return A String with the context path.
    224     */
    225    public String getContextPath()
    226    {
    227        return serverData.getContextPath();
    228    }
    229
    230    /**
    231     * Sets the context path.
    232     *
    233     * @param contextPath A String with the context path
    234     */
    235    public void setContextPath(String contextPath)
    236    {
    237        serverData.setContextPath(contextPath);
    238    }
    239
    240    /**
    241     * Gets the server name.
    242     *
    243     * @return A String with the server name.
    244     */
    245    public String getServerName()
    246    {
    247        return serverData.getServerName();
    248    }
    249
    250    /**
    251     * Sets the server name.
    252     *
    253     * @param serverName A String with the server name.
    254     */
    255    public void setServerName(String serverName)
    256    {
    257        serverData.setServerName(serverName);
    258    }
    259
    260    /**
    261     * Gets the server port.
    262     *
    263     * @return A String with the server port.
    264     */
    265    public int getServerPort()
    266    {
    267        int serverPort = serverData.getServerPort();
    268
    269        if (serverPort == 0)
    270        {
    271            if(getServerScheme().equals(HTTPS))
    272            {
    273                serverPort = HTTPS_PORT;
    274            }
    275            else
    276            {
    277                serverPort = HTTP_PORT;
    278            }
    279        }
    280        return serverPort;
    281    }
    282
    283    /**
    284     * Sets the server port.
    285     *
    286     * @param serverPort An int with the port.
    287     */
    288    public void setServerPort(int serverPort)
    289    {
    290        serverData.setServerPort(serverPort);
    291    }
    292
    293    /**
    294     * Method to specify that a URI should use SSL. The default port
    295     * is used.
    296     */
    297    public void setSecure()
    298    {
    299        setSecure(HTTPS_PORT);
    300    }
    301
    302    /**
    303     * Method to specify that a URI should use SSL.
    304     * Whether or not it does is determined from Turbine.properties.
    305     * If use.ssl in the Turbine.properties is set to false, then
    306     * http is used in any case. (Default of use.ssl is true).
    307     *
    308     * @param port An int with the port number.
    309     */
    310    public void setSecure(int port)
    311    {
    312        boolean useSSL =
    313                Turbine.getConfiguration()
    314                .getBoolean(TurbineConstants.USE_SSL_KEY,
    315                        TurbineConstants.USE_SSL_DEFAULT);
    316
    317        setServerScheme(useSSL ? HTTPS : HTTP);
    318        setServerPort(port);
    319    }
    320
    321    /**
    322     * Sets the scheme (HTTP or HTTPS).
    323     *
    324     * @param serverScheme A String with the scheme.
    325     */
    326    public void setServerScheme(String serverScheme)
    327    {
    328        serverData.setServerScheme(StringUtils.isNotEmpty(serverScheme)
    329                ? serverScheme : "");
    330    }
    331
    332    /**
    333     * Returns the current Server Scheme
    334     *
    335     * @return The current Server scheme
    336     *
    337     */
    338    public String getServerScheme()
    339    {
    340        String serverScheme = serverData.getServerScheme();
    341
    342        return StringUtils.isNotEmpty(serverScheme) ? serverScheme : HTTP;
    343    }
    344
    345    /**
    346     * Sets a reference anchor (#ref).
    347     *
    348     * @param reference A String containing the reference.
    349     */
    350    public void setReference(String reference)
    351    {
    352        this.reference = reference;
    353    }
    354
    355    /**
    356     * Returns the current reference anchor.
    357     *
    358     * @return A String containing the reference.
    359     */
    360    public String getReference()
    361    {
    362        return hasReference() ? reference : "";
    363    }
    364
    365    /**
    366     * Does this URI contain an anchor? (#ref)
    367     *
    368     * @return True if this URI contains an anchor.
    369     */
    370    public boolean hasReference()
    371    {
    372        return StringUtils.isNotEmpty(reference);
    373    }
    374
    375    /*
    376     * ========================================================================
    377     *
    378     * Protected / Private Methods
    379     *
    380     * ========================================================================
    381     *
    382     */
    383
    384    /**
    385     * Set a Response Object to use when creating the
    386     * response string.
    387     *
    388     */
    389    protected void setResponse(HttpServletResponse response)
    390    {
    391        this.response = response;
    392    }
    393
    394    /**
    395     * Returns the Response Object from the Servlet Container.
    396     *
    397     * @return The Servlet Response object or null
    398     *
    399     */
    400    protected HttpServletResponse getResponse()
    401    {
    402        return response;
    403    }
    404
    405    /**
    406     * Append the Context Path and Script Name to the passed
    407     * String Buffer.
    408     *
    409     * <p>
    410     * This is a convenience method to be
    411     * used in the Link output routines of derived classes to
    412     * easily append the correct path.
    413     *
    414     * @param sb The StringBuilder to store context path and script name.
    415     */
    416    protected void getContextAndScript(StringBuilder sb)
    417    {
    418        String context = getContextPath();
    419
    420        if(StringUtils.isNotEmpty(context))
    421        {
    422            if(context.charAt(0) != '/')
    423            {
    424                sb.append('/');
    425            }
    426            sb.append (context);
    427        }
    428
    429        // /servlet/turbine
    430        String script = getScriptName();
    431
    432        if(StringUtils.isNotEmpty(script))
    433        {
    434            if(script.charAt(0) != '/')
    435            {
    436                sb.append('/');
    437            }
    438            sb.append (script);
    439        }
    440    }
    441
    442    /**
    443     * Appends Scheme, Server and optionally the port to the
    444     * supplied String Buffer.
    445     *
    446     * <p>
    447     * This is a convenience method to be
    448     * used in the Link output routines of derived classes to
    449     * easily append the correct server scheme.
    450     *
    451     * @param sb The StringBuilder to store the scheme and port information.
    452     */
    453    protected void getSchemeAndPort(StringBuilder sb)
    454    {
    455        // http(s)://<servername>
    456        sb.append(getServerScheme());
    457        sb.append(URIConstants.URI_SCHEME_SEPARATOR);
    458        sb.append(getServerName());
    459
    460        // (:<port>)
    461        if ((getServerScheme().equals(HTTP)
    462                    && getServerPort() != HTTP_PORT)
    463                || (getServerScheme().equals(HTTPS)
    464                        && getServerPort() != HTTPS_PORT))
    465        {
    466            sb.append(':');
    467            sb.append(getServerPort());
    468        }
    469    }
    470
    471    /**
    472     * Encodes a Response Uri according to the Servlet Container.
    473     * This might add a Java session identifier or do redirection.
    474     * The resulting String can be used in a page or template.
    475     *
    476     * @param uri The Uri to encode
    477     *
    478     * @return An Uri encoded by the container.
    479     */
    480    protected String encodeResponse(String uri)
    481    {
    482        String res = uri;
    483
    484        HttpServletResponse response = getResponse();
    485
    486        if(response == null)
    487        {
    488            log.debug("No Response Object!");
    489        }
    490        else
    491        {
    492            try
    493            {
    494                if(isRedirect())
    495                {
    496                    log.debug("Should Redirect");
    497                    res = response.encodeRedirectURL(uri);
    498                }
    499                else
    500                {
    501                    res = response.encodeURL(uri);
    502                }
    503            }
    504            catch(Exception e)
    505            {
    506                log.error("response" + response + ", uri: " + uri);
    507                log.error("While trying to encode the URI: ", e);
    508            }
    509        }
    510
    511        log.debug("encodeResponse():  " + res);
    512        return res;
    513    }
    514}