Package flex.messaging.client

Source Code of flex.messaging.client.FlexClientManager

/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
*  [2002] - [2007] Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any.  The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated
* and its suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*/
package flex.messaging.client;

import java.util.ArrayList;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;

import flex.management.ManageableComponent;
import flex.management.runtime.messaging.client.FlexClientManagerControl;
import flex.messaging.MessageBroker;
import flex.messaging.config.FlexClientSettings;
import flex.messaging.endpoints.AbstractEndpoint;
import flex.messaging.endpoints.Endpoint;
import flex.messaging.log.Log;
import flex.messaging.log.LogCategories;
import flex.messaging.util.ClassUtil;
import flex.messaging.util.TimeoutAbstractObject;
import flex.messaging.util.TimeoutManager;

/**
* @exclude
* Manages FlexClient instances for a MessageBroker.
*/
public class FlexClientManager extends ManageableComponent
{
    public static final String TYPE = "FlexClientManager";
   
    //--------------------------------------------------------------------------
    //
    // Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * @exclude
     */
    public FlexClientManager()
    {
        this(MessageBroker.getMessageBroker(null));
    }
    /**
     * Constructs a FlexClientManager for the passed MessageBroker.
     */
    public FlexClientManager(MessageBroker broker)
    {
        this(false, broker);
    }
   
    /**
     * @exclude
     */
    public FlexClientManager(boolean enableManagement, MessageBroker mbroker)
    {
        super(enableManagement);
       
        super.setId(TYPE);
       
        // Ensure that we have a message broker:
        broker = (mbroker != null) ? mbroker : MessageBroker.getMessageBroker(null);
       
        FlexClientSettings flexClientSettings = broker.getFlexClientSettings();
        if (flexClientSettings != null)
        {
            // Convert from minutes to millis.
            setFlexClientTimeoutMillis(flexClientSettings.getTimeoutMinutes()*60*1000);
        }
       
        this.setParent(broker);
    }

    //--------------------------------------------------------------------------
    //
    // Variables
    //
    //--------------------------------------------------------------------------

    /**
     * The MessageBroker that owns this manager.
     */
    private final MessageBroker broker;
   
    /**
     * The Mbean controller for this manager.
     */
    private FlexClientManagerControl controller;
   
    /**
     * Table to store FlexClients by id.
     */
    private final Map flexClients = new ConcurrentHashMap();
   
    /**
     * A Timer to use to schedule delayed flushes of outbound messages for FlexClients.
     */
    private Timer flushScheduler;
    private final Object flushInitLock = new Object();
   
    /**
     * Manages time outs for FlexClients.
     * This currently includes timeout of FlexClient instances as well as timeouts for async
     * long-poll handling.
     */
    private volatile TimeoutManager flexClientTimeoutManager;   

    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------
       
    //----------------------------------
    //  clientIds
    //----------------------------------   
   
    /**
     * A string array of the client IDs
     */
    public String[] getClientIds()
    {
        String[] ids = new String[flexClients.size()];
        ArrayList idList = new ArrayList(flexClients.keySet());
       
        for (int i = 0; i < flexClients.size(); i++)
        {
            ids[i] = (String)(idList).get(i);
        }
       
        return ids;
    }
   
    //----------------------------------
    //  flexClientCount
    //----------------------------------   
   
    /**
     * The number of FlexClients in use.
     */
    public int getFlexClientCount()
    {
        return flexClients.size();
    }   
   
    //----------------------------------
    //  flexClientTimeoutMillis
    //----------------------------------   
   
    private volatile long flexClientTimeoutMillis;
   
    /**
     * The idle timeout in milliseconds to apply to new FlexClient instances.
     */
    public long getFlexClientTimeoutMillis()
    {
        return flexClientTimeoutMillis;
    }   
   
    /**
     * Sets the idle timeout in milliseconds to apply to new FlexClient instances.
     *
     * @param value The idle timeout in milliseconds to apply to new FlexClient instances.
     */
    public void setFlexClientTimeoutMillis(long value)
    {
        if (value < 1)
            value = 0;
       
        synchronized (this)
        {
            flexClientTimeoutMillis = value;
        }
    }

    //----------------------------------
    //  messageBroker
    //----------------------------------   

    /**
     * Returns the MessageBroker instance that owns this FlexClientManager.
     *
     * @return The parent MessageBroker instance.
     */
    public MessageBroker getMessageBroker()
    {
        return broker;
    }   
   
    //--------------------------------------------------------------------------
    //
    // Public Methods
    //
    //--------------------------------------------------------------------------
   
    /**
     * Factory method to create new FlexClients with the specified id.
     */
    public FlexClient getFlexClient(String id)
    {   
        FlexClient flexClient = null;
        // Try to lookup an existing instance if we receive an id.
        if (id != null)
        {
            flexClient = (FlexClient)flexClients.get(id);
            if (flexClient != null)
            {
                if (flexClient.isValid() && !flexClient.invalidating)
                {
                    flexClient.updateLastUse();
                    return flexClient;
                }
                else // Invalid, remove it - it will be replaced below.
                {
                    flexClients.remove(id);
                }
            }
        }
        // Use a manager-level lock (this) when creating/recreating a new FlexClient.
        synchronized (this)
        {          
            if (id != null)
            {
                flexClient = (FlexClient)flexClients.get(id);
                if (flexClient != null)
                {
                    flexClient.updateLastUse();
                    return flexClient;
                }
                else
                {
                    flexClient = new FlexClient(this, id);
                }
            }
            else
            {
                flexClient = new FlexClient(this);
            }
            flexClients.put(flexClient.getId(), flexClient);
            if (flexClientTimeoutMillis > 0)
                flexClientTimeoutManager.scheduleTimeout(flexClient);
            flexClient.notifyCreated();           
            return flexClient;
        }
    }
   
    /**
     * Creates a FlexClientOutboundQueueProcessor instance and hooks it up to the passed
     * FlexClient.
     *
     * @param client The FlexClient to equip with a queue processor.
     * @param endpointId The Id of the endpoint the queue processor is used for.
     * @return The FlexClient with a configured queue processor.
     */
    public FlexClientOutboundQueueProcessor createOutboundQueueProcessor(FlexClient flexClient, String endpointId)
    {
        FlexClientOutboundQueueProcessor processor = null;
       
        try
        {
            Endpoint endpoint = broker.getEndpoint(endpointId);
            if (endpoint instanceof AbstractEndpoint)
            {
                Class processorClass = ((AbstractEndpoint)endpoint).getFlexClientOutboundQueueProcessorClass();
                if (processorClass != null)
                {
                    Object instance = ClassUtil.createDefaultInstance(processorClass, null);
                    if (instance instanceof FlexClientOutboundQueueProcessor)
                    {
                        processor = (FlexClientOutboundQueueProcessor)instance;
                        processor.setFlexClient(flexClient);
                        processor.setEndpointId(endpointId);
                        processor.initialize(((AbstractEndpoint)endpoint).getFlexClientOutboundQueueProcessorConfig());
                    }
                }
            }
        }
        catch (Throwable t)
        {
            if (Log.isWarn())
                Log.getLogger(FlexClient.FLEX_CLIENT_LOG_CATEGORY).warn("Failed to create custom outbound queue processor for FlexClient with id '" + flexClient.getId() + "'. Using default queue processor.", t);
        }
       
        if (processor == null)
        {
            processor = new FlexClientOutboundQueueProcessor();
            processor.setFlexClient(flexClient);
            processor.setEndpointId(endpointId);
        }       
       
        return processor;
    }
   
    /**
     * @exclude
     * Monitors an async poll for a FlexClient for timeout.
     *
     * @param asyncPollTimeout The async poll task to monitor for timeout.
     */
    public void monitorAsyncPollTimeout(TimeoutAbstractObject asyncPollTimeout)
    {
        flexClientTimeoutManager.scheduleTimeout(asyncPollTimeout);
    }
   
    /**
     * @exclude
     * Schedules a timed flush for the passed FlexClient to be invoked in the future.
     *
     * @param flexClient The FlexClient to flush.
     */
    public void scheduleFlush(TimerTask flushTask, int waitInterval)
    {
        synchronized (flushInitLock)
        {
            if (flushScheduler == null)
                flushScheduler = new Timer(true /* make this a daemon so it shuts down quickly */);
        }
       
        flushScheduler.schedule(flushTask, waitInterval);
    }

    /**
     * @see flex.management.ManageableComponent#start()
     */
    public void start()
    {
        if (isManaged())
        {
            controller = new FlexClientManagerControl(getParent().getControl(), this);
            setControl(controller);
            controller.register();
        }
       
        final String baseId = getId();
        flexClientTimeoutManager = new TimeoutManager(new ThreadFactory()
        {
            int counter = 1;           
            public synchronized Thread newThread(Runnable runnable)
            {
                Thread t = new Thread(runnable);
                t.setName(baseId + "-TimeoutThread-" + counter++);
                return t;
            }
        });
    }
   
    /**
     * @see flex.management.ManageableComponent#stop()
     */
    public void stop()
    {
        if (controller != null)
        {
            controller.unregister();
        }

        if (flushScheduler != null)
            flushScheduler.cancel();
       
        if (flexClientTimeoutManager != null)
            flexClientTimeoutManager.shutdown();
    }
    //--------------------------------------------------------------------------
    //
    // Protected Methods
    //
    //--------------------------------------------------------------------------
   
    /* (non-Javadoc)
     * @see flex.management.ManageableComponent#getLogCategory()
     */
    protected String getLogCategory()
    {
        return LogCategories.CLIENT_FLEXCLIENT;
    }
   
    //--------------------------------------------------------------------------
    //
    // Package Private Methods
    //
    //--------------------------------------------------------------------------

    /**
     * @exclude
     * Removes a FlexClient from being managed by this manager.
     * This method is invoked by FlexClients when they are invalidated.
     *
     * @param The id of the FlexClient being invalidated.
     */
    void removeFlexClient(FlexClient flexClient)
    {
        if (flexClient != null)
        {
            String id = flexClient.getId();
            synchronized (id)
            {
                FlexClient storedClient = (FlexClient)flexClients.get(id);
                // If the stored instance is the same as the invalidating instance based upon identity,
                // remove it.
                if (storedClient == flexClient)
                    flexClients.remove(id);
            }
        }
    }
}
TOP

Related Classes of flex.messaging.client.FlexClientManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.