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.ad_impl;
21  
22  import java.nio.ByteBuffer;
23  import java.util.Set;
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.ad.AdDirSync;
36  import org.apache.directory.api.ldap.extras.controls.ad.AdDirSyncFlag;
37  import org.apache.directory.api.ldap.extras.controls.ad.AdDirSyncImpl;
38  import org.apache.directory.api.util.Strings;
39  
40  /**
41   * A decorator around AdDirSync control. It will encode and decode this control.
42   * 
43   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
44   */
45  public class AdDirSyncDecorator extends ControlDecorator<AdDirSync> implements AdDirSync
46  {
47      /** The global length for this control */
48      private int adDirSyncLength;
49  
50      /** An instance of this decoder */
51      private static final Asn1Decoder DECODER = new Asn1Decoder();
52  
53  
54      /**
55       * Creates a new instance of AdDirSyncDecorator.
56       * 
57       * @param codec The LDAP Service to use
58       */
59      public AdDirSyncDecorator( LdapApiService codec )
60      {
61          super( codec, new AdDirSyncImpl() );
62      }
63  
64  
65      /**
66       * Creates a new instance of AdDirSyncDecorator.
67       *
68       * @param codec The LDAP Service to use
69       * @param control The control to be decorated
70       */
71      public AdDirSyncDecorator( LdapApiService codec, AdDirSync control )
72      {
73          super( codec, control );
74      }
75      
76      
77      /**
78       * {@inheritDoc}
79       */
80      @Override
81      public Set<AdDirSyncFlag> getFlags()
82      {
83          return getDecorated().getFlags();
84      }
85  
86      
87      /**
88       * {@inheritDoc}
89       */
90      @Override
91      public void setFlags( Set<AdDirSyncFlag> flags )
92      {
93          getDecorated().setFlags( flags );
94      }
95      
96      
97      /**
98       * {@inheritDoc}
99       */
100     @Override
101     public void addFlag( AdDirSyncFlag flag )
102     {
103         getDecorated().addFlag( flag );
104     }
105 
106     
107     /**
108      * {@inheritDoc}
109      */
110     @Override
111     public void removeFlag( AdDirSyncFlag flag )
112     {
113         getDecorated().removeFlag( flag );
114     }
115 
116     
117     /**
118      * {@inheritDoc}
119      */
120     @Override
121     public int getMaxReturnLength()
122     {
123         return getDecorated().getMaxReturnLength();
124     }
125 
126     
127     /**
128      * {@inheritDoc}
129      */
130     @Override
131     public void setMaxReturnLength( int maxReturnLength )
132     {
133         getDecorated().setMaxReturnLength( maxReturnLength );
134     }
135     
136 
137     /**
138      * {@inheritDoc}
139      */
140     @Override
141     public byte[] getCookie()
142     {
143         return getDecorated().getCookie();
144     }
145 
146 
147     /**
148      * {@inheritDoc}
149      */
150     @Override
151     public void setCookie( byte[] cookie )
152     {
153         // Copy the bytes
154         if ( !Strings.isEmpty( cookie ) )
155         {
156             byte[] copy = new byte[cookie.length];
157             System.arraycopy( cookie, 0, copy, 0, cookie.length );
158             getDecorated().setCookie( copy );
159         }
160         else
161         {
162             getDecorated().setCookie( null );
163         }
164     }
165 
166 
167     /**
168      * Compute the AdDirSync length. We use the client side control.
169      * <pre>
170      * 0x30 L1
171      * |
172      * +--&gt; 0x02 0x0(1-4) nnn  (flags)
173      * +--&gt; 0x02 0x0(1-4) nnn  (maxReturnLength)
174      * +--&gt; 0x04 L2 xkcd!!!...     (cookie)
175      * </pre>
176      */
177     @Override
178     public int computeLength()
179     {
180         // the flags length
181         int flagsLength = BerValue.getNbBytes( AdDirSyncFlag.getBitmask( getFlags() ) );
182         adDirSyncLength = 1 + TLV.getNbBytes( flagsLength ) + flagsLength;
183 
184         // the maxReturnLength length
185         int maxReturnLengthLength = BerValue.getNbBytes( getMaxReturnLength() );
186         adDirSyncLength += 1 + TLV.getNbBytes( maxReturnLengthLength ) + maxReturnLengthLength;
187 
188         // cookie's length
189         byte[] cookie = getCookie();
190         
191         if ( cookie == null )
192         {
193             adDirSyncLength += 1 + 1;
194         }
195         else
196         {
197             adDirSyncLength += 1 + TLV.getNbBytes( cookie.length ) + cookie.length;
198         }
199 
200         valueLength = 1 + TLV.getNbBytes( adDirSyncLength ) + adDirSyncLength;
201 
202         // Call the super class to compute the global control length
203         return valueLength;
204     }
205 
206 
207     /**
208      * Encode the AdDirSync control. We use the client side control.
209      *
210      * @param buffer The encoded sink
211      * @return A ByteBuffer that contains the encoded PDU
212      * @throws EncoderException If anything goes wrong while encoding.
213      */
214     @Override
215     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
216     {
217         if ( buffer == null )
218         {
219             throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
220         }
221 
222         // Encode the SEQ
223         buffer.put( UniversalTag.SEQUENCE.getValue() );
224         buffer.put( TLV.getBytes( adDirSyncLength ) );
225 
226         // Encode the flags
227         BerValue.encode( buffer, AdDirSyncFlag.getBitmask( getFlags() ) );
228 
229         // Encode the MaxReturnLength
230         BerValue.encode( buffer, getMaxReturnLength() );
231         
232         // Encode the cookie
233         BerValue.encode( buffer, getCookie() );
234 
235         return buffer;
236     }
237 
238 
239     /**
240      * {@inheritDoc}
241      */
242     @Override
243     public byte[] getValue()
244     {
245         if ( value == null )
246         {
247             try
248             {
249                 computeLength();
250                 ByteBuffer buffer = ByteBuffer.allocate( valueLength );
251 
252                 // Encode the SEQ
253                 buffer.put( UniversalTag.SEQUENCE.getValue() );
254                 buffer.put( TLV.getBytes( adDirSyncLength ) );
255 
256                 // Encode the Flags flag
257                 BerValue.encode( buffer, AdDirSyncFlag.getBitmask( getFlags() ) );
258 
259                 // Encode the MaxReturnLength
260                 BerValue.encode( buffer, getMaxReturnLength() );
261                 
262                 // Encode the cookie
263                 BerValue.encode( buffer, getCookie() );
264 
265                 value = buffer.array();
266             }
267             catch ( Exception e )
268             {
269                 return null;
270             }
271         }
272 
273         return value;
274     }
275     
276     
277     /**
278      * {@inheritDoc}
279      */
280     @Override
281     public Asn1Object decode( byte[] controlBytes ) throws DecoderException
282     {
283         ByteBuffer bb = ByteBuffer.wrap( controlBytes );
284         AdDirSyncContainer container = new AdDirSyncContainer( getCodecService(), this );
285         DECODER.decode( bb, container );
286         return this;
287     }
288 }