Package org.jnp.server

Source Code of org.jnp.server.NamingServer

/*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, JBoss Inc., and individual contributors as indicated
  * by the @authors tag. See the copyright.txt in the distribution for a
  * full listing of individual contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software 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
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
package org.jnp.server;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.naming.Binding;
import javax.naming.CannotProceedException;
import javax.naming.Context;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameClassPair;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.naming.NotContextException;
import javax.naming.Reference;
import javax.naming.event.EventContext;
import javax.naming.event.NamingEvent;
import javax.naming.event.NamingListener;
import javax.naming.spi.ResolveResult;

import org.jboss.logging.Logger;
import org.jboss.naming.JndiPermission;
import org.jnp.interfaces.Naming;
import org.jnp.interfaces.NamingContext;
import org.jnp.interfaces.NamingEvents;
import org.jnp.interfaces.NamingParser;

/**
* The in memory JNDI naming server implementation class.
*
* @author Rickard Oberg
* @author patriot1burke
* @author Scott.Stark@jboss.org
* @version $Revision: 80569 $
*/
public class NamingServer
   implements Naming, NamingEvents, java.io.Serializable
{
   private static Logger log = Logger.getLogger(NamingServer.class);

   /** @since 1.12 at least */
   private static final long serialVersionUID = 4183855539507934373L;
   // Constants -----------------------------------------------------

   // Attributes ----------------------------------------------------
   /** */
   protected Map<String, Binding> table = createTable();
   protected Name prefix;
   protected NamingParser parser = new NamingParser();
   protected NamingServer parent;
   /** The NamingListeners registered with this context */
   private transient EventListeners listeners;
   /** The manager for EventContext listeners */
   private transient EventMgr eventMgr;
   private transient SecurityManager secMgr;
   private transient boolean trace;

   // Static --------------------------------------------------------

   // Constructors --------------------------------------------------

   public NamingServer()
      throws NamingException
   {
      this(null, null);
   }
  
   public NamingServer(Name prefix, NamingServer parent)
      throws NamingException
   {
      this(prefix, parent, null);  
   }
   public NamingServer(Name prefix, NamingServer parent, EventMgr eventMgr)
      throws NamingException
   {
      this(prefix, parent, eventMgr, null)
   }
   public NamingServer(Name prefix, NamingServer parent, EventMgr eventMgr,
         SecurityManager secMgr)
      throws NamingException
   {
      if (prefix == null)
         prefix = parser.parse("");
      this.prefix = prefix;     
      this.parent = parent;
      this.eventMgr = eventMgr;
      this.secMgr = secMgr;
      this.trace = log.isTraceEnabled();
   }

   // Public --------------------------------------------------------

   // NamingListener registration
   public synchronized void addNamingListener(EventContext context, Name target, int scope, NamingListener l)
      throws NamingException
   {
      if(listeners == null)
         listeners = new EventListeners(context);
      if(trace)
         log.trace("addNamingListener, target: "+target+", scope: "+scope);
      listeners.addNamingListener(context, target, scope, l);
   }

   public void removeNamingListener(NamingListener l) throws NamingException
   {
      if(listeners != null)
      {
         listeners.removeNamingListener(l);
      }
   }

    /**
     * We don't need targets to exist?
     * @return false
     * @throws NamingException
     */
    public boolean targetMustExist() throws NamingException
    {
       return false;
    }

   // Naming implementation -----------------------------------------
   public synchronized void bind(Name name, Object obj, String className)
      throws NamingException
   {
      if (name.isEmpty())
      {
         // Empty names are not allowed
         throw new InvalidNameException("An empty name cannot be passed to bind");
      }
      else if (name.size() > 1)
      {
         // Recurse to find correct context
//         System.out.println("bind#"+name+"#");
        
         Object ctx = getObject(name);
         if (ctx != null)
         {
            if (ctx instanceof NamingServer)
            {
               NamingServer ns = (NamingServer) ctx;
               ns.bind(name.getSuffix(1),obj, className);
            }
            else if (ctx instanceof Reference)
            {
               // Federation
               if (((Reference)ctx).get("nns") != null)
               {
                  CannotProceedException cpe = new CannotProceedException();
                  cpe.setResolvedObj(ctx);
                  cpe.setRemainingName(name.getSuffix(1));
                  throw cpe;
               }
               else
               {
                  throw new NotContextException();
               }
            }
            else
            {
               throw new NotContextException();
            }
         }
         else
         {
            throw new NameNotFoundException(name.toString()+" in: "+prefix);
         }
      }
      else
      {
         // Bind object
         if (name.get(0).equals(""))
         {
            throw new InvalidNameException("An empty name cannot be passed to bind");
         }
         else
         {
            if(trace)
               log.trace("bind "+name+"="+obj+", "+className);
            try
            {
               getBinding(name);
               // Already bound
               throw new NameAlreadyBoundException(name.toString());
            }
            catch (NameNotFoundException e)
            {
               Name fullName = (Name) prefix.clone();
               fullName.addAll(name);
               SecurityManager sm = getSecurityManager();
               if(sm != null)
               {
                  JndiPermission perm = new JndiPermission(fullName, JndiPermission.BIND);
                  sm.checkPermission(perm);
               }

               Binding newb = setBinding(name,obj,className);
               // Notify event listeners
               Binding oldb = null;
               this.fireEvent(fullName, oldb, newb, NamingEvent.OBJECT_ADDED, "bind");
            }
         }
      }
   }

   public synchronized void rebind(Name name, Object obj, String className)
      throws NamingException
   {
      if (name.isEmpty())
      {
         // Empty names are not allowed
         throw new InvalidNameException("An empty name cannot be passed to rebind");
      }
      else if (name.size() > 1)
      {
         // Recurse to find correct context
//         System.out.println("rebind#"+name+"#");
        
         Object ctx = getObject(name);
         if (ctx instanceof NamingServer)
         {
            ((NamingServer)ctx).rebind(name.getSuffix(1),obj, className);
         }
         else if (ctx instanceof Reference)
         {
            // Federation
            if (((Reference)ctx).get("nns") != null)
            {
               CannotProceedException cpe = new CannotProceedException();
               cpe.setResolvedObj(ctx);
               cpe.setRemainingName(name.getSuffix(1));
               throw cpe;
            }
            else
            {
               throw new NotContextException();
            }
         }
         else
         {
            throw new NotContextException();
         }
      }
      else
      {
         // Bind object
         if (name.get(0).equals(""))
         {
            throw new InvalidNameException("An empty name cannot be passed to rebind");
         }
         else
         {
            SecurityManager sm = getSecurityManager();
            Name fullName = (Name) prefix.clone();
            String comp = name.get(0);
            fullName.add(comp);
            if(sm != null)
            {
               JndiPermission perm = new JndiPermission(fullName, JndiPermission.REBIND);
               sm.checkPermission(perm);
            }
           
            Binding oldb = table.get(comp);
            Binding newb = setBinding(name,obj,className);
            // Notify event listeners
            if(listeners != null)
            {
               int type = NamingEvent.OBJECT_CHANGED;
               if(oldb == null)
                  type = NamingEvent.OBJECT_ADDED;
               this.fireEvent(fullName, oldb, newb, type, "rebind");
            }
         }
      }
   }
  
   public synchronized void unbind(Name name)
      throws NamingException
   {
      if (name.isEmpty())
      {
         // Empty names are not allowed
         throw new InvalidNameException();
      }
      else if (name.size() > 1)
      {
         // Recurse to find correct context
//         System.out.println("unbind#"+name+"#");
        
         Object ctx = getObject(name);
         if (ctx instanceof NamingServer)
         {
            ((NamingServer)ctx).unbind(name.getSuffix(1));
         }
         else if (ctx instanceof Reference)
         {
            // Federation
            if (((Reference)ctx).get("nns") != null)
            {
               CannotProceedException cpe = new CannotProceedException();
               cpe.setResolvedObj(ctx);
               cpe.setRemainingName(name.getSuffix(1));
               throw cpe;
            }
            else
            {
               throw new NotContextException();
            }
         }
         else
         {
            throw new NotContextException();
         }
      } else
      {
         // Unbind object
         if (name.get(0).equals(""))
         {
            throw new InvalidNameException();
         }
         else
         {
//            System.out.println("unbind "+name+"="+getBinding(name));
            if (getBinding(name) != null)
            {
               SecurityManager sm = getSecurityManager();
               Name fullName = (Name) prefix.clone();
               fullName.addAll(name);
               if(sm != null)
               {
                  JndiPermission perm = new JndiPermission(fullName, JndiPermission.UNBIND);
                  sm.checkPermission(perm);
               }
              
               Binding newb = null;
               Binding oldb = removeBinding(name);
               // Notify event listeners
               int type = NamingEvent.OBJECT_REMOVED;
               this.fireEvent(fullName, oldb, newb, type, "unbind");
            }
            else
            {
               throw new NameNotFoundException();
            }
         }
      }
   }

//   public synchronized Object lookup(Name name)
   public Object lookup(Name name)
      throws NamingException
   {
    Object result;
      if (name.isEmpty())
      {
         SecurityManager sm = getSecurityManager();
         if(sm != null)
         {
            JndiPermission perm = new JndiPermission(prefix, JndiPermission.LOOKUP);
            sm.checkPermission(perm);
         }
        
         // Return this
         result = new NamingContext(null, (Name)(prefix.clone()), getRoot());
      }
      else if (name.size() > 1)
      {
         // Recurse to find correct context
//         System.out.println("lookup#"+name+"#");
        
         Object ctx = getObject(name);
         if (ctx instanceof NamingServer)
         {
            result = ((NamingServer)ctx).lookup(name.getSuffix(1));
         }
         else if (ctx instanceof Reference)
         {
            // Federation
            if (((Reference)ctx).get("nns") != null)
            {
               CannotProceedException cpe = new CannotProceedException();
               cpe.setResolvedObj(ctx);
               cpe.setRemainingName(name.getSuffix(1));
               throw cpe;
            }
           
            result = new ResolveResult(ctx, name.getSuffix(1));
         } else
         {
            throw new NotContextException();
         }
      }
      else
      {
         // Get object to return
         if (name.get(0).equals(""))
         {
            SecurityManager sm = getSecurityManager();
            if(sm != null)
            {
               JndiPermission perm = new JndiPermission(prefix, JndiPermission.LOOKUP);
               sm.checkPermission(perm);
            }
            result = new NamingContext(null, (Name)(prefix.clone()), getRoot());
         }
         else
         {
//            System.out.println("lookup "+name);
            SecurityManager sm = getSecurityManager();
            Name fullName = (Name)(prefix.clone());
            fullName.addAll(name);
            if(sm != null)
            {
               JndiPermission perm = new JndiPermission(fullName, JndiPermission.LOOKUP);
               sm.checkPermission(perm);
            }
           
            Object res = getObject(name);
           
            if (res instanceof NamingServer)
            {
               result = new NamingContext(null, fullName, getRoot());
            }
            else
               result = res;
         }
      }
   
    return result;
   }
  
   public Collection<NameClassPair> list(Name name)
      throws NamingException
   {
      if (name.isEmpty())
      {
         SecurityManager sm = getSecurityManager();
         if(sm != null)
         {
            JndiPermission perm = new JndiPermission(prefix, JndiPermission.LIST);
            sm.checkPermission(perm);
         }

         ArrayList<NameClassPair> list = new ArrayList<NameClassPair>();
         for(Binding b : table.values())
         {
            NameClassPair ncp = new NameClassPair(b.getName(),b.getClassName(), true);
            list.add(ncp);
         }
         return list;
      }
      else
     
         Object ctx = getObject(name);
         if (ctx instanceof NamingServer)
         {
            return ((NamingServer)ctx).list(name.getSuffix(1));
         }
         else if (ctx instanceof Reference)
         {
            // Federation
            if (((Reference)ctx).get("nns") != null)
            {
               CannotProceedException cpe = new CannotProceedException();
               cpe.setResolvedObj(ctx);
               cpe.setRemainingName(name.getSuffix(1));
               throw cpe;
            }
            else
            {
               throw new NotContextException();
            }
         }
         else
         {
            throw new NotContextException();
         }
      }
   }
   
   public Collection<Binding> listBindings(Name name)
      throws NamingException
   {
      if (name.isEmpty())
      {
         SecurityManager sm = getSecurityManager();
         if(sm != null)
         {
            JndiPermission perm = new JndiPermission(prefix, JndiPermission.LIST_BINDINGS);
            sm.checkPermission(perm);
         }

         Collection<Binding> bindings = table.values();
         Collection<Binding> newBindings = new ArrayList<Binding>(bindings.size());
         for(Binding b : bindings)
         {
            if (b.getObject() instanceof NamingServer)
            {
               Name n = (Name)prefix.clone();
               n.add(b.getName());
               newBindings.add(new Binding(b.getName(),
                                           b.getClassName(),
                                           new NamingContext(null, n, getRoot())));
            }
            else
            {
               newBindings.add(b);
            }
         }
        
         return newBindings;
      } else
      {
         Object ctx = getObject(name);
         if (ctx instanceof NamingServer)
         {
            return ((NamingServer)ctx).listBindings(name.getSuffix(1));
         } else if (ctx instanceof Reference)
         {
            // Federation
            if (((Reference)ctx).get("nns") != null)
            {
               CannotProceedException cpe = new CannotProceedException();
               cpe.setResolvedObj(ctx);
               cpe.setRemainingName(name.getSuffix(1));
               throw cpe;
            } else
            {
               throw new NotContextException();
            }
         } else
         {
            throw new NotContextException();
         }
      }
   }
  
   public Context createSubcontext(Name name)
      throws NamingException
   {
       if( name.size() == 0 )
          throw new InvalidNameException("Cannot pass an empty name to createSubcontext");

      NamingException ex = null;
      Context subCtx = null;
      if (name.size() > 1)
      {        
         Object ctx = getObject(name);
         if (ctx != null)
         {
            Name subCtxName = name.getSuffix(1);
            if (ctx instanceof NamingServer)
            {
               subCtx = ((NamingServer)ctx).createSubcontext(subCtxName);
            }
            else if (ctx instanceof Reference)
            {
               // Federation
               if (((Reference)ctx).get("nns") != null)
               {
                  CannotProceedException cpe = new CannotProceedException();
                  cpe.setResolvedObj(ctx);
                  cpe.setRemainingName(subCtxName);
                  throw cpe;
               }
               else
               {
                  ex = new NotContextException();
                  ex.setResolvedName(name.getPrefix(0));
                  ex.setRemainingName(subCtxName);
                  throw ex;
               }
            }
            else
            {
               ex = new NotContextException();
               ex.setResolvedName(name.getPrefix(0));
               ex.setRemainingName(subCtxName);
               throw ex;
            }
         }
         else
         {
            ex = new NameNotFoundException();
            ex.setRemainingName(name);
            throw ex;
         }
      }
      else
      {
         Object binding = table.get(name.get(0));
         if( binding != null )
         {
            ex = new NameAlreadyBoundException();
            ex.setResolvedName(prefix);
            ex.setRemainingName(name);
            throw ex;
         }
         else
         {
            Name fullName = (Name) prefix.clone();
            fullName.addAll(name);
            SecurityManager sm = getSecurityManager();
            if(sm != null)
            {
               JndiPermission perm = new JndiPermission(fullName, JndiPermission.CREATE_SUBCONTEXT);
               sm.checkPermission(perm);
            }
            NamingServer subContext = createNamingServer(fullName, this);
            subCtx = new NamingContext(null, fullName, getRoot());
            setBinding(name, subContext, NamingContext.class.getName());
            // Return the NamingContext as the binding value
            Binding newb = new Binding(name.toString(), NamingContext.class.getName(), subCtx, true);
            // Notify event listeners
            if(listeners != null)
            {
               Binding oldb = null;
               this.fireEvent(fullName, oldb, newb, NamingEvent.OBJECT_ADDED, "createSubcontext");
            }
         }
      }
      return subCtx;
   }

   public Naming getRoot()
   {
      if (parent == null)
         return this;
      else
         return parent.getRoot();
   }

   // Y overrides ---------------------------------------------------

   // Package protected ---------------------------------------------
   
   // Protected -----------------------------------------------------

   protected Map<String, Binding> createTable()
   {
      return new ConcurrentHashMap<String, Binding>()
   }

   /**
    * Create sub naming.
    *
    * @param prefix the prefix
    * @param parent the parent naming server
    * @return new sub instance
    * @throws NamingException for any error
    */
   protected NamingServer createNamingServer(Name prefix, NamingServer parent)
      throws NamingException
   {
      return new NamingServer(prefix, parent, eventMgr);
   }

   protected void fireEvent(Name fullName, Binding oldb, Binding newb, int type,
         String changeInfo)
      throws NamingException
   {
      if(eventMgr == null)
      {
         if(trace)
            log.trace("Skipping event dispatch because there is no EventMgr");
         return;
      }

      if(listeners != null)
      {
         if(trace)
            log.trace("fireEvent, type: "+type+", fullName: "+fullName);
         HashSet<Integer> scopes = new HashSet<Integer>();
         scopes.add(EventContext.OBJECT_SCOPE);
         scopes.add(EventContext.ONELEVEL_SCOPE);
         scopes.add(EventContext.SUBTREE_SCOPE);
         eventMgr.fireEvent(fullName, oldb, newb, type, changeInfo, listeners, scopes);
      }
      else if(trace)
      {
         log.trace("fireEvent, type: "+type+", fullName: "+fullName);
      }
      // Traverse to parent for SUBTREE_SCOPE
      HashSet<Integer> scopes = new HashSet<Integer>();
      scopes.add(EventContext.SUBTREE_SCOPE);
      NamingServer nsparent = parent;
      while(nsparent != null)
      {
         if(nsparent.listeners != null)
         {
            eventMgr.fireEvent(fullName, oldb, newb, type, changeInfo, nsparent.listeners, scopes);
         }
         nsparent = nsparent.parent;
      }
   }

   // Private -------------------------------------------------------

   private Binding setBinding(Name name, Object obj, String className)
   {
      String n = name.toString();
      Binding b = new Binding(n, className, obj, true);
      table.put(n, b);
      if( trace )
      {
         StringBuffer tmp = new StringBuffer(super.toString());
         tmp.append(", setBinding: name=");
         tmp.append(name);
         tmp.append(", obj=");
         tmp.append(obj);
         tmp.append(", className=");
         tmp.append(className);
         log.trace(tmp.toString());
      }
      return b;
   }

   private Binding getBinding(String key)
      throws NameNotFoundException
   {
      Binding b = table.get(key);
      if (b == null)
      {
         if( log.isTraceEnabled() )
         {
            StringBuffer tmp = new StringBuffer(super.toString());
            tmp.append(", No binding for: ");
            tmp.append(key);
            tmp.append(" in context ");
            tmp.append(this.prefix);
            tmp.append(", bindings:\n");
            Iterator<Binding> bindings = table.values().iterator();
            while( bindings.hasNext() )
            {
               Binding value = bindings.next();
               tmp.append(value.getName());
               tmp.append('=');
               if( value.getObject() != null )
                  tmp.append(value.getObject().toString());
               else
                  tmp.append("null");
               tmp.append('\n');
            }
            log.trace(tmp.toString());
         }
         throw new NameNotFoundException(key + " not bound");
      }
      return b;
   }

   private Binding getBinding(Name key)
      throws NameNotFoundException
   {
      return getBinding(key.get(0));
   }
  
   private Object getObject(Name key)
      throws NameNotFoundException
   {
      return getBinding(key).getObject();
   }

   private Binding removeBinding(Name name)
   {
      return table.remove(name.get(0));
   }

   private SecurityManager getSecurityManager()
   {
      if(secMgr == null)
         secMgr = System.getSecurityManager();
      return secMgr;
   }
}
TOP

Related Classes of org.jnp.server.NamingServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.