alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Jetty example source code file (AbstractReplicatedStore.java)

This example Jetty source code file (AbstractReplicatedStore.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Jetty tags/keywords

abstractreplicatedstore, class, class, create_session, exception, integer, integer, localstate, method, method, object, object, reflection, state, string, util

The Jetty AbstractReplicatedStore.java source code

// ========================================================================
// $Id: AbstractReplicatedStore.java,v 1.5 2004/06/22 16:23:44 jules_gosnell Exp $
// Copyright 2002-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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 org.mortbay.j2ee.session;

//----------------------------------------

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.jboss.logging.Logger;

//----------------------------------------

// implement scavenging
// implement setMaxInactiveInterval
// look for NYI/TODO

// this infrastructure could probably be used across JMS aswell -
// think about it...

/**
 * Maintain synchronisation with other States representing the same session by
 * publishing changes made to ourself and updating ourself according to
 * notifications published by the other State objects.
 * 
 * @author <a href="mailto:jules@mortbay.com">Jules Gosnell
 * @version 1.0
 */

abstract public class AbstractReplicatedStore extends AbstractStore
{
    protected final static Logger _log = Logger
            .getLogger(AbstractReplicatedStore.class);

    protected ClassLoader _loader;

    public AbstractReplicatedStore()
    {
        super();
        _loader = Thread.currentThread().getContextClassLoader();
    }

    public ClassLoader getLoader()
    {
        return _loader;
    }

    public void setLoader(ClassLoader loader)
    {
        _loader = loader;
    }

    // ----------------------------------------
    // tmp hack to prevent infinite loop
    private final static ThreadLocal _replicating = new ThreadLocal();

    public static boolean getReplicating()
    {
        return _replicating.get() == Boolean.TRUE;
    }

    public static void setReplicating(boolean replicating)
    {
        _replicating.set(replicating ? Boolean.TRUE : Boolean.FALSE);
    }

    // ----------------------------------------

    public Object clone()
    {
        AbstractReplicatedStore ars = (AbstractReplicatedStore) super.clone();
        ars.setLoader(getLoader());
        return ars;
    }

    protected Map _sessions = new HashMap();

    public int getSessions()
    {
        return _sessions.size();
    }

    // ----------------------------------------
    // Store API - Store LifeCycle

    public void destroy() // corresponds to ctor
    {
        _log.trace("destroying...");
        _sessions.clear();
        _sessions = null;
        setManager(null);
        super.destroy();
        _log.trace("...destroyed");
    }

    // ----------------------------------------
    // Store API - State LifeCycle

    public State newState(String id, int maxInactiveInterval) throws Exception
    {
        long creationTime = System.currentTimeMillis();

        if (!AbstractReplicatedStore.getReplicating())
        {
            Object[] argInstances = { id, new Long(creationTime),
                    new Integer(maxInactiveInterval),
                    new Integer(_actualMaxInactiveInterval) };
            publish(null, CREATE_SESSION, argInstances);
        }

        createSession(id, creationTime, maxInactiveInterval,
                _actualMaxInactiveInterval);

        // if we get one - all we have to do is loadState - because we
        // will have just created it...
        return loadState(id);
    }

    public State loadState(String id)
    {
        // pull it out of our cache - if it is not there, it doesn't
        // exist/hasn't been distributed...

        Object tmp;
        synchronized (_sessions)
        {
            tmp = _sessions.get(id);
        }
        return (State) tmp;
    }

    public void storeState(State state)
    {
        try
        {
            String id = state.getId();
            synchronized (_sessions)
            {
                _sessions.put(id, state);
            }
        }
        catch (Exception e)
        {
            _log.error("error storing session", e);
        }
    }

    public void removeState(State state) throws Exception
    {
        String id = state.getId();

        if (!AbstractReplicatedStore.getReplicating())
        {
            Object[] argInstances = { id };
            publish(null, DESTROY_SESSION, argInstances);
        }

        destroySession(id);
    }

    // ----------------------------------------
    // Store API - garbage collection

    public void scavenge() throws Exception
    {
        _log.trace("starting distributed scavenging...");
        Collection copy;
        synchronized (_sessions)
        {
            copy = new ArrayList(_sessions.values());
        }
        if (_log.isTraceEnabled())
        {
            int n;
            synchronized (_subscribers)
            {
                n = _subscribers.size();
            }
            _log.trace(copy.size() + " distributed sessions, " + n
                    + " subscribers");
        }
        int n = 0;
        for (Iterator i = copy.iterator(); i.hasNext();)
        {
            LocalState state = (LocalState) i.next();
            if (!state.isValid(_scavengerExtraTime))
            {
                String id = state.getId();
                if (_log.isDebugEnabled())
                    _log.debug("scavenging distributed session " + id);
                destroySession(id);
                i.remove();
                ++n;
            }
        }
        if (_log.isTraceEnabled())
            _log.trace("scavenged " + n + " distributed sessions");
        _log.trace("...finished distributed scavenging");
    }

    // ----------------------------------------
    // Store API - hacks... - NYI/TODO

    public void passivateSession(StateAdaptor sa)
    {
    }

    public boolean isDistributed()
    {
        return true;
    }

    // ----------------------------------------
    // utils

    public String getContextPath()
    {
        return getManager().getContextPath();
    }

    // ----------------------------------------
    // change notification API

    protected static Map _methodToInteger = new HashMap();

    protected static Method[] _integerToMethod = new Method[8];

    protected static Method CREATE_SESSION;

    protected static Method DESTROY_SESSION;

    protected static Method TOUCH_SESSIONS;

    protected static Method SET_LAST_ACCESSED_TIME;

    static
    {
        // this is absolutely horrible and will break if anyone changes
        // the shape of the interface - but it is a quick, easy and
        // efficient hack - so I am using it while I think of a better
        // way...
        try
        {
            int index = 0;
            Method m = null;

            // class methods...
            m = CREATE_SESSION = AbstractReplicatedStore.class.getMethod(
                    "createSession", new Class[] { String.class, Long.TYPE,
                            Integer.TYPE, Integer.TYPE });
            _integerToMethod[index] = m;
            _methodToInteger.put(m.getName(), new Integer(index));
            index++;

            m = DESTROY_SESSION = AbstractReplicatedStore.class.getMethod(
                    "destroySession", new Class[] { String.class });
            _integerToMethod[index] = m;
            _methodToInteger.put(m.getName(), new Integer(index));
            index++;

            m = TOUCH_SESSIONS = AbstractReplicatedStore.class.getMethod(
                    "touchSessions", new Class[] { String[].class, Long.TYPE });
            _integerToMethod[index] = m;
            _methodToInteger.put(m.getName(), new Integer(index));
            index++;

            // instance methods...
            m = SET_LAST_ACCESSED_TIME = State.class.getMethod(
                    "setLastAccessedTime", new Class[] { Long.TYPE });
            _integerToMethod[index] = m;
            _methodToInteger.put(m.getName(), new Integer(index));
            index++;

            m = State.class.getMethod("setMaxInactiveInterval",
                    new Class[] { Integer.TYPE });
            _integerToMethod[index] = m;
            _methodToInteger.put(m.getName(), new Integer(index));
            index++;

            m = State.class.getMethod("setAttribute", new Class[] {
                    String.class, Object.class, Boolean.TYPE });
            _integerToMethod[index] = m;
            _methodToInteger.put(m.getName(), new Integer(index));
            index++;

            m = State.class.getMethod("setAttributes",
                    new Class[] { Map.class });
            _integerToMethod[index] = m;
            _methodToInteger.put(m.getName(), new Integer(index));
            index++;

            m = State.class.getMethod("removeAttribute", new Class[] {
                    String.class, Boolean.TYPE });
            _integerToMethod[index] = m;
            _methodToInteger.put(m.getName(), new Integer(index));
            index++;
        }
        catch (Exception e)
        {
            System.err
                    .println("AbstractReplicatedStore: something went wrong building dispatch tables");
            e.printStackTrace(System.err);
        }
    }

    abstract protected void publish(String id, Method method,
            Object[] argInstances);

    protected void dispatch(String id, Integer methodId, Object[] argInstances)
    {
        try
        {
            AbstractReplicatedStore.setReplicating(true);

            Object target = null;
            if (id == null)
            {
                // either this is a class method
                target = this;
            }
            else
            {
                // or an instance method..
                synchronized (_subscribers)
                {
                    target = _subscribers.get(id);
                }
            }

            try
            {
                Method method = _integerToMethod[methodId.intValue()];
                if (target == null)
                    _log.warn("null target for " + method);
                else
                    method.invoke(target, argInstances);
            }
            catch (Exception e)
            {
                _log
                        .error(
                                "this should never happen - code version mismatch ?",
                                e);
            }
        }
        finally
        {
            AbstractReplicatedStore.setReplicating(false);
        }
    }

    public void createSession(String id, long creationTime,
            int maxInactiveInterval, int actualMaxInactiveInterval)
    {
        if (_log.isTraceEnabled())
            _log.trace("creating replicated session: " + id);
        State state = new LocalState(id, creationTime, maxInactiveInterval,
                actualMaxInactiveInterval);
        synchronized (_sessions)
        {
            _sessions.put(id, state);
        }

        if (AbstractReplicatedStore.getReplicating())
        {
            //	_log.info("trying to promote replicated session");
            getManager().getHttpSession(id); // should cause creation of corresponding InterceptorStack
        }
    }

    public void destroySession(String id)
    {
        if (_log.isTraceEnabled())
            _log.trace("destroying replicated session: " + id);
        if (getManager().sessionExists(id))
            getManager().destroySession(getManager().getHttpSession(id));
        synchronized (_sessions)
        {
            _sessions.remove(id);
        }
    }

    public void touchSessions(String[] ids, long time)
    {
        //      _log.info("touching sessions...: "+ids);
        for (int i = 0; i < ids.length; i++)
        {
            String id = ids[i];
            Object target;
            // I could synch the whole block. This is slower, but will not
            // hold up everything else...
            synchronized (_subscribers)
            {
                target = _subscribers.get(id);
            }
            try
            {
                ((StateInterceptor) target).setLastAccessedTime(time);
            }
            catch (Exception e)
            {
                _log.warn("unable to touch session: " + id
                        + " probably already removed");
            }
        }
    }

    //----------------------------------------
    // subscription - Listener management...

    protected Map _subscribers = new HashMap();

    public void subscribe(String id, Object o)
    {
        _log.trace("subscribing: " + id);
        synchronized (_subscribers)
        {
            _subscribers.put(id, o);
        }
    }

    public void unsubscribe(String id)
    {
        _log.trace("unsubscribing: " + id);
        synchronized (_subscribers)
        {
            _subscribers.remove(id);
        }
    }
}

Other Jetty examples (source code examples)

Here is a short list of links related to this Jetty AbstractReplicatedStore.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.