You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2005/08/12 04:00:28 UTC

svn commit: r232182 - in /directory/shared/ldap/trunk/common/src: java/org/apache/ldap/common/name/ java/org/apache/ldap/common/util/ test/org/apache/ldap/common/name/ test/org/apache/ldap/common/util/

Author: akarasulu
Date: Thu Aug 11 19:00:22 2005
New Revision: 232182

URL: http://svn.apache.org/viewcvs?rev=232182&view=rev
Log:
changes ...

 o added test case for DnParser with illegal expression to show it does not 
   accept junk this was for Emmanuels test case, DIRLDAP-39 here:
        http://issues.apache.org/jira/browse/DIRLDAP-39
 o added some utility methods for dealing with composite name components 
   which concatentate several attribute value pairs to form a name component
   using the '+'
 o added test cases for compareTo which corrects the bugs in DIRLDAP-36 here:
        http://issues.apache.org/jira/browse/DIRLDAP-36
 o also added corrective code to the equals() method which had the same issues
   as the compareTo() method

Modified:
    directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/name/LdapName.java
    directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/util/NamespaceTools.java
    directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/DnParserTest.java
    directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/LdapNameTest.java
    directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/util/NamespaceToolsTest.java

Modified: directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/name/LdapName.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/name/LdapName.java?rev=232182&r1=232181&r2=232182&view=diff
==============================================================================
--- directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/name/LdapName.java (original)
+++ directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/name/LdapName.java Thu Aug 11 19:00:22 2005
@@ -27,14 +27,12 @@
 package org.apache.ldap.common.name ;
 
 
+import org.apache.ldap.common.util.NamespaceTools;
+
 import javax.naming.InvalidNameException;
 import javax.naming.Name;
 import javax.naming.NamingException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
+import java.util.*;
 
 
 /**
@@ -195,11 +193,10 @@
              */
             for ( int ii = 0; ii < l_min; ii++ ) 
             {
-                int l_comparison = get( ii ).compareTo( l_dn.get( ii ) ) ;
-                
-                if (  l_comparison != 0 )
+                int compareTo = componentsCompareTo( get( ii ), l_dn.get( ii ) );
+                if ( compareTo != 0 )
                 {
-                    return l_comparison ;
+                    return compareTo;
                 }
             }
             
@@ -648,26 +645,26 @@
     /**
      * @see java.lang.Object#equals(java.lang.Object)
      */
-    public boolean equals( Object an_obj )
+    public boolean equals( Object obj )
     {
-        if ( an_obj instanceof String ) 
+        if ( obj instanceof String )
         {
-            return toString().equals( an_obj ) ;
+            return toString().equals( obj ) ;
         } 
-        else if ( an_obj instanceof Name ) 
+        else if ( obj instanceof Name )
         {
-            Name l_name = ( Name ) an_obj ;
-            if ( l_name.size() != this.size() ) 
+            Name name = ( Name ) obj ;
+
+            if ( name.size() != this.size() )
             {
                 return false ;
             }
 
             for ( int ii = 0; ii < size(); ii++ ) 
             {
-                // Upon finding first non matching component we return false
-                if ( ! l_name.get( ii ).equals( get( ii ) ) ) 
+                if ( ! areComponentsEqual( name.get( ii ), get( ii ) ) )
                 {
-                    return false ;
+                    return false;
                 }
             }
 
@@ -678,6 +675,170 @@
         {
             return false ;
         }
+    }
+
+
+    private boolean areComponentsEqual( String comp0, String comp1 )
+    {
+        // Upon finding first non matching component we return false
+        if ( ! comp0.equals( comp1 ) )
+        {
+            // before returning false check if we have composite components with
+            // different order of attribute value pairs
+
+            boolean isComposite = false;
+
+            try
+            {
+                isComposite = NamespaceTools.hasCompositeComponents( comp0 );
+
+                if ( isComposite && !areCompositeComponentsEqual( comp0, comp0 ) )
+                {
+                    return false;
+                }
+            }
+            catch( NamingException e )
+            {
+                // @todo log somethihng here
+                return false;
+            }
+
+            // before returning false check if the attributeType has a different case
+            if ( ! isComposite && ! NamespaceTools.getRdnValue( comp0 ).equals(
+                                    NamespaceTools.getRdnValue( comp1 ) ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    private int componentsCompareTo( String comp0, String comp1 )
+    {
+        // Upon finding first non matching component we return false
+        if ( ! comp0.equals( comp1 ) )
+        {
+            // before returning false check if we have composite components with
+            // different order of attribute value pairs
+
+            boolean isComposite = false;
+
+            try
+            {
+                isComposite = NamespaceTools.hasCompositeComponents( comp0 );
+
+                if ( isComposite && !areCompositeComponentsEqual( comp0, comp0 ) )
+                {
+                    return comp0.compareTo( comp1 );
+                }
+            }
+            catch( NamingException e )
+            {
+                // @todo log somethihng here
+                return comp0.compareTo( comp1 );
+            }
+
+            // before returning false check if the attributeType has a different case
+            if ( ! isComposite && ! NamespaceTools.getRdnValue( comp0 ).equals(
+                                    NamespaceTools.getRdnValue( comp1 ) ) )
+            {
+                return comp0.compareTo( comp1 );
+            }
+        }
+
+        return 0;
+    }
+
+
+    private boolean areCompositeComponentsEqual( String comp0, String comp1 ) throws NamingException
+    {
+        String[] comps0 = NamespaceTools.getCompositeComponents( comp0 );
+        HashSet set0 = new HashSet(comps0.length);
+        String[] comps1 = NamespaceTools.getCompositeComponents( comp1 );
+        HashSet set1 = new HashSet(comps1.length);
+
+        if ( comps0.length != comps1.length )
+        {
+            return false;
+        }
+
+        // normalize the name component
+        for ( int ii = 0; ii < comps0.length; ii++ )
+        {
+            StringBuffer buf = new StringBuffer();
+            String attr = NamespaceTools.getRdnAttribute( comps0[ii] );
+            String value = NamespaceTools.getRdnValue( comps0[ii] );
+            buf.append( attr.toLowerCase() );
+            buf.append( "=" );
+            buf.append( value );
+            set0.add( buf.toString() );
+
+            buf.setLength( 0 );
+            attr = NamespaceTools.getRdnAttribute( comps1[ii] );
+            value = NamespaceTools.getRdnValue( comps1[ii] );
+            buf.append( attr.toLowerCase() );
+            buf.append( "=" );
+            buf.append( value );
+            set1.add( buf.toString() );
+        }
+
+        Iterator list = set0.iterator();
+        while ( list.hasNext() )
+        {
+            if ( ! set1.contains( list.next() ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    private int compositeComponentsCompareTo( String comp0, String comp1 ) throws NamingException
+    {
+        String[] comps0 = NamespaceTools.getCompositeComponents( comp0 );
+        HashSet set0 = new HashSet(comps0.length);
+        String[] comps1 = NamespaceTools.getCompositeComponents( comp1 );
+        HashSet set1 = new HashSet(comps1.length);
+
+        if ( comps0.length != comps1.length )
+        {
+            return comp0.compareTo( comp1 );
+        }
+
+        // normalize the name component
+        for ( int ii = 0; ii < comps0.length; ii++ )
+        {
+            StringBuffer buf = new StringBuffer();
+            String attr = NamespaceTools.getRdnAttribute( comps0[ii] );
+            String value = NamespaceTools.getRdnValue( comps0[ii] );
+            buf.append( attr.toLowerCase() );
+            buf.append( "=" );
+            buf.append( value );
+            set0.add( buf.toString() );
+
+            buf.setLength( 0 );
+            attr = NamespaceTools.getRdnAttribute( comps1[ii] );
+            value = NamespaceTools.getRdnValue( comps1[ii] );
+            buf.append( attr.toLowerCase() );
+            buf.append( "=" );
+            buf.append( value );
+            set1.add( buf.toString() );
+        }
+
+        Iterator list = set0.iterator();
+        while ( list.hasNext() )
+        {
+            if ( ! set1.contains( list.next() ) )
+            {
+                return comp0.compareTo( comp1 );
+            }
+        }
+
+        return 0;
     }
 
 

Modified: directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/util/NamespaceTools.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/util/NamespaceTools.java?rev=232182&r1=232181&r2=232182&view=diff
==============================================================================
--- directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/util/NamespaceTools.java (original)
+++ directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/util/NamespaceTools.java Thu Aug 11 19:00:22 2005
@@ -29,6 +29,7 @@
 import org.apache.ldap.common.name.LdapName;
 
 import javax.naming.*;
+import java.util.ArrayList;
 
 
 /**
@@ -41,6 +42,9 @@
  */
 public class NamespaceTools
 {
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+
     /**
      * Checks to see if a distinguished name is a root.
      *
@@ -467,6 +471,136 @@
         }
 
         buf.append(realm.substring(start));
+        return buf.toString();
+    }
+
+
+    /**
+     * Gets the '+' appended components of a composite name component.
+     *
+     * @param compositeNameComponent a single name component not a whole name
+     * @return the components of the complex name component in order
+     * @throws NamingException if nameComponent is invalid (starts with a +)
+     */
+    public static String[] getCompositeComponents( String compositeNameComponent ) throws NamingException
+    {
+        int lastIndex = compositeNameComponent.length() - 1;
+        ArrayList comps = new ArrayList();
+
+        for ( int ii = compositeNameComponent.length() - 1; ii >= 0; ii-- )
+        {
+            if ( compositeNameComponent.charAt( ii ) == '+' )
+            {
+                if ( ii == 0 )
+                {
+                    throw new NamingException( "invalid name - a name cannot start with a '+': "
+                            + compositeNameComponent );
+                }
+                if ( compositeNameComponent.charAt( ii - 1 ) != '\\' )
+                {
+                    if ( lastIndex == compositeNameComponent.length() - 1 )
+                    {
+                        comps.add( 0, compositeNameComponent.substring( ii + 1, lastIndex + 1 ) );
+                    }
+                    else
+                    {
+                        comps.add( 0, compositeNameComponent.substring( ii + 1, lastIndex ) );
+                    }
+
+                    lastIndex = ii;
+                }
+            }
+            if ( ii == 0 )
+            {
+                if ( lastIndex == compositeNameComponent.length() - 1 )
+                {
+                    comps.add( 0, compositeNameComponent );
+                }
+                else
+                {
+                    comps.add( 0, compositeNameComponent.substring( ii, lastIndex ) );
+                }
+
+                lastIndex = 0;
+            }
+        }
+
+        if ( comps.size() == 0 )
+        {
+            comps.add( compositeNameComponent );
+        }
+
+        return ( String[] ) comps.toArray( EMPTY_STRING_ARRAY );
+    }
+
+
+    /**
+     * Checks to see if a name has name complex name components in it.
+     *
+     * @param name
+     * @return
+     * @throws NamingException
+     */
+    public static boolean hasCompositeComponents( String name ) throws NamingException
+    {
+        for ( int ii = name.length() - 1; ii >= 0; ii-- )
+        {
+            if ( name.charAt( ii ) == '+' )
+            {
+                if ( ii == 0 )
+                {
+                    throw new NamingException( "invalid name - a name cannot start with a '+': " + name );
+                }
+                if ( name.charAt( ii - 1 ) != '\\' )
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Lowercases the attribute of a complex name component or a simple one with a single
+     * attribute value pair.
+     *
+     * @param nameComponent the name component to lower the case of attribute types
+     * @return the name component with all attribute types lowercased
+     * @throws NamingException if the component is malformed
+     */
+    public String toLowerAttributeType( String nameComponent ) throws NamingException
+    {
+        String attr = null;
+        String value = null;
+        StringBuffer buf = new StringBuffer();
+
+        if ( hasCompositeComponents( nameComponent ) )
+        {
+            String[] comps = getCompositeComponents( nameComponent );
+            for ( int ii = 0; ii < comps.length; ii++ )
+            {
+                attr = getRdnAttribute( nameComponent );
+                value = getRdnValue( nameComponent );
+                buf.append( attr.toLowerCase() );
+                buf.append( "=" );
+                buf.append( value );
+
+                if ( ii != comps.length - 1 )
+                {
+                    buf.append( "+" );
+                }
+            }
+
+            return buf.toString();
+        }
+
+        attr = getRdnAttribute( nameComponent );
+        value = getRdnValue( nameComponent );
+        buf.append( attr.toLowerCase() );
+        buf.append( "=" );
+        buf.append( value );
         return buf.toString();
     }
 }

Modified: directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/DnParserTest.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/DnParserTest.java?rev=232182&r1=232181&r2=232182&view=diff
==============================================================================
--- directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/DnParserTest.java (original)
+++ directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/DnParserTest.java Thu Aug 11 19:00:22 2005
@@ -237,7 +237,7 @@
 
         try
         {
-            Name invalid = parser.parse( "&#347;=&#347;rasulu,dc=example,dc=com" );
+            parser.parse( "&#347;=&#347;rasulu,dc=example,dc=com" );
             fail( "the invalid name should never succeed in a parse" );
         }
         catch ( Exception e )

Modified: directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/LdapNameTest.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/LdapNameTest.java?rev=232182&r1=232181&r2=232182&view=diff
==============================================================================
--- directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/LdapNameTest.java (original)
+++ directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/name/LdapNameTest.java Thu Aug 11 19:00:22 2005
@@ -297,31 +297,31 @@
     public void testSize() 
         throws Exception
     {
-        Name l_name0 =             
+        Name name0 =
             m_parser.parse( "" ) ;
-        Name l_name1 = 
+        Name name1 =
             m_parser.parse( "ou=East" ) ;
-        Name l_name2 = 
+        Name name2 =
             m_parser.parse( "ou=Marketing,ou=East" ) ;
-        Name l_name3 = 
+        Name name3 =
             m_parser.parse( "cn=John,ou=Marketing,ou=East" ) ;
-        Name l_name4 = 
+        Name name4 =
             m_parser.parse( "cn=HomeDir,cn=John,ou=Marketing,ou=East" ) ;
-        Name l_name5 = 
+        Name name5 =
             m_parser.parse( 
                 "cn=Website,cn=HomeDir,cn=John,ou=Marketing,ou=West" ) ;
-        Name l_name6 = 
+        Name name6 =
             m_parser.parse( 
                 "cn=Airline,cn=Website,cn=HomeDir,cn=John,ou=Marketing,ou=West"
                 ) ;
                 
-        super.assertEquals( 0, l_name0.size() ) ;        
-        super.assertEquals( 1, l_name1.size() ) ;        
-        super.assertEquals( 2, l_name2.size() ) ;        
-        super.assertEquals( 3, l_name3.size() ) ;        
-        super.assertEquals( 4, l_name4.size() ) ;        
-        super.assertEquals( 5, l_name5.size() ) ;        
-        super.assertEquals( 6, l_name6.size() ) ;        
+        assertEquals( 0, name0.size() ) ;
+        assertEquals( 1, name1.size() ) ;
+        assertEquals( 2, name2.size() ) ;
+        assertEquals( 3, name3.size() ) ;
+        assertEquals( 4, name4.size() ) ;
+        assertEquals( 5, name5.size() ) ;
+        assertEquals( 6, name6.size() ) ;
     }
 
 
@@ -332,31 +332,31 @@
     public void testIsEmpty() 
         throws Exception
     {
-        Name l_name0 =             
+        Name name0 =
             m_parser.parse( "" ) ;
-        Name l_name1 = 
+        Name name1 =
             m_parser.parse( "ou=East" ) ;
-        Name l_name2 = 
+        Name name2 =
             m_parser.parse( "ou=Marketing,ou=East" ) ;
-        Name l_name3 = 
+        Name name3 =
             m_parser.parse( "cn=John,ou=Marketing,ou=East" ) ;
-        Name l_name4 = 
+        Name name4 =
             m_parser.parse( "cn=HomeDir,cn=John,ou=Marketing,ou=East" ) ;
-        Name l_name5 = 
+        Name name5 =
             m_parser.parse( 
                 "cn=Website,cn=HomeDir,cn=John,ou=Marketing,ou=West" ) ;
-        Name l_name6 = 
+        Name name6 =
             m_parser.parse( 
                 "cn=Airline,cn=Website,cn=HomeDir,cn=John,ou=Marketing,ou=West"
                 ) ;
                 
-        super.assertEquals( true, l_name0.isEmpty() ) ;        
-        super.assertEquals( false, l_name1.isEmpty() ) ;        
-        super.assertEquals( false, l_name2.isEmpty() ) ;        
-        super.assertEquals( false, l_name3.isEmpty() ) ;        
-        super.assertEquals( false, l_name4.isEmpty() ) ;        
-        super.assertEquals( false, l_name5.isEmpty() ) ;        
-        super.assertEquals( false, l_name6.isEmpty() ) ;        
+        assertEquals( true, name0.isEmpty() ) ;
+        assertEquals( false, name1.isEmpty() ) ;
+        assertEquals( false, name2.isEmpty() ) ;
+        assertEquals( false, name3.isEmpty() ) ;
+        assertEquals( false, name4.isEmpty() ) ;
+        assertEquals( false, name5.isEmpty() ) ;
+        assertEquals( false, name6.isEmpty() ) ;
     }
 
 
@@ -868,13 +868,7 @@
         Name l_name = new LdapName() ;
         assertEquals( m_parser.parse( "" ), l_name ) ;
             
-        Name l_name4 = 
-            m_parser.parse( "ou=East" ) ;
-        l_name.add( "ou=East" ) ;
-        l_name.remove( 0 ) ;
-        assertEquals( m_parser.parse( "" ), l_name ) ;
-    
-        Name l_name3 = 
+        Name l_name3 =
             m_parser.parse( "ou=Marketing" ) ;
         l_name.add( "ou=East" ) ;
         l_name.add( 1, "ou=Marketing" ) ;
@@ -946,28 +940,59 @@
             m_parser.parse( "ou=People" ) ) ) ; 
     }
 
-    public void testAttributeValueComparisonIsCaseSensitive() throws Exception
+
+    public void testAttributeEqualsIsCaseInSensitive() throws Exception
     {
         Name name1 = new LdapName( "cn=HomeDir" );
-        Name name2 = new LdapName( "cn=homedir" );
+        Name name2 = new LdapName( "CN=HomeDir" );
 
-        assertTrue( name1.compareTo( name2 ) < 0 );
+        assertTrue( name1.equals( name2 ) );
     }
 
-//   public void testAttributeTypeComparisonIsCaseInsensitive() throws NamingException
-//    {
-//        Name name1 = new LdapName( "cn=HomeDir+cn=WorkDir" );
-//        Name name2 = new LdapName( "cn=HomeDir+CN=WorkDir" );
-//
-//        assertEquals( 0, name1.compareTo( name2 ) );
-//    }
-//
-//    public void testNameComparisonIsInsensitiveToAttributesOrder() throws NamingException
-//     {
-//
-//         Name name1 = new LdapName( "cn=HomeDir+cn=WorkDir" );
-//         Name name2 = new LdapName( "cn=WorkDir+cn=HomeDir" );
-//
-//         assertEquals( 0, name1.compareTo( name2 ) );
-//     }
+
+    public void testAttributeTypeEqualsIsCaseInsensitive() throws Exception
+    {
+        Name name1 = new LdapName( "cn=HomeDir+cn=WorkDir" );
+        Name name2 = new LdapName( "cn=HomeDir+CN=WorkDir" );
+
+        assertTrue( name1.equals( name2 ) );
+    }
+
+
+    public void testNameEqualsIsInsensitiveToAttributesOrder() throws Exception
+    {
+
+        Name name1 = new LdapName( "cn=HomeDir+cn=WorkDir" );
+        Name name2 = new LdapName( "cn=WorkDir+cn=HomeDir" );
+
+        assertTrue( name1.equals( name2 ) );
+    }
+
+
+    public void testAttributeComparisonIsCaseInSensitive() throws Exception
+    {
+        Name name1 = new LdapName( "cn=HomeDir" );
+        Name name2 = new LdapName( "CN=HomeDir" );
+
+        assertEquals( 0, name1.compareTo( name2 ) );
+    }
+
+
+    public void testAttributeTypeComparisonIsCaseInsensitive() throws Exception
+    {
+        Name name1 = new LdapName( "cn=HomeDir+cn=WorkDir" );
+        Name name2 = new LdapName( "cn=HomeDir+CN=WorkDir" );
+
+        assertEquals( 0, name1.compareTo( name2 ) );
+    }
+
+
+    public void testNameComparisonIsInsensitiveToAttributesOrder() throws Exception
+    {
+
+        Name name1 = new LdapName( "cn=HomeDir+cn=WorkDir" );
+        Name name2 = new LdapName( "cn=WorkDir+cn=HomeDir" );
+
+        assertEquals( 0, name1.compareTo( name2 ) );
+    }
 }

Modified: directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/util/NamespaceToolsTest.java
URL: http://svn.apache.org/viewcvs/directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/util/NamespaceToolsTest.java?rev=232182&r1=232181&r2=232182&view=diff
==============================================================================
--- directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/util/NamespaceToolsTest.java (original)
+++ directory/shared/ldap/trunk/common/src/test/org/apache/ldap/common/util/NamespaceToolsTest.java Thu Aug 11 19:00:22 2005
@@ -19,6 +19,8 @@
 import junit.framework.Assert;
 import junit.framework.TestCase;
 
+import javax.naming.NamingException;
+
 /**
  * Test the NameToolsTest class
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
@@ -47,5 +49,35 @@
     public void testFullRealm()
     {
         Assert.assertEquals("dc=CS,dc=UCL,dc=AC,dc=UK", NamespaceTools.inferLdapName("CS.UCL.AC.UK"));
+    }
+
+    public void testHasCompositeComponents() throws NamingException
+    {
+        assertTrue( NamespaceTools.hasCompositeComponents( "givenName=Alex+sn=Karasulu" ) );
+        assertTrue( NamespaceTools.hasCompositeComponents( "givenName=Alex+sn=Karasulu+age=13" ) );
+        assertFalse( NamespaceTools.hasCompositeComponents( "cn=One\\+Two" ) );
+        assertFalse( NamespaceTools.hasCompositeComponents( "cn=Alex" ) );
+    }
+
+    public void testGetCompositeComponents() throws NamingException
+    {
+        String[] args = NamespaceTools.getCompositeComponents( "givenName=Alex+sn=Karasulu" );
+        assertEquals( "expecting two parts : ", 2, args.length );
+        assertEquals( "givenName=Alex", args[0] );
+        assertEquals( "sn=Karasulu", args[1] );
+
+        args = NamespaceTools.getCompositeComponents( "givenName=Alex+sn=Karasulu+age=13" );
+        assertEquals( "expecting two parts : ", 3, args.length );
+        assertEquals( "givenName=Alex", args[0] );
+        assertEquals( "sn=Karasulu", args[1] );
+        assertEquals( "age=13", args[2] );
+
+        args = NamespaceTools.getCompositeComponents( "cn=One\\+Two" );
+        assertEquals( "expecting one part : ", 1, args.length );
+        assertEquals( "cn=One\\+Two", args[0] );
+
+        args = NamespaceTools.getCompositeComponents( "cn=Alex" );
+        assertEquals( "expecting one part : ", 1, args.length );
+        assertEquals( "cn=Alex", args[0] );
     }
 }