com.zz.globalsession.filter.AbstractGlobalSessionFilter.java Source code

Java tutorial

Introduction

Here is the source code for com.zz.globalsession.filter.AbstractGlobalSessionFilter.java

Source

/*
 * Copyright 2012 M3, Inc.
 *
 * Licensed 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.
 */
package com.zz.globalsession.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.zz.globalsession.GlobalHttpSession;
import com.zz.globalsession.GlobalSessionFilterSettings;
import com.zz.globalsession.GlobalSessionHttpRequest;
import com.zz.globalsession.store.SessionStore;
import com.zz.globalsession.util.CookieUtil;

public abstract class AbstractGlobalSessionFilter implements Filter {

    private static Log log = LogFactory.getLog(AbstractGlobalSessionFilter.class);

    private static final String GLOBAL_NAMESPACE = "GLOBAL";
    private static final String DEFAULT_SESSION_ID_NAME = "__gsid__";

    /*
     * private static class ConfigKey {
     * 
     * public static final String NAMESPACE = "namespace"; public static final
     * String SESSION_ID = "sessionId"; public static final String DOMAIN =
     * "domain"; public static final String PATH = "path"; public static final
     * String SECURE = "secure"; public static final String HTTP_ONLY =
     * "httpOnly"; public static final String SESSION_TIMEOUT =
     * "sessionTimeout"; public static final String EXCLUDE_REG_EXP =
     * "excludeRegExp"; }
     */

    private static class RequestAttributeKey {

        protected static final String SESSION_STATUS = "__sessionStatus__";
    }

    private static enum SessionStatus {
        unknown, fixed
    }

    protected SessionStore store;
    protected GlobalSessionFilterSettings settings;

    // private GlobalSessionFilterSettings
    // getGlobalSessionFilterSettings(FilterConfig config) {
    //
    // GlobalSessionFilterSettings settings = new GlobalSessionFilterSettings();
    //
    // settings.setNamespace(getConfigValue(config, ConfigKey.NAMESPACE));
    // if (settings.getNamespace() == null) {
    // settings.setNamespace(GLOBAL_NAMESPACE);
    // }
    //
    // settings.setExcludeRegExp(getConfigValue(config,
    // ConfigKey.EXCLUDE_REG_EXP));
    //
    // settings.setSessionIdKey(getConfigValue(config, ConfigKey.SESSION_ID));
    // if (settings.getSessionIdKey() == null) {
    // settings.setSessionIdKey(DEFAULT_SESSION_ID_NAME);
    // }
    //
    // settings.setDomain(getConfigValue(config, ConfigKey.DOMAIN));
    //
    // settings.setPath(getConfigValue(config, ConfigKey.PATH));
    // if (settings.getPath() == null) {
    // settings.setPath("/");
    // }
    //
    // settings.setSecure(getConfigValue(config, ConfigKey.SECURE) != null
    // && getConfigValue(config, ConfigKey.SECURE).equals("true"));
    //
    // settings.setHttpOnly(getConfigValue(config, ConfigKey.HTTP_ONLY) != null
    // && getConfigValue(config, ConfigKey.HTTP_ONLY).equals("true"));
    //
    // String sessionTimeout = getConfigValue(config,
    // ConfigKey.SESSION_TIMEOUT);
    // if (sessionTimeout == null) {
    // settings.setSessionTimeoutMinutes(10);
    // } else {
    // settings.setSessionTimeoutMinutes(Integer.valueOf(sessionTimeout));
    // }
    //
    // return settings;
    // }

    private Cookie getCurrentValidSessionIdCookie(HttpServletRequest req) {
        if (req.getCookies() != null) {
            for (Cookie cookie : req.getCookies()) {
                if (cookie.getName().equals(settings.getSessionIdKey()) && cookie.getValue() != null
                        && cookie.getValue().trim().length() > 0) {
                    if (isValidSession(createGlobalSessionRequest(req, cookie.getValue()))) {
                        if (log.isDebugEnabled()) {
                            log.debug("SessionId cookie is found. (" + settings.getSessionIdKey() + " -> "
                                    + cookie.getValue() + ")");
                        }
                        return cookie;
                    } else {
                        if (log.isDebugEnabled()) {
                            log.debug("SessionId cookie is found but it's invalid. (" + settings.getSessionIdKey()
                                    + " -> " + cookie.getValue() + ")");
                        }
                        continue;
                    }
                }
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("SessionId cookie is not found.");
        }
        return null;
    }

    private Cookie generateSessionIdCookie(String sessionIdValue) {

        Cookie sessionIdCookie = new Cookie(settings.getSessionIdKey(), sessionIdValue);
        if (settings.getDomain() != null) {
            sessionIdCookie.setDomain(settings.getDomain());
        }
        if (settings.getPath() != null) {
            sessionIdCookie.setPath(settings.getPath());
        } else {
            sessionIdCookie.setPath("/");
        }
        if (settings.isSecure())
            sessionIdCookie.setSecure(settings.isSecure());
        // [Note] httpOnly is not supported by Servlet API 2.x, so add it
        // manually later.
        return sessionIdCookie;
    }

    private GlobalSessionHttpRequest createGlobalSessionRequest(HttpServletRequest req, String sessionIdValue) {
        return new GlobalSessionHttpRequest(req, sessionIdValue, settings.getNamespace(),
                settings.getSessionTimeoutMinutes(), store);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {

    }

    public void initSettings() {
        if (settings == null) {
            settings = new GlobalSessionFilterSettings();
        }
        // DelegatingFilterProxy ?filter
        // private String
        // namespace,sessionId,domain,path,secure,httpOnly,sessiontTimeout,excludeRegExp;
        if (namespace != null) {
            settings.setNamespace(namespace);
        } else {
            settings.setNamespace(GLOBAL_NAMESPACE);
        }
        if (sessionId != null) {
            settings.setSessionIdKey(sessionId);
        } else {
            settings.setSessionIdKey(DEFAULT_SESSION_ID_NAME);
        }
        if (domain != null) {
            settings.setDomain(domain);
        }
        if (path != null) {
            settings.setPath(path);
        }
        if (excludeRegExp != null) {
            settings.setExcludeRegExp(excludeRegExp);
        }
        if (sessiontTimeout > 0) {
            settings.setSessionTimeoutMinutes(sessiontTimeout);
        }
        if (httpOnly) {
            settings.setHttpOnly(httpOnly);
        }
        if (secure) {
            settings.setSecure(secure);
        }
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest _req = (HttpServletRequest) req;
        HttpServletResponse _res = (HttpServletResponse) res;

        if (isGlobalSessionHttpRequest(_req)) {

            if (log.isDebugEnabled()) {
                log.debug("GlobalSessionHttpRequest is already applied.");
            }
            chain.doFilter(_req, _res);

        } else if (settings.getExcludeRegExp() != null
                && _req.getRequestURI().matches(settings.getExcludeRegExp())) {

            if (log.isDebugEnabled()) {
                log.debug("This URI is excluded. (URI: " + _req.getRequestURI() + ")");
            }
            chain.doFilter(_req, _res);

        } else {

            Cookie currentValidSessionIdCookie = getCurrentValidSessionIdCookie(_req);

            String sessionIdValue = null;
            if (currentValidSessionIdCookie == null) {
                // copy JSESSIONID value to original session
                sessionIdValue = _req.getSession().getId();
            } else {
                // current original session is valid
                sessionIdValue = currentValidSessionIdCookie.getValue();
            }

            if (currentValidSessionIdCookie == null) {
                Cookie newSessionIdCookie = generateSessionIdCookie(sessionIdValue);
                // [Note] httpOnly is not supported by Servlet API 2.x, so need
                // to call #addHeader instead of #addCookie
                /*  */
                String setCookie = CookieUtil.createSetCookieHeaderValue(newSessionIdCookie, settings.isHttpOnly());
                _res.addHeader("Set-Cookie", setCookie);

                // _res.addCookie(newSessionIdCookie);
                setSessionStatus(_req, SessionStatus.fixed);

                if (log.isDebugEnabled()) {
                    log.debug("SessionId cookie is updated. (" + sessionIdValue + ")");
                }
            }

            // doFilter with the request wrapper
            GlobalSessionHttpRequest _wrappedReq = createGlobalSessionRequest(_req, sessionIdValue);
            chain.doFilter(_wrappedReq, _res);

            // update attributes, expiration
            GlobalHttpSession session = _wrappedReq.getSession();
            session.reloadAttributes(); // need reloading from the store to work
                                        // with GlassFish
            session.save();
        }
    }

    @Override
    public void destroy() {
    }

    protected static String getConfigValue(FilterConfig config, String keyName) {
        String fromInitParam = config.getInitParameter(keyName);
        if (fromInitParam != null) {
            return fromInitParam;
        }
        return System.getProperty(keyName);
    }

    private void setSessionStatus(HttpServletRequest req, SessionStatus status) {
        req.setAttribute(RequestAttributeKey.SESSION_STATUS, status);
    }

    private SessionStatus getSessionStatus(HttpServletRequest req) {
        Object status = req.getAttribute(RequestAttributeKey.SESSION_STATUS);
        if (status == null) {
            return SessionStatus.unknown;
        } else {
            return (SessionStatus) status;
        }
    }

    private boolean isValidSession(GlobalSessionHttpRequest req) {
        if (getSessionStatus(req) == SessionStatus.fixed) {
            return true;
        }
        return req.getSession().isValid();
    }

    private boolean isGlobalSessionHttpRequest(HttpServletRequest req) {
        return req.getSession() instanceof GlobalHttpSession;
    }

    // 
    private String namespace, sessionId, domain, path;
    private boolean httpOnly, secure;
    private int sessiontTimeout;
    private String excludeRegExp;

    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    // cookie name
    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public void setHttpOnly(boolean httpOnly) {
        this.httpOnly = httpOnly;
    }

    public void setSecure(boolean secure) {
        this.secure = secure;
    }

    public void setSessiontTimeout(int sessiontTimeout) {
        this.sessiontTimeout = sessiontTimeout;
    }

    public void setExcludeRegExp(String excludeRegExp) {
        this.excludeRegExp = excludeRegExp;
    }

}