Package org.jboss.mx.remote.connector

Source Code of org.jboss.mx.remote.connector.ConnectorFactory$Entry

package org.jboss.mx.remote.connector;

import org.jboss.mx.remote.connector.socket.SocketConnectorClient;
import org.jboss.mx.remote.connector.soap.axis.AxisSOAPClient;
import org.jboss.mx.remote.JMXUtil;
import org.jboss.mx.remote.MBeanServerConnection;

import javax.management.MBeanServer;
import java.net.InetAddress;
import java.net.URL;
import java.util.*;
import java.lang.ref.WeakReference;

/**
* ConnectorFactory is for generating an MBeanServer proxy to a remote
* MBeanServer via a specific transport proxy.
*
* @author <a href="telrod@vocalocity.net">Tom Elrod</a>
* @author <a href="jhaynie@vocalocity.net">Jeff Haynie</a>
* @version $Revision: 1.11 $
*/
public class ConnectorFactory
{
    private static final String TRANSPORTS [] = {"socket", "soap"};
    private static final List classloaders=new ArrayList(2);
    private static final Map connectors=new HashMap();
    private static final Vector listeners=new Vector();

    //JGH: this stuff needs to be refactored out when tom adds his code
    // we might consider a MBeanConnection registery?

    /**
     * return an array of connections that are currently used by the ConnectorFactory
     *
     * @return mbean server connections
     */
    public static MBeanServerConnection[] getConnections ()
    {
        synchronized(connectors)
        {
            MBeanServerConnection conn[]=new MBeanServerConnection[connectors.size()];
            int c=0;
            Iterator iter=connectors.values().iterator();
            while(iter.hasNext())
            {
                Entry entry=(Entry)iter.next();
                conn[c++]=entry.conn;
            }
            return conn;
        }
    }
    public static void addListener (Listener listener)
    {
        listeners.add(new WeakReference(listener));
    }
    public static void removeListener (Listener listener)
    {
        listeners.remove(new WeakReference(listener));
    }
    /**
     * return a collection of classloader
     *
     * @return classloaders
     */
    public static final Collection getClassLoaders ()
    {
        return classloaders;
    }
    /**
     * add a classloader that is visible by the Connector and associated classes
     *
     * @param cl
     */
    public static void addClassLoader (ClassLoader cl)
    {
        if (cl!=null)
        {
            classloaders.add(cl);
        }
    }
    /**
     * remove a previously added classloader
     *
     * @param cl
     */
    public static void removeClassLoader (ClassLoader cl)
    {
        if (cl!=null)
        {
            classloaders.remove(cl);
        }
    }
    /**
     * load a class that is visible by the ConnectorFactory
     *
     * @param name
     * @return loaded class
     * @throws ClassNotFoundException
     */
    public static Class loadClass (String name)
        throws ClassNotFoundException
    {
        Iterator i = classloaders.iterator();
        while(i.hasNext())
        {
            try
            {
                return ((ClassLoader)i.next()).loadClass(name);
            }
            catch (Exception ex)
            {

            }
        }
        throw new ClassNotFoundException(name);
    }
    /**
     * get an array of valid transport types for Connectors
     *
     * @return transport types
     */
    public static final String[] getConnectorTransports()
    {
        return TRANSPORTS;
    }

    /**
     * return the remote MBeanServer proxy for a given remote serverId
     *
     * @param serverId
     * @return mbean server proxy
     */
    public static final MBeanServer getMBeanServerForServerId (String serverId)
    {
        Entry entry=(Entry)connectors.get(serverId);
        return (entry==null?null:entry.remote);
    }

    /**
     * return true if the connector factory has a remote mbeanserver registered
     *
     * @param serverId
     * @return true if server has been registered; false otherwise
     */
    public static final boolean hasMBeanServerForServerId (String serverId)
    {
        return connectors.containsKey(serverId);
    }

    /**
     * destroy a previously created connector and allow the connector
     * to clean itself up
     *
     * @param connector
     * @throws Exception
     */
    private static void destroyConnector(MBeanServer connector)
            throws Exception
    {
        String id = JMXUtil.getServerId(connector);
        connectors.remove(id);
        if (connector instanceof ConnectorDestroyable)
        {
            ((ConnectorDestroyable) connector).destroyConnector();
        }
        connector = null;
    }

    /**
     * destroy a connector for a given MBeanServer ID
     *
     * @param serverId
     * @throws Exception
     */
    public static void destroyConnector (String serverId)
        throws Exception
    {
        Entry entry=(Entry)connectors.remove(serverId);
        if (entry!=null)
        {
            fireDestroyed(entry.remote,entry.conn);
            destroyConnector(entry.remote);
            entry=null;
        }
    }

    private static void fireDestroyed (MBeanServer server, MBeanServerConnection conn)
    {
        synchronized(listeners)
        {
            Enumeration e=listeners.elements();
            while(e.hasMoreElements())
            {
                WeakReference ref=(WeakReference)e.nextElement();
                Listener listener=(Listener)ref.get();
                if (listener==null)
                {
                    listeners.remove(ref);
                    ref=null;
                    listener=null;
                }
                else
                {
                    try
                    {
                        listener.connectorDestroyed(server,conn);
                    }
                    catch (Throwable e1)
                    {
                        e1.printStackTrace ();
                    }
                }
            }
        }
    }
    private static void fireCreated (MBeanServer server, MBeanServerConnection conn)
    {
        synchronized(listeners)
        {
            Enumeration e=listeners.elements();
            while(e.hasMoreElements())
            {
                WeakReference ref=(WeakReference)e.nextElement();
                Listener listener=(Listener)ref.get();
                if (listener==null)
                {
                    listeners.remove(ref);
                    ref=null;
                    listener=null;
                }
                else
                {
                    try
                    {
                        listener.connectorCreated(server,conn);
                    }
                    catch (Throwable e1)
                    {
                        e1.printStackTrace ();
                    }
                }
            }
        }
    }

    private final static class Entry
    {
        MBeanServer remote;
        MBeanServerConnection conn;
        final int hashCode;

        Entry (MBeanServer remote, MBeanServerConnection conn)
        {
            this.remote=remote;
            this.conn=conn;
            this.hashCode = remote.hashCode()+conn.hashCode();
        }
        public int hashCode ()
        {
            return hashCode;
        }
        public boolean equals (Object obj)
        {
            if (obj instanceof Entry)
            {
                return hashCode==obj.hashCode();
            }
            return false;
        }
    }
    /**
     * factory method for generating a factory to a remote MBeanServer via a
     * specific transport Connector
     *
     * @param transport
     * @param props
     * @return mbean server proxy
     * @throws Exception
     */
    public static MBeanServer createConnector(MBeanServerConnection conn)
            throws Exception
    {
        if(checkValidTransport(conn.getTransport()))
        {
            MBeanServer remote=null;
            synchronized(connectors)
            {
                Entry entry=(Entry)connectors.get(conn.getServerId());
                if (entry!=null)
                {
                    // return the cached copy
                    return entry.remote;
                }
                if (conn.getTransport().equals("socket"))
                {
                    // create a new socket connector
                    remote = createSocketConnector(conn);
                }
                else if (conn.getTransport().equals("soap"))
                {
                    // create a new axis soap connector
                    remote = createSOAPConnector(conn);

                }
                // register
                connectors.put(conn.getServerId(),new Entry(remote,conn));
            }
            fireCreated(remote,conn);
            return remote;
        }
        else
        {
            throw new IllegalArgumentException("Invalid transport '" + conn.getTransport() + "'");
        }
    }

    /**
     * Checks to see if transport string pased is supported by this connector factory
     * @param requestedTransport
     * @return true if connector factory can create connector with this transport, false if not.
     */
    private static boolean checkValidTransport(String requestedTransport)
    {
        for(int x = 0; x < TRANSPORTS.length; x++)
        {
            if(TRANSPORTS[x].equals(requestedTransport))
            {
                return true;
            }
        }

        return false;
    }

    /**
     * create a SocketConnector connector
     *
     * @param props
     * @return mbean server proxy
     * @throws Exception
     */
    public static MBeanServer createSocketConnector(MBeanServerConnection conn)
            throws Exception
    {
        Map props = conn.getProperties();
        String ip = (String)props.get("ipaddress");
        String port = (String)props.get("port");
        if (ip == null)
        {
            throw new IllegalArgumentException("Couldn't find the 'ipaddress' property for the socket connector");
        }
        if (port == null)
        {
            throw new IllegalArgumentException("Couldn't find the 'port' property for the socket connector");
        }
        // create a connector to the remote SocketConnector
        return SocketConnectorClient.create(conn.getServerId(),InetAddress.getByName(ip), Integer.parseInt(port));
    }

    public static MBeanServer createSOAPConnector(MBeanServerConnection conn)
        throws Exception
    {
        Map props = conn.getProperties();
        String url = (String)props.get("url");
        String serverid = (String)props.get("serverid");
        if (url == null)
        {
            throw new IllegalArgumentException("Couldn't find the 'url' property for the soap connector");
        }
        // create a connector to the remote SOAPConnector
        return AxisSOAPClient.create(url, serverid);
    }
    /**
     * given a valid soap URL, create a direct connection via SOAP and return a dynamic proxy
     * to the remote SOAP mbean server
     *
     * @param urn
     * @return
     * @throws Exception
     */
    public static MBeanServer createSOAPConnector (URL urn)
        throws Exception
    {
        // create a direct connector to the remote SOAPConnector
        MBeanServer mbs=AxisSOAPClient.create(urn.toExternalForm(), null);
        String serverId = (String)mbs.getAttribute(JMXUtil.getMBeanServerObjectName(),"ServerId");
        MBeanServerConnection conn=new MBeanServerConnection("soap",serverId,null,InetAddress.getByName(urn.getHost()),null);
        connectors.put(serverId,new Entry(mbs,conn));
        fireCreated(mbs,conn);
        return mbs;
    }
    /**
     * listener for factory events
     *
     */
    public static interface Listener
    {
        /**
         * event is fired when a connector is created
         *
         * @param server
         * @param serverId
         * @param transport
         * @param props
         */
        public void connectorCreated (MBeanServer server, MBeanServerConnection conn);
        /**
         * event is fired when a connector is destroyed
         *
         * @param server
         * @param serverId
         * @param transport
         * @param props
         */
        public void connectorDestroyed (MBeanServer server, MBeanServerConnection conn);
    }
}
TOP

Related Classes of org.jboss.mx.remote.connector.ConnectorFactory$Entry

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.