directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r423256 - in /directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message: LockableAttributeImpl.java LockableAttributesImpl.java
Date Tue, 18 Jul 2006 21:18:17 GMT
Author: elecharny
Date: Tue Jul 18 14:18:16 2006
New Revision: 423256

URL: http://svn.apache.org/viewvc?rev=423256&view=rev
Log:
Total rewrite of those two classes.
The goal was to add serialization methods to them, but the 
speed improvment obtained in this process woth the commit,
even if the serialization is not included.

Modified:
    directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributeImpl.java
    directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java

Modified: directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributeImpl.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributeImpl.java?rev=423256&r1=423255&r2=423256&view=diff
==============================================================================
--- directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributeImpl.java
(original)
+++ directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributeImpl.java
Tue Jul 18 14:18:16 2006
@@ -18,6 +18,8 @@
 
 
 import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
@@ -25,6 +27,7 @@
 import javax.naming.directory.Attribute;
 import javax.naming.directory.DirContext;
 
+import org.apache.directory.shared.ldap.util.StringTools;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,11 +44,17 @@
 
     private static final long serialVersionUID = -5158233254341746514L;
 
-    /** the name of the attribute */
-    private final String id;
+    /** the name of the attribute, case sensitive */
+    private final String upId;
 
+    /** In case we have only one value, just use this container */
+    private Object value;
+    
     /** the list of attribute values */
-    private final ArrayList list;
+    private List list;
+    
+    /** The number of values stored */
+    private int size = 0;
 
 
     // ------------------------------------------------------------------------
@@ -61,8 +70,10 @@
      */
     public LockableAttributeImpl(final String id)
     {
-        this.id = id;
-        list = new ArrayList();
+        upId = id;
+        value = null;
+        list = null; //new ArrayList();
+        size = 0;
     }
 
 
@@ -76,9 +87,10 @@
      */
     public LockableAttributeImpl(final String id, final Object value)
     {
-        this.id = id;
-        list = new ArrayList();
-        list.add( value );
+        upId = id;
+        list = null; // new ArrayList();
+        this.value = value; //list.add( value );
+        size = 1;
     }
 
 
@@ -92,9 +104,11 @@
      */
     public LockableAttributeImpl(final String id, final byte[] value)
     {
-        this.id = id;
-        list = new ArrayList();
-        list.add( value );
+        upId = id;
+        list = null; //new ArrayList();
+        this.value = value;
+        //list.add( value );
+        size = 1;
     }
 
 
@@ -107,10 +121,12 @@
      * @param list
      *            the list of values to start with
      */
-    private LockableAttributeImpl(final String id, final ArrayList list)
+    private LockableAttributeImpl(final String id, final List list)
     {
-        this.id = id;
+        upId = id;
         this.list = list;
+        value = null;
+        size = (list != null ? list.size() : 0);
     }
 
 
@@ -125,7 +141,35 @@
      */
     public NamingEnumeration getAll()
     {
-        return new IteratorNamingEnumeration( list.iterator() );
+    	if ( size < 2 )
+    	{
+    		return new IteratorNamingEnumeration( new Iterator()
+    		{
+    			private boolean done = (size != 0);
+    				
+    			public boolean hasNext() 
+    			{
+    				return done;
+    			}
+    			
+    			public Object next() 
+    			{
+    				done = false;
+    				return value;
+    			}
+    			
+    			public void remove() 
+    			{
+    				value = null;
+    				done = false;
+    				size = 0;
+    			}
+    		});
+    	}
+    	else
+    	{
+    		return new IteratorNamingEnumeration( list.iterator() );
+    	}
     }
 
 
@@ -136,12 +180,18 @@
      */
     public Object get()
     {
-        if ( list.isEmpty() )
+    	if ( list == null )
+    	{
+    		return value;
+    	}
+    	else if ( list.isEmpty() )
         {
             return null;
         }
-
-        return list.get( 0 );
+    	else
+    	{
+    		return list.get( 0 );
+    	}
     }
 
 
@@ -152,7 +202,7 @@
      */
     public int size()
     {
-        return list.size();
+    	return size;
     }
 
 
@@ -163,7 +213,7 @@
      */
     public String getID()
     {
-        return id;
+        return upId;
     }
 
 
@@ -176,7 +226,17 @@
      */
     public boolean contains( Object attrVal )
     {
-        return list.contains( attrVal );
+    	switch (size)
+    	{
+    		case 0 :
+    			return false;
+    			
+    		case 1 :
+    			return value == null ? attrVal == null : value.equals( attrVal );
+    			
+    		default :
+    			return list.contains( attrVal );
+    	}
     }
 
 
@@ -191,7 +251,32 @@
      */
     public boolean add( Object attrVal )
     {
-        return list.add( attrVal );
+    	boolean exists = false;
+    	
+    	switch ( size )
+    	{
+    		case 0 :
+    			value = attrVal;
+    			size++;
+    			return true;
+    			
+    		case 1 :
+    			exists = value.equals( attrVal );
+
+    			list = new ArrayList();
+    			list.add( value );
+    			list.add( attrVal );
+    			size++;
+    			value = null;
+    			return exists;
+    			
+    		default :
+    			exists = list.contains( attrVal ); 
+    		
+    			list.add( attrVal );
+    			size++;
+    			return exists;
+    	}
     }
 
 
@@ -205,7 +290,28 @@
      */
     public boolean remove( Object attrVal )
     {
-        return list.remove( attrVal );
+    	switch ( size )
+    	{
+    		case 0 :
+    			return false;
+    			
+    		case 1 :
+    			value = null;
+    			size--;
+    			return true;
+    			
+    		case 2 :
+    			list.remove( attrVal );
+    			value = list.get(0);
+    			size = 1;
+    			list = null;
+    			return true;
+    			
+    		default :
+    			list.remove( attrVal );
+    			size--;
+    			return true;
+    	}
     }
 
 
@@ -214,7 +320,21 @@
      */
     public void clear()
     {
-        list.clear();
+    	switch ( size )
+    	{
+    		case 0 :
+    			return;
+    			
+    		case 1 :
+    			value = null;
+    			size = 0;
+    			return;
+    			
+    		default :
+    			list = null;
+    			size = 0;
+    			return;
+    	}
     }
 
 
@@ -248,8 +368,17 @@
      */
     public Object clone()
     {
-        ArrayList l_list = ( ArrayList ) list.clone();
-        return new LockableAttributeImpl( id, l_list );
+    	switch ( size )
+    	{
+    		case 0 :
+    			return new LockableAttributeImpl( upId );
+    			
+    		case 1 :
+    			return new LockableAttributeImpl( upId, value );
+    			
+    		default :
+    			return new LockableAttributeImpl( upId, (List)((ArrayList)list).clone() );
+    	}
     }
 
 
@@ -274,7 +403,17 @@
      */
     public Object get( int index )
     {
-        return list.get( index );
+    	switch ( size )
+    	{
+    		case 0 :
+    			return null;
+    			
+    		case 1 :
+    			return value;
+    			
+    		default :
+    			return list.get( index );
+    	}
     }
 
 
@@ -288,7 +427,21 @@
      */
     public Object remove( int index )
     {
-        return list.remove( index );
+    	switch ( size )
+    	{
+    		case 0 :
+    			return null;
+    			
+    		case 1 :
+    			Object result = value;
+    			value = null;
+    			size = 0;
+    			return result;
+    			
+    		default :
+    			size--;
+    			return list.remove( index );
+    	}
     }
 
 
@@ -303,7 +456,36 @@
      */
     public void add( int index, Object attrVal )
     {
-        list.add( index, attrVal );
+    	switch ( size )
+    	{
+    		case 0 :
+    			size++;
+    			value = attrVal;
+    			return;
+    			
+    		case 1 :
+    			list = new ArrayList();
+    			
+    			if ( index == 0 )
+    			{
+	    			list.add( attrVal );
+	    			list.add( value );
+    			}
+    			else
+    			{
+	    			list.add( value );
+	    			list.add( attrVal );
+    			}
+
+    			size++;
+    			value = null;
+    			return;
+    			
+    		default :
+    			list.add( index, attrVal );
+    			size++;
+    			return;
+    	}
     }
 
 
@@ -318,7 +500,35 @@
      */
     public Object set( int index, Object attrVal )
     {
-        return list.set( index, attrVal );
+    	switch ( size )
+    	{
+    		case 0 :
+    			size++;
+    			value = attrVal;
+    			return null;
+    			
+    		case 1 :
+    			if ( index == 0 )
+    			{
+	    			Object result = value;
+	    			value = attrVal;
+	    			return result;
+    			}
+    			else
+    			{
+    				list = new ArrayList();
+    				list.add( value );
+    				list.add( attrVal );
+    				size = 2;
+    				value = null;
+    				return null;
+    			}
+    			
+    		default :
+    			Object oldValue = list.get( index );
+    			list.set( index, attrVal );
+    			return oldValue;
+    	}
     }
 
 
@@ -349,54 +559,112 @@
         }
 
         Attribute attr = ( Attribute ) obj;
-        if ( !id.equals( attr.getID() ) )
+        
+        if ( !upId.equals( attr.getID() ) )
         {
             return false;
         }
 
-        if ( attr.size() != list.size() )
+        if ( attr.size() != size )
         {
             return false;
         }
 
-        // if ( attr.isOrdered() )
-        // {
-        // for ( int ii = 0; ii < attr.size(); ii++ )
-        // {
-        // try
-        // {
-        // if ( ! list.get( ii).equals( attr.get( ii ) ) )
-        // {
-        // return false;
-        // }
-        // }
-        // catch ( NamingException e )
-        // {
-        // log.warn( "Failed to get an attribute from the specifid attribute: "
-        // + attr, e );
-        // return false;
-        // }
-        // }
-        // }
-        // else
-        // {
-        for ( int ii = 0; ii < attr.size(); ii++ )
+        switch ( size )
         {
-            try
-            {
-                if ( !list.contains( attr.get( ii ) ) )
+        	case 0 :
+        		return true;
+        		
+        	case 1 :
+                try
+                {
+                	return value.equals( attr.get( 0 ) );
+                }
+                catch ( NamingException e )
                 {
+                    log.warn( "Failed to get an attribute from the specifid attribute: "
+ attr, e );
                     return false;
                 }
-            }
-            catch ( NamingException e )
-            {
-                log.warn( "Failed to get an attribute from the specifid attribute: " + attr,
e );
-                return false;
-            }
+        		
+        	default :
+                for ( int i = 0; i < size; i++ )
+                {
+                    try
+                    {
+                        if ( !list.contains( attr.get( i ) ) )
+                        {
+                            return false;
+                        }
+                    }
+                    catch ( NamingException e )
+                    {
+                        log.warn( "Failed to get an attribute from the specifid attribute:
" + attr, e );
+                        return false;
+                    }
+                }
+        		
+        		return true;
         }
-        // }
-
-        return true;
+    }
+    
+    public String toString()
+    {
+    	StringBuffer sb = new StringBuffer();
+    	
+    	sb.append( "Attribute id : '" ).append( upId ).append( "', " );
+    	sb.append( " Values : [");
+    	
+    	switch (size)
+    	{
+    		case 0 :
+    			sb.append( "]\n" );
+    			break;
+    			
+    		case 1 :
+    			if ( value instanceof String ) 
+    			{
+    				sb.append( '\'' ).append( value ).append( '\'' );
+				}
+    			else
+    			{
+    				sb.append( StringTools.dumpBytes( (byte[])value ) );
+    			}
+    			
+    			sb.append( "]\n" );
+    			break;
+    			
+    		default :
+    			boolean isFirst = true;
+    		
+	    		Iterator values = list.iterator();
+	    		
+	    		while ( values.hasNext() )
+	    		{
+	    			Object v = values.next();
+	    			
+	    			if ( isFirst == false )
+	    			{
+	    				sb.append( ", " );
+	    			}
+	    			else
+	    			{
+	    				isFirst = false;
+	    			}
+	    			
+	    			if ( v instanceof String ) 
+	    			{
+	    				sb.append( '\'' ).append( v ).append( '\'' );
+					}
+	    			else
+	    			{
+	    				sb.append( StringTools.dumpBytes( (byte[])v ) );
+	    			}
+	    		}
+	    		
+	    		sb.append( "]\n" );
+	    		break;
+    	}
+    	
+    	return sb.toString();
     }
 }

Modified: directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java?rev=423256&r1=423255&r2=423256&view=diff
==============================================================================
--- directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java
(original)
+++ directory/branches/shared/optimization/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java
Tue Jul 18 14:18:16 2006
@@ -17,16 +17,16 @@
 package org.apache.directory.shared.ldap.message;
 
 
+import java.io.Serializable;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
 
-import javax.naming.NamingException;
 import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
-
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
+import javax.naming.directory.BasicAttribute;
 
 
 /**
@@ -35,13 +35,108 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class LockableAttributesImpl implements Attributes
+public class LockableAttributesImpl implements Attributes, Serializable
 {
-    static final long serialVersionUID = -69864533495992471L;
-
-    /** Map of user provided String ids to Attributes */
-    private final Map map = new HashMap();
+    static transient final long serialVersionUID = -69864533495992471L;
 
+    /**
+     * An holder to store <Id, Attribute> couples
+     * 
+     */
+    private class Holder implements Serializable, Cloneable
+	{
+    	static transient final long serialVersionUID = 1L;
+    	
+		private String upId;
+		private Attribute attribute;
+		
+		private Holder( String upId, Attribute attribute )
+		{
+			this.upId = upId;
+			this.attribute = attribute;
+		}
+		
+		public Object clone() throws CloneNotSupportedException
+		{
+			Holder clone = (Holder)super.clone();
+			
+			clone.upId = upId;
+			clone.attribute = (Attribute)attribute.clone();
+			
+			return clone;
+		}
+		
+		public String toString()
+		{
+			StringBuffer sb = new StringBuffer();
+			
+			sb.append( upId ).append( ": " );
+			
+			sb.append( attribute ).append( '\n' );
+			
+			return sb.toString();
+		}
+	}
+	
+    /**
+     * An iterator which returns Attributes.  
+     */
+	public class AttributeIterator implements Iterator
+	{
+		private Iterator iterator; 
+		
+		private AttributeIterator( LockableAttributesImpl attributes )
+		{
+			iterator = attributes.keyMap.values().iterator();
+		}
+		
+	    /**
+	     * Returns <tt>true</tt> if the iteration has more elements. (In other
+	     * words, returns <tt>true</tt> if <tt>next</tt> would return
an element
+	     * rather than throwing an exception.)
+	     *
+	     * @return <tt>true</tt> if the iterator has more elements.
+	     */
+	    public boolean hasNext()
+	    {
+	    	return iterator.hasNext();
+	    }
+
+	    /**
+	     * Returns the next element in the iteration.  Calling this method
+	     * repeatedly until the {@link #hasNext()} method returns false will
+	     * return each element in the underlying collection exactly once.
+	     *
+	     * @return the next element in the iteration.
+	     * @exception NoSuchElementException iteration has no more elements.
+	     */
+	    public Object next()
+	    {
+	    	return ((Holder)iterator.next()).attribute;
+	    }
+
+	    /**
+	     * 
+	     * Removes from the underlying collection the last element returned by the
+	     * iterator (optional operation).  This method can be called only once per
+	     * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
+	     * the underlying collection is modified while the iteration is in
+	     * progress in any way other than by calling this method.
+	     *
+	     * @exception UnsupportedOperationException if the <tt>remove</tt>
+	     *		  operation is not supported by this Iterator.
+	     
+	     * @exception IllegalStateException if the <tt>next</tt> method has not
+	     *		  yet been called, or the <tt>remove</tt> method has already
+	     *		  been called after the last call to the <tt>next</tt>
+	     *		  method.
+	     */
+	    public void remove()
+	    {
+	    	iterator.remove();
+	    }
+	}
+	
     /** Cache of lowercase id Strings to mixed cased user provided String ids */
     private Map keyMap;
 
@@ -58,32 +153,87 @@
         keyMap = new HashMap();
     }
 
-
-    /**
-     * Used by clone to create a LockableAttributes.
-     * 
-     * @param map
-     *            the primary user provided id to Attribute Map
-     * @param keyMap
-     *            the canonical key to user provided id Map
-     */
-    private LockableAttributesImpl(Map map, Map keyMap)
+    // ------------------------------------------------------------------------
+    // Serialization methods
+    //
+    // We will try to minimize the cost of reading and writing objects to the 
+    // disk.
+    //
+    // We need to save all the attributes stored into the 'map' object, and 
+    // their associated User Provided value.
+    // Attributes are stored following this pattern :
+    //  ( attributeType = (attribute value )* )*
+    //
+    // The streamed value will looks like :
+    // [nbAttrs:int]
+    //   (
+    //		[length attributeType(i):int] [attributeType(i):String] 
+    //		[length attributeTypeUP(i):int] [attributeTypeUP(i):String]
+    //		[attributeValues(i)]
+    //	 )*
+    //
+    // The attribute value is streamed by the LockableAttributeImpl class.
+    // ------------------------------------------------------------------------
+    /*public void readObject( ObjectInputStream oi ) throws IOException, ClassNotFoundException
     {
-        this.keyMap = new HashMap();
-
-        if ( keyMap != null )
-        {
-            this.keyMap.putAll( keyMap );
-        }
-
-        Iterator list = map.values().iterator();
-        while ( list.hasNext() )
-        {
-            Attribute attr = ( Attribute ) list.next();
-            this.map.put( attr.getID(), attr.clone() );
-        }
-    }
-
+    	oi.defaultReadObject();
+    	
+    	// Read the map size
+    	int size = oi.readInt();
+    	
+    	keyMap = new HashMap( size );
+    	
+    	for ( int i = 0; i < size(); i++ )
+    	{
+    		int keySize = oi.readInt();
+    		char[] keyChars = new char[keySize];
+    		
+    		for ( int j = 0; j < keySize; j++)
+    		{
+    			keyChars[j] = oi.readChar();
+    		}
+    		
+    		String upId = new String( keyChars );
+    		String key = upId.toLowerCase();
+    		
+    		Attribute attribute = (LockableAttributeImpl)oi.readObject();
+    		
+    		Holder holder = new Holder( upId, attribute);
+    		
+    		keyMap.put( key, holder );
+    	}
+    }*/
+
+    /**
+     * Write the Attribute to a stream
+     */
+    /*private void writeObject( ObjectOutputStream oo ) throws IOException
+    {
+    	oo.defaultWriteObject();
+    	
+    	// Write the map size
+    	oo.write( keyMap.size() );
+    	
+    	Iterator keys = keyMap.keySet().iterator(); 
+    	
+    	while ( keys.hasNext() )
+    	{
+    		String key = (String)keys.next();
+    		Holder holder = (Holder)keyMap.get( key );
+
+    		// Write the userProvided key
+    		// No need to write the key, it will be
+    		// rebuilt by the read operation
+    		oo.write( holder.upId.length() );
+    		oo.writeChars( holder.upId );
+    		
+    		// Recursively call the writeExternal metho
+    		// of the attribute object
+    		oo.writeObject( holder.attribute );
+    	}
+    	
+    	// That's it !
+    }*/
 
     // ------------------------------------------------------------------------
     // javax.naming.directory.Attributes Interface Method Implementations
@@ -108,7 +258,7 @@
      */
     public int size()
     {
-        return map.size();
+        return keyMap.size();
     }
 
 
@@ -126,14 +276,15 @@
      */
     public Attribute get( String attrId )
     {
-        String key = getUserProvidedId( attrId );
-
-        if ( key == null )
-        {
-            return null;
-        }
-
-        return ( Attribute ) map.get( key );
+    	if ( attrId != null )
+    	{
+    		Holder holder = (Holder)keyMap.get( attrId.toLowerCase() );
+    		return holder != null ? holder.attribute : null;
+    	}
+    	else
+    	{
+    		return null;
+    	}
     }
 
 
@@ -149,7 +300,7 @@
      */
     public NamingEnumeration getAll()
     {
-        return new IteratorNamingEnumeration( map.values().iterator() );
+        return new IteratorNamingEnumeration( new AttributeIterator( this ) );
     }
 
 
@@ -165,7 +316,17 @@
      */
     public NamingEnumeration getIDs()
     {
-        return new ArrayNamingEnumeration( map.keySet().toArray() );
+    	String[] ids = new String[keyMap.size()];
+    	
+    	Iterator values = keyMap.values().iterator();
+    	int i = 0;
+    	
+    	while ( values.hasNext() )
+    	{
+    		ids[i++] = ((Holder)values.next()).upId;
+    	}
+    	
+        return new ArrayNamingEnumeration( ids );
     }
 
 
@@ -185,14 +346,11 @@
      */
     public Attribute put( String attrId, Object val )
     {
-        if ( get( attrId ) == null )
-        {
-            setUserProvidedId( attrId );
-        }
-
         Attribute attr = new LockableAttributeImpl( attrId );
         attr.add( val );
-        map.put( attrId, attr );
+        
+        String key = attrId.toLowerCase();
+        keyMap.put( key, new Holder( attrId, attr) );
         return attr;
     }
 
@@ -205,25 +363,45 @@
      *            the character case of its attribute ids, the case of attr's
      *            identifier is ignored.
      * @return The Attribute with the same ID as attr that was previous in this
-     *         attribute set; null if no such attribute existed.
+     *         attribute set; The new attr if no such attribute existed.
      * @see #remove
      */
     public Attribute put( Attribute attr )
     {
-        Attribute old = get( attr.getID() );
-
-        if ( old != null )
-        {
-            map.remove( old.getID() );
-
-            if ( keyMap != null )
-            {
-                keyMap.remove( old.getID().toLowerCase() );
-            }
+    	String key = attr.getID().toLowerCase();
+    	Attribute old = null;
+    	Attribute newAttr = attr;
+    	
+        if ( keyMap.containsKey( key ) )
+        {
+            old = (Attribute)((Holder)keyMap.remove( key )).attribute;
+        }
+        else
+        {
+        	old = attr;
+        }
+
+        if ( attr instanceof BasicAttribute )
+        {
+        	 newAttr = new LockableAttributeImpl( attr.getID() );
+        	 
+        	 try
+        	 {
+	        	 NamingEnumeration values = attr.getAll();
+	        	 
+	        	 while ( values.hasMore() )
+	        	 {
+	        		 Object value = values.next();
+	        		 newAttr.add( value );
+	        	 }
+        	 }
+        	 catch ( NamingException ne )
+        	 {
+        		 // do nothing
+        	 }
         }
-
-        map.put( attr.getID(), attr );
-        setUserProvidedId( attr.getID() );
+        
+        keyMap.put( key, new Holder( attr.getID(), newAttr ) );
         return old;
     }
 
@@ -241,16 +419,17 @@
      */
     public Attribute remove( String attrId )
     {
-        Attribute old = get( attrId );
-
-        if ( old != null )
-        {
-            map.remove( old.getID() );
-
-            if ( keyMap != null )
-            {
-                keyMap.remove( old.getID().toLowerCase() );
-            }
+    	String key = attrId.toLowerCase();
+    	Attribute old = null;
+    	
+        if ( keyMap.containsKey( key ) )
+        {
+        	Holder holder = (Holder)keyMap.remove( key );
+        	
+        	if ( holder != null ) 
+        	{
+        		old = holder.attribute;
+        	}
         }
 
         return old;
@@ -265,7 +444,27 @@
      */
     public Object clone()
     {
-        return new LockableAttributesImpl( map, keyMap );
+    	try
+    	{
+	    	LockableAttributesImpl clone = (LockableAttributesImpl)super.clone();
+	
+			clone.keyMap = (Map)((HashMap)keyMap).clone();
+			
+	        Iterator keys = keyMap.keySet().iterator();
+	
+	        while ( keys.hasNext() )
+	        {
+	        	String key = (String)keys.next();
+	        	Holder holder = (Holder)keyMap.get( key );
+	            clone.keyMap.put( key, holder.clone() );
+	        }
+	    	
+	        return clone;
+    	}
+    	catch ( CloneNotSupportedException cnse )
+    	{
+    		return null;
+    	}
     }
 
 
@@ -278,27 +477,16 @@
     {
         StringBuffer buf = new StringBuffer();
 
-        Iterator attrs = map.values().iterator();
+        Iterator attrs = keyMap.values().iterator();
+        
         while ( attrs.hasNext() )
         {
-            Attribute l_attr = ( Attribute ) attrs.next();
+        	Holder holder = (Holder)attrs.next();
+            Attribute attr = holder.attribute;
 
-            try
-            {
-                NamingEnumeration l_values = l_attr.getAll();
-                while ( l_values.hasMore() )
-                {
-                    Object l_value = l_values.next();
-                    buf.append( l_attr.getID() );
-                    buf.append( ": " );
-                    buf.append( l_value );
-                    buf.append( '\n' );
-                }
-            }
-            catch ( NamingException e )
-            {
-                buf.append( ExceptionUtils.getFullStackTrace( e ) );
-            }
+            buf.append( holder.upId );
+            buf.append( ": " );
+            buf.append( attr );
         }
 
         return buf.toString();
@@ -340,6 +528,7 @@
         }
 
         NamingEnumeration list = attrs.getAll();
+
         while ( list.hasMoreElements() )
         {
             Attribute attr = ( Attribute ) list.nextElement();
@@ -357,60 +546,5 @@
         }
 
         return true;
-    }
-
-
-    // ------------------------------------------------------------------------
-    // Utility Methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Sets the user provided key by normalizing it and adding a record into the
-     * keymap for future lookups.
-     * 
-     * @param userProvidedId
-     *            the id of the Attribute gotten from the attribute instance via
-     *            getID().
-     */
-    private void setUserProvidedId( String userProvidedId )
-    {
-        if ( keyMap == null )
-        {
-            keyMap = new HashMap();
-            keyMap.put( userProvidedId.toLowerCase(), userProvidedId );
-            return;
-        }
-
-        if ( keyMap.get( userProvidedId ) == null )
-        {
-            keyMap.put( userProvidedId.toLowerCase(), userProvidedId );
-        }
-    }
-
-
-    /**
-     * Gets the user provided key by looking it up using the normalized key in
-     * the key map.
-     * 
-     * @param attrId
-     *            the id of the Attribute in any case.
-     * @return the attribute id as it would be returned on a call to the
-     *         Attribute's getID() method.
-     */
-    private String getUserProvidedId( String attrId )
-    {
-        // First check if it is correct form to save string creation below.
-        if ( map.containsKey( attrId ) )
-        {
-            return attrId;
-        }
-
-        if ( keyMap == null )
-        {
-            keyMap = new HashMap();
-            return null;
-        }
-
-        return ( String ) keyMap.get( attrId.toLowerCase() );
     }
 }



Mime
View raw message