directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1186334 [2/4] - in /directory/documentation/ldap-api-manuals/trunk: ./ src/ src/docbkx-stylesheet/ src/docbkx-stylesheet/fo/ src/docbkx-stylesheet/html/ src/ldap-api-user-guide-confluence/ src/ldap-api-user-guide-confluence/chapter-2/ src/...
Date Wed, 19 Oct 2011 16:58:09 GMT
Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-2/2-4-preparation-to-code.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-2/2-4-preparation-to-code.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-2/2-4-preparation-to-code.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-2/2-4-preparation-to-code.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,16 @@
+h2. Preparation to code
+
+In order to develop with the *Apache Directory LDAP API*, you first have to use a *Java 5* or *Java 6* JDK. 
+
+Second, you have to download the *[API|http://directory.apache.org/api/downloads.html]*. This package contains not only the *LDAP API*, but also all the needed jars (like _commons-lang_, _slf4j_...).
+
+If you are using *Maven*, you don't even have to refer all the libraries that are found in the package, they will be deduced automatically. You will just have to add a dependency on shared-all.jar :
+
+{code:xml}
+    <dependency>
+      <groupId>org.apache.directory.shared</groupId>
+      <artifactId>shared-all</artifactId>
+    </dependency>
+{code}
+
+This is it, you should be ready to code !
\ No newline at end of file

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-1-connection-and-disconnection.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-1-connection-and-disconnection.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-1-connection-and-disconnection.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-1-connection-and-disconnection.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,53 @@
+h2. Connection and disconnection
+
+*LDAP* is a protocol which requires the user to be connected - and eventually identified - in order to be able to send requests to the server. We maintain this connection potentially forever. What make the *LDAP* protocol different from, say, the *HTTP* protocol is that the connection must be issued explicitly. Let's see how we do that.
+
+h3. Opening a connection
+
+We can open a secure or a standard connection. 
+
+h4. Standard connection
+
+We can first establish a standard connection, where the data are sent and received in clear text (encoded in ASN.1 BER, but still not encrypted). This example expose the way it's done :
+
+{code:java}
+    LdapConnection connection = new LdapNetworkConnection( "localhost", 389 );
+{code}
+
+Here, we just created an unsafe connection locally, using the 389 port. Quite simple...
+
+h4. Secure connection
+
+Although the *LDAPS* (*LDAP* over *SSL*) is now considered as deprecated, many people continue to use it. The big advantage of not using *LDAPS* is that you don't need to setup two different listening ports (one for *LDAP* -389- and another one for *LDAPS* -636- ).
+
+The only difference with the previous example is that we have to tell the connection that it has to use *SSL*, by passing *_true{_}* as a third parameter (incidentally, passing *_false{_}* set a unsafe connection).
+
+Here is an example
+
+{code:java}
+    LdapConnection connection = new LdapNetworkConnection( "localhost", 636, true );
+{code}
+
+h3. Maintaining the connection opened
+We keep the connection opened for a limited period of time, defaulting to 30 seconds. This might be not long enough, so one can change this delay by calling the _setTimeOut()_ method :
+
+{code:java}
+    LdapConnection connection = new LdapNetworkConnection( "localhost", 389 );
+    connection.setTimeOut( 0 );
+    ...
+    connection.close();
+{code}
+
+{note}
+Setting a value equal or below 0 will keep the connection opened for ever (or a soon as the connection is not explicitly closed).
+{note}
+
+h3. Closing the connection
+
+Once you don't need to use the connection anymore (remember that hodling a connection keeps a session opened on the server, and a socket opened between the client and the server), then you have to close it. This is done by calling the _close()_ method :
+
+{code:java}
+    LdapConnection connection = new LdapNetworkConnection( "localhost", 389 );
+    ...
+    connection.close();
+{code}

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-2-binding-and-unbinding.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-2-binding-and-unbinding.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-2-binding-and-unbinding.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-2-binding-and-unbinding.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,115 @@
+h2. Binding and unbinding
+
+In *LDAP*, if one wants to access the data in the base, the common way to do it is to bind on the server. However, it's important to understand that binding is a different beast than connection.
+
+Creating a connection to a *LDAP* server is just about opening a socket between the client and the server. You just need to provide the address and the port. 
+
+The bind operation, on the other hand, create a Session which will hold some user's information for the time being of the session. Those information are quite limited, they include the user's credentials.
+
+But it's important to know that it's possible to bind as anonymous, providing no name and password, and still be able to request the server (note though that the server can forbid such anonymous bind).
+
+Once the user has finished to request the server, then he can unbind, destroying his session on the server. That does not close the connection, because, one more time, _bind != connection_.
+
+h3. Binding
+You have two possible types of binds in *LDAP* :
+* *Simple*
+* *SASL*
+
+The first one is based on a user/password being send to the server, which check that they are valid. It's also possible to proceed an Anonymous bind explicitly.
+
+The second one is more complex, and is used if you want to proceed an authentication with some specific mechanism, like *DIGEST-MD5*, *Kerberos* or certificate based.
+
+h4. Simple Bind
+One can issue three kind of Simple bind :
+* _anonymous bind_
+* _name/password bind_
+* _unauthenticated authentication bind_
+
+The first one is the easiest one, but depending on the server configuration, it will be accepted or rejected (all the servers don't allow anonymous binds)
+
+Issuing an anonymous bind is very simple, you just provide no user name nor any password :
+
+{code:java}
+    @Test
+    public void testAnonymousBindRequest() throws Exception
+    {
+        BindResponse bindResponse = connection.bind();
+
+        assertNotNull( bindResponse );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResponse.getLdapResult().getResultCode() );
+        assertTrue( connection.isAuthenticated() );
+    }
+{code}
+
+Issuing a user/password bind is just slightly more complex, you just have to provide your user name and its password :
+
+{code:java}
+    @Test
+    public void testSimpleBindRequest() throws Exception
+    {
+        BindResponse bindResponse = connection.bind( "uid=admin,ou=system", "secret" );
+
+        assertNotNull( bindResponse );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResponse.getLdapResult().getResultCode() );
+        assertTrue( connection.isAuthenticated() );
+    }
+{code}
+
+{note:warn}
+It's important to note that the user's name is a *[DIRAPI:Dn]*, not a simple name like 'John doe"
+{note}
+
+Last, not least, there is a quite unknown feature in *LDAP* bind that allows you to issue a Bind request without providing a password. It's equivalent to an anonymous bind, except that the server can log the user's name, thus being able to trace what the user does. Servers might forbid such bind, and this will be the case if the server disallow anonymous binds.
+
+Note that this kind of bind will be supported only if the server allows anonymous binds. It's not supported by *ApacheDS*.
+
+{code:java}
+    @Test
+    public void testSimpleBindRequest() throws Exception
+    {
+
+        BindResponse bindResponse = connection.bind( "uid=admin,ou=system" );
+
+        assertNotNull( bindResponse );
+        assertEquals( ResultCodeEnum.SUCCESS, bindResponse.getLdapResult().getResultCode() );
+        assertFalse( connection.isAuthenticated() );
+    }
+{code}
+
+h4. SASL Bind
+
+TO BE COMPLETED
+
+h3. Unbinding
+
+This is a trivial operation : you just send an *[UnbindRequest]* to the server, which will invalidate your session. 
+
+It's important to know that when you issue an *Unbind*, the connection is dropped. However, if you immediately try another bind, the *API* will open the connection again, using the information provided when the connection has been created. You can then do such a thing :
+
+{code:java}
+    @Test
+    public void testDoubleSimpleBindValid() throws Exception
+    {
+        BindResponse response = connection.bind( "uid=admin,ou=system", "secret" );
+        assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
+        assertTrue( connection.isConnected() );
+        assertTrue( connection.isAuthenticated() );
+
+        // Now, unbind
+        connection.unBind();
+        assertFalse( connection.isConnected() );
+        assertFalse( connection.isAuthenticated() );
+
+        // And Bind again.
+        response = connection.bind( "uid=admin,ou=system", "secret" );
+        LdapResult ldapResult3 = response3.getLdapResult();
+        assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult.getResultCode() );
+        assertTrue( connection.isConnected() );
+        assertTrue( connection.isAuthenticated() );
+    }
+{code}
+
+If you issue a _bind_ on the same connection with some different credentials, then the existing session will be terminated on the server, and a new one will be created. All the pending requests for the initial session will be lost.
+
+Last, not least, if you close the connection, then the session will also be terminated.
+ 

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-3-searching.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-3-searching.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-3-searching.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-3-searching.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,40 @@
+h2. Searching
+
+Searching is the most important operation in *LDAP*. It has to be fast, very fast. On the other hand, as the server does not a lot of processing while looking for entries, the client has to provide many information in order to get some accurate results.
+
+The idea is to define a search *API* which is easy to use in the simplest cases, but provides all the necessary bolts if you need to send complex search requests.
+
+{note:warn}
+This part of the API is very likely to change in the next milestone, to provide an easier way to get the results in the simple cases.
+{note}
+
+h3. Simple search
+
+Let's first look at a simple search. What we basically need to process a search is a starting point in the tree, a filter, a scope. Here is an example :
+
+{code:java}
+    @Test
+    public void testSimpleSearch() throws Exception
+    {
+        SearchCursor cursor = connection.search( "ou=system", "(objectclass=*)", SearchScope.ONELEVEL );
+        
+        while ( cursor.next() )
+        {
+            Response response = cursor.get();
+            assertNotNull( response );
+            assertTrue( response instanceof SearchResultEntry );
+            System.out.println( ((SearchResultEntry)response).getEntry() );
+        }
+
+        SearchResultDone done = cursor.getSearchResultDone();
+
+        assertNotNull( done );
+        assertEquals( ResultCodeEnum.SUCCESS, done.getLdapResult().getResultCode() );
+
+        cursor.close();
+    }
+{code}
+
+In this example, the _connection_ has been previously created. We just search for all the entries starting at *ou=system* and their children, which have an _ObjectClass_ attribute (all the entries have such an attribute, so we should get back all the entries). The scope (_ONELEVEL_) says we just search one level under the starting base.
+
+We get back a cursor, which can be walked forward. Every call to the _get()_ method will return a response, which will be either a _SearchResultEntry_, a _SearchResultReference_ or an _IntermediateResponse_.
\ No newline at end of file

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-4-adding-entries.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-4-adding-entries.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-4-adding-entries.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-4-adding-entries.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,151 @@
+h2. Adding entries
+
+Adding entries is one of the base operation a user can do on a *LDAP* server. Nevertheless, such an operation implies a lot of checks, and frequently the user gets some weird error messages. We will see how we can add an entry using the *LDAP API*, and then analyze the different error cases we can face.
+
+h3. Adding an entry
+We will first see the easiest way to add an entry into the server, assuming that the entry is correct. In order to add an entry, you only have to provide the place where this entry will be stored (its *[DIRAPI:Dn]*) and the list of its *[DIRAPI:Attribute]s*.
+
+Here is two examples where we inject the entry using *LDIF*:
+
+{code:java}
+    @Test
+    public void testAddLdif() throws Exception
+    {
+        AddResponse response = connection.add( 
+            new DefaultEntry( 
+                "cn=testadd,ou=system",    // The Dn
+                "ObjectClass: top",
+                "ObjectClass: person",
+                "cn: testadd_cn",
+                "sn: testadd_sn"
+                ) );
+
+        assertNotNull( response );
+        assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
+
+        assertTrue( session.exists( "cn=testadd,ou=system" ) );
+    }
+{code}
+
+In this basic example, we are adding a new entry, created using some *LDIF* formatted parameters, the first one being the entry's Dn.
+Note that it is possible to use some variables in the *LDIF* instead of pure text. Here is the same example, resulting to the same entry being added:
+
+{code:java}
+    @Test
+    public void testAddLdif() throws Exception
+    {
+        String cn = "testadd_cn";
+        String sn = "testadd_sn";
+
+        AddResponse response = connection.add( 
+            new DefaultEntry( 
+                "cn=testadd,ou=system",    // The Dn
+                "ObjectClass: top",
+                "ObjectClass: person",
+                "cn", cn,                  // Note : there is no ':' when using a variable
+                "sn", sn
+                ) );
+
+        assertNotNull( response );
+        assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
+
+        assertTrue( session.exists( "cn=testadd,ou=system" ) );
+    }
+{code}
+
+Down the line, what is important is that the _add()_ operation is taking a full *[DIRAPI:Entry]*. 
+
+We can also create the *[DIRAPI:Entry]* in a different way, which will be exposed in the following paragraphs.
+
+h3. Sending an *[DIRAPI:AddRequest]*
+
+Sometimes, we want more control. We can ask the server to add an entry by sending an *[DIRAPI:AddRequest]*, which allows you to send a *[DIRAPI:Control]* at the same time.
+
+Here is an example (note that the control is just injected to demonstrate the feature, it simply does nothing in this case):
+
+{code:java}
+    @Test
+    public void testAddWithControl() throws Exception
+    {
+        assertFalse( session.exists( "cn=testadd,ou=system" ) );
+        
+        Entry entry = new DefaultEntry( 
+            "cn=testadd,ou=system",
+            "ObjectClass : top",
+            "ObjectClass : person",
+            "cn: testadd_sn",
+            "sn: testadd_sn"
+            );
+        
+        AddRequest addRequest = new AddRequestImpl();
+        addRequest.setEntry( entry );
+        addRequest.addControl( new ManageDsaITImpl() );
+
+        AddResponse response = connection.add( addRequest );
+
+        assertNotNull( response );
+        assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
+
+        assertTrue( session.exists( "cn=testadd,ou=system" ) );
+    }
+{code}
+
+h4. Asynchronous addition
+
+Some may want to add an entry, but will not check the result immediately. It's just a matter of calling the _addAsync()_ method, which will return a _Future_ that can be checked somewhere else in the code:
+
+{code:java}
+    @Test
+    public void testAddAsyncLdif() throws Exception
+    {
+        Entry entry = new DefaultEntry( 
+            "cn=testAsyncAdd,ou=system",
+            "ObjectClass: top",
+            "ObjectClass: person",
+            "cn: testAsyncAdd_cn",
+            "sn: testAsyncAdd_sn" );
+
+        assertFalse( session.exists( "cn=testAsyncAdd,ou=system" ) );
+        AddRequest addRequest = new AddRequestImpl();
+        addRequest.setEntry( entry );
+
+        AddFuture addFuture = connection.addAsync( addRequest );
+
+        // Here, we can do something else before checking that the entry has been added
+
+        AddResponse addResponse = addFuture.get( 1000, TimeUnit.MILLISECONDS );
+
+        assertNotNull( addResponse );
+        assertEquals( ResultCodeEnum.SUCCESS, addResponse.getLdapResult().getResultCode() );
+        assertTrue( session.exists( "cn=testAsyncAdd,ou=system" ) );
+    }
+{code}
+
+h3. Do, Don't
+
+Successfully adding an entry assume that the entry is correct, ie that the attributes and the value are compatible with the schema. There are many things checked by the server. Here is a list of constraints that you should respect in order to get your entry injected:
+* The entry must have at least one *Structural* *[DIRAPI:ObjectClass]*
+* If the entry has more than one *Structural* *[DIRAPI:ObjectClass]*, then they must be hierarchically related
+* The *[DIRAPI:ObjectClass]es* define the list of allowed *Structural* *[DIRAPI:AttributeType]s* that can be used (*MAY* and *MUST*)
+* All the *MUST* *[DIRAPI:AttributeType]s* must be present
+* Each added value must follow the *[DIRAPI:AttributeType]* *[DIRAPI:Syntax]*
+* If the *[DIRAPI:AttributeType]* is single valued, then you can't add more than one value
+* The entry's *[DIRAPI:Dn]* must have a parent
+* You are not allowed as a user to inject operational attributes, unless they have the *USER-MODIFICATION* flag set to true.
+
+
+There are also some other constraints, depending on the server, if it implements *[DIRAPI:NameForm]s*, *[DIRAPI:DITStructureRule]s* or *[DIRAPI:DITContentRule]s*.
+
+One other reason your entry can be rejected is that you don't have enough privilege to add it. You have to check that the server configuration allows you to add an entry where you want to add it.
+
+h3. Errors
+
+{note}
+At first, you might expect to get an exception if the entry addition has failed. If the server is rejecting the addition, *you will get NO exception*. Exceptions are only thrown client side if the entry is not built correctly, or if the connection is not opened. 
+
+In any other case, the server will simply return a *[DIRAPI:LdapResult]* instance containing either *SUCCESS* or the cause of the rejection.
+{note}
+
+Usually, if you get an error while adding an entry, the message might be pretty tedious. Most of the cases it's because either your entry already exists, or because your entry has some schema violation.
+
+The *[DIRAPI:LdapResult]* in the response will give you a clue about what going on.
\ No newline at end of file

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-5-deleting-entries.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-5-deleting-entries.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-5-deleting-entries.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-5-deleting-entries.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,105 @@
+h2. Deleting entries
+
+Deleting an entry is really easy. It's just a matter to know its *[DIRAPI:Dn]*. There is one important thing to understand though : if this entry has some children, it won't be deleted.
+
+h3. Simple entry deletion
+
+We can ask the deletion by providing the entry's *[DIRAPI:Dn]*, like what is done in the following example :
+
+{code:java}
+    @Test
+    public void testDeleteLeafNode() throws Exception
+    {
+        assertTrue( session.exists( "cn=child1,cn=parent,ou=system" ) );
+
+        DeleteResponse response = connection.delete( "cn=child1,cn=parent,ou=system" );
+        assertNotNull( response );
+        assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
+
+        assertFalse( session.exists( "cn=child1,cn=parent,ou=system" ) );
+    }
+{code}
+
+Trying to delete the parent alone would leads to an error (NOT_ALLOWED_ON_NON_LEAF) :
+
+{code:java}
+    @Test
+    public void testDeleteNonLeafFailure() throws Exception
+    {
+        assertTrue( session.exists( "cn=parent,ou=system" ) );
+
+        DeleteResponse response = connection.delete( "cn=parent,ou=system" );
+        assertNotNull( response );
+        assertEquals( ResultCodeEnum.NOT_ALLOWED_ON_NON_LEAF, response.getLdapResult().getResultCode() );
+
+        assertTrue( session.exists( "cn=parent,ou=system" ) );
+    }
+{code}
+
+h3. Recursive deletion of entries
+
+Usually, you can't delete an entry and all of its children. However, some server accept such a request if you send a delete request and a TreeDelete control. This control is a [draft|http://tools.ietf.org/html/draft-armijo-ldap-treedelete-02], which has been implemented by *Microsoft*, *OpenDS*, *OpenDJ*. It will delete all the children and the entry itself. We don't use a normal _delete()_ method, there is a specific method, _deleteTree()_. Here is an example :
+
+{code:java}
+    @Test
+    public void testDeleteWithCascadeControl() throws Exception
+    {
+        assertTrue( session.exists( "cn=parent,ou=system" ) );
+
+
+        DeleteResponse response = connection.deleteTree( "cn=parent,ou=system" );
+        assertNotNull( response );
+        assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
+
+        assertFalse( session.exists( "cn=parent,ou=system" ) );
+    }
+{code}
+
+h3. Sending a DeleteRequest with a control
+
+It's also possible to associate a *[DIRAPI:Control]* with the delete request. In order to do that, you have to create a *[DIRAPI:DelRequest]* instance. In the following example, we will add the Delete Tree control (this make this call equivalent to the _deleteTree()_ method).
+
+{code:java}
+    @Test
+    public void testDeleteWithControl() throws Exception
+    {
+        assertTrue( session.exists( "cn=parent,ou=system" ) );
+
+        if ( connection.isControlSupported( "1.2.840.113556.1.4.805" ) )
+        {
+            DeleteRequest deleteRequest = new DeleteRequestImpl();
+            deleteRequest.setName( new Dn( "cn=parent,ou=system" ) );
+            Control deleteTreeControl = new OpaqueControl( "1.2.840.113556.1.4.805" );
+            deleteRequest.addControl( deleteTreeControl );
+    
+            DeleteResponse deleteResponse = connection.delete( deleteRequest );
+    
+            assertNotNull( deleteResponse );
+            assertEquals( ResultCodeEnum.SUCCESS, deleteResponse.getLdapResult().getResultCode() );
+            assertFalse( session.exists( "cn=parent,ou=system" ) );
+        }
+    }
+{code}
+
+h3. Asynchronous delete
+
+You can also decide to send an asynchronous delete request : the method will return a Future that you can check later. You have to construct a *[DIRAPI:DeleteRequest]* instance. Here is an example :
+
+{code:java}
+    @Test
+    public void testDeleteAsync() throws Exception
+    {
+        assertTrue( session.exists( "cn=child,cn=parent,ou=system" ) );
+
+        DeleteRequest deleteRequest = new DeleteRequestImpl();
+        deleteRequest.setName( new Dn( "cn=child,cn=parent,ou=system" ) );
+
+        DeleteFuture deleteFuture = connection.deleteAsync( deleteRequest );
+
+        DeleteResponse deleteResponse = deleteFuture.get( 1000, TimeUnit.MILLISECONDS );
+
+        assertNotNull( deleteResponse );
+        assertEquals( ResultCodeEnum.SUCCESS, deleteResponse.getLdapResult().getResultCode() );
+        assertFalse( session.exists( "cn=child,cn=parent,ou=system" ) );
+    }
+{code}
\ No newline at end of file

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-6-modifying-entries.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-6-modifying-entries.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-6-modifying-entries.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-6-modifying-entries.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,3 @@
+h2. Modifying entries
+
+TODO...
\ No newline at end of file

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-7-moving-and-renaming-entries.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-7-moving-and-renaming-entries.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-7-moving-and-renaming-entries.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-7-moving-and-renaming-entries.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,3 @@
+h2. Moving and Renaming entries
+
+TODO...
\ No newline at end of file

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-8-comparing-entries.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-8-comparing-entries.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-8-comparing-entries.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-8-comparing-entries.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,3 @@
+h2. Comparing entries
+
+TODO...
\ No newline at end of file

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-9-exception-management.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-9-exception-management.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-9-exception-management.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-3/3-9-exception-management.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,65 @@
+h2. Exception management
+
+{scrollbar}
+
+h3. Introduction
+
+We use some dedicated exceptions for each problem we might encounter while communicating with a LDAP Server. All those exceptions as associated with a *[DIRAPI:ResultCode] value. This chapter will expose the associated exception for each of those values
+
+h3. Ldap operation Exception mapping
+
+Each operation exception inherits from the _LdapOperationException_ class. Those exception are generated when sending a message to the remote server, and may be thrown as a result of the called operation. In any case, they are only issued after having had an exchange with the remote server.
+
+
+The following table expose the relation between a *ResultCode* and its associated exception (note that some *ResultCodes* are not associated with an exception, they are either for a successful operation, or an intermediate result ) :
+
+|| ResultCode || Exception ||
+| SUCCESS | no exception |
+| REFERRAL | no exception |
+| SASL_BIND_IN_PROGRESS | no exception |
+| CANCELED | no exception |
+| COMPARE_TRUE | no exception |
+| COMPARE_FALSE | no exception |
+| PARTIAL_RESULTS | no exception |
+| INVALID_CREDENTIALS | LdapAuthenticationException |
+| UNWILLING_TO_PERFORM | LdapUnwillingToPerformException |
+| UNAVAILABLE_CRITICAL_EXTENSION | LdapUnwillingToPerformException |
+| INSUFFICIENT_ACCESS_RIGHTS | LdapNoPermissionException |
+| NOT_ALLOWED_ON_NON_LEAF | LdapContextNotEmptyException |
+| NO_SUCH_OBJECT | LdapNoSuchObjectException |
+| NO_SUCH_ATTRIBUTE | LdapNoSuchAttributeException |
+| ATTRIBUTE_OR_VALUE_EXISTS | LdapAttributeInUseException |
+| ENTRY_ALREADY_EXISTS | LdapEntryAlreadyExistsException |
+| OBJECT_CLASS_VIOLATION | LdapSchemaViolationException |
+| NOT_ALLOWED_ON_RDN | LdapSchemaViolationException |
+| OBJECT_CLASS_MODS_PROHIBITED | LdapSchemaViolationException |
+| ALIAS_PROBLEM | LdapAliasException |
+| AFFECTS_MULTIPLE_DSAS | LdapAffectMultipleDsaException |
+| ALIAS_DEREFERENCING_PROBLEM | LdapAliasDereferencingException |
+| AUTH_METHOD_NOT_SUPPORTED | LdapAuthenticationNotSupportedException |
+| INAPPROPRIATE_AUTHENTICATION | LdapAuthenticationNotSupportedException |
+| CONFIDENTIALITY_REQUIRED | LdapAuthenticationNotSupportedException | 
+| BUSY | LdapServiceUnavailableException |
+| UNAVAILABLE | LdapServiceUnavailableException |
+| CONSTRAINT_VIOLATION | LdapInvalidAttributeValueException |
+| INVALID_ATTRIBUTE_SYNTAX | LdapInvalidAttributeValueException |
+| INAPPROPRIATE_MATCHING |  LdapInvalidSearchFilterException |
+| INVALID_DN_SYNTAX | LdapInvalidDnException |
+| NAMING_VIOLATION | LdapInvalidDnException |
+| LOOP_DETECT | LdapLoopDetectedException |
+| OPERATIONS_ERROR | LdapOperationErrorException |
+| PROTOCOL_ERROR | LdapProtocolErrorException |
+| TIME_LIMIT_EXCEEDED | LdapTimeLimitExceededException |
+| UNDEFINED_ATTRIBUTE_TYPE | LdapInvalidAttributeTypeException |
+| OTHER | LdapOtherException |
+| TOO_LATE | LdapTooLateException |
+| UNKNOWN | LdapUnknownException |
+| ADMIN_LIMIT_EXCEEDED | LdapAdminLimitExceededException |
+| CANNOT_CANCEL | LdapCannotCancelException |
+| E_SYNC_REFRESH_REQUIRED | LdapOperationException |
+| STRONG_AUTH_REQUIRED | LdapStringAuthenticationRequiredException |
+| SIZE_LIMIT_EXCEEDED | LdapSizeLimitExceededException |
+| NO_SUCH_OPERATION | LdapNoSuchOperationException |
+
+h3. Other exceptions
+TO BE CONTINUED
\ No newline at end of file

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-1-controls.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-1-controls.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-1-controls.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-1-controls.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,102 @@
+h2. Controls
+
+A *Control* is used to extend *LDAP* operations. They can be used for requests and responses. They basically modify the operation's semantic. For instance, when using a _DeleteTree_ *Control* within a delete operation, you will be able to delete not only the entry itself, but also all of its children. Obviously, this *Control* has a meaning for the _delete_ operation, not for any other operation.
+
+Each server is free to implement the *Controls* it wants, so you have to check if the *Control* you want to use is a supported one.
+
+h3. Control structure
+
+A *Control* contains three elements :
+* An *[DIRAPI:Oid]*, which names the control
+* A _criticality_ flag, telling if this control semantic has to be applied. It's only set for a Request.
+* A value, which is an opaque array of bytes. Each *Control* knows how to decode its value
+
+What is important is that the value has to be encoded before the control is send to the server (or back to the client, if it's a response's *Control*). If the user does not know about the *Control* semantic, then it's impossible to encode or decode this value. However, usually, the *LDAP API* provides the needed controls (or it can be extended).
+
+h3. Existing controls
+
+There are a list of existing controls, defined in RFCs. Not all those controls are supported by all the *LDAP* servers, nor this is mandatory that a *Control* is to be implemented (except a very few ones).
+
+|| OID || RFC || Description || 
+| 1.2.840.113549.6.0 | [RFC2649|http://tools.ietf.org/html/rfc2649] | An LDAP Control and Schema for Holding Operation Signatures |
+| 1.2.840.113556.1.4.319 | [RFC2696|http://tools.ietf.org/html/rfc2696] | LDAP Control Extension for Simple Paged Results Manipulation |
+| 1.2.840.113556.1.4.473 | [RFC2891|http://tools.ietf.org/html/rfc2891] | LDAP Control Extension for Server Side Sorting of Search Results |
+| 2.16.840.1.113730.3.2.6 | [RFC3296|http://tools.ietf.org/html/rfc3296] | Named Subordinate References |
+| 2.16.840.1.113730.3.4.15, 2.16.840.1.113730.3.4.16 | [RFC3829|http://tools.ietf.org/html/rfc3829] | Authorization Identity Request and Response Controls |
+| 2.16.840.1.113730.3.4.18 | [RFC4370|http://tools.ietf.org/html/rfc4370] | Proxied Authorization Control |
+| 1.3.6.1.1.13.1, 1.3.6.1.1.13.2 | [RFC4527|http://tools.ietf.org/html/rfc4527] | Read Entry Controls |
+| 1.3.6.1.1.12 | [RFC4528|http://tools.ietf.org/html/rfc4528] | Assertion Control |
+| 1.3.6.1.1.22 | [RFC6171|http://tools.ietf.org/html/rfc6171] | Don't Use Copy Control |
+
+h4. AD supported controls
+|| OID || Description ||
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+(TODO)
+
+h4. ApacheDS supported controls
+|| OID || Name || Description ||
+| 1.3.6.1.4.1.18060.0.0.1 | Cascade | Used to manage the deletion of schema elements |
+| 2.16.840.1.113730.3.2.6 | ManageDSAIt | ManageDSA IT control [RFC3296|http://tools.ietf.org/html/rfc3296] |
+| 1.2.840.113556.1.4.319 | PagedResults | Paged Results control [RFC2696|http://tools.ietf.org/html/rfc2696] |
+| 2.16.840.1.113730.3.4.3 | PersistentSearch | PersistentSearch request control [psearch draft|http://www3.ietf.org/proceedings/01aug/I-D/draft-ietf-ldapext-psearch-03.txt] |
+| 2.16.840.1.113730.3.4.7 | EntryChange | PersistentSearch response control ([psearch draft|http://www3.ietf.org/proceedings/01aug/I-D/draft-ietf-ldapext-psearch-03.txt])|
+| 1.3.6.1.4.1.4203.1.10.1 | Subentries | [RFC3672|http://tools.ietf.org/html/rfc3672] |
+| 1.3.6.1.4.1.4203.1.9.1.1 | SyncRequestValye | Replication [RFC4533|http://tools.ietf.org/html/rfc4533] |
+| 1.3.6.1.4.1.4203.1.9.1.2 | SyncStateValue | Replication [RFC4533|http://tools.ietf.org/html/rfc4533] |
+| 1.3.6.1.4.1.4203.1.9.1.3 | SyncDoneValue | Replication [RFC4533|http://tools.ietf.org/html/rfc4533]  |
+| 1.3.6.1.4.1.4203.1.9.1.4 | SyncInfoValue | Replication [RFC4533|http://tools.ietf.org/html/rfc4533]  |
+| 1.3.6.1.4.1.4203.1.9.1.5 | SyncModifyDn | Replication [RFC4533|http://tools.ietf.org/html/rfc4533]  |
+
+
+h4. IDS supported controls
+|| OID || Description ||
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+(TODO)
+
+h4. OpenLDAP supported controls
+|| OID || Description ||
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+(TODO)
+
+h4. OpenDJ supported controls
+|| OID || Description ||
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+(TODO)
+
+h4. OpenDS supported controls
+|| OID || Description ||
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+(TODO)
+
+h4. SunDS supported controls
+|| OID || Description ||
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+|  |  |
+(TODO)
+
+
+...(to be continued)
+

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-2-extended-operations.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-2-extended-operations.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-2-extended-operations.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-2-extended-operations.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,3 @@
+h2. Extended operations
+
+

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-3-referrals.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-3-referrals.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-3-referrals.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-3-referrals.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,2 @@
+h2. Referrals
+

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-4-aliases.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-4-aliases.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-4-aliases.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-4-aliases.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,2 @@
+h2. Aliases
+

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-5-ldif-and-dsml.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-5-ldif-and-dsml.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-5-ldif-and-dsml.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-5-ldif-and-dsml.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,21 @@
+h2. LDIF and DSML
+
+Entries are stored in the *LDAP* database in a format that is not readable. This is not convenient when one wants to manipulate entries as text. Hopefully, two formats have been defined that allows a user to describe an entry using a text editor. 
+
+One small issue is that some of the attributes may be binary, thus cannot be described using a text. We also have to deal with non ASCII characters, like european accents or languages like Japanese. 
+
+We will see how those constraints can be fulfilled by the two formats, *LDIF* and *DSML*.
+
+h3. LDIF format
+
+The *LDIF* format is a full ASCII text format. It can be used to describe a full entry, and thus be injected into a LDAP server, but it ca also be used to apply some modification on existing entries.
+
+It is described in the *[RFC2849|http://www.ietf.org/rfc/rfc2849.txt]*.
+
+The *LDAP API* has three classes that can be used to manipulate a *LDIF* entry :
+* *[DIRAPI:LdifEntry]* : contains the entry when it has been parsed, but can also be created from scotch. We can get the entry exported in the *LDIF* format.
+* *LdifReader* : This class is able to read a _String_ or a file which contains *LDIF* framed entries, and produces a list of *LdifEntry*.
+* *LdifUtils* : 
+
+TO BE CONTINUED
+

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-6-abandonning-and-operation.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-6-abandonning-and-operation.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-6-abandonning-and-operation.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-6-abandonning-and-operation.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,2 @@
+h2. Abandonning an operation
+

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-7-server-informations.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-7-server-informations.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-7-server-informations.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-4/4-7-server-informations.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,2 @@
+h2. Server informations
+

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-1-schemamanager.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-1-schemamanager.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-1-schemamanager.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-1-schemamanager.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,39 @@
+h2. The SchemaManager
+
+Apache DS has to keep the schema elements available from all the parts of the server. This is done through what we call the *SchemaManager*. It hides all the internal structure from the users.
+
+h3. Description
+
+The *SchemaManager* stores all the Schema elements (*[AttributeTypes (e)]*, *[ObjectClasses (e)]*, ... Internally, we store those elements into the *Registries*, which are hives where each Schema Objects are stored.
+
+From the user point of view, the *SchemaManager* is seen as a representation of the available schemas. It can of course be extended, or modified, by adding or removing some schema elements.
+
+The server has one instance of a *SchemaManager*, which is used internally, and a user won't control it, in any case. On the client side, we can load a *SchemaManager* either from the server (and then we have a duplicated instance), or from existing schema files. We can even create a brand new *SchemaManager* and fill it with all what we need.
+
+h3. Content
+
+The *SchemaManager* stores all the 11 kind of schema elements :
+
+|| Name ||
+| *[ObjectClass (e)]* |
+| *[AttributeType (...)]* |
+| *[LdapSyntax (e)]* |
+| *[MatchingRule (e)]* |
+| *[DITContentRule (e)]* |
+| *[DITStructureRule (e)]* |
+| *[NameForm (e)]* |
+| *[MatchingRuleUse (e)]* |
+| _*[SyntaxChecker (e)]{*}_ |
+| _*[Normalizer (e)]{*}_ |
+| _*[LdapComparator (e)]{*}_ |
+
+The last three elements are ApacheDS specific.
+
+All those elements have some tight relationships. The following schema expose all the relations between all those elements :
+
+!SchemaObjects.png|border=1!
+
+
+h3. Using a SchemaManager
+
+

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-2-attribute-types.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-2-attribute-types.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-2-attribute-types.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-2-attribute-types.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. Attribute Types

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-3-object-classes.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-3-object-classes.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-3-object-classes.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-3-object-classes.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. Object Classes

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-4-matching-rules.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-4-matching-rules.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-4-matching-rules.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-4-matching-rules.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. Matching Rules

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-5-syntaxes.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-5-syntaxes.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-5-syntaxes.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-5-syntaxes.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. Syntaxes

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-6-name-forms.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-6-name-forms.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-6-name-forms.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-6-name-forms.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. Name Forms

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-7-dit-content-rules.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-7-dit-content-rules.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-7-dit-content-rules.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-7-dit-content-rules.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. DIT Content Rules

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-8-dit-structure-rules.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-8-dit-structure-rules.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-8-dit-structure-rules.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-8-dit-structure-rules.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. DIT Structure Rules

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-9-matching-rule-uses.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-9-matching-rule-uses.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-9-matching-rule-uses.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-5/5-9-matching-rule-uses.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. Matching Rule Uses

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-1-aci-and-acls.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-1-aci-and-acls.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-1-aci-and-acls.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-1-aci-and-acls.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. ACI and ACLs

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-2-ssl.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-2-ssl.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-2-ssl.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-2-ssl.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. SSL

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-3-start-tls.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-3-start-tls.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-3-start-tls.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-3-start-tls.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. StartTLS

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-4-password-policy.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-4-password-policy.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-4-password-policy.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-6/6-4-password-policy.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1 @@
+h2. Password Policy

Added: directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-7/7-01-Entry.confluence
URL: http://svn.apache.org/viewvc/directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-7/7-01-Entry.confluence?rev=1186334&view=auto
==============================================================================
--- directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-7/7-01-Entry.confluence (added)
+++ directory/documentation/ldap-api-manuals/trunk/src/ldap-api-user-guide-confluence/chapter-7/7-01-Entry.confluence Wed Oct 19 16:58:05 2011
@@ -0,0 +1,579 @@
+h2. Entry
+
+The *Entry* class is one of the most important one in the *API*. It describes the base element stored into a *LDAP* server, and it associates a *[#Dn]* and some *[#Attribute]s*.
+
+We have two kinds of *Entry* in the *API*, depending on the presence of a *[SchemaManager (...)]* in the *Entry*, or not.
+
+We also provide a few extended classes, like the *ImmutableEntry*, an immutable version of the *Entry*.
+
+h3. Creating an Entry
+
+We have many ways to create an *Entry*. Basically, an *Entry* has a *[DIRAPI:Dn]* and some *[DIRAPI:Attribute]s*. It can be schema aware, or not. We provide constructors to allow a user to create the kind of *Entry* he wants.
+
+The simplest way to create an *Entry* is to call the default constructor. The created entry will have no attributes, and no Dn. We can also make it schema aware by passing a *[SchemaManager (...)]*. Here is an example:
+
+{code:java}
+    @Test
+    public void testCreateEmptyEntry()
+    {
+        Entry entry = new DefaultEntry();
+        
+        assertNotNull( entry.getDn() );
+        assertEquals( Dn.EMPTY_DN, entry.getDn() );
+        assertNotNull( entry.getAttributeTypes() );
+        assertEquals( 0, entry.size() );
+        assertFalse( entry.isSchemaAware() );
+
+        Entry entry2 = new DefaultEntry( schemaManager);
+        
+        assertNotNull( entry2.getDn() );
+        assertEquals( Dn.EMPTY_DN, entry2.getDn() );
+        assertNotNull( entry2.getAttributeTypes() );
+        assertEquals( 0, entry2.size() );
+        assertTrue( entry2.isSchemaAware() );
+    }
+{code}
+
+You can also create an *Entry* passing a *[DIRAPI:Dn]*, but no attribute. We can create schema aware entries this way too, passing a *[SchemaManager (...)]*.
+
+{code:java}
+    @Test
+    public void testCreateEntryWithDn() throws LdapException
+    {
+        Dn dn = new Dn( schemaManager, "DomainComponent=example, dc=COM" );
+        Entry entry = new DefaultEntry( "dc=example, dc=com" );
+        
+        assertNotNull( entry.getDn() );
+        assertEquals( "dc=example, dc=com", entry.getDn().toString() );
+        assertNotNull( entry.getAttributeTypes() );
+        assertEquals( 0, entry.size() );
+        assertFalse( entry.isSchemaAware() );
+
+        Entry entry2 = new DefaultEntry( schemaManager, "dc=example, dc=com" );
+        
+        assertNotNull( entry2.getDn() );
+        assertEquals( dn, entry2.getDn() );
+        assertNotNull( entry2.getAttributeTypes() );
+        assertEquals( 0, entry2.size() );
+        assertTrue( entry2.isSchemaAware() );
+    }
+{code}
+
+We can also create an entry by copying an existing entry. The created *Entry* must be schema aware. Here is an example:
+
+{code:java}
+    @Test
+    public void testCreateEntryCopy() throws LdapException
+    {
+        Entry entry = new DefaultEntry( schemaManager, "dc=example, dc=com" );
+        entry.add( atCn, "test" );
+        entry.add( atSn, "Test" );
+        entry.add( atObjectClass, "top", "person" );
+        
+        Entry entry2 = new DefaultEntry( schemaManager, entry );
+        
+        assertEquals( entry.getDn(), entry2.getDn() );
+        
+        entry.clear();
+        assertTrue( entry2.contains( atCn, "TEST" ) );
+        assertTrue( entry2.contains( atSn, "TEST" ) );
+        assertTrue( entry2.contains( atObjectClass, "top", "person" ) );
+    }
+{code}
+
+Last, not least, it's possible to create an *Entry* using a list of LDIF formated attributes. An example worth ten lines of documentation, so let's see what it means.
+
+First, we will create a schema agnostic entry:
+
+{code:java}
+    @Test
+    public void testCreateEntryLdif() throws Exception
+    {
+        Entry entry = new DefaultEntry( 
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "cn: test",
+            "sn: test"
+            );
+        
+        assertEquals( "dc=example, dc=com", entry.getDn().toString() );
+        assertTrue( entry.contains( "cn", "test" ) );
+        assertTrue( entry.contains( "sn", "test" ) );
+        assertTrue( entry.contains( "objectClass", "top", "person" ) );
+    }
+{code}
+
+We can also provide a complete LDIF file (except that we can't add the _dn_):
+
+{code:java}
+    @Test
+    public void testCreateEntryLdifComplete() throws Exception
+    {
+        String ldif =
+            "objectClass: top\n" +           // The \n is mandatory.
+            "objectClass: person\n" +
+            "cn: test\n" +
+            "sn: test";
+
+        Entry entry = new DefaultEntry( "dc=example, dc=com", ldif );
+        
+        assertEquals( "dc=example, dc=com", entry.getDn().toString() );
+        assertTrue( entry.contains( "cn", "test" ) );
+        assertTrue( entry.contains( "sn", "test" ) );
+        assertTrue( entry.contains( "objectClass", "top", "person" ) );
+    }
+{code}
+
+One can also combine LDIF and variables like in this example (note that if you use a variable, the attribute must not be followed by the *':'* char):
+
+{code:java}
+    @Test
+    public void testCreateEntryLdif2() throws Exception
+    {
+        String name = "test";
+        String surname = "test";
+        
+        Entry entry = new DefaultEntry( 
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "cn", name,             // No ':'
+            "sn", surname
+            );
+        
+        assertEquals( "dc=example, dc=com", entry.getDn().toString() );
+        assertTrue( entry.contains( "cn", "test" ) );
+        assertTrue( entry.contains( "sn", "test" ) );
+        assertTrue( entry.contains( "objectClass", "top", "person" ) );
+    }
+{code}
+
+h3. Modifying an Entry
+We have four methods available that modify the *Entry* content : _add_, _remove_, _put_ and _set_. We will review those four methods in the following paragraphs.
+
+h4. Adding Attributes
+Two methods can be used to add some attribute into an *Entry*, depending on the fact that we will add some value without replacing an existing attribute with the same name (and we use the _add_ method for that), or replace it with a new attribute (and we use the _put_ method for that).
+
+In any case, we can add either an empty attribute, or an attribute with some values. Those values can be _Strings_, _byte[]_ or *[DIRAPI:Value]s*. The added attributes can be schema aware, and we can also provide a user provided name for the attribute type.
+
+h5. add() methods
+
+The first method makes it possible to add some existing *[DIRAPI:Attribute]* to an *Entry*. Let's see how it works:
+
+{code:java}
+    @Test
+    public void testEntryAddAttribute() throws LdapException
+    {
+        Attribute cn = new DefaultAttribute( "cn", "test" );
+        Attribute cn2 = new DefaultAttribute( "cn", "test2" );
+        
+        Entry entry = new DefaultEntry( 
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test" );
+        
+        assertFalse( entry.containsAttribute( "cn" ) );
+        
+        // Add the new attribute
+        entry.add( cn );
+        
+        assertTrue( entry.contains( "cn", "test" ) );
+        
+        // Try to add a second value
+        entry.add( cn2 );
+
+        // Both values must be present
+        assertTrue( entry.contains( "cn", "test", "test2" ) );
+    }
+{code}
+
+Otherwise, we can add a new attribute and values into the *Entry* by passing both parameters. We can also pass an *[AttributeType (...)]* to the _add()_ method, making the added attribute schema aware. Note that if the *Entry* itself is already schema aware, this is not necessary.
+
+Here are some examples, the first one with a schema aware *Entry*, the second one with a schema agnostic *Entry*:
+
+{code:java}
+    @Test
+    public void testEntryAddAtValue() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            schemaManager,
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test" );
+        
+        assertFalse( entry.containsAttribute( "cn" ) );
+        
+        // Add the new attribute
+        entry.add( "cn", "test" );
+        
+        assertTrue( entry.contains( "CN", "test" ) );
+        
+        // Try to add a second value
+        entry.add( atCn, "A  second test   " );
+
+        // Both values must be present
+        assertTrue( entry.contains( "cn", "test", "a second test" ) );
+    }
+{code}
+
+{note:title=Warning !}
+When manipulating a schema agnostic *Entry*, do not expect that the attribute type will be recognized if you inject schema aware attributes.
+{note}
+
+{code:java}
+    @Test
+    public void testEntryAddAtValue() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test" );
+        
+        assertFalse( entry.containsAttribute( "cn" ) );
+        
+        // Add the new attribute
+        entry.add( "cn", "test" );
+        
+        assertTrue( entry.contains( "cn", "test" ) );
+        
+        // Try to add a second value
+        entry.add( atCn, "A  second  test" );
+
+        // Both values must be present
+        assertTrue( entry.contains( "cn", "test" ) );
+        assertTrue( entry.contains( "2.5.4.3", "a second test" ) );
+        assertFalse( entry.contains( "cn", "A  second  test" ) );
+    }
+{code}
+
+h5. put() methods
+
+The big difference with the _add_ method is that the attribute is not added, it will replace an existing one. let's see with an example :
+
+{code:java}
+    @Test
+    public void testEntryPutAttribute() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            schemaManager, 
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test" );
+        
+        assertFalse( entry.containsAttribute( "cn" ) );
+        
+        // Add the new attribute
+        entry.put( "cn", "test" );
+        
+        assertTrue( entry.contains( "cn", "test" ) );
+        
+        // Try to add a second value
+        entry.put( "cn", "test2" );
+
+        // Both values must be present
+        assertFalse( entry.contains( "cn", "test", "test2" ) );
+        assertFalse( entry.contains( "cn", "test" ) );
+        assertTrue( entry.contains( "cn", "test2" ) );
+    }
+{code}
+
+h4. Removing Attributes
+
+We can remove either an attribute having a specific value, or an entire attribute. In order to remove a complete attribute, you just have to provide the attribute's name, and use the _removeAttributes_ method.
+
+Here are some example for both usages :
+
+{code:java}
+    @Test
+    public void testRemoveAttribute() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            schemaManager,
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test",
+            "cn: test1",
+            "cn: test2",
+            "cn: test3" );
+        
+        assertTrue( entry.contains( "cn", "test1", "test2", "test3" ) );
+        
+        // Remove the "test2" value
+        entry.remove( "cn", "test2" );
+        
+        assertTrue( entry.contains( "cn", "test1", "test3" ) );
+        assertFalse( entry.contains( "cn", "test2" ) );
+        
+        // Try to remove the full attribute
+        entry.removeAttributes( "cn" );
+
+        assertFalse( entry.containsAttribute( "cn" ) );
+    }
+{code}
+
+h5. Storing a Dn
+
+It's also possible to store a new *[DIRAPI:Dn]* into the Entry, using the _setDn() method. It will replace an existing *[DIRAPI:Dn]*. This method takes either a *[DIRAPI:Dn]* instance, or a _String_.
+
+h3. Attribute data access methods
+
+The *API* provides convenient methods to access the *Entry* content, and to check if it contains some attributes or some values. We will shortly expose those methods in the following paragraphs.
+
+h4. Contains method
+The _contains_ and _containsAttributes_ methods check that the *Entry* contain a couple of <attributeType/values> for the first set of methods, and for the existence of a specific attribute for the second method.
+
+One can check for the existence of a specific value for a given attribute, or even for multiple values for a specific attribute. Let's see the _contains_ method in action:
+
+{code:java}
+    @Test
+    public void testContains() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            schemaManager,
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test",
+            "cn: test1",
+            "cn: test2",
+            "cn: test3" );
+        
+        assertTrue( entry.containsAttribute( "cn", "sn" ) );
+        assertTrue( entry.contains( "cn", "test1", "test2", "test3" ) );
+        assertTrue( entry.contains( "cn", "test1" ) );
+
+        // The value does not exist for the "cn" attribute
+        assertFalse( entry.contains( "cn", "test4" ) );
+    }
+{code}
+
+h5. get(AttributeType) and get(String)
+
+Returns the *[DIRAPI:Attribute]* having the given name if it exists. The following test demonstrates its usage:
+
+{code:java}
+    @Test
+    public void testGet() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            schemaManager,
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test",
+            "cn: test1",
+            "cn: test2",
+            "cn: test3" );
+        
+        // With an attribute's name
+        assertNotNull( entry.get( "cn" ) );
+        assertTrue( entry.get( "cn" ).contains( "test1", "test2", "test3" ) );
+
+        // With an AttributeType
+        assertNotNull( entry.get( atSn ) );
+        assertTrue( entry.get( atSn ).contains( "test" ) );
+    }
+{code}
+
+h5. getAttributeTypes()
+
+This method returns the list of *[AttributeType (...)]s* stored into the *Entry*.
+
+{note:title=Be careful !}
+This method is only valuable if the *Entry* is schema aware !
+{note}
+
+Here is an example of usage:
+
+{code:java}
+    @Test
+    public void testGetAttributeTypes() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            schemaManager,
+            "cn=example, dc=com", 
+            "objectClass: top",
+            "objectClass: person",
+            "cn: example",
+            "sn: test"
+            );
+        
+        for ( AttributeType attr : entry.getAttributeTypes() )
+        {
+            System.out.println( attr.getName() );
+        }
+    }
+{code}
+
+This code produces the following output:
+
+{code:java}
+sn
+objectClass
+cn
+{code}
+
+h5. getDn()
+
+This method returns the *Entry*'s *[DIRAPI:Dn]*.
+
+h5. hasObjectClass methods
+
+The _hasObjectClass()_ methods are used to discover if an *Entry* has a specific _ObjectClass_. This is a convenient method, as it's possible to do the same thing with a _contains()_ call, but with one less parameter (you don't have to provide the _"ObjectClass"_ as a first parameter).
+
+Here is an example using the two existing methods:
+
+{code:java}
+    @Test
+    public void testHasObjectClass() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            schemaManager,
+            "cn=example, dc=com", 
+            "objectClass: top",
+            "objectClass: person",
+            "cn: example",
+            "sn: test"
+            );
+        
+        // Test the presence
+        assertTrue( entry.hasObjectClass( "person", " TOP " ) );
+        assertFalse( entry.hasObjectClass( "domain ", "TOP" ) );
+        assertTrue( entry.hasObjectClass( "Person " ) );
+        
+        // Same test, but with Attributes
+        Attribute oc1 = new DefaultAttribute( atObjectClass, "TOP ", "person" );
+        Attribute oc2 = new DefaultAttribute( atObjectClass, "person " );
+        Attribute oc3 = new DefaultAttribute( atObjectClass, "TOP", "domain" );
+        
+        assertTrue( entry.hasObjectClass( oc1, oc2 ) );
+        assertFalse( entry.hasObjectClass( oc1, oc3 ) );
+    }
+{code}
+
+Obviously, dealing with a schema agnostic *Entry*, those methods are more strict. You have to use the exact ObjectClasses case sensitive trimmed names (in the previous example, we can use upper cased names, even with spaces around the names).
+
+Also note that the _hasObjectClass_ method used with *[AttributeType (...)]* does not work on a schema agnostic entry.
+
+h3. Miscellaneous methods
+We also have some other methods which can be used on an *Entry*. Here is a list of those methods.
+
+h5. clear()
+This method removes all the added *[DIRAPI:Attribute]s* from this *Entry*. The *[DIRAPI:Dn]* remains the same.
+
+h5. clone()
+Creates a copy of the current *Entry*. All the *[DIRAPI:Attribute]s* are also cloned.
+
+h5. iterator()
+Allows an iteration over all the *[DIRAPI:Attribute]s*. The following examples shows how this can be used:
+
+{code:java}
+    @Test
+    public void testIterator() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            "cn=example, dc=com", 
+            "objectClass: top",
+            "objectClass: person",
+            "cn: example",
+            "sn: test"
+            );
+        
+        for ( Attribute attribute : entry )
+        {
+            System.out.println( "Attribute : \n" + attribute.toString() );
+        }
+    }
+{code}
+
+This produces the following output:
+
+{code:java}
+Attribute : 
+    sn: test
+
+Attribute : 
+    cn: example
+
+Attribute : 
+    objectclass: top
+    objectclass: person
+{code}
+
+Note that the *[DIRAPI:Attribute]* order is not guaranteed.
+
+h5. isSchemaAware()
+
+Tells if the ¬*Entry* has an associated *[SchemaManager (...)]*.
+
+h5. size()
+Returns the number of *[DIRAPI:Attribute]* stored in the *Entry*.
+
+h5. equals(Object)
+Check if two *Entries* are equal or not. It's important to understand that depending on whether the entry is schema aware or not, the comparison will be processed differently. Typically, the attribute's name must be equals when they have been trimmed and lower cased if the entry is not schema aware, and we can't compare an attribute named 'cn' with another one named '2.5.4.3' in this case (the *Entry* must be schema aware to allow such comparison). More important, the values *must* be identical (same casing, same spaces) in this case.
+The attribute's values order is irrelevant.
+
+Here are one example with a schema agnostic *Entry*:
+
+{code:java}
+    @Test
+    public void testEntryEquals() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test",
+            "cn: test1",
+            "cn: test2",
+            "cn: test3" );
+
+        Entry entry2 = new DefaultEntry( 
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test",
+            "cn: test2",
+            "CN: test1",
+            "cn: test3" );
+
+        assertEquals( entry, entry2 );
+    }
+{code}
+
+and another example with a schema aware *Entry*:
+
+{code:java}
+    @Test
+    public void testSchemaAwayeEntryEquals() throws LdapException
+    {
+        Entry entry = new DefaultEntry( 
+            schemaManager,
+            "dc=example, dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "sn: test",
+            "cn: test1",
+            "cn: test2",
+            "cn: test3" );
+
+        Entry entry2 = new DefaultEntry( 
+            schemaManager,
+            "dc=example,dc=com",
+            "objectClass: TOP",
+            "objectClass: person",
+            "sn: Test",
+            "cn: Test2",
+            "2.5.4.3: test1",
+            "CommonName: test3" );
+
+        assertEquals( entry, entry2 );
+    }
+{code}
+



Mime
View raw message