All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cometd.common.AbstractClientSession Maven / Gradle / Ivy

package org.cometd.common;

import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import org.cometd.bayeux.Channel;
import org.cometd.bayeux.Message;
import org.cometd.bayeux.Message.Mutable;
import org.cometd.bayeux.client.ClientSession;
import org.cometd.bayeux.client.SessionChannel;
import org.cometd.bayeux.client.SessionChannel.SubscriberListener;
import org.eclipse.jetty.util.AttributesMap;
import org.eclipse.jetty.util.log.Log;


/* ------------------------------------------------------------ */
public abstract class AbstractClientSession implements ClientSession
{
    protected final List _extensions = new CopyOnWriteArrayList();
    protected final AttributesMap _attributes = new AttributesMap();
    protected final ConcurrentMap _channels = new ConcurrentHashMap();
    protected final AtomicInteger _batch = new AtomicInteger();
    protected final List _wild = new CopyOnWriteArrayList();
    protected final AtomicInteger _idGen = new AtomicInteger(0);
    

    /* ------------------------------------------------------------ */
    protected AbstractClientSession()
    {
    }

    /* ------------------------------------------------------------ */
    public void addExtension(Extension extension)
    {
        _extensions.add(extension);
    }

    /* ------------------------------------------------------------ */
    protected abstract ChannelId newChannelId(String channelId);

    /* ------------------------------------------------------------ */
    protected abstract AbstractSessionChannel newChannel(ChannelId channelId);
    
    /* ------------------------------------------------------------ */
    public SessionChannel getChannel(String channelId)
    {
        AbstractSessionChannel channel = _channels.get(channelId);
        if (channel==null)
        {
            ChannelId id = newChannelId(channelId);
            AbstractSessionChannel new_channel=newChannel(id);
            channel=_channels.putIfAbsent(channelId,new_channel);
            if (channel==null)
                channel=new_channel;
        }
        if (channel.isWild())
            _wild.add(channel);
        return channel;
    }

    /* ------------------------------------------------------------ */
    public void startBatch()
    {
        _batch.incrementAndGet();
    }

    /* ------------------------------------------------------------ */
    protected abstract void sendBatch();
    
    /* ------------------------------------------------------------ */
    public void endBatch()
    {  
        if (_batch.decrementAndGet()==0)
        {
            sendBatch();
        }
    }

    /* ------------------------------------------------------------ */
    public void batch(Runnable batch)
    {
        startBatch();
        try
        {
            batch.run();
        }
        finally
        {
            endBatch();
        }
    }

    /* ------------------------------------------------------------ */
    public Object getAttribute(String name)
    {
        return _attributes.getAttribute(name);
    }

    /* ------------------------------------------------------------ */
    public Set getAttributeNames()
    {
        return _attributes.getAttributeNameSet();
    }

    /* ------------------------------------------------------------ */
    public Object removeAttribute(String name)
    {
        Object old = _attributes.getAttribute(name);
        _attributes.removeAttribute(name);
        return old;
    }

    /* ------------------------------------------------------------ */
    public void setAttribute(String name, Object value)
    {
        _attributes.setAttribute(name,value);
    }

    /* ------------------------------------------------------------ */
    /** Receive a message (from the server)
     * 

* This method calls the receive extensions, the ClientSessionListeners and then * the subscribed MessageListeners. * @param message the message to receive. */ public void receive(final Message message, final Message.Mutable mutable) { final String id=message.getChannel(); final AbstractSessionChannel channel=id==null?null:(AbstractSessionChannel)getChannel(id); final ChannelId channelId=channel==null?null:channel.getChannelId(); if (channel!=null && channel._handler!=null) channel._handler.handle(this,mutable); if (message.isMeta()) { for (Extension extension : _extensions) if (!extension.rcvMeta(this,mutable)) return; String error = (String)message.get(Message.ERROR_FIELD); boolean successful = message.isSuccessful(); if (channelId!=null) { for (AbstractSessionChannel wild : _wild) { if (wild._id.matches(channelId)) { for (SessionChannel.SessionChannelListener listener : wild._listeners) { try { if (listener instanceof SessionChannel.MetaChannelListener) ((SessionChannel.MetaChannelListener)listener).onMetaMessage(channel,message,successful,error); if (listener instanceof SessionChannel.MessageListener) ((SessionChannel.MessageListener)listener).onMessage(this,message); } catch(Exception e) { Log.warn(e); } } } } for (SessionChannel.SessionChannelListener listener : channel._listeners) { try { if (listener instanceof SessionChannel.MetaChannelListener) ((SessionChannel.MetaChannelListener)listener).onMetaMessage(channel,message,message.isSuccessful(),error); } catch(Exception e) { Log.warn(e); } } } } else { for (Extension extension : _extensions) if (!extension.rcv(AbstractClientSession.this,mutable)) return; if (channelId!=null) { for (AbstractSessionChannel wild : _wild) { try { if (wild._id.matches(channel._id)) { for (SessionChannel.SessionChannelListener listener : wild._listeners) { if (listener instanceof SessionChannel.MessageListener) ((SessionChannel.MessageListener)listener).onMessage(this,message); } } } catch(Exception e) { Log.warn(e); } } } } if (channel!=null && (channel.isMeta() || message.getData()!=null)) { for (SubscriberListener listener : channel._subscriptions) { try { listener.onMessage(channel,message); } catch(Exception e) { Log.warn(e); } } } if (Channel.META_DISCONNECT.equals(id) && message.isSuccessful()) doDisconnected(); } /* ------------------------------------------------------------ */ protected abstract void doDisconnected(); /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ protected interface Handler { void handle(AbstractClientSession session, Message.Mutable mutable); } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /** A SessionChannel scoped to this LocalChannel */ protected abstract static class AbstractSessionChannel implements SessionChannel { protected final ChannelId _id; protected CopyOnWriteArrayList _subscriptions = new CopyOnWriteArrayList(); protected CopyOnWriteArrayList _listeners = new CopyOnWriteArrayList(); protected Handler _handler; /* ------------------------------------------------------------ */ protected AbstractSessionChannel(ChannelId id) { _id=id; } /* ------------------------------------------------------------ */ public ChannelId getChannelId() { return _id; } /* ------------------------------------------------------------ */ public void addListener(SessionChannelListener listener) { _listeners.add(listener); } /* ------------------------------------------------------------ */ public void removeListener(SessionChannelListener listener) { _listeners.remove(listener); } /* ------------------------------------------------------------ */ protected abstract void sendSubscribe(); /* ------------------------------------------------------------ */ protected abstract void sendUnSubscribe(); /* ------------------------------------------------------------ */ public void subscribe(SubscriberListener listener) { _subscriptions.add(listener); if (_subscriptions.size()==1) sendSubscribe(); } /* ------------------------------------------------------------ */ public void unsubscribe(SubscriberListener listener) { if (_subscriptions.remove(listener) && _subscriptions.size()==0) { sendUnSubscribe(); } } /* ------------------------------------------------------------ */ public void unsubscribe() { for (SubscriberListener listener : _subscriptions) unsubscribe(listener); } /* ------------------------------------------------------------ */ public String getId() { return _id.toString(); } /* ------------------------------------------------------------ */ public boolean isDeepWild() { return _id.isDeepWild(); } /* ------------------------------------------------------------ */ public boolean isMeta() { return _id.isMeta(); } /* ------------------------------------------------------------ */ public boolean isService() { return _id.isService(); } /* ------------------------------------------------------------ */ public boolean isWild() { return _id.isWild(); } /* ------------------------------------------------------------ */ public void setHandler(Handler handler) { _handler=handler; } /* ------------------------------------------------------------ */ @Override public String toString() { return _id.toString(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy