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/24 07:45:53 UTC
svn commit: r1024235 - in /websites/staging/directory/trunk/content: ./
api/internal-design-guide/ api/internal-design-guide/images/
Author: buildbot
Date: Wed Jan 24 07:45:53 2018
New Revision: 1024235
Log:
Staging update by buildbot for directory
Modified:
websites/staging/directory/trunk/content/ (props changed)
websites/staging/directory/trunk/content/api/internal-design-guide/14-extended-operations.html
websites/staging/directory/trunk/content/api/internal-design-guide/images/extended-request-decorator.graphml
websites/staging/directory/trunk/content/api/internal-design-guide/images/extended-request-decorator.png
Propchange: websites/staging/directory/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Jan 24 07:45:53 2018
@@ -1 +1 @@
-1821950
+1822082
Modified: websites/staging/directory/trunk/content/api/internal-design-guide/14-extended-operations.html
==============================================================================
--- websites/staging/directory/trunk/content/api/internal-design-guide/14-extended-operations.html (original)
+++ websites/staging/directory/trunk/content/api/internal-design-guide/14-extended-operations.html Wed Jan 24 07:45:53 2018
@@ -214,8 +214,8 @@ ExtendedResponse ::= [APPLICATION 24] SE
</ul>
<h2 id="encoding-and-decoding">Encoding and decoding<a class="headerlink" href="#encoding-and-decoding" title="Permanent link">¶</a></h2>
<p>When the <em>requestValue</em> part is present, it has to be encoded (when the client sends the request to the srrver) or decoded ( when the client receives the response from the server).</p>
-<h3 id="decoding-a-request">Decoding a request<a class="headerlink" href="#decoding-a-request" title="Permanent link">¶</a></h3>
-<p>The payload is decoded on the fly when the request is processed during the <em>extendedRequest</em> is being decoded. The <em>StoreExtendedRequestValue</em> will store the <em>byte[]</em> - if any - and depending on the operation, the specific request will decode the value. Here is the <em>action</em> method for the <em>StoreExtendedRequestValue</em> class :</p>
+<h3 id="decoding-a-requestresponse">Decoding a request/response<a class="headerlink" href="#decoding-a-requestresponse" title="Permanent link">¶</a></h3>
+<p>The payload is decoded on the fly when the request/response is processed during the <em>extendedRequest</em>/<em>extendedResponse</em> is being decoded. The <em>StoreExtendedRequestValue</em>/<em>StoreExtendedResponseValue</em> will store the <em>byte[]</em> - if any - and depending on the operation, the specific request/response will decode the value. Here is the <em>action</em> method for the <em>StoreExtendedRequestValue</em> class :</p>
<div class="codehilite"><pre><span class="kd">public</span> <span class="kt">void</span> <span class="nf">action</span><span class="o">(</span> <span class="n">LdapMessageContainer</span><span class="o"><</span><span class="n">ExtendedRequestDecorator</span><span class="o"><?>></span> <span class="n">container</span> <span class="o">)</span> <span class="kd">throws</span> <span class="n">DecoderException</span>
<span class="o">{</span>
<span class="c1">// We can allocate the ExtendedRequest Object</span>
@@ -237,7 +237,7 @@ ExtendedResponse ::= [APPLICATION 24] SE
</pre></div>
-<p>Each implementaion may have a <em>setRequestValue</em> methd, overloading the parentclass. In this case, the value is decoded by the method.</p>
+<p>Each implementaion may have a <em>setRequestValue</em>/<em>setResponseValue</em> methd, overloading the parentclass. In this case, the value is decoded by the method.</p>
<p>Here is an example of <em>setRequestValue</em> implementation (for the <em>PasswordModifyRequest</em> class) :</p>
<div class="codehilite"><pre><span class="kd">public</span> <span class="kt">void</span> <span class="nf">setRequestValue</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">requestValue</span> <span class="o">)</span>
<span class="o">{</span>
@@ -266,10 +266,762 @@ ExtendedResponse ::= [APPLICATION 24] SE
</pre></div>
-<p>As we can see, the decoder is invoked if the <em>requestValye</em> bytes is not null. It instanciate a <em>PasswordModifyRequest</em>.</p>
+<p>As we can see, the decoder is invoked if the <em>requestValue</em> bytes is not null. It instanciate a <em>PasswordModifyRequest</em>.</p>
<p>If there is no payload, the parent's method is invoked (which basically does nothing).</p>
-<p>Here is a schema showing which operation as a payload that needs to be decoded :</p>
+<p>Here is a schema showing which request/response operations as a payload that needs to be decoded :</p>
<p><img alt="Extended Operations Payload" src="images/extended-request-decorator.png" /></p>
+<h3 id="encoding-a-requestresponse">Encoding a request/response<a class="headerlink" href="#encoding-a-requestresponse" title="Permanent link">¶</a></h3>
+<p>Encoding is done through a <em>Decorator</em>. Each extended operation has a dedicated <em>Decorator</em>, which may have a specific encoding function. Again, as we only encode the payload, if this payload is absent, there is nothing to encode. Not all the extended operations have a payload.</p>
+<p>If there is a payload to encode, this is done by calling the <em>getRequestValue()</em>/<em>getResponseValue()</em> method in the decorator. Here is an example :</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kt">byte</span><span class="o">[]</span> <span class="nf">getRequestValue</span><span class="o">()</span>
+<span class="o">{</span>
+ <span class="k">if</span> <span class="o">(</span> <span class="n">requestValue</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">try</span>
+ <span class="o">{</span>
+ <span class="n">requestValue</span> <span class="o">=</span> <span class="n">encodeInternal</span><span class="o">().</span><span class="na">array</span><span class="o">();</span>
+ <span class="o">}</span>
+ <span class="k">catch</span> <span class="o">(</span> <span class="n">EncoderException</span> <span class="n">e</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="n">LOG</span><span class="o">.</span><span class="na">error</span><span class="o">(</span> <span class="n">I18n</span><span class="o">.</span><span class="na">err</span><span class="o">(</span> <span class="n">I18n</span><span class="o">.</span><span class="na">ERR_04167</span> <span class="o">),</span> <span class="n">e</span> <span class="o">);</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span> <span class="n">e</span> <span class="o">);</span>
+ <span class="o">}</span>
+ <span class="o">}</span>
+
+ <span class="k">return</span> <span class="n">requestValue</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The <em>encodeInternal</em> method is in charge of encoding teh paylod.</p>
+<p>If the <em>getRequestValue</em>/getResponseValue_ method is absent, that leans there is nothing to encode. The inherited method will be executed, which returns null.</p>
+<p>Internally, we compute the length of the needed <strong>PDU</strong> accordingly to the data we have to encode, allocate a <em>ByteBuffer</em> to hold the encoded data, and store teh encoded data into it :</p>
+<div class="codehilite"><pre><span class="cm">/**</span>
+<span class="cm"> * Encodes the PasswordModifyRequest extended operation.</span>
+<span class="cm"> * </span>
+<span class="cm"> * @return A ByteBuffer that contains the encoded PDU</span>
+<span class="cm"> * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong.</span>
+<span class="cm"> */</span>
+<span class="cm">/* No qualifier */</span><span class="n">ByteBuffer</span> <span class="n">encodeInternal</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">EncoderException</span>
+<span class="o">{</span>
+ <span class="n">ByteBuffer</span> <span class="n">bb</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">computeLengthInternal</span><span class="o">()</span> <span class="o">);</span>
+
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">UniversalTag</span><span class="o">.</span><span class="na">SEQUENCE</span><span class="o">.</span><span class="na">getValue</span><span class="o">()</span> <span class="o">);</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(</span> <span class="n">requestLength</span> <span class="o">)</span> <span class="o">);</span>
+
+ <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getUserIdentity</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kt">byte</span><span class="o">[]</span> <span class="n">userIdentity</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getUserIdentity</span><span class="o">();</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="o">(</span> <span class="kt">byte</span> <span class="o">)</span> <span class="n">PasswordModifyRequestConstants</span><span class="o">.</span><span class="na">USER_IDENTITY_TAG</span> <span class="o">);</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(</span> <span class="n">userIdentity</span><span class="o">.</span><span class="na">length</span> <span class="o">)</span> <span class="o">);</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">userIdentity</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+ <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getOldPassword</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kt">byte</span><span class="o">[]</span> <span class="n">oldPassword</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getOldPassword</span><span class="o">();</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="o">(</span> <span class="kt">byte</span> <span class="o">)</span> <span class="n">PasswordModifyRequestConstants</span><span class="o">.</span><span class="na">OLD_PASSWORD_TAG</span> <span class="o">);</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(</span> <span class="n">oldPassword</span><span class="o">.</span><span class="na">length</span> <span class="o">)</span> <span class="o">);</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">oldPassword</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+ <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getNewPassword</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kt">byte</span><span class="o">[]</span> <span class="n">newPassword</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getNewPassword</span><span class="o">();</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="o">(</span> <span class="kt">byte</span> <span class="o">)</span> <span class="n">PasswordModifyRequestConstants</span><span class="o">.</span><span class="na">NEW_PASSWORD_TAG</span> <span class="o">);</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(</span> <span class="n">newPassword</span><span class="o">.</span><span class="na">length</span> <span class="o">)</span> <span class="o">);</span>
+ <span class="n">bb</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">newPassword</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+ <span class="k">return</span> <span class="n">bb</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>and the <em>computeLength</em> method is :</p>
+<div class="codehilite"><pre><span class="cm">/**</span>
+<span class="cm"> * Compute the PasswordModifyRequest extended operation length</span>
+<span class="cm"> * <pre></span>
+<span class="cm"> * 0x30 L1 </span>
+<span class="cm"> * | </span>
+<span class="cm"> * [+-- 0x80 L2 userIdentity] </span>
+<span class="cm"> * [+-- 0x81 L3 oldPassword] </span>
+<span class="cm"> * [+-- 0x82 L4 newPassword] </span>
+<span class="cm"> * </pre></span>
+<span class="cm"> */</span>
+<span class="cm">/* No qualifier */</span><span class="kt">int</span> <span class="n">computeLengthInternal</span><span class="o">()</span>
+<span class="o">{</span>
+ <span class="n">requestLength</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
+
+ <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getUserIdentity</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getUserIdentity</span><span class="o">().</span><span class="na">length</span><span class="o">;</span>
+ <span class="n">requestLength</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getNbBytes</span><span class="o">(</span> <span class="n">len</span> <span class="o">)</span> <span class="o">+</span> <span class="n">len</span><span class="o">;</span>
+ <span class="o">}</span>
+
+ <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getOldPassword</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getOldPassword</span><span class="o">().</span><span class="na">length</span><span class="o">;</span>
+ <span class="n">requestLength</span> <span class="o">+=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getNbBytes</span><span class="o">(</span> <span class="n">len</span> <span class="o">)</span> <span class="o">+</span> <span class="n">len</span><span class="o">;</span>
+ <span class="o">}</span>
+
+ <span class="k">if</span> <span class="o">(</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getNewPassword</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">passwordModifyRequest</span><span class="o">.</span><span class="na">getNewPassword</span><span class="o">().</span><span class="na">length</span><span class="o">;</span>
+ <span class="n">requestLength</span> <span class="o">+=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getNbBytes</span><span class="o">(</span> <span class="n">len</span> <span class="o">)</span> <span class="o">+</span> <span class="n">len</span><span class="o">;</span>
+ <span class="o">}</span>
+
+ <span class="k">return</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">TLV</span><span class="o">.</span><span class="na">getNbBytes</span><span class="o">(</span> <span class="n">requestLength</span> <span class="o">)</span> <span class="o">+</span> <span class="n">requestLength</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="adding-a-new-extended-operation">Adding a new Extended operation<a class="headerlink" href="#adding-a-new-extended-operation" title="Permanent link">¶</a></h2>
+<p>We will show how to add a new extended operation in the <strong>LDAP API</strong>. The added operation is the <em>startTransaction</em> operation, described in <a href="https://tools.ietf.org/html/rfc5805">RFC 5805</a>. </p>
+<p>The <em>startTransactionRequest</em> has a <em>requestName</em> containing <strong>1.3.6.1.1.21.1</strong>, and no <em>requestValue</em>.
+The <em>startTransactionResponse</em> has no <em>responseName</em> and a <em>responseValue</em> containing an opaque transaction identifier (ie, it does not need to be decoced).</p>
+<p>We first need to declare an interface and implementation for each of those two operations. Those four elements are declared in the <em><coec-api></em> module (in <em>/ldap/extras/codec-api</em>), and in the <em>org.apache.directory.api.ldap.extras.extended.startTransaction</em> package, beside the other extended operations :</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">extended</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedRequest</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * The TransactionRequest interface. This is for the RFC 5805 Start Transaction Request,</span>
+<span class="cm"> * which grammar is :</span>
+<span class="cm"> * <pre></span>
+<span class="cm"> * ExtendedRequest ::= [APPLICATION 23] SEQUENCE {</span>
+<span class="cm"> * requestName [0] LDAPOID,</span>
+<span class="cm"> * requestValue [1] OCTET STRING OPTIONAL }</span>
+<span class="cm"> * </pre></span>
+<span class="cm"> * </span>
+<span class="cm"> * where 'requestName' is 1.3.6.1.1.21.1 and requestValue is absent.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">StartTransactionRequest</span> <span class="kd">extends</span> <span class="n">ExtendedRequest</span>
+<span class="o">{</span>
+ <span class="cm">/** The OID for the Transaction extended operation request. */</span>
+ <span class="n">String</span> <span class="n">EXTENSION_OID</span> <span class="o">=</span> <span class="s">"1.3.6.1.1.21.1"</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The request interface defines noting but the <em>OID</em>, as we don't have any payload.</p>
+<p>Here is the implementation :</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">extended</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.AbstractExtendedRequest</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * Implement the extended Start Transaction Request as described in RFC 5805.</span>
+<span class="cm"> * </span>
+<span class="cm"> * It's grammar is :</span>
+<span class="cm"> * </span>
+<span class="cm"> * <pre></span>
+<span class="cm"> * ExtendedRequest ::= [APPLICATION 23] SEQUENCE {</span>
+<span class="cm"> * requestName [0] LDAPOID,</span>
+<span class="cm"> * requestValue [1] OCTET STRING OPTIONAL }</span>
+<span class="cm"> * </pre></span>
+<span class="cm"> * </span>
+<span class="cm"> * where 'requestName' is 1.3.6.1.1.21.1 and requestValue is absent.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionRequestImpl</span> <span class="kd">extends</span> <span class="n">AbstractExtendedRequest</span> <span class="kd">implements</span> <span class="n">StartTransactionRequest</span>
+<span class="o">{</span>
+ <span class="cm">/**</span>
+<span class="cm"> * Creates a new instance of StartTransactionRequestImpl.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @param messageId the message id</span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionRequestImpl</span><span class="o">(</span> <span class="kt">int</span> <span class="n">messageId</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kd">super</span><span class="o">(</span> <span class="n">messageId</span> <span class="o">);</span>
+ <span class="n">setRequestName</span><span class="o">(</span> <span class="n">EXTENSION_OID</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * Creates a new instance of StartTransactionRequestImpl.</span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionRequestImpl</span><span class="o">()</span>
+ <span class="o">{</span>
+ <span class="n">setRequestName</span><span class="o">(</span> <span class="n">EXTENSION_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">StartTransactionResponse</span> <span class="nf">getResultResponse</span><span class="o">()</span>
+ <span class="o">{</span>
+ <span class="k">if</span> <span class="o">(</span> <span class="n">getResponse</span><span class="o">()</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="n">setResponse</span><span class="o">(</span> <span class="k">new</span> <span class="n">StartTransactionResponseImpl</span><span class="o">()</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+ <span class="k">return</span> <span class="o">(</span> <span class="n">StartTransactionResponse</span> <span class="o">)</span> <span class="n">getResponse</span><span class="o">();</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>We just implement the method that returns the associated response.</p>
+<p>Now for the response, which has an opaque value, here is the interface :</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">extended</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedResponse</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * The interface for Start Transaction Extended Response. It's described in RFC 5805 :</span>
+<span class="cm"> * </span>
+<span class="cm"> * <pre></span>
+<span class="cm"> * ExtendedResponse ::= [APPLICATION 24] SEQUENCE {</span>
+<span class="cm"> * COMPONENTS OF LDAPResult,</span>
+<span class="cm"> * responseName [10] LDAPOID OPTIONAL,</span>
+<span class="cm"> * responseValue [11] OCTET STRING OPTIONAL }</span>
+<span class="cm"> * </pre></span>
+<span class="cm"> * </span>
+<span class="cm"> * where the responseName is not present, and the responseValue contain</span>
+<span class="cm"> * a transaction identifier when the result is SUCCESS.</span>
+<span class="cm"> * </span>
+<span class="cm"> * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">StartTransactionResponse</span> <span class="kd">extends</span> <span class="n">ExtendedResponse</span>
+<span class="o">{</span>
+ <span class="cm">/** The OID for the Start Transaction extended operation response. */</span>
+ <span class="n">String</span> <span class="n">EXTENSION_OID</span> <span class="o">=</span> <span class="n">StartTransactionRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span><span class="o">;</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * @return The transaction ID if success</span>
+<span class="cm"> */</span>
+ <span class="kt">byte</span><span class="o">[]</span> <span class="nf">getTransactionId</span><span class="o">();</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>As the response value is opaque, we return it as a <em>byte[]</em>.</p>
+<p>Here is the implementation :</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">extended</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.i18n.I18n</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedResponseImpl</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ResultCodeEnum</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 interface for Start Transaction Extended Response. It's described in RFC 5805 :</span>
+<span class="cm"> * </span>
+<span class="cm"> * <pre></span>
+<span class="cm"> * ExtendedResponse ::= [APPLICATION 24] SEQUENCE {</span>
+<span class="cm"> * COMPONENTS OF LDAPResult,</span>
+<span class="cm"> * responseName [10] LDAPOID OPTIONAL,</span>
+<span class="cm"> * responseValue [11] OCTET STRING OPTIONAL }</span>
+<span class="cm"> * </pre></span>
+<span class="cm"> * </span>
+<span class="cm"> * where the responseName is not present, and the responseValue contain</span>
+<span class="cm"> * a transaction identifier when the result is SUCCESS.</span>
+<span class="cm"> * </span>
+<span class="cm"> *</span>
+<span class="cm"> * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionResponseImpl</span> <span class="kd">extends</span> <span class="n">ExtendedResponseImpl</span> <span class="kd">implements</span> <span class="n">StartTransactionResponse</span>
+<span class="o">{</span>
+ <span class="cm">/** The transaction ID if the request was successful */</span>
+ <span class="kd">private</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span><span class="o">;</span>
+
+ <span class="cm">/**</span>
+<span class="cm"> * Create a new StartTransactionResponseImpl object</span>
+<span class="cm"> * </span>
+<span class="cm"> * @param messageId The messageId</span>
+<span class="cm"> * @param rcode the result code</span>
+<span class="cm"> * @param transactionId The transaction ID </span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionResponseImpl</span><span class="o">(</span> <span class="kt">int</span> <span class="n">messageId</span><span class="o">,</span> <span class="n">ResultCodeEnum</span> <span class="n">resultCode</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kd">super</span><span class="o">(</span> <span class="n">messageId</span> <span class="o">);</span>
+
+ <span class="k">switch</span> <span class="o">(</span> <span class="n">resultCode</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">case</span> <span class="nl">SUCCESS:</span>
+ <span class="k">this</span><span class="o">.</span><span class="na">transactionId</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+ <span class="c1">// pass through ...</span>
+ <span class="k">case</span> <span class="nl">CANCELED:</span>
+ <span class="k">case</span> <span class="nl">CANNOT_CANCEL:</span>
+ <span class="k">case</span> <span class="nl">NO_SUCH_OPERATION:</span>
+ <span class="k">case</span> <span class="nl">TOO_LATE:</span>
+ <span class="k">break</span><span class="o">;</span>
+
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalArgumentException</span><span class="o">(</span> <span class="n">I18n</span><span class="o">.</span><span class="na">err</span><span class="o">(</span> <span class="n">I18n</span><span class="o">.</span><span class="na">ERR_04166</span><span class="o">,</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">SUCCESS</span><span class="o">,</span>
+ <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">OPERATIONS_ERROR</span><span class="o">,</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">INSUFFICIENT_ACCESS_RIGHTS</span> <span class="o">)</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+ <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setMatchedDn</span><span class="o">(</span> <span class="kc">null</span> <span class="o">);</span>
+ <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setResultCode</span><span class="o">(</span> <span class="n">resultCode</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * Create a new StartTransactionResponseImpl instance</span>
+<span class="cm"> * </span>
+<span class="cm"> * @param messageId The request's messageId</span>
+<span class="cm"> * @param transactionId The transaction ID </span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionResponseImpl</span><span class="o">(</span> <span class="kt">int</span> <span class="n">messageId</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kd">super</span><span class="o">(</span> <span class="n">messageId</span> <span class="o">);</span>
+ <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setMatchedDn</span><span class="o">(</span> <span class="kc">null</span> <span class="o">);</span>
+ <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setResultCode</span><span class="o">(</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">SUCCESS</span> <span class="o">);</span>
+ <span class="k">this</span><span class="o">.</span><span class="na">transactionId</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * Create a new StartTransactionResponseImpl instance</span>
+<span class="cm"> * </span>
+<span class="cm"> * @param transactionId The transaction ID </span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionResponseImpl</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="kd">super</span><span class="o">(</span> <span class="n">StartTransactionRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span> <span class="o">);</span>
+ <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setMatchedDn</span><span class="o">(</span> <span class="kc">null</span> <span class="o">);</span>
+ <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setResultCode</span><span class="o">(</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">SUCCESS</span> <span class="o">);</span>
+ <span class="k">this</span><span class="o">.</span><span class="na">transactionId</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * Create a new StartTransactionResponseImpl instance</span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionResponseImpl</span><span class="o">()</span>
+ <span class="o">{</span>
+ <span class="kd">super</span><span class="o">(</span> <span class="n">StartTransactionRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span> <span class="o">);</span>
+ <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setMatchedDn</span><span class="o">(</span> <span class="kc">null</span> <span class="o">);</span>
+ <span class="kd">super</span><span class="o">.</span><span class="na">getLdapResult</span><span class="o">().</span><span class="na">setResultCode</span><span class="o">(</span> <span class="n">ResultCodeEnum</span><span class="o">.</span><span class="na">UNWILLING_TO_PERFORM</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * Gets the OID uniquely identifying this extended response (a.k.a. its</span>
+<span class="cm"> * name). It's a null value for the Cancel response</span>
+<span class="cm"> * </span>
+<span class="cm"> * @return the OID of the extended response type.</span>
+<span class="cm"> */</span>
+ <span class="nd">@Override</span>
+ <span class="kd">public</span> <span class="n">String</span> <span class="nf">getResponseName</span><span class="o">()</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="s">""</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">hashCode</span><span class="o">()</span>
+ <span class="o">{</span>
+ <span class="kt">int</span> <span class="n">hash</span> <span class="o">=</span> <span class="mi">37</span><span class="o">;</span>
+
+ <span class="k">if</span> <span class="o">(</span> <span class="n">transactionId</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">for</span> <span class="o">(</span> <span class="kt">byte</span> <span class="n">b</span> <span class="o">:</span> <span class="n">transactionId</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="n">hash</span> <span class="o">+=</span> <span class="n">hash</span> <span class="o">*</span> <span class="mi">17</span> <span class="o">+</span> <span class="n">b</span><span class="o">;</span>
+ <span class="o">}</span>
+ <span class="o">}</span>
+
+ <span class="n">hash</span> <span class="o">=</span> <span class="n">hash</span> <span class="o">*</span> <span class="mi">17</span> <span class="o">+</span> <span class="n">getClass</span><span class="o">().</span><span class="na">getName</span><span class="o">().</span><span class="na">hashCode</span><span class="o">();</span>
+
+ <span class="k">return</span> <span class="n">hash</span><span class="o">;</span>
+ <span class="o">}</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * @see Object#equals(Object)</span>
+<span class="cm"> */</span>
+ <span class="nd">@Override</span>
+ <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span> <span class="n">Object</span> <span class="n">obj</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">if</span> <span class="o">(</span> <span class="n">obj</span> <span class="o">==</span> <span class="k">this</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
+ <span class="o">}</span>
+
+ <span class="k">if</span> <span class="o">(</span> <span class="o">!(</span> <span class="n">obj</span> <span class="k">instanceof</span> <span class="n">StartTransactionResponseImpl</span> <span class="o">)</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
+ <span class="o">}</span>
+
+ <span class="k">return</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span> <span class="n">transactionId</span><span class="o">,</span> <span class="o">(</span> <span class="o">(</span> <span class="n">StartTransactionResponseImpl</span> <span class="o">)</span> <span class="n">obj</span> <span class="o">).</span><span class="na">transactionId</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">getTransactionId</span><span class="o">()</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+ <span class="o">}</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * {@inheritDoc}</span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setTransactionId</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">transactionId</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">this</span><span class="o">.</span><span class="na">transactionId</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">transactionId</span> <span class="o">);</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>There is nothing special in this implementation, we just make it so the <em>transactionId</em> bytes are copied to be sure they can't be altered from the outside. Basically, the payload is transfered pristine into the instance.</p>
+<p>Now that we have the interfaces and implementations, we need to add the decorators and the factory. The factory is used to initialize the <strong>API</strong> with the list of available extended operaiton at startup, as a mean to make the <strong>API</strong> extensible. It creates request and response, and the associated decorator.</p>
+<p>Here is the factory code, declared in the <em><extra-codec></em> module :</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">extended</span><span class="o">.</span><span class="na">ads_impl</span><span class="o">.</span><span class="na">startTransaction</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.ldap.codec.api.ExtendedOperationFactory</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="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.cancel.CancelRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionRequestImpl</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponse</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponseImpl</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.model.message.ExtendedResponse</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * An {@link ExtendedOperationFactory} for creating cancel extended request response </span>
+<span class="cm"> * pairs.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionFactory</span> <span class="kd">implements</span> <span class="n">ExtendedOperationFactory</span>
+<span class="o">{</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 CancelFactory.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @param codec The codec for this factory.</span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionFactory</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">CancelRequest</span><span class="o">.</span><span class="na">EXTENSION_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">StartTransactionResponse</span> <span class="nf">newResponse</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">encodedValue</span> <span class="o">)</span> <span class="kd">throws</span> <span class="n">DecoderException</span>
+ <span class="o">{</span>
+ <span class="n">StartTransactionResponseDecorator</span> <span class="n">response</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTransactionResponseDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="k">new</span> <span class="n">StartTransactionResponseImpl</span><span class="o">()</span> <span class="o">);</span>
+ <span class="n">response</span><span class="o">.</span><span class="na">setResponseValue</span><span class="o">(</span> <span class="n">encodedValue</span> <span class="o">);</span>
+
+ <span class="k">return</span> <span class="n">response</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">StartTransactionRequest</span> <span class="nf">newRequest</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">value</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="k">new</span> <span class="nf">StartTransactionRequestDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="k">new</span> <span class="n">StartTransactionRequestImpl</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">StartTransactionRequestDecorator</span> <span class="nf">decorate</span><span class="o">(</span> <span class="n">ExtendedRequest</span> <span class="n">modelRequest</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">if</span> <span class="o">(</span> <span class="n">modelRequest</span> <span class="k">instanceof</span> <span class="n">StartTransactionRequestDecorator</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="o">(</span> <span class="n">StartTransactionRequestDecorator</span> <span class="o">)</span> <span class="n">modelRequest</span><span class="o">;</span>
+ <span class="o">}</span>
+
+ <span class="k">return</span> <span class="k">new</span> <span class="nf">StartTransactionRequestDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="kc">null</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">StartTransactionResponseDecorator</span> <span class="nf">decorate</span><span class="o">(</span> <span class="n">ExtendedResponse</span> <span class="n">decoratedMessage</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">if</span> <span class="o">(</span> <span class="n">decoratedMessage</span> <span class="k">instanceof</span> <span class="n">StartTransactionResponseDecorator</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="o">(</span> <span class="n">StartTransactionResponseDecorator</span> <span class="o">)</span> <span class="n">decoratedMessage</span><span class="o">;</span>
+ <span class="o">}</span>
+
+ <span class="k">return</span> <span class="k">new</span> <span class="nf">StartTransactionResponseDecorator</span><span class="o">(</span> <span class="n">codec</span><span class="o">,</span> <span class="kc">null</span> <span class="o">);</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The decorator are very simple : they just encapsulate the requets or response instance. It's because encoding or decoding is non existant for this operation. Decorators are declared in the <em><extra-codec></em> module.</p>
+<p>Here is teh code for both those decorators :</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">extended</span><span class="o">.</span><span class="na">ads_impl</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator</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="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponse</span><span class="o">;</span>
+
+
+<span class="cm">/**</span>
+<span class="cm"> * A Decorator for startTransaction request.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionRequestDecorator</span> <span class="kd">extends</span> <span class="n">ExtendedRequestDecorator</span><span class="o"><</span><span class="n">StartTransactionRequest</span><span class="o">></span> <span class="kd">implements</span>
+ <span class="n">StartTransactionRequest</span>
+<span class="o">{</span>
+ <span class="cm">/** The internal startTransaction request */</span>
+ <span class="kd">private</span> <span class="n">StartTransactionRequest</span> <span class="n">startTransactionRequest</span><span class="o">;</span>
+
+
+ <span class="cm">/**</span>
+<span class="cm"> * Creates a new instance of StartTransactionRequestDecorator.</span>
+<span class="cm"> * </span>
+<span class="cm"> * @param codec The LDAP Service to use</span>
+<span class="cm"> * @param decoratedMessage The canceled request</span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionRequestDecorator</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span><span class="o">,</span> <span class="n">StartTransactionRequest</span> <span class="n">decoratedMessage</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">decoratedMessage</span> <span class="o">);</span>
+ <span class="n">startTransactionRequest</span> <span class="o">=</span> <span class="n">decoratedMessage</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">StartTransactionResponse</span> <span class="nf">getResultResponse</span><span class="o">()</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="o">(</span> <span class="n">StartTransactionResponse</span> <span class="o">)</span> <span class="n">startTransactionRequest</span><span class="o">.</span><span class="na">getResultResponse</span><span class="o">();</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>and for the response :</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">extended</span><span class="o">.</span><span class="na">ads_impl</span><span class="o">.</span><span class="na">startTransaction</span><span class="o">;</span>
+
+
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.codec.api.ExtendedResponseDecorator</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="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponse</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"> * A Decorator for CancelResponses.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></span>
+<span class="cm"> */</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">StartTransactionResponseDecorator</span> <span class="kd">extends</span> <span class="n">ExtendedResponseDecorator</span><span class="o"><</span><span class="n">StartTransactionResponse</span><span class="o">></span> <span class="kd">implements</span> <span class="n">StartTransactionResponse</span>
+<span class="o">{</span>
+ <span class="cm">/** The startTransaction response */</span>
+ <span class="kd">private</span> <span class="n">StartTransactionResponse</span> <span class="n">startTransactionResponse</span><span class="o">;</span>
+
+ <span class="cm">/**</span>
+<span class="cm"> * Creates a new instance of CancelResponseDecorator.</span>
+<span class="cm"> *</span>
+<span class="cm"> * @param codec The LDAP service instance</span>
+<span class="cm"> * @param decoratedMessage The decorated message</span>
+<span class="cm"> */</span>
+ <span class="kd">public</span> <span class="nf">StartTransactionResponseDecorator</span><span class="o">(</span> <span class="n">LdapApiService</span> <span class="n">codec</span><span class="o">,</span> <span class="n">StartTransactionResponse</span> <span class="n">decoratedMessage</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">decoratedMessage</span> <span class="o">);</span>
+ <span class="n">startTransactionResponse</span> <span class="o">=</span> <span class="n">decoratedMessage</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">setResponseValue</span><span class="o">(</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">responseValue</span> <span class="o">)</span>
+ <span class="o">{</span>
+ <span class="k">this</span><span class="o">.</span><span class="na">responseValue</span> <span class="o">=</span> <span class="n">Strings</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span> <span class="n">responseValue</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">getTransactionId</span><span class="o">()</span>
+ <span class="o">{</span>
+ <span class="k">return</span> <span class="n">startTransactionResponse</span><span class="o">.</span><span class="na">getTransactionId</span><span class="o">();</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The last step is to declare the extended operation in the <strong>LDAP API</strong> initialization and <strong>OSGi</strong>. There are two places we have to declare the factory :</p>
+<ul>
+<li><em>CodecFactoryUtil</em> class, in the <em><ldap/codec/standalone></em> module</li>
+<li><em>ExtrasBundleActivator</em> class, in the <em><ldap/extras/codec></em> module</li>
+</ul>
+<p>Here is the added code in the <em>CodecFactoryUtil</em> class :</p>
+<div class="codehilite"><pre><span class="o">...</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.ads_impl.startTls.StartTlsFactory</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.ads_impl.startTransaction.StartTransactionFactory</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 <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></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="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">loadStockExtendedOperations</span><span class="o">(</span>
+ <span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">ExtendedOperationFactory</span><span class="o">></span> <span class="n">extendendOperationsFactories</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="o">...</span>
+
+ <span class="n">StartTlsFactory</span> <span class="n">startTlsFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTlsFactory</span><span class="o">(</span> <span class="n">apiService</span> <span class="o">);</span>
+ <span class="n">extendendOperationsFactories</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">startTlsFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">(),</span> <span class="n">startTlsFactory</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">"Registered pre-bundled extended operation factory: {}"</span><span class="o">,</span> <span class="n">startTlsFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">()</span> <span class="o">);</span>
+
+ <span class="n">StartTransactionFactory</span> <span class="n">startTransactionFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTransactionFactory</span><span class="o">(</span> <span class="n">apiService</span> <span class="o">);</span>
+ <span class="n">extendendOperationsFactories</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">startTransactionFactory</span><span class="o">.</span><span class="na">getOid</span><span class="o">(),</span> <span class="n">startTransactionFactory</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">"Registered pre-bundled extended operation factory: {}"</span><span class="o">,</span> <span class="n">startTransactionFactory</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 just need to instanciate the factory, and to add it to the map of supported extended operations.</p>
+<p>And the added code for the <em>ExtrasBundleActivator</em> class :</p>
+<div class="codehilite"><pre><span class="o">...</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.ads_impl.startTls.StartTlsFactory</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.ads_impl.startTransaction.StartTransactionFactory</span><span class="o">;</span>
+<span class="o">...</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTls.StartTlsRequest</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionRequest</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 <a href="mailto:dev@directory.apache.org">Apache Directory Project</a></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 extended operations 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">registerExtrasExtendedOps</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="c1">// --------------------------------------------------------------------</span>
+ <span class="c1">// Register Extended Request Factories</span>
+ <span class="c1">// --------------------------------------------------------------------</span>
+ <span class="o">...</span>
+
+ <span class="n">StartTlsFactory</span> <span class="n">startTlsFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTlsFactory</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">registerExtendedRequest</span><span class="o">(</span> <span class="n">startTlsFactory</span> <span class="o">);</span>
+
+ <span class="n">StartTransactionFactory</span> <span class="n">startTransactionFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StartTransactionFactory</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">registerExtendedRequest</span><span class="o">(</span> <span class="n">startTransactionFactory</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">unregisterExtrasExtendedOps</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="o">...</span>
+ <span class="n">codec</span><span class="o">.</span><span class="na">unregisterExtendedRequest</span><span class="o">(</span> <span class="n">StartTlsRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span> <span class="o">);</span>
+ <span class="n">codec</span><span class="o">.</span><span class="na">unregisterExtendedRequest</span><span class="o">(</span> <span class="n">StartTransactionRequest</span><span class="o">.</span><span class="na">EXTENSION_OID</span> <span class="o">);</span>
+ <span class="o">...</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>We also have to export the package for it to be visible when using <strong>OSGi</strong>. This is done by modifying some <em>pom.xml</em> files.</p>
+<p><em><ldap/extras/codec></em> module <em>pom.xml</em> file :</p>
+<div class="codehilite"><pre>...
+<span class="nt"><configuration></span>
+ <span class="nt"><manifestLocation></span>META-INF<span class="nt"></manifestLocation></span>
+ <span class="nt"><instructions></span>
+ <span class="nt"><Bundle-SymbolicName></span>${project.groupId}.ldap.extras.codec<span class="nt"></Bundle-SymbolicName></span>
+ <span class="nt"><Export-Package></span>
+ {local-packages};version=${project.version};-noimport:=true
+ <span class="nt"></Export-Package></span>
+ <span class="nt"><Export-Package></span>
+ ...
+ org.apache.directory.api.ldap.extras.extended.ads_impl.startTls;version=${project.version};-noimport:=true,
+ org.apache.directory.api.ldap.extras.extended.ads_impl.startTransaction;version=${project.version};-noimport:=true,
+ ...
+ <span class="nt"></Export-Package></span>
+ <span class="nt"><Import-Package></span>
+ ...
+ org.apache.directory.api.ldap.extras.extended.startTls;version=${project.version},
+ org.apache.directory.api.ldap.extras.extended.startTransaction;version=${project.version},
+ ...
+ <span class="nt"></Import-Package></span>
+</pre></div>
+
+
+<p><em><ldap/extras/codec-api></em> module <em>pom.xml</em> file :</p>
+<div class="codehilite"><pre>...
+<span class="nt"><configuration></span>
+ <span class="nt"><manifestLocation></span>META-INF<span class="nt"></manifestLocation></span>
+ <span class="nt"><instructions></span>
+ <span class="nt"><Bundle-SymbolicName></span>${project.groupId}.ldap.extras.codec.api<span class="nt"></Bundle-SymbolicName></span>
+ <span class="nt"><Export-Package></span>
+ ...
+ org.apache.directory.api.ldap.extras.extended.startTls;version=${project.version};-noimport:=true,
+ org.apache.directory.api.ldap.extras.extended.startTransaction;version=${project.version};-noimport:=true,
+ ...
+ <span class="nt"></Export-Package></span>
+</pre></div>
<div class="nav">
Modified: websites/staging/directory/trunk/content/api/internal-design-guide/images/extended-request-decorator.graphml
==============================================================================
Binary files - no diff available.
Modified: websites/staging/directory/trunk/content/api/internal-design-guide/images/extended-request-decorator.png
==============================================================================
Binary files - no diff available.