You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2008/03/31 18:20:08 UTC
svn commit: r643046 [7/8] - in /directory:
apacheds/branches/bigbang/benchmarks/
apacheds/branches/bigbang/core-constants/src/main/java/org/apache/directory/server/constants/
apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/serve...
Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/Entry.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/Entry.java?rev=643046&r1=643045&r2=643046&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/Entry.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/Entry.java Mon Mar 31 09:19:45 2008
@@ -20,7 +20,6 @@
import org.apache.directory.shared.ldap.name.LdapDN;
-import org.apache.directory.shared.ldap.schema.AttributeType;
import javax.naming.NamingException;
@@ -29,49 +28,109 @@
/**
+ * <p>
* This interface represent a LDAP entry. An LDAP entry contains :
- * - A distinguished name (DN)
- * - A list of attributes
- *
+ * <li> A distinguished name (DN)</li>
+ * <li> A list of attributes</li>
+ * </p>
+ * <p>
* The available methods on this object are described in this interface.
- *
+ * </p>
+ * <p>
* This interface is used by the serverEntry and clientEntry interfaces.
- *
+ *</p>
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
-public interface Entry<T extends EntryAttribute> extends Cloneable, Iterable<T>
+public interface Entry extends Cloneable, Iterable<EntryAttribute>
{
/**
- * Removes all the attributes.
+ * Remove all the attributes for this entry. The DN is not reset
*/
void clear();
/**
+ * Clone the current entry
+ */
+ Entry clone();
+
+
+ /**
* Get this entry's DN.
*
- * @return The entry DN
+ * @return The entry's DN
*/
LdapDN getDn();
/**
+ * Tells if an entry as a specific ObjectClass value
+ *
+ * @param objectClass The ObjectClassw we want to check
+ * @return <code>true</code> if the ObjectClass value is present
+ * in the ObjectClass attribute
+ */
+ boolean hasObjectClass( String objectClass );
+
+
+ /**
+ * <p>
+ * Returns the attribute with the specified alias. The return value
+ * is <code>null</code> if no match is found.
+ * </p>
+ * <p>An Attribute with an id different from the supplied alias may
+ * be returned: for example a call with 'cn' may in some implementations
+ * return an Attribute whose getId() field returns 'commonName'.
+ * </p>
+ *
+ * @param alias an aliased name of the attribute identifier
+ * @return the attribute associated with the alias
+ */
+ EntryAttribute get( String alias );
+
+
+ /**
+ * <p>
+ * Put some new ClientAttribute using the User Provided ID.
+ * No value is inserted.
+ * </p>
+ * <p>
+ * If an existing Attribute is found, it will be replaced by an
+ * empty attribute, and returned to the caller.
+ * </p>
+ *
+ * @param upIds The user provided IDs of the AttributeTypes to add.
+ * @return A list of replaced Attributes.
+ */
+ List<EntryAttribute> set( String... upIds );
+
+
+ /**
* Set this entry's DN.
*
- * @param dn The LdapdN associated with this entry
+ * @param dn The DN associated with this entry
*/
- void setDn( LdapDN dn);
+ void setDn( LdapDN dn );
/**
* Returns an enumeration containing the zero or more attributes in the
- * collection. The behaviour of the enumeration is not specified if the
+ * collection. The behavior of the enumeration is not specified if the
* attribute collection is changed.
*
* @return an enumeration of all contained attributes
*/
- Iterator<T> iterator();
+ Iterator<EntryAttribute> iterator();
+
+
+ /**
+ * Add some Attributes to the current Entry.
+ *
+ * @param attributes The attributes to add
+ * @throws NamingException If we can't add any of the attributes
+ */
+ void add( EntryAttribute... attributes ) throws NamingException;
/**
@@ -80,45 +139,97 @@
* @param upId The user provided ID of the attribute we want to add
* some values to
* @param values The list of String values to add
- * @throws NamingException
+ * @throws NamingException If we can't add any of the values
*/
void add( String upId, String... values ) throws NamingException;
-
+
/**
* Add some binary values to the current Entry.
*
* @param upId The user provided ID of the attribute we want to add
* some values to
* @param values The list of binary values to add
- * @throws NamingException
+ * @throws NamingException If we can't add any of the values
*/
void add( String upId, byte[]... values ) throws NamingException;
-
+
/**
* Add some Values to the current Entry.
*
* @param upId The user provided ID of the attribute we want to add
* some values to
* @param values The list of Values to add
- * @throws NamingException
+ * @throws NamingException If we can't add any of the values
*/
void add( String upId, Value<?>... values ) throws NamingException;
-
-
+
+
/**
- * Places non-null attributes in the attribute collection. If there is
- * already an attribute with the same OID as any of the new attributes,
- * the old ones are removed from the collection and are returned by this
- * method. If there was no attribute with the same OID the return value
- * is <code>null</code>.
+ * <p>
+ * Places attributes in the attribute collection.
+ * </p>
+ * <p>If there is already an attribute with the same ID as any of the
+ * new attributes, the old ones are removed from the collection and
+ * are returned by this method. If there was no attribute with the
+ * same ID the return value is <code>null</code>.
+ *</p>
*
* @param attributes the attributes to be put
* @return the old attributes with the same OID, if exist; otherwise
* <code>null</code>
+ * @exception NamingException if the operation fails
+ */
+ List<EntryAttribute> put( EntryAttribute... attributes ) throws NamingException;
+
+
+ /**
+ * <p>
+ * Put an attribute (represented by its ID and some binary values) into an entry.
+ * </p>
+ * <p>
+ * If the attribute already exists, the previous attribute will be
+ * replaced and returned.
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param values The list of binary values to put. It can be empty.
+ * @return The replaced attribute
+ */
+ EntryAttribute put( String upId, byte[]... values );
+
+
+ /**
+ * <p>
+ * Put an attribute (represented by its ID and some String values) into an entry.
+ * </p>
+ * <p>
+ * If the attribute already exists, the previous attribute will be
+ * replaced and returned.
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param values The list of String values to put. It can be empty.
+ * @return The replaced attribute
+ */
+ EntryAttribute put( String upId, String... values );
+
+
+ /**
+ * <p>
+ * Put an attribute (represented by its ID and some values) into an entry.
+ * </p>
+ * <p>
+ * If the attribute already exists, the previous attribute will be
+ * replaced and returned.
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param values The list of values to put. It can be empty.
+ * @return The replaced attribute
*/
- List<T> put( T... attributes ) throws NamingException;
+ EntryAttribute put( String upId, Value<?>... values );
/**
@@ -129,57 +240,162 @@
* @param attributes the attributes to be removed
* @return the removed attribute, if exists; otherwise <code>null</code>
*/
- List<T> remove( T... attributes ) throws NamingException;
+ List<EntryAttribute> remove( EntryAttribute... attributes ) throws NamingException;
/**
- * Checks if an entry contains an attribute with a given value.
+ * <p>
+ * Removes the specified binary values from an attribute.
+ * </p>
+ * <p>
+ * If at least one value is removed, this method returns <code>true</code>.
+ * </p>
+ * <p>
+ * If there is no more value after having removed the values, the attribute
+ * will be removed too.
+ * </p>
+ * <p>
+ * If the attribute does not exist, nothing is done and the method returns
+ * <code>false</code>
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param attributes the attributes to be removed
+ * @return <code>true</code> if at least a value is removed, <code>false</code>
+ * if not all the values have been removed or if the attribute does not exist.
+ */
+ boolean remove( String upId, byte[]... values ) throws NamingException;
+
+
+ /**
+ * <p>
+ * Removes the specified String values from an attribute.
+ * </p>
+ * <p>
+ * If at least one value is removed, this method returns <code>true</code>.
+ * </p>
+ * <p>
+ * If there is no more value after havong removed the values, the attribute
+ * will be removed too.
+ * </p>
+ * <p>
+ * If the attribute does not exist, nothing is done and the method returns
+ * <code>false</code>
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param attributes the attributes to be removed
+ * @return <code>true</code> if at least a value is removed, <code>false</code>
+ * if no values have been removed or if the attribute does not exist.
+ */
+ boolean remove( String upId, String... values ) throws NamingException;
+
+
+ /**
+ * <p>
+ * Removes the specified values from an attribute.
+ * </p>
+ * <p>
+ * If at least one value is removed, this method returns <code>true</code>.
+ * </p>
+ * <p>
+ * If there is no more value after having removed the values, the attribute
+ * will be removed too.
+ * </p>
+ * <p>
+ * If the attribute does not exist, nothing is done and the method returns
+ * <code>false</code>
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param attributes the attributes to be removed
+ * @return <code>true</code> if at least a value is removed, <code>false</code>
+ * if not all the values have been removed or if the attribute does not exist.
+ */
+ boolean remove( String upId, Value<?>... values ) throws NamingException;
+
+
+ /**
+ * <p>
+ * Removes the attribute with the specified alias.
+ * </p>
+ * <p>
+ * The removed attribute are returned by this method.
+ * </p>
+ * <p>
+ * If there is no attribute with the specified alias,
+ * the return value is <code>null</code>.
+ * </p>
+ *
+ * @param attributes an aliased name of the attribute to be removed
+ * @return the removed attributes, if any, as a list; otherwise <code>null</code>
+ */
+ List<EntryAttribute> removeAttributes( String... attributes );
+
+
+ /**
+ * <p>
+ * Checks if an entry contains a list of attributes.
+ * </p>
+ * <p>
+ * If the list is null or empty, this method will return <code>true</code>
+ * if the entry has no attribute, <code>false</code> otherwise.
+ * </p>
*
- * @param attributeType The Attribute type we are looking for
- * @param value The searched value
- * @return <code>true</code> if the value is found within the attribute
+ * @param attributes The Attributes to look for
+ * @return <code>true</code> if all the attributes are found within
+ * the entry, <code>false</code> if at least one of them is not present.
* @throws NamingException If the attribute does not exist
*/
- boolean contains( AttributeType attributeType, Value<?> value ) throws NamingException;
-
-
+ boolean contains( EntryAttribute... attributes ) throws NamingException;
+
+
/**
- * Checks if an entry contains an attribute with a given value.
+ * Checks if an entry contains an attribute with some binary values.
*
- * @param id The Attribute ID we are looking for
- * @param value The searched value
- * @return <code>true</code> if the value is found within the attribute
- * @throws NamingException If the attribute does not exist
+ * @param id The Attribute we are looking for.
+ * @param values The searched values.
+ * @return <code>true</code> if all the values are found within the attribute,
+ * false if at least one value is not present or if the ID is not valid.
*/
- boolean contains( String id, Value<?> value ) throws NamingException;
-
-
+ boolean contains( String upId, byte[]... values );
+
+
/**
- * Checks if an entry contains an attribute with a given value.
+ * Checks if an entry contains an attribute with some String values.
*
- * @param id The Attribute ID we are looking for
- * @param value The searched value
- * @return <code>true</code> if the value is found within the attribute
- * @throws NamingException If the attribute does not exist
+ * @param id The Attribute we are looking for.
+ * @param values The searched values.
+ * @return <code>true</code> if all the values are found within the attribute,
+ * false if at least one value is not present or if the ID is not valid.
*/
- boolean contains( String id, String value ) throws NamingException;
+ boolean contains( String upId, String... values );
+
-
/**
- * Checks if an entry contains an attribute with a given value.
+ * Checks if an entry contains an attribute with some values.
*
- * @param id The Attribute ID we are looking for
- * @param value The searched value
- * @return <code>true</code> if the value is found within the attribute
- * @throws NamingException If the attribute does not exist
+ * @param id The Attribute we are looking for.
+ * @param values The searched values.
+ * @return <code>true</code> if all the values are found within the attribute,
+ * false if at least one value is not present or if the ID is not valid.
*/
- boolean contains( String id, byte[] value ) throws NamingException;
+ boolean contains( String upId, Value<?>... values );
+
+
+ /**
+ * Checks if an entry contains some specific attributes.
+ *
+ * @param attributes The Attributes to look for.
+ * @return <code>true</code> if the attributes are all found within the entry.
+ */
+ boolean containsAttribute( String... attributes );
/**
- * Returns the number of attributes.
- *
- * @return the number of attributes
- */
+ * Returns the number of attributes.
+ *
+ * @return the number of attributes
+ */
int size();
}
Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/Value.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/Value.java?rev=643046&r1=643045&r2=643046&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/Value.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/Value.java Mon Mar 31 09:19:45 2008
@@ -19,7 +19,7 @@
*/
package org.apache.directory.shared.ldap.entry;
-import java.io.Serializable;
+import java.io.Externalizable;
import javax.naming.NamingException;
@@ -34,7 +34,7 @@
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
-public interface Value<T> extends Cloneable, Serializable, Comparable<Value<T>>
+public interface Value<T> extends Cloneable, Externalizable, Comparable<Value<T>>
{
Value<T> clone();
Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientBinaryValue.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientBinaryValue.java?rev=643046&r1=643045&r2=643046&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientBinaryValue.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientBinaryValue.java Mon Mar 31 09:19:45 2008
@@ -29,6 +29,11 @@
import org.slf4j.LoggerFactory;
import javax.naming.NamingException;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
import java.util.Arrays;
@@ -335,6 +340,25 @@
}
+ /**
+ * @see Externalizable#readExternal(ObjectInput)
+ */
+ public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
+ {
+ // TODO implement this method
+ return;
+ }
+
+
+ /**
+ * @see Externalizable#writeExternal(ObjectOutput)
+ */
+ public void writeExternal( ObjectOutput out ) throws IOException
+ {
+ // TODO Implement this method
+ }
+
+
/**
* Dumps binary in hex with label.
*
Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientEntry.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientEntry.java?rev=643046&r1=643045&r2=643046&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientEntry.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientEntry.java Mon Mar 31 09:19:45 2008
@@ -20,7 +20,6 @@
import org.apache.directory.shared.ldap.entry.Entry;
-import org.apache.directory.shared.ldap.entry.Value;
/**
@@ -34,85 +33,4 @@
*/
public interface ClientEntry extends Entry
{
- /**
- * Returns the attribute with the specified alias. The return value
- * is <code>null</code> if no match is found. An Attribute with an id
- * different from the supplied alias may be returned: for example a call
- * with 'cn' may in some implementations return a ClientAttribute whose
- * getId() feild returns 'commonName'.
- *
- * @param alias an aliased name of the attribute identifier
- * @return the attribute associated with the alias
- */
- ClientAttribute get( String alias );
-
-
- /**
- * Places a new attribute with the supplied alias and value into the
- * attribute collection. If there is already an attribute associated with
- * the alias, the old one is removed from the collection and is returned
- * by this method. If there was no attribute associated with the alias the
- * return value is <code>null</code>. An attribute with an id different
- * from the supplied alias may be returned: for example a call with 'cn'
- * may in some implementations return a ClientAttribute whose getId()
- * feild returns 'commonName'.
- *
- * This method provides a mechanism to put an attribute with a <code>null
- * </code> value: the value of <code>val</code> may be <code>null</code>.
- *
- * @param alias an aliased name of the new attribute to be put
- * @param val the value of the new attribute to be put
- * @return the old attribute with associated with the specified alias,
- * if exists; otherwise <code>null</code>
- */
- ClientAttribute put( String alias, Value<?> 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 alias an aliased name 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 identifier, if exists; otherwise
- * <code>null</code>
- */
- ClientAttribute put( String alias, String 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 alias an aliased 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 identifier, if exists; otherwise
- * <code>null</code>
- */
- ClientAttribute put( String alias, byte[] val );
-
-
- /**
- * Removes the attribute with the specified alias. 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 alias an aliased name of the attribute to be removed
- * @return the removed attribute, if exists; otherwise <code>null</code>
- */
- ClientAttribute remove( String alias );
}
Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java?rev=643046&r1=643045&r2=643046&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java Mon Mar 31 09:19:45 2008
@@ -19,6 +19,11 @@
package org.apache.directory.shared.ldap.entry.client;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
import org.apache.directory.shared.ldap.NotImplementedException;
import org.apache.directory.shared.ldap.entry.AbstractValue;
import org.apache.directory.shared.ldap.entry.Value;
@@ -286,6 +291,25 @@
// Test the normalized values
return this.getNormalizedValue().equals( other.getNormalizedValue() );
+ }
+
+
+ /**
+ * @see Externalizable#readExternal(ObjectInput)
+ */
+ public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
+ {
+ // TODO implement this method
+ return;
+ }
+
+
+ /**
+ * @see Externalizable#writeExternal(ObjectOutput)
+ */
+ public void writeExternal( ObjectOutput out ) throws IOException
+ {
+ // TODO Implement this method
}
Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java?rev=643046&r1=643045&r2=643046&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java Mon Mar 31 09:19:45 2008
@@ -108,15 +108,9 @@
{
for ( Value<?> val:vals )
{
- if ( val instanceof ClientStringValue )
- {
- ClientStringValue serverString = ( ClientStringValue ) val;
- add( new ClientStringValue( serverString.get() ) );
- }
- else if ( val instanceof ClientBinaryValue )
+ if ( ( val instanceof ClientStringValue ) || ( val instanceof ClientBinaryValue ) )
{
- ClientBinaryValue serverBinary = ( ClientBinaryValue ) val;
- add( new ClientBinaryValue( serverBinary.getCopy() ) );
+ add( val );
}
else
{
@@ -415,6 +409,7 @@
values.add( nullBinaryValue );
values.add( nullStringValue );
nullValueAdded = true;
+ nbAdded++;
}
else if ( !isHR )
{
@@ -425,6 +420,7 @@
if ( !values.contains( nullBinaryValue ) )
{
values.add( nullBinaryValue );
+ nbAdded++;
}
}
@@ -451,6 +447,7 @@
// The attribute type will be set to HR
isHR = true;
values.add( val );
+ nbAdded++;
}
else if ( !isHR )
{
@@ -459,12 +456,20 @@
ClientBinaryValue cbv = new ClientBinaryValue();
cbv.set( StringTools.getBytesUtf8( (String)val.get() ) );
- values.add( cbv );
+ if ( !contains( cbv ) )
+ {
+ values.add( cbv );
+ nbAdded++;
+ }
}
else
{
// The attributeType is HR, simply add the value
- values.add( val );
+ if ( !contains( val ) )
+ {
+ values.add( val );
+ nbAdded++;
+ }
}
}
else
@@ -475,11 +480,16 @@
// The attribute type will be set to binary
isHR = false;
values.add( val );
+ nbAdded++;
}
else if ( !isHR )
{
- // The attributeType is not HR, simply add the value
- values.add( val );
+ // The attributeType is not HR, simply add the value if it does not already exist
+ if ( !contains( val ) )
+ {
+ values.add( val );
+ nbAdded++;
+ }
}
else
{
@@ -488,12 +498,14 @@
ClientStringValue csv = new ClientStringValue();
csv.set( StringTools.utf8ToString( (byte[])val.get() ) );
- values.add( csv );
+ if ( !contains( csv ) )
+ {
+ values.add( csv );
+ nbAdded++;
+ }
}
}
}
-
- nbAdded++;
}
// Last, not least, if a nullValue has been added, and if other
@@ -536,9 +548,13 @@
{
for ( String val:vals )
{
- if ( add( new ClientStringValue( val ) ) == 1 )
+ // Call the add(Value) method, if not already present
+ if ( !contains( val ) )
{
- nbAdded++;
+ if ( add( new ClientStringValue( val ) ) == 1 )
+ {
+ nbAdded++;
+ }
}
}
}
@@ -618,10 +634,13 @@
valString = StringTools.utf8ToString( val );
}
- // Now call the add(Value) method
- if ( add( new ClientStringValue( valString ) ) == 1 )
+ // Now call the add(Value) method, if not already present
+ if ( !contains( val ) )
{
- nbAdded++;
+ if ( add( new ClientStringValue( valString ) ) == 1 )
+ {
+ nbAdded++;
+ }
}
}
}
@@ -1321,7 +1340,18 @@
{
for ( Value<?> value:values )
{
- sb.append( " " ).append( upId ).append( ": " ).append( value ).append( '\n' );
+ sb.append( " " ).append( upId ).append( ": " );
+
+ if ( value.isNull() )
+ {
+ sb.append( "''" );
+ }
+ else
+ {
+ sb.append( value );
+ }
+
+ sb.append( '\n' );
}
}
else
Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientEntry.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientEntry.java?rev=643046&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientEntry.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientEntry.java Mon Mar 31 09:19:45 2008
@@ -0,0 +1,1160 @@
+/*
+ * 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.entry.client;
+
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.directory.shared.ldap.entry.AbstractEntry;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.NamingException;
+
+
+/**
+ * A default implementation of a ServerEntry which should suite most
+ * use cases.
+ *
+ * This class is final, it should not be extended.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public final class DefaultClientEntry extends AbstractEntry<String> implements ClientEntry, Externalizable
+{
+ /** Used for serialization */
+ public static final long serialVersionUID = 2L;
+
+ /** The logger for this class */
+ private static final Logger LOG = LoggerFactory.getLogger( DefaultClientEntry.class );
+
+ //-------------------------------------------------------------------------
+ // Constructors
+ //-------------------------------------------------------------------------
+ /**
+ * Creates a new instance of DefaultClientEntry.
+ * <p>
+ * This entry <b>must</b> be initialized before being used !
+ */
+ public DefaultClientEntry()
+ {
+ }
+
+
+ /**
+ * Creates a new instance of DefaultServerEntry, with a
+ * DN.
+ *
+ * @param dn The DN for this serverEntry. Can be null.
+ */
+ public DefaultClientEntry( LdapDN dn )
+ {
+ this.dn = dn;
+ }
+
+
+ /**
+ * Creates a new instance of DefaultServerEntry, with a
+ * DN and a list of IDs.
+ *
+ * @param dn The DN for this serverEntry. Can be null.
+ * @param upIds The list of attributes to create.
+ */
+ public DefaultClientEntry( LdapDN dn, String... upIds )
+ {
+ this.dn = dn;
+
+ for ( String upId:upIds )
+ {
+ // Add a new AttributeType without value
+ set( upId );
+ }
+ }
+
+
+ /**
+ * <p>
+ * Creates a new instance of DefaultClientEntry, with a
+ * DN and a list of EntryAttributes.
+ * </p>
+ *
+ * @param dn The DN for this serverEntry. Can be null
+ * @param attributes The list of attributes to create
+ */
+ public DefaultClientEntry( LdapDN dn, EntryAttribute... attributes )
+ {
+ this.dn = dn;
+
+ for ( EntryAttribute attribute:attributes )
+ {
+ if ( attribute == null )
+ {
+ continue;
+ }
+
+ // Store a new ClientAttribute
+ this.attributes.put( attribute.getId(), attribute );
+ }
+ }
+
+
+ //-------------------------------------------------------------------------
+ // Helper methods
+ //-------------------------------------------------------------------------
+ private String getId( String upId ) throws IllegalArgumentException
+ {
+ String id = StringTools.trim( StringTools.toLowerCase( upId ) );
+
+ // If empty, throw an error
+ if ( ( id == null ) || ( id.length() == 0 ) )
+ {
+ String message = "The attributeType ID should not be null or empty";
+ LOG.error( message );
+ throw new IllegalArgumentException( message );
+ }
+
+ return id;
+ }
+
+
+ //-------------------------------------------------------------------------
+ // Entry methods
+ //-------------------------------------------------------------------------
+ /**
+ * Add some Attributes to the current Entry.
+ *
+ * @param attributes The attributes to add
+ * @throws NamingException If we can't add any of the attributes
+ */
+ public void add( EntryAttribute... attributes ) throws NamingException
+ {
+ // Loop on all the added attributes
+ for ( EntryAttribute attribute:attributes )
+ {
+ // If the attribute already exist, we will add the new values.
+ if ( contains( attribute ) )
+ {
+ EntryAttribute existingAttr = get( attribute.getId() );
+
+ // Loop on all the values, and add them to the existing attribute
+ for ( Value<?> value:attribute )
+ {
+ existingAttr.add( value );
+ }
+ }
+ else
+ {
+ // Stores the attribute into the entry
+ this.attributes.put( attribute.getId(), (ClientAttribute)attribute );
+ }
+ }
+ }
+
+
+ /**
+ * Add an attribute (represented by its ID and binary values) into an entry.
+ *
+ * @param upId The attribute ID
+ * @param values The list of binary values to inject. It can be empty
+ * @throws NamingException If the attribute does not exist
+ */
+ public void add( String upId, byte[]... values ) throws NamingException
+ {
+ // First, transform the upID to a valid ID
+ String id = getId( upId );
+
+ // Now, check to see if we already have such an attribute
+ EntryAttribute attribute = attributes.get( id );
+
+ if ( attribute != null )
+ {
+ // This Attribute already exist, we add the values
+ // into it. (If the values already exists, they will
+ // not be added, but this is done in the add() method)
+ attribute.add( values );
+ attribute.setUpId( upId );
+ }
+ else
+ {
+ // We have to create a new Attribute and set the values
+ // and the upId
+ attributes.put( id, new DefaultClientAttribute( upId, values ) );
+ }
+ }
+
+
+ /**
+ * Add some String values to the current Entry.
+ *
+ * @param upId The user provided ID of the attribute we want to add
+ * some values to
+ * @param values The list of String values to add
+ * @throws NamingException If we can't add any of the values
+ */
+ public void add( String upId, String... values ) throws NamingException
+ {
+ // First, transform the upID to a valid ID
+ String id = getId( upId );
+
+ // Now, check to see if we already have such an attribute
+ EntryAttribute attribute = attributes.get( id );
+
+ if ( attribute != null )
+ {
+ // This Attribute already exist, we add the values
+ // into it. (If the values already exists, they will
+ // not be added, but this is done in the add() method)
+ attribute.add( values );
+ attribute.setUpId( upId );
+ }
+ else
+ {
+ // We have to create a new Attribute and set the values
+ // and the upId
+ attributes.put( id, new DefaultClientAttribute( upId, values ) );
+ }
+ }
+
+
+ /**
+ * Add an attribute (represented by its ID and Value values) into an entry.
+ *
+ * @param upId The attribute ID
+ * @param values The list of Value values to inject. It can be empty
+ * @throws NamingException If the attribute does not exist
+ */
+ public void add( String upId, Value<?>... values ) throws NamingException
+ {
+ // First, transform the upID to a valid ID
+ String id = getId( upId );
+
+ // Now, check to see if we already have such an attribute
+ EntryAttribute attribute = attributes.get( id );
+
+ if ( attribute != null )
+ {
+ // This Attribute already exist, we add the values
+ // into it. (If the values already exists, they will
+ // not be added, but this is done in the add() method)
+ attribute.add( values );
+ attribute.setUpId( upId );
+ }
+ else
+ {
+ // We have to create a new Attribute and set the values
+ // and the upId
+ attributes.put( id, new DefaultClientAttribute( upId, values ) );
+ }
+ }
+
+
+ /**
+ * Clone an entry. All the element are duplicated, so a modification on
+ * the original object won't affect the cloned object, as a modification
+ * on the cloned object has no impact on the original object
+ */
+ public Entry clone()
+ {
+ // First, clone the structure
+ DefaultClientEntry clone = (DefaultClientEntry)super.clone();
+
+ // Just in case ... Should *never* happen
+ if ( clone == null )
+ {
+ return null;
+ }
+
+ // An Entry has a DN and many attributes.
+ // First, clone the DN, if not null.
+ if ( dn != null )
+ {
+ clone.setDn( (LdapDN)dn.clone() );
+ }
+
+ // then clone the ClientAttribute Map.
+ clone.attributes = (Map<String, EntryAttribute>)(((HashMap<String, EntryAttribute>)attributes).clone());
+
+ // now clone all the attributes
+ clone.attributes.clear();
+
+ for ( EntryAttribute attribute:attributes.values() )
+ {
+ clone.attributes.put( attribute.getId(), attribute.clone() );
+ }
+
+ // We are done !
+ return clone;
+ }
+
+
+ /**
+ * <p>
+ * Checks if an entry contains a list of attributes.
+ * </p>
+ * <p>
+ * If the list is null or empty, this method will return <code>true</code>
+ * if the entry has no attribute, <code>false</code> otherwise.
+ * </p>
+ *
+ * @param attributes The Attributes to look for
+ * @return <code>true</code> if all the attributes are found within
+ * the entry, <code>false</code> if at least one of them is not present.
+ * @throws NamingException If the attribute does not exist
+ */
+ public boolean contains( EntryAttribute... attributes ) throws NamingException
+ {
+ for ( EntryAttribute attribute:attributes )
+ {
+ if ( attribute == null )
+ {
+ return this.attributes.size() == 0;
+ }
+
+ if ( !this.attributes.containsKey( attribute.getId() ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Checks if an entry contains a specific attribute
+ *
+ * @param attributes The Attributes to look for
+ * @return <code>true</code> if the attributes are found within the entry
+ * @throws NamingException If the attribute does not exist
+ */
+ public boolean contains( String upId ) throws NamingException
+ {
+ String id = getId( upId );
+
+ return attributes.containsKey( id );
+ }
+
+
+ /**
+ * Checks if an entry contains an attribute with some binary values.
+ *
+ * @param id The Attribute we are looking for.
+ * @param values The searched values.
+ * @return <code>true</code> if all the values are found within the attribute,
+ * false if at least one value is not present or if the ID is not valid.
+ */
+ public boolean contains( String upId, byte[]... values )
+ {
+ String id = getId( upId );
+
+ EntryAttribute attribute = attributes.get( id );
+
+ if ( attribute == null )
+ {
+ return false;
+ }
+
+ return attribute.contains( values );
+ }
+
+
+ /**
+ * Checks if an entry contains an attribute with some String values.
+ *
+ * @param id The Attribute we are looking for.
+ * @param values The searched values.
+ * @return <code>true</code> if all the values are found within the attribute,
+ * false if at least one value is not present or if the ID is not valid.
+ */
+ public boolean contains( String upId, String... values )
+ {
+ String id = getId( upId );
+
+ EntryAttribute attribute = attributes.get( id );
+
+ if ( attribute == null )
+ {
+ return false;
+ }
+
+ return attribute.contains( values );
+ }
+
+
+ /**
+ * Checks if an entry contains an attribute with some values.
+ *
+ * @param id The Attribute we are looking for.
+ * @param values The searched values.
+ * @return <code>true</code> if all the values are found within the attribute,
+ * false if at least one value is not present or if the ID is not valid.
+ */
+ public boolean contains( String upId, Value<?>... values )
+ {
+ String id = getId( upId );
+
+ EntryAttribute attribute = attributes.get( id );
+
+ if ( attribute == null )
+ {
+ return false;
+ }
+
+ return attribute.contains( values );
+ }
+
+
+ /**
+ * Checks if an entry contains some specific attributes.
+ *
+ * @param attributes The Attributes to look for.
+ * @return <code>true</code> if the attributes are all found within the entry.
+ */
+ public boolean containsAttribute( String... attributes )
+ {
+ for ( String attribute:attributes )
+ {
+ String id = getId( attribute );
+
+ if ( !this.attributes.containsKey( id ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ /**
+ * <p>
+ * Returns the attribute with the specified alias. The return value
+ * is <code>null</code> if no match is found.
+ * </p>
+ * <p>An Attribute with an id different from the supplied alias may
+ * be returned: for example a call with 'cn' may in some implementations
+ * return an Attribute whose getId() field returns 'commonName'.
+ * </p>
+ *
+ * @param alias an aliased name of the attribute identifier
+ * @return the attribute associated with the alias
+ */
+ public EntryAttribute get( String alias )
+ {
+ try
+ {
+ String id = getId( alias );
+
+ return attributes.get( id );
+ }
+ catch( IllegalArgumentException iea )
+ {
+ LOG.error( "An exception has been raised while looking for attribute id {}''", alias );
+ return null;
+ }
+ }
+
+
+ /**
+ * <p>
+ * Put an attribute (represented by its ID and some binary values) into an entry.
+ * </p>
+ * <p>
+ * If the attribute already exists, the previous attribute will be
+ * replaced and returned.
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param values The list of binary values to put. It can be empty.
+ * @return The replaced attribute
+ */
+ public EntryAttribute put( String upId, byte[]... values )
+ {
+ // Get the normalized form of the ID
+ String id = getId( upId );
+
+ // Create a new attribute
+ ClientAttribute clientAttribute = new DefaultClientAttribute( upId, values );
+
+ // Replace the previous one, and return it back
+ return attributes.put( id, clientAttribute );
+ }
+
+
+ /**
+ * <p>
+ * Put an attribute (represented by its ID and some String values) into an entry.
+ * </p>
+ * <p>
+ * If the attribute already exists, the previous attribute will be
+ * replaced and returned.
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param values The list of String values to put. It can be empty.
+ * @return The replaced attribute
+ */
+ public EntryAttribute put( String upId, String... values )
+ {
+ // Get the normalized form of the ID
+ String id = getId( upId );
+
+ // Create a new attribute
+ ClientAttribute clientAttribute = new DefaultClientAttribute( upId, values );
+
+ // Replace the previous one, and return it back
+ return attributes.put( id, clientAttribute );
+ }
+
+
+ /**
+ * <p>
+ * Put an attribute (represented by its ID and some values) into an entry.
+ * </p>
+ * <p>
+ * If the attribute already exists, the previous attribute will be
+ * replaced and returned.
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param values The list of values to put. It can be empty.
+ * @return The replaced attribute
+ */
+ public EntryAttribute put( String upId, Value<?>... values )
+ {
+ // Get the normalized form of the ID
+ String id = getId( upId );
+
+ // Create a new attribute
+ ClientAttribute clientAttribute = new DefaultClientAttribute( upId, values );
+
+ // Replace the previous one, and return it back
+ return attributes.put( id, clientAttribute );
+ }
+
+
+ /**
+ * <p>
+ * Put some new ClientAttribute using the User Provided ID.
+ * No value is inserted.
+ * </p>
+ * <p>
+ * If an existing Attribute is found, it will be replaced by an
+ * empty attribute, and returned to the caller.
+ * </p>
+ *
+ * @param upIds The user provided IDs of the AttributeTypes to add.
+ * @return A list of replaced Attributes.
+ */
+ public List<EntryAttribute> set( String... upIds )
+ {
+ if ( upIds == null )
+ {
+ String message = "The AttributeType list should not be null";
+ LOG.error( message );
+ throw new IllegalArgumentException( message );
+ }
+
+ List<EntryAttribute> returnedClientAttributes = new ArrayList<EntryAttribute>();
+
+ // Now, loop on all the attributeType to add
+ for ( String upId:upIds )
+ {
+ String id = StringTools.trim( StringTools.toLowerCase( upId ) );
+
+ if ( id == null )
+ {
+ String message = "The AttributeType list should not contain null values";
+ LOG.error( message );
+ throw new IllegalArgumentException( message );
+ }
+
+ if ( attributes.containsKey( id ) )
+ {
+ // Add the removed serverAttribute to the list
+ returnedClientAttributes.add( attributes.remove( id ) );
+ }
+
+ ClientAttribute newAttribute = new DefaultClientAttribute( upId );
+ attributes.put( id, newAttribute );
+ }
+
+ return returnedClientAttributes;
+ }
+
+
+ /**
+ * <p>
+ * Places attributes in the attribute collection.
+ * </p>
+ * <p>If there is already an attribute with the same ID as any of the
+ * new attributes, the old ones are removed from the collection and
+ * are returned by this method. If there was no attribute with the
+ * same ID the return value is <code>null</code>.
+ *</p>
+ *
+ * @param attributes the attributes to be put
+ * @return the old attributes with the same OID, if exist; otherwise
+ * <code>null</code>
+ * @exception NamingException if the operation fails
+ */
+ public List<EntryAttribute> put( EntryAttribute... attributes ) throws NamingException
+ {
+ // First, get the existing attributes
+ List<EntryAttribute> previous = new ArrayList<EntryAttribute>();
+
+ for ( EntryAttribute attribute:attributes )
+ {
+ String id = attribute.getId();
+
+ if ( contains( id ) )
+ {
+ // Store the attribute and remove it from the list
+ previous.add( get( id ) );
+ this.attributes.remove( id );
+ }
+
+ // add the new one
+ this.attributes.put( id, (ClientAttribute)attribute );
+ }
+
+ // return the previous attributes
+ return previous;
+ }
+
+
+ public List<EntryAttribute> remove( EntryAttribute... attributes ) throws NamingException
+ {
+ List<EntryAttribute> removedAttributes = new ArrayList<EntryAttribute>();
+
+ for ( EntryAttribute attribute:attributes )
+ {
+ if ( contains( attribute.getId() ) )
+ {
+ this.attributes.remove( attribute.getId() );
+ removedAttributes.add( attribute );
+ }
+ }
+
+ return removedAttributes;
+ }
+
+
+ /**
+ * <p>
+ * Removes the attribute with the specified alias.
+ * </p>
+ * <p>
+ * The removed attribute are returned by this method.
+ * </p>
+ * <p>
+ * If there is no attribute with the specified alias,
+ * the return value is <code>null</code>.
+ * </p>
+ *
+ * @param attributes an aliased name of the attribute to be removed
+ * @return the removed attributes, if any, as a list; otherwise <code>null</code>
+ */
+ public List<EntryAttribute> removeAttributes( String... attributes )
+ {
+ if ( attributes.length == 0 )
+ {
+ return null;
+ }
+
+ List<EntryAttribute> removed = new ArrayList<EntryAttribute>( attributes.length );
+
+ for ( String attribute:attributes )
+ {
+ EntryAttribute attr = get( attribute );
+
+ if ( attr != null )
+ {
+ removed.add( this.attributes.remove( attr.getId() ) );
+ }
+ else
+ {
+ String message = "The attribute '" + attribute + "' does not exist in the entry";
+ LOG.warn( message );
+ continue;
+ }
+ }
+
+ if ( removed.size() == 0 )
+ {
+ return null;
+ }
+ else
+ {
+ return removed;
+ }
+ }
+
+
+ /**
+ * <p>
+ * Removes the specified binary values from an attribute.
+ * </p>
+ * <p>
+ * If at least one value is removed, this method returns <code>true</code>.
+ * </p>
+ * <p>
+ * If there is no more value after having removed the values, the attribute
+ * will be removed too.
+ * </p>
+ * <p>
+ * If the attribute does not exist, nothing is done and the method returns
+ * <code>false</code>
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param values the values to be removed
+ * @return <code>true</code> if at least a value is removed, <code>false</code>
+ * if not all the values have been removed or if the attribute does not exist.
+ */
+ public boolean remove( String upId, byte[]... values ) throws NamingException
+ {
+ try
+ {
+ String id = getId( upId );
+
+ EntryAttribute attribute = get( id );
+
+ if ( attribute == null )
+ {
+ // Can't remove values from a not existing attribute !
+ return false;
+ }
+
+ int nbOldValues = attribute.size();
+
+ // Remove the values
+ attribute.remove( values );
+
+ if ( attribute.size() == 0 )
+ {
+ // No mare values, remove the attribute
+ attributes.remove( id );
+
+ return true;
+ }
+
+ if ( nbOldValues != attribute.size() )
+ {
+ // At least one value have been removed, return true.
+ return true;
+ }
+ else
+ {
+ // No values have been removed, return false.
+ return false;
+ }
+ }
+ catch ( IllegalArgumentException iae )
+ {
+ LOG.error( "The removal of values for the missing '{}' attribute is not possible", upId );
+ return false;
+ }
+ }
+
+
+ /**
+ * <p>
+ * Removes the specified String values from an attribute.
+ * </p>
+ * <p>
+ * If at least one value is removed, this method returns <code>true</code>.
+ * </p>
+ * <p>
+ * If there is no more value after having removed the values, the attribute
+ * will be removed too.
+ * </p>
+ * <p>
+ * If the attribute does not exist, nothing is done and the method returns
+ * <code>false</code>
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param attributes the attributes to be removed
+ * @return <code>true</code> if at least a value is removed, <code>false</code>
+ * if not all the values have been removed or if the attribute does not exist.
+ */
+ public boolean remove( String upId, String... values ) throws NamingException
+ {
+ try
+ {
+ String id = getId( upId );
+
+ EntryAttribute attribute = get( id );
+
+ if ( attribute == null )
+ {
+ // Can't remove values from a not existing attribute !
+ return false;
+ }
+
+ int nbOldValues = attribute.size();
+
+ // Remove the values
+ attribute.remove( values );
+
+ if ( attribute.size() == 0 )
+ {
+ // No mare values, remove the attribute
+ attributes.remove( id );
+
+ return true;
+ }
+
+ if ( nbOldValues != attribute.size() )
+ {
+ // At least one value have been removed, return true.
+ return true;
+ }
+ else
+ {
+ // No values have been removed, return false.
+ return false;
+ }
+ }
+ catch ( IllegalArgumentException iae )
+ {
+ LOG.error( "The removal of values for the missing '{}' attribute is not possible", upId );
+ return false;
+ }
+ }
+
+
+ /**
+ * <p>
+ * Removes the specified values from an attribute.
+ * </p>
+ * <p>
+ * If at least one value is removed, this method returns <code>true</code>.
+ * </p>
+ * <p>
+ * If there is no more value after having removed the values, the attribute
+ * will be removed too.
+ * </p>
+ * <p>
+ * If the attribute does not exist, nothing is done and the method returns
+ * <code>false</code>
+ * </p>
+ *
+ * @param upId The attribute ID
+ * @param attributes the attributes to be removed
+ * @return <code>true</code> if at least a value is removed, <code>false</code>
+ * if not all the values have been removed or if the attribute does not exist.
+ */
+ public boolean remove( String upId, Value<?>... values ) throws NamingException
+ {
+ try
+ {
+ String id = getId( upId );
+
+ EntryAttribute attribute = get( id );
+
+ if ( attribute == null )
+ {
+ // Can't remove values from a not existing attribute !
+ return false;
+ }
+
+ int nbOldValues = attribute.size();
+
+ // Remove the values
+ attribute.remove( values );
+
+ if ( attribute.size() == 0 )
+ {
+ // No mare values, remove the attribute
+ attributes.remove( id );
+
+ return true;
+ }
+
+ if ( nbOldValues != attribute.size() )
+ {
+ // At least one value have been removed, return true.
+ return true;
+ }
+ else
+ {
+ // No values have been removed, return false.
+ return false;
+ }
+ }
+ catch ( IllegalArgumentException iae )
+ {
+ LOG.error( "The removal of values for the missing '{}' attribute is not possible", upId );
+ return false;
+ }
+ }
+
+
+ public Iterator<EntryAttribute> iterator()
+ {
+ return Collections.unmodifiableMap( attributes ).values().iterator();
+ }
+
+
+ /**
+ * @see Externalizable#writeExternal(ObjectOutput)<p>
+ *
+ * This is the place where we serialize entries, and all theirs
+ * elements. the reason why we don't call the underlying methods
+ * (<code>ClientAttribute.write(), Value.write()</code>) is that we need
+ * access to the registries to read back the values.
+ * <p>
+ * The structure used to store the entry is the following :
+ * <li><b>[DN length]</b> : can be -1 if we don't have a DN, 0 if the
+ * DN is empty, otherwise contains the DN's length.<p>
+ * <b>NOTE :</b>This should be unnecessary, as the DN should always exists
+ * <p>
+ * </li>
+ * <li>
+ * <b>DN</b> : The entry's DN. Can be empty (rootDSE=<p>
+ * </li>
+ * We have to store the UPid, and all the values, if any.
+ */
+ public void writeExternal( ObjectOutput out ) throws IOException
+ {
+ // First, the DN
+ if ( dn == null )
+ {
+ // Write an empty DN
+ LdapDN.EMPTY_LDAPDN.writeExternal( out );
+ }
+ else
+ {
+ // Write the DN
+ out.writeObject( dn );
+ }
+
+ // Then the attributes.
+ if ( attributes == null )
+ {
+ // A negative number denotes no attributes
+ out.writeInt( -1 );
+ }
+ else
+ {
+ // Store the attributes' nulber first
+ out.writeInt( attributes.size() );
+
+ // Iterate through the keys. We store the Attribute
+ // here, to be able to restore it in the readExternal :
+ // we need access to the registries, which are not available
+ // in the ClientAttribute class.
+ for ( EntryAttribute attribute:attributes.values() )
+ {
+ // Store the UP id
+ out.writeUTF( attribute.getUpId() );
+
+ // The number of values
+ int nbValues = attribute.size();
+
+ if ( nbValues == 0 )
+ {
+ out.writeInt( 0 );
+ }
+ else
+ {
+ out.writeInt( nbValues );
+
+ for ( Value<?> value:attribute )
+ {
+ out.writeObject( value );
+ }
+ }
+ }
+ }
+
+ out.flush();
+ }
+
+
+ /**
+ * @see Externalizable#readExternal(ObjectInput)
+ */
+ public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
+ {
+ // Read the DN
+ LdapDN dn = (LdapDN)in.readObject();
+
+ // Read the number of attributes
+ int nbAttributes = in.readInt();
+
+ attributes = new HashMap<String, EntryAttribute>();
+
+ // Read the attributes
+ for ( int i = 0; i < nbAttributes; i++ )
+ {
+ String upId = in.readUTF();
+
+ EntryAttribute attribute = new DefaultClientAttribute( upId );
+
+ // Read the number of values
+ int nbValues = in.readInt();
+
+ for ( int j = 0; j < nbValues; j++ )
+ {
+ Value<?> value = (Value<?>)in.readObject();
+ attribute.add( value );
+ }
+
+ attributes.put( attribute.getId(), attribute );
+ }
+ }
+
+
+ /**
+ * Get the hashcode of this ClientEntry.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode()
+ {
+ int result = 37;
+
+ result = result*17 + dn.hashCode();
+
+ for ( EntryAttribute attribute:attributes.values() )
+ {
+ result = result*17 + attribute.hashCode();
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Tells if an entry has a specific ObjectClass value
+ *
+ * @param objectClass The ObjectClass we want to check
+ * @return <code>true</code> if the ObjectClass value is present
+ * in the ObjectClass attribute
+ */
+ public boolean hasObjectClass( String objectClass )
+ {
+ return contains( "objectclass", objectClass );
+ }
+
+
+ /**
+ * @see Object#equals(Object)
+ */
+ public boolean equals( Object o )
+ {
+ // Short circuit
+
+ if ( this == o )
+ {
+ return true;
+ }
+
+ if ( ! ( o instanceof DefaultClientEntry ) )
+ {
+ return false;
+ }
+
+ DefaultClientEntry other = (DefaultClientEntry)o;
+
+ // Both DN must be equal
+ if ( dn == null )
+ {
+ if ( other.getDn() != null )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if ( !dn.equals( other.getDn() ) )
+ {
+ return false;
+ }
+ }
+
+ // They must have the same number of attributes
+ if ( size() != other.size() )
+ {
+ return false;
+ }
+
+ // Each attribute must be equal
+ for ( EntryAttribute attribute:other )
+ {
+ if ( !attribute.equals( this.get( attribute.getId() ) ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "ClientEntry\n" );
+ sb.append( " dn: " ).append( dn ).append( '\n' );
+
+ // First dump the ObjectClass attribute
+ if ( containsAttribute( "objectClass" ) )
+ {
+ EntryAttribute objectClass = get( "objectclass" );
+
+ sb.append( objectClass );
+ }
+
+ if ( attributes.size() != 0 )
+ {
+ for ( EntryAttribute attribute:attributes.values() )
+ {
+ if ( !attribute.getId().equals( "objectclass" ) )
+ {
+ sb.append( attribute );
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+}
Modified: directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttributeTest.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttributeTest.java?rev=643046&r1=643045&r2=643046&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttributeTest.java (original)
+++ directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttributeTest.java Mon Mar 31 09:19:45 2008
@@ -537,6 +537,15 @@
assertFalse( attr6.isHR() );
assertTrue( attr6.contains( new byte[]{'a'} ) );
assertTrue( attr6.contains( (byte[])null ) );
+
+ EntryAttribute attr7 = new DefaultClientAttribute( "test" );
+
+ attr7.add( "a", "b" );
+ assertEquals( 2, attr7.size() );
+
+ assertEquals( 1, attr7.add( "b", "c" ) );
+ assertEquals( 3, attr7.size() );
+ assertTrue( attr7.contains( "a", "b", "c" ) );
}