alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (RegistryContext.java)

This example Java source code file (RegistryContext.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

binding, cannot, compositename, hashtable, invalidnameexception, nameparser, naming, namingenumeration, namingexception, object, operationnotsupportedexception, reference, registrycontext, remoteexception, rmi, string, util

The RegistryContext.java Java example source code

/*
 * Copyright (c) 1999, 2011, 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<String, Object> 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.
     */
    @SuppressWarnings("unchecked")
    public RegistryContext(String host, int port, Hashtable<?, ?> env)
            throws NamingException
    {
        environment = (env == null)
                      ? new Hashtable<String, Object>(5)
                      : (Hashtable<String, Object>) 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.
    @SuppressWarnings("unchecked") // clone()
    RegistryContext(RegistryContext ctx) {
        environment = (Hashtable<String, Object>)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<NameClassPair> 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<NameClassPair> list(String name) throws
            NamingException {
        return list(new CompositeName(name));
    }

    public NamingEnumeration<Binding> 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<Binding> 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);
    }

    @SuppressWarnings("unchecked") // clone()
    public Hashtable<String, Object> getEnvironment() throws NamingException {
        return (Hashtable<String, Object>)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.
 */
class NameClassPairEnumeration implements NamingEnumeration<NameClassPair> {
    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 NameClassPair 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 NameClassPair 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<Binding> {
    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 Binding 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 Binding nextElement() {
        try {
            return next();
        } catch (NamingException e) {
            throw (new java.util.NoSuchElementException(
                    "javax.naming.NamingException was thrown"));
        }
    }

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

Other Java examples (source code examples)

Here is a short list of links related to this Java RegistryContext.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.