All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.iiop.JBossNamingContextImpl Maven / Gradle / Ivy

The newest version!
package org.jboss.iiop;

import java.io.IOException;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import org.jacorb.naming.BindingIteratorImpl;
import org.jacorb.naming.Name;
import org.jboss.logging.Logger;
import org.omg.CORBA.INTERNAL;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.Binding;
import org.omg.CosNaming.BindingIteratorHelper;
import org.omg.CosNaming.BindingIteratorHolder;
import org.omg.CosNaming.BindingListHolder;
import org.omg.CosNaming.BindingType;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextExtPOA;
import org.omg.CosNaming.NamingContextExtPackage.InvalidAddress;
import org.omg.CosNaming.NamingContextPackage.AlreadyBound;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.InvalidName;
import org.omg.CosNaming.NamingContextPackage.NotEmpty;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.CosNaming.NamingContextPackage.NotFoundReason;
import org.omg.PortableServer.POA;

public class JBossNamingContextImpl extends NamingContextExtPOA implements Serializable
{
   
   private static final long serialVersionUID = 132820915998903191L;

   /** the logger used by the naming service implementation. */
   private static final Logger logger = Logger.getLogger(JBossNamingContextImpl.class);

   /** static references to the running ORB and root POA. */
   private static ORB orb;
   private static POA rootPoa;

   /** the naming service POA - i.e. the POA that activates all naming contexts. */
   private transient POA poa;
   
   /** table of all name bindings in this contexts, ie. name -> obj ref. */
   private Map names = new Hashtable();

   /** table of all subordinate naming contexts, ie. name -> obj ref. */
   private Map contexts = new Hashtable();

   /** 
    * cache of all active naming context implementations - used when resolving contexts recursively to avoid
    * unnecessary remote calls that may lead to thread pool depletion.
    */
   private static Map contextImpls = new Hashtable();

   /** no tests of bound objects for existence */
   private boolean noPing = false;

   /** purge? */
   private boolean doPurge = false;

   private boolean destroyed = false;

   private int childCount = 0;

   //======================================= Initialization Methods ==================================//
   
   /**
    * This method needs to be called once to initialize the static fields orb and rootPoa.
    */
   public static void init(org.omg.CORBA.ORB orb, org.omg.PortableServer.POA rootPoa)
   {
      JBossNamingContextImpl.orb = orb;
      JBossNamingContextImpl.rootPoa = rootPoa;
   }

   /**
    * This method needs to be called for each newly created or re-read naming context to set its POA.
    */
   public void init(POA poa, boolean doPurge, boolean noPing)
   {
      this.poa = poa;
      this.doPurge = doPurge;
      this.noPing = noPing;

      /**
       * Recreate tables. For serialization, object references have been
       * transformed into strings
       */
      for (Name key : this.contexts.keySet())
      {
         String ref = (String) this.contexts.remove(key);
         this.contexts.put(key, orb.string_to_object(ref));
      }

      for (Name key : this.names.keySet())
      {
         String ref = (String) this.names.remove(key);
         this.names.put(key, orb.string_to_object(ref));
      }

   }

   //======================================= NamingContextOperation Methods ==================================//
   
   /**
    * Bind a name (an array of name components) to an object.
    */
   public void bind(NameComponent[] nc, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, InvalidName,
         AlreadyBound
   {
      if (this.destroyed)
         throw new CannotProceed();

      if (nc == null || nc.length == 0)
         throw new InvalidName();

      if (obj == null)
         throw new org.omg.CORBA.BAD_PARAM();

      Name n = new Name(nc);
      Name ctx = n.ctxName();
      NameComponent nb = n.baseNameComponent();

      if (ctx == null)
      {
         if (this.names.containsKey(n))
         {
            // if the name is still in use, try to ping the object
            org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.names.get(n);
            if (isDead(ref))
            {
               rebind(n.components(), obj);
               return;
            }
            throw new AlreadyBound();
         }
         else if (this.contexts.containsKey(n))
         {
            // if the name is still in use, try to ping the object
            org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.contexts.get(n);
            if (isDead(ref))
               unbind(n.components());
            throw new AlreadyBound();
         }

         if ((this.names.put(n, obj)) != null)
            throw new CannotProceed(_this(), n.components());

         logger.debugf("Bound name: " + n.toString());
      }
      else
      {
         NameComponent[] ncx = new NameComponent[] {nb};
         org.omg.CORBA.Object context = this.resolve(ctx.components());
       
         // try first to call the context implementation object directly.
         String contextOID = this.getObjectOID(context);
         JBossNamingContextImpl jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
         if (jbossContext != null)
            jbossContext.bind(ncx, obj);
         else
            NamingContextExtHelper.narrow(context).bind(ncx, obj);
      }
   }

   /**
    * Bind a context to a name.
    */
   public void bind_context(NameComponent[] nc, NamingContext obj) throws NotFound, CannotProceed, InvalidName,
         AlreadyBound
   {
      if (this.destroyed)
         throw new CannotProceed();

      Name n = new Name(nc);
      Name ctx = n.ctxName();
      NameComponent nb = n.baseNameComponent();

      if (ctx == null)
      {
         if (this.names.containsKey(n))
         {
            // if the name is still in use, try to ping the object
            org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.names.get(n);
            if (isDead(ref))
               unbind(n.components());
            else
               throw new AlreadyBound();
         }
         else if (this.contexts.containsKey(n))
         {
            // if the name is still in use, try to ping the object
            org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.contexts.get(n);
            if (isDead(ref))
            {
               rebind_context(n.components(), obj);
               return;
            }
            throw new AlreadyBound();
         }

         if ((this.contexts.put(n, obj)) != null)
            throw new CannotProceed(_this(), n.components());

         logger.debugf("Bound context: " + n.toString());
      }
      else
      {
         NameComponent[] ncx = new NameComponent[] {nb};
         org.omg.CORBA.Object context = this.resolve(ctx.components());
         
         // try first to call the context implementation object directly.
         String contextOID = this.getObjectOID(context);
         JBossNamingContextImpl jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
         if (jbossContext != null)
            jbossContext.bind_context(ncx, obj);
         else
            NamingContextExtHelper.narrow(context).bind_context(ncx, obj);
      }
   }

   public NamingContext bind_new_context(NameComponent[] nc) throws NotFound, CannotProceed, InvalidName, AlreadyBound
   {
      if (this.destroyed)
         throw new CannotProceed();

      if (nc == null || nc.length == 0)
         throw new InvalidName();

      NamingContext context = new_context();
      if (context == null)
         throw new CannotProceed();

      bind_context(nc, context);
      return context;
   }

   public void destroy() throws NotEmpty
   {
      if (this.destroyed)
         return;

      if (!this.names.isEmpty() || !this.contexts.isEmpty())
         throw new NotEmpty();
      else
      {
         this.names = null;
         this.contexts = null;
         this.destroyed = true;
      }
   }

   /**
    * List all bindings
    */
   public void list(int how_many, BindingListHolder bl, BindingIteratorHolder bi)
   {
      if (this.destroyed)
         return;

      Binding[] result;
      this.cleanup();

      int size = how_many();

      Iterator names = this.names.keySet().iterator();
      Iterator contexts = this.contexts.keySet().iterator();

      if (how_many < size)
      {
         // counter for copies
         int how_many_ctr = how_many;

         // set up an array with "how_many" bindings
         result = new Binding[how_many];
         for (; names.hasNext() && how_many_ctr > 0; how_many_ctr--)
            result[how_many_ctr - 1] = new Binding((names.next()).components(), BindingType.nobject);

         for (; contexts.hasNext() && how_many_ctr > 0; how_many_ctr--)
            result[how_many_ctr - 1] = new Binding((contexts.next()).components(), BindingType.ncontext);

         // create a new BindingIterator for the remaining arrays
         size -= how_many;
         Binding[] rest = new Binding[size];
         for (; names.hasNext() && size > 0; size--)
            rest[size - 1] = new Binding(((Name) names.next()).components(), BindingType.nobject);

         for (; contexts.hasNext() && size > 0; size--)
            rest[size - 1] = new Binding(((Name) contexts.next()).components(), BindingType.ncontext);

         org.omg.CORBA.Object o = null;
         try
         {
            // Iterators are activated with the RootPOA (transient)
            byte[] oid = rootPoa.activate_object(new BindingIteratorImpl(rest));
            o = rootPoa.id_to_reference(oid);
         }
         catch (Exception e)
         {
            logger.errorf("unexpected exception", e);
            throw new INTERNAL(e.toString());
         }

         bi.value = BindingIteratorHelper.narrow(o);
      }
      else
      {
         result = new Binding[size];
         for (; names.hasNext() && size > 0; size--)
            result[size - 1] = new Binding((names.next()).components(), BindingType.nobject);

         for (; contexts.hasNext() && size > 0; size--)
            result[size - 1] = new Binding((contexts.next()).components(), BindingType.ncontext);
      }

      bl.value = result;
   }

   public NamingContext new_context()
   {
      try
      {
         // create and initialize a new context.
         JBossNamingContextImpl newContextImpl = new JBossNamingContextImpl();
         newContextImpl.init(this.poa, this.doPurge, this.noPing);
         // create the oid for the new context and activate it with the naming service POA.
         String oid = new String(this.poa.servant_to_id(this) + "/ctx" + (++this.childCount));
         this.poa.activate_object_with_id(oid.getBytes(), newContextImpl);
         // add the newly-created context to the cache.
         contextImpls.put(oid, newContextImpl);
         return NamingContextExtHelper.narrow(this.poa.create_reference_with_id(oid.getBytes(),
               "IDL:omg.org/CosNaming/NamingContextExt:1.0"));
      }
      catch (Exception e)
      {
         logger.errorf("Cannot create CORBA naming context", e);
         return null;
      }
   }

   /**
    * Bind an object to a name that's already in use, i.e. rebind the name.
    */
   public void rebind(NameComponent[] nc, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, InvalidName
   {
      if (this.destroyed)
         throw new CannotProceed();

      if (nc == null || nc.length == 0)
         throw new InvalidName();

      if (obj == null)
         throw new org.omg.CORBA.BAD_PARAM();

      Name n = new Name(nc);
      Name ctx = n.ctxName();
      NameComponent nb = n.baseNameComponent();

      if (ctx == null)
      {
         // the name is bound, but it is bound to a context - the client should have been using rebind_context!
         if (this.contexts.containsKey(n))
            throw new NotFound(NotFoundReason.not_object, new NameComponent[]{nb});

         // try remove an existing binding.
         org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.names.remove(n);
         if (ref != null)
            ref._release();

         // do the rebinding in this context
         this.names.put(n, obj);
         logger.debugf("re-Bound name: " + n.toString());
      }
      else
      {
         // rebind in the correct context
         NameComponent[] ncx = new NameComponent[] {nb};
         org.omg.CORBA.Object context = this.resolve(ctx.components());
         
         // try first to call the context implementation object directly.
         String contextOID = this.getObjectOID(context);
         JBossNamingContextImpl jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
         if (jbossContext != null)
            jbossContext.rebind(ncx, obj);
         else
            NamingContextExtHelper.narrow(context).rebind(ncx, obj);
      }
   }

   /**
    * Bind an context to a name that's already in use, i.e. rebind the name.
    */
   public void rebind_context(NameComponent[] nc, NamingContext obj) throws NotFound, CannotProceed, InvalidName
   {
      if (this.destroyed)
         throw new CannotProceed();

      if (nc == null || nc.length == 0)
         throw new InvalidName();

      if (obj == null)
         throw new org.omg.CORBA.BAD_PARAM();

      Name n = new Name(nc);
      Name ctx = n.ctxName();
      NameComponent nb = n.baseNameComponent();

      if (ctx == null)
      {
         // the name is bound, but it is bound to an object - the client should have been using rebind().
         if (this.names.containsKey(n))
            throw new NotFound(NotFoundReason.not_context, new NameComponent[] {nb});
   
         // try to remove an existing context binding.
         org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.contexts.remove(n);
         if (ref != null)
         {
            ref._release();
            // remove the old context from the implementation cache.
            String oid = this.getObjectOID(ref);
            if (oid != null)
               contextImpls.remove(oid);
         }

         this.contexts.put(n, obj);
         logger.debugf("Re-Bound context: " + n.baseNameComponent().id);
      }
      else
      {
         // rebind in the correct context
         NameComponent[] ncx = new NameComponent[] {nb};
         org.omg.CORBA.Object context = this.resolve(ctx.components());
         
         // try first to call the context implementation object directly.
         String contextOID = this.getObjectOID(context);
         JBossNamingContextImpl jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
         if (jbossContext != null)
            jbossContext.rebind_context(ncx, obj);
         else
            NamingContextExtHelper.narrow(context).rebind_context(ncx, obj);
      }
   }

   public org.omg.CORBA.Object resolve(NameComponent[] nc) throws NotFound, CannotProceed, InvalidName
   {
      if (this.destroyed)
         throw new CannotProceed();

      if (nc == null || nc.length == 0)
         throw new InvalidName();

      Name n = new Name(nc[0]);
      if (nc.length > 1)
      {
         org.omg.CORBA.Object next_context = (org.omg.CORBA.Object) this.contexts.get(n);
         if ((next_context == null) || (isDead(next_context)))
            throw new NotFound(NotFoundReason.missing_node, nc);

         NameComponent[] nc_prime = new NameComponent[nc.length - 1];
         for (int i = 1; i < nc.length; i++)
            nc_prime[i - 1] = nc[i];

         // try first to call the context implementation object directly.
         String contextOID = this.getObjectOID(next_context);
         JBossNamingContextImpl jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
         if (jbossContext != null)
            return jbossContext.resolve(nc_prime);
         else
            return NamingContextExtHelper.narrow(next_context).resolve(nc_prime);
      }
      else
      {
         org.omg.CORBA.Object result = (org.omg.CORBA.Object) this.contexts.get(n);

         if (result == null)
            result = (org.omg.CORBA.Object) this.names.get(n);

         if (result == null)
            throw new NotFound(NotFoundReason.missing_node, n.components());

         if (!noPing && isDead(result))
            throw new NotFound(NotFoundReason.missing_node, n.components());

         return result;
      }
   }

   /**
    * Unbind a name
    */
   public void unbind(NameComponent[] nc) throws NotFound, CannotProceed, InvalidName
   {
      if (this.destroyed)
         throw new CannotProceed();

      if (nc == null || nc.length == 0)
         throw new InvalidName();

      Name n = new Name(nc);
      Name ctx = n.ctxName();
      NameComponent nb = n.baseNameComponent();

      if (ctx == null)
      {
         if (this.names.containsKey(n))
         {
            org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.names.remove(n);
            ref._release();
            logger.debugf("Unbound: " + n.toString());
         }
         else if (this.contexts.containsKey(n))
         {
            org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.contexts.remove(n);
            ref._release();
            // remove the context from the implementation cache.
            String oid = this.getObjectOID(ref);
            if (oid != null)
               contextImpls.remove(oid);

            logger.debugf("Unbound: " + n.toString());
         }
         else
         {
            logger.warnf("Unbind failed for " + n.toString());
            throw new NotFound(NotFoundReason.not_context, n.components());
         }
      }
      else
      {
         NameComponent[] ncx = new NameComponent[] {nb};
         org.omg.CORBA.Object context = this.resolve(ctx.components());
         
         // try first to call the context implementation object directly.
         String contextOID = this.getObjectOID(context);
         JBossNamingContextImpl jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
         if (jbossContext != null)
            jbossContext.unbind(ncx);
         else
            NamingContextExtHelper.narrow(context).unbind(ncx);
      }
   }

   //======================================= NamingContextExtOperations Methods ==================================//

   public org.omg.CORBA.Object resolve_str(String n) throws NotFound, CannotProceed, InvalidName
   {
      return resolve(to_name(n));
   }
   
   /**
    * Convert a string into name
    * 
    * @throws InvalidName
    */
   public NameComponent[] to_name(String sn) throws InvalidName
   {
      return Name.toName(sn);
   }

   /**
    * Convert a name into its string representation
    */
   public String to_string(NameComponent[] n) throws InvalidName
   {
      return Name.toString(n);
   }

   /**
    * Convert a name into its URL representation.
    */
   public String to_url(String addr, String sn) throws InvalidAddress, InvalidName
   {
      org.jacorb.orb.util.CorbaLoc corbaLoc;
      try
      {
         corbaLoc = new org.jacorb.orb.util.CorbaLoc((org.jacorb.orb.ORB) orb, addr);
         return corbaLoc.toCorbaName(sn);
      }
      catch (IllegalArgumentException ia)
      {
         throw new InvalidAddress();
      }
   }

   //======================================= Private Helper Methods ==================================//

   /**
    * cleanup bindings, i.e. ping every object and remove bindings to non-existent objects
    */
   private void cleanup()
   {
      // Check if object purging enabled
      if (!this.doPurge)
         return;

      for (Name key : this.names.keySet())
      {
         if (isDead(((org.omg.CORBA.Object) this.names.get(key))))
         {
            logger.debugf("Removing name " + key.baseNameComponent().id);
            this.names.remove(key);
         }
      }

      for (Name key : this.contexts.keySet())
      {
         org.omg.CORBA.Object object = (org.omg.CORBA.Object) this.contexts.get(key);
         if (isDead(object))
         {
            logger.debugf("Removing context " + key.baseNameComponent().id);
            this.contexts.remove(key);
            String oid = this.getObjectOID(object);
            if (oid != null)
               contextImpls.remove(oid);
         }
      }
   }

   /**
    * 

* Obtains the OID of the specified CORBA object. *

* * @param object the CORBA object whose OID is to be extracted. * @return a {@code String} representing the object OID or null if the method is unable to obtain the object OID. */ private String getObjectOID(org.omg.CORBA.Object object) { String oid = null; try { byte[] oidBytes = this.poa.reference_to_id(object); if (oidBytes != null) oid = new String(oidBytes); } catch (Exception e) { logger.debugf("Unable to obtain oid from object", e); } return oid; } /** * @return The number of bindings in this context */ private int how_many() { if (this.destroyed) return 0; return this.names.size() + this.contexts.size(); } /** * determine if non_existent */ private boolean isDead(org.omg.CORBA.Object o) { boolean non_exist = true; try { non_exist = o._non_existent(); } catch (org.omg.CORBA.SystemException e) { non_exist = true; } return non_exist; } /** * Overrides writeObject in Serializable */ private void writeObject(java.io.ObjectOutputStream out) throws IOException { /* * For serialization, object references are transformed into strings */ for (Name key : this.contexts.keySet()) { org.omg.CORBA.Object o = (org.omg.CORBA.Object) this.contexts.remove(key); this.contexts.put(key, orb.object_to_string(o)); } for (Name key : this.names.keySet()) { org.omg.CORBA.Object o = (org.omg.CORBA.Object) this.names.remove(key); this.names.put(key, orb.object_to_string(o)); } out.defaultWriteObject(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy