directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r609459 [1/4] - in /directory: apacheds/branches/bigbang/bootstrap-plugin/ apacheds/branches/bigbang/bootstrap-plugin/src/main/java/org/apache/directory/server/core/bootstrap/plugin/ apacheds/branches/bigbang/core-entry/src/main/java/org/ap...
Date Sun, 06 Jan 2008 22:58:16 GMT
Author: elecharny
Date: Sun Jan  6 14:58:12 2008
New Revision: 609459

URL: http://svn.apache.org/viewvc?rev=609459&view=rev
Log:
Mofified the SetContextEntry to use ServerEntry. Improved the core-entry API with lot of tests additions

Added:
    directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryPropertyEditor.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/AbstractClientAttribute.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientBinaryValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java
Removed:
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientAttribute.java
    directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/common/
Modified:
    directory/apacheds/branches/bigbang/bootstrap-plugin/pom.xml
    directory/apacheds/branches/bigbang/bootstrap-plugin/src/main/java/org/apache/directory/server/core/bootstrap/plugin/BootstrapPlugin.java
    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/DefaultServerAttribute.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/ObjectClassAttribute.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/main/java/org/apache/directory/server/core/entry/ServerEntry.java
    directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java
    directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStreamedValue.java
    directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStringValue.java
    directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerValue.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/configuration/PartitionConfigurationIT.java
    directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/MixedCaseITest.java
    directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchWithIndicesITest.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/authn/AuthenticationInterceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/authz/AciAuthorizationInterceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/interceptor/BaseInterceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/interceptor/Interceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/interceptor/InterceptorChain.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/interceptor/NextInterceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/jndi/ServerContext.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/Partition.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexusProxy.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/BTreePartition.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/sp/LdapClassLoader.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/core/src/test/java/org/apache/directory/server/core/interceptor/MockInterceptor.java
    directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/schema/PartitionSchemaLoaderTest.java
    directory/apacheds/branches/bigbang/jdbm-store/pom.xml
    directory/apacheds/branches/bigbang/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStore.java
    directory/apacheds/branches/bigbang/mitosis/src/main/java/org/apache/directory/mitosis/service/ReplicationInterceptor.java
    directory/apacheds/branches/bigbang/mitosis/src/main/java/org/apache/directory/mitosis/service/protocol/handler/ReplicationClientContextHandler.java
    directory/apacheds/branches/bigbang/protocol-kerberos/src/test/java/org/apache/directory/server/kerberos/kdc/SaslGssapiBindITest.java
    directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java
    directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/configuration/ApacheDS.java
    directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/commands/dumpcmd/DumpCommandExecutor.java
    directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/SaslBindITest.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/jndi/ServerContextFactoryTest.java
    directory/shared/branches/bigbang/ldap-constants/src/main/java/org/apache/directory/shared/ldap/constants/SchemaConstants.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/AbstractBinaryValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/AbstractStreamedValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/AbstractStringValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/EntryAttribute.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java
    directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java

Modified: directory/apacheds/branches/bigbang/bootstrap-plugin/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/bootstrap-plugin/pom.xml?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/bootstrap-plugin/pom.xml (original)
+++ directory/apacheds/branches/bigbang/bootstrap-plugin/pom.xml Sun Jan  6 14:58:12 2008
@@ -65,6 +65,12 @@
 
     <dependency>
       <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-core-entry</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
       <artifactId>apacheds-schema-bootstrap</artifactId>
       <version>${pom.version}</version>
     </dependency>

Modified: directory/apacheds/branches/bigbang/bootstrap-plugin/src/main/java/org/apache/directory/server/core/bootstrap/plugin/BootstrapPlugin.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/bootstrap-plugin/src/main/java/org/apache/directory/server/core/bootstrap/plugin/BootstrapPlugin.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/bootstrap-plugin/src/main/java/org/apache/directory/server/core/bootstrap/plugin/BootstrapPlugin.java (original)
+++ directory/apacheds/branches/bigbang/bootstrap-plugin/src/main/java/org/apache/directory/server/core/bootstrap/plugin/BootstrapPlugin.java Sun Jan  6 14:58:12 2008
@@ -22,6 +22,9 @@
 
 import org.apache.directory.server.constants.ApacheSchemaConstants;
 import org.apache.directory.server.constants.MetaSchemaConstants;
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
 import org.apache.directory.server.core.partition.impl.btree.Index;
 import org.apache.directory.server.core.partition.impl.btree.IndexNotFoundException;
 import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
@@ -202,7 +205,16 @@
         }
 
         initializeSchemas();
-        initializePartition( schemaDirectory );
+        
+        try
+        {
+            initializePartition( schemaDirectory );
+        }
+        catch ( NamingException ne )
+        {
+            throw new MojoFailureException( "Failed to initialize the root partition :" + 
+                ne.getMessage() );
+        }
 
         try
         {
@@ -616,7 +628,7 @@
      *
      * @throws MojoFailureException
      */
-    private void initializePartition( File workingDirectory ) throws MojoFailureException
+    private void initializePartition( File workingDirectory ) throws MojoFailureException, NamingException
     {
         store.setCacheSize( 1000 );
         store.setEnableOptimizer( false );
@@ -637,8 +649,8 @@
         
         store.setUserIndices( userIndices );
 
-        Attributes rootEntry = new AttributesImpl( SchemaConstants.OBJECT_CLASS_AT, 
-            SchemaConstants.ORGANIZATIONAL_UNIT_OC, true );
+        ServerEntry rootEntry = new DefaultServerEntry( registries, new LdapDN( ServerDNConstants.OU_SCHEMA_DN ) );
+        rootEntry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.ORGANIZATIONAL_UNIT_OC );
         rootEntry.put( SchemaConstants.OU_AT, "schema" );
         store.setContextEntry( rootEntry );
 

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=609459&r1=609458&r2=609459&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 Sun Jan  6 14:58:12 2008
@@ -19,8 +19,10 @@
 package org.apache.directory.server.core.entry;
 
 
+import org.apache.directory.shared.asn1.primitives.OID;
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.util.StringTools;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,7 +41,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public abstract class AbstractServerAttribute implements ServerAttribute
+public abstract class AbstractServerAttribute implements ServerAttribute, Cloneable
 {
     /** logger for reporting errors that might not be handled properly upstream */
     private static final Logger LOG = LoggerFactory.getLogger( AbstractServerAttribute.class );
@@ -58,19 +60,10 @@
     // utility methods
     // -----------------------------------------------------------------------
     /**
-     * Utility method to get some logs if an assert fails
-     */
-    protected String logAssert( String message )
-    {
-        LOG.error( message );
-        return message;
-    }
-    
-    /**
      *  Check the attributeType member. It should not be null, 
      *  and it should contains a syntax.
      */
-    protected String checkAttributeType( AttributeType attributeType )
+    protected String getErrorMessage( AttributeType attributeType )
     {
         try
         {
@@ -92,33 +85,97 @@
         }
     }
     
+    
+    /**
+     * Private helper method used to set an UpId from an attributeType
+     */
+    private String getUpId( AttributeType attributeType )
+    {
+        String upId = attributeType.getName();
+        
+        if ( upId == null )
+        {
+            upId = attributeType.getOid();
+        }
+        
+        return upId;
+    }
+    
+    
     /**
      * 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
      */
     protected void setUpId( String upId, AttributeType attributeType )
     {
-        if ( upId == null )
+        if ( StringTools.isEmpty( upId ) )
+        {
+            this.upId = getUpId( attributeType );
+        }
+        else
         {
             String name = attributeType.getName();
             
             if ( name == null )
             {
-                this.upId = attributeType.getOid();
+                // If the name is null, then we may have to store an OID
+                if ( OID.isOID( upId )  && attributeType.getOid().equals( upId ) )
+                {
+                    //  Everything is fine, store the upId. 
+                    this.upId = upId;
+                }
+                else
+                {
+                    // We have a difference or the upId is not a valid OID :
+                    // we will use the attributeTypeOID in this case.
+                    LOG.warn( "The upID ({}) is not an OID or is different from the AttributeType OID({})",
+                        upId, attributeType.getOid() );
+                    this.upId = attributeType.getOid();
+                }
             }
             else
             {
-                this.upId = name;
+                // We have at least one name. Check that the normalized upId
+                // is one of those names. Otherwise, the upId may be an OID too.
+                // In this case, it must be equals to the attributeType OID.
+                String normUpId = StringTools.trim( StringTools.toLowerCase( upId ) );
+                
+                for ( String id:attributeType.getNames() )
+                {
+                    if ( id.equalsIgnoreCase( normUpId ) )
+                    {
+                        // Found ! We can store the upId and get out
+                        this.upId = upId;
+                        return;
+                    }
+                }
+    
+                // UpId was not found in names. It should be an OID, or if not, we 
+                // will use the AttributeType name.
+                if ( OID.isOID( upId ) )
+                {
+                    // We have an OID : stores it
+                    this.upId = upId;
+                }
+                else
+                {
+                    String message = "The upID (" + upId + ") is not an OID or is different from the AttributeType OID (" + 
+                                        attributeType.getOid() + ")";
+                    // Not a valid OID : use the AttributeTypes OID name instead
+                    LOG.error( message );
+                    throw new IllegalArgumentException( message );
+                }
             }
         }
-        else
-        {
-            this.upId = upId;
-        }
     }
 
 
@@ -179,36 +236,6 @@
 
 
     /**
-     * @see EntryAttribute#add(org.apache.directory.shared.ldap.entry.Value)
-     */
-    public boolean add( ServerValue<?> val ) throws InvalidAttributeValueException, NamingException
-    {
-        if ( attributeType.getSyntax().isHumanReadable() )
-        {
-            if ( !( val instanceof ServerStringValue ) )
-            {
-                String message = "The value must be a String, as its AttributeType is H/R";
-                LOG.error( message );
-                throw new InvalidAttributeValueException( message );
-            }
-        }
-        else
-        {
-            if ( !( val instanceof ServerBinaryValue ) )
-            {
-                String message = "The value must be a byte[], as its AttributeType is not H/R";
-                LOG.error( message );
-                throw new InvalidAttributeValueException( message );
-            }
-        }
-        
-        boolean added = values.add( val );
-        
-        return added;
-    }
-
-
-    /**
      * @see EntryAttribute#add(org.apache.directory.shared.ldap.entry.Value...)
      */
     public int add( ServerValue<?>... vals ) throws InvalidAttributeValueException, NamingException
@@ -217,10 +244,27 @@
         
         for ( ServerValue<?> val:vals )
         {
-            if ( add( val ) )
+            if ( attributeType.getSyntax().isHumanReadable() )
             {
-                nbAdded ++;
+                if ( !( val instanceof ServerStringValue ) )
+                {
+                    String message = "The value must be a String, as its AttributeType is H/R";
+                    LOG.error( message );
+                    throw new InvalidAttributeValueException( message );
+                }
             }
+            else
+            {
+                if ( !( val instanceof ServerBinaryValue ) )
+                {
+                    String message = "The value must be a byte[], as its AttributeType is not H/R";
+                    LOG.error( message );
+                    throw new InvalidAttributeValueException( message );
+                }
+            }
+            
+            values.add( val );
+            nbAdded ++;
         }
         
         return nbAdded;
@@ -228,23 +272,14 @@
 
 
     /**
-     * @see EntryAttribute#add(String)
+     * @see EntryAttribute#put(org.apache.directory.shared.ldap.entry.Value...)
      */
-    public boolean add( String val ) throws InvalidAttributeValueException, NamingException
+    public int put( ServerValue<?>... vals ) throws InvalidAttributeValueException, NamingException
     {
-        if ( attributeType.getSyntax().isHumanReadable() )
-        {
-            return add( new ServerStringValue( attributeType, val ) );
-        }
-        else
-        {
-            String message = "The value must be a String, as its AttributeType is H/R";
-            LOG.error( message );
-            throw new InvalidAttributeValueException( message );
-        }
+        values.clear();
+        return add( vals );
     }
-
-
+    
     /**
      * @see EntryAttribute#add(String...)
      */
@@ -254,10 +289,18 @@
         
         for ( String val:vals )
         {
-            if ( add( val ) )
+            if ( attributeType.getSyntax().isHumanReadable() )
             {
-                nbAdded ++;
+                values.add( new ServerStringValue( attributeType, val ) );
             }
+            else
+            {
+                String message = "The value must be a String, as its AttributeType is H/R";
+                LOG.error( message );
+                throw new InvalidAttributeValueException( message );
+            }
+
+            nbAdded ++;
         }
         
         return nbAdded;
@@ -265,22 +308,14 @@
     
     
     /**
-     * @see EntryAttribute#add(byte[])
+     * @see EntryAttribute#put(String...)
      */
-    public boolean add( byte[] val ) throws InvalidAttributeValueException, NamingException
+    public int put( String... vals ) throws InvalidAttributeValueException, NamingException
     {
-        if ( ! attributeType.getSyntax().isHumanReadable() )
-        {
-            return add( new ServerBinaryValue( attributeType, val ) );
-        }
-        else
-        {
-            String message = "The value must be a byte[], as its AttributeType is not H/R";
-            LOG.error( message );
-            throw new InvalidAttributeValueException( message );
-        }
+        values.clear();
+        return add( vals );
     }
-
+    
     
     /**
      * @see EntryAttribute#add(byte[]...)
@@ -291,15 +326,34 @@
         
         for ( byte[] val:vals )
         {
-            if ( add( val ) )
+            if ( attributeType.getSyntax().isHumanReadable() )
+            {
+                String message = "The value must be a byte[], as its AttributeType is not H/R";
+                LOG.error( message );
+                throw new InvalidAttributeValueException( message );
+            }
+            else
             {
-                nbAdded ++;
+                values.add( new ServerBinaryValue( attributeType, val ) );
             }
+            
+            nbAdded ++;
         }
         
         return nbAdded;
     }    
 
+
+    /**
+     * @see EntryAttribute#put(byte[]...)
+     */
+    public int put( byte[]... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        values.clear();
+        return add( vals );
+    }    
+
+    
     /**
      * Remove all the values from this attribute type, including a 
      * null value. 
@@ -309,6 +363,36 @@
         values.clear();
     }
 
+    
+    /**
+     * @return A copy of the current attribute
+     */
+    public ServerAttribute clone()
+    {
+        try
+        {
+            AbstractServerAttribute clone = (AbstractServerAttribute)super.clone();
+
+            // Copy the values. The attributeType is immutable.
+            if ( ( values != null ) && ( values.size() != 0 ) )
+            {
+                clone.values = new ArrayList<ServerValue<?>>( values.size() );
+                
+                for ( ServerValue<?> value:values )
+                {
+                    clone.values.add( value.clone() );
+                }
+            }
+        
+            return clone;
+        }
+        catch ( CloneNotSupportedException cnse )
+        {
+            return null;
+        }
+    }
+
+    
 
     /**
      * @see EntryAttribute#contains(org.apache.directory.shared.ldap.entry.Value)

Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java Sun Jan  6 14:58:12 2008
@@ -43,7 +43,8 @@
 {
     /** logger for reporting errors that might not be handled properly upstream */
     private static final Logger LOG = LoggerFactory.getLogger( DefaultServerAttribute.class );
-
+    
+    
     // maybe have some additional convenience constructors which take
     // an initial value as a string or a byte[]
     /**
@@ -51,7 +52,10 @@
      */
     public DefaultServerAttribute( AttributeType attributeType )
     {
-        assert checkAttributeType( attributeType) == null : logAssert( checkAttributeType( attributeType ) );
+        if ( attributeType == null )
+        {
+            throw new IllegalArgumentException( getErrorMessage( attributeType ) );
+        }
         
         this.attributeType = attributeType;
         setUpId( null, attributeType );
@@ -63,7 +67,12 @@
      */
     public DefaultServerAttribute( String upId, AttributeType attributeType )
     {
-        assert checkAttributeType( attributeType) == null : logAssert( checkAttributeType( attributeType ) );
+        if ( attributeType == null ) 
+        {
+            String message = getErrorMessage( attributeType );
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
+        }
 
         this.attributeType = attributeType;
         setUpId( upId, attributeType );
@@ -103,12 +112,15 @@
      */
     public DefaultServerAttribute( String upId, AttributeType attributeType, ServerValue<?>... vals ) throws NamingException
     {
-        assert checkAttributeType( attributeType) == null : logAssert( checkAttributeType( attributeType ) );
+        if ( attributeType == null )
+        {
+            throw new IllegalArgumentException( getErrorMessage( attributeType ) );
+        }
         
         this.attributeType = attributeType;
         
         // The value can be null, this is a valid value.
-        if ( vals == null )
+        if ( vals[0] == null )
         {
             if ( attributeType.getSyntax().isHumanReadable() )
             {
@@ -164,7 +176,10 @@
      */
     public DefaultServerAttribute( String upId, AttributeType attributeType, String... vals ) throws NamingException
     {
-        assert checkAttributeType( attributeType) == null : logAssert( checkAttributeType( attributeType ) );
+        if ( attributeType == null )
+        {
+            throw new IllegalArgumentException( getErrorMessage( attributeType ) );
+        }
 
         this.attributeType = attributeType;
         add( vals );
@@ -186,7 +201,10 @@
      */
     public DefaultServerAttribute( String upId, AttributeType attributeType, byte[]... vals ) throws NamingException
     {
-        assert checkAttributeType( attributeType) == null : logAssert( checkAttributeType( attributeType ) );
+        if ( attributeType == null )
+        {
+            throw new IllegalArgumentException( getErrorMessage( attributeType ) );
+        }
 
         this.attributeType = attributeType;
         add( vals );
@@ -254,6 +272,21 @@
     {
         if ( attributeType.getSyntax().isHumanReadable() )
         {
+            if ( val == null )
+            {
+                ServerValue<String> nullSV = new ServerStringValue( attributeType, (String)null );
+                
+                if ( values.contains( nullSV ) )
+                {
+                    return false;
+                }
+                else
+                {
+                    values.add( nullSV );
+                    return true;
+                }
+            }
+            
             if ( !( val instanceof AbstractStringValue ) )
             {
                 String message = "The value must be a String, as its AttributeType is H/R";
@@ -263,6 +296,21 @@
         }
         else
         {
+            if ( val == null )
+            {
+                ServerValue<byte[]> nullSV = new ServerBinaryValue( attributeType, (byte[])null );
+                
+                if ( values.contains( nullSV ) )
+                {
+                    return false;
+                }
+                else
+                {
+                    values.add( nullSV );
+                    return true;
+                }
+            }
+            
             if ( !( val instanceof AbstractBinaryValue ) )
             {
                 String message = "The value must be a byte[], as its AttributeType is not H/R";
@@ -271,6 +319,11 @@
             }
         }
         
+        if ( values.contains( val ) )
+        {
+            return false;
+        }
+        
         return values.add( val );
     }
 
@@ -315,7 +368,7 @@
     /**
      * @see EntryAttribute#add(String...)
      */
-    public int add( String... vals ) throws InvalidAttributeValueException, NamingException
+    public int add( String... vals ) throws NamingException
     {
         int nbAdded = 0;
         
@@ -366,7 +419,8 @@
         
         return nbAdded;
     }    
-
+    
+    
     /**
      * Remove all the values from this attribute type, including a 
      * null value. 
@@ -636,12 +690,12 @@
         {
             for ( ServerValue<?> value:values )
             {
-                sb.append( upId ).append( ": " ).append( value ).append( '\n' );
+                sb.append( "    " ).append( upId ).append( ": " ).append( value ).append( '\n' );
             }
         }
         else
         {
-            sb.append( upId ).append( ": (null)\n" );
+            sb.append( "    " ).append( upId ).append( ": (null)\n" );
         }
         
         return sb.toString();

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=609459&r1=609458&r2=609459&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 Sun Jan  6 14:58:12 2008
@@ -34,6 +34,7 @@
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.schema.AttributeType;
 import org.apache.directory.shared.ldap.schema.ObjectClass;
+import org.apache.directory.shared.ldap.util.StringTools;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,34 +67,348 @@
     /** A speedup to get the ObjectClass attribute */
     private static transient AttributeType OBJECT_CLASS_AT;
     
-    /** An object used to protect the OBJECT_CLASS_AT while initializing it */
-    private static final Object MUTEX = new Object();
-    
     /** The DN for this entry */
     private LdapDN dn;
+    
+    /** A mutex to manage synchronization*/
+    private transient static Object MUTEX = new Object();
+
+
+    /**
+     * This method is used to initialize the OBJECT_CLASS_AT attributeType.
+     * 
+     * We want to do it only once, so it's a synchronized method. Note that
+     * the alternative would be to call the lookup() every time, but this won't
+     * be very efficient, as it will get the AT from a map, which is also
+     * synchronized, so here, we have a very minimal cost.
+     * 
+     * We can't do it once as a static part in the body of this class, because
+     * the access to the registries is mandatory to get back the AttributeType.
+     */
+    private void initObjectClassAT( Registries registries )
+    {
+        try
+        {
+            if ( OBJECT_CLASS_AT == null )
+            {
+                synchronized ( MUTEX )
+                {
+                    OBJECT_CLASS_AT = registries.getAttributeTypeRegistry().lookup( SchemaConstants.OBJECT_CLASS_AT );
+                }
+            }
+            
+            setObjectClassAttribute( new ObjectClassAttribute( registries, SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC ) );
+        }
+        catch ( NamingException ne )
+        {
+            // do nothing...
+        }
+    }
+
+    
+    /**
+     * Creates a new instance of DefaultServerEntry.
+     * <p>
+     * This entry <b>must</b> be initialized before being used !
+     */
+    public DefaultServerEntry()
+    {
+        registries = null;
+        
+        initObjectClassAT( registries );
+    }
 
 
-    public DefaultServerEntry( LdapDN dn, Registries registries ) throws NamingException
+    /**
+     * Creates a new instance of DefaultServerEntry, with a 
+     * DN and registries. 
+     * <p>
+     * No attributes will be created except the ObjectClass attribute,
+     * which will contains "top". 
+     * 
+     * @param registries The reference to the global registries
+     * @param dn The DN for this serverEntry. Can be null.
+     */
+    public DefaultServerEntry( Registries registries, LdapDN dn )
     {
         this.dn = dn;
         this.registries = registries;
 
-        synchronized( MUTEX )
+        initObjectClassAT( registries );
+    }
+
+
+    /**
+     * Creates a new instance of DefaultServerEntry, with a 
+     * DN, registries and a list of attributeTypes. 
+     * <p>
+     * No attributes will be created except the ObjectClass attribute,
+     * which will contains "top". 
+     * <p>
+     * If any of the AttributeType does not exist, they are simply discarded.
+     * 
+     * @param registries The reference to the global registries
+     * @param dn The DN for this serverEntry. Can be null.
+     * @param attributeTypes The list of attributes to create, without value.
+     */
+    public DefaultServerEntry( Registries registries, LdapDN dn, AttributeType... attributeTypes )
+    {
+        this.dn = dn;
+        this.registries = registries;
+
+        initObjectClassAT( registries );
+
+        for ( AttributeType attributeType:attributeTypes )
         {
-            if ( OBJECT_CLASS_AT == null )
+            if ( attributeType.equals(  OBJECT_CLASS_AT ) )
             {
-                OBJECT_CLASS_AT = registries.getAttributeTypeRegistry().lookup( SchemaConstants.OBJECT_CLASS_AT );
+                // The ObjectClass AttributeType has already been added
+                continue;
             }
+            
+            // Add a new AttributeType without value
+            set( attributeType );
+        }
+    }
+
+    
+    /**
+     * Creates a new instance of DefaultServerEntry, with a 
+     * DN, registries and an attributeType with the user provided ID. 
+     * <p>
+     * No attributes will be created except the ObjectClass attribute,
+     * which will contains "top". 
+     * <p>
+     * If the AttributeType does not exist, then an empty Entry is created.
+     * <p>
+     * We also check that the normalized upID equals the AttributeType ID
+     * 
+     * @param registries The reference to the global registries
+     * @param dn The DN for this serverEntry. Can be null.
+     * @param attributeType The attribute to create, without value.
+     * @param upId The User Provided ID fro this AttributeType
+     */
+    public DefaultServerEntry( Registries registries, LdapDN dn, AttributeType attributeType, String upId )
+    {
+        this.dn = dn;
+        this.registries = registries;
+
+        initObjectClassAT( registries );
+
+        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 );
+        }
+        else
+        {
+            try
+            {
+                put( upId, attributeType, (String)null );
+            }
+            catch ( NamingException ne )
+            {
+                // What do we do ???
+                LOG.error( "We have had an error while adding the '{}' AttributeType : {}", upId, ne.getMessage() );
+            }
+        }
+    }
+
+    
+    /**
+     * Creates a new instance of DefaultServerEntry, with a 
+     * DN, registries and a list of IDs. 
+     * <p>
+     * No attributes will be created except the ObjectClass attribute,
+     * which will contains "top". 
+     * <p>
+     * If any of the AttributeType does not exist, they are simply discarded.
+     * 
+     * @param registries The reference to the global registries
+     * @param dn The DN for this serverEntry. Can be null.
+     * @param upIds The list of attributes to create.
+     */
+    public DefaultServerEntry( Registries registries, LdapDN dn, String... upIds )
+    {
+        this.dn = dn;
+        this.registries = registries;
+
+        initObjectClassAT( registries );
+
+        for ( String upId:upIds )
+        {
+            try
+            {
+                AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( upId );
+                
+                if ( attributeType.equals(  OBJECT_CLASS_AT ) )
+                {
+                    // The ObjectClass AttributeType has already been added
+                    continue;
+                }
+                
+                // Add a new AttributeType without value
+                set( upId );
+            }
+            catch ( NamingException ne )
+            {
+                // Just log an error...
+                LOG.error( "The '{}' AttributeType does not exist", upId );
+            }
+        }
+    }
+
+    
+    /**
+     * Creates a new instance of DefaultServerEntry, with a 
+     * DN, registries and a list of ServerAttributes. 
+     * <p>
+     * No attributes will be created except the ObjectClass attribute,
+     * which will contains "top". 
+     * <p>
+     * If any of the AttributeType does not exist, they are simply discarded.
+     * 
+     * @param registries The reference to the global registries
+     * @param dn The DN for this serverEntry. Can be null
+     * @param attributes The list of attributes to create
+     */
+    public DefaultServerEntry( Registries registries, LdapDN dn, ServerAttribute... attributes )
+    {
+        this.dn = dn;
+        this.registries = registries;
+
+        initObjectClassAT( registries );
+
+        for ( ServerAttribute attribute:attributes )
+        {
+            if ( attribute.getType().equals(  OBJECT_CLASS_AT ) )
+            {
+                // Treat the ObjectClass in a specific way
+                setObjectClassAttribute( attribute );
+                continue;
+            }
+            
+            // Store a new ServerAttribute
+            try
+            {
+                put( attribute );
+            }
+            catch ( NamingException ne )
+            {
+                LOG.warn( "The ServerAttribute '{}' does not exist. It has been discarded", attribute );
+            }
+        }
+    }
+
+    
+    //-------------------------------------------------------------------------
+    // Helper methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Returns the attributeType from an Attribute ID.
+     */
+    private AttributeType getAttributeType( String upId ) throws NamingException
+    {
+        if ( StringTools.isEmpty( StringTools.trim( upId ) ) )
+        {
+            String message = "The ID should not be null";
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
         }
         
-        setObjectClassAttribute( new ObjectClassAttribute( registries ) );
+        return registries.getAttributeTypeRegistry().lookup( upId );
     }
 
+    
+    /**
+     * Get the UpId if it was null.
+     */
+    public static String getUpId( String upId, AttributeType attributeType ) throws NamingException
+    {
+        String normUpId = StringTools.trim( upId );
+
+        if ( ( attributeType == null ) )
+        {
+            if ( StringTools.isEmpty( normUpId ) )
+            {
+                String message = "Cannot add an attribute without an ID";
+                LOG.error( message );
+                throw new IllegalArgumentException( message );
+            }
+        }
+        else if ( StringTools.isEmpty( normUpId ) )
+        {
+            upId = attributeType.getName();
+            
+            if ( StringTools.isEmpty( upId ) )
+            {
+                upId = attributeType.getOid();
+            }
+        }
+        
+        return upId;
+    }
 
-    private ServerAttribute setObjectClassAttribute( ServerAttribute objectClassAttribute ) throws NamingException
+    
+    /**
+     * Get the attributeType from the UpId if null.
+     */
+    private AttributeType getAttributeType( String upId, AttributeType attributeType ) throws NamingException
     {
-        this.objectClassAttribute = (ObjectClassAttribute)objectClassAttribute;
-        return serverAttributeMap.put( OBJECT_CLASS_AT, objectClassAttribute );
+        if ( ( attributeType == null ) )
+        {
+            String normUpId = StringTools.trim( upId );
+            
+            if ( StringTools.isEmpty( normUpId ) )
+            {
+                String message = "Cannot add an attribute without an ID";
+                LOG.error( message );
+                throw new IllegalArgumentException( message );
+            }
+            else
+            {
+                attributeType = registries.getAttributeTypeRegistry().lookup( upId );
+            }
+        }
+        
+        return attributeType;
+    }
+
+    
+    /**
+     * Stores the ObjectClassAttribute into its container.
+     *
+     * @param objectClassAttribute The instance of ObjectClassAttribute
+     * @return The previously stored ObjectClassAttribute, if any
+     */
+    private ServerAttribute setObjectClassAttribute( ObjectClassAttribute objectClassAttribute )
+    {
+        assert objectClassAttribute != null : "The ObjectClass Attribute should not be null";
+        
+        this.objectClassAttribute = objectClassAttribute;
+        ServerAttribute previous = serverAttributeMap.put( OBJECT_CLASS_AT, objectClassAttribute );
+        
+        return previous;
+    }
+
+
+    /**
+     * Stores the ObjectClassAttribute into its container.
+     *
+     * @param objectClassAttribute The instance of ObjectClassAttribute
+     * @return The previously stored ObjectClassAttribute, if any
+     */
+    private ServerAttribute setObjectClassAttribute( ServerAttribute serverAttribute )
+    {
+        assert serverAttribute != null : "The ObjectClass Attribute should not be null";
+        
+        this.objectClassAttribute = new ObjectClassAttribute( registries );
+        ServerAttribute previous = serverAttributeMap.put( OBJECT_CLASS_AT, objectClassAttribute );
+        
+        return previous;
     }
 
 
@@ -221,51 +536,6 @@
     }
 
 
-    public List<ServerAttribute> put( ServerAttribute... serverAttributes ) throws NamingException
-    {
-        List<ServerAttribute> duplicatedAttributes = new ArrayList<ServerAttribute>();
-        
-        for ( ServerAttribute serverAttribute:serverAttributes )
-        {
-            if ( serverAttribute.getType().equals( OBJECT_CLASS_AT ) )
-            {
-                if ( serverAttribute instanceof ObjectClassAttribute )
-                {
-                    setObjectClassAttribute( ( ObjectClassAttribute ) serverAttribute );
-                }
-                else
-                {
-                    ObjectClassAttribute objectClassAttribute = new ObjectClassAttribute( registries );
-                    
-                    for ( ServerValue<?> val : serverAttribute )
-                    {
-                        objectClassAttribute.add( (ServerStringValue)val );
-                    }
-                    
-                    setObjectClassAttribute( objectClassAttribute );
-                }
-            }
-
-            if ( serverAttributeMap.containsKey( serverAttribute.getType() ) )
-            {
-                duplicatedAttributes.add( serverAttribute );
-            }
-            else
-            {
-                serverAttributeMap.put( serverAttribute.getType(), serverAttribute );
-            }
-        }
-        
-        return duplicatedAttributes;
-    }
-
-
-    public ServerAttribute put( String upId, AttributeType attributeType ) throws NamingException
-    {
-        throw new NotImplementedException();
-    }
-
-
     /**
      * Put an attribute (represented by its ID and values) into an entry. 
      * If the attribute already exists, the previous attribute will be 
@@ -278,15 +548,7 @@
      */
     public ServerAttribute put( String upId, String... values ) throws NamingException
     {
-        AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( upId );
-        ServerAttribute existing = serverAttributeMap.get( attributeType );
-
-        for ( String value:values )
-        {
-            put( attributeType, value );
-        }
-        
-        return existing;
+        return put( getAttributeType( upId ), values );
     }
 
 
@@ -296,33 +558,169 @@
      * replaced and returned.
      *
      * @param upId The attribute ID
-     * @param values The list of values to inject. It can be empty
+     * @param values The list of values to inject. It can be empty.
      * @return The replaced attribute
      * @throws NamingException If the attribute does not exist
      */
     public ServerAttribute put( String upId, byte[]... values ) throws NamingException
     {
-        AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( upId );
-        ServerAttribute existing = serverAttributeMap.get( attributeType );
+        return put( getAttributeType( upId ), values );
+    }
+
 
-        for ( byte[] value:values )
+    /**
+     * Set some new empty AttributeTypes into the serverEntry.
+     * <p>
+     * If there is already a ServerAttribute with the same AttributeType, 
+     * it will be removed from the entry and returned back to the caller.
+     * 
+     * @param attributeTypse the new ServerAttribute attributeType to be added
+     * @return The list of existing ServerAttribute, if any with the same AttributeType
+     */
+    public List<ServerAttribute> set( AttributeType... attributeTypes )
+    {
+        if ( attributeTypes == null )
         {
-            put( attributeType, value );
+            String message = "The AttributeType list should not be null";
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
         }
         
-        return existing;
-    }
+        List<ServerAttribute> returnedServerAttributes = null;
+        
+        // Now, loop on all the attributeType to add
+        for ( AttributeType attributeType:attributeTypes )
+        {
+            if ( attributeType == null )
+            {
+                String message = "The AttributeType list should not contain null values";
+                LOG.error( message );
+                throw new IllegalArgumentException( message );
+            }
+            
+            // The ObjectClass AT is special
+            if ( attributeType.equals( OBJECT_CLASS_AT ) )
+            {
+                // Just do nothing but clear the ObjectClass values
+                objectClassAttribute.clear();
+            }
+            else
+            {
+                if ( returnedServerAttributes == null )
+                {
+                    returnedServerAttributes = new ArrayList<ServerAttribute>();
+                }
+
+                if ( serverAttributeMap.containsKey( attributeType ) )
+                {
+                    // Add the removed serverAttribute to the list
+                    returnedServerAttributes.add( serverAttributeMap.remove( attributeType ) );
+                }
 
+                ServerAttribute newAttribute = new DefaultServerAttribute( attributeType );
+                serverAttributeMap.put( attributeType, newAttribute );
+            }
+        }
+        
+        return returnedServerAttributes;
+    }
 
-    public ServerAttribute put( AttributeType attributeType ) throws NamingException
+    
+    /**
+     * Put some new empty ServerAttribute into the serverEntry. 
+     * <p>
+     * If there is already a ServerAttribute with the same AttributeType, 
+     * it will be removed from the entry and returned back to the caller.
+     * <p>
+     * The added ServerAttributes are supposed to be valid.
+     * 
+     * @param serverAttributes the new ServerAttributes to put into the serverEntry
+     * @return An existing ServerAttribute, if any of the added serverAttribute 
+     * already exists
+     */
+    public List<ServerAttribute> put( ServerAttribute... serverAttributes ) throws NamingException
     {
-        throw new NotImplementedException();
+        List<ServerAttribute> previous = new ArrayList<ServerAttribute>();
+        
+        for ( ServerAttribute serverAttribute:serverAttributes )
+        {
+            if ( serverAttribute == null )
+            {
+                String message = "The ServerAttribute list should not contain null elements";
+                LOG.error( message );
+                throw new IllegalArgumentException( message );
+            }
+            
+            if ( serverAttribute.getType().equals( OBJECT_CLASS_AT ) )
+            {
+                // The objectClass attributeType is special 
+                if ( serverAttribute instanceof ObjectClassAttribute )
+                {
+                    ServerAttribute removed = setObjectClassAttribute( ( ObjectClassAttribute ) serverAttribute );
+
+                    previous.add( removed );
+                }
+                else
+                {
+                    // Here, the attributeType is ObjectClass, but the Attribute itself is 
+                    // not a instance of the ObjectClassAttribute. We will store all of
+                    // its values into a new instance of ObjectClassAttribute. 
+                    ObjectClassAttribute objectClassAttribute = new ObjectClassAttribute( registries, serverAttribute );
+                    ServerAttribute removed = setObjectClassAttribute( objectClassAttribute );
+
+                    previous.add( removed );
+                }
+            }
+            else
+            {
+                ServerAttribute removed = serverAttributeMap.put( serverAttribute.getType(), serverAttribute );
+                
+                if ( removed != null )
+                {
+                    previous.add( removed );
+                }
+            }
+        }
+        
+        return previous;
     }
 
 
-    public ServerAttribute put( String upId ) throws NamingException
+    /**
+     * Put some new ServerAttribute using the User Provided ID to select
+     * the AttributeType. No value is inserted.
+     * 
+     * @param upIds The user provided IDs of the AttributeTypes to add.
+     * @return A list of existing ServerAttribute, if any with the same 
+     * AttributeType
+     * 
+     * @throws NamingException If one of the user provided ID is not an 
+     * attributeType's name
+     */
+    public List<ServerAttribute> set( String... upIds ) throws NamingException
     {
-        throw new NotImplementedException();
+        List<ServerAttribute> existings = null;
+        
+        for ( String upId:upIds )
+        {
+            // Search for the corresponding AttributeType, based on the upID 
+            AttributeType attributeType = getAttributeType( upId );
+            
+            ServerAttribute existing = serverAttributeMap.put( attributeType, 
+                new DefaultServerAttribute( upId, attributeType ));
+            
+            if ( existing != null )
+            {
+                if ( existings == null )
+                {
+                    existings = new ArrayList<ServerAttribute>();
+                }
+                
+                existings.add( existing );
+            }
+        }
+        
+        return existings;
     }
 
 
@@ -348,85 +746,199 @@
     }
 
 
+    /**
+     * Stores a new attribute with some values into the entry.
+     * <p>
+     * The previous attribute with the same attributeType, if any, is returned.
+     * 
+     * @param attributeType The attributeType to add
+     * @param values The associated values
+     * @return The existing ServerAttribute, if any
+     * @throws NamingException If some values conflict with the attributeType
+     * 
+     */
     public ServerAttribute put( 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 )
         {
-            return put( existing.getUpId(), attributeType, values );
+            // We have an existing attribute : clone it and return it
+            ServerAttribute previous = (ServerAttribute)existing.clone();
+            
+            // Stores the new values into the attribute
+            existing.put( values );
+
+            return previous;
         }
         else
         {
-            return put( null, attributeType, values );
+            ServerAttribute serverAttribute = new DefaultServerAttribute( attributeType, values );
+            put( serverAttribute );
+            
+            return null;
         }
     }
 
 
-    public ServerAttribute put( String upId, AttributeType attributeType, ServerValue<?>... vals ) throws NamingException
+    /**
+     * Stores a new attribute with some 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 values to store into the new Attribute
+     * @return The existing attribute if any
+     * @throws NamingException 
+     */
+    public ServerAttribute put( String upId, AttributeType attributeType, ServerValue<?>... values ) throws NamingException
     {
+        upId = getUpId( upId, attributeType );
+        attributeType = getAttributeType( upId, attributeType );
+
+        ServerAttribute serverAttribute = new DefaultServerAttribute( upId, attributeType );
+
         if ( attributeType.equals( OBJECT_CLASS_AT ) )
         {
-            return setObjectClassAttribute( new ObjectClassAttribute( registries, upId, vals ) );
+            // 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.
+            ServerAttribute previous = objectClassAttribute.clone();
+            objectClassAttribute.setUpId( upId, OBJECT_CLASS_AT );
+            objectClassAttribute.put( values );
+            return previous;
+        }
+        else
+        {
+            // We simply have to set the current attribute values
+            serverAttribute.put( values );
+            return serverAttributeMap.put( attributeType, serverAttribute );
         }
-
-        return serverAttributeMap.put( attributeType, new DefaultServerAttribute( upId, attributeType, vals ) );
     }
 
 
-    public ServerAttribute put( String upId, ServerValue<?>... vals ) throws NamingException
+    /**
+     * Put an attribute (represented by its ID and some values) into an entry. 
+     * If the attribute already exists, the previous attribute will be 
+     * replaced and returned.
+     * <p>
+     * The values are stored as ServerValue<?> objects.
+     *
+     * @param upId The attribute ID
+     * @param values The list of ServerValue<?> objects to inject. It can be empty.
+     * @return The replaced attribute
+     * @throws NamingException If the attribute does not exist
+     */
+    public ServerAttribute put( String upId, ServerValue<?>... values ) throws NamingException
     {
-        assert registries != null : "The AttributeType registry should not be null";
-        
-        AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( upId );
-        
-        if ( attributeType.equals( OBJECT_CLASS_AT ) )
-        {
-            return setObjectClassAttribute( new ObjectClassAttribute( registries, upId, vals ) );
-        }
-
-        return serverAttributeMap.put( attributeType, new DefaultServerAttribute( upId, attributeType, vals ) );
+        return put( upId, getAttributeType( upId ), values );
     }
 
 
+    /**
+     * Stores a new attribute, creating it from its attributeType and String values.
+     * <p>
+     * The values are Strings, so the attributeType must be humanReadable. Otherwise,
+     * we will try to convert values from String to byte[]
+     * 
+     * @param attributeType The attributeType
+     * @param vals The String values to add to the attribute
+     * @return The existing ServerAttribute which has been replaced, if any
+     * @throws NamingException If some values conflict with the attributeType
+     */
     public ServerAttribute put( AttributeType attributeType, String... vals ) throws NamingException
     {
-        ServerAttribute existing = serverAttributeMap.get( attributeType );
-
-        if ( attributeType.equals( OBJECT_CLASS_AT ) )
+        if ( attributeType == null )
         {
-            if ( existing != null )
-            {
-                return setObjectClassAttribute( new ObjectClassAttribute( registries, existing.getUpId(), vals ) );
-            }
-
-            return setObjectClassAttribute( new ObjectClassAttribute( registries, OBJECT_CLASS_AT.getName(), vals ) );
+            String message = "The attributeType should not be null";
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
         }
+        
+        ServerAttribute existing = serverAttributeMap.get( attributeType );
 
         if ( existing != null )
         {
-            return put( existing.getUpId(), attributeType, vals );
+            ServerAttribute previous = (ServerAttribute)existing.clone();
+            existing.put( vals );
+            return previous;
         }
         else
         {
-            return put( null, attributeType, vals );
+            if ( attributeType.equals( OBJECT_CLASS_AT ) )
+            {
+                return setObjectClassAttribute( new ObjectClassAttribute( registries, OBJECT_CLASS_AT.getName(), vals ) );
+            }
+            else
+            {
+                return put( null, attributeType, vals );
+            }
         }
     }
 
-
+    
+    /**
+     * Stores 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
+     * @return The existing attribute if any
+     * @throws NamingException 
+     */
     public ServerAttribute put( String upId, AttributeType attributeType, String... values ) throws NamingException
     {
+        upId = getUpId( upId, attributeType );
+        attributeType = getAttributeType( upId, attributeType );
+
+        ServerAttribute serverAttribute = new DefaultServerAttribute( upId, attributeType );
+
         if ( attributeType.equals( OBJECT_CLASS_AT ) )
         {
-            return setObjectClassAttribute( new ObjectClassAttribute( registries, upId, values ) );
+            // 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.
+            ServerAttribute previous = objectClassAttribute.clone();
+            objectClassAttribute.setUpId( upId, OBJECT_CLASS_AT );
+            objectClassAttribute.put( values );
+            return previous;
+        }
+        else
+        {
+            // We simply have to set the current attribute values
+            serverAttribute.put( values );
+            return serverAttributeMap.put( attributeType, serverAttribute );
         }
-
-        return serverAttributeMap.put( attributeType, new DefaultServerAttribute( upId, attributeType, values ) );
     }
 
 
+    /**
+     * Stores a new attribute, creating it from its attributeType and byte[] values.
+     * <p>
+     * The values are byte[], so the attributeType must be non-humanReadable.
+     * 
+     * @param attributeType The attributeType
+     * @param vals The byte[] values to add to the attribute
+     * @return The existing ServerAttribute which has been replaced, if any
+     * @throws NamingException If some values conflict with the attributeType
+     */
     public ServerAttribute put( AttributeType attributeType, byte[]... vals ) throws NamingException
     {
+        if ( attributeType == null )
+        {
+            String message = "The attributeType should not be null";
+            LOG.error( message );
+            throw new IllegalArgumentException( message );
+        }
+
         if ( attributeType.equals( OBJECT_CLASS_AT ) )
         {
             throw new UnsupportedOperationException( "Only String values supported for objectClass attribute" );
@@ -436,7 +948,9 @@
 
         if ( existing != null )
         {
-            return put( existing.getUpId(), attributeType, vals );
+            ServerAttribute previous = (ServerAttribute)existing.clone();
+            existing.put( vals );
+            return previous;
         }
         else
         {
@@ -445,14 +959,29 @@
     }
 
 
-    public ServerAttribute put( String upId, AttributeType attributeType, byte[]... vals ) throws NamingException
+    /**
+     * Store 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 byte[] values to store into the new Attribute
+     * @return The existing attribute if any
+     * @throws NamingException 
+     */
+    public ServerAttribute put( String upId, AttributeType attributeType, byte[]... values ) throws NamingException
     {
+        upId = getUpId( upId, attributeType );
+        attributeType = getAttributeType( upId, attributeType );
+
         if ( attributeType.equals( OBJECT_CLASS_AT ) )
         {
             throw new UnsupportedOperationException( "Only String values supported for objectClass attribute" );
         }
 
-        return serverAttributeMap.put( attributeType, new DefaultServerAttribute( upId, attributeType, vals ) );
+        ServerAttribute serverAttribute = new DefaultServerAttribute( upId, attributeType );
+        serverAttribute.put( values );
+        return serverAttributeMap.put( attributeType, serverAttribute );
     }
 
 
@@ -514,16 +1043,7 @@
     {
         serverAttributeMap.clear();
 
-        try
-        {
-            setObjectClassAttribute( new ObjectClassAttribute( registries ) );
-        }
-        catch ( NamingException e )
-        {
-            String msg = "failed to properly set the objectClass attribute on clear";
-            LOG.error( msg, e );
-            throw new IllegalStateException( msg, e );
-        }
+        setObjectClassAttribute( new ObjectClassAttribute( registries ) );
     }
 
 
@@ -722,7 +1242,7 @@
             {
                 if ( !attribute.getType().equals( OBJECT_CLASS_AT ) )
                 {
-                    sb.append( "    " ).append( attribute );
+                    sb.append( attribute );
                 }
             }
         }

Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ObjectClassAttribute.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ObjectClassAttribute.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ObjectClassAttribute.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ObjectClassAttribute.java Sun Jan  6 14:58:12 2008
@@ -29,6 +29,7 @@
 import javax.naming.directory.InvalidAttributeIdentifierException;
 
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Set;
 import java.util.Collections;
 
@@ -43,6 +44,13 @@
 {
     /** logger for reporting errors that might not be handled properly upstream */
     private static final Logger LOG = LoggerFactory.getLogger( ObjectClassAttribute.class );
+    
+    /** A speedup to get the ObjectClass attribute */
+    private static transient AttributeType OBJECT_CLASS_AT;
+    
+    /** A mutex to manage synchronization*/
+    private transient static Object MUTEX = new Object();
+
 
     // Sets dealing with objectClass operations
     private Set<ObjectClass> allObjectClasses = new HashSet<ObjectClass>();
@@ -57,15 +65,100 @@
     private Registries registries;
 
 
+    /**
+     * This method is used to initialize the OBJECT_CLASS_AT attributeType.
+     * 
+     * We want to do it only once, so it's a synchronized method. Note that
+     * the alternative would be to call the lookup() every time, but this won't
+     * be very efficient, as it will get the AT from a map, which is also
+     * synchronized, so here, we have a very minimal cost.
+     * 
+     * We can't do it once as a static part in the body of this class, because
+     * the access to the registries is mandatory to get back the AttributeType.
+     */
+    private void initObjectClassAT( Registries registries )
+    {
+        if ( OBJECT_CLASS_AT == null )
+        {
+            try
+            {
+                synchronized ( MUTEX )
+                {
+                    OBJECT_CLASS_AT = registries.getAttributeTypeRegistry().lookup( SchemaConstants.OBJECT_CLASS_AT );
+                }
+            }
+            catch ( NamingException ne )
+            {
+                // do nothing...
+            }
+        }
+    }
+
 
     /**
-     * Creates a new ObjectClassAttribute with a null ID
+     * Creates a new ObjectClassAttribute with a null ID.
+     * <p>
+     * We will use the default name : 'objectClass'
      * 
      * @param registries The server registries to use
      */
-    public ObjectClassAttribute( Registries registries ) throws NamingException
+    public ObjectClassAttribute( Registries registries )
     {
-        this( registries, (String)null );
+        this( registries, SchemaConstants.OBJECT_CLASS_AT );
+    }
+
+
+    /**
+     * Creates a new ObjectClassAttribute with ServerAttribute.
+     * <p>
+     * The ServerAttribute must have the ObjectClass attributeType
+     * 
+     * @param registries The server registries to use
+     * @param serverAttribute The serverAttribute containing the objectClasses
+     */
+    public ObjectClassAttribute( Registries registries, ServerAttribute serverAttribute )
+    {
+        this( registries, SchemaConstants.OBJECT_CLASS_AT );
+
+        if ( serverAttribute == null )
+        {
+            LOG.error( "We cannot create an ObjectClassAttribute without any serverAttribute" );
+        }
+        else
+        {
+            if ( !serverAttribute.getType().getOid().equals( SchemaConstants.OBJECT_CLASS_AT_OID ) )
+            {
+                LOG.error(  "The ServerAttribute does not represent an ObjectClass" );
+            }
+            else
+            {
+                // Iterate through the attribute values and store them in the ObjectClass,
+                // if they are valid.
+                for ( Iterator<ServerValue<?>> values = serverAttribute.getAll(); values.hasNext(); )
+                {
+                    ServerValue<?> value = values.next();
+                    
+                    if ( value instanceof ServerStringValue )
+                    {
+                        String objectClassName = ((ServerStringValue)value).get();
+                        
+                    
+                        try
+                        {
+                            // Fond the objectClass and update the internal structures
+                            ObjectClass objectClass =  registries.getObjectClassRegistry().lookup( objectClassName );
+
+                            addObjectClass( objectClass );
+                        }
+                        catch ( NamingException ne )
+                        {
+                            // We didn't found the objectClass. Just ditch it
+                            LOG.error(  "The '{}' objectclass does not exist or the associated schema is not loaded", objectClassName );
+                        }
+                    }
+                }
+            }
+        }
     }
 
 
@@ -76,10 +169,13 @@
      * @param registries The atRegistry to use to initialize this object
      * @throws NamingException If something went wrong
      */
-    public ObjectClassAttribute( Registries registries, String upId ) throws NamingException
+    public ObjectClassAttribute( Registries registries, String upId )
     {
         this.registries = registries;
-        attributeType = registries.getAttributeTypeRegistry().lookup( SchemaConstants.OBJECT_CLASS_AT_OID );
+        
+        initObjectClassAT( registries );
+        
+        attributeType = OBJECT_CLASS_AT;
         setUpId( upId, attributeType );
     }
 
@@ -358,7 +454,7 @@
     {
         StringBuilder sb = new StringBuilder();
         
-        sb.append( "ObjectClass : " );
+        sb.append( "    ObjectClass : " );
         
         if ( ( values != null ) && ( values.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=609459&r1=609458&r2=609459&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 Sun Jan  6 14:58:12 2008
@@ -32,7 +32,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public interface ServerAttribute extends EntryAttribute<ServerValue<?>>, Iterable<ServerValue<?>>
+public interface ServerAttribute extends EntryAttribute<ServerValue<?>>, Iterable<ServerValue<?>>, Cloneable
 {
     /**
      * Gets the attribute type associated with this ServerAttribute.

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=609459&r1=609458&r2=609459&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 Sun Jan  6 14:58:12 2008
@@ -41,7 +41,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class ServerBinaryValue extends AbstractBinaryValue implements ServerValue<byte[]>
+public class ServerBinaryValue extends AbstractBinaryValue implements ServerValue<byte[]>, Cloneable
 {
     /** logger for reporting errors that might not be handled properly upstream */
     private static final Logger LOG = LoggerFactory.getLogger( ServerBinaryValue.class );
@@ -431,5 +431,22 @@
         }
 
         return mr.getComparator();
+    }
+    
+    
+    /**
+     * @return a copy of the current value
+     */
+    public ServerBinaryValue clone()
+    {
+        ServerBinaryValue clone = (ServerBinaryValue)super.clone();
+        
+        if ( normalizedValue != null )
+        {
+            clone.normalizedValue = new byte[ normalizedValue.length ];
+            System.arraycopy( normalizedValue, 0, clone.normalizedValue, 0, normalizedValue.length );
+        }
+        
+        return clone;
     }
 }

Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntry.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntry.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntry.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntry.java Sun Jan  6 14:58:12 2008
@@ -230,12 +230,10 @@
     ServerAttribute put( String upId, String... values ) throws NamingException;
 
     ServerAttribute put( String upId, byte[]... values ) throws NamingException;
+    
+    List<ServerAttribute> set( String... upIds ) throws NamingException;
 
-    // no value put'ters
-    ServerAttribute put( String upId ) throws NamingException;
-
-    ServerAttribute put( AttributeType attributeType ) throws NamingException;
-
+    List<ServerAttribute> set( AttributeType... attributeTypes ) throws NamingException;
 
     /**
      * Places a new attribute of the supplied type and value into the attribute

Added: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryPropertyEditor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryPropertyEditor.java?rev=609459&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryPropertyEditor.java (added)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryPropertyEditor.java Sun Jan  6 14:58:12 2008
@@ -0,0 +1,247 @@
+/*
+ *  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 org.apache.directory.shared.ldap.ldif.LdifComposer;
+import org.apache.directory.shared.ldap.ldif.LdifComposerImpl;
+import org.apache.directory.shared.ldap.ldif.LdifReader;
+import org.apache.directory.shared.ldap.message.AttributesImpl;
+import org.apache.directory.shared.ldap.util.MultiMap;
+import org.apache.directory.shared.ldap.util.StringTools;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import java.beans.PropertyEditor;
+import java.beans.PropertyEditorSupport;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * A JavaBeans {@link PropertyEditor} that can convert {@link ServerEntry} to
+ * LDIF string and vice versa. This class is useful when you're going to
+ * configure a {@link DirectoryService} with 3rd party containers such as <a
+ * href="http://www.springframework.org/">Spring Framework</a>.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 582462 $, $Date: 2007-10-06 08:48:35 +0200 (Sat, 06 Oct 2007) $
+ */
+public class ServerEntryPropertyEditor extends PropertyEditorSupport
+{
+
+    /**
+     * Creates a new instance.
+     */
+    public ServerEntryPropertyEditor()
+    {
+        super();
+    }
+
+    /**
+     * Creates a new instance with source object.
+     */
+    public ServerEntryPropertyEditor( Object source )
+    {
+        super( source );
+    }
+
+    /**
+     * Returns LDIF string of {@link Attributes} object.
+     */
+    public String getAsText()
+    {
+        LdifComposer composer = new LdifComposerImpl();
+        MultiMap map = new MultiMap()
+        {
+            // FIXME Stop forking commons-collections.
+            private final org.apache.commons.collections.MultiHashMap map = 
+                new org.apache.commons.collections.MultiHashMap();
+
+            public Object remove( Object arg0, Object arg1 )
+            {
+                return map.remove( arg0, arg1 );
+            }
+
+            public int size()
+            {
+                return map.size();
+            }
+
+            public Object get( Object arg0 )
+            {
+                return map.get( arg0 );
+            }
+
+            public boolean containsValue( Object arg0 )
+            {
+                return map.containsValue( arg0 );
+            }
+
+            public Object put( Object arg0, Object arg1 )
+            {
+                return map.put( arg0, arg1 );
+            }
+
+            public Object remove( Object arg0 )
+            {
+                return map.remove( arg0 );
+            }
+
+            @SuppressWarnings("unchecked")
+            public Collection<Object> values()
+            {
+                return map.values();
+            }
+
+            public boolean isEmpty()
+            {
+                return map.isEmpty();
+            }
+
+            public boolean containsKey( Object key )
+            {
+                return map.containsKey( key );
+            }
+
+            @SuppressWarnings("unchecked")
+            public void putAll( Map arg0 )
+            {
+                map.putAll( arg0 );
+            }
+
+            public void clear()
+            {
+                map.clear();
+            }
+
+            public Set<?> keySet()
+            {
+                return map.keySet();
+            }
+
+            public Set<?> entrySet()
+            {
+                return map.entrySet();
+            }
+        };
+
+        Attributes attrs = (Attributes) getValue();
+        try
+        {
+            NamingEnumeration<? extends Attribute> e = attrs.getAll();
+            while ( e.hasMore() )
+            {
+                Attribute attr = e.next();
+                NamingEnumeration<? extends Object> e2 = attr.getAll();
+                while ( e2.hasMoreElements() )
+                {
+                    Object value = e2.next();
+                    map.put( attr.getID(), value );
+                }
+            }
+
+            return composer.compose( map );
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * Read an entry (without DN)
+     * 
+     * @param text
+     *            The ldif format file
+     * @return An Attributes.
+     */
+    private Attributes readEntry( String text )
+    {
+        StringReader strIn = new StringReader( text );
+        BufferedReader in = new BufferedReader( strIn );
+
+        String line = null;
+        Attributes attributes = new AttributesImpl( true );
+
+        try
+        {
+            while ( ( line = in.readLine() ) != null )
+            {
+                if ( line.length() == 0 )
+                {
+                    continue;
+                }
+
+                String addedLine = line.trim();
+
+                if ( StringTools.isEmpty( addedLine ) )
+                {
+                    continue;
+                }
+
+                Attribute attribute = LdifReader.parseAttributeValue( addedLine );
+                Attribute oldAttribute = attributes.get( attribute.getID() );
+
+                if ( oldAttribute != null )
+                {
+                    try
+                    {
+                        oldAttribute.add( attribute.get() );
+                        attributes.put( oldAttribute );
+                    }
+                    catch (NamingException ne)
+                    {
+                        // Do nothing
+                    }
+                }
+                else
+                {
+                    attributes.put( attribute );
+                }
+            }
+        }
+        catch (IOException ioe)
+        {
+            // Do nothing : we can't reach this point !
+        }
+
+        return attributes;
+    }
+
+    /**
+     * Converts the specified LDIF string into {@link Attributes}.
+     */
+    public void setAsText( String text ) throws IllegalArgumentException
+    {
+        if ( text == null )
+        {
+            text = "";
+        }
+
+        setValue( readEntry( text ) );
+    }
+}

Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java Sun Jan  6 14:58:12 2008
@@ -134,7 +134,7 @@
         {
             try 
             {
-                ServerEntry entry = new DefaultServerEntry( dn, registries );
+                ServerEntry entry = new DefaultServerEntry( registries, dn );
     
                 for ( NamingEnumeration<? extends Attribute> attrs = attributes.getAll(); attrs.hasMoreElements(); )
                 {

Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStreamedValue.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStreamedValue.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStreamedValue.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStreamedValue.java Sun Jan  6 14:58:12 2008
@@ -72,7 +72,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class ServerStreamedValue extends AbstractStreamedValue implements ServerValue<URI>
+public class ServerStreamedValue extends AbstractStreamedValue implements ServerValue<URI>, Cloneable
 {
     /** logger for reporting errors that might not be handled properly upstream */
     private static final Logger LOG = LoggerFactory.getLogger( ServerStreamedValue.class );
@@ -245,5 +245,23 @@
         }
 
         return false;
+    }
+    
+
+    /**
+     * @return a copy of the current value
+     */
+    public ServerStreamedValue clone()
+    {
+        try
+        {
+            ServerStreamedValue clone = (ServerStreamedValue)super.clone();
+            
+            return clone;
+        }
+        catch ( CloneNotSupportedException cnse )
+        {
+            return null;
+        }
     }
 }

Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStringValue.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStringValue.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStringValue.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerStringValue.java Sun Jan  6 14:58:12 2008
@@ -40,7 +40,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class ServerStringValue extends AbstractStringValue implements ServerValue<String>
+public class ServerStringValue extends AbstractStringValue implements ServerValue<String>, Cloneable
 {
     /** logger for reporting errors that might not be handled properly upstream */
     private static final Logger LOG = LoggerFactory.getLogger( ServerStringValue.class );
@@ -395,5 +395,21 @@
         }
 
         return mr.getComparator();
+    }
+    
+    
+    /**
+     * @return a copy of the current value
+     */
+    public ServerStringValue clone()
+    {
+        try
+        {
+            return (ServerStringValue)super.clone();
+        }
+        catch ( CloneNotSupportedException cnse )
+        {
+            return null;
+        }
     }
 }



Mime
View raw message