commits@directory.apache.org
[Top] [All Lists]

svn commit: r610856 [1/2] - in /directory: apacheds/branches/bigbang/cor

Subject: svn commit: r610856 [1/2] - in /directory: apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ apacheds/branches/bigbang/core-entry/src/test/java/org/apache/directory/server/core/entry/ apacheds/branches/bigbang/c...
From:
Date: Thu, 10 Jan 2008 18:09:24 -0000
Author: elecharny
Date: Thu Jan 10 10:09:16 2008
New Revision: 610856

URL: http://svn.apache.org/viewvc?rev=610856&view=rev
Log:
o Fixed the build problems we had on the bigbang branch with the last commit.
The server.xml file now contains all the beans necessary to initialize the 
DirectoryServer contextEntries
o Added some more tests into the ServerEntry API
o Started to write the serializer for ServerEntry (commented)
o Added some Attributes to LDIF serialization 
o Fixed some tests to inject ServerEntry into the server instead of Attributes 
when creating partitions

Added:
    
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttributeSerializerUtils.java
    
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntrySerializerUtils.java
    
directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifAttributesReader.java
    
directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/ldif/LdifAttributesReaderTest.java
Modified:
    
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java
    
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerEntry.java
    
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttribute.java
    
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerBinaryValue.java
    
directory/apacheds/branches/bigbang/core-entry/src/test/java/org/apache/directory/server/core/entry/DefaultServerEntryTest.java
    
directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchWithIndicesITest.java
    directory/apacheds/branches/bigbang/core-plugin/src/main/antlr/openldap.g
    
directory/apacheds/branches/bigbang/core-plugin/src/test/java/org/apache/directory/server/core/tools/schema/OpenLdapSchemaParserTest.java
    
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
    
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DirectoryService.java
    
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java
    
directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/authz/support/MaxImmSubFilterTest.java
    
directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/interceptor/InterceptorChainTest.java
    
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/DIRSERVER951ITest.java
    
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/NegationOperatorITest.java
    directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml
    
directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifReader.java
    
directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifUtils.java
    
directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/ldif/LdifUtilsTest.java

Modified: 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java
URL: 
http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java?rev=610856&r1=610855&r2=610856&view=diff
==============================================================================
--- 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java
 (original)
+++ 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java
 Thu Jan 10 10:09:16 2008
@@ -115,7 +115,7 @@
      * @param upId The attribute ID
      * @param attributeType The associated attributeType
      */
-    protected void setUpId( String upId, AttributeType attributeType )
+    public void setUpId( String upId, AttributeType attributeType )
     {
         if ( StringTools.isEmpty( upId ) )
         {
@@ -177,8 +177,8 @@
             }
         }
     }
-
-
+    
+    
     // -----------------------------------------------------------------------
     // API
     // -----------------------------------------------------------------------

Modified: 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerEntry.java
URL: 
http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerEntry.java?rev=610856&r1=610855&r2=610856&view=diff
==============================================================================
--- 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerEntry.java
 (original)
+++ 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerEntry.java
 Thu Jan 10 10:09:16 2008
@@ -548,7 +548,7 @@
      */
     public ServerAttribute put( String upId, String... values ) throws 
NamingException
     {
-        return put( getAttributeType( upId ), values );
+        return put( upId, getAttributeType( upId ), values );
     }
 
 
@@ -976,7 +976,9 @@
 
         if ( attributeType.equals( OBJECT_CLASS_AT ) )
         {
-            throw new UnsupportedOperationException( "Only String values 
supported for objectClass attribute" );
+            String message = "Only String values supported for objectClass 
attribute";
+            LOG.error(  message  );
+            throw new UnsupportedOperationException( message );
         }
 
         ServerAttribute serverAttribute = new DefaultServerAttribute( upId, 
attributeType );
@@ -1002,7 +1004,10 @@
             }
             else
             {
-                attributes.add( serverAttributeMap.remove( attributeType ) );
+                if ( serverAttributeMap.containsKey( attributeType ) )
+                {
+                    attributes.add( serverAttributeMap.remove( attributeType ) 
);
+                }
             }
         }
         
@@ -1181,6 +1186,31 @@
     /**
      * Checks if an entry contains an attribute with a given value.
      *
+     * @param attributeType The Attribute we are looking for
+     * @param value The searched value
+     * @return <code>true</code> if the value is found within the attribute
+     * @throws NamingException If the attribute does not exists
+     */
+    public boolean contains( AttributeType attributeType, String value ) 
throws NamingException
+    {
+        if ( attributeType == null )
+        {
+            return false;
+        }
+        else if ( serverAttributeMap.containsKey( attributeType ) )
+        {
+            return serverAttributeMap.get( attributeType ).contains( value );
+        }
+        else
+        {
+            return false;
+        }
+    }
+    
+    
+    /**
+     * Checks if an entry contains an attribute with a given value.
+     *
      * @param id The Attribute we are looking for
      * @param value The searched value
      * @return <code>true</code> if the value is found within the attribute
@@ -1211,6 +1241,31 @@
     
     
     /**
+     * Checks if an entry contains an attribute with a given value.
+     *
+     * @param attributeType The Attribute we are looking for
+     * @param value The searched value
+     * @return <code>true</code> if the value is found within the attribute
+     * @throws NamingException If the attribute does not exists
+     */
+    public boolean contains( AttributeType attributeType, byte[] value ) 
throws NamingException
+    {
+        if ( attributeType == null )
+        {
+            return false;
+        }
+        else if ( serverAttributeMap.containsKey( attributeType ) )
+        {
+            return serverAttributeMap.get( attributeType ).contains( value );
+        }
+        else
+        {
+            return false;
+        }
+    }
+    
+    
+    /**
      * Gets all the attributes type (ObjectClasses, May and Must)
      *
      * @return The combined set of all the attributes, including ObjectClass.
@@ -1222,6 +1277,279 @@
     
     
     /**
+     * Add an attribute (represented by its ID and some String values) into an 
+     * entry.
+     * <p> 
+     * If we already have an attribute with the same value, nothing is done
+     *
+     * @param attributeType The attribute Type
+     * @param values The list of String values to inject. It can be empty
+     * @throws NamingException If the attribute does not exist
+     */
+    public void add( AttributeType attributeType, String... values ) throws 
NamingException
+    {
+        if ( attributeType == null )
+        {
+            String message = "The attributeType should not be null";
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
+        }
+        
+        ServerAttribute existing = serverAttributeMap.get( attributeType );
+
+        if ( existing != null )
+        {
+            existing.add( values );
+        }
+        else
+        {
+            if ( attributeType.equals( OBJECT_CLASS_AT ) )
+            {
+                setObjectClassAttribute( new ObjectClassAttribute( registries, 
OBJECT_CLASS_AT.getName(), values ) );
+            }
+            else
+            {
+                put( null, attributeType, values );
+            }
+        }
+    }
+
+    
+    /**
+     * Add an attribute (represented by its ID and some Binary values) into an 
+     * entry.
+     * <p> 
+     * If we already have an attribute with the same value, nothing is done
+     *
+     * @param attributeType The attribute Type
+     * @param values The list of binary values to inject. It can be empty
+     * @throws NamingException If the attribute does not exist
+     */
+    public void add( AttributeType attributeType, byte[]... values ) throws 
NamingException
+    {
+        if ( attributeType == null )
+        {
+            String message = "The attributeType should not be null";
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
+        }
+        
+        ServerAttribute existing = serverAttributeMap.get( attributeType );
+
+        if ( existing != null )
+        {
+            existing.add( values );
+        }
+        else
+        {
+            if ( attributeType.equals( OBJECT_CLASS_AT ) )
+            {
+                String message = "Only String values supported for objectClass 
attribute";
+                LOG.error(  message  );
+                throw new UnsupportedOperationException( message );
+            }
+            else
+            {
+                put( null, attributeType, values );
+            }
+        }
+    }
+
+
+    /**
+     * Add a new attribute with some ServerValue values into the entry.
+     * <p>
+     * 
+     * @param attributeType The attributeType to add
+     * @param values The associated ServerValue values
+     * @throws NamingException If some values conflict with the attributeType
+     * 
+     */
+    public void add( AttributeType attributeType, ServerValue<?>... values ) 
throws NamingException
+    {
+        if ( attributeType == null )
+        {
+            String message = "The attributeType should not be null";
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
+        }
+        
+        ServerAttribute existing = serverAttributeMap.get( attributeType );
+
+        if ( existing != null )
+        {
+            // Adds the new values into the attribute
+            existing.add( values );
+        }
+        else
+        {
+            ServerAttribute serverAttribute = new DefaultServerAttribute( 
attributeType, values );
+            put( serverAttribute );
+        }
+    }
+
+
+    /**
+     * Add an attribute (represented by its ID and string values) into an 
entry. 
+     *
+     * @param upId The attribute ID
+     * @param values The list of string values to inject. It can be empty
+     * @throws NamingException If the attribute does not exist
+     */
+    public void add( String upId, String... values ) throws NamingException
+    {
+        add( upId, getAttributeType( upId ), values );
+    }
+
+
+    /**
+     * Add an attribute (represented by its ID and binary values) into an 
entry. 
+     *
+     * @param upId The attribute ID
+     * @param values The list of binary values to inject. It can be empty
+     * @throws NamingException If the attribute does not exist
+     */
+    public void add( String upId, byte[]... values ) throws NamingException
+    {
+        add( upId, getAttributeType( upId ), values );
+    }
+
+
+    /**
+     * Add an attribute (represented by its ID and ServerValue values) into an 
entry. 
+     *
+     * @param upId The attribute ID
+     * @param values The list of ServerValue values to inject. It can be empty
+     * @throws NamingException If the attribute does not exist
+     */
+    public void add( String upId, ServerValue<?>... values ) throws 
NamingException
+    {
+        add( upId, getAttributeType( upId ), values );
+    }
+
+
+    /**
+     * Adds a new attribute with some String values into an entry, setting
+     * the User Provided ID in the same time.
+     *
+     * @param upId The User provided ID
+     * @param attributeType The associated AttributeType
+     * @param values The String values to store into the new Attribute
+     * @throws NamingException 
+     */
+    public void add( String upId, AttributeType attributeType, String... 
values ) throws NamingException
+    {
+        upId = getUpId( upId, attributeType );
+        attributeType = getAttributeType( upId, attributeType );
+        
+        ServerAttribute existing = serverAttributeMap.get( attributeType );
+        
+        if ( existing == null )
+        {
+            put( upId, attributeType, values );
+        }
+        else
+        {
+            if ( attributeType.equals( OBJECT_CLASS_AT ) )
+            {
+                // If the AttributeType is the ObjectClass AttributeType, then
+                // we don't add it to the entry, as it has already been added
+                // before. But we have to store the upId.
+                objectClassAttribute.setUpId( upId, OBJECT_CLASS_AT );
+                objectClassAttribute.add( values );
+            }
+            else
+            {
+                // We simply have to set the current attribute values
+                // and to change its upId
+                existing.add( values );
+                existing.setUpId( upId, attributeType );
+            }
+        }
+    }
+
+
+    /**
+     * Adds a new attribute with some Binary values into an entry, setting
+     * the User Provided ID in the same time.
+     *
+     * @param upId The User provided ID
+     * @param attributeType The associated AttributeType
+     * @param values The Binary values to store into the new Attribute
+     * @throws NamingException 
+     */
+    public void add( String upId, AttributeType attributeType, byte[]... 
values ) throws NamingException
+    {
+        upId = getUpId( upId, attributeType );
+        attributeType = getAttributeType( upId, attributeType );
+        
+        ServerAttribute existing = serverAttributeMap.get( attributeType );
+        
+        if ( existing == null )
+        {
+            put( upId, attributeType, values );
+        }
+        else
+        {
+            if ( attributeType.equals( OBJECT_CLASS_AT ) )
+            {
+                String message = "Only String values supported for objectClass 
attribute";
+                LOG.error(  message  );
+                throw new UnsupportedOperationException( message );
+            }
+            else
+            {
+                // We simply have to set the current attribute values
+                // and to change its upId
+                existing.add( values );
+                existing.setUpId( upId, attributeType );
+            }
+        }
+    }
+
+
+    /**
+     * Adds a new attribute with some ServerValue values into an entry, setting
+     * the User Provided ID in the same time.
+     *
+     * @param upId The User provided ID
+     * @param attributeType The associated AttributeType
+     * @param values The ServerValue values to store into the new Attribute
+     * @throws NamingException 
+     */
+    public void add( String upId, AttributeType attributeType, 
ServerValue<?>... values ) throws NamingException
+    {
+        upId = getUpId( upId, attributeType );
+        attributeType = getAttributeType( upId, attributeType );
+        
+        ServerAttribute existing = serverAttributeMap.get( attributeType );
+        
+        if ( existing == null )
+        {
+            put( upId, attributeType, values );
+        }
+        else
+        {
+            if ( attributeType.equals( OBJECT_CLASS_AT ) )
+            {
+                // If the AttributeType is the ObjectClass AttributeType, then
+                // we don't add it to the entry, as it has already been added
+                // before. But we have to store the upId.
+                objectClassAttribute.setUpId( upId, OBJECT_CLASS_AT );
+                objectClassAttribute.add( values );
+            }
+            else
+            {
+                // We simply have to set the current attribute values
+                // and to change its upId
+                existing.add( values );
+                existing.setUpId( upId, attributeType );
+            }
+        }
+    }
+
+
+    /**
      * @see Object#toString()
      */
     public String toString()
@@ -1233,7 +1561,7 @@
         
         if ( objectClassAttribute != null )
         {
-            sb.append( "    " ).append( objectClassAttribute );
+            sb.append( objectClassAttribute );
         }
 
         if ( serverAttributeMap.size() != 0 )

Modified: 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttribute.java
URL: 
http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttribute.java?rev=610856&r1=610855&r2=610856&view=diff
==============================================================================
--- 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttribute.java
 (original)
+++ 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttribute.java
 Thu Jan 10 10:09:16 2008
@@ -53,6 +53,22 @@
      * @return the user provided identifier for this attribute
      */
     String getUpId();
+    
+    
+    /**
+     * Set the user provided ID. If we have none, the upId is assigned
+     * the attributetype's name. If it does not have any name, we will
+     * use the OID.
+     * <p>
+     * If we have an upId and an AttributeType, they must be compatible. :
+     *  - if the upId is an OID, it must be the AttributeType's OID
+     *  - otherwise, its normalized form must be equals to ones of
+     *  the attributeType's names.
+     *
+     * @param upId The attribute ID
+     * @param attributeType The associated attributeType
+     */
+    public void setUpId( String upId, AttributeType attributeType );
 
     
     /**

Added: 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttributeSerializerUtils.java
URL: 
http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttributeSerializerUtils.java?rev=610856&view=auto
==============================================================================
--- 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttributeSerializerUtils.java
 (added)
+++ 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerAttributeSerializerUtils.java
 Thu Jan 10 10:09:16 2008
@@ -0,0 +1,585 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.entry;
+
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+
+import org.apache.directory.shared.asn1.codec.DecoderException;
+import org.apache.directory.shared.asn1.primitives.OID;
+import org.apache.directory.shared.ldap.message.AttributeImpl;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Attr;
+
+/**
+ * Serializes a ServerAttribute object using a custom serialization mechanism
+ * so we do not have to rely on Java Serialization which is much more 
+ * costly.
+ * 
+ * @author <a href="mailto:dev@xxxxxxxxxxxxxxxxxxxx";>Apache Directory 
Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ServerAttributeSerializerUtils
+{
+    /** logger for reporting errors that might not be handled properly 
upstream */
+/*    private final static Logger LOG = LoggerFactory.getLogger( 
ServerAttributeSerializerUtils.class );
+
+    private static final long serialVersionUID = -3756830073760754086L;
+    
+    private class InnerData
+    {
+        byte[] upIdBytes;
+        byte[] oidBytes;
+        byte[][] normalizedBytes;
+        byte[][] wrappedBytes;
+    }
+  */
+    // -----------------------------------------------------------------------
+    // Methods for deserialization
+    // -----------------------------------------------------------------------
+    /**
+     * Deserializes an attribute from the custom serialization structure.
+     * 
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     *
+    public static final Object deserialize( byte[] buf )
+    {
+        String id = readString( buf );
+        AttributeImpl attr = new AttributeImpl( id );
+        int pos = ( id.length() << 1 ) + 4;
+        
+        // read the type of the objects stored in this attribute
+        if ( buf[pos] == STRING_TYPE )
+        {
+            pos++;
+            while ( pos < buf.length )
+            {
+                String value = readString( buf, pos );
+                pos += ( value.length() << 1 ) + 4;
+                attr.add( value );
+            }
+        }
+        else
+        {
+            pos++;
+            while ( pos < buf.length )
+            {
+                byte[] value = readBytes( buf, pos );
+                pos += value.length + 4;
+                attr.add( value );
+            }
+        }
+        
+        return attr;
+    }
+
+    
+    /**
+     * Deserializes an attribute from the custom serialization structure.
+     * 
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     *
+    public static final DeserializedAttribute deserialize( byte[] buf, int 
offset )
+    {
+        final String id = readString( buf, offset );
+        final AttributeImpl attr = new AttributeImpl( id );
+        int pos = ( id.length() << 1 ) + 4 + offset;
+        
+        // read the type of the objects stored in this attribute
+        if ( buf[pos] == STRING_TYPE )
+        {
+            pos++;
+            while ( pos < buf.length )
+            {
+                String value = readString( buf, pos );
+                pos += ( value.length() << 1 ) + 4;
+                attr.add( value );
+            }
+        }
+        else
+        {
+            pos++;
+            while ( pos < buf.length )
+            {
+                byte[] value = readBytes( buf, pos );
+                pos += value.length + 4;
+                attr.add( value );
+            }
+        }
+        
+        return new DeserializedAttribute( attr, pos );
+    }
+
+    
+    final static class DeserializedAttribute 
+    {
+        private final int pos;
+        private final Attribute attr;
+        
+        private DeserializedAttribute( Attribute attr, int pos )
+        {
+            this.pos = pos;
+            this.attr = attr;
+        }
+
+        public int getPos()
+        {
+            return pos;
+        }
+
+        public Attribute getAttr()
+        {
+            return attr;
+        }
+    }
+    
+    
+    /**
+     * Reads a String and it's length bytes from a buffer starting at 
+     * position 0.
+     * 
+     * @param buf the buffer to read the length and character bytes from
+     * @return the String contained at the start of the buffer
+     *
+    static final String readString( byte[] buf )
+    {
+        int length = getLength( buf );
+        
+        if ( length == 0 )
+        {
+            return "";
+        }
+
+        // create the new char buffer
+        char[] strchars = new char[length>>1];
+        
+        int ch = 0;
+        for ( int ii = 0, jj = 0; ii < strchars.length; ii++ )
+        {
+            jj = ( ii << 1 ) + 4;
+            ch = buf[jj] << 8 & 0x0000FF00;
+            ch |= buf[jj+1] & 0x000000FF;
+            strchars[ii] = ( char ) ch;
+        }
+
+        return new String( strchars );
+    }
+    
+    
+    /**
+     * Reads a String and it's length bytes from a buffer starting at 
+     * a specific offset.
+     * 
+     * @param buf the buffer to read the length and character bytes from
+     * @param offset the offset into the buffer to start reading from
+     * @return the String contained at the offset in the buffer
+     *
+    static final String readString( byte[] buf, int offset )
+    {
+        int length = getLength( buf, offset );
+        
+        if ( length == 0 )
+        {
+            return "";
+        }
+
+        // create the new char buffer
+        char[] strchars = new char[length>>1];
+        
+        int ch = 0;
+        for ( int ii = 0, jj = 0; ii < strchars.length; ii++ )
+        {
+            jj = ( ii << 1 ) + 4 + offset;
+            ch = buf[jj] << 8 & 0x0000FF00;
+            ch |= buf[jj+1] & 0x000000FF;
+            strchars[ii] = ( char ) ch;
+        }
+
+        return new String( strchars );
+    }
+    
+    
+    /**
+     * Reads a byte array from a buffer including its length starting
+     * from an offset in the buffer.
+     * 
+     * @param buf the buffer to read the byte array from
+     * @param offset the offset to start reading from starting with 4-byte 
length
+     * @return the byte array contained in the buffer
+     *
+    static final byte[] readBytes( byte[] buf, int offset )
+    {
+        int length = getLength( buf, offset );
+        
+        if ( length == 0 )
+        {
+            return StringTools.EMPTY_BYTES;
+        }
+
+        byte[] bites = new byte[length];
+        System.arraycopy( buf, offset+4, bites, 0, length );
+        return bites;
+    }
+
+    
+    // -----------------------------------------------------------------------
+    // Methods for serialization
+    // -----------------------------------------------------------------------
+    
+    
+    /**
+     * The data structure used is the following :
+     * <code>
+     * [length] : total length for this attriute
+     * [length][upId] : if the length is null, then the UpId is the 
AttributeType name
+     * [length][OID] : the attributeType OID
+     * [nb-values] : can't be 0
+     * for each value :
+     *   [length][value] : the value is stored as a byte array, even for a 
String value. 
+     *   If the length is 0, then the value is null.
+     * </code>
+     * 
+     * Here the id-length is the 4 byte int value of the length of bytes
+     * for the id string bytes.  The id-bytes are the bytes for the id string.
+     * The is-binary byte is a true or false for whether or not the values 
+     * are byte[] or String types.  Following this is an array of length-value 
+     * tuples for the values of the Attributes.  
+     * 
+     *
+    public static final byte[] serialize( Object obj ) throws IOException
+    {
+        if ( ! ( obj instanceof ServerAttribute ) )
+        {
+            String message = "The object to serialize must be a 
ServerAttribute instance";
+            LOG.error( message );
+            throw new IOException( message ); 
+        }
+        
+        ServerAttribute attr = ( ServerAttribute ) obj;
+        
+        // calculate the size of the entire byte[] and allocate
+        int globalSize = computeSize( attr );
+        ByteBuffer bb = ByteBuffer.allocate( 4096 );
+        
+        bb.hasRemaining();
+        byte[] buf = new byte[calculateSize( attr )];
+        
+        // write the length of the id and it's value
+        int pos = write( buf, attr.getID() );
+        
+        try
+        {
+            // write the type or is-binary field
+            Object first = attr.get();
+            
+            if ( first instanceof String )
+            {
+                buf[pos] = STRING_TYPE;
+                pos++;
+
+                // write out each value to the buffer whatever type it may be
+                for ( NamingEnumeration<?> ii = attr.getAll(); ii.hasMore(); )
+                {
+                    String value = ( String ) ii.next();
+                    pos = write( buf, value, pos );
+                }
+            }
+            else
+            {
+                buf[pos] = BYTE_ARRAY_TYPE;
+                pos++;
+
+                // write out each value to the buffer whatever type it may be
+                for ( NamingEnumeration<?> ii = attr.getAll(); ii.hasMore(); )
+                {
+                    byte[] value = ( byte[] ) ii.next();
+                    pos = write( buf, value, pos );
+                }
+            }
+
+        }
+        catch ( NamingException e )
+        {
+            IOException ioe = new IOException( "Failed while accesssing 
attribute values." );
+            ioe.initCause( e );
+            throw ioe;
+        }
+        
+        return buf;
+    }
+    
+    
+    static final int computeSize( ServerAttribute attr, InnerData data ) 
throws IOException
+    {
+        // start with first length for attribute id
+        int size = 4; 
+    
+        // Compute the ID length
+        String upId = attr.getUpId();
+        
+        if ( !StringTools.isEmpty( upId ) )
+        {
+            data.upIdBytes = StringTools.getBytesUtf8( upId );
+            size += data.upIdBytes.length; // 
+        }
+        
+        // get the AttributeType OID length
+        try
+        {
+            data.oidBytes = new OID( attr.getType().getOid() ).getOID();
+        }
+        catch ( DecoderException de )
+        {
+            String message = "Bad OID : '" + attr.getType().getOid() + "'";
+            LOG.error( message );
+            throw new IOException( message );
+        }
+        
+        size += 4;
+        size += data.oidBytes.length;
+        
+        // Get the number of values
+        size += 4;
+        
+        // For each value, compute its size
+        if ( attr.size() != 0 )
+        {
+            Iterator<ServerValue<?>> values = attr.getAll();
+            data.normalizedBytes = new byte[(attr.size())][];
+            data.wrappedBytes = new byte[(attr.size())][];
+            int valueNb = 0;;
+            
+            while ( values.hasNext() )
+            {
+                ServerValue<?> value = values.next();
+                
+                // To store the value length
+                size += 4;
+                
+                if ( value.get() == null )
+                {
+                    // We have a null value : do nothing
+                    continue;
+                }
+                else if ( value instanceof ServerStringValue )
+                {
+                    data.wrappedBytes[valueNb] = StringTools.getBytesUtf8( 
((ServerStringValue)value).get() );
+                    size += data.wrappedBytes[valueNb].length;
+
+                    try
+                    {
+                        data.normalizedBytes[valueNb] = 
StringTools.getBytesUtf8( ((ServerStringValue)value).getNormalized() );
+                        size += data.normalizedBytes[valueNb].length;
+                    }
+                    catch ( NamingException ne )
+                    {
+                        String message = "Cannot compute the Normalized length 
for this String value";
+                        LOG.error( message );
+                        throw new IOException( message ); 
+                    }
+                }
+                else
+                {
+                    // We have a Binary value. Compute the wrapped size
+                    data.wrappedBytes[valueNb] = 
((ServerBinaryValue)value).getReference();
+                    size += data.wrappedBytes[valueNb].length;
+                    
+                    // Now, if the normalized value is different, store it
+                    if ( attr.isDifferent() )
+                    {
+                        try
+                        {
+                            data.normalizedBytes[valueNb] = 
((ServerBinaryValue)value).getNormalizedReference();
+                            size += data.normalizedBytes[valueNb].length;
+                        }
+                        catch ( NamingException ne )
+                        {
+                            String message = "Cannot compute the Normalized 
length for this binary value";
+                            LOG.error( message );
+                            throw new IOException( message ); 
+                        }
+                    }
+                    else
+                    {
+                        size += 4;
+                    }
+                }
+            }
+        }
+        else
+        {
+            // We don't have any value : the length will be 0
+            size += 4;
+        }
+        
+        return size;
+    }
+    
+    
+    static final byte[] getLengthBytes( String str )
+    {
+        return getLengthBytes( str.length() << 1 );
+    }
+    
+    
+    static final byte[] getLengthBytes( byte[] bites )
+    {
+        return getLengthBytes( bites.length );
+    }
+
+    
+    static final byte[] getLengthBytes( int length )
+    {
+        byte[] lengthBytes = new byte[4];
+
+        lengthBytes[0] = ( byte ) ( length >> 24 & 0x000000FF );
+        lengthBytes[1] = ( byte ) ( length >> 16 & 0x000000FF );
+        lengthBytes[2] = ( byte ) ( length >> 8 & 0x000000FF );
+        lengthBytes[3] = ( byte ) ( length & 0x000000FF );
+        
+        return lengthBytes;
+    }
+
+    
+    static final int getLength( byte[] bites )
+    {
+        int length  = bites[0] << 24 & 0xFF000000;
+        length     |= bites[1] << 16 & 0x00FF0000;
+        length     |= bites[2] <<  8 & 0x0000FF00;
+        length     |= bites[3]       & 0x000000FF;
+        
+        return length;
+    }
+
+    
+    static final int getLength( byte[] bites, int offset )
+    {
+        int length  = bites[offset]   << 24 & 0xFF000000;
+        length     |= bites[offset+1] << 16 & 0x00FF0000;
+        length     |= bites[offset+2] <<  8 & 0x0000FF00;
+        length     |= bites[offset+3]       & 0x000000FF;
+        
+        return length;
+    }
+
+    
+    static final int write( byte[] buf, String value )
+    {
+        int pos = writeLengthBytes( buf, value.length() << 1 );
+        return writeValueBytes( buf, value, pos );
+    }
+    
+
+    static final int write( byte[] buf, byte[] value )
+    {
+        int pos = writeLengthBytes( buf, value.length );
+        return writeValueBytes( buf, value, pos );
+    }
+    
+
+    static final int write( byte[] buf, String value, int offset )
+    {
+        offset = writeLengthBytes( buf, value.length() << 1, offset );
+        return writeValueBytes( buf, value, offset );
+    }
+    
+
+    static final int write( byte[] buf, byte[] value, int offset )
+    {
+        offset = writeLengthBytes( buf, value.length, offset );
+        return writeValueBytes( buf, value, offset );
+    }
+    
+
+    static final int writeValueBytes( byte[] buf, String value )
+    {
+        if ( value.length() == 0 )
+        {
+            return 0;
+        }
+        
+        char[] strchars = value.toCharArray();
+        int jj = 0;
+        for ( int ii = 0; ii < strchars.length; ii++, jj = ii << 1 )
+        {
+            buf[jj] = ( byte ) ( strchars[ii] >> 8 & 0x00FF );
+            buf[jj+1] = ( byte ) ( strchars[ii] & 0x00FF );
+        }
+        return jj+2;
+    }
+
+    
+    static final int writeValueBytes( byte[] buf, String value, int offset )
+    {
+        if ( value.length() == 0 )
+        {
+            return offset;
+        }
+        
+        char[] strchars = value.toCharArray();
+        int jj = 0;
+        for ( int ii = 0; ii < strchars.length; ii++, jj = ii << 1 )
+        {
+            buf[jj+offset] = ( byte ) ( strchars[ii] >> 8 & 0x00FF );
+            buf[jj+offset+1] = ( byte ) ( strchars[ii] & 0x00FF );
+        }
+        return jj+offset;
+    }
+
+    
+    static final int writeValueBytes( byte[] buf, byte[] value, int offset )
+    {
+        if ( value.length == 0 )
+        {
+            return offset;
+        }
+
+        System.arraycopy( value, 0, buf, offset, value.length );
+        return offset + value.length;
+    }
+
+    
+    static final int writeLengthBytes( byte[] buf, int length )
+    {
+        buf[0] = ( byte ) ( length >> 24 & 0x000000FF );
+        buf[1] = ( byte ) ( length >> 16 & 0x000000FF );
+        buf[2] = ( byte ) ( length >> 8 & 0x000000FF );
+        buf[3] = ( byte ) ( length & 0x000000FF );
+        return 4;
+    }
+    
+    
+    static final int writeLengthBytes( byte[] buf, int length, int offset )
+    {
+        buf[0+offset] = ( byte ) ( length >> 24 & 0x000000FF );
+        buf[1+offset] = ( byte ) ( length >> 16 & 0x000000FF );
+        buf[2+offset] = ( byte ) ( length >> 8 & 0x000000FF );
+        buf[3+offset] = ( byte ) ( length & 0x000000FF );
+        return offset+4;
+    }*/
+}

Modified: 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerBinaryValue.java
URL: 
http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerBinaryValue.java?rev=610856&r1=610855&r2=610856&view=diff
==============================================================================
--- 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerBinaryValue.java
 (original)
+++ 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerBinaryValue.java
 Thu Jan 10 10:09:16 2008
@@ -51,6 +51,9 @@
 
     /** the canonical representation of the wrapped binary value */
     private transient byte[] normalizedValue;
+    
+    /** A flag set if the normalized data is different from the wrapped data */
+    private transient boolean same;
 
     /** cached results of the isValid() method call */
     private transient Boolean valid;
@@ -161,6 +164,15 @@
             else
             {
                 normalizedValue = ( byte[] ) normalizer.normalize( getCopy() );
+            }
+            
+            if ( Arrays.equals( super.getReference(), normalizedValue ) )
+            {
+                same = true;
+            }
+            else
+            {
+                same = false;
             }
         }
 

Added: 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntrySerializerUtils.java
URL: 
http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntrySerializerUtils.java?rev=610856&view=auto
==============================================================================
--- 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntrySerializerUtils.java
 (added)
+++ 
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntrySerializerUtils.java
 Thu Jan 10 10:09:16 2008
@@ -0,0 +1,190 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.entry;
+
+
+import java.io.IOException;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+
+import org.apache.directory.shared.ldap.message.AttributeImpl;
+import org.apache.directory.shared.ldap.message.AttributesImpl;
+
+/**
+ *
+ * @author <a href="mailto:dev@xxxxxxxxxxxxxxxxxxxx";>Apache Directory 
Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ServerEntrySerializerUtils
+{
+    private static final long serialVersionUID = -3756830073760754086L;
+    private static final byte SEPARATOR = -1;
+
+
+    /**
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     *
+    public static final Object deserialize( byte[] buf )
+    {
+        if ( buf.length == 0 )
+        {
+            return new AttributesImpl();
+        }
+
+        int pos = 0;
+        AttributesImpl attrs = new AttributesImpl();
+        
+        while ( pos < buf.length )
+        {
+            String id = ServerAttributeSerializerUtils.readString( buf, pos );
+            AttributeImpl attr = new AttributeImpl( id );
+            pos += ( id.length() << 1 ) + 4;
+
+            // read the type of the objects stored in this attribute
+            if ( buf[pos] == ServerAttributeSerializerUtils.STRING_TYPE )
+            {
+                pos++;
+                while ( pos < buf.length && buf[pos] != SEPARATOR )
+                {
+                    String value = ServerAttributeSerializerUtils.readString( 
buf, pos );
+                    pos += ( value.length() << 1 ) + 4;
+                    attr.add( value );
+                }
+            }
+            else
+            {
+                pos++;
+                while ( pos < buf.length && buf[pos] != SEPARATOR )
+                {
+                    byte[] value = ServerAttributeSerializerUtils.readBytes( 
buf, pos );
+                    pos += value.length + 4;
+                    attr.add( value );
+                }
+            }
+
+            pos++; // skip the separator
+            attrs.put( attr );
+        }
+
+        return attrs;
+    }
+
+
+    /**
+     * @see jdbm.helper.Serializer#serialize(java.lang.Object)
+     *
+    public static final byte[] serialize( Object attrsObj ) throws IOException
+    {
+        Attributes attrs = ( Attributes ) attrsObj;
+
+        // calculate the size of the entire byte[] and allocate
+        byte[] buf = new byte[calculateSize( attrs )];
+        int pos = 0;
+        
+        try
+        {
+            for ( NamingEnumeration<? extends Attribute> ii = attrs.getAll(); 
ii.hasMore(); )
+            {
+                // get an attribute at a time
+                Attribute attr = ii.next();
+
+                // write the length of the id and it's value
+                pos = ServerAttributeSerializerUtils.write( buf, attr.getID(), 
pos );
+
+                // write the type or is-binary field
+                Object first = attr.get();
+                if ( first instanceof String )
+                {
+                    buf[pos] = ServerAttributeSerializerUtils.STRING_TYPE;
+                    pos++;
+
+                    // write out each value to the buffer whatever type it may 
be
+                    for ( NamingEnumeration<?> jj = attr.getAll(); 
jj.hasMore(); )
+                    {
+                        String value = ( String ) jj.next();
+                        pos = ServerAttributeSerializerUtils.write( buf, 
value, pos );
+                    }
+                }
+                else
+                {
+                    buf[pos] = ServerAttributeSerializerUtils.BYTE_ARRAY_TYPE;
+                    pos++;
+
+                    // write out each value to the buffer whatever type it may 
be
+                    for ( NamingEnumeration<?> jj = attr.getAll(); 
jj.hasMore(); )
+                    {
+                        byte[] value = ( byte[] ) jj.next();
+                        pos = ServerAttributeSerializerUtils.write( buf, 
value, pos );
+                    }
+                }
+                
+                if ( ii.hasMore() )
+                {
+                    buf[pos] = SEPARATOR;
+                    pos++;
+                }
+            }
+        }
+        catch ( NamingException e )
+        {
+            IOException ioe = new IOException( "Failed while accesssing 
attributes and/or their values." );
+            ioe.initCause( e );
+            throw ioe;
+        }
+
+        return buf;
+    }
+
+
+    private static final int calculateSize( Attributes attrs ) throws 
IOException
+    {
+        int size = 0;
+
+        try
+        {
+            for ( NamingEnumeration<? extends Attribute> ii = attrs.getAll(); 
ii.hasMore(); )
+            {
+                Attribute attr = ( Attribute ) ii.next();
+
+                if ( ii.hasMore() )
+                {
+                    // augment by attribute size and 1 for the separator
+                    size += ServerAttributeSerializerUtils.calculateSize( attr 
) + 1;
+                }
+                else
+                {
+                    // augment by attribute size only since there are no more 
attributes left
+                    size += ServerAttributeSerializerUtils.calculateSize( attr 
);
+                }
+            }
+        }
+        catch ( NamingException e )
+        {
+            IOException ioe = new IOException( "Failed while accesssing 
attributes." );
+            ioe.initCause( e );
+            throw ioe;
+        }
+
+        return size;
+    }*/
+}

Modified: 
directory/apacheds/branches/bigbang/core-entry/src/test/java/org/apache/directory/server/core/entry/DefaultServerEntryTest.java
URL: 
http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/test/java/org/apache/directory/server/core/entry/DefaultServerEntryTest.java?rev=610856&r1=610855&r2=610856&view=diff
==============================================================================
--- 
directory/apacheds/branches/bigbang/core-entry/src/test/java/org/apache/directory/server/core/entry/DefaultServerEntryTest.java
 (original)
+++ 
directory/apacheds/branches/bigbang/core-entry/src/test/java/org/apache/directory/server/core/entry/DefaultServerEntryTest.java
 Thu Jan 10 10:09:16 2008
@@ -20,7 +20,6 @@
 package org.apache.directory.server.core.entry;
 
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -30,6 +29,7 @@
 import javax.naming.NamingException;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.InvalidAttributeValueException;
 
 import org.apache.directory.server.schema.bootstrap.ApacheSchema;
 import org.apache.directory.server.schema.bootstrap.ApachemetaSchema;
@@ -47,11 +47,6 @@
 import org.apache.directory.shared.ldap.message.AttributesImpl;
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.schema.AttributeType;
-import org.apache.directory.shared.ldap.schema.MatchingRule;
-import org.apache.directory.shared.ldap.schema.Normalizer;
-import org.apache.directory.shared.ldap.schema.Syntax;
-import org.apache.directory.shared.ldap.schema.UsageEnum;
-import org.apache.directory.shared.ldap.schema.syntax.SyntaxChecker;
 import org.apache.directory.shared.ldap.util.StringTools;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -73,7 +68,7 @@
     private static BootstrapSchemaLoader loader;
     private static Registries registries;
     private static OidRegistry oidRegistry;
-    private static AttributeType AT;
+    //private static AttributeType AT;
     
     /**
      * Initialize the registries once for the whole test suite
@@ -95,6 +90,7 @@
         bootstrapSchemas.add( new CosineSchema() );
         loader.loadWithDependencies( bootstrapSchemas, registries );
         
+        /*
         AT = new AttributeType()
         {
             private static final long serialVersionUID = 1L;
@@ -367,14 +363,10 @@
             public void setSchema( String schemaName )
             {
             }
-        };
+        };*/
     }
 
 
-    //-------------------------------------------------------------------------
-    // Test the constructors
-    //-------------------------------------------------------------------------
-    
     /**
      * Test a conversion from a ServerEntry to an AttributesImpl
      */
@@ -454,7 +446,7 @@
     /**
      * Test the set(AT...) method
      */
-    @Test public void tesSetATElipsis() throws NamingException
+    @Test public void testSetATElipsis() throws NamingException
     {
         LdapDN dn = new LdapDN( "cn=test" );
         DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
@@ -968,6 +960,10 @@
         assertEquals( 2, entry.get( atCN ).size() );
         assertTrue( entry.contains( "cn", "test1" ) );
         assertTrue( entry.contains( "cn", "test2" ) );
+        
+        // Check the UpId
+        entry.put( "CN", "test4" );
+        assertEquals( "CN", entry.get( atCN ).getUpId() );
     }
     
 
@@ -1287,4 +1283,795 @@
         assertTrue( entry.contains( "CN", "test2" ) );
         assertTrue( entry.contains( "commonName", "test3" ) );
     }
+
+    
+    //-------------------------------------------------------------------------
+    // Test the Add methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Test the add( AT, String... ) method
+     */
+    @Test public void testAddAtStringElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atCN = registries.getAttributeTypeRegistry().lookup( 
"cn" );
+        
+        // Test a simple addition
+        entry.add( atCN, "test1" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 1, entry.get( atCN ).size() );
+        assertEquals( "test1", entry.get( atCN ).get().get() );
+        
+        // Test some more addition
+        entry.add( atCN, "test2", "test3" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test some addition of existing values
+        entry.add( atCN, "test2" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test the addition of a null value
+        entry.add( atCN, (String)null );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 4, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        assertTrue( entry.contains( atCN, (String )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a binary value
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+        
+        try
+        {
+            entry.add( atCN, test4 );
+            fail();
+        }
+        catch ( InvalidAttributeValueException iave )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    /**
+     * Test the add( AT, byte[]... ) method
+     */
+    @Test public void testAddAtBytesElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atPassword = 
registries.getAttributeTypeRegistry().lookup( "userPassword" );
+        
+        byte[] test1 = StringTools.getBytesUtf8( "test1" );
+        byte[] test2 = StringTools.getBytesUtf8( "test2" );
+        byte[] test3 = StringTools.getBytesUtf8( "test3" );
+        
+        // Test a simple addition
+        entry.add( atPassword, test1 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( Arrays.equals( test1, (byte[])entry.get( atPassword 
).get().get() ) );
+        
+        // Test some more addition
+        entry.add( atPassword, test2, test3 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        
+        // Test some addition of existing values
+        entry.add( atPassword, test2 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        
+        // Test the addition of a null value
+        entry.add( atPassword, (byte[])null );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 4, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        assertTrue( entry.contains( atPassword, (byte[] )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+
+        entry.add( atPassword, "test4" );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test4 ) );
+    }
+
+
+    /**
+     * Test the add( AT, SV... ) method
+     */
+    @Test public void testAddAtServerValueElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atCN = registries.getAttributeTypeRegistry().lookup( 
"cn" );
+        AttributeType atPassword = 
registries.getAttributeTypeRegistry().lookup( "userPassword" );
+        
+        byte[] b1 = StringTools.getBytesUtf8( "test1" );
+        byte[] b2 = StringTools.getBytesUtf8( "test2" );
+        byte[] b3 = StringTools.getBytesUtf8( "test3" );
+
+        ServerValue<String> test1 = new ServerStringValue( atCN, "test1" );
+        ServerValue<String> test2 = new ServerStringValue( atCN, "test2" );
+        ServerValue<String> test3 = new ServerStringValue( atCN, "test3" );
+        
+        ServerValue<byte[]> testB1 = new ServerBinaryValue( atPassword, b1 );
+        ServerValue<byte[]> testB2 = new ServerBinaryValue( atPassword, b2 );
+        ServerValue<byte[]> testB3 = new ServerBinaryValue( atPassword, b3 );
+        
+        // Test a simple addition in atCN
+        entry.add( atCN, test1 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 1, entry.get( atCN ).size() );
+        assertEquals( "test1", entry.get( atCN ).get().get() );
+        
+        // Test some more addition
+        entry.add( atCN, test2, test3 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test some addition of existing values
+        entry.add( atCN, test2 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test the addition of a null value
+        entry.add( atCN, (String)null );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 4, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        assertTrue( entry.contains( atCN, (String )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+
+        try
+        {
+            entry.add( atCN, test4 );
+            fail();
+        }
+        catch ( InvalidAttributeValueException iave )
+        {
+            assertTrue( true );
+        }
+
+        // Now, work with a binary attribute
+        // Test a simple addition
+        entry.add( atPassword, testB1 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( Arrays.equals( b1, (byte[])entry.get( atPassword 
).get().get() ) );
+        
+        // Test some more addition
+        entry.add( atPassword, testB2, testB3 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        
+        // Test some addition of existing values
+        entry.add( atPassword, testB2 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        
+        // Test the addition of a null value
+        entry.add( atPassword, (byte[])null );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 4, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        assertTrue( entry.contains( atPassword, (byte[] )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] b4 = StringTools.getBytesUtf8( "test4" );
+
+        entry.add( atPassword, "test4" );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b4 ) );
+    }
+
+
+    /**
+     * Test the add( upId, String... ) method
+     */
+    @Test public void testAddUpIdStringElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atCN = registries.getAttributeTypeRegistry().lookup( 
"cn" );
+        
+        // Test a simple addition
+        entry.add( "CN", "test1" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( atCN, entry.get( atCN ).getType() );
+        assertEquals( "cn", entry.get( atCN ).getType().getName() );
+        assertEquals( "CN", entry.get( atCN ).getUpId() );
+        assertEquals( 1, entry.get( atCN ).size() );
+        assertEquals( "test1", entry.get( atCN ).get().get() );
+        
+        // Test some more addition
+        entry.add( "CN", "test2", "test3" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test some addition of existing values
+        entry.add( "CN", "test2" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test the addition of a null value
+        entry.add( "CN", (String)null );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 4, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        assertTrue( entry.contains( atCN, (String )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a binary value
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+        
+        try
+        {
+            entry.add( "CN", test4 );
+            fail();
+        }
+        catch ( InvalidAttributeValueException iave )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    /**
+     * Test the add( upId, byte[]... ) method
+     */
+    @Test public void testAddUpIdBytesElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atPassword = 
registries.getAttributeTypeRegistry().lookup( "userPassword" );
+        
+        byte[] test1 = StringTools.getBytesUtf8( "test1" );
+        byte[] test2 = StringTools.getBytesUtf8( "test2" );
+        byte[] test3 = StringTools.getBytesUtf8( "test3" );
+        
+        // Test a simple addition
+        entry.add( "userPassword", test1 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( Arrays.equals( test1, (byte[])entry.get( atPassword 
).get().get() ) );
+        
+        // Test some more addition
+        entry.add( "userPassword", test2, test3 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        
+        // Test some addition of existing values
+        entry.add( "userPassword", test2 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        
+        // Test the addition of a null value
+        entry.add( "userPassword", (byte[])null );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 4, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        assertTrue( entry.contains( atPassword, (byte[] )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+
+        entry.add( "userPassword", "test4" );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test4 ) );
+    }
+
+
+    /**
+     * Test the add( upId, SV... ) method
+     */
+    @Test public void testAddUpIdServerValueElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atCN = registries.getAttributeTypeRegistry().lookup( 
"cn" );
+        AttributeType atPassword = 
registries.getAttributeTypeRegistry().lookup( "userPassword" );
+        
+        byte[] b1 = StringTools.getBytesUtf8( "test1" );
+        byte[] b2 = StringTools.getBytesUtf8( "test2" );
+        byte[] b3 = StringTools.getBytesUtf8( "test3" );
+
+        ServerValue<String> test1 = new ServerStringValue( atCN, "test1" );
+        ServerValue<String> test2 = new ServerStringValue( atCN, "test2" );
+        ServerValue<String> test3 = new ServerStringValue( atCN, "test3" );
+        
+        ServerValue<byte[]> testB1 = new ServerBinaryValue( atPassword, b1 );
+        ServerValue<byte[]> testB2 = new ServerBinaryValue( atPassword, b2 );
+        ServerValue<byte[]> testB3 = new ServerBinaryValue( atPassword, b3 );
+        
+        // Test a simple addition in atCN
+        entry.add( "cN", test1 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 1, entry.get( atCN ).size() );
+        assertEquals( "test1", entry.get( atCN ).get().get() );
+        assertEquals( atCN, entry.get( atCN ).getType() );
+        assertEquals( "cN", entry.get( atCN ).getUpId() );
+        
+        // Test some more addition
+        entry.add( "cN", test2, test3 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        assertEquals( atCN, entry.get( atCN ).getType() );
+        assertEquals( "cN", entry.get( atCN ).getUpId() );
+        
+        // Test some addition of existing values
+        entry.add( "cN", test2 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test the addition of a null value
+        entry.add( "cN", (String)null );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 4, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        assertTrue( entry.contains( atCN, (String )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+
+        try
+        {
+            entry.add( "cN", test4 );
+            fail();
+        }
+        catch ( InvalidAttributeValueException iave )
+        {
+            assertTrue( true );
+        }
+
+        // Now, work with a binary attribute
+        // Test a simple addition
+        entry.add( "userPASSWORD", testB1 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( Arrays.equals( b1, (byte[])entry.get( atPassword 
).get().get() ) );
+        assertEquals( atPassword, entry.get( atPassword ).getType() );
+        assertEquals( "userPASSWORD", entry.get( atPassword ).getUpId() );
+        
+        // Test some more addition
+        entry.add( "userPASSWORD", testB2, testB3 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        
+        // Test some addition of existing values
+        entry.add( "userPASSWORD", testB2 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        
+        // Test the addition of a null value
+        entry.add( "userPASSWORD", (byte[])null );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 4, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        assertTrue( entry.contains( atPassword, (byte[] )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] b4 = StringTools.getBytesUtf8( "test4" );
+
+        entry.add( "userPASSWORD", "test4" );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b4 ) );
+    }
+
+
+    /**
+     * Test the add( UpId, AT, String... ) method
+     */
+    @Test public void testAddUpIdAtStringElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atCN = registries.getAttributeTypeRegistry().lookup( 
"cn" );
+        
+        // Test a simple addition
+        entry.add( "cn", atCN, "test1" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 1, entry.get( atCN ).size() );
+        assertEquals( "test1", entry.get( atCN ).get().get() );
+        
+        // Test some more addition
+        entry.add( "CN", atCN, "test2", "test3" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test some addition of existing values
+        entry.add( "commonName", atCN, "test2" );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test the addition of a null value
+        entry.add( "COMMONname", atCN, (String)null );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 4, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        assertTrue( entry.contains( atCN, (String )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a binary value
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+        
+        try
+        {
+            entry.add( "cn", atCN, test4 );
+            fail();
+        }
+        catch ( InvalidAttributeValueException iave )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    /**
+     * Test the add( upId, AT, byte[]... ) method
+     */
+    @Test public void testAddUpIdAtBytesElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atPassword = 
registries.getAttributeTypeRegistry().lookup( "userPassword" );
+        
+        byte[] test1 = StringTools.getBytesUtf8( "test1" );
+        byte[] test2 = StringTools.getBytesUtf8( "test2" );
+        byte[] test3 = StringTools.getBytesUtf8( "test3" );
+        
+        // Test a simple addition
+        entry.add( "userPassword", atPassword, test1 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( Arrays.equals( test1, (byte[])entry.get( atPassword 
).get().get() ) );
+        
+        // Test some more addition
+        entry.add( "userPassword", atPassword, test2, test3 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        
+        // Test some addition of existing values
+        entry.add( "userPassword", atPassword, test2 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        
+        // Test the addition of a null value
+        entry.add( "userPassword", atPassword, (byte[])null );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 4, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test1 ) );
+        assertTrue( entry.contains( atPassword, test2 ) );
+        assertTrue( entry.contains( atPassword, test3 ) );
+        assertTrue( entry.contains( atPassword, (byte[] )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+
+        entry.add( "userPassword", atPassword, "test4" );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, test4 ) );
+    }
+
+
+    /**
+     * Test the add( upId, AT, SV... ) method
+     */
+    @Test public void testAddUpIdAtServerValueElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atCN = registries.getAttributeTypeRegistry().lookup( 
"cn" );
+        AttributeType atPassword = 
registries.getAttributeTypeRegistry().lookup( "userPassword" );
+        
+        byte[] b1 = StringTools.getBytesUtf8( "test1" );
+        byte[] b2 = StringTools.getBytesUtf8( "test2" );
+        byte[] b3 = StringTools.getBytesUtf8( "test3" );
+
+        ServerValue<String> test1 = new ServerStringValue( atCN, "test1" );
+        ServerValue<String> test2 = new ServerStringValue( atCN, "test2" );
+        ServerValue<String> test3 = new ServerStringValue( atCN, "test3" );
+        
+        ServerValue<byte[]> testB1 = new ServerBinaryValue( atPassword, b1 );
+        ServerValue<byte[]> testB2 = new ServerBinaryValue( atPassword, b2 );
+        ServerValue<byte[]> testB3 = new ServerBinaryValue( atPassword, b3 );
+        
+        // Test a simple addition in atCN
+        entry.add( "cN", atCN, test1 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 1, entry.get( atCN ).size() );
+        assertEquals( "test1", entry.get( atCN ).get().get() );
+        assertEquals( atCN, entry.get( atCN ).getType() );
+        assertEquals( "cN", entry.get( atCN ).getUpId() );
+        
+        // Test some more addition
+        entry.add( "cN", atCN, test2, test3 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        assertEquals( atCN, entry.get( atCN ).getType() );
+        assertEquals( "cN", entry.get( atCN ).getUpId() );
+        
+        // Test some addition of existing values
+        entry.add( "cN", atCN, test2 );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 3, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        
+        // Test the addition of a null value
+        entry.add( "cN", atCN, (String)null );
+        assertNotNull( entry.get( atCN ) );
+        assertEquals( 4, entry.get( atCN ).size() );
+        assertTrue( entry.contains( atCN, "test1" ) );
+        assertTrue( entry.contains( atCN, "test2" ) );
+        assertTrue( entry.contains( atCN, "test3" ) );
+        assertTrue( entry.contains( atCN, (String )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] test4 = StringTools.getBytesUtf8( "test4" );
+
+        try
+        {
+            entry.add( "cN", atCN, test4 );
+            fail();
+        }
+        catch ( InvalidAttributeValueException iave )
+        {
+            assertTrue( true );
+        }
+
+        // Now, work with a binary attribute
+        // Test a simple addition
+        entry.add( "userPASSWORD", atPassword, testB1 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( Arrays.equals( b1, (byte[])entry.get( atPassword 
).get().get() ) );
+        assertEquals( atPassword, entry.get( atPassword ).getType() );
+        assertEquals( "userPASSWORD", entry.get( atPassword ).getUpId() );
+        
+        // Test some more addition
+        entry.add( "userPASSWORD", atPassword, testB2, testB3 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        
+        // Test some addition of existing values
+        entry.add( "userPASSWORD", atPassword, testB2 );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 3, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        
+        // Test the addition of a null value
+        entry.add( "userPASSWORD", atPassword, (byte[])null );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 4, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b1 ) );
+        assertTrue( entry.contains( atPassword, b2 ) );
+        assertTrue( entry.contains( atPassword, b3 ) );
+        assertTrue( entry.contains( atPassword, (byte[] )null ) ); 
+        
+        entry.clear();
+        
+        // Test the addition of a String value. It should be converted to a 
byte array
+        byte[] b4 = StringTools.getBytesUtf8( "test4" );
+
+        entry.add( "userPASSWORD", atPassword, "test4" );
+        assertNotNull( entry.get( atPassword ) );
+        assertEquals( 1, entry.get( atPassword ).size() );
+        assertTrue( entry.contains( atPassword, b4 ) );
+    }
+
+    //-------------------------------------------------------------------------
+    // Test the remove method
+    //-------------------------------------------------------------------------
+
+    /**
+     * Test the remove( AT...) method
+     */
+    @Test public void testRemoveAtElipsis()
+    {
+        
+    }
+
+    /**
+     * Test the remove( upId...) method
+     */
+    @Test public void testRemoveUpIdElipsis() throws NamingException
+    {
+        LdapDN dn = new LdapDN( "cn=test" );
+        DefaultServerEntry entry = new DefaultServerEntry( registries, dn );
+        
+        AttributeType atCN = registries.getAttributeTypeRegistry().lookup( 
"cn" );
+        AttributeType atPassword = 
registries.getAttributeTypeRegistry().lookup( "userPassword" );
+        
+        byte[] b1 = StringTools.getBytesUtf8( "test1" );
+        byte[] b2 = StringTools.getBytesUtf8( "test2" );
+        byte[] b3 = StringTools.getBytesUtf8( "test3" );
+
+        ServerValue<String> test1 = new ServerStringValue( atCN, "test1" );
+        ServerValue<String> test2 = new ServerStringValue( atCN, "test2" );
+        
+        ServerValue<byte[]> testB1 = new ServerBinaryValue( atPassword, b1 );
+        ServerValue<byte[]> testB2 = new ServerBinaryValue( atPassword, b2 );
+        
+        // test a removal of an non existing attribute
+        List<ServerAttribute> removed = entry.remove( atCN );
+        assertEquals( 0, removed.size() );
+        
+        // Test a simple removal
+        entry.add( "cN", atCN, test1 );
+        assertEquals( 2, entry.size() );
+        assertNotNull( entry.get( atCN ) );
+        entry.remove( "CN" );
+        assertEquals( 1, entry.size() );
+        assertNull( entry.get( atCN ) );
+        
+        // Test a removal of many elements
+        entry.put( "CN", test1, test2 );
+        entry.put( "userPassword", testB1, testB2 );
+        assertEquals( 3, entry.size() );
+        assertNotNull( entry.get( atCN ) );
+        assertNotNull( entry.get( atPassword ) );
+        
+        AttributeType OBJECT_CLASS_AT = 
registries.getAttributeTypeRegistry().lookup( SchemaConstants.OBJECT_CLASS_AT );
+        
+        entry.remove( "cN", "UsErPaSsWoRd" );
+        assertEquals( 1, entry.size() );
+        assertNull( entry.get( atCN ) );
+        assertNull( entry.get( atPassword ) );
+        assertTrue( entry.contains( OBJECT_CLASS_AT, "top" ) );
+        
+        // test the removal of a bad Attribute
+        entry.put( "CN", test1, test2 );
+        entry.put( "userPassword", testB1, testB2 );
+        assertEquals( 3, entry.size() );
+        assertNotNull( entry.get( atCN ) );
+        assertNotNull( entry.get( atPassword ) );
+        
+        try
+        {
+            entry.remove( "badAttribute" );
+            fail();
+        }
+        catch ( NamingException ne )
+        {
+            assertTrue( true );
+        }
+    }
+
+    /**
+     * Test the remove( SA...) method
+     */
+    @Test public void testRemoveSaElipsis()
+    {
+        
+    }
+
 }
+

Modified: 
directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchWithIndicesITest.java
URL: 
http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchWithIndicesITest.java?rev=610856&r1=610855&r2=610856&view=diff
==============================================================================
--- 
directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchWithIndicesITest.java
 (original)
+++ 
directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchWithIndicesITest.java
 Thu Jan 10 10:09:16 2008
@@ -131,20 +131,19 @@
             JdbmPartition partition = new JdbmPartition();
             partition.setId( "system" );
             
-            /*
-            ServerEntry serverEntry = new DefaultServerEntry( new LdapDN( 
"ou=system" ), service.getRegistries() );
-            serverEntry.put( "objectClass", "top", "organizationalUnit" );
-            serverEntry.put( "ou", "system" );
-            partition.setContextEntry( serverEntry );
-            partition.setSuffix( "ou=system" );
-            */
-            
-            Attributes attrs = new AttributesImpl( "objectClass", "top", true 
);
-            attrs.get( "objectClass" ).add( "organizationalUnit" );
-            attrs.put( "ou", "system" );
-            partition.setContextEntry( attrs );
-            partition.setSuffix( "ou=system" );
-            
+            try
+            {
+                ServerEntry serverEntry = new DefaultServerEntry( 
service.getRegistries(), new LdapDN( "ou=system" ) );
+                serverEntry.put( "objectClass", "top", "organizationalUnit" );
+                serverEntry.put( "ou", "system" );
+                partition.setContextEntry( serverEntry );
+                partition.setSuffix( "ou=system" );
+
+            }
+            catch ( NamingException ne )
+            {
+                // Do nothing
+            }
 
             Set<Index> indices = new HashSet<Index>();
             indices.addAll( partition.getIndexedAttributes() );


<Prev in Thread] Current Thread [Next in Thread>
  • svn commit: r610856 [1/2] - in /directory: apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ apacheds/branches/bigbang/core-entry/src/test/java/org/apache/directory/server/core/entry/ apacheds/branches/bigbang/c..., elecharny <=