/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 flex.messaging;

import java.util.concurrent.CopyOnWriteArrayList;

/**
 *
 * Abstract base class for <tt>ConnectionAwareSession</tt> implementations.
 * Provides support for registering <tt>FlexSessionConnectivityListener</tt>s
 * along with protected methods to notify registered listeners of <tt>FlexSessionConnectivityEvent</tt>s.
 */
public abstract class AbstractConnectionAwareSession extends FlexSession implements ConnectionAwareSession
{
    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------

    /**
     *
     * Constructs a new instance.
     *
     * @param sessionProvider The provider that instantiated this instance.
     */
    public AbstractConnectionAwareSession(AbstractFlexSessionProvider sessionProvider)
    {
        super(sessionProvider);
    }
    
    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  connected
    //----------------------------------
    
    /**
     * Connected flag for the session.
     */
    private boolean connected;

    /**
     * Returns whether the session is connected.
     * 
     * @return true if the session is connected; otherwise false.
     */
    public boolean isConnected()
    {
        synchronized (lock)
        {
            return connected;
        }
    }
    
    /**
     * Sets the connected state for the session.
     * 
     * @param value true for a connected session; false for a disconnected session.
     */
    public void setConnected(boolean value)
    {
        boolean notify = false;
        synchronized (lock)
        {
            if (connected != value)
            {
                connected = value;
                notify = true;
            }
        }
        if (notify)
        {
            if (!value)
                notifySessionDisconnected();
            else
                notifySessionConnected();
        }
    }
    
    //----------------------------------
    //  connectivityListeners
    //----------------------------------
    
    /**
     * The list of connectivity listeners for the session.
     */
    private volatile CopyOnWriteArrayList<FlexSessionConnectivityListener> connectivityListeners;
    
    /**
     * (non-JavaDoc)
     * @see flex.messaging.ConnectionAwareSession#addConnectivityListener(FlexSessionConnectivityListener)
     */
    public void addConnectivityListener(FlexSessionConnectivityListener listener)
    {
        if (connectivityListeners == null)
        {
            synchronized (lock)
            {
                if (connectivityListeners == null)
                    connectivityListeners = new CopyOnWriteArrayList<FlexSessionConnectivityListener>(); 
            }
        }
        if (connectivityListeners.addIfAbsent(listener) && isConnected())
        {
            // If the listener is added when the session has already connected, notify it at add time.
            FlexSessionConnectivityEvent event = new FlexSessionConnectivityEvent(this);
            listener.sessionConnected(event);
        }
    }

    /**
     * (non-JavaDoc)
     * @see flex.messaging.ConnectionAwareSession#removeConnectivityListener(FlexSessionConnectivityListener)
     */
    public void removeConnectivityListener(FlexSessionConnectivityListener listener)
    {
        if (connectivityListeners == null) return;
        connectivityListeners.remove(listener);
    }
    
    //--------------------------------------------------------------------------
    //
    // Protected Methods
    //
    //--------------------------------------------------------------------------    
    
    /**
     * Notifies registered <tt>FlexSessionConnectivityListener</tt>s that the session has connected.
     */
    protected void notifySessionConnected()
    {
        if (connectivityListeners != null)
        {
            FlexSessionConnectivityEvent event = new FlexSessionConnectivityEvent(this);
            for (FlexSessionConnectivityListener listener : connectivityListeners)
                listener.sessionDisconnected(event);
        }
    }
    
    /**
     * Notifies registered <tt>FlexSessionConnectivityListener</tt>s that the session has disconnected.
     */
    protected void notifySessionDisconnected()
    {
        if (connectivityListeners != null)
        {
            FlexSessionConnectivityEvent event = new FlexSessionConnectivityEvent(this);
            for (FlexSessionConnectivityListener listener : connectivityListeners)
                listener.sessionDisconnected(event);            
        }
    }    
}