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   *    http://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.controls.syncrepl_impl;
21  
22  
23  import java.nio.ByteBuffer;
24  
25  import org.apache.directory.api.asn1.Asn1Object;
26  import org.apache.directory.api.asn1.DecoderException;
27  import org.apache.directory.api.asn1.EncoderException;
28  import org.apache.directory.api.asn1.ber.Asn1Decoder;
29  import org.apache.directory.api.asn1.ber.tlv.BerValue;
30  import org.apache.directory.api.asn1.ber.tlv.TLV;
31  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
32  import org.apache.directory.api.i18n.I18n;
33  import org.apache.directory.api.ldap.codec.api.ControlDecorator;
34  import org.apache.directory.api.ldap.codec.api.LdapApiService;
35  import org.apache.directory.api.ldap.extras.controls.SynchronizationModeEnum;
36  import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SyncRequestValue;
37  import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SyncRequestValueImpl;
38  import org.apache.directory.api.util.Strings;
39  
40  
41  /**
42   * A syncRequestValue object, as defined in RFC 4533
43   *
44   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
45   */
46  public class SyncRequestValueDecorator extends ControlDecorator<SyncRequestValue> implements SyncRequestValue
47  {
48      /** The global length for this control */
49      private int syncRequestValueLength;
50  
51      /** An instance of this decoder */
52      private static final Asn1Decoder DECODER = new Asn1Decoder();
53  
54  
55      /**
56       * Create a new SyncRequestValueDecorator instance 
57       * 
58       * @param codec The LDAP API service to use
59       */
60      public SyncRequestValueDecorator( LdapApiService codec )
61      {
62          super( codec, new SyncRequestValueImpl() );
63      }
64  
65  
66      /**
67       * Create a new SyncRequestValueDecorator instance 
68       * 
69       * @param codec The LDAP API service to use
70       * @param control The decorated SyncRequestValue control
71       */
72      public SyncRequestValueDecorator( LdapApiService codec, SyncRequestValue control )
73      {
74          super( codec, control );
75      }
76  
77  
78      /**
79       * {@inheritDoc}
80       */
81      @Override
82      public SynchronizationModeEnum getMode()
83      {
84          return getDecorated().getMode();
85      }
86  
87  
88      /**
89       * {@inheritDoc}
90       */
91      @Override
92      public void setMode( SynchronizationModeEnum mode )
93      {
94          getDecorated().setMode( mode );
95      }
96  
97  
98      /**
99       * {@inheritDoc}
100      */
101     @Override
102     public byte[] getCookie()
103     {
104         return getDecorated().getCookie();
105     }
106 
107 
108     /**
109      * {@inheritDoc}
110      */
111     @Override
112     public void setCookie( byte[] cookie )
113     {
114         // Copy the bytes
115         if ( !Strings.isEmpty( cookie ) )
116         {
117             byte[] copy = new byte[cookie.length];
118             System.arraycopy( cookie, 0, copy, 0, cookie.length );
119             getDecorated().setCookie( copy );
120         }
121         else
122         {
123             getDecorated().setCookie( null );
124         }
125     }
126 
127 
128     /**
129      * {@inheritDoc}
130      */
131     @Override
132     public boolean isReloadHint()
133     {
134         return getDecorated().isReloadHint();
135     }
136 
137 
138     /**
139      * {@inheritDoc}
140      */
141     @Override
142     public void setReloadHint( boolean reloadHint )
143     {
144         getDecorated().setReloadHint( reloadHint );
145     }
146 
147 
148     /**
149      * Compute the SyncRequestValue length.
150      * <br>
151      * SyncRequestValue :
152      * <pre>
153      * 0x30 L1
154      *  |
155      *  +--&gt; 0x0A 0x01 [0x00|0x01|0x02|0x03] (mode)
156      * [+--&gt; 0x04 L2 abcd...                 (cookie)
157      *  +--&gt; 0x01 0x01 [0x00|0xFF]           (reloadHint)
158      * </pre>
159      * 
160      * @return The computed length
161      */
162     @Override
163     public int computeLength()
164     {
165         // The mode length
166         syncRequestValueLength = 1 + 1 + 1;
167 
168         // The cookie length, if we have a cookie
169         if ( getCookie() != null )
170         {
171             syncRequestValueLength += 1 + TLV.getNbBytes( getCookie().length ) + getCookie().length;
172         }
173 
174         // The reloadHint length, default to false
175         if ( isReloadHint() )
176         {
177             syncRequestValueLength += 1 + 1 + 1;
178         }
179 
180         valueLength = 1 + TLV.getNbBytes( syncRequestValueLength ) + syncRequestValueLength;
181 
182         // Call the super class to compute the global control length
183         return valueLength;
184     }
185 
186 
187     /**
188      * Encode the SyncRequestValue control
189      *
190      * @param buffer The encoded sink
191      * @return A ByteBuffer that contains the encoded PDU
192      * @throws EncoderException If anything goes wrong.
193      */
194     @Override
195     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
196     {
197         if ( buffer == null )
198         {
199             throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
200         }
201 
202         // Encode the SEQ
203         buffer.put( UniversalTag.SEQUENCE.getValue() );
204         buffer.put( TLV.getBytes( syncRequestValueLength ) );
205 
206         // The mode
207         buffer.put( UniversalTag.ENUMERATED.getValue() );
208         buffer.put( ( byte ) 0x01 );
209         buffer.put( BerValue.getBytes( getMode().getValue() ) );
210 
211         // The cookie
212         if ( getCookie() != null )
213         {
214             BerValue.encode( buffer, getCookie() );
215         }
216 
217         // The reloadHint if not false
218         if ( isReloadHint() )
219         {
220             BerValue.encode( buffer, isReloadHint() );
221         }
222 
223         return buffer;
224     }
225 
226 
227     /**
228      * {@inheritDoc}
229      */
230     @Override
231     public byte[] getValue()
232     {
233         if ( value == null )
234         {
235             try
236             {
237                 computeLength();
238                 ByteBuffer buffer = ByteBuffer.allocate( valueLength );
239 
240                 // Encode the SEQ
241                 buffer.put( UniversalTag.SEQUENCE.getValue() );
242                 buffer.put( TLV.getBytes( syncRequestValueLength ) );
243 
244                 // The mode
245                 buffer.put( UniversalTag.ENUMERATED.getValue() );
246                 buffer.put( ( byte ) 0x01 );
247                 buffer.put( BerValue.getBytes( getMode().getValue() ) );
248 
249                 // The cookie
250                 if ( getCookie() != null )
251                 {
252                     BerValue.encode( buffer, getCookie() );
253                 }
254 
255                 // The reloadHint if not false
256                 if ( isReloadHint() )
257                 {
258                     BerValue.encode( buffer, isReloadHint() );
259                 }
260 
261                 value = buffer.array();
262             }
263             catch ( Exception e )
264             {
265                 return null;
266             }
267         }
268 
269         return value;
270     }
271 
272 
273     /**
274      * {@inheritDoc}
275      */
276     @Override
277     public Asn1Object decode( byte[] controlBytes ) throws DecoderException
278     {
279         ByteBuffer bb = ByteBuffer.wrap( controlBytes );
280         SyncRequestValueContainer container = new SyncRequestValueContainer( this );
281         DECODER.decode( bb, container );
282         return this;
283     }
284 }