You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2008/03/18 06:07:29 UTC
svn commit: r638218 [2/4] - in /directory/sandbox/akarasulu/bigbang/shared:
./ asn1-codec/ asn1-codec/src/main/resources/META-INF/ asn1-codec/src/site/
asn1/ asn1/src/main/resources/META-INF/ asn1/src/site/ convert/
convert/src/main/java/org/apache/dir...
Modified: directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java?rev=638218&r1=638217&r2=638218&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java (original)
+++ directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java Mon Mar 17 22:07:20 2008
@@ -20,7 +20,9 @@
import org.apache.directory.shared.ldap.NotImplementedException;
-import org.apache.directory.shared.ldap.entry.AbstractStringValue;
+import org.apache.directory.shared.ldap.entry.AbstractValue;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.schema.Normalizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,26 +38,26 @@
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
-public class ClientStringValue extends AbstractStringValue implements ClientValue<String>
+public class ClientStringValue extends AbstractValue<String>
{
/** Used for serialization */
public static final long serialVersionUID = 2L;
+
/** logger for reporting errors that might not be handled properly upstream */
private static final Logger LOG = LoggerFactory.getLogger( ClientStringValue.class );
- /** the canonical representation of the wrapped String value */
- private transient String normalizedValue;
-
- /** cached results of the isValid() method call */
- private transient Boolean valid;
-
-
+
+ // -----------------------------------------------------------------------
+ // Constructors
+ // -----------------------------------------------------------------------
/**
* Creates a ServerStringValue without an initial wrapped value.
*/
public ClientStringValue()
{
+ normalized = false;
+ valid = null;
}
@@ -66,16 +68,40 @@
*/
public ClientStringValue( String wrapped )
{
- super.set( wrapped );
+ this.wrapped = wrapped;
+ normalized = false;
+ valid = null;
}
// -----------------------------------------------------------------------
// Value<String> Methods
// -----------------------------------------------------------------------
+ /**
+ * Get the stored value.
+ *
+ * @return The stored value
+ */
+ public String get()
+ {
+ return wrapped;
+ }
/**
+ * Get a copy of the stored value.
+ *
+ * @return A copy of the stored value.
+ */
+ public String getCopy()
+ {
+ // The String is immutable, we can safely return the internal
+ // object without copying it.
+ return wrapped;
+ }
+
+
+ /**
* Sets the wrapped String value. Has the side effect of setting the
* normalizedValue and the valid flags to null if the wrapped value is
* different than what is already set. These cached values must be
@@ -87,34 +113,29 @@
{
// Why should we invalidate the normalized value if it's we're setting the
// wrapper to it's current value?
- if ( wrapped.equals( get() ) )
+ if ( ( wrapped != null ) && wrapped.equals( get() ) )
{
return;
}
normalizedValue = null;
+ normalized = false;
valid = null;
- super.set( wrapped );
+ this.wrapped = wrapped;
}
- // -----------------------------------------------------------------------
- // ServerValue<String> Methods
- // -----------------------------------------------------------------------
-
-
/**
- * Gets the normalized (cannonical) representation for the wrapped string.
+ * Gets the normalized (canonical) representation for the wrapped string.
* If the wrapped String is null, null is returned, otherwise the normalized
- * form is returned. If no the normalizedValue is null, then this method
+ * form is returned. If the normalizedValue is null, then this method
* will attempt to generate it from the wrapped value: repeated calls to
* this method do not unnecessarily normalize the wrapped value. Only changes
* to the wrapped value result in attempts to normalize the wrapped value.
*
* @return gets the normalized value
- * @throws NamingException if the value cannot be properly normalized
*/
- public String getNormalized() throws NamingException
+ public String getNormalizedValue()
{
if ( isNull() )
{
@@ -123,6 +144,7 @@
if ( normalizedValue == null )
{
+ return wrapped;
}
return normalizedValue;
@@ -130,31 +152,45 @@
/**
- * Uses the syntaxChecker associated with the attributeType to check if the
- * value is valid. Repeated calls to this method do not attempt to re-check
- * the syntax of the wrapped value every time if the wrapped value does not
- * change. Syntax checks only result on the first check, and when the wrapped
- * value changes.
+ * Gets a copy of the the normalized (canonical) representation
+ * for the wrapped value.
*
- * @see ServerValue#isValid()
+ * @return gets a copy of the normalized value
+ */
+ public String getNormalizedValueCopy()
+ {
+ return getNormalizedValue();
+ }
+
+
+ /**
+ * Normalize the value. For a client String value, applies the given normalizer.
+ *
+ * It supposes that the client has access to the schema in order to select the
+ * appropriate normalizer.
+ *
+ * @param Normalizer The normalizer to apply to the value
+ * @exception NamingException If the value cannot be normalized
*/
- public final boolean isValid() throws NamingException
+ public final void normalize( Normalizer normalizer ) throws NamingException
{
- if ( valid != null )
+ if ( normalizer != null )
{
- return valid;
+ normalizedValue = (String)normalizer.normalize( wrapped );
+ normalized = true;
}
-
- return valid;
}
-
+
+ // -----------------------------------------------------------------------
+ // Comparable<String> Methods
+ // -----------------------------------------------------------------------
/**
* @see ServerValue#compareTo(ServerValue)
* @throws IllegalStateException on failures to extract the comparator, or the
* normalizers needed to perform the required comparisons based on the schema
*/
- public int compareTo( ClientValue<String> value )
+ public int compareTo( Value<String> value )
{
if ( isNull() )
{
@@ -175,17 +211,35 @@
if ( value instanceof ClientStringValue )
{
ClientStringValue stringValue = ( ClientStringValue ) value;
+
+ return getNormalizedValue().compareTo( stringValue.getNormalizedValue() );
+ }
+ else
+ {
+ String message = "Cannot compare " + toString() + " with the unknown value " + value.getClass();
+ LOG.error( message );
+ throw new NotImplementedException( message );
}
-
- throw new NotImplementedException( "I don't know what to do if value is not a ServerStringValue" );
}
// -----------------------------------------------------------------------
- // Object Methods
+ // Cloneable methods
// -----------------------------------------------------------------------
+ /**
+ * Get a clone of the Client Value
+ *
+ * @return a copy of the current value
+ */
+ public ClientStringValue clone()
+ {
+ return (ClientStringValue)super.clone();
+ }
+ // -----------------------------------------------------------------------
+ // Object Methods
+ // -----------------------------------------------------------------------
/**
* @see Object#hashCode()
* @throws IllegalStateException on failures to extract the comparator, or the
@@ -200,26 +254,16 @@
return 0;
}
- try
- {
- return getNormalized().hashCode();
- }
- catch ( NamingException e )
- {
- String msg = "Failed to normalize \"" + get() + "\" while trying to get hashCode()";
- LOG.error( msg, e );
- throw new IllegalStateException( msg, e );
- }
+ // If the normalized value is null, will default to wrapped
+ // which cannot be null at this point.
+ return getNormalizedValue().hashCode();
}
/**
- * Checks to see if this ServerStringValue equals the supplied object.
- *
- * This equals implementation overrides the StringValue implementation which
- * is not schema aware.
- * @throws IllegalStateException on failures to extract the comparator, or the
- * normalizers needed to perform the required comparisons based on the schema
+ * @see Object#equals(Object)
+ *
+ * Two ClientStringValue are equals if their normalized values are equal
*/
public boolean equals( Object obj )
{
@@ -235,46 +279,21 @@
ClientStringValue other = ( ClientStringValue ) obj;
- if ( isNull() && other.isNull() )
- {
- return true;
- }
-
- if ( isNull() != other.isNull() )
+ if ( this.isNull() )
{
- return false;
- }
-
- // now unlike regular values we have to compare the normalized values
- try
- {
- return getNormalized().equals( other.getNormalized() );
- }
- catch ( NamingException e )
- {
- String msg = "Failed to normalize while testing for equality on String values: \"";
- msg += get() + "\"" + " and \"" + other.get() + "\"" ;
- LOG.error( msg, e );
- throw new IllegalStateException( msg, e );
+ return other.isNull();
}
+
+ // Test the normalized values
+ return this.getNormalizedValue().equals( other.getNormalizedValue() );
}
-
-
- // -----------------------------------------------------------------------
- // Private Helper Methods (might be put into abstract base class)
- // -----------------------------------------------------------------------
+
+
/**
- * @return a copy of the current value
+ * @see Object#toString()
*/
- public ClientStringValue clone()
+ public String toString()
{
- try
- {
- return (ClientStringValue)super.clone();
- }
- catch ( CloneNotSupportedException cnse )
- {
- return null;
- }
+ return "'" + wrapped + "'";
}
}
Modified: directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java?rev=638218&r1=638217&r2=638218&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java (original)
+++ directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java Mon Mar 17 22:07:20 2008
@@ -20,6 +20,9 @@
import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.schema.syntax.SyntaxChecker;
+import org.apache.directory.shared.ldap.util.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -27,15 +30,21 @@
import javax.naming.directory.InvalidAttributeValueException;
import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
/**
- * A server side entry attribute aware of schema.
+ * A client side entry attribute. The client is not aware of the schema,
+ * so we can't tell if the stored value will be String or Binary. We will
+ * default to Binary.<p>
+ * To define the kind of data stored, the client must set the isHR flag.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
-public final class DefaultClientAttribute extends AbstractClientAttribute
+public class DefaultClientAttribute implements ClientAttribute
{
/** Used for serialization */
public static final long serialVersionUID = 2L;
@@ -44,6 +53,20 @@
private static final Logger LOG = LoggerFactory.getLogger( DefaultClientAttribute.class );
+ /** The set of contained values */
+ protected Set<Value<?>> values = new LinkedHashSet<Value<?>>();
+
+ /** The User provided ID */
+ protected String upId;
+
+ /** The normalized ID */
+ protected String id;
+
+ /** Tells if the attribute is Human Readable or not. When not set,
+ * this flag is null. */
+ protected Boolean isHR;
+
+
// maybe have some additional convenience constructors which take
// an initial value as a string or a byte[]
/**
@@ -64,24 +87,6 @@
/**
- * Doc me more!
- *
- * If the value does not correspond to the same attributeType, then it's
- * wrapped value is copied into a new ClientValue which uses the specified
- * attributeType.
- *
- * @param vals an initial set of values for this attribute
- * @throws NamingException if there are problems creating the new attribute
- */
- public DefaultClientAttribute( ClientValue<?>... vals ) throws NamingException
- {
- this( null, vals );
- }
-
-
- /**
- * Doc me more!
- *
* If the value does not correspond to the same attributeType, then it's
* wrapped value is copied into a new ClientValue which uses the specified
* attributeType.
@@ -91,9 +96,8 @@
* @param upId
* @param attributeType the attribute type according to the schema
* @param vals an initial set of values for this attribute
- * @throws NamingException if there are problems creating the new attribute
*/
- public DefaultClientAttribute( String upId, ClientValue<?>... vals ) throws NamingException
+ public DefaultClientAttribute( String upId, Value<?>... vals )
{
// The value can be null, this is a valid value.
if ( vals[0] == null )
@@ -102,7 +106,7 @@
}
else
{
- for ( ClientValue<?> val:vals )
+ for ( Value<?> val:vals )
{
if ( val instanceof ClientStringValue )
{
@@ -128,18 +132,19 @@
/**
- * Create a new instance of a EntryAttribute, without ID but with some values.
+ * Create a new instance of a EntryAttribute.
*/
- public DefaultClientAttribute( String... vals ) throws NamingException
+ public DefaultClientAttribute( String upId, String... vals )
{
- this( null, vals );
+ add( vals );
+ setUpId( upId );
}
/**
- * Create a new instance of a EntryAttribute.
+ * Create a new instance of a EntryAttribute, with some byte[] values.
*/
- public DefaultClientAttribute( String upId, String... vals ) throws NamingException
+ public DefaultClientAttribute( String upId, byte[]... vals )
{
add( vals );
setUpId( upId );
@@ -147,25 +152,111 @@
/**
- * Create a new instance of a EntryAttribute, with some byte[] values.
+ * <p>
+ * Get the byte[] value, if and only if the value is known to be Binary,
+ * otherwise a InvalidAttributeValueException will be thrown
+ * </p>
+ * <p>
+ * Note that this method returns the first value only.
+ * </p>
+ *
+ * @return The value as a byte[]
+ * @throws InvalidAttributeValueException If the value is a String
+ */
+ public byte[] getBytes() throws InvalidAttributeValueException
+ {
+ Value<?> value = get();
+
+ if ( value instanceof ClientBinaryValue )
+ {
+ return (byte[])value.get();
+ }
+ else
+ {
+ String message = "The value is expected to be a byte[]";
+ LOG.error( message );
+ throw new InvalidAttributeValueException( message );
+ }
+ }
+
+
+ /**
+ * <p>
+ * Get the String value, if and only if the value is known to be a String,
+ * otherwise a InvalidAttributeValueException will be thrown
+ * </p>
+ * <p>
+ * Note that this method returns the first value only.
+ * </p>
+ *
+ * @return The value as a String
+ * @throws InvalidAttributeValueException If the value is a byte[]
*/
- public DefaultClientAttribute( byte[]... vals ) throws NamingException
+ public String getString() throws InvalidAttributeValueException
{
- this( null, vals );
+ Value<?> value = get();
+
+ if ( value instanceof ClientStringValue )
+ {
+ return (String)value.get();
+ }
+ else
+ {
+ String message = "The value is expected to be a String";
+ LOG.error( message );
+ throw new InvalidAttributeValueException( message );
+ }
}
/**
- * Create a new instance of a EntryAttribute, with some byte[] values.
+ * Get's the attribute identifier. Its value is the same than the
+ * user provided ID.
+ *
+ * @return the attribute's identifier
*/
- public DefaultClientAttribute( String upId, byte[]... vals ) throws NamingException
+ public String getId()
{
- add( vals );
- setUpId( upId );
+ return id;
}
/**
+ * <p>
+ * Set the attribute to Human Readable or to Binary.
+ * </p>
+ * @param isHR <code>true</code> for a Human Readable attribute,
+ * <code>false</code> for a Binary attribute.
+ */
+ public void setHR( boolean isHR )
+ {
+ this.isHR = isHR;
+ //TODO : deal with the values, we may have to convert them.
+ }
+
+
+ /**
+ * Set the normalized ID. The ID will be lowercased, and spaces
+ * will be trimmed.
+ *
+ * @param id The attribute ID
+ * @throws IllegalArgumentException If the ID is empty or null or
+ * resolve to an empty value after being trimmed
+ */
+ public void setId( String id )
+ {
+ this.id = StringTools.trim( StringTools.lowerCaseAscii( id ) );
+
+ if ( this.id.length() == 0 )
+ {
+ this.id = null;
+ throw new IllegalArgumentException( "An ID cannnot be null, empty, or resolved to an emtpy" +
+ " value when trimmed" );
+ }
+ }
+
+
+ /**
* Get's the user provided identifier for this entry. This is the value
* that will be used as the identifier for the attribute within the
* entry. If this is a commonName attribute for example and the user
@@ -183,6 +274,44 @@
/**
+ * Set the user provided ID. It will also set the ID, normalizing
+ * the upId (removing spaces before and after, and lowercasing it)
+ *
+ * @param upId The attribute ID
+ * @throws IllegalArgumentException If the ID is empty or null or
+ * resolve to an empty value after being trimmed
+ */
+ public void setUpId( String upId )
+ {
+ this.upId = StringTools.trim( upId );
+
+ if ( this.upId.length() == 0 )
+ {
+ this.upId = null;
+ throw new IllegalArgumentException( "An ID cannnot be null, empty, or resolved to an emtpy" +
+ " value when trimmed" );
+ }
+
+ this.id = StringTools.lowerCaseAscii( this.upId );
+ }
+
+
+ /**
+ * <p>
+ * Tells if the attribute is Human Readable.
+ * </p>
+ * <p>This flag is set by the caller, or implicitly when adding String
+ * values into an attribute which is not yet declared as Binary.
+ * </p>
+ * @return
+ */
+ public boolean isHR()
+ {
+ return isHR != null ? isHR : false;
+ }
+
+
+ /**
* Checks to see if this attribute is valid along with the values it contains.
*
* @return true if the attribute and it's values are valid, false otherwise
@@ -190,9 +319,9 @@
*/
public boolean isValid() throws NamingException
{
- for ( ClientValue<?> value : values )
+ for ( Value<?> value:values )
{
- if ( ! value.isValid() )
+ if ( !value.isValid() )
{
return false;
}
@@ -203,74 +332,233 @@
/**
- * @see EntryAttribute#add(org.apache.directory.shared.ldap.entry.Value)
+ * Checks to see if this attribute is valid along with the values it contains.
+ *
+ * @return true if the attribute and it's values are valid, false otherwise
+ * @throws NamingException if there is a failure to check syntaxes of values
*/
- public boolean add( ClientValue<?> val ) throws InvalidAttributeValueException, NamingException
+ public boolean isValid( SyntaxChecker checker ) throws NamingException
{
- if ( val == null )
+ for ( Value<?> value : values )
{
- ClientValue<String> nullSV = new ClientStringValue( (String)null );
-
- if ( values.contains( nullSV ) )
+ if ( !value.isValid( checker ) )
{
return false;
}
- else
- {
- values.add( nullSV );
- return true;
- }
}
- if ( values.contains( val ) )
- {
- return false;
- }
-
- return values.add( val );
+ return true;
}
/**
- * @see EntryAttribute#add(org.apache.directory.shared.ldap.entry.Value...)
+ * Adds some values to this attribute. If the new values are already present in
+ * the attribute values, the method has no effect.
+ * <p>
+ * The new values are added at the end of list of values.
+ * </p>
+ * <p>
+ * This method returns the number of values that were added.
+ * </p>
+ * <p>
+ * If the value's type is different from the attribute's type,
+ * a conversion is done. For instance, if we try to set some
+ * StringValue into a Binary attribute, we just store the UTF-8
+ * byte array encoding for this StringValue.
+ * </p>
+ * <p>
+ * If we try to store some BinaryValue in a HR attribute, we try to
+ * convert those BinaryValue assuming they represent an UTF-8 encoded
+ * String. Of course, if it's not the case, the stored value will
+ * be incorrect.
+ * </p>
+ * <p>
+ * It's the responsibility of the caller to check if the stored
+ * values are consistent with the attribute's type.
+ * </p>
+ * <p>
+ * The caller can set the HR flag in order to enforce a type for
+ * the current attribute, otherwise this type will be set while
+ * adding the first value, using the value's type to set the flag.
+ * </p>
+ * <p>
+ * <b>Note : </b>If the entry contains no value, and the unique added value
+ * is a null length value, then this value will be considered as
+ * a binary value.
+ * </p>
+ * @param val some new values to be added which may be null
+ * @return the number of added values, or 0 if none has been added
*/
- public int add( ClientValue<?>... vals ) throws InvalidAttributeValueException, NamingException
+ public int add( Value<?>... vals )
{
int nbAdded = 0;
+ ClientBinaryValue nullBinaryValue = null;
+ ClientStringValue nullStringValue = null;
+ boolean nullValueAdded = false;
- for ( ClientValue<?> val:vals )
+ for ( Value<?> val:vals )
{
- if ( add( val ) )
+ if ( val == null )
{
- nbAdded ++;
+ // We have a null value. If the HR flag is not set, we will consider
+ // that the attribute is not HR. We may change this later
+ if ( isHR == null )
+ {
+ // This is the first value. Add both types, as we
+ // don't know yet the attribute type's, but we may
+ // know later if we add some new value.
+ // We have to do that because we are using a Set,
+ // and we can't remove the first element of the Set.
+ nullBinaryValue = new ClientBinaryValue( null );
+ nullStringValue = new ClientStringValue( null );
+
+ values.add( nullBinaryValue );
+ values.add( nullStringValue );
+ nullValueAdded = true;
+ }
+ else if ( !isHR )
+ {
+ // The attribute type is binary.
+ nullBinaryValue = new ClientBinaryValue( null );
+
+ // Don't add a value if it already exists.
+ if ( !values.contains( nullBinaryValue ) )
+ {
+ values.add( nullBinaryValue );
+ }
+
+ }
+ else
+ {
+ // The attribute is HR
+ nullStringValue = new ClientStringValue( null );
+
+ // Don't add a value if it already exists.
+ if ( !values.contains( nullStringValue ) )
+ {
+ values.add( nullStringValue );
+ }
+ }
}
+ else
+ {
+ // Let's check the value type.
+ if ( val instanceof ClientStringValue )
+ {
+ // We have a String value
+ if ( isHR == null )
+ {
+ // The attribute type will be set to HR
+ isHR = true;
+ values.add( val );
+ }
+ else if ( !isHR )
+ {
+ // The attributeType is binary, convert the
+ // value to a BinaryValue
+ ClientBinaryValue cbv = new ClientBinaryValue();
+ cbv.set( StringTools.getBytesUtf8( (String)val.get() ) );
+
+ values.add( cbv );
+ }
+ else
+ {
+ // The attributeType is HR, simply add the value
+ values.add( val );
+ }
+ }
+ else
+ {
+ // We have a Binary value
+ if ( isHR == null )
+ {
+ // The attribute type will be set to binary
+ isHR = false;
+ values.add( val );
+ }
+ else if ( !isHR )
+ {
+ // The attributeType is not HR, simply add the value
+ values.add( val );
+ }
+ else
+ {
+ // The attribute Type is HR, convert the
+ // value to a StringValue
+ ClientStringValue csv = new ClientStringValue();
+ csv.set( StringTools.utf8ToString( (byte[])val.get() ) );
+
+ values.add( csv );
+ }
+ }
+ }
+
+ nbAdded++;
}
-
- return nbAdded;
- }
+ // Last, not least, if a nullValue has been added, and if other
+ // values are all String, we have to keep the correct nullValue,
+ // and to remove the other
+ if ( nullValueAdded )
+ {
+ if ( isHR )
+ {
+ // Remove the Binary value
+ values.remove( nullBinaryValue );
+ }
+ else
+ {
+ // Remove the String value
+ values.remove( nullStringValue );
+ }
+ }
- /**
- * @see EntryAttribute#add(String)
- */
- public boolean add( String val ) throws InvalidAttributeValueException, NamingException
- {
- return add( new ClientStringValue( val ) );
+ return nbAdded;
}
/**
* @see EntryAttribute#add(String...)
*/
- public int add( String... vals ) throws NamingException
+ public int add( String... vals )
{
int nbAdded = 0;
- for ( String val:vals )
+ // First, if the isHR flag is not set, we assume that the
+ // attribute is HR, because we are asked to add some strings.
+ if ( isHR == null )
{
- if ( add( val ) )
+ isHR = true;
+ }
+
+ // Check the attribute type.
+ if ( isHR )
+ {
+ for ( String val:vals )
+ {
+ if ( add( new ClientStringValue( val ) ) == 1 )
+ {
+ nbAdded++;
+ }
+ }
+ }
+ else
+ {
+ // The attribute is binary. Transform the String to byte[]
+ for ( String val:vals )
{
- nbAdded ++;
+ byte[] valBytes = null;
+
+ if ( val != null )
+ {
+ valBytes = StringTools.getBytesUtf8( val );
+ }
+
+ // Now call the add(Value) method
+ if ( add( new ClientBinaryValue( valBytes ) ) == 1 )
+ {
+ nbAdded++;
+ }
}
}
@@ -279,26 +567,72 @@
/**
- * @see EntryAttribute#add(byte[])
- */
- public boolean add( byte[] val ) throws InvalidAttributeValueException, NamingException
- {
- return add( new ClientBinaryValue( val ) );
- }
-
-
- /**
- * @see EntryAttribute#add(byte[]...)
+ * Adds some values to this attribute. If the new values are already present in
+ * the attribute values, the method has no effect.
+ * <p>
+ * The new values are added at the end of list of values.
+ * </p>
+ * <p>
+ * This method returns the number of values that were added.
+ * </p>
+ * If the value's type is different from the attribute's type,
+ * a conversion is done. For instance, if we try to set some String
+ * into a Binary attribute, we just store the UTF-8 byte array
+ * encoding for this String.
+ * If we try to store some byte[] in a HR attribute, we try to
+ * convert those byte[] assuming they represent an UTF-8 encoded
+ * String. Of course, if it's not the case, the stored value will
+ * be incorrect.
+ * <br>
+ * It's the responsibility of the caller to check if the stored
+ * values are consistent with the attribute's type.
+ * <br>
+ * The caller can set the HR flag in order to enforce a type for
+ * the current attribute, otherwise this type will be set while
+ * adding the first value, using the value's type to set the flag.
+ *
+ * @param val some new values to be added which may be null
+ * @return the number of added values, or 0 if none has been added
*/
- public int add( byte[]... vals ) throws InvalidAttributeValueException, NamingException
+ public int add( byte[]... vals )
{
int nbAdded = 0;
- for ( byte[] val:vals )
+ // First, if the isHR flag is not set, we assume that the
+ // attribute is not HR, because we are asked to add some byte[].
+ if ( isHR == null )
{
- if ( add( val ) )
+ isHR = false;
+ }
+
+ // Check the attribute type.
+ if ( isHR )
+ {
+ // The attribute is HR. Transform the byte[] to String
+ for ( byte[] val:vals )
{
- nbAdded ++;
+ String valString = null;
+
+ if ( val != null )
+ {
+ valString = StringTools.utf8ToString( val );
+ }
+
+ // Now call the add(Value) method
+ if ( add( new ClientStringValue( valString ) ) == 1 )
+ {
+ nbAdded++;
+ }
+ }
+ }
+ else
+ {
+ for ( byte[] val:vals )
+ {
+ if ( add( new ClientBinaryValue( val ) ) == 1 )
+ {
+ nbAdded++;
+ }
}
}
@@ -307,8 +641,7 @@
/**
- * Remove all the values from this attribute type, including a
- * null value.
+ * Remove all the values from this attribute.
*/
public void clear()
{
@@ -317,26 +650,75 @@
/**
- * @see EntryAttribute#contains(org.apache.directory.shared.ldap.entry.Value)
+ * <p>
+ * Indicates whether the specified values are some of the attribute's values.
+ * </p>
+ * <p>
+ * If the Attribute is HR, the binary values will be converted to String before
+ * being checked.
+ * </p>
+ *
+ * @param vals the values
+ * @return true if this attribute contains all the values, otherwise false
*/
- public boolean contains( ClientValue<?> val )
+ public boolean contains( Value<?>... vals )
{
- return values.contains( val );
- }
-
+ if ( isHR == null )
+ {
+ // If this flag is null, then there is no values.
+ return false;
+ }
- /**
- * @see EntryAttribute#contains(org.apache.directory.shared.ldap.entry.Value...)
- */
- public boolean contains( ClientValue<?>... vals )
- {
- // Iterate through all the values, and quit if we
- // don't find one in the values
- for ( ClientValue<?> val:vals )
+ if ( isHR )
{
- if ( !values.contains( val ) )
+ // Iterate through all the values, convert the Binary values
+ // to String values, and quit id any of the values is not
+ // contained in the object
+ for ( Value<?> val:vals )
{
- return false;
+ if ( val instanceof ClientStringValue )
+ {
+ if ( !values.contains( val ) )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ byte[] binaryVal = (byte[])val.get();
+
+ // We have to convert the binary value to a String
+ if ( ! values.contains( new ClientStringValue( StringTools.utf8ToString( binaryVal ) ) ) )
+ {
+ return false;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Iterate through all the values, convert the String values
+ // to binary values, and quit id any of the values is not
+ // contained in the object
+ for ( Value<?> val:vals )
+ {
+ if ( val instanceof ClientBinaryValue )
+ {
+ if ( !values.contains( val ) )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ String stringVal = (String)val.get();
+
+ // We have to convert the binary value to a String
+ if ( ! values.contains( new ClientBinaryValue( StringTools.getBytesUtf8( stringVal ) ) ) )
+ {
+ return false;
+ }
+ }
}
}
@@ -345,28 +727,50 @@
/**
- * @see EntryAttribute#contains(String)
- */
- public boolean contains( String val )
- {
- ClientStringValue value = new ClientStringValue( val );
-
- return values.contains( value );
- }
-
-
- /**
- * @see EntryAttribute#contains(String...)
+ * <p>
+ * Indicates whether the specified values are some of the attribute's values.
+ * </p>
+ * <p>
+ * If the Attribute is not HR, the values will be converted to byte[]
+ * </p>
+ *
+ * @param vals the values
+ * @return true if this attribute contains all the values, otherwise false
*/
public boolean contains( String... vals )
{
- // Iterate through all the values, and quit if we
- // don't find one in the values
- for ( String val:vals )
+ if ( isHR == null )
+ {
+ // If this flag is null, then there is no values.
+ return false;
+ }
+
+ if ( isHR )
{
- if ( !contains( val ) )
+ // Iterate through all the values, and quit if we
+ // don't find one in the values
+ for ( String val:vals )
{
- return false;
+ if ( !contains( new ClientStringValue( val ) ) )
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // As the attribute type is binary, we have to convert
+ // the values before checking for them in the values
+ // Iterate through all the values, and quit if we
+ // don't find one in the values
+ for ( String val:vals )
+ {
+ byte[] binaryVal = StringTools.getBytesUtf8( val );
+
+ if ( !contains( new ClientBinaryValue( binaryVal ) ) )
+ {
+ return false;
+ }
}
}
@@ -375,45 +779,131 @@
/**
- * @see EntryAttribute#contains(byte[])
+ * <p>
+ * Indicates whether the specified values are some of the attribute's values.
+ * </p>
+ * <p>
+ * If the Attribute is HR, the values will be converted to String
+ * </p>
+ *
+ * @param vals the values
+ * @return true if this attribute contains all the values, otherwise false
*/
- public boolean contains( byte[] val )
+ public boolean contains( byte[]... vals )
{
- ClientBinaryValue sbv = new ClientBinaryValue( val );
- return values.contains( sbv );
- }
+ if ( isHR == null )
+ {
+ // If this flag is null, then there is no values.
+ return false;
+ }
+ if ( !isHR )
+ {
+ // Iterate through all the values, and quit if we
+ // don't find one in the values
+ for ( byte[] val:vals )
+ {
+ if ( !contains( new ClientBinaryValue( val ) ) )
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // As the attribute type is String, we have to convert
+ // the values before checking for them in the values
+ // Iterate through all the values, and quit if we
+ // don't find one in the values
+ for ( byte[] val:vals )
+ {
+ String stringVal = StringTools.utf8ToString( val );
+ if ( !contains( new ClientStringValue( stringVal ) ) )
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+
/**
- * @see EntryAttribute#contains(byte[]...)
+ * @see EntryAttribute#contains(Object...)
*/
- public boolean contains( byte[]... vals )
+ public boolean contains( Object... vals )
{
+ boolean isHR = true;
+ boolean seen = false;
+
// Iterate through all the values, and quit if we
// don't find one in the values
- for ( byte[] val:vals )
+ for ( Object val:vals )
{
- if ( !contains( val ) )
+ if ( ( val instanceof String ) )
{
- return false;
+ if ( !seen )
+ {
+ isHR = true;
+ seen = true;
+ }
+
+ if ( isHR )
+ {
+ if ( !contains( (String)val ) )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if ( !seen )
+ {
+ isHR = false;
+ seen = true;
+ }
+
+ if ( !isHR )
+ {
+ if ( !contains( (byte[])val ) )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
}
}
return true;
}
-
+
/**
+ * <p>
* Get the first value of this attribute. If there is none,
* null is returned.
- *
- * Note : as we are storing values into a Set, one can't assume
- * the values to be ordered in any way. This method is meant to
- * be used if the attribute hold only one value.
+ * </p>
+ * <p>
+ * Note : even if we are storing values into a Set, one can assume
+ * the values are ordered following the insertion order.
+ * </p>
+ * <p>
+ * This method is meant to be used if the attribute hold only one value.
+ * </p>
*
* @return The first value for this attribute.
*/
- public ClientValue<?> get()
+ public Value<?> get()
{
if ( values.isEmpty() )
{
@@ -425,21 +915,28 @@
/**
- * Get all the stored values.
- *
- * @return An iterator over the values stored into the attribute
+ * Returns an iterator over 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
*/
- public Iterator<ClientValue<?>> getAll()
+ public Iterator<Value<?>> getAll()
{
return iterator();
}
/**
- * Get the number or values stored in the attribute
- *
- * @return the number of stored values. As 'null' can be a valid
- * value, it is counted as one result, not 0.
+ * Retrieves the number of values in this attribute.
+ *
+ * @return the number of values in this attribute, including any values
+ * wrapping a null value if there is one
*/
public int size()
{
@@ -448,26 +945,60 @@
/**
- * @see EntryAttribute#remove(org.apache.directory.shared.ldap.entry.Value)
- */
- public boolean remove( ClientValue<?> val )
- {
- return values.remove( val );
- }
-
-
- /**
- * @see EntryAttribute#remove(org.apache.directory.shared.ldap.entry.Value...)
+ * <p>
+ * Removes all the values that are equal to the given values.
+ * </p>
+ * <p>
+ * Returns true if all the values are removed.
+ * </p>
+ * <p>
+ * If the attribute type is HR and some value which are not String, we
+ * will convert the values first (same thing for a non-HR attribute).
+ * </p>
+ *
+ * @param vals the values to be removed
+ * @return true if all the values are removed, otherwise false
*/
- public boolean remove( ClientValue<?>... vals )
+ public boolean remove( Value<?>... vals )
{
- boolean removed = false;
+ if ( ( isHR == null ) || ( values.size() == 0 ) )
+ {
+ // Trying to remove a value from an empty list will fail
+ return false;
+ }
- // Loop through all the values to remove. If one of
- // them is not present, the method will return false.
- for ( ClientValue<?> val:vals )
+ boolean removed = true;
+
+ if ( isHR )
+ {
+ for ( Value<?> val:vals )
+ {
+ if ( val instanceof ClientStringValue )
+ {
+ removed &= values.remove( val );
+ }
+ else
+ {
+ // Convert the binary value to a string value
+ byte[] binaryVal = (byte[])val.get();
+ removed &= values.remove( new ClientStringValue( StringTools.utf8ToString( binaryVal ) ) );
+ }
+ }
+ }
+ else
{
- removed &= values.remove( val );
+ for ( Value<?> val:vals )
+ {
+ if ( val instanceof ClientBinaryValue )
+ {
+ removed &= values.remove( val );
+ }
+ else
+ {
+ String stringVal = (String)val.get();
+ removed &= values.remove( new ClientBinaryValue( StringTools.getBytesUtf8( stringVal ) ) );
+ }
+ }
}
return removed;
@@ -475,26 +1006,95 @@
/**
- * @see EntryAttribute#remove(byte[])
+ * <p>
+ * Removes all the values that are equal to the given values.
+ * </p>
+ * <p>
+ * Returns true if all the values are removed.
+ * </p>
+ * <p>
+ * If the attribute type is HR, then the values will be first converted
+ * to String
+ * </p>
+ *
+ * @param vals the values to be removed
+ * @return true if all the values are removed, otherwise false
*/
- public boolean remove( byte[] val )
+ public boolean remove( byte[]... vals )
{
- ClientBinaryValue sbv = new ClientBinaryValue( val );
- return values.remove( sbv );
+ if ( ( isHR == null ) || ( values.size() == 0 ) )
+ {
+ // Trying to remove a value from an empty list will fail
+ return false;
+ }
+
+ boolean removed = true;
+
+ if ( !isHR )
+ {
+ // The attribute type is not HR, we can directly process the values
+ for ( byte[] val:vals )
+ {
+ ClientBinaryValue value = new ClientBinaryValue( val );
+ removed &= values.remove( value );
+ }
+ }
+ else
+ {
+ // The attribute type is String, we have to convert the values
+ // to String before removing them
+ for ( byte[] val:vals )
+ {
+ ClientStringValue value = new ClientStringValue( StringTools.utf8ToString( val ) );
+ removed &= values.remove( value );
+ }
+ }
+
+ return removed;
}
/**
- * @see EntryAttribute#remove(byte[]...)
+ * Removes all the values that are equal to the given values.
+ * <p>
+ * Returns true if all the values are removed.
+ * </p>
+ * <p>
+ * If the attribute type is not HR, then the values will be first converted
+ * to byte[]
+ * </p>
+ *
+ * @param vals the values to be removed
+ * @return true if all the values are removed, otherwise false
*/
- public boolean remove( byte[]... vals )
+ public boolean remove( String... vals )
{
+ if ( ( isHR == null ) || ( values.size() == 0 ) )
+ {
+ // Trying to remove a value from an empty list will fail
+ return false;
+ }
+
boolean removed = true;
- for ( byte[] val:vals )
+ if ( isHR )
{
- ClientBinaryValue value = new ClientBinaryValue( val );
- removed &= values.remove( value );
+ // The attribute type is HR, we can directly process the values
+ for ( String val:vals )
+ {
+ ClientStringValue value = new ClientStringValue( val );
+ removed &= values.remove( value );
+ }
+ }
+ else
+ {
+ // The attribute type is binary, we have to convert the values
+ // to byte[] before removing them
+ for ( String val:vals )
+ {
+ ClientBinaryValue value = new ClientBinaryValue( StringTools.getBytesUtf8( val ) );
+ removed &= values.remove( value );
+ }
}
return removed;
@@ -502,42 +1102,214 @@
/**
- * @see EntryAttribute#remove(String)
+ * An iterator on top of the stored values.
+ *
+ * @return an iterator over the stored values.
*/
- public boolean remove( String val )
+ public Iterator<Value<?>> iterator()
{
- ClientStringValue ssv = new ClientStringValue( val );
- return values.remove( ssv );
+ return values.iterator();
+ }
+
+
+ /**
+ * Puts some values to this attribute.
+ * <p>
+ * The new values will replace the previous values.
+ * </p>
+ * <p>
+ * This method returns the number of values that were put.
+ * </p>
+ *
+ * @param val some values to be put which may be null
+ * @return the number of added values, or 0 if none has been added
+ */
+ public int put( String... vals )
+ {
+ values.clear();
+ return add( vals );
+ }
+
+
+ /**
+ * Puts some values to this attribute.
+ * <p>
+ * The new values will replace the previous values.
+ * </p>
+ * <p>
+ * This method returns the number of values that were put.
+ * </p>
+ *
+ * @param val some values to be put which may be null
+ * @return the number of added values, or 0 if none has been added
+ */
+ public int put( byte[]... vals )
+ {
+ values.clear();
+ return add( vals );
}
-
+
/**
- * @see EntryAttribute#remove(String...)
+ * Puts some values to this attribute.
+ * <p>
+ * The new values are replace the previous values.
+ * </p>
+ * <p>
+ * This method returns the number of values that were put.
+ * </p>
+ *
+ * @param val some values to be put which may be null
+ * @return the number of added values, or 0 if none has been added
*/
- public boolean remove( String... vals )
+ public int put( Value<?>... vals )
{
- boolean removed = true;
+ values.clear();
+ return add( vals );
+ }
+
+
+ /**
+ * <p>
+ * Puts a list of values into this attribute.
+ * </p>
+ * <p>
+ * The new values will replace the previous values.
+ * </p>
+ * <p>
+ * This method returns the number of values that were put.
+ * </p>
+ *
+ * @param vals the values to be put
+ * @return the number of added values, or 0 if none has been added
+ */
+ public int put( List<Value<?>> vals )
+ {
+ values.clear();
+
+ // Transform the List to an array
+ Value<?>[] valArray = new Value<?>[vals.size()];
+ return add( vals.toArray( valArray ) );
+ }
+
+ //-------------------------------------------------------------------------
+ // Overloaded Object classes
+ //-------------------------------------------------------------------------
+ /**
+ * The hashCode is based on the id, the isHR flag and
+ * on the internal values.
+ *
+ * @see Object#hashCode()
+ */
+ public int hashCode()
+ {
+ int h = 37;
- for ( String val:vals )
+ if ( isHR != null )
{
- ClientStringValue value = new ClientStringValue( val );
- removed &= values.remove( value );
+ h = h*17 + isHR.hashCode();
}
- return removed;
+ if ( id != null )
+ {
+ h = h*17 + id.hashCode();
+ }
+
+ for ( Value<?> value:values )
+ {
+ h = h*17 + value.hashCode();
+ }
+
+ return h;
}
-
-
+
+
/**
- * An iterator on top of the stored values.
- *
- * @return an iterator over the stored values.
+ * @see Object#equals(Object)
*/
- public Iterator<ClientValue<?>> iterator()
+ public boolean equals( Object obj )
{
- return values.iterator();
+ if ( obj == this )
+ {
+ return true;
+ }
+
+ if ( ! (obj instanceof EntryAttribute ) )
+ {
+ return false;
+ }
+
+ EntryAttribute other = (EntryAttribute)obj;
+
+ if ( id == null )
+ {
+ if ( other.getId() != null )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if ( other.getId() == null )
+ {
+ return false;
+ }
+ else
+ {
+ if ( !id.equals( other.getId() ) )
+ {
+ return false;
+ }
+ }
+ }
+
+ if ( isHR() != other.isHR() )
+ {
+ return false;
+ }
+
+ if ( values.size() != other.size() )
+ {
+ return false;
+ }
+
+ for ( Value<?> val:values )
+ {
+ if ( ! other.contains( val ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
}
+
+ /**
+ * @see Cloneable#clone()
+ */
+ public EntryAttribute clone()
+ {
+ try
+ {
+ DefaultClientAttribute attribute = (DefaultClientAttribute)super.clone();
+
+ attribute.values = new LinkedHashSet<Value<?>>( values.size() );
+
+ for ( Value<?> value:values )
+ {
+ attribute.values.add( value.clone() );
+ }
+
+ return attribute;
+ }
+ catch ( CloneNotSupportedException cnse )
+ {
+ return null;
+ }
+ }
+
+
/**
* @see Object#toString()
*/
@@ -547,7 +1319,7 @@
if ( ( values != null ) && ( values.size() != 0 ) )
{
- for ( ClientValue<?> value:values )
+ for ( Value<?> value:values )
{
sb.append( " " ).append( upId ).append( ": " ).append( value ).append( '\n' );
}
@@ -559,5 +1331,4 @@
return sb.toString();
}
-
}
Modified: directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifReader.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifReader.java?rev=638218&r1=638217&r2=638218&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifReader.java (original)
+++ directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifReader.java Mon Mar 17 22:07:20 2008
@@ -152,7 +152,7 @@
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class LdifReader implements Iterator<Entry>
+public class LdifReader implements Iterator<LdifEntry>
{
/** A logger */
private static final Logger LOG = LoggerFactory.getLogger( LdifReader.class );
@@ -211,7 +211,7 @@
protected static final int ATTRVAL_SPEC_OR_SEP = 2;
/** Iterator prefetched entry */
- protected Entry prefetched;
+ protected LdifEntry prefetched;
/** The ldif Reader */
protected Reader in;
@@ -855,7 +855,7 @@
* @throws NamingException
* If anything goes wrong
*/
- public void parseAttributeValue( Entry entry, String line, String lowerLine ) throws NamingException
+ public void parseAttributeValue( LdifEntry entry, String line, String lowerLine ) throws NamingException
{
int colonIndex = line.indexOf( ':' );
@@ -884,7 +884,7 @@
* @throws NamingException
* If anything goes wrong
*/
- private void parseModRdn( Entry entry, Iterator<String> iter ) throws NamingException
+ private void parseModRdn( LdifEntry entry, Iterator<String> iter ) throws NamingException
{
// We must have two lines : one starting with "newrdn:" or "newrdn::",
// and the second starting with "deleteoldrdn:"
@@ -955,7 +955,7 @@
* @param iter
* The lines
*/
- private void parseModify( Entry entry, Iterator<String> iter ) throws NamingException
+ private void parseModify( LdifEntry entry, Iterator<String> iter ) throws NamingException
{
int state = MOD_SPEC;
String modified = null;
@@ -1105,7 +1105,7 @@
* The associated control, if any
* @return A modification entry
*/
- private void parseChange( Entry entry, Iterator<String> iter, ChangeType operation, Control control ) throws NamingException
+ private void parseChange( LdifEntry entry, Iterator<String> iter, ChangeType operation, Control control ) throws NamingException
{
// The changetype and operation has already been parsed.
entry.setChangeType( operation );
@@ -1187,7 +1187,7 @@
* <distinguishedName> | "dn::" <fill> <base64-distinguishedName>
* <changerecord> ::= "changetype:" <fill> <change-op>
*/
- private Entry parseEntry() throws NamingException
+ private LdifEntry parseEntry() throws NamingException
{
if ( ( lines == null ) || ( lines.size() == 0 ) )
{
@@ -1201,7 +1201,7 @@
String dn = parseDn( line );
// Ok, we have found a DN
- Entry entry = new Entry();
+ LdifEntry entry = new LdifEntry();
entry.setDn( dn );
// We remove this dn from the lines
@@ -1501,7 +1501,7 @@
* @throws NamingException
* If the parsing fails
*/
- public List<Entry> parseLdifFile( String fileName ) throws NamingException
+ public List<LdifEntry> parseLdifFile( String fileName ) throws NamingException
{
return parseLdifFile( fileName, Charset.forName( StringTools.getDefaultCharsetName() ).toString() );
}
@@ -1517,7 +1517,7 @@
* @throws NamingException
* If the parsing fails
*/
- public List<Entry> parseLdifFile( String fileName, String encoding ) throws NamingException
+ public List<LdifEntry> parseLdifFile( String fileName, String encoding ) throws NamingException
{
if ( StringTools.isEmpty( fileName ) )
{
@@ -1558,13 +1558,13 @@
* @throws NamingException
* If something went wrong
*/
- public List<Entry> parseLdif( String ldif ) throws NamingException
+ public List<LdifEntry> parseLdif( String ldif ) throws NamingException
{
LOG.debug( "Starts parsing ldif buffer" );
if ( StringTools.isEmpty( ldif ) )
{
- return new ArrayList<Entry>();
+ return new ArrayList<LdifEntry>();
}
StringReader strIn = new StringReader( ldif );
@@ -1572,7 +1572,7 @@
try
{
- List<Entry> entries = parseLdif( inf );
+ List<LdifEntry> entries = parseLdif( inf );
if ( LOG.isDebugEnabled() )
{
@@ -1597,13 +1597,13 @@
*
* @return the next LDIF as a String.
*/
- public Entry next() throws NoSuchElementException
+ public LdifEntry next() throws NoSuchElementException
{
try
{
LOG.debug( "next(): -- called" );
- Entry entry = prefetched;
+ LdifEntry entry = prefetched;
readLines();
try
@@ -1652,7 +1652,7 @@
/**
* @return An iterator on the file
*/
- public Iterator<Entry> iterator()
+ public Iterator<LdifEntry> iterator()
{
return this;
}
@@ -1683,10 +1683,10 @@
* @throws NamingException
* If something went wrong
*/
- public List<Entry> parseLdif( BufferedReader inf ) throws NamingException
+ public List<LdifEntry> parseLdif( BufferedReader inf ) throws NamingException
{
// Create a list that will contain the read entries
- List<Entry> entries = new ArrayList<Entry>();
+ List<LdifEntry> entries = new ArrayList<LdifEntry>();
this.in = inf;
@@ -1697,7 +1697,7 @@
// When done, get the entries one by one.
while ( hasNext() )
{
- Entry entry = next();
+ LdifEntry entry = next();
if ( error != null )
{
Modified: directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifUtils.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifUtils.java?rev=638218&r1=638217&r2=638218&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifUtils.java (original)
+++ directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/ldif/LdifUtils.java Mon Mar 17 22:07:20 2008
@@ -188,7 +188,7 @@
* @return the corresponding LDIF as a String
* @throws NamingException If a naming exception is encountered.
*/
- public static String convertToLdif( Entry entry ) throws NamingException
+ public static String convertToLdif( LdifEntry entry ) throws NamingException
{
return convertToLdif( entry, DEFAULT_LINE_LENGTH );
}
@@ -199,7 +199,7 @@
* @return the corresponding LDIF as a String
* @throws NamingException If a naming exception is encountered.
*/
- public static String convertToLdif( Entry entry, int length ) throws NamingException
+ public static String convertToLdif( LdifEntry entry, int length ) throws NamingException
{
StringBuilder sb = new StringBuilder();
@@ -471,9 +471,9 @@
* @return a reverse LDIF
* @throws NamingException If something went wrong
*/
- public static Entry reverseAdd( LdapDN dn ) throws NamingException
+ public static LdifEntry reverseAdd( LdapDN dn ) throws NamingException
{
- Entry entry = new Entry();
+ LdifEntry entry = new LdifEntry();
entry.setChangeType( ChangeType.Delete );
entry.setDn( dn.getUpName() );
return entry;
@@ -489,9 +489,9 @@
* @return A reverse LDIF
* @throws NamingException If something went wrong
*/
- public static Entry reverseDel( LdapDN dn, Attributes deletedEntry ) throws NamingException
+ public static LdifEntry reverseDel( LdapDN dn, Attributes deletedEntry ) throws NamingException
{
- Entry entry = new Entry();
+ LdifEntry entry = new LdifEntry();
entry.setDn( dn.getUpName() );
entry.setChangeType( ChangeType.Add );
@@ -516,9 +516,9 @@
* @return a reverse LDIF
* @throws NamingException if something went wrong
*/
- public static Entry reverseModifyDn( LdapDN newSuperiorDn, LdapDN modifiedDn ) throws NamingException
+ public static LdifEntry reverseModifyDn( LdapDN newSuperiorDn, LdapDN modifiedDn ) throws NamingException
{
- Entry entry = new Entry();
+ LdifEntry entry = new LdifEntry();
LdapDN currentParent;
LdapDN newDn;
@@ -551,9 +551,9 @@
}
- public static Entry reverseRename( Attributes t0, LdapDN t0_dn, Rdn t1_rdn ) throws NamingException
+ public static LdifEntry reverseRename( Attributes t0, LdapDN t0_dn, Rdn t1_rdn ) throws NamingException
{
- Entry entry = new Entry();
+ LdifEntry entry = new LdifEntry();
LdapDN parent;
LdapDN newDn;
@@ -598,7 +598,7 @@
* @return A reverse LDIF
* @throws NamingException If something went wrong
*/
- public static Entry reverseModifyRdn( Attributes t0, LdapDN t1_parentDn, LdapDN t0_dn, Rdn t1_rdn )
+ public static LdifEntry reverseModifyRdn( Attributes t0, LdapDN t1_parentDn, LdapDN t0_dn, Rdn t1_rdn )
throws NamingException
{
if ( t0_dn == null )
@@ -630,7 +630,7 @@
// -------------------------------------------------------------------
// the reverse LDIF we will create
- Entry reverse = new Entry();
+ LdifEntry reverse = new LdifEntry();
// take the dn before the forward change was applied, and get it's
// parent, this parent will be the newSuperiorDn to be used for the
@@ -709,13 +709,13 @@
* @return A reversed LDIF
* @throws NamingException If something went wrong
*/
- public static Entry reverseModify( LdapDN dn, List<ModificationItemImpl> forwardModifications,
+ public static LdifEntry reverseModify( LdapDN dn, List<ModificationItemImpl> forwardModifications,
Attributes modifiedEntry ) throws NamingException
{
// First, protect the original entry by cloning it : we will modify it
Attributes clonedEntry = ( Attributes ) modifiedEntry.clone();
- Entry entry = new Entry();
+ LdifEntry entry = new LdifEntry();
entry.setChangeType( ChangeType.Modify );
entry.setDn( dn.getUpName() );
Modified: directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/AttributeTypeAndValue.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/AttributeTypeAndValue.java?rev=638218&r1=638217&r2=638218&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/AttributeTypeAndValue.java (original)
+++ directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/AttributeTypeAndValue.java Mon Mar 17 22:07:20 2008
@@ -69,7 +69,7 @@
private String upType;
/** The name value. It can be a String or a byte array */
- private Object value;
+ private Object normValue;
/** The name user provided value. It can be a String or a byte array */
private Object upValue;
@@ -97,7 +97,7 @@
{
normType = null;
upType = null;
- value = null;
+ normValue = null;
upValue = null;
upName = "";
start = -1;
@@ -156,11 +156,11 @@
{
if ( normValue instanceof String )
{
- this.value = StringTools.isEmpty( ( String ) normValue ) ? "" : normValue;
+ this.normValue = StringTools.isEmpty( ( String ) normValue ) ? "" : normValue;
}
else
{
- this.value = normValue;
+ this.normValue = normValue;
}
if ( upValue instanceof String )
@@ -179,11 +179,11 @@
if ( normValue instanceof String )
{
- this.value = StringTools.isEmpty( ( String ) normValue ) ? "" : normValue;
+ this.normValue = StringTools.isEmpty( ( String ) normValue ) ? "" : normValue;
}
else
{
- this.value = normValue;
+ this.normValue = normValue;
}
}
@@ -194,6 +194,38 @@
/**
+ * Construct an AttributeTypeAndValue. The type and value are normalized :
+ * <li> the type is trimmed and lowercased </li>
+ * <li> the value is trimmed </li>
+ * <p>
+ * Note that the upValue should <b>not</b> be null or empty, or resolved
+ * to an empty string after having trimmed it.
+ *
+ * @param upType The Usrr Provided type
+ * @param normType The normalized type
+ * @param upValue The User Provided value
+ * @param normValue The normalized value
+ */
+ /**No protection*/ AttributeTypeAndValue(
+ String upType,
+ String normType,
+ Object upValue,
+ Object normValue,
+ int start,
+ int length,
+ String upName )
+ {
+ this.upType = upType;
+ this.normType = normType;
+ this.upValue = upValue;
+ this.normValue = normValue;
+ this.start = start;
+ this.length = length;
+ this.upName = upName;
+ }
+
+
+ /**
* Get the normalized type of a AttributeTypeAndValue
*
* @return The normalized type
@@ -283,9 +315,9 @@
*
* @return The value
*/
- public Object getValue()
+ public Object getNormValue()
{
- return value;
+ return normValue;
}
/**
@@ -315,15 +347,15 @@
* @param value
* The value of the AttributeTypeAndValue
*/
- public void setValue( Object upValue, Object value )
+ public void setValue( Object upValue, Object normValue )
{
- if ( value instanceof String )
+ if ( normValue instanceof String )
{
- this.value = StringTools.isEmpty( ( String ) value ) ? "" : ( String ) value;
+ this.normValue = StringTools.isEmpty( ( String ) normValue ) ? "" : ( String ) normValue;
}
else
{
- this.value = value;
+ this.normValue = normValue;
}
this.upValue = upValue;
@@ -378,11 +410,11 @@
if ( StringTools.isEmpty( newValue ) )
{
- this.value = "";
+ this.normValue = "";
}
else
{
- this.value = newValue;
+ this.normValue = newValue;
}
upName = upName.substring( 0, upName.indexOf( '=' ) + 1 ) + value;
@@ -410,8 +442,9 @@
/**
- * Compares two NameComponents. They are equals if : - types are equals,
- * case insensitive, - values are equals, case sensitive
+ * Compares two NameComponents. They are equals if :
+ * - types are equals, case insensitive,
+ * - values are equals, case sensitive
*
* @param object
* @return 0 if both NC are equals, otherwise a positive value if the
@@ -432,7 +465,7 @@
}
else
{
- return compareValue( value, nc.value, CASE_SENSITIVE );
+ return compareValue( normValue, nc.normValue, CASE_SENSITIVE );
}
}
else
@@ -443,8 +476,9 @@
/**
- * Compares two NameComponents. They are equals if : - types are equals,
- * case insensitive, - values are equals, case insensitive
+ * Compares two NameComponents. They are equals if :
+ * - types are equals, case insensitive,
+ * - values are equals, case insensitive
*
* @param object
* @return 0 if both NC are equals, otherwise a positive value if the
@@ -465,7 +499,7 @@
}
else
{
- return compareValue( value, nc.value, CASE_INSENSITIVE );
+ return compareValue( normValue, nc.normValue, CASE_INSENSITIVE );
}
}
else
@@ -572,7 +606,7 @@
*/
public String normalize()
{
- if ( value instanceof String )
+ if ( normValue instanceof String )
{
// The result will be gathered in a stringBuilder
StringBuilder sb = new StringBuilder();
@@ -580,7 +614,7 @@
// First, store the type and the '=' char
sb.append( normType ).append( '=' );
- String normalizedValue = ( String ) value;
+ String normalizedValue = ( String ) normValue;
int valueLength = normalizedValue.length();
boolean escaped = false;
@@ -680,7 +714,7 @@
else
{
return normType + "=#"
- + StringTools.dumpHexPairs( ( byte[] ) value );
+ + StringTools.dumpHexPairs( ( byte[] ) normValue );
}
}
@@ -695,7 +729,7 @@
int result = 37;
result = result*17 + ( normType != null ? normType.hashCode() : 0 );
- result = result*17 + ( value != null ? value.hashCode() : 0 );
+ result = result*17 + ( normValue != null ? normValue.hashCode() : 0 );
return result;
}
@@ -734,26 +768,26 @@
}
// Compare the values
- if ( value == null )
+ if ( normValue == null )
{
- return instance.value == null;
+ return instance.normValue == null;
}
- else if ( value instanceof String )
+ else if ( normValue instanceof String )
{
- if ( instance.value instanceof String )
+ if ( instance.normValue instanceof String )
{
- return value.equals( instance.value );
+ return normValue.equals( instance.normValue );
}
else
{
return false;
}
}
- else if ( value instanceof byte[] )
+ else if ( normValue instanceof byte[] )
{
- if ( instance.value instanceof byte[] )
+ if ( instance.normValue instanceof byte[] )
{
- return Arrays.equals( (byte[])value, (byte[])instance.value );
+ return Arrays.equals( (byte[])normValue, (byte[])instance.normValue );
}
else
{
@@ -798,7 +832,7 @@
( start < 0 ) ||
( length < 2 ) || // At least a type and '='
( upValue == null ) ||
- ( value == null ) )
+ ( normValue == null ) )
{
String message = "Cannot serialize an wrong ATAV, ";
@@ -826,7 +860,7 @@
{
message += "the upValue should not be null";
}
- else if ( value == null )
+ else if ( normValue == null )
{
message += "the value should not be null";
}
@@ -841,21 +875,21 @@
out.writeUTF( upType );
out.writeUTF( normType );
- boolean isHR = ( value instanceof String );
+ boolean isHR = ( normValue instanceof String );
out.writeBoolean( isHR );
if ( isHR )
{
out.writeUTF( (String)upValue );
- out.writeUTF( (String)value );
+ out.writeUTF( (String)normValue );
}
else
{
out.writeInt( ((byte[])upValue).length );
out.write( (byte[])upValue );
- out.writeInt( ((byte[])value).length );
- out.write( (byte[])value );
+ out.writeInt( ((byte[])normValue).length );
+ out.write( (byte[])normValue );
}
out.flush();
@@ -882,7 +916,7 @@
if ( isHR )
{
upValue = in.readUTF();
- value = in.readUTF();
+ normValue = in.readUTF();
}
else
{
@@ -891,8 +925,8 @@
in.readFully( (byte[])upValue );
int valueLength = in.readInt();
- value = new byte[valueLength];
- in.readFully( (byte[])value );
+ normValue = new byte[valueLength];
+ in.readFully( (byte[])normValue );
}
}
@@ -913,9 +947,9 @@
sb.append( normType ).append( "=" );
- if ( value != null )
+ if ( normValue != null )
{
- sb.append( value );
+ sb.append( normValue );
}
return sb.toString();
Modified: directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java?rev=638218&r1=638217&r2=638218&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java (original)
+++ directory/sandbox/akarasulu/bigbang/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java Mon Mar 17 22:07:20 2008
@@ -214,6 +214,18 @@
/**
+ * Create a DN when deserializing it.
+ */
+ /* No protection */ LdapDN( String upName, String normName, byte[] bytes )
+ {
+ normalized = true;
+ this.upName = upName;
+ this.normName = normName;
+ this.bytes = bytes;
+ }
+
+
+ /**
* Static factory which creates a normalized DN from a String and a Map of OIDs.
*
* @param name The DN as a String
@@ -295,7 +307,7 @@
*/
public String toNormName()
{
- if ( ( rdns == null ) || ( rdns.size() == 0 ) )
+ if ( rdns.size() == 0 )
{
bytes = null;
return "";
@@ -351,7 +363,7 @@
*/
private String toUpName()
{
- if ( ( rdns == null ) || ( rdns.size() == 0 ) )
+ if ( rdns.size() == 0 )
{
upName = "";
}
@@ -491,12 +503,9 @@
{
int result = 37;
- if ( ( rdns != null ) && ( rdns.size() != 0 ) )
+ for ( Rdn rdn : rdns )
{
- for ( Rdn rdn : rdns )
- {
- result = result * 17 + rdn.hashCode();
- }
+ result = result * 17 + rdn.hashCode();
}
return result;
@@ -526,9 +535,9 @@
/**
- * Get the number of NameComponent conatained in this LdapDN
+ * Get the number of NameComponent contained in this LdapDN
*
- * @return The number of NameComponent conatained in this LdapDN
+ * @return The number of NameComponent contained in this LdapDN
*/
public int size()
{
@@ -639,7 +648,6 @@
}
catch ( InvalidNameException e )
{
- e.printStackTrace();
LOG.error( "Failed to parse RDN for name " + name.toString(), e );
return false;
}
@@ -1173,6 +1181,25 @@
return this;
}
+
+ /**
+ * Adds a single RDN to a specific position.
+ *
+ * @param newRdn the RDN to add
+ * @param pos The position where we want to add the Rdn
+ * @return the updated name (not a new one)
+ */
+ public Name add( int pos, Rdn newRdn )
+ {
+ rdns.add( newRdn );
+
+ normalizeInternal();
+ toUpName();
+
+ return this;
+ }
+
+
/**
* Adds a single normalized RDN to the (leaf) end of this name.
*
@@ -1424,7 +1451,7 @@
{
return new AttributeTypeAndValue( atav.getUpType(), oidNormalizer.getAttributeTypeOid(),
atav.getUpValue(),
- oidNormalizer.getNormalizer().normalize( atav.getValue() ) );
+ oidNormalizer.getNormalizer().normalize( atav.getNormValue() ) );
}
else
@@ -1488,7 +1515,7 @@
{
AttributeTypeAndValue val = atavs.next();
AttributeTypeAndValue newAtav = atavOidToName( val, oidsMap );
- rdn.addAttributeTypeAndValue( val.getUpType(), newAtav.getNormType(), val.getUpValue(), newAtav.getValue() );
+ rdn.addAttributeTypeAndValue( val.getUpType(), newAtav.getNormType(), val.getUpValue(), newAtav.getNormValue() );
}
}
@@ -1709,24 +1736,15 @@
// Should we store the byte[] ???
// Write the RDNs. Is it's null, the number will be -1.
- if ( rdns == null )
- {
- out.writeInt( -1 );
- }
- else if ( rdns.size() == 0 )
- {
- out.writeInt( 0 );
- }
- else
+ out.writeInt( rdns.size() );
+
+ // Loop on the RDNs
+ for ( Rdn rdn:rdns )
{
- out.writeInt( rdns.size() );
-
- // Loop on the RDNs
- for ( Rdn rdn:rdns )
- {
- out.writeObject( rdn );
- }
+ out.writeObject( rdn );
}
+
+ out.flush();
}
@@ -1761,28 +1779,12 @@
// Read the RDNs. Is it's null, the number will be -1.
int nbRdns = in.readInt();
+ rdns = new ArrayList<Rdn>( nbRdns );
- switch ( nbRdns )
+ for ( int i = 0; i < nbRdns; i++ )
{
- case -1 :
- // No RDN at all...
- rdns = null;
- break;
-
- case 0 :
- // No RDN, but we have to initialize the list
- // Note : this may not be a different case than -1
- rdns = new ArrayList<Rdn>();
- break;
-
- default :
- for ( int i = 0; i < nbRdns; i++ )
- {
- Rdn rdn = (Rdn)in.readObject();
- rdns.add( rdn );
- }
-
- break;
+ Rdn rdn = (Rdn)in.readObject();
+ rdns.add( rdn );
}
}
}