/*
 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.jndi.rmi.registry;


import java.util.Hashtable;
import java.util.Properties;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;

import javax.naming.*;
import javax.naming.spi.NamingManager;


/**
 * A RegistryContext is a context representing a remote RMI registry.
 *
 * @author Scott Seligman
 */


public class RegistryContext implements Context, Referenceable {

    private Hashtable environment;
    private Registry registry;
    private String host;
    private int port;
    private static final NameParser nameParser = new AtomicNameParser();
    private static final String SOCKET_FACTORY = "com.sun.jndi.rmi.factory.socket";

    Reference reference = null; // ref used to create this context, if any

    // Environment property that, if set, indicates that a security
    // manager should be installed (if none is already in place).
    public static final String SECURITY_MGR =
            "java.naming.rmi.security.manager";

    /**
     * Returns a context for the registry at a given host and port.
     * If "host" is null, uses default host.
     * If "port" is non-positive, uses default port.
     * Cloning of "env" is handled by caller; see comments within
     * RegistryContextFactory.getObjectInstance(), for example.
     */
    public RegistryContext(String host, int port, Hashtable env)
            throws NamingException
    {
        environment = ((env == null) ? new Hashtable(5) : env);
        if (environment.get(SECURITY_MGR) != null) {
            installSecurityMgr();
        }

        // chop off '[' and ']' in an IPv6 literal address
        if ((host != null) && (host.charAt(0) == '[')) {
            host = host.substring(1, host.length() - 1);
        }

        RMIClientSocketFactory socketFactory =
                (RMIClientSocketFactory) environment.get(SOCKET_FACTORY);
        registry = getRegistry(host, port, socketFactory);
        this.host = host;
        this.port = port;
    }

    /**
     * Returns a clone of a registry context.  The context's private state
     * is independent of the original's (so closing one context, for example,
     * won't close the other).
     */
    // %%% Alternatively, this could be done with a clone() method.
    RegistryContext(RegistryContext ctx) {
        environment = (Hashtable)ctx.environment.clone();
        registry = ctx.registry;
        host = ctx.host;
        port = ctx.port;
        reference = ctx.reference;
    }

    protected void finalize() {
        close();
    }

    public Object lookup(Name name) throws NamingException {
        if (name.isEmpty()) {
            return (new RegistryContext(this));
        }
        Remote obj;
        try {
            obj = registry.lookup(name.get(0));
        } catch (NotBoundException e) {
            throw (new NameNotFoundException(name.get(0)));
        } catch (RemoteException e) {
            throw (NamingException)wrapRemoteException(e).fillInStackTrace();
        }
        return (decodeObject(obj, name.getPrefix(1)));
    }

    public Object lookup(String name) throws NamingException {
        return lookup(new CompositeName(name));
    }

    /**
     * If the object to be bound is both Remote and Referenceable, binds the
     * object itself, not its Reference.
     */
    public void bind(Name name, Object obj) throws NamingException {
        if (name.isEmpty()) {
            throw (new InvalidNameException(
                    "RegistryContext: Cannot bind empty name"));
        }
        try {
            registry.bind(name.get(0), encodeObject(obj, name.getPrefix(1)));
        } catch (AlreadyBoundException e) {
            NamingException ne = new NameAlreadyBoundException(name.get(0));
            ne.setRootCause(e);
            throw ne;
        } catch (RemoteException e) {
            throw (NamingException)wrapRemoteException(e).fillInStackTrace();
        }
    }

    public void bind(String name, Object obj) throws NamingException {
        bind(new CompositeName(name), obj);
    }

    public void rebind(Name name, Object obj) throws NamingException {
        if (name.isEmpty()) {
            throw (new InvalidNameException(
                    "RegistryContext: Cannot rebind empty name"));
        }
        try {
            registry.rebind(name.get(0), encodeObject(obj, name.getPrefix(1)));
        } catch (RemoteException e) {
            throw (NamingException)wrapRemoteException(e).fillInStackTrace();
        }
    }

    public void rebind(String name, Object obj) throws NamingException {
        rebind(new CompositeName(name), obj);
    }

    public void unbind(Name name) throws NamingException {
        if (name.isEmpty()) {
            throw (new InvalidNameException(
                    "RegistryContext: Cannot unbind empty name"));
        }
        try {
            registry.unbind(name.get(0));
        } catch (NotBoundException e) {
            // method is idempotent
        } catch (RemoteException e) {
            throw (NamingException)wrapRemoteException(e).fillInStackTrace();
        }
    }

    public void unbind(String name) throws NamingException {
        unbind(new CompositeName(name));
    }

    /**
     * Rename is implemented by this sequence of operations:
     * lookup, bind, unbind.  The sequence is not performed atomically.
     */
    public void rename(Name oldName, Name newName) throws NamingException {
        bind(newName, lookup(oldName));
        unbind(oldName);
    }

    public void rename(String name, String newName) throws NamingException {
        rename(new CompositeName(name), new CompositeName(newName));
    }

    public NamingEnumeration list(Name name)    throws NamingException {
        if (!name.isEmpty()) {
            throw (new InvalidNameException(
                    "RegistryContext: can only list \"\""));
        }
        try {
            String[] names = registry.list();
            return (new NameClassPairEnumeration(names));
        } catch (RemoteException e) {
            throw (NamingException)wrapRemoteException(e).fillInStackTrace();
        }
    }

    public NamingEnumeration list(String name) throws NamingException {
        return list(new CompositeName(name));
    }

    public NamingEnumeration listBindings(Name name)
            throws NamingException
    {
        if (!name.isEmpty()) {
            throw (new InvalidNameException(
                    "RegistryContext: can only list \"\""));
        }
        try {
            String[] names = registry.list();
            return (new BindingEnumeration(this, names));
        } catch (RemoteException e) {
            throw (NamingException)wrapRemoteException(e).fillInStackTrace();
        }
    }

    public NamingEnumeration listBindings(String name) throws NamingException {
        return listBindings(new CompositeName(name));
    }

    public void destroySubcontext(Name name) throws NamingException {
        throw (new OperationNotSupportedException());
    }

    public void destroySubcontext(String name) throws NamingException {
        throw (new OperationNotSupportedException());
    }

    public Context createSubcontext(Name name) throws NamingException {
        throw (new OperationNotSupportedException());
    }

    public Context createSubcontext(String name) throws NamingException {
        throw (new OperationNotSupportedException());
    }

    public Object lookupLink(Name name) throws NamingException {
        return lookup(name);
    }

    public Object lookupLink(String name) throws NamingException {
        return lookup(name);
    }

    public NameParser getNameParser(Name name) throws NamingException {
        return nameParser;
    }

    public NameParser getNameParser(String name) throws NamingException {
        return nameParser;
    }

    public Name composeName(Name name, Name prefix) throws NamingException {
        Name result = (Name)prefix.clone();
        return result.addAll(name);
    }

    public String composeName(String name, String prefix)
            throws NamingException
    {
        return composeName(new CompositeName(name),
                           new CompositeName(prefix)).toString();
    }

    public Object removeFromEnvironment(String propName)
            throws NamingException
    {
        return environment.remove(propName);
    }

    public Object addToEnvironment(String propName, Object propVal)
            throws NamingException
    {
        if (propName.equals(SECURITY_MGR)) {
            installSecurityMgr();
        }
        return environment.put(propName, propVal);
    }

    public Hashtable getEnvironment() throws NamingException {
        return (Hashtable)environment.clone();
    }

    public void close() {
        environment = null;
        registry = null;
        // &&& If we were caching registry connections, we would probably
        // uncache this one now.
    }

    public String getNameInNamespace() {
        return ""; // Registry has an empty name
    }

    /**
     * Returns an RMI registry reference for this context.
     *<p>
     * If this context was created from a reference, that reference is
     * returned.  Otherwise, an exception is thrown if the registry's
     * host is "localhost" or the default (null).  Although this could
     * possibly make for a valid reference, it's far more likely to be
     * an easily made error.
     *
     * @see RegistryContextFactory
     */
    public Reference getReference() throws NamingException {
        if (reference != null) {
            return (Reference)reference.clone();  // %%% clone the addrs too?
        }
        if (host == null || host.equals("localhost")) {
            throw (new ConfigurationException(
                    "Cannot create a reference for an RMI registry whose " +
                    "host was unspecified or specified as \"localhost\""));
        }
        String url = "rmi://";

        // Enclose IPv6 literal address in '[' and ']'
        url = (host.indexOf(":") > -1) ? url + "[" + host + "]" :
                                         url + host;
        if (port > 0) {
            url += ":" + Integer.toString(port);
        }
        RefAddr addr = new StringRefAddr(RegistryContextFactory.ADDRESS_TYPE,
                                         url);
        return (new Reference(RegistryContext.class.getName(),
                              addr,
                              RegistryContextFactory.class.getName(),
                              null));
    }


    /**
     * Wrap a RemoteException inside a NamingException.
     */
    public static NamingException wrapRemoteException(RemoteException re) {

        NamingException ne;

        if (re instanceof ConnectException) {
            ne = new ServiceUnavailableException();

        } else if (re instanceof AccessException) {
            ne = new NoPermissionException();

        } else if (re instanceof StubNotFoundException ||
                   re instanceof UnknownHostException ||
                   re instanceof SocketSecurityException) {
            ne = new ConfigurationException();

        } else if (re instanceof ExportException ||
                   re instanceof ConnectIOException ||
                   re instanceof MarshalException ||
                   re instanceof UnmarshalException ||
                   re instanceof NoSuchObjectException) {
            ne = new CommunicationException();

        } else if (re instanceof ServerException &&
                   re.detail instanceof RemoteException) {
            ne = wrapRemoteException((RemoteException)re.detail);

        } else {
            ne = new NamingException();
        }
        ne.setRootCause(re);
        return ne;
    }

    /**
     * Returns the registry at a given host, port and socket factory.
     * If "host" is null, uses default host.
     * If "port" is non-positive, uses default port.
     * If "socketFactory" is null, uses the default socket.
     */
    private static Registry getRegistry(String host, int port,
                RMIClientSocketFactory socketFactory)
            throws NamingException
    {
        // %%% We could cache registry connections here.  The transport layer
        // may already reuse connections.
        try {
            if (socketFactory == null) {
                return LocateRegistry.getRegistry(host, port);
            } else {
                return LocateRegistry.getRegistry(host, port, socketFactory);
            }
        } catch (RemoteException e) {
            throw (NamingException)wrapRemoteException(e).fillInStackTrace();
        }
    }

    /**
     * Attempts to install a security manager if none is currently in
     * place.
     */
    private static void installSecurityMgr() {

        try {
            System.setSecurityManager(new RMISecurityManager());
        } catch (Exception e) {
        }
    }

    /**
     * Encodes an object prior to binding it in the registry.  First,
     * NamingManager.getStateToBind() is invoked.  If the resulting
     * object is Remote, it is returned.  If it is a Reference or
     * Referenceable, the reference is wrapped in a Remote object.
     * Otherwise, an exception is thrown.
     *
     * @param name      The object's name relative to this context.
     */
    private Remote encodeObject(Object obj, Name name)
            throws NamingException, RemoteException
    {
        obj = NamingManager.getStateToBind(obj, name, this, environment);

        if (obj instanceof Remote) {
            return (Remote)obj;
        }
        if (obj instanceof Reference) {
            return (new ReferenceWrapper((Reference)obj));
        }
        if (obj instanceof Referenceable) {
            return (new ReferenceWrapper(((Referenceable)obj).getReference()));
        }
        throw (new IllegalArgumentException(
                "RegistryContext: " +
                "object to bind must be Remote, Reference, or Referenceable"));
    }

    /**
     * Decodes an object that has been retrieved from the registry.
     * First, if the object is a RemoteReference, the Reference is
     * unwrapped.  Then, NamingManager.getObjectInstance() is invoked.
     *
     * @param name      The object's name relative to this context.
     */
    private Object decodeObject(Remote r, Name name) throws NamingException {
        try {
            Object obj = (r instanceof RemoteReference)
                        ? ((RemoteReference)r).getReference()
                        : (Object)r;
            return NamingManager.getObjectInstance(obj, name, this,
                                                   environment);
        } catch (NamingException e) {
            throw e;
        } catch (RemoteException e) {
            throw (NamingException)
                wrapRemoteException(e).fillInStackTrace();
        } catch (Exception e) {
            NamingException ne = new NamingException();
            ne.setRootCause(e);
            throw ne;
        }
    }

}


/**
 * A name parser for case-sensitive atomic names.
 */
class AtomicNameParser implements NameParser {
    private static final Properties syntax = new Properties();

    public Name parse(String name) throws NamingException {
        return (new CompoundName(name, syntax));
    }
}


/**
 * An enumeration of name / class-name pairs.  Since we don't know anything
 * about the classes, each class name is returned as the generic
 * "java.lang.Object".
 */
class NameClassPairEnumeration implements NamingEnumeration {
    private final String[] names;
    private int nextName;       // index into "names"

    NameClassPairEnumeration(String[] names) {
        this.names = names;
        nextName = 0;
    }

    public boolean hasMore() {
        return (nextName < names.length);
    }

    public Object next() throws NamingException {
        if (!hasMore()) {
            throw (new java.util.NoSuchElementException());
        }
        // Convert name to a one-element composite name, so embedded
        // meta-characters are properly escaped.
        String name = names[nextName++];
        Name cname = (new CompositeName()).add(name);
        NameClassPair ncp = new NameClassPair(cname.toString(),
                                            "java.lang.Object");
        ncp.setNameInNamespace(name);
        return ncp;
    }

    public boolean hasMoreElements() {
        return hasMore();
    }

    public Object nextElement() {
        try {
            return next();
        } catch (NamingException e) {   // should never happen
            throw (new java.util.NoSuchElementException(
                    "javax.naming.NamingException was thrown"));
        }
    }

    public void close() {
        nextName = names.length;
    }
}


/**
 * An enumeration of Bindings.
 *
 * The actual registry lookups are performed when next() is called.  It would
 * be nicer to defer this until the object (or its class name) is actually
 * requested.  The problem with that approach is that Binding.getObject()
 * cannot throw NamingException.
 */
class BindingEnumeration implements NamingEnumeration {
    private RegistryContext ctx;
    private final String[] names;
    private int nextName;       // index into "names"

    BindingEnumeration(RegistryContext ctx, String[] names) {
        // Clone ctx in case someone closes it before we're through.
        this.ctx = new RegistryContext(ctx);
        this.names = names;
        nextName = 0;
    }

    protected void finalize() {
        ctx.close();
    }

    public boolean hasMore() {
        if (nextName >= names.length) {
            ctx.close();
        }
        return (nextName < names.length);
    }

    public Object next() throws NamingException {
        if (!hasMore()) {
            throw (new java.util.NoSuchElementException());
        }
        // Convert name to a one-element composite name, so embedded
        // meta-characters are properly escaped.
        String name = names[nextName++];
        Name cname = (new CompositeName()).add(name);

        Object obj = ctx.lookup(cname);
        String cnameStr = cname.toString();
        Binding binding = new Binding(cnameStr, obj);
        binding.setNameInNamespace(cnameStr);
        return binding;
    }

    public boolean hasMoreElements() {
        return hasMore();
    }

    public Object nextElement() {
        try {
            return next();
        } catch (NamingException e) {
            throw (new java.util.NoSuchElementException(
                    "javax.naming.NamingException was thrown"));
        }
    }

    public void close () {
        finalize();
    }
}
