/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file 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.jboss.test.security.ejb.project.support; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import javax.naming.Binding; import javax.naming.CompositeName; import javax.naming.Context; import javax.naming.InvalidNameException; import javax.naming.Name; import javax.naming.NameAlreadyBoundException; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.NameNotFoundException; import javax.naming.NameParser; import javax.naming.NotContextException; import javax.naming.OperationNotSupportedException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; /** A simple in memory implementation of DirContext that uses a HashMap as the store and unix style path names. @author Scott_Stark@displayscape.com @version $Id: HeirMemoryMap.java 81036 2008-11-14 13:36:39Z dimitris@jboss.org $ */ public class HeirMemoryMap extends DirContextStringImpl implements DirContext, Serializable { private static NameParser nameParser = DefaultName.getNameParser(); private HashMap bindings = new HashMap(); private HashMap bindingAttrs = new HashMap(); private HeirMemoryMap parent; private String contextName; private Hashtable env; /** Creates new HeirMemoryMap */ public HeirMemoryMap() { this.contextName = ""; } public HeirMemoryMap(String contextName, HeirMemoryMap parent, Attributes attributes) throws NamingException { this(contextName, parent, attributes, null); } public HeirMemoryMap(String contextName, HeirMemoryMap parent, Attributes attributes, Hashtable env) throws NamingException { this.contextName = contextName == null ? "" : contextName; this.parent = parent; bindingAttrs.put("", attributes.clone()); if( parent != null ) parent.bind(contextName, this); this.env = env; } public String toString() { Name name = null; try { name = getFullName(); } catch(NamingException e) { } return name.toString(); } String getName() { return contextName; } void setName(String contextName) { this.contextName = contextName; } Name getFullName() throws NamingException { CompositeName name = new CompositeName(getName()); HeirMemoryMap context = parent; if( context == null ) return name; try { while( context.parent != null ) { name.add(0, context.getName()); context = context.parent; } } catch(NamingException e) { } return name; } // --- public Object addToEnvironment(String p1,Object p2) throws NamingException { return null; } public Object removeFromEnvironment(String p1) throws NamingException { return null; } public void bind(Name name, Object value) throws NamingException { bind(name, value, null); } public void bind(Name name, Object value, Attributes attributes) throws NamingException { if( name.isEmpty() ) { throw new InvalidNameException("Cannot bind empty name"); } internalBind(name, value, attributes, true); } public void close() throws NamingException { } public Name composeName(Name p1,Name p2) throws NamingException { return null; } public Context createSubcontext(Name name) throws NamingException { return createSubcontext(name, null); } public DirContext createSubcontext(Name name, Attributes attributes) throws NamingException { if( name.isEmpty() ) { throw new InvalidNameException("Cannot createSubcontext with empty name"); } DirContext subctx = null; String atom = name.get(0); if( name.size() == 1 ) { subctx = new HeirMemoryMap(atom, this, attributes, env); } else { DirContext context = (DirContext) bindings.get(atom); subctx = context.createSubcontext(name.getSuffix(1), attributes); } return subctx; } public void destroySubcontext(Name name) throws NamingException { unbind(name); } public Attributes getAttributes(Name name) throws NamingException { return getAttributes(name, null); } public Attributes getAttributes(Name name, String[] attrIDs) throws NamingException { Attributes nameAttributes = null; String atom = name.get(0); if( name.isEmpty() == true ) { nameAttributes = (Attributes) bindingAttrs.get(""); } else if( name.size() == 1 ) { Object binding = bindings.get(atom); if( binding != null ) { if( binding instanceof DirContext ) { DirContext dirCtx = (DirContext) binding; return dirCtx.getAttributes(name.getSuffix(1), attrIDs); } } nameAttributes = (Attributes) bindingAttrs.get(atom); } else { DirContext context = (DirContext) bindings.get(atom); nameAttributes = context.getAttributes(name.getSuffix(1), attrIDs); } if( nameAttributes != null && attrIDs != null ) { BasicAttributes matches = new BasicAttributes(nameAttributes.isCaseIgnored()); for(int a = 0; a < attrIDs.length; a ++) { Attribute attr = nameAttributes.get(attrIDs[a]); if( attr != null ) matches.put(attr); } nameAttributes = matches; } return nameAttributes; } public java.util.Hashtable getEnvironment() throws NamingException { return env; } public String getNameInNamespace() throws NamingException { return toString(); } public NameParser getNameParser(Name p1) throws NamingException { return nameParser; } public DirContext getSchema(Name p1) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public DirContext getSchemaClassDefinition(Name p1) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public NamingEnumeration list(Name p1) throws NamingException { return null; } public NamingEnumeration listBindings(Name name) throws NamingException { NamingEnumeration iter = null; if( name.isEmpty() == true ) { Iterator keys = bindings.keySet().iterator(); ArrayList tmp = new ArrayList(); while( keys.hasNext() ) { String key = (String) keys.next(); Object value = bindings.get(key); Attributes attributes = (Attributes) bindingAttrs.get(key); DirBinding tuple = new DirBinding(key, value, attributes); tmp.add(tuple); } iter = new NameBindingIterator(tmp.iterator(), this); } else { String atom = name.get(0); Context context = (Context) bindings.get(atom); iter = context.listBindings(name.getSuffix(1)); } return iter; } public Object lookup(Name name) throws NamingException { if( name.isEmpty() == true ) return this; String atom = name.get(0); Object binding = bindings.get(atom); if( name.size() == 1 ) { /* Need to check that binding is null and atom is not a key since a null value could have been bound. */ if( binding == null && bindings.containsKey(atom) == false ) { NameNotFoundException e = new NameNotFoundException("Failed to find: "+atom); e.setRemainingName(name); e.setResolvedObj(this); throw e; } } else if( (binding instanceof Context) ) { Context context = (Context) binding; binding = context.lookup(name.getSuffix(1)); } else { NotContextException e = new NotContextException(atom + " does not name a directory context that supports attributes"); e.setRemainingName(name); e.setResolvedObj(binding); throw e; } return binding; } public Object lookupLink(Name p1) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public void modifyAttributes(Name p1,ModificationItem[] p2) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public void modifyAttributes(Name p1,int p2,Attributes p3) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public void rebind(Name name, Object value) throws NamingException { rebind(name, value, null); } public void rebind(Name name, Object value, Attributes attributes) throws NamingException { if( name.isEmpty() ) { throw new InvalidNameException("Cannot bind empty name"); } internalBind(name, value, attributes, false); } public void rename(Name p1,Name p2) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public NamingEnumeration search(Name p1,Attributes p2) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public NamingEnumeration search(Name p1,String p2,SearchControls p3) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public NamingEnumeration search(Name p1,Attributes p2,String[] p3) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public NamingEnumeration search(Name p1,String p2,Object[] p3,SearchControls p4) throws NamingException { throw new OperationNotSupportedException("Not implemented yet"); } public void unbind(Name name) throws NamingException { if( name.isEmpty() ) { throw new InvalidNameException("Cannot unbind empty name"); } String atom = name.get(0); Object binding = bindings.get(atom); if( name.size() == 1 ) { /* Need to check that binding is null and atom is not a key since a null value could have been bound. */ if( binding == null && bindings.containsKey(atom) == false ) { NameNotFoundException e = new NameNotFoundException("Failed to find: "+atom); e.setRemainingName(name); e.setResolvedObj(this); throw e; } bindings.remove(atom); bindingAttrs.remove(atom); } else if( (binding instanceof Context) ) { Context context = (Context) binding; context.unbind(name.getSuffix(1)); } else { NotContextException e = new NotContextException(atom + " does not name a directory context that supports attributes"); e.setRemainingName(name); e.setResolvedObj(binding); throw e; } } // --- private void internalBind(Name name, Object value, Attributes attributes, boolean isBind) throws NamingException { String atom = name.get(0); Object binding = bindings.get(atom); if( name.size() == 1 ) { if( binding != null && isBind == false ) { throw new NameAlreadyBoundException("Use rebind to override"); } // Add object to internal data structure bindings.put(atom, value); // Add attributes if( attributes != null ) { bindingAttrs.put(atom, attributes); } } else { // Intermediate name: Consume name in this context and continue if( (binding instanceof Context) == false ) { NotContextException e = new NotContextException(atom + " does not name a context"); e.setRemainingName(name); e.setResolvedObj(binding); throw e; } if( attributes == null ) { Context context = (Context) binding; if( isBind == true ) context.bind(name.getSuffix(1), value); else context.rebind(name.getSuffix(1), value); } else if( (binding instanceof DirContext) == false ) { NotContextException e = new NotContextException(atom + " does not name a directory context that supports attributes"); e.setRemainingName(name); e.setResolvedObj(binding); throw e; } else { DirContext context = (DirContext) binding; if( isBind == true ) context.bind(name.getSuffix(1), value, attributes); else context.rebind(name.getSuffix(1), value, attributes); } } } }