directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r609459 [4/4] - in /directory: apacheds/branches/bigbang/bootstrap-plugin/ apacheds/branches/bigbang/bootstrap-plugin/src/main/java/org/apache/directory/server/core/bootstrap/plugin/ apacheds/branches/bigbang/core-entry/src/main/java/org/ap...
Date Sun, 06 Jan 2008 22:58:16 GMT
Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/AbstractClientAttribute.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/AbstractClientAttribute.java?rev=609459&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/AbstractClientAttribute.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/AbstractClientAttribute.java Sun Jan  6 14:58:12 2008
@@ -0,0 +1,504 @@
+/*
+ * 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 org.apache.directory.shared.asn1.primitives.OID;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.NamingException;
+import javax.naming.directory.InvalidAttributeValueException;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * An abstract class to collect common methods and common members for the
+ * BasicServerAttribute and ObjectClassAttribute classes.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractClientAttribute implements ClientAttribute, Cloneable
+{
+    /** logger for reporting errors that might not be handled properly upstream */
+    private static final Logger LOG = LoggerFactory.getLogger( AbstractClientAttribute.class );
+
+    /** The set of contained values */
+    protected List<ClientValue<?>> values = new ArrayList<ClientValue<?>>();
+    
+    /** The User provided ID */
+    protected String upId;
+
+    
+    // -----------------------------------------------------------------------
+    // utility methods
+    // -----------------------------------------------------------------------
+    /**
+     *  Check the attributeType member. It should not be null, 
+     *  and it should contains a syntax.
+     */
+    protected String getErrorMessage( AttributeType attributeType )
+    {
+        try
+        {
+            if ( attributeType == null )
+            {
+                return "The AttributeType parameter should not be null";
+            }
+            
+            if ( attributeType.getSyntax() == null )
+            {
+                return "There is no Syntax associated with this attributeType";
+            }
+
+            return null;
+        }
+        catch ( NamingException ne )
+        {
+            return "This AttributeType is incorrect";
+        }
+    }
+    
+    
+    /**
+     * Private helper method used to set an UpId from an attributeType
+     */
+    private String getUpId( AttributeType attributeType )
+    {
+        String upId = attributeType.getName();
+        
+        if ( upId == null )
+        {
+            upId = attributeType.getOid();
+        }
+        
+        return upId;
+    }
+    
+    
+    /**
+     * Set the user provided ID. If we have none, the upId is assigned
+     * the attributetype's name. If it does not have any name, we will
+     * use the OID.
+     * <p>
+     * If we have an upId and an AttributeType, they must be compatible. :
+     *  - if the upId is an OID, it must be the AttributeType's OID
+     *  - otherwise, its normalized form must be equals to ones of
+     *  the attributeType's names.
+     *
+     * @param upId The attribute ID
+     * @param attributeType The associated attributeType
+     */
+    protected void setUpId( String upId )
+    {
+        this.upId = upId;
+    }
+
+
+    // -----------------------------------------------------------------------
+    // API
+    // -----------------------------------------------------------------------
+    /**
+     * 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
+     * provides "COMMONname" instead when adding the entry then this is
+     * the format the user will have that entry returned by the directory
+     * server.  To do so we store this value as it was given and track it
+     * in the attribute using this property.
+     *
+     * @return the user provided identifier for this attribute
+     */
+    public String getUpId()
+    {
+        return upId;
+    }
+
+
+    /**
+     * 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 isValid() throws NamingException
+    {
+        for ( ClientValue<?> value : values )
+        {
+            if ( ! value.isValid() )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    /**
+     * @see EntryAttribute#add(org.apache.directory.shared.ldap.entry.Value...)
+     */
+    public int add( ClientValue<?>... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        int nbAdded = 0;
+        
+        for ( ClientValue<?> val:vals )
+        {
+            values.add( val );
+            nbAdded ++;
+        }
+        
+        return nbAdded;
+    }
+
+
+    /**
+     * @see EntryAttribute#put(org.apache.directory.shared.ldap.entry.Value...)
+     */
+    public int put( ClientValue<?>... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        values.clear();
+        return add( vals );
+    }
+    
+    /**
+     * @see EntryAttribute#add(String...)
+     */
+    public int add( String... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        int nbAdded = 0;
+        
+        for ( String val:vals )
+        {
+            values.add( new ClientStringValue( val ) );
+
+            nbAdded ++;
+        }
+        
+        return nbAdded;
+    }    
+    
+    
+    /**
+     * @see EntryAttribute#put(String...)
+     */
+    public int put( String... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        values.clear();
+        return add( vals );
+    }
+    
+    
+    /**
+     * @see EntryAttribute#add(byte[]...)
+     */
+    public int add( byte[]... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        int nbAdded = 0;
+        
+        for ( byte[] val:vals )
+        {
+            values.add( new ClientBinaryValue( val ) );
+            
+            nbAdded ++;
+        }
+        
+        return nbAdded;
+    }    
+
+
+    /**
+     * @see EntryAttribute#put(byte[]...)
+     */
+    public int put( byte[]... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        values.clear();
+        return add( vals );
+    }    
+
+    
+    /**
+     * Remove all the values from this attribute type, including a 
+     * null value. 
+     */
+    public void clear()
+    {
+        values.clear();
+    }
+
+    
+    /**
+     * @return A copy of the current attribute
+     */
+    public ClientAttribute clone()
+    {
+        try
+        {
+            AbstractClientAttribute clone = (AbstractClientAttribute)super.clone();
+
+            // Copy the values. The attributeType is immutable.
+            if ( ( values != null ) && ( values.size() != 0 ) )
+            {
+                clone.values = new ArrayList<ClientValue<?>>( values.size() );
+                
+                for ( ClientValue<?> value:values )
+                {
+                    clone.values.add( value.clone() );
+                }
+            }
+        
+            return clone;
+        }
+        catch ( CloneNotSupportedException cnse )
+        {
+            return null;
+        }
+    }
+
+    
+
+    /**
+     * @see EntryAttribute#contains(org.apache.directory.shared.ldap.entry.Value)
+     */
+    public boolean contains( ClientValue<?> val )
+    {
+        return values.contains( val );
+    }
+
+
+    /**
+     * @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 ( !values.contains( val ) )
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+
+
+    /**
+     * @see EntryAttribute#contains(String)
+     */
+    public boolean contains( String val )
+    {
+        ClientStringValue value = new ClientStringValue( val );
+        
+        return values.contains( value );
+    }
+
+
+    /**
+     * @see EntryAttribute#contains(String...)
+     */
+    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 ( !contains( val ) )
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    
+    /**
+     * @see EntryAttribute#contains(byte[])
+     */
+    public boolean contains( byte[] val )
+    {
+        ClientBinaryValue sbv = new ClientBinaryValue( val );
+        return values.contains( sbv );
+    }
+
+
+    /**
+     * @see EntryAttribute#contains(byte[]...)
+     */
+    public boolean contains( byte[]... vals )
+    {
+        // Iterate through all the values, and quit if we 
+        // don't find one in the values
+        for ( byte[] val:vals )
+        {
+            if ( !contains( val ) )
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    
+    /**
+     * 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.
+     * 
+     *  @return The first value for this attribute.
+     */
+    public ClientValue<?> get()
+    {
+        if ( values.isEmpty() )
+        {
+            return null;
+        }
+        
+        return values.iterator().next();
+    }
+
+
+    /**
+     * Get all the stored values.
+     * 
+     * @return An iterator over the values stored into the attribute
+     */
+    public Iterator<ClientValue<?>> 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.
+     */
+    public int size()
+    {
+        return values.size();
+    }
+
+
+    /**
+     * @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...)
+     */
+    public boolean remove( ClientValue<?>... vals )
+    {
+        boolean removed = false;
+        
+        // Loop through all the values to remove. If one of
+        // them is not present, the method will return false.
+        for ( ClientValue<?> val:vals )
+        {
+            removed &= values.remove( val );
+        }
+        
+        return removed;
+    }
+
+
+    /**
+     * @see EntryAttribute#remove(byte[])
+     */
+    public boolean remove( byte[] val )
+    {
+        ClientBinaryValue sbv = new ClientBinaryValue( val );
+        return values.remove( sbv );
+    }
+
+
+    /**
+     * @see EntryAttribute#remove(byte[]...)
+     */
+    public boolean remove( byte[]... vals )
+    {
+        boolean removed = true;
+        
+        for ( byte[] val:vals )
+        {
+            ClientBinaryValue value = new ClientBinaryValue( val );
+            removed &= values.remove( value );
+        }
+        
+        return removed;
+    }
+
+
+    /**
+     * @see EntryAttribute#remove(String)
+     */
+    public boolean remove( String val )
+    {
+        ClientStringValue ssv = new ClientStringValue( val );
+        return values.remove( ssv );
+    }
+
+
+    /**
+     * @see EntryAttribute#remove(String...)
+     */
+    public boolean remove( String... vals )
+    {
+        boolean removed = true;
+        
+        for ( String val:vals )
+        {
+            ClientStringValue value = new ClientStringValue( val );
+            removed &= values.remove( value );
+        }
+        
+        return removed;
+    }
+
+
+    /**
+     * An iterator on top of the stored values.
+     * 
+     * @return an iterator over the stored values.
+     */
+    public Iterator<ClientValue<?>> iterator()
+    {
+        return values.iterator();
+    }
+}

Added: 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=609459&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientBinaryValue.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientBinaryValue.java Sun Jan  6 14:58:12 2008
@@ -0,0 +1,321 @@
+/*
+ * 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 org.apache.directory.shared.ldap.NotImplementedException;
+import org.apache.directory.shared.ldap.entry.AbstractBinaryValue;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.MatchingRule;
+import org.apache.directory.shared.ldap.schema.Normalizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.NamingException;
+import java.util.Arrays;
+import java.util.Comparator;
+
+
+/**
+ * A server side schema aware wrapper around a binary attribute value.
+ * This value wrapper uses schema information to syntax check values,
+ * and to compare them for equality and ordering.  It caches results
+ * and invalidates them when the wrapped value changes.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ClientBinaryValue extends AbstractBinaryValue implements ClientValue<byte[]>, Cloneable
+{
+    /** logger for reporting errors that might not be handled properly upstream */
+    private static final Logger LOG = LoggerFactory.getLogger( ClientBinaryValue.class );
+
+    /** the canonical representation of the wrapped binary value */
+    private transient byte[] normalizedValue;
+
+    /** cached results of the isValid() method call */
+    private transient Boolean valid;
+
+
+    /**
+     * Creates a ServerBinaryValue without an initial wrapped value.
+     *
+     * @param attributeType the schema type associated with this ServerBinaryValue
+     */
+    public ClientBinaryValue()
+    {
+    }
+
+
+    /**
+     * Creates a ServerBinaryValue with an initial wrapped binary value.
+     *
+     * @param attributeType the schema type associated with this ServerBinaryValue
+     * @param wrapped the binary value to wrap which may be null, or a zero length byte array
+     */
+    public ClientBinaryValue( byte[] wrapped )
+    {
+        super.set( wrapped );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Value<String> Methods
+    // -----------------------------------------------------------------------
+
+
+    /**
+     * Sets the wrapped binary 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
+     * recomputed to be correct with different values.
+     *
+     * @see ServerValue#set(Object)
+     */
+    public final void set( byte[] wrapped )
+    {
+        // Why should we invalidate the normalized value if it's we're setting the
+        // wrapper to it's current value?
+        byte[] value = getReference();
+        
+        if ( value != null )
+        {
+            if ( Arrays.equals( wrapped, value ) )
+            {
+                return;
+            }
+        }
+
+        normalizedValue = null;
+        valid = null;
+        super.set( wrapped );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // ServerValue<String> Methods
+    // -----------------------------------------------------------------------
+
+
+    /**
+     * Gets the normalized (cannonical) 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
+     * 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 a reference to the normalized version of the wrapped value
+     * @throws NamingException with failures to normalize
+     */
+    public byte[] getNormalizedReference() throws NamingException
+    {
+        if ( isNull() )
+        {
+            return null;
+        }
+
+        if ( normalizedValue == null )
+        {
+        }
+
+        return normalizedValue;
+    }
+
+
+    /**
+     * Gets a direct reference to the normalized representation for the
+     * wrapped value of this ServerValue wrapper. Implementations will most
+     * likely leverage the attributeType this value is associated with to
+     * determine how to properly normalize the wrapped value.
+     *
+     * @return the normalized version of the wrapped value
+     * @throws NamingException if schema entity resolution fails or normalization fails
+     */
+    public byte[] getNormalizedCopy() throws NamingException
+    {
+        if ( normalizedValue == null )
+        {
+            getNormalizedReference();
+        }
+
+        byte[] copy = new byte[ normalizedValue.length ];
+        System.arraycopy( normalizedValue, 0, copy, 0, normalizedValue.length );
+        return copy;
+    }
+
+
+    /**
+     * 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.
+     *
+     * @see ServerValue#isValid()
+     */
+    public final boolean isValid() throws NamingException
+    {
+        if ( valid != null )
+        {
+            return valid;
+        }
+
+        return valid;
+    }
+
+
+    /**
+     *
+     * @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<byte[]> value )
+    {
+        if ( isNull() )
+        {
+            if ( ( value == null ) || value.isNull() )
+            {
+                return 0;
+            }
+            else
+            {
+                return -1;
+            }
+        }
+        else
+        {
+            if ( ( value == null ) || value.isNull() ) 
+            {
+                return 1;
+            }
+        }
+
+        if ( value instanceof ClientBinaryValue )
+        {
+            ClientBinaryValue binaryValue = ( ClientBinaryValue ) value;
+        }
+
+        throw new NotImplementedException( "I don't really know how to compare anything other " +
+                "than ServerBinaryValues at this point in time." );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Object Methods
+    // -----------------------------------------------------------------------
+
+
+    /**
+     * @see Object#hashCode()
+     * @throws IllegalStateException on failures to extract the comparator, or the
+     * normalizers needed to perform the required comparisons based on the schema
+     */
+    public int hashCode()
+    {
+        // return zero if the value is null so only one null value can be
+        // stored in an attribute - the string version does the same
+        if ( isNull() )
+        {
+            return 0;
+        }
+
+        try
+        {
+            return Arrays.hashCode( getNormalizedReference() );
+        }
+        catch ( NamingException e )
+        {
+            String msg = "Failed to normalize \"" + toString() + "\" while trying to get hashCode()";
+            LOG.error( msg, e );
+            throw new IllegalStateException( msg, e );
+        }
+    }
+
+
+    /**
+     * Checks to see if this ServerBinaryValue equals the supplied object.
+     *
+     * This equals implementation overrides the BinaryValue 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
+     */
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+
+        if ( ! ( obj instanceof ClientBinaryValue ) )
+        {
+            return false;
+        }
+
+        ClientBinaryValue other = ( ClientBinaryValue ) obj;
+        
+        if ( isNull() && other.isNull() )
+        {
+            return true;
+        }
+
+        if ( isNull() != other.isNull() )
+        {
+            return false;
+        }
+
+        // now unlike regular values we have to compare the normalized values
+        try
+        {
+            return Arrays.equals( getNormalizedReference(), other.getNormalizedReference() );
+        }
+        catch ( NamingException e )
+        {
+            // 1st this is a warning because we're recovering from it and secondly
+            // we build big string since waste is not an issue when exception handling
+            LOG.warn( "Failed to get normalized value while trying to compare StringValues: "
+                    + toString() + " and " + other.toString() , e );
+
+            // recover by comparing non-normalized values
+            return Arrays.equals( getReference(), other.getReference() );
+        }
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Private Helper Methods (might be put into abstract base class)
+    // -----------------------------------------------------------------------
+    /**
+     * @return a copy of the current value
+     */
+    public ClientBinaryValue clone()
+    {
+        ClientBinaryValue clone = (ClientBinaryValue)super.clone();
+        
+        if ( normalizedValue != null )
+        {
+            clone.normalizedValue = new byte[ normalizedValue.length ];
+            System.arraycopy( normalizedValue, 0, clone.normalizedValue, 0, normalizedValue.length );
+        }
+        
+        return clone;
+    }
+}
\ No newline at end of file

Added: 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=609459&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientStringValue.java Sun Jan  6 14:58:12 2008
@@ -0,0 +1,281 @@
+/*
+ * 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 org.apache.directory.shared.ldap.NotImplementedException;
+import org.apache.directory.shared.ldap.entry.AbstractStringValue;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.MatchingRule;
+import org.apache.directory.shared.ldap.schema.Normalizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.NamingException;
+import java.util.Comparator;
+
+
+/**
+ * A server side schema aware wrapper around a String attribute value.
+ * This value wrapper uses schema information to syntax check values,
+ * and to compare them for equality and ordering.  It caches results
+ * and invalidates them when the wrapped value changes.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ClientStringValue extends AbstractStringValue implements ClientValue<String>, Cloneable
+{
+    /** 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;
+
+
+    /**
+     * Creates a ServerStringValue without an initial wrapped value.
+     */
+    public ClientStringValue()
+    {
+    }
+
+
+    /**
+     * Creates a ServerStringValue with an initial wrapped String value.
+     *
+     * @param wrapped the value to wrap which can be null
+     */
+    public ClientStringValue( String wrapped )
+    {
+        super.set( wrapped );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Value<String> Methods
+    // -----------------------------------------------------------------------
+
+
+    /**
+     * 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
+     * recomputed to be correct with different values.
+     *
+     * @see ServerValue#set(Object)
+     */
+    public final void set( String wrapped )
+    {
+        // Why should we invalidate the normalized value if it's we're setting the
+        // wrapper to it's current value?
+        if ( wrapped.equals( get() ) )
+        {
+            return;
+        }
+
+        normalizedValue = null;
+        valid = null;
+        super.set( wrapped );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // ServerValue<String> Methods
+    // -----------------------------------------------------------------------
+
+
+    /**
+     * Gets the normalized (cannonical) 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
+     * 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
+    {
+        if ( isNull() )
+        {
+            return null;
+        }
+
+        if ( normalizedValue == null )
+        {
+        }
+
+        return normalizedValue;
+    }
+
+
+    /**
+     * 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.
+     *
+     * @see ServerValue#isValid()
+     */
+    public final boolean isValid() throws NamingException
+    {
+        if ( valid != null )
+        {
+            return valid;
+        }
+
+        return valid;
+    }
+
+
+    /**
+     * @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 )
+    {
+        if ( isNull() )
+        {
+            if ( ( value == null ) || value.isNull() )
+            {
+                return 0;
+            }
+            else
+            {
+                return -1;
+            }
+        }
+        else if ( ( value == null ) || value.isNull() )
+        {
+            return 1;
+        }
+
+        if ( value instanceof ClientStringValue )
+        {
+            ClientStringValue stringValue = ( ClientStringValue ) value;
+        }
+
+        throw new NotImplementedException( "I don't know what to do if value is not a ServerStringValue" );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Object Methods
+    // -----------------------------------------------------------------------
+
+
+    /**
+     * @see Object#hashCode()
+     * @throws IllegalStateException on failures to extract the comparator, or the
+     * normalizers needed to perform the required comparisons based on the schema
+     */
+    public int hashCode()
+    {
+        // return zero if the value is null so only one null value can be
+        // stored in an attribute - the binary version does the same 
+        if ( isNull() )
+        {
+            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 );
+        }
+    }
+
+
+    /**
+     * 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
+     */
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+
+        if ( ! ( obj instanceof ClientStringValue ) )
+        {
+            return false;
+        }
+
+        ClientStringValue other = ( ClientStringValue ) obj;
+        
+        if ( isNull() && other.isNull() )
+        {
+            return true;
+        }
+
+        if ( isNull() != other.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 );
+        }
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Private Helper Methods (might be put into abstract base class)
+    // -----------------------------------------------------------------------
+    /**
+     * @return a copy of the current value
+     */
+    public ClientStringValue clone()
+    {
+        try
+        {
+            return (ClientStringValue)super.clone();
+        }
+        catch ( CloneNotSupportedException cnse )
+        {
+            return null;
+        }
+    }
+}

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientValue.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientValue.java?rev=609459&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientValue.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/ClientValue.java Sun Jan  6 14:58:12 2008
@@ -0,0 +1,82 @@
+/*
+ * 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 org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+
+import javax.naming.NamingException;
+
+
+/**
+ * A server side entry value wrapper.  Server side value wrappers are
+ * schema aware, knowing the attributeType of the attributes which contain them,
+ * and hence they are capable of things like:
+ *
+ * <ul>
+ *   <li>producing, caching and invalidate normalized versions of their wrapped values</li>
+ *   <li>
+ *     determining if the wrapped value complies with the syntax of their associated
+ *     attributeType
+ *   </li>
+ *   <li>
+ *     comparing wrapped values on the basis of their cannonical representation which
+ *     utilizes the matchingRules of the attributeType associated with these server
+ *     side values
+ *   </li>
+ * </ul>
+ *
+ * These characteristics have a major impact on how these objects are treated in
+ * containers: compared (ordered), hashed, added, removed, and looked up. Furthermore
+ * a great advantage is gained in simplifying code which must deal with values based
+ * on their associated schema.  A large portion of the value managing code which is
+ * setup to compare and test values can now be avoided.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ClientValue<T> extends Value<T>, Comparable<ClientValue<T>>
+{
+    /**
+     * Checks to see if this ServerValue is valid according to the syntax
+     * of the ServerAttribute which contains it.
+     *
+     * @return true if valid according to syntax, false otherwise
+     * @throws NamingException if schema entity resolution fails or the syntaxChecker fails
+     */
+    boolean isValid() throws NamingException;
+
+
+    /**
+     * Compares two ServerValue objects for ordering based on the matchingRules
+     * associated with the ServerAttribute containing this ServerValue.
+     * Implementations should be using the normalized versions of the wrapped
+     * value when conducting comparisons.
+     *
+     * @param value the ServerValue object to compare this ServerValue to
+     * @return 0 if the objects are equivalent according to equals(), 1 or greater
+     * if this ServerValue is greater than the supplied ServerValue, -1 or lesser
+     * if this ServerValue is less than the supplied ServerValue.
+     */
+    int compareTo( ClientValue<T> value );
+
+
+    ClientValue<T> clone();
+}

Added: 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=609459&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/entry/client/DefaultClientAttribute.java Sun Jan  6 14:58:12 2008
@@ -0,0 +1,564 @@
+/*
+ * 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 org.apache.directory.shared.ldap.entry.AbstractBinaryValue;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.AbstractStringValue;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.NamingException;
+import javax.naming.directory.InvalidAttributeValueException;
+
+import java.util.Iterator;
+
+
+/**
+ * A server side entry attribute aware of schema.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public final class DefaultClientAttribute extends AbstractClientAttribute
+{
+    /** logger for reporting errors that might not be handled properly upstream */
+    private static final Logger LOG = LoggerFactory.getLogger( DefaultClientAttribute.class );
+    
+    
+    // maybe have some additional convenience constructors which take
+    // an initial value as a string or a byte[]
+    /**
+     * Create a new instance of a EntryAttribute, without ID nor value.
+     */
+    public DefaultClientAttribute()
+    {
+    }
+
+
+    /**
+     * Create a new instance of a EntryAttribute, without value.
+     */
+    public DefaultClientAttribute( String upId )
+    {
+        setUpId( upId );
+    }
+
+
+    /**
+     * 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.
+     * 
+     * Otherwise, the value is stored, but as a reference. It's not a copy.
+     *
+     * @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
+    {
+        // The value can be null, this is a valid value.
+        if ( vals[0] == null )
+        {
+             add( new ClientStringValue() );
+        }
+        else
+        {
+            for ( ClientValue<?> val:vals )
+            {
+                if ( val instanceof ClientStringValue )
+                {
+                    ClientStringValue serverString = ( ClientStringValue ) val;
+                    add( new ClientStringValue( serverString.get() ) );
+                }
+                else if ( val instanceof ClientBinaryValue )
+                {
+                    ClientBinaryValue serverBinary = ( ClientBinaryValue ) val;
+                    add( new ClientBinaryValue( serverBinary.getCopy() ) );
+                }
+                else
+                {
+                    String message = "Unknown value type: " + val.getClass().getName();
+                    LOG.error( message );
+                    throw new IllegalStateException( message );
+                }
+            }
+        }
+        
+        setUpId( upId );
+    }
+
+
+    /**
+     * Create a new instance of a EntryAttribute, without ID but with some values.
+     */
+    public DefaultClientAttribute( String... vals ) throws NamingException
+    {
+        this( null, vals );
+    }
+
+
+    /**
+     * Create a new instance of a EntryAttribute.
+     */
+    public DefaultClientAttribute( String upId, String... vals ) throws NamingException
+    {
+        add( vals );
+        setUpId( upId );
+    }
+
+
+    /**
+     * Create a new instance of a EntryAttribute, with some byte[] values.
+     */
+    public DefaultClientAttribute( byte[]... vals ) throws NamingException
+    {
+        this( null, vals );
+    }
+
+
+    /**
+     * Create a new instance of a EntryAttribute, with some byte[] values.
+     */
+    public DefaultClientAttribute( String upId, byte[]... vals ) throws NamingException
+    {
+        add( vals );
+        setUpId( upId );
+    }
+
+
+    /**
+     * 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
+     * provides "COMMONname" instead when adding the entry then this is
+     * the format the user will have that entry returned by the directory
+     * server.  To do so we store this value as it was given and track it
+     * in the attribute using this property.
+     *
+     * @return the user provided identifier for this attribute
+     */
+    public String getUpId()
+    {
+        return upId;
+    }
+
+
+    /**
+     * 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 isValid() throws NamingException
+    {
+        for ( ClientValue<?> value : values )
+        {
+            if ( ! value.isValid() )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    /**
+     * @see EntryAttribute#add(org.apache.directory.shared.ldap.entry.Value)
+     */
+    public boolean add( ClientValue<?> val ) throws InvalidAttributeValueException, NamingException
+    {
+        if ( val == null )
+        {
+            ClientValue<String> nullSV = new ClientStringValue( (String)null );
+            
+            if ( values.contains( nullSV ) )
+            {
+                return false;
+            }
+            else
+            {
+                values.add( nullSV );
+                return true;
+            }
+        }
+
+        if ( values.contains( val ) )
+        {
+            return false;
+        }
+        
+        return values.add( val );
+    }
+
+
+    /**
+     * @see EntryAttribute#add(org.apache.directory.shared.ldap.entry.Value...)
+     */
+    public int add( ClientValue<?>... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        int nbAdded = 0;
+        
+        for ( ClientValue<?> val:vals )
+        {
+            if ( add( val ) )
+            {
+                nbAdded ++;
+            }
+        }
+        
+        return nbAdded;
+    }
+
+
+    /**
+     * @see EntryAttribute#add(String)
+     */
+    public boolean add( String val ) throws InvalidAttributeValueException, NamingException
+    {
+        return add( new ClientStringValue( val ) );
+    }
+
+
+    /**
+     * @see EntryAttribute#add(String...)
+     */
+    public int add( String... vals ) throws NamingException
+    {
+        int nbAdded = 0;
+        
+        for ( String val:vals )
+        {
+            if ( add( val ) )
+            {
+                nbAdded ++;
+            }
+        }
+        
+        return nbAdded;
+    }    
+    
+    
+    /**
+     * @see EntryAttribute#add(byte[])
+     */
+    public boolean add( byte[] val ) throws InvalidAttributeValueException, NamingException
+    {
+        return add( new ClientBinaryValue( val ) );
+    }
+
+    
+    /**
+     * @see EntryAttribute#add(byte[]...)
+     */
+    public int add( byte[]... vals ) throws InvalidAttributeValueException, NamingException
+    {
+        int nbAdded = 0;
+        
+        for ( byte[] val:vals )
+        {
+            if ( add( val ) )
+            {
+                nbAdded ++;
+            }
+        }
+        
+        return nbAdded;
+    }    
+    
+    
+    /**
+     * Remove all the values from this attribute type, including a 
+     * null value. 
+     */
+    public void clear()
+    {
+        values.clear();
+    }
+
+
+    /**
+     * @see EntryAttribute#contains(org.apache.directory.shared.ldap.entry.Value)
+     */
+    public boolean contains( ClientValue<?> val )
+    {
+        return values.contains( val );
+    }
+
+
+    /**
+     * @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 ( !values.contains( val ) )
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+
+
+    /**
+     * @see EntryAttribute#contains(String)
+     */
+    public boolean contains( String val )
+    {
+        ClientStringValue value = new ClientStringValue( val );
+        
+        return values.contains( value );
+    }
+
+
+    /**
+     * @see EntryAttribute#contains(String...)
+     */
+    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 ( !contains( val ) )
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    
+    /**
+     * @see EntryAttribute#contains(byte[])
+     */
+    public boolean contains( byte[] val )
+    {
+        ClientBinaryValue sbv = new ClientBinaryValue( val );
+        return values.contains( sbv );
+    }
+
+
+    /**
+     * @see EntryAttribute#contains(byte[]...)
+     */
+    public boolean contains( byte[]... vals )
+    {
+        // Iterate through all the values, and quit if we 
+        // don't find one in the values
+        for ( byte[] val:vals )
+        {
+            if ( !contains( val ) )
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    
+    /**
+     * 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.
+     * 
+     *  @return The first value for this attribute.
+     */
+    public ClientValue<?> get()
+    {
+        if ( values.isEmpty() )
+        {
+            return null;
+        }
+        
+        return values.iterator().next();
+    }
+
+
+    /**
+     * Get all the stored values.
+     * 
+     * @return An iterator over the values stored into the attribute
+     */
+    public Iterator<ClientValue<?>> 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.
+     */
+    public int size()
+    {
+        return values.size();
+    }
+
+
+    /**
+     * @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...)
+     */
+    public boolean remove( ClientValue<?>... vals )
+    {
+        boolean removed = false;
+        
+        // Loop through all the values to remove. If one of
+        // them is not present, the method will return false.
+        for ( ClientValue<?> val:vals )
+        {
+            removed &= values.remove( val );
+        }
+        
+        return removed;
+    }
+
+
+    /**
+     * @see EntryAttribute#remove(byte[])
+     */
+    public boolean remove( byte[] val )
+    {
+        ClientBinaryValue sbv = new ClientBinaryValue( val );
+        return values.remove( sbv );
+    }
+
+
+    /**
+     * @see EntryAttribute#remove(byte[]...)
+     */
+    public boolean remove( byte[]... vals )
+    {
+        boolean removed = true;
+        
+        for ( byte[] val:vals )
+        {
+            ClientBinaryValue value = new ClientBinaryValue( val );
+            removed &= values.remove( value );
+        }
+        
+        return removed;
+    }
+
+
+    /**
+     * @see EntryAttribute#remove(String)
+     */
+    public boolean remove( String val )
+    {
+        ClientStringValue ssv = new ClientStringValue( val );
+        return values.remove( ssv );
+    }
+
+
+    /**
+     * @see EntryAttribute#remove(String...)
+     */
+    public boolean remove( String... vals )
+    {
+        boolean removed = true;
+        
+        for ( String val:vals )
+        {
+            ClientStringValue value = new ClientStringValue( val );
+            removed &= values.remove( value );
+        }
+        
+        return removed;
+    }
+
+
+    /**
+     * An iterator on top of the stored values.
+     * 
+     * @return an iterator over the stored values.
+     */
+    public Iterator<ClientValue<?>> iterator()
+    {
+        return values.iterator();
+    }
+    
+    /**
+     * @see Object#toString() 
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        if ( ( values != null ) && ( values.size() != 0 ) )
+        {
+            for ( ClientValue<?> value:values )
+            {
+                sb.append( "    " ).append( upId ).append( ": " ).append( value ).append( '\n' );
+            }
+        }
+        else
+        {
+            sb.append( "    " ).append( upId ).append( ": (null)\n" );
+        }
+        
+        return sb.toString();
+    }
+
+}

Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java Sun Jan  6 14:58:12 2008
@@ -20,14 +20,9 @@
 package org.apache.directory.shared.ldap.util;
 
 
-import org.apache.directory.shared.ldap.common.ServerAttribute;
-import org.apache.directory.shared.ldap.common.ServerAttributeImpl;
-import org.apache.directory.shared.ldap.common.ServerEntry;
-import org.apache.directory.shared.ldap.common.ServerEntryImpl;
 import org.apache.directory.shared.ldap.message.AttributeImpl;
 import org.apache.directory.shared.ldap.message.AttributesImpl;
 import org.apache.directory.shared.ldap.message.ModificationItemImpl;
-import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.schema.AttributeType;
 import org.apache.directory.shared.ldap.schema.MatchingRule;
 import org.apache.directory.shared.ldap.schema.NoOpNormalizer;
@@ -100,6 +95,11 @@
             return true;
         }
         
+        if ( value1 == null )
+        {
+            return ( value2 == null );
+        }
+        
         if ( value1 instanceof byte[] )
         {
             if ( value2 instanceof byte[] )
@@ -1122,68 +1122,6 @@
     {
         return toString( "", attributes );
     }
-    
-    
-    /**
-     * Convert a BasicAttribute or an AttributeImpl instance to a
-     * ServerAttribute instance
-     *
-     * @param attribute The attribute to convert
-     * @return A ServerAttributeImpl instance 
-     */
-    public static ServerAttribute convertAttribute( Attribute attribute ) throws NamingException
-    {
-        assert( attribute != null );
-        
-        ServerAttribute serverAttribute = new ServerAttributeImpl( attribute.getID() );
-        NamingEnumeration<?> values = attribute.getAll();
-        
-        while ( values.hasMoreElements() )
-        {
-            Object value = values.nextElement();
-            
-            if ( value instanceof String )
-            {
-                serverAttribute.add( (String)value );
-            }
-            else if ( value instanceof byte[] )
-            {
-                serverAttribute.add( (byte[])value );
-            }
-            else
-            {
-                serverAttribute.add( (String)null );
-            }
-        }
-        
-        return serverAttribute;
-    }
-    
-    
-    /**
-     * Convert an instance of Attributes to an instance of ServerEntry
-     *
-     * @param attributes The instance to convert
-     * @return An instance of ServerEntryImpl
-     */
-    public static ServerEntry convertEntry( LdapDN dn, Attributes attributes ) throws NamingException
-    {
-        assert( dn != null );
-        assert( attributes != null );
-        
-        ServerEntry serverEntry = new ServerEntryImpl( dn );
-        
-        NamingEnumeration<? extends Attribute> attrs = attributes.getAll();
-        
-        while ( attrs.hasMoreElements() )
-        {
-            Attribute attribute = attrs.nextElement();
-            serverEntry.put( convertAttribute( attribute ) );
-        }
-        
-        return serverEntry;
-    }
-
 
 
     /**

Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java Sun Jan  6 14:58:12 2008
@@ -624,6 +624,11 @@
      */
     public static final String toLowerCase( String value )
     {
+        if ( ( null == value ) || ( value.length() == 0 ) )
+        {
+            return "";
+        }
+        
         char[] chars = value.toCharArray();
         
         for ( int i = 0; i < chars.length; i++ )
@@ -644,6 +649,11 @@
      */
     public static final String toUpperCase( String value )
     {
+        if ( ( null == value ) || ( value.length() == 0 ) )
+        {
+            return "";
+        }
+        
         char[] chars = value.toCharArray();
         
         for ( int i = 0; i < chars.length; i++ )

Modified: directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java?rev=609459&r1=609458&r2=609459&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java (original)
+++ directory/shared/branches/bigbang/ldap/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java Sun Jan  6 14:58:12 2008
@@ -53,7 +53,7 @@
     {
         File jpeg = File.createTempFile( name, "jpg" );
         
-	jpeg.createNewFile();
+        jpeg.createNewFile();
 
         DataOutputStream os = new DataOutputStream( new FileOutputStream( jpeg ) );
 



Mime
View raw message