/*
 * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.management.remote.rmi;

import com.sun.jmx.remote.internal.ArrayNotificationBuffer;
import com.sun.jmx.remote.internal.NotificationBuffer;
import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
import com.sun.jmx.remote.util.ClassLogger;

import java.io.Closeable;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.rmi.Remote;
import java.rmi.server.RemoteServer;
import java.rmi.server.ServerNotActiveException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.management.MBeanServer;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXConnectorServer;
import javax.security.auth.Subject;

/**
 * <p>An RMI object representing a connector server.  Remote clients
 * can make connections using the {@link #newClient(Object)} method.  This
 * method returns an RMI object representing the connection.</p>
 *
 * <p>User code does not usually reference this class directly.
 * RMI connection servers are usually created with the class {@link
 * RMIConnectorServer}.  Remote clients usually create connections
 * either with {@link javax.management.remote.JMXConnectorFactory}
 * or by instantiating {@link RMIConnector}.</p>
 *
 * <p>This is an abstract class.  Concrete subclasses define the
 * details of the client connection objects, such as whether they use
 * JRMP or IIOP.</p>
 *
 * @since 1.5
 */
public abstract class RMIServerImpl implements Closeable, RMIServer {
    /**
     * <p>Constructs a new <code>RMIServerImpl</code>.</p>
     *
     * @param env the environment containing attributes for the new
     * <code>RMIServerImpl</code>.  Can be null, which is equivalent
     * to an empty Map.
     */
    public RMIServerImpl(Map<String,?> env) {
        this.env = (env == null) ? Collections.EMPTY_MAP : env;
    }

    void setRMIConnectorServer(RMIConnectorServer connServer)
            throws IOException {
        this.connServer = connServer;
    }

    /**
     * <p>Exports this RMI object.</p>
     *
     * @exception IOException if this RMI object cannot be exported.
     */
    protected abstract void export() throws IOException;

    /**
     * Returns a remotable stub for this server object.
     * @return a remotable stub.
     * @exception IOException if the stub cannot be obtained - e.g the
     *            RMIServerImpl has not been exported yet.
     **/
    public abstract Remote toStub() throws IOException;

    /**
     * <p>Sets the default <code>ClassLoader</code> for this connector
     * server. New client connections will use this classloader.
     * Existing client connections are unaffected.</p>
     *
     * @param cl the new <code>ClassLoader</code> to be used by this
     * connector server.
     *
     * @see #getDefaultClassLoader
     */
    public synchronized void setDefaultClassLoader(ClassLoader cl) {
        this.cl = cl;
    }

    /**
     * <p>Gets the default <code>ClassLoader</code> used by this connector
     * server.</p>
     *
     * @return the default <code>ClassLoader</code> used by this
     * connector server.</p>
     *
     * @see #setDefaultClassLoader
     */
    public synchronized ClassLoader getDefaultClassLoader() {
        return cl;
    }

    /**
     * <p>Sets the <code>MBeanServer</code> to which this connector
     * server is attached. New client connections will interact
     * with this <code>MBeanServer</code>. Existing client connections are
     * unaffected.</p>
     *
     * @param mbs the new <code>MBeanServer</code>.  Can be null, but
     * new client connections will be refused as long as it is.
     *
     * @see #getMBeanServer
     */
    public synchronized void setMBeanServer(MBeanServer mbs) {
        this.mbeanServer = mbs;
    }

    /**
     * <p>The <code>MBeanServer</code> to which this connector server
     * is attached.  This is the last value passed to {@link
     * #setMBeanServer} on this object, or null if that method has
     * never been called.</p>
     *
     * @return the <code>MBeanServer</code> to which this connector
     * is attached.
     *
     * @see #setMBeanServer
     */
    public synchronized MBeanServer getMBeanServer() {
        return mbeanServer;
    }

    public String getVersion() {
        // Expected format is: "protocol-version implementation-name"
        try {
            return "1.0 java_runtime_" +
                    System.getProperty("java.runtime.version");
        } catch (SecurityException e) {
            return "1.0 ";
        }
    }

    /**
     * <p>Creates a new client connection.  This method calls {@link
     * #makeClient makeClient} and adds the returned client connection
     * object to an internal list.  When this
     * <code>RMIServerImpl</code> is shut down via its {@link
     * #close()} method, the {@link RMIConnection#close() close()}
     * method of each object remaining in the list is called.</p>
     *
     * <p>The fact that a client connection object is in this internal
     * list does not prevent it from being garbage collected.</p>
     *
     * @param credentials this object specifies the user-defined
     * credentials to be passed in to the server in order to
     * authenticate the caller before creating the
     * <code>RMIConnection</code>.  Can be null.
     *
     * @return the newly-created <code>RMIConnection</code>.  This is
     * usually the object created by <code>makeClient</code>, though
     * an implementation may choose to wrap that object in another
     * object implementing <code>RMIConnection</code>.
     *
     * @exception IOException if the new client object cannot be
     * created or exported.
     *
     * @exception SecurityException if the given credentials do not allow
     * the server to authenticate the user successfully.
     *
     * @exception IllegalStateException if {@link #getMBeanServer()}
     * is null.
     */
    public RMIConnection newClient(Object credentials) throws IOException {
        return doNewClient(credentials);
    }

    /**
     * This method could be overridden by subclasses defined in this package
     * to perform additional operations specific to the underlying transport
     * before creating the new client connection.
     */
    RMIConnection doNewClient(Object credentials) throws IOException {
        final boolean tracing = logger.traceOn();

        if (tracing) logger.trace("newClient","making new client");

        if (getMBeanServer() == null)
            throw new IllegalStateException("Not attached to an MBean server");

        Subject subject = null;
        JMXAuthenticator authenticator =
            (JMXAuthenticator) env.get(JMXConnectorServer.AUTHENTICATOR);
        if (authenticator == null) {
            /*
             * Create the JAAS-based authenticator only if authentication
             * has been enabled
             */
            if (env.get("jmx.remote.x.password.file") != null ||
                env.get("jmx.remote.x.login.config") != null) {
                authenticator = new JMXPluggableAuthenticator(env);
            }
        }
        if (authenticator != null) {
            if (tracing) logger.trace("newClient","got authenticator: " +
                               authenticator.getClass().getName());
            try {
                subject = authenticator.authenticate(credentials);
            } catch (SecurityException e) {
                logger.trace("newClient", "Authentication failed: " + e);
                throw e;
            }
        }

        if (tracing) {
            if (subject != null)
                logger.trace("newClient","subject is not null");
            else logger.trace("newClient","no subject");
        }

        final String connectionId = makeConnectionId(getProtocol(), subject);

        if (tracing)
            logger.trace("newClient","making new connection: " + connectionId);

        RMIConnection client = makeClient(connectionId, subject);

        connServer.connectionOpened(connectionId, "Connection opened", null);

        dropDeadReferences();
        WeakReference<RMIConnection> wr = new WeakReference<RMIConnection>(client);
        synchronized (clientList) {
            clientList.add(wr);
        }

        if (tracing)
            logger.trace("newClient","new connection done: " + connectionId );

        return client;
    }

    /**
     * <p>Creates a new client connection.  This method is called by
     * the public method {@link #newClient(Object)}.</p>
     *
     * @param connectionId the ID of the new connection.  Every
     * connection opened by this connector server will have a
     * different ID.  The behavior is unspecified if this parameter is
     * null.
     *
     * @param subject the authenticated subject.  Can be null.
     *
     * @return the newly-created <code>RMIConnection</code>.
     *
     * @exception IOException if the new client object cannot be
     * created or exported.
     */
    protected abstract RMIConnection makeClient(String connectionId,
                                                Subject subject)
            throws IOException;

    /**
     * <p>Closes a client connection made by {@link #makeClient makeClient}.
     *
     * @param client a connection previously returned by
     * <code>makeClient</code> on which the <code>closeClient</code>
     * method has not previously been called.  The behavior is
     * unspecified if these conditions are violated, including the
     * case where <code>client</code> is null.
     *
     * @exception IOException if the client connection cannot be
     * closed.
     */
    protected abstract void closeClient(RMIConnection client)
            throws IOException;

    /**
     * <p>Returns the protocol string for this object.  The string is
     * <code>rmi</code> for RMI/JRMP and <code>iiop</code> for RMI/IIOP.
     *
     * @return the protocol string for this object.
     */
    protected abstract String getProtocol();

    /**
     * <p>Method called when a client connection created by {@link
     * #makeClient makeClient} is closed.  A subclass that defines
     * <code>makeClient</code> must arrange for this method to be
     * called when the resultant object's {@link RMIConnection#close()
     * close} method is called.  This enables it to be removed from
     * the <code>RMIServerImpl</code>'s list of connections.  It is
     * not an error for <code>client</code> not to be in that
     * list.</p>
     *
     * <p>After removing <code>client</code> from the list of
     * connections, this method calls {@link #closeClient
     * closeClient(client)}.</p>
     *
     * @param client the client connection that has been closed.
     *
     * @exception IOException if {@link #closeClient} throws this
     * exception.
     *
     * @exception NullPointerException if <code>client</code> is null.
     */
    protected void clientClosed(RMIConnection client) throws IOException {
        final boolean debug = logger.debugOn();

        if (debug) logger.trace("clientClosed","client="+client);

        if (client == null)
            throw new NullPointerException("Null client");

        synchronized (clientList) {
            dropDeadReferences();
            for (Iterator it = clientList.iterator(); it.hasNext(); ) {
                WeakReference wr = (WeakReference) it.next();
                if (wr.get() == client) {
                    it.remove();
                    break;
                }
            }
            /* It is not a bug for this loop not to find the client.  In
               our close() method, we remove a client from the list before
               calling its close() method.  */
        }

        if (debug) logger.trace("clientClosed", "closing client.");
        closeClient(client);

        if (debug) logger.trace("clientClosed", "sending notif");
        connServer.connectionClosed(client.getConnectionId(),
                                    "Client connection closed", null);

        if (debug) logger.trace("clientClosed","done");
    }

    /**
     * <p>Closes this connection server.  This method first calls the
     * {@link #closeServer()} method so that no new client connections
     * will be accepted.  Then, for each remaining {@link
     * RMIConnection} object returned by {@link #makeClient
     * makeClient}, its {@link RMIConnection#close() close} method is
     * called.</p>
     *
     * <p>The behavior when this method is called more than once is
     * unspecified.</p>
     *
     * <p>If {@link #closeServer()} throws an
     * <code>IOException</code>, the individual connections are
     * nevertheless closed, and then the <code>IOException</code> is
     * thrown from this method.</p>
     *
     * <p>If {@link #closeServer()} returns normally but one or more
     * of the individual connections throws an
     * <code>IOException</code>, then, after closing all the
     * connections, one of those <code>IOException</code>s is thrown
     * from this method.  If more than one connection throws an
     * <code>IOException</code>, it is unspecified which one is thrown
     * from this method.</p>
     *
     * @exception IOException if {@link #closeServer()} or one of the
     * {@link RMIConnection#close()} calls threw
     * <code>IOException</code>.
     */
    public synchronized void close() throws IOException {
        final boolean tracing = logger.traceOn();
        final boolean debug   = logger.debugOn();

        if (tracing) logger.trace("close","closing");

        IOException ioException = null;
        try {
            if (debug)   logger.debug("close","closing Server");
            closeServer();
        } catch (IOException e) {
            if (tracing) logger.trace("close","Failed to close server: " + e);
            if (debug)   logger.debug("close",e);
            ioException = e;
        }

        if (debug)   logger.debug("close","closing Clients");
        // Loop to close all clients
        while (true) {
            synchronized (clientList) {
                if (debug) logger.debug("close","droping dead references");
                dropDeadReferences();

                if (debug) logger.debug("close","client count: "+clientList.size());
                if (clientList.size() == 0)
                    break;
                /* Loop until we find a non-null client.  Because we called
                   dropDeadReferences(), this will usually be the first
                   element of the list, but a garbage collection could have
                   happened in between.  */
                for (Iterator it = clientList.iterator(); it.hasNext(); ) {
                    WeakReference wr = (WeakReference) it.next();
                    RMIConnection client = (RMIConnection) wr.get();
                    it.remove();
                    if (client != null) {
                        try {
                            client.close();
                        } catch (IOException e) {
                            if (tracing)
                                logger.trace("close","Failed to close client: " + e);
                            if (debug) logger.debug("close",e);
                            if (ioException == null)
                                ioException = e;
                        }
                        break;
                    }
                }
            }
        }

        if(notifBuffer != null)
            notifBuffer.dispose();

        if (ioException != null) {
            if (tracing) logger.trace("close","close failed.");
            throw ioException;
        }

        if (tracing) logger.trace("close","closed.");
    }

    /**
     * <p>Called by {@link #close()} to close the connector server.
     * After returning from this method, the connector server must
     * not accept any new connections.</p>
     *
     * @exception IOException if the attempt to close the connector
     * server failed.
     */
    protected abstract void closeServer() throws IOException;

    private static synchronized String makeConnectionId(String protocol,
                                                        Subject subject) {
        connectionIdNumber++;

        String clientHost = "";
        try {
            clientHost = RemoteServer.getClientHost();
        } catch (ServerNotActiveException e) {
            logger.trace("makeConnectionId", "getClientHost", e);
        }

        final StringBuilder buf = new StringBuilder();
        buf.append(protocol).append(":");
        if (clientHost.length() > 0)
            buf.append("//").append(clientHost);
        buf.append(" ");
        if (subject != null) {
            Set principals = subject.getPrincipals();
            String sep = "";
            for (Iterator it = principals.iterator(); it.hasNext(); ) {
                Principal p = (Principal) it.next();
                String name = p.getName().replace(' ', '_').replace(';', ':');
                buf.append(sep).append(name);
                sep = ";";
            }
        }
        buf.append(" ").append(connectionIdNumber);
        if (logger.traceOn())
            logger.trace("newConnectionId","connectionId="+buf);
        return buf.toString();
    }

    private void dropDeadReferences() {
        synchronized (clientList) {
            for (Iterator it = clientList.iterator(); it.hasNext(); ) {
                WeakReference wr = (WeakReference) it.next();
                if (wr.get() == null)
                    it.remove();
            }
        }
    }

    synchronized NotificationBuffer getNotifBuffer() {
        //Notification buffer is lazily created when the first client connects
        if(notifBuffer == null)
            notifBuffer =
                ArrayNotificationBuffer.getNotificationBuffer(mbeanServer,
                                                              env);
        return notifBuffer;
    }

    private static final ClassLogger logger =
        new ClassLogger("javax.management.remote.rmi", "RMIServerImpl");

    /** List of WeakReference values.  Each one references an
        RMIConnection created by this object, or null if the
        RMIConnection has been garbage-collected.  */
    private final List<WeakReference<RMIConnection>> clientList =
            new ArrayList<WeakReference<RMIConnection>>();

    private ClassLoader cl;

    private MBeanServer mbeanServer;

    private final Map env;

    private RMIConnectorServer connServer;

    private static int connectionIdNumber;

    private NotificationBuffer notifBuffer;
}
