org.acmsl.commons.utils.http.HttpServletUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.acmsl.commons.utils.http.HttpServletUtils.java

Source

//;-*- mode: java -*-
/*
                    ACM-SL Commons
    
Copyright (C) 2002-today  Jose San Leandro Armendariz
                          chous@acm-sl.org
    
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or any later version.
    
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
    
You should have received a copy of the GNU General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    
Thanks to ACM S.L. for distributing this library under the GPL license.
Contact info: jose.sanleandro@acm-sl.com
     
 ******************************************************************************
 *
 * Filename: HttpServletUtils.java
 *
 * Author: Jose San Leandro Armendariz
 *
 * Description: Provides some useful methods when dealing with HTTP-related
 *              issues.
 */
package org.acmsl.commons.utils.http;

/*
 * Importing project classes.
 */
import org.acmsl.commons.patterns.Utils;
import org.acmsl.commons.patterns.Singleton;
import org.acmsl.commons.regexpplugin.Matcher;
import org.acmsl.commons.regexpplugin.MatchResult;
import org.acmsl.commons.regexpplugin.Pattern;
import org.acmsl.commons.regexpplugin.RegexpEngine;
import org.acmsl.commons.regexpplugin.RegexpEngineNotFoundException;
import org.acmsl.commons.regexpplugin.RegexpManager;
import org.acmsl.commons.regexpplugin.RegexpPluginMisconfiguredException;
import org.acmsl.commons.utils.regexp.RegexpUtils;

/*
 * Importing some Servlet-related classes.
 */
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;

/*
 * Importing some JDK classes.
 */
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Locale;
import java.util.StringTokenizer;

/*
 * Importing some Apache Commons Logging classes.
 */
import org.apache.commons.logging.LogFactory;

/*
 * Importing JetBrains annotations.
 */
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Provides some useful methods when dealing with HttpServlet-related issues.
 * @author <a href="mailto:chous@acm-sl.org">Jose San Leandro Armendariz</a>
 */
public class HttpServletUtils implements Utils, Singleton {
    /**
     * The locale parameter.
     */
    public static final String LOCALE_PARAMETER = "lang";

    /**
     * The name-value pair regexp.
     */
    public static final String NAME_VALUE_PAIR_REGEXP = "(.*)?=(.*)";

    /**
     * A cached name-value pair compiled regexp.
     */
    private static Pattern m__NameValuePairRegexp;

    /**
     * Singleton implemented to avoid the double-checked locking.
     */
    private static class HttpServletUtilsSingletonContainer {
        /**
         * The actual singleton.
         */
        @NotNull
        public static final HttpServletUtils SINGLETON = new HttpServletUtils();
    }

    /**
     * Default protected constructor to avoid accidental instantiation.
     */
    protected HttpServletUtils() {
    }

    /**
     * Retrieves a HttpServletUtils instance.
     * @return such instance.
     */
    @NotNull
    public static HttpServletUtils getInstance() {
        return HttpServletUtilsSingletonContainer.SINGLETON;
    }

    /**
     * Specifies the name-value pair regexp.
     * @param regexp such regexp.
     */
    protected static final void immutableSetNameValuePairRegexp(@NotNull final Pattern regexp) {
        m__NameValuePairRegexp = regexp;
    }

    /**
     * Specifies the name-value pair regexp.
     * @param regexp such regexp.
     */
    protected static void setNameValuePairRegexp(@NotNull final Pattern regexp) {
        immutableSetNameValuePairRegexp(regexp);
    }

    /**
     * Retrieves the name-value pair regexp.
     * @return such regexp.
     */
    @Nullable
    protected static Pattern getNameValuePairRegexp() {
        return m__NameValuePairRegexp;
    }

    /**
     * Internationalizes given URL using a configurable convention.
     * @param url the url to internationalize.
     * @param locale the language.
     * @return the translated url.
     */
    @NotNull
    public String i14e(@NotNull final String url, @NotNull final Locale locale) {
        return i14e(url, locale, LOCALE_PARAMETER);
    }

    /**
     * Internationalizes given URL using a configurable convention.
     * @param url the url to internationalize.
     * @param locale the language.
     * @param localeParameter the locale parameter.
     * @return the translated url.
     */
    @NotNull
    public String i14e(@NotNull final String url, @NotNull final Locale locale,
            @NotNull final String localeParameter) {
        return addParameter(url, localeParameter, locale.getLanguage());
    }

    /**
     * Adds a concrete parameter to given URL.
     * @param url the url to be updated.
     * @param paramName the parameter name.
     * @param paramValue the parameter value.
     * @return the modified url.
     */
    @NotNull
    public String addParameter(@NotNull final String url, @NotNull final String paramName,
            @NotNull final String paramValue) {
        @NotNull
        String result = url;

        try {
            result = append(url,
                    URLEncoder.encode(paramName, "UTF-8") + "=" + URLEncoder.encode(paramValue, "UTF-8"));
        } catch (final UnsupportedEncodingException unsupportedEncodingException) {
            LogFactory.getLog(HttpServletUtils.class).fatal("cannot manage query-string parameters",
                    unsupportedEncodingException);
        }

        return result;
    }

    /**
     * Safely appends extra information to given url.
     * @param url the first part of the url.
     * @param extraInfo the new information to add.
     * @return the updated url.
     */
    @NotNull
    public String append(@NotNull final String url, @NotNull final String extraInfo) {
        String result;

        int questionPosition = url.indexOf("?");

        result = (questionPosition == -1) ? "?" : "&";

        questionPosition = extraInfo.indexOf("?");

        @NotNull
        final String params = (questionPosition == -1) ? extraInfo
                : (questionPosition == extraInfo.length() - 1) ? extraInfo.substring(0, questionPosition)
                        : extraInfo.substring(0, questionPosition) + "&"
                                + extraInfo.substring(questionPosition + 1);

        result = url + result + params;

        return result;
    }

    /**
     * Retrieves an integer parameter.
     * @param request the request.
     * @param paramName the parameter name
     * @param defaultValue the default value.
     * @return the int value.
     */
    public int getIntParam(@NotNull final ServletRequest request, @NotNull final String paramName,
            final int defaultValue) {
        int result = defaultValue;

        @Nullable
        final String value = request.getParameter(paramName);

        if (value != null) {
            result = getIntParam(paramName, value, defaultValue);
        }

        return result;
    }

    /**
     * Retrieves an integer parameter.
     * @param paramName the parameter name.
     * @param paramValue the parameter value.
     * @param defaultValue the default value.
     * @return the int value.
     */
    protected int getIntParam(@NotNull final String paramName, @NotNull final String paramValue,
            final int defaultValue) {
        int result = defaultValue;

        try {
            result = Integer.parseInt(paramValue);
        } catch (final NumberFormatException numberFormatException) {
            LogFactory.getLog(HttpServletUtils.class).debug("Cannot retrieve the " + paramName + " value");
        }

        return result;
    }

    /**
     * Retrieves the real context path (even if it's managed by Struts)
     * of the application.
     * @param request the request.
     * @return the real context path.
     */
    @NotNull
    public String getContextPath(@NotNull final HttpServletRequest request) {
        return getContextPath(request, removeServletInfo(request.getServletPath()));
    }

    /**
     * Retrieves the real context path (even if it's managed by Struts)
     * of the application.
     * @param request the request.
     * @param subContext the subcontext.
     * @return the real context path.
     */
    @NotNull
    protected String getContextPath(@NotNull final HttpServletRequest request, @NotNull final String subContext) {
        return request.getContextPath() + subContext;
    }

    /**
     * Retrieves the real context path (even if it's managed by Struts)
     * of the application.
     * @param request the request.
     * @return the real context path.
     */
    @NotNull
    public String getServletPath(@NotNull final HttpServletRequest request) {
        return removeServletInfo(request.getServletPath());
    }

    /**
     * Removes the trailing servlet info from given servlet path.
     * @param servletPath the servlet path.
     * @return the actual relative path of the servlet, without the
     * information about the servlet itself.
     */
    @NotNull
    protected String removeServletInfo(@NotNull final String servletPath) {
        @NotNull
        final StringBuilder result = new StringBuilder();

        @NotNull
        final StringTokenizer tokenizer = new StringTokenizer(servletPath, "/");

        final int totalTokens = tokenizer.countTokens();

        int tokenIndex = 1;

        while (tokenizer.hasMoreTokens()) {
            if (tokenIndex < totalTokens) {
                result.append("/");
                result.append(tokenizer.nextToken());
                tokenIndex++;
            } else {
                break;
            }
        }

        return result.toString();
    }

    /**
     * Retrieves an object from the repository.
     * @param key the key.
     * @param request the request.
     * @return the object if it's found.
     */
    @Nullable
    public Object retrieve(@NotNull final String key, @NotNull final HttpServletRequest request) {
        return retrieve(key, request, request.getSession(true), null);
    }

    /**
     * Retrieves an object from the repository.
     * @param key the key.
     * @param session the session.
     * @return the object if it's found.
     */
    @Nullable
    public Object retrieve(@NotNull final String key, @NotNull final HttpSession session) {
        return retrieve(key, null, session, null);
    }

    /**
     * Retrieves an object from the repository.
     * @param key the key.
     * @param request the request.
     * @param session the session.
     * @return the object if it's found.
     */
    @Nullable
    public Object retrieve(@NotNull final String key, @NotNull final ServletRequest request,
            @NotNull final HttpSession session) {
        return retrieve(key, request, session, null);
    }

    /**
     * Retrieves an object from the repository.
     * @param key the key.
     * @param request the request.
     * @param session the session.
     * @param context the context.
     * @return the object if it's found.
     */
    @Nullable
    public Object retrieve(@NotNull final String key, @Nullable final ServletRequest request,
            @Nullable final HttpSession session, @Nullable final ServletContext context) {
        @Nullable
        Object result = null;

        // Thanks Sun for had missed an interface for
        // all classes that export setAttribute().
        if (request != null) {
            result = request.getAttribute(key);
        }

        if ((result == null) && (session != null)) {
            result = session.getAttribute(key);
        }

        if ((result == null) && (context != null)) {
            result = context.getAttribute(key);
        }

        return result;
    }

    /**
     * Stores an object in the repository.
     * @param object the object to store.
     * @param key the key.
     * @param request the request.
     * @param session the session.
     * @return <code>true</code> if the object has been stored successfully.
     */
    public boolean store(@NotNull final Object object, @NotNull final String key,
            @Nullable final ServletRequest request, @Nullable final HttpSession session) {
        return store(object, key, request, session, null);
    }

    /**
     * Stores an object in the repository.
     * @param object the object to store.
     * @param key the key.
     * @param request the request.
     * @return <code>true</code> if the object has been stored successfully.
     */
    public boolean store(@NotNull final Object object, @NotNull final String key,
            @NotNull final ServletRequest request) {
        return store(object, key, request, null);
    }

    /**
     * Stores an object in the repository.
     * @param object the object to store.
     * @param key the key.
     * @param session the session.
     * @return <code>true</code> if the object has been stored successfully.
     */
    public boolean store(@NotNull final Object object, @NotNull final String key,
            @NotNull final HttpSession session) {
        return store(object, key, null, session);
    }

    /**
     * Stores an object in the repository.
     * @param object the object to store.
     * @param key the key.
     * @param request the request.
     * @param session the session.
     * @param servletContext the context.
     * @return <code>true</code> if the object has been stored successfully.
     */
    public boolean store(@NotNull final Object object, @NotNull final String key,
            @Nullable final ServletRequest request, @Nullable final HttpSession session,
            @Nullable final ServletContext servletContext) {
        boolean result = false;

        // Thanks Sun for had missed an interface for
        // all classes that export setAttribute().
        if (request != null) {
            request.setAttribute(key, object);
            result = true;
        }

        if (session != null) {
            session.setAttribute(key, object);
            result = true;
        }

        if (servletContext != null) {
            servletContext.setAttribute(key, object);
            result = true;
        }

        return result;
    }

    /**
     * Removes an object from the repository.
     * @param key the key.
     * @param session the session.
     * @return <code>true</code> if the object has been removed successfully.
     */
    public boolean remove(@NotNull final String key, @NotNull final HttpSession session) {
        return remove(key, null, session, null);
    }

    /**
     * Removes an object from the repository.
     * @param key the key.
     * @param request the request.
     * @param session the session.
     * @return <code>true</code> if the object has been removed successfully.
     */
    public boolean remove(@NotNull final String key, @Nullable final ServletRequest request,
            @Nullable final HttpSession session) {
        return remove(key, request, session, null);
    }

    /**
     * Removes an object from the repository.
     * @param key the key.
     * @param request the request.
     * @param session the session.
     * @param context the context.
     * @return <code>true</code> if the object has been removed successfully.
     */
    public boolean remove(@NotNull final String key, @Nullable final ServletRequest request,
            @Nullable final HttpSession session, @Nullable final ServletContext context) {
        boolean result = false;

        // Thanks Sun for had missed an interface for
        // all classes that export setAttribute().
        if (request != null) {
            request.removeAttribute(key);
            result = true;
        }

        if (session != null) {
            session.removeAttribute(key);
            result = true;
        }

        if (context != null) {
            context.removeAttribute(key);
            result = true;
        }

        return result;
    }

    /**
     * Creates the matcher.
     * @return the regexp matcher.
     * @throws RegexpEngineNotFoundException if a suitable instance
     * cannot be created.
     * @throws RegexpPluginMisconfiguredException if RegexpPlugin is
     * misconfigured.
     */
    @NotNull
    protected static synchronized Matcher createMatcher()
            throws RegexpEngineNotFoundException, RegexpPluginMisconfiguredException {
        return createMatcher(RegexpManager.getInstance());
    }

    /**
     * Creates the matcher.
     * @param regexpManager the RegexpManager instance.
     * @return the regexp matcher.
     * @throws RegexpEngineNotFoundException if a suitable instance
     * cannot be created.
     * @throws RegexpPluginMisconfiguredException if RegexpPlugin is
     * misconfigured.
     */
    @NotNull
    protected static synchronized Matcher createMatcher(@NotNull final RegexpManager regexpManager)
            throws RegexpEngineNotFoundException, RegexpPluginMisconfiguredException {
        return createMatcher(regexpManager.getEngine());
    }

    /**
     * Creates the matcher.
     * @param regexpEngine the RegexpEngine instance.
     * @return the regexp matcher.
     */
    @NotNull
    protected static synchronized Matcher createMatcher(@NotNull final RegexpEngine regexpEngine) {
        return regexpEngine.createMatcher();
    }

    /**
     * Parses a name=value text, splitting it in two strings.
     * @param unparsed the text to parse.
     * @return a two-element array, first for the left part, second for the
     * right.
     * @throws RegexpEngineNotFoundException if the system is not configured
     * properly in order to provide regexp services.
     */
    @NotNull
    public String[] parseNameValuePair(@NotNull final String unparsed) throws RegexpEngineNotFoundException {
        return parseNameValuePair(unparsed, createMatcher(RegexpManager.getInstance()));
    }

    /**
     * Parses a name=value text, splitting it in two strings.
     * @param unparsed the text to parse.
     * @param matcher the regexp matcher.
     * @return a two-element array, first for the left part, second for the
     * right.
     */
    @NotNull
    public String[] parseNameValuePair(@NotNull final String unparsed, @NotNull final Matcher matcher) {
        @Nullable
        Pattern t_Pattern = getNameValuePairRegexp();

        @NotNull
        final RegexpUtils regexpUtils = RegexpUtils.getInstance();

        if (t_Pattern == null) {
            t_Pattern = buildNameValuePairRegexp(regexpUtils);

            setNameValuePairRegexp(t_Pattern);
        }

        return parseNameValuePair(unparsed, t_Pattern, matcher);
    }

    /**
     * Builds the regexp for parsing name=value texts.
     * @param regexpUtils the RegexpUtils instance.
     * @return such compiled regexp.
     */
    protected Pattern buildNameValuePairRegexp(@NotNull final RegexpUtils regexpUtils) {
        return regexpUtils.buildPattern(NAME_VALUE_PAIR_REGEXP);
    }

    /**
     * Parses a name=value text, splitting it in two strings.
     * @param unparsed the text to parse.
     * @param pattern the regexp pattern.
     * @param matcher the regexp matcher.
     * @return a two-element array, first for the left part, second for the
     * right.
     */
    @NotNull
    protected String[] parseNameValuePair(@NotNull final String unparsed, @NotNull final Pattern pattern,
            @NotNull final Matcher matcher) {
        @NotNull
        final String[] result = new String[2];

        if (matcher.contains(unparsed, pattern)) {
            @Nullable
            final MatchResult t_MatchResult = matcher.getMatch();

            if ((t_MatchResult != null) && (t_MatchResult.groups() >= 2)) {
                result[0] = t_MatchResult.group(1);
                result[1] = t_MatchResult.group(2);
            }
        }

        return result;
    }
}