    001    package 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
    024    import javax.servlet.http.HttpServletResponse;
    025
    026    import org.apache.commons.lang.StringUtils;
    027
    028    import org.apache.commons.logging.Log;
    029    import org.apache.commons.logging.LogFactory;
    030
    031    import org.apache.turbine.Turbine;
    032    import org.apache.turbine.TurbineConstants;
    033
    034    import org.apache.turbine.util.RunData;
    035    import 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 615328 2008-01-25 20:25:05Z tv $
    047     */
    048
    049    public 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 StringBuffer to store context path and script name.
    415         */
    416        protected void getContextAndScript(StringBuffer 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 StringBuffer to store the scheme and port information.
    452         */
    453        protected void getSchemeAndPort(StringBuffer 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    }