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

svn commit: r1023911 - in /websites/staging/directory/trunk/content: ./ api/dev-guide/13-controls.html

Author: buildbot
Date: Tue Jan 16 23:35:59 2018
New Revision: 1023911

Log:
Staging update by buildbot for directory

Modified:
    websites/staging/directory/trunk/content/   (props changed)
    websites/staging/directory/trunk/content/api/dev-guide/13-controls.html

Propchange: websites/staging/directory/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Tue Jan 16 23:35:59 2018
@@ -1 +1 @@
-1821250
+1821335

Modified: websites/staging/directory/trunk/content/api/dev-guide/13-controls.html
==============================================================================
--- websites/staging/directory/trunk/content/api/dev-guide/13-controls.html (original)
+++ websites/staging/directory/trunk/content/api/dev-guide/13-controls.html Tue Jan 16 23:35:59 2018
@@ -190,12 +190,43 @@ h2:hover > .headerlink, h3:hover > .head
 <li>a <strong>Criticality</strong> flag, which tells if the control can be ignored or not</li>
 <li>a value, which might be <strong>BER</strong> encoded </li>
 </ul>
-<p>We have 21 <strong>Control</strong>s declared in the <strong>LDAP API</strong>, and we can add more.</p>
+<p>We have 20 <strong>Control</strong>s declared in the <strong>LDAP API</strong>, and we can add more.</p>
 <h2 id="implementation">Implementation<a class="headerlink" href="#implementation" title="Permanent link">&para;</a></h2>
-<p>Here is teh <strong>Control</strong> classes and interfaces hierarchy :</p>
+<p>Here is the <strong>Control</strong> classes and interfaces hierarchy :</p>
 <p><img alt="Control Hierarchy" src="images/controls.png" /></p>
 <p>As we can see, each <em>Impl</em> class is coupled with a <em>Decorator</em> class, used to process teh encoding and decoding of a <strong>Control</strong></p>
 <p>Keep in mind that <strong>Control</strong>s have to be sent within a message, thus be encoded or decoded when the response come back.</p>
+<h2 id="packagemodule">Package/module<a class="headerlink" href="#packagemodule" title="Permanent link">&para;</a></h2>
+<p>We have two flavors of <strong>Control</strong>s, standard and 'extra'. Standard <strong>Control</strong>s are those supported by all he servers, extras are oly supported by a few servers. This is an arbitrary decision, we could have put all of them at teh same place.</p>
+<p>The list of standard <strong>Control</strong>s is :</p>
+<ul>
+<li><em>Cascade</em></li>
+<li><em>EntryChange</em></li>
+<li><em>ManageDsaIT</em></li>
+<li><em>PagedResults</em></li>
+<li><em>PersistentSearch</em></li>
+<li><em>ProxiedAuthz</em></li>
+<li><em>SortRequest</em></li>
+<li><em>SortResponse</em></li>
+<li><em>Subentries</em></li>
+</ul>
+<p>The list of extra <strong>Control</strong>s is :</p>
+<ul>
+<li><em>AdDirSync</em></li>
+<li><em>AdPolicyHints</em></li>
+<li><em>AdShowDeleted</em></li>
+<li><em>ChangeNotifications</em></li>
+<li><em>PermissiveModify</em></li>
+<li><em>PasswordPolicy</em></li>
+<li><em>SyncDoneValue</em></li>
+<li><em>SyncRequestValue</em></li>
+<li><em>SyncStateValue</em></li>
+<li><em>VirtualListViewRequest</em></li>
+<li><em>VirtualListViewResponse</em></li>
+</ul>
+<p>The standard <strong>Control</strong>s are described in the <em>ldap/model</em> module (for the classes and interfaces) and in the <em>ldap/codec/core</em> module (for the <em>Decorator</em> and the decoding classes), in the <em>org.apache.directory.api.ldap.model.message.controls</em> package.</p>
+<p>The extra <strong>Control</strong>s are described in the <em>ldap/extras/codec</em> and <em>ldap/extras/codec-api modules (the first module contains the _classes</em> and <em>interfaces</em>, the second module contains the <em>Decorator_s and all the decoder classes.) , in the _org.apache.directory.api.ldap.extras.controls.XXX</em> packages (one sub-package per control) and in the <em>org.apache.directory.api.ldap.codec.controls.XXX</em> package.</p>
+<p>Any new <strong>Control</strong> is likely to be declared as an extra <strong>Control</strong>.</p>
 <h2 id="creating-a-new-control">Creating a new Control<a class="headerlink" href="#creating-a-new-control" title="Permanent link">&para;</a></h2>
 <p>The <strong>Control</strong> creation follows a few rules :</p>
 <ul>
@@ -220,7 +251,11 @@ update request.
 
 
 <p>The <em>Interface</em> will just expose the <em>Transaction Identifier</em>, and store the <strong>Control</strong> <strong>OID</strong> :</p>
-<div class="codehilite"><pre><span class="cm">/**</span>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">controls</span><span class="o">.</span><span class="na">transaction</span><span class="o">;</span>
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.Control</span><span class="o">;</span>
+
+<span class="cm">/**</span>
 <span class="cm"> * The Transaction Specification control. It&#39;s defined in RFC 5805.</span>
 <span class="cm"> * This control is sent with every update once a transaction is started.</span>
 <span class="cm"> * It contains the Transaction ID. </span>
@@ -248,8 +283,13 @@ update request.
 
 
 <p>We now need an implementation for this <strong>Control</strong>. It really just a matter of having an instanciable object. Note that this class exteds the <em>AbstractControl</em> class.</p>
-<p>Here is it :</p>
-<div class="codehilite"><pre><span class="cm">/**</span>
+<p>Here it is :</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">controls</span><span class="o">.</span><span class="na">transaction</span><span class="o">;</span>
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.controls.AbstractControl</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.util.Strings</span><span class="o">;</span>
+
+<span class="cm">/**</span>
 <span class="cm"> * The Transaction Specification control. It&#39;s defined in RFC 5805.</span>
 <span class="cm"> * This control is sent with every update once a transaction is started.</span>
 <span class="cm"> * It contains the Transaction ID. </span>
@@ -316,10 +356,273 @@ update request.
 
 
 <p>Nothing much to say, except that we have a default constructor that use the <strong>Control</strong>'s <strong>OID</strong> and a <em>toString()</em> method, for convenience. The <em>Identifier</em> is printed in hex format.</p>
-<h3 id="encoding">Encoding<a class="headerlink" href="#encoding" title="Permanent link">&para;</a></h3>
-<h3 id="decoding">Decoding<a class="headerlink" href="#decoding" title="Permanent link">&para;</a></h3>
+<p>That's it for the two base <em>class</em> and <em>interface</em>, we now have to deal with encoding and decoding.</p>
+<h3 id="encoding-decoding">Encoding &amp; Decoding<a class="headerlink" href="#encoding-decoding" title="Permanent link">&para;</a></h3>
+<p>Encoding the <strong>Control</strong> is done by the <strong>Decorator</strong>. This class implements the <em>Asn1Object</em> which defines the method <em>encode()</em>. Let's see how it works...</p>
+<p>In order to encode the value we need to know its length, this is why we also have to implement the <em>computeLegth()</em> method. In our case, it's superflouous, as the length is known : it's the <em>identifier</em>'s length.
+Decoidng is quitre trivial : as we only need to decode the <strong>Control</strong> value, and as it's an opaque <em>byte[]</em>, we just need to copy this value in the instance.</p>
+<p>In any case, we don't encode the whole <strong>Control</strong>, we just encode it's value : the <strong>Control</strong> itself is encode by the <strong>LdapMessage</strong>.</p>
+<p>Here is the <em>Decorator</em> code.</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">controls</span><span class="o">.</span><span class="na">transaction</span><span class="o">;</span>
+
+<span class="kn">import</span> <span class="nn">java.nio.ByteBuffer</span><span class="o">;</span>
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.asn1.Asn1Object</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.asn1.DecoderException</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.asn1.EncoderException</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.ControlDecorator</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.LdapApiService</span><span class="o">;</span>
+
+<span class="cm">/**</span>
+<span class="cm"> * TransactionSpecification decorator.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">TransactionSpecificationDecorator</span> <span class="kd">extends</span> <span class="n">ControlDecorator</span><span class="o">&lt;</span><span class="n">TransactionSpecification</span><span class="o">&gt;</span> <span class="kd">implements</span> <span class="n">TransactionSpecification</span>
+<span class="o">{</span>
+    <span class="cm">/**</span>
+<span class="cm">     * Create a new instance of TransactionSpecificationDecorator</span>
+<span class="cm">     * </span>
+<span class="cm">     * @param codec  The LDAP Service to use</span>
+<span class="cm">     * @param decoratedControl The control to decorate</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">TransactionSpecificationDecorator</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span><span class="o">,</span> <span class="n">TransactionSpecification</span> <span class="n">decoratedControl</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="kd">super</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="n">decoratedControl</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">Asn1Object</span> <span class="nf">decode</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">controlBytes</span> <span class="o">)</span> <span class="kd">throws</span> <span class="n">DecoderException</span>
+    <span class="o">{</span>
+        <span class="c1">// Nothing to decode, the byte array is copied as is in identifier</span>
+        <span class="n">setIdentifier</span><span class="o">(</span> <span class="n">controlBytes</span> <span class="o">);</span>
+
+        <span class="k">return</span> <span class="k">this</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">computeLength</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="kt">byte</span><span class="o">[]</span> <span class="n">identifier</span> <span class="o">=</span> <span class="n">getDecorated</span><span class="o">().</span><span class="na">getIdentifier</span><span class="o">();</span>
+
+        <span class="k">if</span> <span class="o">(</span> <span class="n">identifier</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="k">return</span> <span class="n">identifier</span><span class="o">.</span><span class="na">length</span><span class="o">;</span>
+        <span class="o">}</span>
+        <span class="k">else</span>
+        <span class="o">{</span>
+            <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="o">;</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">ByteBuffer</span> <span class="nf">encode</span><span class="o">(</span> <span class="n">ByteBuffer</span> <span class="n">buffer</span> <span class="o">)</span> <span class="kd">throws</span> <span class="n">EncoderException</span>
+    <span class="o">{</span>
+        <span class="kt">byte</span><span class="o">[]</span> <span class="n">identifier</span> <span class="o">=</span> <span class="n">getDecorated</span><span class="o">().</span><span class="na">getIdentifier</span><span class="o">();</span>
+
+        <span class="k">if</span> <span class="o">(</span> <span class="n">identifier</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+        <span class="o">{</span>
+            <span class="n">ByteBuffer</span> <span class="n">encoded</span> <span class="o">=</span> <span class="n">ByteBuffer</span><span class="o">.</span><span class="na">allocate</span><span class="o">(</span> <span class="n">identifier</span><span class="o">.</span><span class="na">length</span> <span class="o">);</span>
+
+            <span class="n">encoded</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">identifier</span> <span class="o">);</span>
+
+            <span class="k">return</span> <span class="n">encoded</span><span class="o">;</span>
+        <span class="o">}</span>
+        <span class="k">else</span>
+        <span class="o">{</span>
+            <span class="k">return</span> <span class="n">ByteBuffer</span><span class="o">.</span><span class="na">allocate</span><span class="o">(</span> <span class="mi">0</span> <span class="o">);</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="nf">getIdentifier</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="nf">getDecorated</span><span class="o">().</span><span class="na">getIdentifier</span><span class="o">();</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setIdentifier</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">identifier</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="n">getDecorated</span><span class="o">().</span><span class="na">setIdentifier</span><span class="o">(</span> <span class="n">identifier</span> <span class="o">);</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h3 id="the-factory">The Factory<a class="headerlink" href="#the-factory" title="Permanent link">&para;</a></h3>
+<p>We also need a <em>Factory</em> class that is used to register the <strong>Control</strong>. This class simply expose a constructor for the <strong>Control</strong>. It's code is pretty trival, there is nothing specific to the added <strong>Control</strong>.</p>
+<p>Side note : as this class is ony invoked at startup, we could use reflection instead of having one <em>Factory</em> per <strong>Control</strong>...</p>
+<div class="codehilite"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">directory</span><span class="o">.</span><span class="na">api</span><span class="o">.</span><span class="na">ldap</span><span class="o">.</span><span class="na">extras</span><span class="o">.</span><span class="na">controls</span><span class="o">.</span><span class="na">transaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.CodecControl</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.ControlFactory</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.LdapApiService</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * A codec {@link ControlFactory} implementation for {@link TransactionSpecification} controls.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">TransactionSpecificationFactory</span> <span class="kd">implements</span> <span class="n">ControlFactory</span><span class="o">&lt;</span><span class="n">TransactionSpecification</span><span class="o">&gt;</span>
+<span class="o">{</span>
+    <span class="cm">/** The LDAP codec responsible for encoding and decoding Cascade Controls */</span>
+    <span class="kd">private</span> <span class="n">LdapApiService</span> <span class="n">codec</span><span class="o">;</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * Creates a new instance of TransactionSpecificationFactory.</span>
+<span class="cm">     *</span>
+<span class="cm">     * @param codec The LDAP codec</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="nf">TransactionSpecificationFactory</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">this</span><span class="o">.</span><span class="na">codec</span> <span class="o">=</span> <span class="n">codec</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">String</span> <span class="nf">getOid</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">TransactionSpecification</span><span class="o">.</span><span class="na">OID</span><span class="o">;</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">CodecControl</span><span class="o">&lt;</span><span class="n">TransactionSpecification</span><span class="o">&gt;</span> <span class="n">newCodecControl</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span> <span class="nf">TransactionSpecificationDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="k">new</span> <span class="n">TransactionSpecificationImpl</span><span class="o">()</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+
+    <span class="cm">/**</span>
+<span class="cm">     * {@inheritDoc}</span>
+<span class="cm">     */</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">CodecControl</span><span class="o">&lt;</span><span class="n">TransactionSpecification</span><span class="o">&gt;</span> <span class="n">newCodecControl</span><span class="o">(</span> <span class="n">TransactionSpecification</span> <span class="n">control</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span> <span class="nf">TransactionSpecificationDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="n">control</span> <span class="o">);</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="a-more-complex-control">A more complex Control<a class="headerlink" href="#a-more-complex-control" title="Permanent link">&para;</a></h2>
+<p>We just shown a <strong>Control</strong> which was easy to encode or decode. Most of the time, the <strong>Control</strong>'s value is itself an <strong>ASN/1</strong> <strong>BER</strong> encoded value, and we need more classes to be able to process the decoding. Let use another <strong>Control</strong> as a sample : </p>
+<p>TODO</p>
 <h2 id="adding-a-control-to-the-api">Adding a Control to the API<a class="headerlink" href="#adding-a-control-to-the-api" title="Permanent link">&para;</a></h2>
-<p>When </p>
+<p>Once we have written the <strong>Control</strong> classes and interfaces, we need to declare it so that the <strong>LDAP API</strong> can use it.</p>
+<p>The thing is that the <strong>LDAP API</strong> is <strong>OSGi</strong> compliant, so we need to expose the <strong>Control</strong>s and we also have to activate them.</p>
+<p>The <em>ExtrasBundleActivator</em> class (in the <em>ldap/extras/codec</em> module) has to be modified to register and unregister the added <strong>Control</strong> :</p>
+<div class="codehilite"><pre><span class="o">...</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.controls.changeNotifications.TransactionSpecification</span><span class="o">;</span>
+<span class="o">...</span>
+
+<span class="cm">/**</span>
+<span class="cm"> * A BundleActivator for the ldap codec extras extension: extra ApacheDS and </span>
+<span class="cm"> * Apache Directory Studio specific controls and extended operations. </span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ExtrasBundleActivator</span> <span class="kd">implements</span> <span class="n">BundleActivator</span>
+<span class="o">{</span>
+    <span class="o">....</span>
+    <span class="cm">/**</span>
+<span class="cm">     * Registers all the extras controls present in this control pack.</span>
+<span class="cm">     *</span>
+<span class="cm">     * @param codec The codec service.</span>
+<span class="cm">     */</span>
+    <span class="kd">private</span> <span class="kt">void</span> <span class="nf">registerExtrasControls</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="n">ControlFactory</span><span class="o">&lt;</span><span class="n">AdDirSync</span><span class="o">&gt;</span> <span class="n">adDirSyncFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AdDirSyncFactory</span><span class="o">(</span> <span class="n">codec</span> <span class="o">);</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">registerControl</span><span class="o">(</span> <span class="n">adDirSyncFactory</span> <span class="o">);</span>
+        <span class="o">...</span>
+
+        <span class="n">ControlFactory</span><span class="o">&lt;</span><span class="n">TransactionSpecification</span><span class="o">&gt;</span> <span class="n">TransactionSpecificationFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TransactionSpecificationFactory</span><span class="o">(</span> <span class="n">codec</span> <span class="o">);</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">registerControl</span><span class="o">(</span> <span class="n">TransactionSpecification</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="o">...</span>
+
+    <span class="kd">private</span> <span class="kt">void</span> <span class="nf">unregisterExtrasControls</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">unregisterControl</span><span class="o">(</span> <span class="n">AdDirSync</span><span class="o">.</span><span class="na">OID</span> <span class="o">);</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">unregisterControl</span><span class="o">(</span> <span class="n">AdShowDeleted</span><span class="o">.</span><span class="na">OID</span> <span class="o">);</span>
+        <span class="o">...</span>
+        <span class="n">codec</span><span class="o">.</span><span class="na">unregisterControl</span><span class="o">(</span> <span class="n">TransactionSpecification</span><span class="o">.</span><span class="na">OID</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="o">....</span>
+</pre></div>
+
+
+<p>Here we added the <em>TransactionSpecification</em> <strong>Control</strong> at the end of thse two methods, and added the associated <em>import</em>.</p>
+<p>Last, not least, we need to update the <em>loadStockControls</em> method in the <em>CodecFactoryUtil</em> class (in <em>ldap/codec/standalone</em> module) :</p>
+<div class="codehilite"><pre><span class="o">...</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.controls.changeNotifications.TransactionSpecification</span><span class="o">;</span>
+<span class="o">...</span>
+
+<span class="cm">/**</span>
+<span class="cm"> * A utility class for adding Codec and extended operation factories.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author &lt;a href=&quot;mailto:dev@directory.apache.org&quot;&gt;Apache Directory Project&lt;/a&gt;</span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">CodecFactoryUtil</span>
+<span class="o">{</span>
+    <span class="o">....</span>
+    <span class="cm">/**</span>
+<span class="cm">     * Loads the Controls implement out of the box in the codec.</span>
+<span class="cm">     * </span>
+<span class="cm">     * @param controlFactories The Control factories to use</span>
+<span class="cm">     * @param apiService The LDAP Service instance to use</span>
+<span class="cm">     */</span>
+    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">loadStockControls</span><span class="o">(</span> <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">ControlFactory</span><span class="o">&lt;?&gt;&gt;</span> <span class="n">controlFactories</span><span class="o">,</span> <span class="n">LdapApiService</span> <span class="n">apiService</span> <span class="o">)</span>
+    <span class="o">{</span>
+        <span class="c1">// Standard controls</span>
+        <span class="n">ControlFactory</span><span class="o">&lt;</span><span class="n">Cascade</span><span class="o">&gt;</span> <span class="n">cascadeFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">CascadeFactory</span><span class="o">(</span> <span class="n">apiService</span> <span class="o">);</span>
+        <span class="n">controlFactories</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">cascadeFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">(),</span> <span class="n">cascadeFactory</span> <span class="o">);</span>
+        <span class="n">LOG</span><span class="o">.</span><span class="na">info</span><span class="o">(</span> <span class="s">&quot;Registered pre-bundled control factory: {}&quot;</span><span class="o">,</span> <span class="n">cascadeFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">()</span> <span class="o">);</span>
+
+        <span class="o">...</span>
+        <span class="n">ControlFactory</span><span class="o">&lt;</span><span class="n">TransactionSpecification</span><span class="o">&gt;</span> <span class="n">transactionSpecificationFactory</span> <span class="o">=</span> 
+            <span class="k">new</span> <span class="nf">TransactionSpecificationFactory</span><span class="o">(</span> <span class="n">apiService</span> <span class="o">);</span>
+        <span class="n">controlFactories</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">transactionSpecificationFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">(),</span> <span class="n">transactionSpecificationFactory</span> <span class="o">);</span>
+        <span class="n">LOG</span><span class="o">.</span><span class="na">info</span><span class="o">(</span> <span class="s">&quot;Registered pre-bundled control factory: {}&quot;</span><span class="o">,</span> <span class="n">transactionSpecificationFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">()</span> <span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="o">...</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>We are done ! Note that there is nothing to change in the <em>MANISFEST.MF</em> file, as the packages are already exported.</p>
 
 
     <div class="nav">