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