View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     https://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  package org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction;
21  
22  
23  import java.nio.ByteBuffer;
24  import java.util.Iterator;
25  
26  import org.apache.directory.api.asn1.DecoderException;
27  import org.apache.directory.api.asn1.ber.Asn1Decoder;
28  import org.apache.directory.api.asn1.ber.tlv.BerValue;
29  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
30  import org.apache.directory.api.asn1.util.Asn1Buffer;
31  import org.apache.directory.api.ldap.codec.api.AbstractExtendedOperationFactory;
32  import org.apache.directory.api.ldap.codec.api.ControlFactory;
33  import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory;
34  import org.apache.directory.api.ldap.codec.api.LdapApiService;
35  import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionRequest;
36  import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionRequestImpl;
37  import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionResponse;
38  import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionResponseImpl;
39  import org.apache.directory.api.ldap.extras.extended.endTransaction.UpdateControls;
40  import org.apache.directory.api.ldap.model.message.Control;
41  import org.apache.directory.api.ldap.model.message.ExtendedRequest;
42  import org.apache.directory.api.ldap.model.message.ExtendedResponse;
43  
44  
45  /**
46   * An {@link ExtendedOperationFactory} for creating EndTransaction extended request response 
47   * pairs.
48   *
49   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
50   */
51  public class EndTransactionFactory extends AbstractExtendedOperationFactory
52  {
53      /**
54       * Creates a new instance of EndTransactionFactory.
55       *
56       * @param codec The codec for this factory.
57       */
58      public EndTransactionFactory( LdapApiService codec )
59      {
60          super( codec, EndTransactionRequest.EXTENSION_OID );
61      }
62  
63  
64      /**
65       * {@inheritDoc}
66       */
67      @Override
68      public EndTransactionRequest newRequest()
69      {
70          EndTransactionRequest endTransactionRequest = new EndTransactionRequestImpl();
71  
72          return endTransactionRequest;
73  
74      }
75  
76  
77      /**
78       * {@inheritDoc}
79       */
80      @Override
81      public EndTransactionRequest newRequest( byte[] encodedValue ) throws DecoderException
82      {
83          EndTransactionRequest endTransactionRequest = new EndTransactionRequestImpl();
84          decodeValue( endTransactionRequest, encodedValue );
85  
86          return endTransactionRequest;
87  
88      }
89  
90  
91      /**
92       * {@inheritDoc}
93       */
94      @Override
95      public EndTransactionResponse newResponse()
96      {
97          EndTransactionResponse endTransactionResponse = new EndTransactionResponseImpl();
98  
99          return endTransactionResponse;
100     }
101 
102 
103     /**
104      * {@inheritDoc}
105      */
106     @Override
107     public EndTransactionResponse newResponse( byte[] encodedValue ) throws DecoderException
108     {
109         EndTransactionResponse endTransactionResponse = new EndTransactionResponseImpl();
110         decodeValue( endTransactionResponse, encodedValue );
111 
112         return endTransactionResponse;
113     }
114 
115 
116     /**
117      * {@inheritDoc}
118      */
119     @Override
120     public void decodeValue( ExtendedRequest extendedRequest, byte[] requestValue ) throws DecoderException
121     {
122         ByteBuffer bb = ByteBuffer.wrap( requestValue );
123         EndTransactionRequestContainer container = new EndTransactionRequestContainer();
124         container.setEndTransactionRequest( ( EndTransactionRequest ) extendedRequest ); 
125         Asn1Decoder.decode( bb, container );
126     }
127 
128 
129     /**
130      * {@inheritDoc}
131      */
132     @Override
133     public void decodeValue( ExtendedResponse extendedResponse, byte[] requestValue ) throws DecoderException
134     {
135         ByteBuffer bb = ByteBuffer.wrap( requestValue );
136         EndTransactionResponseContainer container = new EndTransactionResponseContainer();
137         container.setEndTransactionResponse( ( EndTransactionResponse ) extendedResponse ); 
138         Asn1Decoder.decode( bb, container );
139     }
140 
141 
142     /**
143      * {@inheritDoc}
144      */
145     @Override
146     public void encodeValue( Asn1Buffer buffer, ExtendedRequest extendedRequest )
147     {
148         int start  = buffer.getPos();
149         EndTransactionRequest transactionRequest = ( EndTransactionRequest ) extendedRequest;
150         
151         // The identifier
152         BerValue.encodeOctetString( buffer, transactionRequest.getTransactionId() );
153         
154         // The commit flag, if false
155         if ( !transactionRequest.getCommit() )
156         {
157             BerValue.encodeBoolean( buffer, false );
158         }
159         
160         // The sequence
161         BerValue.encodeSequence( buffer, start );
162     }
163     
164     
165     private void encodeControls( Asn1Buffer buffer, Iterator<Control> controls )
166     {
167         if ( controls.hasNext() )
168         {
169             Control control = controls.next();
170             
171             encodeControls( buffer, controls );
172 
173             int start = buffer.getPos();
174             
175             // The control value, if any
176             ControlFactory<?> controlFactory = codec.getResponseControlFactories().get( control.getOid() );
177             
178             if ( controlFactory != null )
179             {
180                 controlFactory.encodeValue( buffer, control );
181                 
182                 // The value sequence
183                 BerValue.encodeSequence( buffer, UniversalTag.OCTET_STRING.getValue(), start );
184             }
185             
186             // The control criticality of TRUE
187             if ( control.isCritical() )
188             {
189                 BerValue.encodeBoolean( buffer, true );
190             }
191             
192             // The control oid
193             BerValue.encodeOctetString( buffer, control.getOid() );
194             
195             // The control sequence
196             BerValue.encodeSequence( buffer, start );
197         }
198     } 
199     
200     
201     private void encodeUpdatedControls( Asn1Buffer buffer, Iterator<UpdateControls> updateControls )
202     {
203         if ( updateControls.hasNext() )
204         {
205             UpdateControls updateControl = updateControls.next();
206             
207             encodeUpdatedControls( buffer, updateControls );
208 
209             int start = buffer.getPos();
210             
211             // The controls
212             encodeControls( buffer, updateControl.getControls().iterator() );
213             
214             // The controls sequence
215             BerValue.encodeSequence( buffer, start );
216             
217             // The messageID
218             BerValue.encodeInteger( buffer, updateControl.getMessageId() );
219 
220             // The sequence
221             BerValue.encodeSequence( buffer, start );
222         }
223     }
224 
225 
226     /**
227      * {@inheritDoc}
228      */
229     @Override
230     public void encodeValue( Asn1Buffer buffer, ExtendedResponse extendedResponse )
231     {
232         // This is a hack !!! We remove the response name from the response
233         // because it has only be added to find the factory, but we don't want it
234         // top be injected in the encoded PDU...
235         extendedResponse.setResponseName( null );
236 
237         int start  = buffer.getPos();
238         EndTransactionResponse endTransactionResponse = ( EndTransactionResponse ) extendedResponse;
239         
240         // The controls
241         if ( endTransactionResponse.getUpdateControls().size() > 0 )
242         {
243             encodeUpdatedControls( buffer, endTransactionResponse.getUpdateControls().iterator() );
244             
245             BerValue.encodeSequence( buffer, start );
246         }
247         
248         // The messageID flag, if false
249         if ( endTransactionResponse.getFailedMessageId() >= 0 )
250         {
251             BerValue.encodeInteger( buffer, endTransactionResponse.getFailedMessageId() );
252         }
253         
254         // The sequence
255         BerValue.encodeSequence( buffer, start );
256     }
257 }