You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2006/08/02 01:35:23 UTC

svn commit: r427793 [3/6] - in /directory/branches/shared/0.9.5: asn1/src/main/java/org/apache/directory/shared/asn1/ber/ asn1/src/main/java/org/apache/directory/shared/asn1/ber/grammar/ ldap/ ldap/src/main/antlr/ ldap/src/main/java/org/apache/director...

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/message/LockableAttributesImpl.java Tue Aug  1 16:35:20 2006
@@ -17,16 +17,18 @@
 package org.apache.directory.shared.ldap.message;
 
 
+import java.io.Serializable;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
 
-import javax.naming.NamingException;
 import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
 
-import org.apache.directory.shared.ldap.util.ExceptionUtils;
+import org.apache.directory.shared.ldap.util.StringTools;
 
 
 /**
@@ -35,13 +37,108 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class LockableAttributesImpl implements Attributes
+public class LockableAttributesImpl implements Attributes, Serializable
 {
-    static final long serialVersionUID = -69864533495992471L;
-
-    /** Map of user provided String ids to Attributes */
-    private final Map map = new HashMap();
+    static transient final long serialVersionUID = -69864533495992471L;
 
+    /**
+     * An holder to store <Id, Attribute> couples
+     * 
+     */
+    private class Holder implements Serializable, Cloneable
+	{
+    	static transient final long serialVersionUID = 1L;
+    	
+		private String upId;
+		private Attribute attribute;
+		
+		private Holder( String upId, Attribute attribute )
+		{
+			this.upId = upId;
+			this.attribute = attribute;
+		}
+		
+		public Object clone() throws CloneNotSupportedException
+		{
+			Holder clone = (Holder)super.clone();
+			
+			clone.upId = upId;
+			clone.attribute = (Attribute)attribute.clone();
+			
+			return clone;
+		}
+		
+		public String toString()
+		{
+			StringBuffer sb = new StringBuffer();
+			
+			sb.append( upId ).append( ": " );
+			
+			sb.append( attribute ).append( '\n' );
+			
+			return sb.toString();
+		}
+	}
+	
+    /**
+     * An iterator which returns Attributes.  
+     */
+	public class AttributeIterator implements Iterator
+	{
+		private Iterator iterator; 
+		
+		private AttributeIterator( LockableAttributesImpl attributes )
+		{
+			iterator = attributes.keyMap.values().iterator();
+		}
+		
+	    /**
+	     * Returns <tt>true</tt> if the iteration has more elements. (In other
+	     * words, returns <tt>true</tt> if <tt>next</tt> would return an element
+	     * rather than throwing an exception.)
+	     *
+	     * @return <tt>true</tt> if the iterator has more elements.
+	     */
+	    public boolean hasNext()
+	    {
+	    	return iterator.hasNext();
+	    }
+
+	    /**
+	     * Returns the next element in the iteration.  Calling this method
+	     * repeatedly until the {@link #hasNext()} method returns false will
+	     * return each element in the underlying collection exactly once.
+	     *
+	     * @return the next element in the iteration.
+	     * @exception NoSuchElementException iteration has no more elements.
+	     */
+	    public Object next()
+	    {
+	    	return ((Holder)iterator.next()).attribute;
+	    }
+
+	    /**
+	     * 
+	     * Removes from the underlying collection the last element returned by the
+	     * iterator (optional operation).  This method can be called only once per
+	     * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
+	     * the underlying collection is modified while the iteration is in
+	     * progress in any way other than by calling this method.
+	     *
+	     * @exception UnsupportedOperationException if the <tt>remove</tt>
+	     *		  operation is not supported by this Iterator.
+	     
+	     * @exception IllegalStateException if the <tt>next</tt> method has not
+	     *		  yet been called, or the <tt>remove</tt> method has already
+	     *		  been called after the last call to the <tt>next</tt>
+	     *		  method.
+	     */
+	    public void remove()
+	    {
+	    	iterator.remove();
+	    }
+	}
+	
     /** Cache of lowercase id Strings to mixed cased user provided String ids */
     private Map keyMap;
 
@@ -58,32 +155,87 @@
         keyMap = new HashMap();
     }
 
-
-    /**
-     * Used by clone to create a LockableAttributes.
-     * 
-     * @param map
-     *            the primary user provided id to Attribute Map
-     * @param keyMap
-     *            the canonical key to user provided id Map
-     */
-    private LockableAttributesImpl(Map map, Map keyMap)
+    // ------------------------------------------------------------------------
+    // Serialization methods
+    //
+    // We will try to minimize the cost of reading and writing objects to the 
+    // disk.
+    //
+    // We need to save all the attributes stored into the 'map' object, and 
+    // their associated User Provided value.
+    // Attributes are stored following this pattern :
+    //  ( attributeType = (attribute value )* )*
+    //
+    // The streamed value will looks like :
+    // [nbAttrs:int]
+    //   (
+    //		[length attributeType(i):int] [attributeType(i):String] 
+    //		[length attributeTypeUP(i):int] [attributeTypeUP(i):String]
+    //		[attributeValues(i)]
+    //	 )*
+    //
+    // The attribute value is streamed by the LockableAttributeImpl class.
+    // ------------------------------------------------------------------------
+    /*public void readObject( ObjectInputStream oi ) throws IOException, ClassNotFoundException
     {
-        this.keyMap = new HashMap();
-
-        if ( keyMap != null )
-        {
-            this.keyMap.putAll( keyMap );
-        }
-
-        Iterator list = map.values().iterator();
-        while ( list.hasNext() )
-        {
-            Attribute attr = ( Attribute ) list.next();
-            this.map.put( attr.getID(), attr.clone() );
-        }
-    }
-
+    	oi.defaultReadObject();
+    	
+    	// Read the map size
+    	int size = oi.readInt();
+    	
+    	keyMap = new HashMap( size );
+    	
+    	for ( int i = 0; i < size(); i++ )
+    	{
+    		int keySize = oi.readInt();
+    		char[] keyChars = new char[keySize];
+    		
+    		for ( int j = 0; j < keySize; j++)
+    		{
+    			keyChars[j] = oi.readChar();
+    		}
+    		
+    		String upId = new String( keyChars );
+    		String key = upId.toLowerCase();
+    		
+    		Attribute attribute = (LockableAttributeImpl)oi.readObject();
+    		
+    		Holder holder = new Holder( upId, attribute);
+    		
+    		keyMap.put( key, holder );
+    	}
+    }*/
+
+    /**
+     * Write the Attribute to a stream
+     */
+    /*private void writeObject( ObjectOutputStream oo ) throws IOException
+    {
+    	oo.defaultWriteObject();
+    	
+    	// Write the map size
+    	oo.write( keyMap.size() );
+    	
+    	Iterator keys = keyMap.keySet().iterator(); 
+    	
+    	while ( keys.hasNext() )
+    	{
+    		String key = (String)keys.next();
+    		Holder holder = (Holder)keyMap.get( key );
+
+    		// Write the userProvided key
+    		// No need to write the key, it will be
+    		// rebuilt by the read operation
+    		oo.write( holder.upId.length() );
+    		oo.writeChars( holder.upId );
+    		
+    		// Recursively call the writeExternal metho
+    		// of the attribute object
+    		oo.writeObject( holder.attribute );
+    	}
+    	
+    	// That's it !
+    }*/
 
     // ------------------------------------------------------------------------
     // javax.naming.directory.Attributes Interface Method Implementations
@@ -108,7 +260,7 @@
      */
     public int size()
     {
-        return map.size();
+        return keyMap.size();
     }
 
 
@@ -126,14 +278,15 @@
      */
     public Attribute get( String attrId )
     {
-        String key = getUserProvidedId( attrId );
-
-        if ( key == null )
-        {
-            return null;
-        }
-
-        return ( Attribute ) map.get( key );
+    	if ( attrId != null )
+    	{
+    		Holder holder = (Holder)keyMap.get( StringTools.toLowerCase( attrId ) );
+    		return holder != null ? holder.attribute : null;
+    	}
+    	else
+    	{
+    		return null;
+    	}
     }
 
 
@@ -149,7 +302,7 @@
      */
     public NamingEnumeration getAll()
     {
-        return new IteratorNamingEnumeration( map.values().iterator() );
+        return new IteratorNamingEnumeration( new AttributeIterator( this ) );
     }
 
 
@@ -165,7 +318,17 @@
      */
     public NamingEnumeration getIDs()
     {
-        return new ArrayNamingEnumeration( map.keySet().toArray() );
+    	String[] ids = new String[keyMap.size()];
+    	
+    	Iterator values = keyMap.values().iterator();
+    	int i = 0;
+    	
+    	while ( values.hasNext() )
+    	{
+    		ids[i++] = ((Holder)values.next()).upId;
+    	}
+    	
+        return new ArrayNamingEnumeration( ids );
     }
 
 
@@ -185,14 +348,11 @@
      */
     public Attribute put( String attrId, Object val )
     {
-        if ( get( attrId ) == null )
-        {
-            setUserProvidedId( attrId );
-        }
-
         Attribute attr = new LockableAttributeImpl( attrId );
         attr.add( val );
-        map.put( attrId, attr );
+        
+        String key = StringTools.toLowerCase( attrId );
+        keyMap.put( key, new Holder( attrId, attr) );
         return attr;
     }
 
@@ -205,25 +365,45 @@
      *            the character case of its attribute ids, the case of attr's
      *            identifier is ignored.
      * @return The Attribute with the same ID as attr that was previous in this
-     *         attribute set; null if no such attribute existed.
+     *         attribute set; The new attr if no such attribute existed.
      * @see #remove
      */
     public Attribute put( Attribute attr )
     {
-        Attribute old = get( attr.getID() );
-
-        if ( old != null )
-        {
-            map.remove( old.getID() );
-
-            if ( keyMap != null )
-            {
-                keyMap.remove( old.getID().toLowerCase() );
-            }
+    	String key = StringTools.toLowerCase( attr.getID() );
+    	Attribute old = null;
+    	Attribute newAttr = attr;
+    	
+        if ( keyMap.containsKey( key ) )
+        {
+            old = (Attribute)((Holder)keyMap.remove( key )).attribute;
+        }
+        else
+        {
+        	old = attr;
+        }
+
+        if ( attr instanceof BasicAttribute )
+        {
+        	 newAttr = new LockableAttributeImpl( attr.getID() );
+        	 
+        	 try
+        	 {
+	        	 NamingEnumeration values = attr.getAll();
+	        	 
+	        	 while ( values.hasMore() )
+	        	 {
+	        		 Object value = values.next();
+	        		 newAttr.add( value );
+	        	 }
+        	 }
+        	 catch ( NamingException ne )
+        	 {
+        		 // do nothing
+        	 }
         }
-
-        map.put( attr.getID(), attr );
-        setUserProvidedId( attr.getID() );
+        
+        keyMap.put( key, new Holder( attr.getID(), newAttr ) );
         return old;
     }
 
@@ -241,16 +421,17 @@
      */
     public Attribute remove( String attrId )
     {
-        Attribute old = get( attrId );
-
-        if ( old != null )
-        {
-            map.remove( old.getID() );
-
-            if ( keyMap != null )
-            {
-                keyMap.remove( old.getID().toLowerCase() );
-            }
+    	String key = StringTools.toLowerCase( attrId );
+    	Attribute old = null;
+    	
+        if ( keyMap.containsKey( key ) )
+        {
+        	Holder holder = (Holder)keyMap.remove( key );
+        	
+        	if ( holder != null ) 
+        	{
+        		old = holder.attribute;
+        	}
         }
 
         return old;
@@ -265,7 +446,27 @@
      */
     public Object clone()
     {
-        return new LockableAttributesImpl( map, keyMap );
+    	try
+    	{
+	    	LockableAttributesImpl clone = (LockableAttributesImpl)super.clone();
+	
+			clone.keyMap = (Map)((HashMap)keyMap).clone();
+			
+	        Iterator keys = keyMap.keySet().iterator();
+	
+	        while ( keys.hasNext() )
+	        {
+	        	String key = (String)keys.next();
+	        	Holder holder = (Holder)keyMap.get( key );
+	            clone.keyMap.put( key, holder.clone() );
+	        }
+	    	
+	        return clone;
+    	}
+    	catch ( CloneNotSupportedException cnse )
+    	{
+    		return null;
+    	}
     }
 
 
@@ -278,27 +479,16 @@
     {
         StringBuffer buf = new StringBuffer();
 
-        Iterator attrs = map.values().iterator();
+        Iterator attrs = keyMap.values().iterator();
+        
         while ( attrs.hasNext() )
         {
-            Attribute l_attr = ( Attribute ) attrs.next();
+        	Holder holder = (Holder)attrs.next();
+            Attribute attr = holder.attribute;
 
-            try
-            {
-                NamingEnumeration l_values = l_attr.getAll();
-                while ( l_values.hasMore() )
-                {
-                    Object l_value = l_values.next();
-                    buf.append( l_attr.getID() );
-                    buf.append( ": " );
-                    buf.append( l_value );
-                    buf.append( '\n' );
-                }
-            }
-            catch ( NamingException e )
-            {
-                buf.append( ExceptionUtils.getFullStackTrace( e ) );
-            }
+            buf.append( holder.upId );
+            buf.append( ": " );
+            buf.append( attr );
         }
 
         return buf.toString();
@@ -340,6 +530,7 @@
         }
 
         NamingEnumeration list = attrs.getAll();
+
         while ( list.hasMoreElements() )
         {
             Attribute attr = ( Attribute ) list.nextElement();
@@ -357,60 +548,5 @@
         }
 
         return true;
-    }
-
-
-    // ------------------------------------------------------------------------
-    // Utility Methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Sets the user provided key by normalizing it and adding a record into the
-     * keymap for future lookups.
-     * 
-     * @param userProvidedId
-     *            the id of the Attribute gotten from the attribute instance via
-     *            getID().
-     */
-    private void setUserProvidedId( String userProvidedId )
-    {
-        if ( keyMap == null )
-        {
-            keyMap = new HashMap();
-            keyMap.put( userProvidedId.toLowerCase(), userProvidedId );
-            return;
-        }
-
-        if ( keyMap.get( userProvidedId ) == null )
-        {
-            keyMap.put( userProvidedId.toLowerCase(), userProvidedId );
-        }
-    }
-
-
-    /**
-     * Gets the user provided key by looking it up using the normalized key in
-     * the key map.
-     * 
-     * @param attrId
-     *            the id of the Attribute in any case.
-     * @return the attribute id as it would be returned on a call to the
-     *         Attribute's getID() method.
-     */
-    private String getUserProvidedId( String attrId )
-    {
-        // First check if it is correct form to save string creation below.
-        if ( map.containsKey( attrId ) )
-        {
-            return attrId;
-        }
-
-        if ( keyMap == null )
-        {
-            keyMap = new HashMap();
-            return null;
-        }
-
-        return ( String ) keyMap.get( attrId.toLowerCase() );
     }
 }

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyDnResponseImpl.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyDnResponseImpl.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyDnResponseImpl.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/message/ModifyDnResponseImpl.java Tue Aug  1 16:35:20 2006
@@ -1,3 +1,19 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.message;
 
 

Propchange: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/NormalizerMappingResolver.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/NormalizerMappingResolver.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/NormalizerMappingResolver.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/NormalizerMappingResolver.java Tue Aug  1 16:35:20 2006
@@ -1,3 +1,19 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.schema;
 
 import java.util.Map;

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SchemaObject.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SchemaObject.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SchemaObject.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SchemaObject.java Tue Aug  1 16:35:20 2006
@@ -1,51 +1,18 @@
 /*
-
- ============================================================================
- The Apache Software License, Version 1.1
- ============================================================================
-
- Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modifica-
- tion, are permitted provided that the following conditions are met:
-
- 1. Redistributions of  source code must  retain the above copyright  notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- 3. The end-user documentation included with the redistribution, if any, must
- include  the following  acknowledgment:  "This product includes  software
- developed  by the  Apache Software Foundation  (http://www.apache.org/)."
- Alternately, this  acknowledgment may  appear in the software itself,  if
- and wherever such third-party acknowledgments normally appear.
-
- 4. The names "Eve Directory Server", "Apache Directory Project", "Apache Eve" 
- and "Apache Software Foundation"  must not be used to endorse or promote
- products derived  from this  software without  prior written
- permission. For written permission, please contact apache@apache.org.
-
- 5. Products  derived from this software may not  be called "Apache", nor may
- "Apache" appear  in their name,  without prior written permission  of the
- Apache Software Foundation.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
- APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
- DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
- ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
- (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- This software  consists of voluntary contributions made  by many individuals
- on  behalf of the Apache Software  Foundation. For more  information on the
- Apache Software Foundation, please see <http://www.apache.org/>.
-
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.schema;
 

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SyntaxChecker.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SyntaxChecker.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SyntaxChecker.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/schema/SyntaxChecker.java Tue Aug  1 16:35:20 2006
@@ -1,51 +1,18 @@
 /*
-
- ============================================================================
- The Apache Software License, Version 1.1
- ============================================================================
-
- Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modifica-
- tion, are permitted provided that the following conditions are met:
-
- 1. Redistributions of  source code must  retain the above copyright  notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- 3. The end-user documentation included with the redistribution, if any, must
- include  the following  acknowledgment:  "This product includes  software
- developed  by the  Apache Software Foundation  (http://www.apache.org/)."
- Alternately, this  acknowledgment may  appear in the software itself,  if
- and wherever such third-party acknowledgments normally appear.
-
- 4. The names "Eve Directory Server", "Apache Directory Project", "Apache Eve" 
- and "Apache Software Foundation"  must not be used to endorse or promote
- products derived  from this  software without  prior written
- permission. For written permission, please contact apache@apache.org.
-
- 5. Products  derived from this software may not  be called "Apache", nor may
- "Apache" appear  in their name,  without prior written permission  of the
- Apache Software Foundation.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
- APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
- DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
- ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
- (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- This software  consists of voluntary contributions made  by many individuals
- on  behalf of the Apache Software  Foundation. For more  information on the
- Apache Software Foundation, please see <http://www.apache.org/>.
-
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.schema;
 

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParser.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParser.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParser.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/SubtreeSpecificationParser.java Tue Aug  1 16:35:20 2006
@@ -20,6 +20,7 @@
 
 import java.io.StringReader;
 import java.text.ParseException;
+import java.util.Map;
 
 import org.apache.directory.shared.ldap.schema.NormalizerMappingResolver;
 
@@ -51,13 +52,13 @@
     /**
      * Creates a subtree specification parser.
      */
-    public SubtreeSpecificationParser()
+    public SubtreeSpecificationParser( Map oidsMap )
     {
         StringReader in = new StringReader( "" ); // place holder for the
                                                     // first input
         this.lexer = new ReusableAntlrSubtreeSpecificationLexer( in );
         this.parser = new ReusableAntlrSubtreeSpecificationParser( lexer );
-        this.parser.init(); // this method MUST be called while we cannot do
+        this.parser.init( oidsMap ); // this method MUST be called while we cannot do
         // constructor overloading for antlr generated parser
         this.isNormalizing = false;
     }
@@ -66,14 +67,14 @@
     /**
      * Creates a normalizing subtree specification parser.
      */
-    public SubtreeSpecificationParser( NormalizerMappingResolver resolver )
+    public SubtreeSpecificationParser( NormalizerMappingResolver resolver, Map oidsMap  )
     {
         StringReader in = new StringReader( "" ); // place holder for the
                                                     // first input
         this.lexer = new ReusableAntlrSubtreeSpecificationLexer( in );
         this.parser = new ReusableAntlrSubtreeSpecificationParser( lexer );
         this.parser.setNormalizerMappingResolver( resolver );
-        this.parser.init(); // this method MUST be called while we cannot do
+        this.parser.init( oidsMap ); // this method MUST be called while we cannot do
         // constructor overloading for antlr generated parser
         this.isNormalizing = true;
     }

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeUtils.java Tue Aug  1 16:35:20 2006
@@ -23,6 +23,7 @@
 
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
+import javax.naming.directory.ModificationItem;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 
@@ -35,7 +36,88 @@
  */
 public class AttributeUtils
 {
-    public static boolean containsValue( Attribute attr, Object compared, AttributeType type ) throws NamingException
+    /**
+     * Utility method to extract an attribute from Attributes object using
+     * all combinationos of the name including aliases.
+     * 
+     * @param attrs the Attributes to get the Attribute object from
+     * @param type the attribute type specification
+     * @return an Attribute with matching the attributeType spec or null
+     */
+    public final static Attribute getAttribute( Attributes attrs, AttributeType type )
+    {
+        // optimization bypass to avoid cost of the loop below
+        if ( type.getNames().length == 1 )
+        {
+            return attrs.get( type.getNames()[0] );
+        }
+        
+        // check if the attribute's OID is used
+        if ( attrs.get( type.getOid() ) != null )
+        {
+            return attrs.get( type.getOid() );
+        }
+        
+        // iterate through aliases
+        for ( int ii = 0; ii < type.getNames().length; ii++ )
+        {
+            if ( attrs.get( type.getNames()[ii] ) != null )
+            {
+                return attrs.get( type.getNames()[ii] );
+            }
+        }
+        
+        return null;
+    }
+    
+    
+    /**
+     * Utility method to extract an attribute from an array of modifications.
+     * 
+     * @param mods the array of ModificationItems to extract the Attribute from.
+     * @param type the attributeType spec of the Attribute to extract
+     * @return the extract Attribute or null if no such attribute exists
+     */
+    public final static Attribute getAttribute( ModificationItem[] mods, AttributeType type )
+    {
+        // optimization bypass to avoid cost of the loop below
+        if ( type.getNames().length == 1 )
+        {
+            for ( int jj = 0; jj < mods.length; jj++ )
+            {
+                if ( mods[jj].getAttribute().getID().equalsIgnoreCase( type.getNames()[0] ) )
+                {
+                    return mods[jj].getAttribute();
+                }
+            }
+        }
+        
+        // check if the attribute's OID is used
+        for ( int jj = 0; jj < mods.length; jj++ )
+        {
+            if ( mods[jj].getAttribute().getID().equals( type.getOid() ) )
+            {
+                return mods[jj].getAttribute();
+            }
+        }
+        
+        // iterate through aliases
+        for ( int ii = 0; ii < type.getNames().length; ii++ )
+        {
+            for ( int jj = 0; jj < mods.length; jj++ )
+            {
+                if ( mods[jj].getAttribute().getID().equalsIgnoreCase( type.getNames()[ii] ) )
+                {
+                    return mods[jj].getAttribute();
+                }
+            }
+        }
+        
+        return null;
+    }
+    
+    
+    public final static boolean containsValue( Attribute attr, Object compared, AttributeType type ) throws NamingException
     {
         // quick bypass test
         if ( attr.contains( compared ) )

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ComponentsMonitor.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ComponentsMonitor.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ComponentsMonitor.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ComponentsMonitor.java Tue Aug  1 16:35:20 2006
@@ -1,3 +1,19 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.util;
 
 

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java?rev=427793&r1=427792&r2=427793&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/DNUtils.java Tue Aug  1 16:35:20 2006
@@ -16,6 +16,9 @@
  */
 package org.apache.directory.shared.ldap.util;
 
+import org.apache.directory.shared.ldap.util.Position;
+import org.apache.directory.shared.ldap.util.StringTools;
+
 
 /**
  * Utility class used by the LdapDN Parser.
@@ -26,69 +29,151 @@
 {
     // ~ Static fields/initializers
     // -----------------------------------------------------------------
+    /** A value if we got an error while parsing */
+    public static final int PARSING_ERROR = -1;
+
+    /** A value if we got a correct parsing */
+    public static final int PARSING_OK = 0;
+
+    /** If an hex pair contains only one char, this value is returned */
+    public static final int BAD_HEX_PAIR = -2;
+
+    /** A constant representing one char length */
+    public static final int ONE_CHAR = 1;
+
+    /** A constant representing two chars length */
+    public static final int TWO_CHARS = 2;
+
+    /** A constant representing one byte length */
+    public static final int ONE_BYTE = 1;
+
+    /** A constant representing two bytes length */
+    public static final int TWO_BYTES = 2;
 
     /**
      * <safe-init-char> ::= [0x01-0x09] | 0x0B | 0x0C | [0x0E-0x1F] |
      * [0x21-0x39] | 0x3B | [0x3D-0x7F]
      */
     private static final boolean[] SAFE_INIT_CHAR =
-        { false, true, true, true, true, true, true, true, true, true, false, true, true, false, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, false, true, false, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true };
+        { 
+            false, true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  false, true,  true,  false, true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            false, true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  false, true,  false, true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true 
+        };
 
     /** <safe-char> ::= [0x01-0x09] | 0x0B | 0x0C | [0x0E-0x7F] */
     private static final boolean[] SAFE_CHAR =
-        { false, true, true, true, true, true, true, true, true, true, false, true, true, false, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true };
+        { 
+            false, true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  false, true,  true,  false, true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+        };
 
     /**
      * <base64-char> ::= 0x2B | 0x2F | [0x30-0x39] | 0x3D | [0x41-0x5A] |
      * [0x61-0x7A]
      */
     private static final boolean[] BASE64_CHAR =
-        { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
-            false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
-            false, false, false, false, false, false, false, false, false, false, false, false, false, true, false,
-            false, false, true, true, true, true, true, true, true, true, true, true, true, false, false, false, true,
-            false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false,
-            false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
-            true, true, true, true, true, true, true, true, true, true, false, false, false, false, false };
+        { 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, true,  false, false, false, true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  false, false, false, true,  false, false, 
+            false, true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  false, false, false, false, false,
+            false, true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  true,  false, false, false, false, false 
+        };
 
     /**
-     * '"' | '#' | '+' | ',' | [0-9] | ';' | '<' | '=' | '>' | [A-F] | '\' |
+     * ' ' | '"' | '#' | '+' | ',' | [0-9] | ';' | '<' | '=' | '>' | [A-F] | '\' |
      * [a-f] 0x22 | 0x23 | 0x2B | 0x2C | [0x30-0x39] | 0x3B | 0x3C | 0x3D | 0x3E |
      * [0x41-0x46] | 0x5C | [0x61-0x66]
      */
     private static final boolean[] PAIR_CHAR =
-        { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
-            false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
-            false, false, false, false, true, true, false, false, false, false, false, false, false, true, true, false,
-            false, false, true, true, true, true, true, true, true, true, true, true, false, true, true, true, true,
-            false, false, true, true, true, true, true, true, false, false, false, false, false, false, false, false,
-            false, false, false, false, false, false, false, false, false, false, false, false, false, true, false,
-            false, false, false, true, true, true, true, true, true, false, false, false, false, false, false, false,
-            false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
-            false, false, false };
+        { 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            true,  false, true,  true,  false, false, false, false, 
+            false, false, false, true,  true,  false, false, false, 
+            true,  true,  true,  true,  true,  true,  true,  true, 
+            true,  true,  false, true,  true,  true,  true,  false, 
+            false, true,  true,  true,  true,  true,  true,  false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, true,  false, false, false, 
+            false, true,  true,  true,  true,  true,  true,  false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false, 
+            false, false, false, false, false, false, false, false 
+        };
+
+    /**
+     * '"' | '#' | '+' | ',' | [0-9] | ';' | '<' | '=' | '>' | [A-F] | '\' |
+     * [a-f] 0x22 | 0x23 | 0x2B | 0x2C | [0x30-0x39] | 0x3B | 0x3C | 0x3D | 0x3E |
+     * [0x41-0x46] | 0x5C | [0x61-0x66]
+     */
+    private static final int[] STRING_CHAR =
+        { 
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 00 -> 03
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 04 -> 07
+            ONE_CHAR,      ONE_CHAR,      PARSING_ERROR, ONE_CHAR,     // 08 -> 0B
+            ONE_CHAR,      PARSING_ERROR, ONE_CHAR,      ONE_CHAR,     // 0C -> 0F
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 10 -> 13
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 14 -> 17
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 18 -> 1B
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 1C -> 1F
+            ONE_CHAR,      ONE_CHAR,      PARSING_ERROR, PARSING_ERROR,// 20 -> 23
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 24 -> 27
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      PARSING_ERROR,// 28 -> 2B
+            PARSING_ERROR, ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 2C -> 2F
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 30 -> 33
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      ONE_CHAR,     // 34 -> 37
+            ONE_CHAR,      ONE_CHAR,      ONE_CHAR,      PARSING_ERROR,// 38 -> 3B
+            PARSING_ERROR, PARSING_ERROR, PARSING_ERROR, ONE_CHAR      // 3C -> 3F
+        };
 
     /** "oid." static */
-    public static final char[] OID_LOWER = new char[]
-        { 'o', 'i', 'd', '.' };
+    public static final String OID_LOWER = "oid.";
 
     /** "OID." static */
-    public static final char[] OID_UPPER = new char[]
-        { 'O', 'I', 'D', '.' };
+    public static final String OID_UPPER = "OID.";
 
     /** "oid." static */
     public static final byte[] OID_LOWER_BYTES = new byte[]
@@ -98,23 +183,6 @@
     public static final byte[] OID_UPPER_BYTES = new byte[]
         { 'O', 'I', 'D', '.' };
 
-    /** A value if we got an error while parsing */
-    public static final int PARSING_ERROR = -1;
-
-    /** If an hex pair contains only one char, this value is returned */
-    public static final int BAD_HEX_PAIR = -2;
-
-    /** A constant representing one char length */
-    public static final int ONE_CHAR = 1;
-
-    /** A constant representing two chars length */
-    public static final int TWO_CHARS = 2;
-
-    /** A constant representing one byte length */
-    public static final int ONE_BYTE = 1;
-
-    /** A constant representing two bytes length */
-    public static final int TWO_BYTES = 2;
 
 
     // ~ Methods
@@ -308,6 +376,48 @@
         }
     }
 
+    /**
+     * Check if the current character is a Pair Char 
+     * 
+     * <pairchar> ::= ' ' | ',' | '=' | '+' | '<' | '>' | '#' | ';' | 
+     *                  '\' | '"' | [0-9a-fA-F] [0-9a-fA-F]
+     * 
+     * @param string
+     *            The string which contains the data
+     * @param index
+     *            Current position in the string
+     * @return <code>true</code> if the current character is a Pair Char
+     */
+    public static int isPairChar( String string, int index )
+    {
+        int length = string.length();
+        
+        if ( ( string == null ) || ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
+        {
+            return PARSING_ERROR;
+        }
+        else
+        {
+            char c = string.charAt( index );
+
+            if ( ( c > 127 ) || ( PAIR_CHAR[c] == false ) )
+            {
+                return PARSING_ERROR;
+            }
+            else
+            {
+                if ( StringTools.isHex( string, index++ ) )
+                {
+                    return StringTools.isHex( string, index ) ? 2 : PARSING_ERROR;
+                }
+                else
+                {
+                    return 1;
+                }
+            }
+        }
+    }
+
 
     /**
      * Check if the current character is a String Char. Chars are Unicode, not
@@ -330,10 +440,9 @@
         {
             byte c = byteArray[index];
 
-            if ( ( c == 0x0A ) || ( c == 0x0D ) || ( c == '"' ) || ( c == '#' ) || ( c == '+' ) || ( c == ',' )
-                || ( c == ';' ) || ( c == '<' ) || ( c == '=' ) || ( c == '>' ) )
+            if ( c < 0x40 )
             {
-                return -1;
+                return STRING_CHAR[ c ];
             }
             else
             {
@@ -376,6 +485,40 @@
         }
     }
 
+    /**
+     * Check if the current character is a String Char. Chars are Unicode, not
+     * ASCII. <stringchar> ::= [0x00-0xFFFF] - [,=+<>#;\"\n\r]
+     * 
+     * @param string
+     *            The string which contains the data
+     * @param index
+     *            Current position in the string
+     * @return The current char if it is a String Char, or '#' (this is simpler
+     *         than throwing an exception :)
+     */
+    public static int isStringChar( String string, int index )
+    {
+        int length = string.length();
+        
+        if ( ( string == null ) || ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
+        {
+            return PARSING_ERROR;
+        }
+        else
+        {
+            char c = string.charAt( index );
+
+            if ( c < 0x40 )
+            {
+                return STRING_CHAR[ c ];
+            }
+            else
+            {
+                return ONE_CHAR;
+            }
+        }
+    }
+
 
     /**
      * Check if the current character is a Quote Char We are testing Unicode
@@ -438,6 +581,38 @@
         }
     }
 
+    /**
+     * Check if the current character is a Quote Char We are testing Unicode
+     * chars <quotechar> ::= [0x00-0xFFFF] - [\"]
+     * 
+     * @param string The string which contains the data
+     * @param index Current position in the string
+     *
+     * @return <code>true</code> if the current character is a Quote Char
+     */
+    public static int isQuoteChar( String string, int index )
+    {
+        int length = string.length();
+
+        if ( ( string == null ) || ( length == 0 ) || ( index < 0 ) || ( index >= length ) )
+        {
+            return PARSING_ERROR;
+        }
+        else
+        {
+            char c = string.charAt( index );
+
+            if ( ( c == '\\' ) || ( c == '"' ) )
+            {
+                return PARSING_ERROR;
+            }
+            else
+            {
+                return ONE_CHAR;
+            }
+        }
+    }
+
 
     /**
      * Parse an hex pair <hexpair> ::= <hex> <hex>
@@ -498,6 +673,34 @@
         }
     }
 
+    /**
+     * Parse an hex pair <hexpair> ::= <hex> <hex>
+     * 
+     * @param string
+     *            The string which contains the data
+     * @param index
+     *            Current position in the string
+     * @return The new position, -1 if the string does not contain an HexPair,
+     *         -2 if the string contains an hex byte but not two.
+     */
+    public static int parseHexPair( String string, int index )
+    {
+        if ( StringTools.isHex( string, index ) )
+        {
+            if ( StringTools.isHex( string, index + 1 ) )
+            {
+                return index + TWO_CHARS;
+            }
+            else
+            {
+                return BAD_HEX_PAIR;
+            }
+        }
+        else
+        {
+            return PARSING_ERROR;
+        }
+    }
 
     /**
      * Parse an hex string, which is a list of hex pairs <hexstring> ::=
@@ -566,6 +769,39 @@
         return ( ( result == BAD_HEX_PAIR ) ? PARSING_ERROR : index );
     }
 
+    /**
+     * Parse an hex string, which is a list of hex pairs <hexstring> ::=
+     * <hexpair> <hexpairs> <hexpairs> ::= <hexpair> <hexpairs> | e
+     * 
+     * @param string
+     *            The string which contains the data
+     * @param index
+     *            Current position in the string
+     * @return Return the first position which is not an hex pair, or -1 if
+     *         there is no hexpair at the beginning or if an hexpair is invalid
+     *         (if we have only one hex instead of 2)
+     */
+    public static int parseHexString( String string, Position pos )
+    {
+        pos.end = pos.start;
+        int result = parseHexPair( string, pos.start );
+
+        if ( result < 0 )
+        {
+            return PARSING_ERROR;
+        }
+        else
+        {
+            pos.end += TWO_CHARS;
+        }
+
+        while ( ( result = parseHexPair( string, pos.end ) ) >= 0 )
+        {
+            pos.end += TWO_CHARS;
+        }
+
+        return ( ( result == BAD_HEX_PAIR ) ? PARSING_ERROR : PARSING_OK );
+    }
 
     /**
      * Walk the buffer while characters are Base64 characters : <base64-string>
@@ -611,5 +847,4 @@
             return index;
         }
     }
-
 }