directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r581113 - /directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/
Date Mon, 01 Oct 2007 23:57:37 GMT
Author: elecharny
Date: Mon Oct  1 16:57:36 2007
New Revision: 581113

URL: http://svn.apache.org/viewvc?rev=581113&view=rev
Log:
Added all the new interfaces and classes for Attributes and values

Added:
    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/common/AbstractValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/BinaryValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttribute.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttributeImpl.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntry.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntryImpl.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/StringValue.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/Value.java

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/AbstractValue.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/AbstractValue.java?rev=581113&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/AbstractValue.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/AbstractValue.java Mon Oct  1 16:57:36 2007
@@ -0,0 +1,151 @@
+/*
+ *  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.shared.ldap.common;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.ldap.schema.Normalizer;
+
+/**
+ * Abstract implementation for Value subclasses.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractValue<T> implements Value<T>
+{
+    /** The stored value */
+    protected T value;
+    
+    /** The normalized value */
+    protected T normValue;
+    
+
+    /**
+     * Creates a new instance of StringValue with no value
+     */
+    public AbstractValue( T value )
+    {
+        this.value = value;
+        normValue = null;
+    }
+    
+    
+    /**
+     * 
+     * Set a new value
+     *
+     * @param value The value to set
+     */
+    public void setValue( T value )
+    {
+        this.value = value;
+        normValue = null;
+    }
+    
+    
+    /**
+     * 
+     * Get the stored value
+     *
+     * @return The stored value
+     */
+    public T getValue()
+    {
+        return value;
+    }
+    
+    
+    /**
+     * 
+     * Get the stored normalized value
+     *
+     * @return The stored normalized value
+     */
+    public T getNormValue()
+    {
+        return normValue;
+    }
+    
+    
+    /**
+     * Tells if this value is binary or not
+     *
+     * @return True if the value is binary, false otherwise
+     */
+    public final boolean isBinary()
+    {
+        return value instanceof byte[];
+    }
+
+
+    /**
+     * Tells if this value is ormalized or not
+     *
+     * @return True if the value is normalized, false otherwise
+     */
+    public final boolean isNormalized()
+    {
+        return normValue != null;
+    }
+    
+    
+    /**
+     * Normalize the value
+     */
+    public void normalize( Normalizer<T> normalizer ) throws NamingException
+    {
+        normValue = normalizer.normalize( value );
+    }
+    
+    
+    /**
+     * Clone the value.
+     */
+    public Object clone() throws CloneNotSupportedException
+    {
+        // Simply clone the object
+        return (Value)super.clone();
+    }
+    
+    
+    /**
+     * @see Object#equals(Object)
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( ( obj == null ) || !( obj instanceof Value ) )
+        {
+            return false;
+        }
+        
+        if ( obj.getClass() != this.getClass() )
+        {
+            return false;
+        }
+        
+        return true;
+    }
+}

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/BinaryValue.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/BinaryValue.java?rev=581113&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/BinaryValue.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/BinaryValue.java Mon Oct  1 16:57:36 2007
@@ -0,0 +1,122 @@
+/*
+ *  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.shared.ldap.common;
+
+import java.util.Arrays;
+
+import org.apache.directory.shared.ldap.util.StringTools;
+
+/**
+ * A class storing a byte[] value.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class BinaryValue extends AbstractValue<byte[]>
+{
+    /**
+     * serialVersionUID 
+     */
+    static final long serialVersionUID = 2L;
+
+    
+    /**
+     * Creates a new instance of StringValue with no value
+     */
+    public BinaryValue()
+    {
+        super( null );
+    }
+    
+    
+    /**
+     * Creates a new instance of StringValue with a value
+     */
+    public BinaryValue( byte[] value )
+    {
+        super( value );
+    }
+    
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        return "BinaryValue : " + StringTools.dumpBytes( value );
+    }
+    
+
+    /**
+     * @see Object#hashCode()
+     */
+    public int hashCode()
+    {
+        return Arrays.hashCode( value );
+    }
+
+    
+    /**
+     * Makes a copy of the Value. 
+     *
+     * @return A non-null copy of the Value.
+     */
+    public Object clone() throws CloneNotSupportedException
+    {
+        // Clone the superclass
+        BinaryValue cloned = (BinaryValue)super.clone();
+        
+        // Clone the byte[] value, if it's not null
+        byte[] clonedValue = null;
+        
+        if ( value != null )
+        {
+            clonedValue = ( value == null ? null : (byte[])value.clone() );
+        
+            System.arraycopy( value, 0, clonedValue, 0, value.length );
+        }
+        
+        cloned.value = clonedValue;
+        
+        // We can return the cloned result
+        return cloned;
+    }
+    
+    
+    /**
+     * @see Object#equals(Object)
+     */
+    public boolean equals( Object obj )
+    {
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+        
+        BinaryValue value = (BinaryValue)obj;
+        
+        if ( this.value == null )
+        {
+            return value.value == null;
+        }
+        
+        return Arrays.equals( this.value, value.value );
+    }
+}

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttribute.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttribute.java?rev=581113&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttribute.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttribute.java Mon Oct  1 16:57:36 2007
@@ -0,0 +1,268 @@
+/*
+ *  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.shared.ldap.common;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.asn1.primitives.OID;
+import org.apache.directory.shared.ldap.schema.Normalizer;
+
+/**
+ * This interface defines the valid operations on a particular attribute of a
+ * directory entry.
+ * <p>
+ * An attribute can have zero or more values. The value may be null. Values are
+ * not ordered
+ * </p>
+ * <p>
+ * The indexed operations work as if the values
+ * added previously to the attribute had been done using ordered semantics. For
+ * example, if the values "a", "b" and "c" were previously added to an unordered
+ * attribute using "<code>add("a"); add("b"); add("c");</code>", it is
+ * equivalent to adding the same objects to an ordered attribute using "<code>add(0,"a"); add(1,"b"); add(2,"c");</code>".
+ * In this case, if we do "<code>remove(1)</code>" on the unordered list,
+ * the value "b" is removed, changing the index of "c" to 1.
+ * </p>
+ * <p>
+ * Multiple null values can be added to an attribute. It is not the same as
+ * having no values on an attribute. If a null value is added to an unordered
+ * attribute which already has a null value, the <code>add</code> method has
+ * no effect.
+ * </p>
+ * <p>
+ * Note that updates to the attribute via this interface do not affect the
+ * directory directly.
+ * 
+ * </p>
+ * This interface represents an attribute used internally by the
+ * server. It's a subset of the javax.naming.directory.Attribute, where
+ * some methods have been removed, and which manipulates Value instead
+ * of Object
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ * @version $Rev: 499013 $
+ */
+public interface ServerAttribute extends Cloneable, Serializable 
+{
+    /**
+     * This constant is used during deserialization to check the version which
+     * created the serialized object.
+     */
+    static final long serialVersionUID = 2L;
+    
+    
+    /**
+     * Adds a value to this attribute. If the new value is already present in 
+     * the attribute values, the method has no effect.
+     * <p>
+     * The new value is added at the end of list of values.
+     * </p>
+     * <p>
+     * This method returns true or false to indicate whether a value was added.
+     * </p>
+     * 
+     * @param val a new value to be added which may be null
+     * @return true if a value was added, otherwise false
+     */
+    boolean add( Value val );
+    
+    
+    /**
+     * Adds a value to this attribute. If the new value is already present in 
+     * the attribute values, the method has no effect.
+     * <p>
+     * The new value is added at the end of list of values.
+     * </p>
+     * <p>
+     * This method returns true or false to indicate whether a value was added.
+     * </p>
+     * 
+     * @param val a new value to be added which may be null
+     * @return true if a value was added, otherwise false
+     */
+    boolean add( String val );
+    
+    
+    /**
+     * Adds a value to this attribute. If the new value is already present in 
+     * the attribute values, the method has no effect.
+     * <p>
+     * The new value is added at the end of list of values.
+     * </p>
+     * <p>
+     * This method returns true or false to indicate whether a value was added.
+     * </p>
+     * 
+     * @param val a new value to be added which may be null
+     * @return true if a value was added, otherwise false
+     */
+    boolean add( byte[] val );
+    
+    
+    /**
+     * Removes all values of this attribute.
+     */
+    void clear();
+
+
+    /**
+     * Returns a deep copy of the attribute containing all the same values. The
+     * values <b>are</b> cloned.
+     * 
+     * @return a deep clone of this attribute
+     */
+    Object clone();
+
+   
+    /**
+     * Indicates whether the specified value is one of the attribute's values.
+     * 
+     * @param val the value which may be null
+     * @return true if this attribute contains the value, otherwise false
+     */
+    boolean contains( Value val );
+    
+
+    /**
+     * Indicates whether the specified value is one of the attribute's values.
+     * 
+     * @param val the value which may be null
+     * @return true if this attribute contains the value, otherwise false
+     */
+    boolean contains( String val );
+    
+
+    /**
+     * Indicates whether the specified value is one of the attribute's values.
+     * 
+     * @param val the value which may be null
+     * @return true if this attribute contains the value, otherwise false
+     */
+    boolean contains( byte[] val );
+    
+
+    /**
+     * Gets a value of this attribute. Returns the first one, if many. 
+     * <code>null</code> is a valid value.
+     * <p>
+     * 
+     * If the attribute has no values this method throws
+     * <code>NoSuchElementException</code>.
+     * </p>
+     * 
+     * @return a value of this attribute
+     * @throws NamingException If the attribute has no value.
+     */
+    Value get() throws NamingException;
+
+
+    /**
+     * Returns an enumeration of all the attribute's values. 
+     * <p>
+     * The effect on the returned enumeration of adding or removing values of
+     * the attribute is not specified.
+     * </p>
+     * <p>
+     * This method will throw any <code>NamingException</code> that occurs.
+     * </p>
+     * 
+     * @return an enumeration of all values of the attribute
+     * @throws NamingException If any <code>NamingException</code> occurs.
+     */
+    Iterator<Value> getAll() throws NamingException;
+
+
+    /**
+     * Returns the identity of this attribute. This method is not expected to
+     * return null.
+     *
+     * @return The id of this attribute
+     */
+    String getID();
+
+   
+    /**
+     * Returns the OID of this attribute. This method is not expected to
+     * return null.
+     *
+     * @return The OID of this attribute
+     */
+    OID getOid();
+
+   
+   /** 
+      * Retrieves the number of values in this attribute.
+      *
+      * @return The number of values in this attribute, including the null value
+      * if there is one.
+      */
+    int size();
+
+    
+    /**
+     * Removes a value that is equal to the given value. 
+     * <p>
+     * Returns true if a value is removed. If there is no value equal to <code>
+     * val</code> this method simply returns false.
+     * </p>
+     * 
+     * @param val the value to be removed
+     * @return true if the value is removed, otherwise false
+     */
+    boolean remove( Value val );
+    
+
+    /**
+     * Removes a value that is equal to the given value. 
+     * <p>
+     * Returns true if a value is removed. If there is no value equal to <code>
+     * val</code> this method simply returns false.
+     * </p>
+     * 
+     * @param val the value to be removed
+     * @return true if the value is removed, otherwise false
+     */
+    boolean remove( byte[] val );
+    
+
+    /**
+     * Removes a value that is equal to the given value. 
+     * <p>
+     * Returns true if a value is removed. If there is no value equal to <code>
+     * val</code> this method simply returns false.
+     * </p>
+     * 
+     * @param val the value to be removed
+     * @return true if the value is removed, otherwise false
+     */
+    boolean remove( String val );
+    
+
+    /**
+     * Normalize the attribute, setting the OID and normalizing the values 
+     *
+     * @param oid The attribute OID
+     * @param normalizer The normalizer
+     */
+    void normalize( OID oid, Normalizer<?> normalizer ) throws NamingException;
+}

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttributeImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttributeImpl.java?rev=581113&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttributeImpl.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerAttributeImpl.java Mon Oct  1 16:57:36 2007
@@ -0,0 +1,928 @@
+/*
+ *  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.shared.ldap.common;
+
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.BasicAttribute;
+
+import org.apache.directory.shared.asn1.primitives.OID;
+import org.apache.directory.shared.ldap.common.Value;
+import org.apache.directory.shared.ldap.schema.Normalizer;
+import org.apache.directory.shared.ldap.util.AttributeUtils;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Attribute implementation.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
+ * @version $Rev: 499013 $
+ */
+public class ServerAttributeImpl implements ServerAttribute, Serializable, Cloneable
+{
+    private static final Logger log = LoggerFactory.getLogger( ServerAttributeImpl.class );
+
+    /** For serialization */
+    private static final long serialVersionUID = 2L;
+
+    /** the name of the attribute, case sensitive */
+    private final String upId;
+
+    /** the OID of the attribute */
+    private OID oid;
+
+    /** In case we have only one value, just use this container */
+    private Value value;
+    
+    /** the list of attribute values, if unordered */
+    private List<Value> values;
+    
+    /** A size to handle the number of values, as one of them can be null */
+    private int size;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Creates a ServerAttribute with an id
+     * 
+     * @param id the id or name of this attribute.
+     */
+    public ServerAttributeImpl( String id ) throws NamingException
+    {
+        if ( StringTools.isEmpty( id ) )
+        {
+            log.error( "Attributes with an empty ID or OID are not allowed" );
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+
+        upId = id;
+        value = null;
+        values = null;
+        oid = null;
+        size = 0;
+    }
+
+
+    /**
+     * Creates a ServerAttribute with an oid
+     * 
+     * @param oid the oid of this attribute.
+     */
+    public ServerAttributeImpl( OID oid ) throws NamingException
+    {
+        if ( oid == null )
+        {
+            log.error( "Attributes with an empty ID or OID are not allowed" );
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+
+        upId = oid.toString();
+        value = null;
+        values = null;
+        this.oid = oid;
+        size = 0;
+    }
+
+
+    /**
+     * Creates a ServerAttribute with an id and a value
+     * 
+     * @param id the id or name of this attribute.
+     * @param val the attribute's value
+     */
+    public ServerAttributeImpl( String id, Value val ) throws NamingException
+    {
+        if ( StringTools.isEmpty( id ) )
+        {
+            log.error( "Attributes with an empty ID or OID are not allowed" );
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+
+        upId = id;
+        value = val;
+        values = null;
+        oid = null;
+        size = 1;
+    }
+
+
+    /**
+     * Creates a ServerAttribute with an oid and a value
+     * 
+     * @param oid the oid of this attribute.
+     * @param val the attribute's value
+     */
+    public ServerAttributeImpl( OID oid, Value val ) throws NamingException
+    {
+        if ( oid == null )
+        {
+            log.error( "Attributes with an empty ID or OID are not allowed" );
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+
+        upId = oid.toString();
+        value = val;
+        values = null;
+        this.oid = oid;
+        size = 1;
+    }
+
+    
+    /**
+     * Creates a ServerAttribute with an id and a byte[] value
+     * 
+     * @param id the id or name of this attribute.
+     * @param val a value for the attribute
+     */
+    public ServerAttributeImpl( String id, byte[] val ) throws NamingException
+    {
+        if ( StringTools.isEmpty( id ) )
+        {
+            log.error( "Attributes with an empty ID or OID are not allowed" );
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+
+        upId = id;
+        values = null;
+        value = new BinaryValue( val );
+        oid = null;
+        size = 1;
+    }
+
+    
+    /**
+     * Creates a ServerAttribute with an oid and a byte[] value
+     * 
+     * @param oid the oid of this attribute.
+     * @param val a value for the attribute
+     */
+    public ServerAttributeImpl( OID oid, byte[] val ) throws NamingException
+    {
+        if ( oid == null )
+        {
+            log.error( "Attributes with an empty ID or OID are not allowed" );
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+
+        upId = oid.toString();
+        values = null;
+        value = new BinaryValue( val );
+        this.oid = oid;
+        size = 1;
+    }
+
+    
+    /**
+     * Creates a ServerAttribute with an id and a String value
+     * 
+     * @param id the id or name of this attribute.
+     * @param val a value for the attribute
+     */
+    public ServerAttributeImpl( String id, String val ) throws NamingException
+    {
+        if ( StringTools.isEmpty( id ) )
+        {
+            log.error( "Attributes with an empty ID or OID are not allowed" );
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+
+        upId = id;
+        values = null;
+        value = new StringValue( val );
+        oid = null;
+        size = 1;
+    }
+
+    
+    /**
+     * Creates a ServerAttribute with an oid and a String value
+     * 
+     * @param oid the oid of this attribute.
+     * @param val a value for the attribute
+     */
+    public ServerAttributeImpl( OID oid, String val ) throws NamingException
+    {
+        if ( oid == null )
+        {
+            log.error( "Attributes with an empty ID or OID are not allowed" );
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+
+        upId = oid.toString();
+        values = null;
+        value = new StringValue( val );
+        this.oid = oid;
+        size = 1;
+    }
+
+    
+    /**
+     * Create a copy of an Attribute, be it an ServerAttributeImpl
+     * instance of a BasicAttribute instance
+     * 
+     * @param attribute the Attribute instace to copy
+     * @throws NamingException if the attribute is not an instance of BasicAttribute
+     * or ServerAttributeImpl or is null
+     */
+    public ServerAttributeImpl( Attribute attribute ) throws NamingException
+    {
+        if ( attribute == null )
+        {
+            log.error(  "Null attribute is not allowed" );
+            throw new NamingException( "Null attribute is not allowed" );
+        }
+        else if ( attribute instanceof ServerAttributeImpl )
+        {
+            ServerAttributeImpl copy = (ServerAttributeImpl)attribute;
+            
+            upId  = copy.upId;
+            oid = copy.oid;
+            
+            switch ( copy.size() )
+            {
+                case 0:
+                    values = null;
+                    value = null;
+                    size = 0;
+                    break;
+
+                case 1:
+                    value = getClonedValue( copy.get() );
+                    values = null;
+                    size = 1;
+                    break;
+                    
+                default :
+                    value = null;
+                    values = new ArrayList<Value>( copy.size() );
+                    
+                    Iterator<Value> vals = copy.getAll();
+                    
+                    while ( vals.hasNext() )
+                    {
+                        Value val = vals.next();
+                        values.add( val );
+                    }
+                    
+                    size = copy.size();
+                    
+                    break;
+            }
+
+            oid = null;
+        }
+        else if ( attribute instanceof BasicAttribute )
+        {
+            upId = attribute.getID();
+            oid = null;
+            
+            switch ( attribute.size() )
+            {
+                case 0 :
+                    value = null;
+                    values = null;
+                    size = 0;
+                    break;
+                    
+                case 1 :
+                    Object val = attribute.get();
+                    
+                    if ( val instanceof String )
+                    {
+                        value = new StringValue( (String)val );
+                    }
+                    else if ( val instanceof byte[] )
+                    {
+                        value = new BinaryValue( (byte[])val );
+                    }
+                    else
+                    {
+                        log.error( "The value's type is not String or byte[]" );
+                        throw new NamingException( "The value's type is not String or byte[]" );
+                    }
+
+                    values = null;
+                    size = 1;
+                    
+                    break;
+                    
+                default :   
+                    NamingEnumeration vals = attribute.getAll();
+                    
+                    while ( vals.hasMoreElements() )
+                    {
+                        val = vals.nextElement();
+                        
+                        if ( val instanceof String )
+                        {
+                            value = new StringValue( (String)val );
+                        }
+                        else if ( val instanceof byte[] )
+                        {
+                            value = new BinaryValue( (byte[])val );
+                        }
+                        else
+                        {
+                            log.error( "The value's type is not String or byte[]" );
+                            throw new NamingException( "The value's type is not String or byte[]" );
+                        }
+                    }
+                    
+                    values = null;
+                    size = attribute.size();
+                    
+                    break;
+            }
+        }
+        else
+        {
+            log.error( "Attribute must be an instance of BasicAttribute or AttributeImpl" );
+            throw new NamingException( "Attribute must be an instance of BasicAttribute or AttributeImpl" );
+        }
+    }
+
+    
+    /**
+     * 
+     * Clone a value. This private message is used to avoid adding try--catch
+     * all over the code.
+     */
+    private Value getClonedValue( Value value )
+    {
+        try
+        {
+            return (Value)value.clone();
+        }
+        catch ( CloneNotSupportedException csne )
+        {
+            return null;
+        }
+    }
+    
+    // ------------------------------------------------------------------------
+    // ServerAttribute Interface Method Implementations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Gets a Iterator wrapped around the iterator of the value list.
+     * 
+     * @return the Iterator wrapped as a NamingEnumberation.
+     */
+    public Iterator<Value> getAll()
+    {
+        if ( size < 2 )
+        {
+            return new Iterator<Value>()
+            {
+                private boolean more = (value != null);
+                    
+                public boolean hasNext() 
+                {
+                    return more;
+                }
+                
+                public Value next() 
+                {
+                    more = false;
+                    return value;
+                }
+                
+                public void remove() 
+                {
+                    value = null;
+                    more = true;
+                }
+            };
+        }
+        else
+        {
+            return values.iterator();
+        }
+    }
+
+
+    /**
+     * Gets the first value of the list or null if no values exist.
+     * 
+     * @return the first value or null.
+     */
+    public Value get()
+    {
+        switch ( size )
+        {
+            case 0 :
+                return null;
+                
+            case 1 :
+                return value;
+                
+            default :
+                return values.get( 0 );
+        }
+    }
+
+
+    /**
+     * Gets the size of the value list.
+     * 
+     * @return size of the value list.
+     */
+    public int size()
+    {
+        return size;
+    }
+
+
+    /**
+     * Gets the id or name of this Attribute.
+     * 
+     * @return the identifier for this Attribute.
+     */
+    public String getID()
+    {
+        return upId;
+    }
+
+
+    /**
+     * Gets the OID of this Attribute.
+     * 
+     * @return the OID for this Attribute.
+     */
+    public OID getOid()
+    {
+        return oid;
+    }
+
+
+    /**
+     * Checks to see if this Attribute contains val in the list.
+     * 
+     * @param val the value to test for
+     * @return true if val is in the list backing store, false otherwise
+     */
+    public boolean contains( Value val )
+    {
+        switch ( size )
+        {
+            case 0 :
+                return false;
+                
+            case 1 :
+                return AttributeUtils.equals( value, val );
+                
+            default :
+                for ( Value value:values )
+                {
+                    if ( AttributeUtils.equals( value, val ) )
+                    {
+                        return true;
+                    }
+                }
+                
+                return false;
+        }
+    }
+
+
+    /**
+     * Checks to see if this Attribute contains val in the list.
+     * 
+     * @param val the value to test for
+     * @return true if val is in the list backing store, false otherwise
+     */
+    public boolean contains( String val )
+    {
+        return contains( new StringValue( val) );
+    }
+    
+    
+    /**
+     * Checks to see if this Attribute contains val in the list.
+     * 
+     * @param val the value to test for
+     * @return true if val is in the list backing store, false otherwise
+     */
+    public boolean contains( byte[] val )
+    {
+        return contains( new BinaryValue( val) );
+    }
+
+    
+    /**
+     * Adds val into the list of this Attribute's values at the end of the
+     * list.
+     * 
+     * @param val the value to add to the end of the list.
+     * @return true if val is added to the list backing store, false if it
+     *         already existed there.
+     */
+    public boolean add( Value val )
+    {
+        boolean exists = false;
+        
+        if ( contains( val ) )
+        {
+            // Do not duplicate values
+            return true;
+        }
+        
+        // First copy the value
+        val = getClonedValue( val );
+        
+        switch ( size() )
+        {
+            case 0 :
+                value = val;
+                size++;
+                return true;
+                
+            case 1 :
+                // We can't store different kind of Values in the attribute
+                // The null value is an exception
+                if ( ( value != null) && ( val != null ) && 
+                     ( value.getClass() != val.getClass() ) )
+                {
+                    return false;
+                }
+                
+                exists = value.equals( val );
+
+                if ( exists )
+                {
+                    // Don't add two times the same value
+                    return true;
+                }
+                else
+                {
+                    values = new ArrayList<Value>();
+                    values.add( value );
+                    values.add( val );
+                    value = null;
+                    size++;
+                    return true;
+                }
+                
+            default :
+                Value firstValue = values.get( 0 );
+            
+                if ( firstValue.getValue() == null )
+                {
+                    firstValue = values.get( 1 );
+                }
+                
+                // We can't store different kind of Values in the attribute
+                // The null value is an exception
+                if ( ( val != null ) && ( val.getValue() != null ) &&
+                     ( firstValue.getValue().getClass() != val.getClass() ) )
+                {
+                    return false;
+                }
+
+                exists = values.contains( val ); 
+            
+                if ( exists )
+                {
+                    // Don't add two times the same value
+                    return true;
+                }
+                
+                values.add( val );
+                size++;
+                
+                return exists;
+        }
+    }
+
+
+    /**
+     * Adds val into the list of this Attribute's values at the end of the
+     * list.
+     * 
+     * @param val the value to add to the end of the list.
+     * @return true if val is added to the list backing store, false if it
+     *         already existed there.
+     */
+    public boolean add( String val )
+    {
+        return add( new StringValue( val) );
+    }
+
+    
+    /**
+     * Adds val into the list of this Attribute's values at the end of the
+     * list.
+     * 
+     * @param val the value to add to the end of the list.
+     * @return true if val is added to the list backing store, false if it
+     *         already existed there.
+     */
+    public boolean add( byte[] val )
+    {
+        return add( new BinaryValue( val) );
+    }
+    
+    
+    /**
+     * Removes val from the list of this Attribute's values.
+     * 
+     * @param val the value to remove
+     * @return true if val is remove from the list backing store, false if
+     *         never existed there.
+     */
+    public boolean remove( Value val )
+    {
+        if ( contains( val) )
+        {
+            switch ( size )
+            {
+                case 0 :
+                    return false;
+                    
+                case 1 :
+                    value = null;
+                    size = 0;
+                    return true;
+                    
+                case 2 : 
+                    values.remove( val );
+                    value = values.get(0);
+                    values = null;
+                    size--;
+                    return true;
+                    
+                default :
+                    values.remove( val );
+                    size--;
+                    return true;
+            }
+        }
+        else
+        {
+            return false;
+        }
+    }
+    
+    
+    /**
+     * Removes val from the list of this Attribute's values.
+     * 
+     * @param val the value to remove
+     * @return true if val is remove from the list backing store, false if
+     *         never existed there.
+     */
+    public boolean remove( String val )
+    {
+        return remove( new StringValue( val ) );
+    }
+    
+    
+    /**
+     * Removes val from the list of this Attribute's values.
+     * 
+     * @param val the value to remove
+     * @return true if val is remove from the list backing store, false if
+     *         never existed there.
+     */
+    public boolean remove( byte[] val )
+    {
+        return remove( new BinaryValue( val ) );
+    }
+
+
+    /**
+     * Removes all the values of this Attribute from the list backing store.
+     */
+    public void clear()
+    {
+        switch ( size )
+        {
+            case 0 :
+                return;
+                
+            case 1 :
+                value = null;
+                size = 0;
+                return;
+                
+            default :
+                values = null;
+                size = 0;
+                return;
+        }
+    }
+
+
+    /**
+     * Not a deep clone.
+     * 
+     * @return a copy of this attribute using the same parent lock and id
+     *         containing references to all the values of the original.
+     */
+    public Object clone()
+    {
+        try
+        {
+            ServerAttributeImpl clone = (ServerAttributeImpl)super.clone();
+            
+            // Simply copy the OID.
+            clone.oid = oid;
+            
+            if ( size < 2 )
+            {
+                clone.value = (Value)value.clone();
+            }
+            else
+            {
+                clone.values = new ArrayList<Value>( values.size() );
+                
+                for ( Value value:values )
+                {
+                    Value newValue = (Value)value.clone();
+                    clone.values.add( newValue );
+                }
+            }
+            
+            return clone;
+        }
+        catch ( CloneNotSupportedException cnse )
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * Checks for equality between this Attribute instance and another. The 
+     * Attribute ID's are compared with regard to case.
+     * 
+     * The values are supposed to have been normalized first
+     *       
+     * @param obj the Attribute to test for equality
+     * @return true if the obj is an Attribute and equals this Attribute false
+     *         otherwise
+     */
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( ( obj == null ) || !( obj instanceof ServerAttributeImpl ) )
+        {
+            return false;
+        }
+
+        ServerAttributeImpl attr = ( ServerAttributeImpl ) obj;
+        
+        if ( attr.oid != oid )
+        {
+            return false;
+        }
+        
+        if ( !upId.equalsIgnoreCase( attr.getID() ) )
+        {
+            return false;
+        }
+        
+        if ( attr.size != size )
+        {
+            return false;
+        }
+
+        switch ( size )
+        {
+            case 0 :
+                return true;
+                
+            case 1 :
+                return ( value.equals( attr.get() ) );
+            
+            default :
+                Iterator<Value> vals = getAll();
+                
+                while ( vals.hasNext() )
+                {
+                    Value val = vals.next();
+                    
+                    if ( !attr.contains( val ) )
+                    {
+                        return false;
+                    }
+                }
+                
+                return true;
+        }
+    }
+    
+    
+    /**
+     * Normalize the attribute, setting the OID and normalizing the values 
+     *
+     * @param oid The attribute OID
+     * @param normalizer The normalizer
+     */
+    @SuppressWarnings(value="unchecked")
+    public void normalize( OID oid, Normalizer<?> normalizer ) throws NamingException
+    {
+        this.oid = oid;
+        
+        switch ( size )
+        {
+            case 0 :
+                return;
+                
+            case 1 :
+                value.normalize( normalizer );
+                return;
+                
+            default :
+                for ( Value value:values)
+                {
+                    value.normalize( normalizer );
+                }
+        }
+    }
+    
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append( "ServerAttribute id : '" ).append( upId ).append( "', " );
+        
+        if ( oid != null )
+        {
+            sb.append( " OID : " ).append( oid ).append( '\n' );
+        }
+        
+        sb.append( " Values : [");
+        
+        switch ( size )
+        {
+            case 0 :
+                sb.append( "]\n" );
+                break;
+                
+            case 1 :
+                sb.append( '\'' ).append( value ).append( '\'' );
+                sb.append( "]\n" );
+                break;
+                
+            default :
+                boolean isFirst = true;
+            
+                for ( Value value:values )
+                {
+                    if ( isFirst == false )
+                    {
+                        sb.append( ", " );
+                    }
+                    else
+                    {
+                        isFirst = false;
+                    }
+                    
+                    sb.append( '\'' ).append( value ).append( '\'' );
+                }
+                
+                sb.append( "]\n" );
+                break;
+        }
+        
+        return sb.toString();
+    }
+}

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntry.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntry.java?rev=581113&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntry.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntry.java Mon Oct  1 16:57:36 2007
@@ -0,0 +1,224 @@
+/*
+ *  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.shared.ldap.common;
+
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.asn1.primitives.OID;
+import org.apache.directory.shared.ldap.name.LdapDN;
+
+
+/**
+ * This is the interface to a collection of attributes associated with a
+ * directory entry.
+ * <p>
+ * This interface defines the methods that are implemented by a collection of a
+ * particular directory entry's attributes.
+ * </p>
+ * <p>
+ * A directory entry can have zero or more attributes comprising its attributes
+ * collection. The attributes can be identified by name. The names of attributes 
+ * are case insensitive. Method names refer to attribute OID rather than name, 
+ * for performance reasons, as we are internal to the server, where we manipulate
+ * OIDs only.
+ * </p>
+ * <p>
+ * The attribute collection is created when the directory entry is created.
+ * </p>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ServerEntry extends Cloneable, Serializable
+{
+    /**
+     * This constant is used during deserialization to check the version which
+     * created the serialized object.
+     */
+    static final long serialVersionUID = 2L;
+
+
+    /**
+     * Removes all the attributes.
+     */
+    void clear();
+
+
+    /**
+     * Returns a deep copy of this <code>Attributes</code> instance. The
+     * attribute objects <b>are</b> cloned.
+     * 
+     * @return a deep copy of this <code>Attributes</code> instance
+     */
+    Object clone();
+
+
+    /**
+     * Returns the attribute with the specified OID. The return value
+     * is <code>null</code> if no match is found.
+     * 
+     * @param oid attribute OID
+     * @return the attribute with the specified OID
+     */
+    ServerAttribute get( OID oid );
+
+
+    /**
+     * Returns an enumeration containing the zero or more attributes in the
+     * collection. The behaviour of the enumeration is not specified if the
+     * attribute collection is changed.
+     * 
+     * @return an enumeration of all contained attributes
+     */
+    Iterator<ServerAttribute> getAll();
+
+    
+    /**
+     * Get this entry's DN.
+     *
+     * @return The entry DN
+     */
+    public LdapDN getDN();
+    
+
+    /**
+     * Set this entry's DN.
+     * 
+     * @param dn The LdapdN associated with this entry
+     */
+    public void setDN( LdapDN dn);
+    
+
+    /**
+     * Returns an enumeration containing the zero or more OIDs of the
+     * attributes in the collection. The behaviour of the enumeration is not
+     * specified if the attribute collection is changed.
+     * 
+     * @return an enumeration of the OIDs of all contained attributes
+     */
+    Iterator<OID> getOIDs();
+    
+    
+    /**
+     * Places a non-null attribute in the attribute collection. If there is
+     * already an attribute with the same OID as the new attribute, the old one
+     * is removed from the collection and is returned by this method. If there
+     * was no attribute with the same OID the return value is <code>null</code>.
+     * 
+     * @param attribute the attribute to be put
+     * @return the old attribute with the same OID, if exists; otherwise
+     *         <code>null</code>
+     */
+    ServerAttribute put( ServerAttribute attr );
+
+
+    /**
+     * Places a new attribute with the supplied OID and value into the attribute
+     * collection. If there is already an attribute with the same OID, the old
+     * one is removed from the collection and is returned by this method. If
+     * there was no attribute with the same OID the return value is
+     * <code>null</code>.
+     * 
+     * This method provides a mechanism to put an attribute with a
+     * <code>null</code> value: the value of <code>obj</code> may be
+     * <code>null</code>.
+     * 
+     * @param oid the OID of the new attribute to be put
+     * @param val the value of the new attribute to be put
+     * @return the old attribute with the same OID, if exists; otherwise
+     *         <code>null</code>
+     * @throws NamingException If the oid is null.
+     */
+    ServerAttribute put( OID oid, Value val ) throws NamingException;
+    
+
+    /**
+     * Places a new attribute with the supplied OID and value into the attribute
+     * collection. If there is already an attribute with the same OID, the old
+     * one is removed from the collection and is returned by this method. If
+     * there was no attribute with the same OID the return value is
+     * <code>null</code>.
+     * 
+     * This method provides a mechanism to put an attribute with a
+     * <code>null</code> value: the value of <code>obj</code> may be
+     * <code>null</code>.
+     * 
+     * @param oid the OID of the new attribute to be put
+     * @param val the value of the new attribute to be put
+     * @return the old attribute with the same OID, if exists; otherwise
+     *         <code>null</code>
+     * @throws NamingException If the oid is null.
+     */
+    ServerAttribute put( OID oid, String val ) throws NamingException;
+    
+
+    /**
+     * Places a new attribute with the supplied OID and value into the attribute
+     * collection. If there is already an attribute with the same OID, the old
+     * one is removed from the collection and is returned by this method. If
+     * there was no attribute with the same OID the return value is
+     * <code>null</code>.
+     * 
+     * This method provides a mechanism to put an attribute with a
+     * <code>null</code> value: the value of <code>obj</code> may be
+     * <code>null</code>.
+     * 
+     * @param oid the OID of the new attribute to be put
+     * @param val the value of the new attribute to be put
+     * @return the old attribute with the same OID, if exists; otherwise
+     *         <code>null</code>
+     * @throws NamingException If the oid is null.
+     */
+    ServerAttribute put( OID oid, byte[] val ) throws NamingException;
+ 
+    
+    /**
+     * Removes the attribute with the specified OID. The removed attribute is
+     * returned by this method. If there is no attribute with the specified OID,
+     * the return value is <code>null</code>.
+     * 
+     * @param oid the OID of the attribute to be removed
+     * @return the removed attribute, if exists; otherwise <code>null</code>
+     */
+     ServerAttribute remove( OID oid );
+
+
+     /**
+      * Removes the specified attribute. The removed attribute is
+      * returned by this method. If there were no attribute the return value 
+      * is <code>null</code>.
+      * 
+      * @param attribute the attribute to be removed
+      * @return the removed attribute, if exists; otherwise <code>null</code>
+      */
+     ServerAttribute remove( ServerAttribute attribute );
+
+
+     /**
+      * Returns the number of attributes.
+      * 
+      * @return the number of attributes
+      */
+     int size();
+}

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntryImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntryImpl.java?rev=581113&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntryImpl.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/ServerEntryImpl.java Mon Oct  1 16:57:36 2007
@@ -0,0 +1,548 @@
+/*
+ *  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.shared.ldap.common;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.asn1.primitives.OID;
+import org.apache.directory.shared.ldap.name.LdapDN;
+
+/**
+ * An implementation of an Entry. Compared to the javax.naming.Attributes, 
+ * we store the entry DN into this element, to avoid a DN parsing when
+ * retrieving an entry from the backend.
+ * 
+ * This class is <b>not</b> thread safe ! Manipulating entry's attributes in 
+ * two threads may lead to inconsistancies
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ServerEntryImpl implements ServerEntry
+{
+    /** The entry's DN */
+    private LdapDN dn;
+    
+    /** 
+     * An Hashed structure to store a link between attribute OID and
+     * the ServerAttribute. It is used for increasing performances
+     */
+    private transient Map<OID, ServerAttribute> hashAttrs;
+    
+    /** The attribute list. */
+    private List<ServerAttribute> attributes;
+    
+    /**
+     * This constant is used during deserialization to check the version which
+     * created the serialized object.
+     */
+    static final long serialVersionUID = 2L;
+
+    
+    /**
+     * 
+     * Creates a new instance of ServerEntryImpl.
+     *
+     */
+    public ServerEntryImpl()
+    {
+        attributes = new ArrayList<ServerAttribute>();
+        hashAttrs = new HashMap<OID, ServerAttribute>();
+    }
+
+    
+    /**
+     * 
+     * Creates a new instance of ServerEntryImpl.
+     *
+     */
+    public ServerEntryImpl( LdapDN dn)
+    {
+        attributes = new ArrayList<ServerAttribute>();
+        hashAttrs = new HashMap<OID, ServerAttribute>();
+        this.dn = dn;
+    }
+
+    
+    /**
+     * Removes all the attributes.
+     */
+    public void clear()
+    {
+        if ( attributes != null )
+        {
+            attributes.clear();
+            hashAttrs.clear();
+        }
+    }
+
+
+    /**
+     * Returns a deep copy of this <code>Attributes</code> instance. The
+     * attribute objects <b>are</b> cloned.
+     * 
+     * @return a deep copy of this <code>Attributes</code> instance
+     */
+    public Object clone()
+    {
+        try
+        {
+            ServerEntryImpl clone = (ServerEntryImpl)super.clone();
+            
+            clone.dn = (LdapDN)dn.clone();
+            
+            if ( attributes != null )
+            {
+                clone.attributes = new ArrayList<ServerAttribute>( attributes.size() );
+                clone.hashAttrs = new HashMap<OID, ServerAttribute>( attributes.size() );
+            
+                for ( ServerAttribute attr:attributes )
+                {
+                    ServerAttribute clonedAttr = (ServerAttribute)attr.clone();
+                    clone.attributes.add( attr );
+                    clone.hashAttrs.put( attr.getOid(), clonedAttr );
+                }
+            }
+            
+            return clone;
+        }
+        catch ( CloneNotSupportedException cnse )
+        {
+            // I see no reason why it should ever happen...
+            return null;
+        }
+    }
+
+
+    /**
+     * Returns the attribute with the specified OID. The return value
+     * is <code>null</code> if no match is found.
+     * 
+     * @param oid attribute OID
+     * @return the attribute with the specified OID
+     */
+    public ServerAttribute get( OID oid )
+    {
+        assert( oid != null );
+        
+        return hashAttrs.get( oid );
+    }
+
+
+    /**
+     * Returns an iterator containing the zero or more attributes in the
+     * collection. The behaviour of the iterator is not specified if the
+     * attribute collection is changed.
+     * 
+     * @return an iterator of all contained attributes
+     */
+    public Iterator<ServerAttribute> getAll()
+    {
+        return new ServerAttributeIterator();
+    }
+
+    
+    /**
+     * Get this entry's DN.
+     *
+     * @return The entry DN
+     */
+    public LdapDN getDN()
+    {
+        return dn;
+    }
+    
+    
+    /**
+     * Set this entry's DN.
+     * 
+     * @param dn The LdapdN associated with this entry
+     */
+    public void setDN( LdapDN dn)
+    {
+        this.dn = dn;
+    }
+    
+
+    /**
+     * An inner class used to iterate through OIDs.
+=    */
+    private class OidIterator implements Iterator<OID>
+    {
+        /** The iterator */
+        private Iterator<ServerAttribute> iterator;
+        
+        /** The current position */
+        int index;
+        
+        /** The max number of elements */
+        int max;
+        
+        /**
+         * Creates a new instance of OidIterator.
+         */
+        private OidIterator()
+        {
+            iterator = attributes.iterator();
+            
+            index = 0;
+
+            if ( ( attributes != null ) && ( attributes.size() != 0 ) )
+            {
+                max = 0;
+            }
+            else
+            {
+                max = attributes.size();
+            }
+        }
+    
+        /**
+         * Not supported
+         */
+        public void remove()
+        {
+            throw new UnsupportedOperationException( "Remove is not supported" );
+        }
+        
+        /**
+         * Tells if there is a next element in the list
+         */
+        public boolean hasNext()
+        {
+            return index < max;
+        }
+        
+        /**
+         * Returns the next OID in the list
+         */
+        public OID next()
+        {
+            if ( index >= max )
+            {
+                return null;
+            }
+            
+            index++;
+            ServerAttribute current = iterator.next();
+             
+            return current.getOid();
+        }
+    }    
+
+    
+    /**
+     * An inner class used to iterate through ServerAttributes.
+=    */
+    private class ServerAttributeIterator implements Iterator<ServerAttribute>
+    {
+        /** The iterator */
+        private Iterator<ServerAttribute> iterator;
+        
+        /** The current position */
+        int index;
+        
+        /** The max number of elements */
+        int max;
+        
+        /**
+         * Creates a new instance of ServerAttributeIterator.
+         */
+        private ServerAttributeIterator()
+        {
+            iterator = attributes.iterator();
+            
+            index = 0;
+
+            if ( ( attributes != null ) && ( attributes.size() != 0 ) )
+            {
+                max = 0;
+            }
+            else
+            {
+                max = attributes.size();
+            }
+        }
+    
+        /**
+         * Not supported
+         */
+        public void remove()
+        {
+            throw new UnsupportedOperationException( "Remove is not supported" );
+        }
+        
+        /**
+         * Tells if there is a next element in the list
+         */
+        public boolean hasNext()
+        {
+            return index < max;
+        }
+        
+        /**
+         * Returns the next OID in the list
+         */
+        public ServerAttribute next()
+        {
+            if ( index >= max )
+            {
+                return null;
+            }
+            
+            index++;
+            ServerAttribute current = iterator.next();
+             
+            return current;
+        }
+    }    
+
+    
+    /**
+     * Returns an iterator containing zero or more OIDs of the
+     * attributes in the collection. The behaviour of the iterator is not
+     * specified if the attribute collection is changed.
+     * 
+     * @return an iterator of the OIDs of all contained attributes
+     */
+    public Iterator<OID> getOIDs()
+    {
+        return new OidIterator();
+    }
+    
+    
+    /**
+     * Places a non-null attribute in the attribute collection. If there is
+     * already an attribute with the same OID as the new attribute, the old one
+     * is removed from the collection and is returned by this method. If there
+     * was no attribute with the same OID the return value is <code>null</code>.
+     * 
+     * @param attribute the attribute to be put
+     * @return the old attribute with the same OID, if exists; otherwise
+     *         <code>null</code>
+     */
+    public ServerAttribute put( ServerAttribute attr )
+    {
+        // First, some defensive code
+        if ( attr == null )
+        {
+            return null;
+        }
+        
+        if( attr.getOid() == null )
+        {
+            return null;
+        }
+        
+        // Get the previous attribute, if any
+        ServerAttribute replacedAttribute = hashAttrs.put( attr.getOid(), attr );
+        
+        if ( replacedAttribute != null )
+        {
+            // Remove the previous attribute from the list
+            attributes.remove( replacedAttribute );
+        }
+        
+        // Store the new attribute at the end of the list 
+        attributes.add( attr );
+        
+        return replacedAttribute;
+    }
+    
+    
+    /**
+     * Places a new attribute with the supplied OID and value into the attribute
+     * collection. If there is already an attribute with the same OID, the old
+     * one is removed from the collection and is returned by this method. If
+     * there was no attribute with the same OID the return value is
+     * <code>null</code>.
+     * 
+     * This method provides a mechanism to put an attribute with a
+     * <code>null</code> value: the value of <code>obj</code> may be
+     * <code>null</code>.
+     * 
+     * @param oid the OID of the new attribute to be put
+     * @param val the value of the new attribute to be put
+     * @return the old attribute with the same OID, if exists; otherwise
+     *         <code>null</code>
+     * @throws NamingException If the oid is null.
+     */
+    public ServerAttribute put( OID oid, Value val ) throws NamingException
+    {
+        return put( new ServerAttributeImpl( oid, val ) );
+    }
+    
+
+    /**
+     * Places a new attribute with the supplied OID and value into the attribute
+     * collection. If there is already an attribute with the same OID, the old
+     * one is removed from the collection and is returned by this method. If
+     * there was no attribute with the same OID the return value is
+     * <code>null</code>.
+     * 
+     * This method provides a mechanism to put an attribute with a
+     * <code>null</code> value: the value of <code>obj</code> may be
+     * <code>null</code>.
+     * 
+     * @param oid the OID of the new attribute to be put
+     * @param val the value of the new attribute to be put
+     * @return the old attribute with the same OID, if exists; otherwise
+     *         <code>null</code>
+     * @throws NamingException If the oid is null.
+     */
+    public ServerAttribute put( OID oid, String val ) throws NamingException
+    {
+        return put( new ServerAttributeImpl( oid, val ) );
+    }
+    
+    
+
+    /**
+     * Places a new attribute with the supplied OID and value into the attribute
+     * collection. If there is already an attribute with the same OID, the old
+     * one is removed from the collection and is returned by this method. If
+     * there was no attribute with the same OID the return value is
+     * <code>null</code>.
+     * 
+     * This method provides a mechanism to put an attribute with a
+     * <code>null</code> value: the value of <code>obj</code> may be
+     * <code>null</code>.
+     * 
+     * @param oid the OID of the new attribute to be put
+     * @param val the value of the new attribute to be put
+     * @return the old attribute with the same OID, if exists; otherwise
+     *         <code>null</code>
+     * @throws NamingException If the oid is null.
+     */
+    public ServerAttribute put( OID oid, byte[] val ) throws NamingException
+    {
+        if ( oid == null )
+        {
+            // We can't add a new ServerAttribute with no OID
+            throw new NamingException( "Attributes with an empty ID or OID are not allowed" );
+        }
+        
+        // Remove any previoulsy existing ServerAttribute with the
+        // same OID
+        ServerAttribute oldAttr = hashAttrs.get( oid );
+        
+        if ( oldAttr != null )
+        {
+            attributes.remove( oid );
+            hashAttrs.remove( oid );
+        }
+        
+        // Create a new ServerAttribute
+        ServerAttribute attribute = new ServerAttributeImpl( oid, val );
+        
+        attributes.add( attribute );
+        hashAttrs.put(  oid, attribute );
+        
+        return oldAttr;
+    }
+    
+    /**
+     * Removes the attribute with the specified OID. The removed attribute is
+     * returned by this method. If there is no attribute with the specified OID,
+     * the return value is <code>null</code>.
+     * 
+     * @param oid the OID of the attribute to be removed
+     * @return the removed attribute, if exists; otherwise <code>null</code>
+     */
+     public ServerAttribute remove( OID oid )
+     {
+         // First, some defensive code
+         if ( oid == null )
+         {
+             return null;
+         }
+         
+         // Get the previous attribute, if any
+         ServerAttribute attribute = hashAttrs.get( oid );
+         
+         if ( attribute != null )
+         {
+             hashAttrs.remove( oid );
+             attributes.remove( attribute );
+         }
+         
+         return attribute;
+     }
+
+
+     /**
+      * Removes the attribute with the specified OID. The removed attribute is
+      * returned by this method. If there is no attribute with the specified OID,
+      * the return value is <code>null</code>.
+      * 
+      * @param attribute the attribute to be removed
+      * @return the removed attribute, if exists; otherwise <code>null</code>
+      */
+      public ServerAttribute remove( ServerAttribute attribute )
+      {
+          // First, some defensive code
+          if ( attribute == null )
+          {
+              return null;
+          }
+          
+          OID oid = attribute.getOid();
+
+          if ( oid == null )
+          {
+              return null;
+          }
+          
+          // Get the previous attribute, if any
+          ServerAttribute existingAttr = hashAttrs.get( oid );
+          
+          if ( existingAttr != null )
+          {
+              hashAttrs.remove( oid );
+              attributes.remove( existingAttr );
+          }
+          
+          return existingAttr;
+      }
+
+
+     /**
+      * Returns the number of attributes.
+      * 
+      * @return the number of attributes
+      */
+     public int size()
+     {
+         if ( attributes == null )
+         {
+             return 0;
+         }
+         else
+         {
+             return attributes.size();
+         }
+     }
+}

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/StringValue.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/StringValue.java?rev=581113&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/StringValue.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/StringValue.java Mon Oct  1 16:57:36 2007
@@ -0,0 +1,92 @@
+/*
+ *  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.shared.ldap.common;
+
+
+/**
+ * A class storing a String value.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class StringValue extends AbstractValue<String>
+{
+    /**
+     * serialVersionUID 
+     */
+    static final long serialVersionUID = 2L;
+
+    
+    /**
+     * Creates a new instance of StringValue with no value
+     */
+    public StringValue()
+    {
+        super( null );
+    }
+    
+    
+    /**
+     * Creates a new instance of StringValue with a value
+     */
+    public StringValue( String value )
+    {
+        super( value );
+    }
+    
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        return "StringValue : " + value;
+    }
+    
+    
+    /**
+     * @see Object#hashCode()
+     */
+    public int hashCode()
+    {
+        return value.hashCode();
+    }
+
+    
+    /**
+     * @see Object#equals(Object)
+     */
+    public boolean equals( Object obj )
+    {
+        if ( !super.equals( obj ) )
+        {
+            return false;
+        }
+        
+        StringValue value = (StringValue)obj;
+        
+        if ( this.value == null )
+        {
+            return value.value == null;
+        }
+        
+        return this.value.equals( value.value );
+    }
+}

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/Value.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/Value.java?rev=581113&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/Value.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/common/Value.java Mon Oct  1 16:57:36 2007
@@ -0,0 +1,91 @@
+/*
+ *  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.shared.ldap.common;
+
+import java.io.Serializable;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.ldap.schema.Normalizer;
+
+/**
+ * A common interface for values stored into a ServerAttribute. Thos values can 
+ * be String or byte[] 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface Value<T> extends Serializable, Cloneable
+{
+    /**
+     * Tells if the Value is a StringValue or a BinaryValue
+     *
+     * @return <code>true</code> if the Value is a BinaryVale, <code>false</code>
+     * otherwise
+     */
+    boolean isBinary();
+    
+    /**
+     * Get the inner value
+     *
+     * @return The stored value, in its original type (String or byte[])
+     */
+    T getValue();
+    
+    
+    /**
+     * Get the normalized inner value
+     *
+     * @return The normalized stored value, in its original type (String or byte[])
+     */
+    T getNormValue();
+    
+    
+    /**
+     * Store a value into the object
+     *
+     * @param value The value to store. Should be either a String or a byte[]
+     */
+    void setValue( T value );
+    
+    /**
+     * 
+     * Normalize the value using the given normalizer
+     *
+     * @param normalizer The normalizer to use
+     * @throws NamingException If the normalization fail
+     */
+    void normalize( Normalizer<T> normalizer ) throws NamingException;
+    
+    /**
+     * Tells if the value has been normalized. It's a speedup.
+     *
+     * @return <code>true</code> if the Value has been normalized, <code>false</code>
+     * otherwise
+     */
+    boolean isNormalized();
+    
+    /**
+     * Makes a copy of the Value. 
+     *
+     * @return A non-null copy of the Value.
+     */
+    Object clone() throws CloneNotSupportedException;
+}



Mime
View raw message