src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java

Print this page




  29 import java.util.Hashtable;
  30 import java.util.Properties;
  31 import java.rmi.*;
  32 import java.rmi.server.*;
  33 import java.rmi.registry.Registry;
  34 import java.rmi.registry.LocateRegistry;
  35 
  36 import javax.naming.*;
  37 import javax.naming.spi.NamingManager;
  38 
  39 
  40 /**
  41  * A RegistryContext is a context representing a remote RMI registry.
  42  *
  43  * @author Scott Seligman
  44  */
  45 
  46 
  47 public class RegistryContext implements Context, Referenceable {
  48 
  49     private Hashtable environment;
  50     private Registry registry;
  51     private String host;
  52     private int port;
  53     private static final NameParser nameParser = new AtomicNameParser();
  54     private static final String SOCKET_FACTORY = "com.sun.jndi.rmi.factory.socket";
  55 
  56     Reference reference = null; // ref used to create this context, if any
  57 
  58     // Environment property that, if set, indicates that a security
  59     // manager should be installed (if none is already in place).
  60     public static final String SECURITY_MGR =
  61             "java.naming.rmi.security.manager";
  62 
  63     /**
  64      * Returns a context for the registry at a given host and port.
  65      * If "host" is null, uses default host.
  66      * If "port" is non-positive, uses default port.
  67      * Cloning of "env" is handled by caller; see comments within
  68      * RegistryContextFactory.getObjectInstance(), for example.
  69      */
  70     public RegistryContext(String host, int port, Hashtable env)

  71             throws NamingException
  72     {
  73         environment = ((env == null) ? new Hashtable(5) : env);


  74         if (environment.get(SECURITY_MGR) != null) {
  75             installSecurityMgr();
  76         }
  77 
  78         // chop off '[' and ']' in an IPv6 literal address
  79         if ((host != null) && (host.charAt(0) == '[')) {
  80             host = host.substring(1, host.length() - 1);
  81         }
  82 
  83         RMIClientSocketFactory socketFactory =
  84                 (RMIClientSocketFactory) environment.get(SOCKET_FACTORY);
  85         registry = getRegistry(host, port, socketFactory);
  86         this.host = host;
  87         this.port = port;
  88     }
  89 
  90     /**
  91      * Returns a clone of a registry context.  The context's private state
  92      * is independent of the original's (so closing one context, for example,
  93      * won't close the other).
  94      */
  95     // %%% Alternatively, this could be done with a clone() method.

  96     RegistryContext(RegistryContext ctx) {
  97         environment = (Hashtable)ctx.environment.clone();
  98         registry = ctx.registry;
  99         host = ctx.host;
 100         port = ctx.port;
 101         reference = ctx.reference;
 102     }
 103 
 104     protected void finalize() {
 105         close();
 106     }
 107 
 108     public Object lookup(Name name) throws NamingException {
 109         if (name.isEmpty()) {
 110             return (new RegistryContext(this));
 111         }
 112         Remote obj;
 113         try {
 114             obj = registry.lookup(name.get(0));
 115         } catch (NotBoundException e) {
 116             throw (new NameNotFoundException(name.get(0)));
 117         } catch (RemoteException e) {


 178         }
 179     }
 180 
 181     public void unbind(String name) throws NamingException {
 182         unbind(new CompositeName(name));
 183     }
 184 
 185     /**
 186      * Rename is implemented by this sequence of operations:
 187      * lookup, bind, unbind.  The sequence is not performed atomically.
 188      */
 189     public void rename(Name oldName, Name newName) throws NamingException {
 190         bind(newName, lookup(oldName));
 191         unbind(oldName);
 192     }
 193 
 194     public void rename(String name, String newName) throws NamingException {
 195         rename(new CompositeName(name), new CompositeName(newName));
 196     }
 197 
 198     public NamingEnumeration list(Name name)    throws NamingException {

 199         if (!name.isEmpty()) {
 200             throw (new InvalidNameException(
 201                     "RegistryContext: can only list \"\""));
 202         }
 203         try {
 204             String[] names = registry.list();
 205             return (new NameClassPairEnumeration(names));
 206         } catch (RemoteException e) {
 207             throw (NamingException)wrapRemoteException(e).fillInStackTrace();
 208         }
 209     }
 210 
 211     public NamingEnumeration list(String name) throws NamingException {

 212         return list(new CompositeName(name));
 213     }
 214 
 215     public NamingEnumeration listBindings(Name name)
 216             throws NamingException
 217     {
 218         if (!name.isEmpty()) {
 219             throw (new InvalidNameException(
 220                     "RegistryContext: can only list \"\""));
 221         }
 222         try {
 223             String[] names = registry.list();
 224             return (new BindingEnumeration(this, names));
 225         } catch (RemoteException e) {
 226             throw (NamingException)wrapRemoteException(e).fillInStackTrace();
 227         }
 228     }
 229 
 230     public NamingEnumeration listBindings(String name) throws NamingException {

 231         return listBindings(new CompositeName(name));
 232     }
 233 
 234     public void destroySubcontext(Name name) throws NamingException {
 235         throw (new OperationNotSupportedException());
 236     }
 237 
 238     public void destroySubcontext(String name) throws NamingException {
 239         throw (new OperationNotSupportedException());
 240     }
 241 
 242     public Context createSubcontext(Name name) throws NamingException {
 243         throw (new OperationNotSupportedException());
 244     }
 245 
 246     public Context createSubcontext(String name) throws NamingException {
 247         throw (new OperationNotSupportedException());
 248     }
 249 
 250     public Object lookupLink(Name name) throws NamingException {


 273     {
 274         return composeName(new CompositeName(name),
 275                            new CompositeName(prefix)).toString();
 276     }
 277 
 278     public Object removeFromEnvironment(String propName)
 279             throws NamingException
 280     {
 281         return environment.remove(propName);
 282     }
 283 
 284     public Object addToEnvironment(String propName, Object propVal)
 285             throws NamingException
 286     {
 287         if (propName.equals(SECURITY_MGR)) {
 288             installSecurityMgr();
 289         }
 290         return environment.put(propName, propVal);
 291     }
 292 
 293     public Hashtable getEnvironment() throws NamingException {
 294         return (Hashtable)environment.clone();

 295     }
 296 
 297     public void close() {
 298         environment = null;
 299         registry = null;
 300         // &&& If we were caching registry connections, we would probably
 301         // uncache this one now.
 302     }
 303 
 304     public String getNameInNamespace() {
 305         return ""; // Registry has an empty name
 306     }
 307 
 308     /**
 309      * Returns an RMI registry reference for this context.
 310      *<p>
 311      * If this context was created from a reference, that reference is
 312      * returned.  Otherwise, an exception is thrown if the registry's
 313      * host is "localhost" or the default (null).  Although this could
 314      * possibly make for a valid reference, it's far more likely to be


 466             throw ne;
 467         }
 468     }
 469 
 470 }
 471 
 472 
 473 /**
 474  * A name parser for case-sensitive atomic names.
 475  */
 476 class AtomicNameParser implements NameParser {
 477     private static final Properties syntax = new Properties();
 478 
 479     public Name parse(String name) throws NamingException {
 480         return (new CompoundName(name, syntax));
 481     }
 482 }
 483 
 484 
 485 /**
 486  * An enumeration of name / class-name pairs.  Since we don't know anything
 487  * about the classes, each class name is returned as the generic
 488  * "java.lang.Object".
 489  */
 490 class NameClassPairEnumeration implements NamingEnumeration {
 491     private final String[] names;
 492     private int nextName;       // index into "names"
 493 
 494     NameClassPairEnumeration(String[] names) {
 495         this.names = names;
 496         nextName = 0;
 497     }
 498 
 499     public boolean hasMore() {
 500         return (nextName < names.length);
 501     }
 502 
 503     public Object next() throws NamingException {
 504         if (!hasMore()) {
 505             throw (new java.util.NoSuchElementException());
 506         }
 507         // Convert name to a one-element composite name, so embedded
 508         // meta-characters are properly escaped.
 509         String name = names[nextName++];
 510         Name cname = (new CompositeName()).add(name);
 511         NameClassPair ncp = new NameClassPair(cname.toString(),
 512                                             "java.lang.Object");
 513         ncp.setNameInNamespace(name);
 514         return ncp;
 515     }
 516 
 517     public boolean hasMoreElements() {
 518         return hasMore();
 519     }
 520 
 521     public Object nextElement() {
 522         try {
 523             return next();
 524         } catch (NamingException e) {   // should never happen
 525             throw (new java.util.NoSuchElementException(
 526                     "javax.naming.NamingException was thrown"));
 527         }
 528     }
 529 
 530     public void close() {
 531         nextName = names.length;
 532     }
 533 }
 534 
 535 
 536 /**
 537  * An enumeration of Bindings.
 538  *
 539  * The actual registry lookups are performed when next() is called.  It would
 540  * be nicer to defer this until the object (or its class name) is actually
 541  * requested.  The problem with that approach is that Binding.getObject()
 542  * cannot throw NamingException.
 543  */
 544 class BindingEnumeration implements NamingEnumeration {
 545     private RegistryContext ctx;
 546     private final String[] names;
 547     private int nextName;       // index into "names"
 548 
 549     BindingEnumeration(RegistryContext ctx, String[] names) {
 550         // Clone ctx in case someone closes it before we're through.
 551         this.ctx = new RegistryContext(ctx);
 552         this.names = names;
 553         nextName = 0;
 554     }
 555 
 556     protected void finalize() {
 557         ctx.close();
 558     }
 559 
 560     public boolean hasMore() {
 561         if (nextName >= names.length) {
 562             ctx.close();
 563         }
 564         return (nextName < names.length);
 565     }
 566 
 567     public Object next() throws NamingException {
 568         if (!hasMore()) {
 569             throw (new java.util.NoSuchElementException());
 570         }
 571         // Convert name to a one-element composite name, so embedded
 572         // meta-characters are properly escaped.
 573         String name = names[nextName++];
 574         Name cname = (new CompositeName()).add(name);
 575 
 576         Object obj = ctx.lookup(cname);
 577         String cnameStr = cname.toString();
 578         Binding binding = new Binding(cnameStr, obj);
 579         binding.setNameInNamespace(cnameStr);
 580         return binding;
 581     }
 582 
 583     public boolean hasMoreElements() {
 584         return hasMore();
 585     }
 586 
 587     public Object nextElement() {
 588         try {
 589             return next();
 590         } catch (NamingException e) {
 591             throw (new java.util.NoSuchElementException(
 592                     "javax.naming.NamingException was thrown"));
 593         }
 594     }
 595 
 596     public void close () {
 597         finalize();
 598     }
 599 }


  29 import java.util.Hashtable;
  30 import java.util.Properties;
  31 import java.rmi.*;
  32 import java.rmi.server.*;
  33 import java.rmi.registry.Registry;
  34 import java.rmi.registry.LocateRegistry;
  35 
  36 import javax.naming.*;
  37 import javax.naming.spi.NamingManager;
  38 
  39 
  40 /**
  41  * A RegistryContext is a context representing a remote RMI registry.
  42  *
  43  * @author Scott Seligman
  44  */
  45 
  46 
  47 public class RegistryContext implements Context, Referenceable {
  48 
  49     private Hashtable<String, Object> environment;
  50     private Registry registry;
  51     private String host;
  52     private int port;
  53     private static final NameParser nameParser = new AtomicNameParser();
  54     private static final String SOCKET_FACTORY = "com.sun.jndi.rmi.factory.socket";
  55 
  56     Reference reference = null; // ref used to create this context, if any
  57 
  58     // Environment property that, if set, indicates that a security
  59     // manager should be installed (if none is already in place).
  60     public static final String SECURITY_MGR =
  61             "java.naming.rmi.security.manager";
  62 
  63     /**
  64      * Returns a context for the registry at a given host and port.
  65      * If "host" is null, uses default host.
  66      * If "port" is non-positive, uses default port.
  67      * Cloning of "env" is handled by caller; see comments within
  68      * RegistryContextFactory.getObjectInstance(), for example.
  69      */
  70     @SuppressWarnings("unchecked")
  71     public RegistryContext(String host, int port, Hashtable<?, ?> env)
  72             throws NamingException
  73     {
  74         environment = (env == null)
  75                       ? new Hashtable<String, Object>(5)
  76                       : (Hashtable<String, Object>) env;
  77         if (environment.get(SECURITY_MGR) != null) {
  78             installSecurityMgr();
  79         }
  80 
  81         // chop off '[' and ']' in an IPv6 literal address
  82         if ((host != null) && (host.charAt(0) == '[')) {
  83             host = host.substring(1, host.length() - 1);
  84         }
  85 
  86         RMIClientSocketFactory socketFactory =
  87                 (RMIClientSocketFactory) environment.get(SOCKET_FACTORY);
  88         registry = getRegistry(host, port, socketFactory);
  89         this.host = host;
  90         this.port = port;
  91     }
  92 
  93     /**
  94      * Returns a clone of a registry context.  The context's private state
  95      * is independent of the original's (so closing one context, for example,
  96      * won't close the other).
  97      */
  98     // %%% Alternatively, this could be done with a clone() method.
  99     @SuppressWarnings("unchecked") // clone()
 100     RegistryContext(RegistryContext ctx) {
 101         environment = (Hashtable<String, Object>)ctx.environment.clone();
 102         registry = ctx.registry;
 103         host = ctx.host;
 104         port = ctx.port;
 105         reference = ctx.reference;
 106     }
 107 
 108     protected void finalize() {
 109         close();
 110     }
 111 
 112     public Object lookup(Name name) throws NamingException {
 113         if (name.isEmpty()) {
 114             return (new RegistryContext(this));
 115         }
 116         Remote obj;
 117         try {
 118             obj = registry.lookup(name.get(0));
 119         } catch (NotBoundException e) {
 120             throw (new NameNotFoundException(name.get(0)));
 121         } catch (RemoteException e) {


 182         }
 183     }
 184 
 185     public void unbind(String name) throws NamingException {
 186         unbind(new CompositeName(name));
 187     }
 188 
 189     /**
 190      * Rename is implemented by this sequence of operations:
 191      * lookup, bind, unbind.  The sequence is not performed atomically.
 192      */
 193     public void rename(Name oldName, Name newName) throws NamingException {
 194         bind(newName, lookup(oldName));
 195         unbind(oldName);
 196     }
 197 
 198     public void rename(String name, String newName) throws NamingException {
 199         rename(new CompositeName(name), new CompositeName(newName));
 200     }
 201 
 202     public NamingEnumeration<NameClassPair> list(Name name) throws
 203             NamingException {
 204         if (!name.isEmpty()) {
 205             throw (new InvalidNameException(
 206                     "RegistryContext: can only list \"\""));
 207         }
 208         try {
 209             String[] names = registry.list();
 210             return (new NameClassPairEnumeration(names));
 211         } catch (RemoteException e) {
 212             throw (NamingException)wrapRemoteException(e).fillInStackTrace();
 213         }
 214     }
 215 
 216     public NamingEnumeration<NameClassPair> list(String name) throws
 217             NamingException {
 218         return list(new CompositeName(name));
 219     }
 220 
 221     public NamingEnumeration<Binding> listBindings(Name name)
 222             throws NamingException
 223     {
 224         if (!name.isEmpty()) {
 225             throw (new InvalidNameException(
 226                     "RegistryContext: can only list \"\""));
 227         }
 228         try {
 229             String[] names = registry.list();
 230             return (new BindingEnumeration(this, names));
 231         } catch (RemoteException e) {
 232             throw (NamingException)wrapRemoteException(e).fillInStackTrace();
 233         }
 234     }
 235 
 236     public NamingEnumeration<Binding> listBindings(String name) throws
 237             NamingException {
 238         return listBindings(new CompositeName(name));
 239     }
 240 
 241     public void destroySubcontext(Name name) throws NamingException {
 242         throw (new OperationNotSupportedException());
 243     }
 244 
 245     public void destroySubcontext(String name) throws NamingException {
 246         throw (new OperationNotSupportedException());
 247     }
 248 
 249     public Context createSubcontext(Name name) throws NamingException {
 250         throw (new OperationNotSupportedException());
 251     }
 252 
 253     public Context createSubcontext(String name) throws NamingException {
 254         throw (new OperationNotSupportedException());
 255     }
 256 
 257     public Object lookupLink(Name name) throws NamingException {


 280     {
 281         return composeName(new CompositeName(name),
 282                            new CompositeName(prefix)).toString();
 283     }
 284 
 285     public Object removeFromEnvironment(String propName)
 286             throws NamingException
 287     {
 288         return environment.remove(propName);
 289     }
 290 
 291     public Object addToEnvironment(String propName, Object propVal)
 292             throws NamingException
 293     {
 294         if (propName.equals(SECURITY_MGR)) {
 295             installSecurityMgr();
 296         }
 297         return environment.put(propName, propVal);
 298     }
 299 
 300     @SuppressWarnings("unchecked") // clone()
 301     public Hashtable<String, Object> getEnvironment() throws NamingException {
 302         return (Hashtable<String, Object>)environment.clone();
 303     }
 304 
 305     public void close() {
 306         environment = null;
 307         registry = null;
 308         // &&& If we were caching registry connections, we would probably
 309         // uncache this one now.
 310     }
 311 
 312     public String getNameInNamespace() {
 313         return ""; // Registry has an empty name
 314     }
 315 
 316     /**
 317      * Returns an RMI registry reference for this context.
 318      *<p>
 319      * If this context was created from a reference, that reference is
 320      * returned.  Otherwise, an exception is thrown if the registry's
 321      * host is "localhost" or the default (null).  Although this could
 322      * possibly make for a valid reference, it's far more likely to be


 474             throw ne;
 475         }
 476     }
 477 
 478 }
 479 
 480 
 481 /**
 482  * A name parser for case-sensitive atomic names.
 483  */
 484 class AtomicNameParser implements NameParser {
 485     private static final Properties syntax = new Properties();
 486 
 487     public Name parse(String name) throws NamingException {
 488         return (new CompoundName(name, syntax));
 489     }
 490 }
 491 
 492 
 493 /**
 494  * An enumeration of name / class-name pairs.


 495  */
 496 class NameClassPairEnumeration implements NamingEnumeration<NameClassPair> {
 497     private final String[] names;
 498     private int nextName;       // index into "names"
 499 
 500     NameClassPairEnumeration(String[] names) {
 501         this.names = names;
 502         nextName = 0;
 503     }
 504 
 505     public boolean hasMore() {
 506         return (nextName < names.length);
 507     }
 508 
 509     public NameClassPair next() throws NamingException {
 510         if (!hasMore()) {
 511             throw (new java.util.NoSuchElementException());
 512         }
 513         // Convert name to a one-element composite name, so embedded
 514         // meta-characters are properly escaped.
 515         String name = names[nextName++];
 516         Name cname = (new CompositeName()).add(name);
 517         NameClassPair ncp = new NameClassPair(cname.toString(),
 518                                             "java.lang.Object");
 519         ncp.setNameInNamespace(name);
 520         return ncp;
 521     }
 522 
 523     public boolean hasMoreElements() {
 524         return hasMore();
 525     }
 526 
 527     public NameClassPair nextElement() {
 528         try {
 529             return next();
 530         } catch (NamingException e) {   // should never happen
 531             throw (new java.util.NoSuchElementException(
 532                     "javax.naming.NamingException was thrown"));
 533         }
 534     }
 535 
 536     public void close() {
 537         nextName = names.length;
 538     }
 539 }
 540 
 541 
 542 /**
 543  * An enumeration of Bindings.
 544  *
 545  * The actual registry lookups are performed when next() is called.  It would
 546  * be nicer to defer this until the object (or its class name) is actually
 547  * requested.  The problem with that approach is that Binding.getObject()
 548  * cannot throw NamingException.
 549  */
 550 class BindingEnumeration implements NamingEnumeration<Binding> {
 551     private RegistryContext ctx;
 552     private final String[] names;
 553     private int nextName;       // index into "names"
 554 
 555     BindingEnumeration(RegistryContext ctx, String[] names) {
 556         // Clone ctx in case someone closes it before we're through.
 557         this.ctx = new RegistryContext(ctx);
 558         this.names = names;
 559         nextName = 0;
 560     }
 561 
 562     protected void finalize() {
 563         ctx.close();
 564     }
 565 
 566     public boolean hasMore() {
 567         if (nextName >= names.length) {
 568             ctx.close();
 569         }
 570         return (nextName < names.length);
 571     }
 572 
 573     public Binding next() throws NamingException {
 574         if (!hasMore()) {
 575             throw (new java.util.NoSuchElementException());
 576         }
 577         // Convert name to a one-element composite name, so embedded
 578         // meta-characters are properly escaped.
 579         String name = names[nextName++];
 580         Name cname = (new CompositeName()).add(name);
 581 
 582         Object obj = ctx.lookup(cname);
 583         String cnameStr = cname.toString();
 584         Binding binding = new Binding(cnameStr, obj);
 585         binding.setNameInNamespace(cnameStr);
 586         return binding;
 587     }
 588 
 589     public boolean hasMoreElements() {
 590         return hasMore();
 591     }
 592 
 593     public Binding nextElement() {
 594         try {
 595             return next();
 596         } catch (NamingException e) {
 597             throw (new java.util.NoSuchElementException(
 598                     "javax.naming.NamingException was thrown"));
 599         }
 600     }
 601 
 602     public void close () {
 603         finalize();
 604     }
 605 }