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.syncrepl.syncState.SyncStateTypeEnum;
36  import org.apache.directory.api.ldap.extras.controls.syncrepl.syncState.SyncStateValue;
37  import org.apache.directory.api.ldap.extras.controls.syncrepl.syncState.SyncStateValueImpl;
38  
39  
40  /**
41   * A syncStateValue object, as defined in RFC 4533
42   *
43   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
44   */
45  public class SyncStateValueDecorator extends ControlDecorator<SyncStateValue> implements SyncStateValue
46  {
47      /** Global length for the control */
48      private int syncStateSeqLength;
49  
50      /** An instance of this decoder */
51      private static final Asn1Decoder decoder = new Asn1Decoder();
52  
53  
54      public SyncStateValueDecorator( LdapApiService codec )
55      {
56          super( codec, new SyncStateValueImpl() );
57      }
58  
59  
60      public SyncStateValueDecorator( LdapApiService codec, SyncStateValue value )
61      {
62          super( codec, value );
63      }
64  
65  
66      /**
67       * {@inheritDoc}
68       */
69      public byte[] getCookie()
70      {
71          return getDecorated().getCookie();
72      }
73  
74  
75      /**
76       * {@inheritDoc}
77       */
78      public void setCookie( byte[] cookie )
79      {
80          getDecorated().setCookie( cookie );
81      }
82  
83  
84      /**
85       * {@inheritDoc}
86       */
87      public SyncStateTypeEnum getSyncStateType()
88      {
89          return getDecorated().getSyncStateType();
90      }
91  
92  
93      /**
94       * {@inheritDoc}
95       */
96      public void setSyncStateType( SyncStateTypeEnum syncStateType )
97      {
98          getDecorated().setSyncStateType( syncStateType );
99      }
100 
101 
102     /**
103      * {@inheritDoc}
104      */
105     public byte[] getEntryUUID()
106     {
107         return getDecorated().getEntryUUID();
108     }
109 
110 
111     /**
112      * {@inheritDoc}
113      */
114     public void setEntryUUID( byte[] entryUUID )
115     {
116         getDecorated().setEntryUUID( entryUUID );
117     }
118 
119 
120     /**
121      * Compute the SyncStateValue length.
122      *
123      * SyncStateValue :
124      * 0x30 L1
125      *  |
126      *  +--> 0x0A 0x01 [0x00|0x01|0x02|0x03] (type)
127      * [+--> 0x04 L2 abcd...                 (entryUUID)
128      * [+--> 0x04 L3 abcd...                 (cookie)
129      *
130      */
131     @Override
132     public int computeLength()
133     {
134         // The sync state type length
135         syncStateSeqLength = 1 + 1 + 1;
136 
137         syncStateSeqLength += 1 + TLV.getNbBytes( getEntryUUID().length ) + getEntryUUID().length;
138 
139         // The cookie length, if we have a cookie
140         if ( getCookie() != null )
141         {
142             syncStateSeqLength += 1 + TLV.getNbBytes( getCookie().length ) + getCookie().length;
143         }
144 
145         valueLength = 1 + TLV.getNbBytes( syncStateSeqLength ) + syncStateSeqLength;
146 
147         return valueLength;
148     }
149 
150 
151     /**
152      * Encode the SyncStateValue control
153      *
154      * @param buffer The encoded sink
155      * @return A ByteBuffer that contains the encoded PDU
156      * @throws EncoderException If anything goes wrong.
157      */
158     @Override
159     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
160     {
161         if ( buffer == null )
162         {
163             throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
164         }
165 
166         // Encode the SEQ
167         buffer.put( UniversalTag.SEQUENCE.getValue() );
168         buffer.put( TLV.getBytes( syncStateSeqLength ) );
169 
170         // The mode
171         buffer.put( UniversalTag.ENUMERATED.getValue() );
172         buffer.put( ( byte ) 0x01 );
173         buffer.put( BerValue.getBytes( getSyncStateType().getValue() ) );
174 
175         // the entryUUID
176         BerValue.encode( buffer, getEntryUUID() );
177 
178         // The cookie
179         if ( getCookie() != null )
180         {
181             BerValue.encode( buffer, getCookie() );
182         }
183 
184         return buffer;
185     }
186 
187 
188     /**
189      * {@inheritDoc}
190      */
191     @Override
192     public byte[] getValue()
193     {
194         if ( value == null )
195         {
196             try
197             {
198                 computeLength();
199                 ByteBuffer buffer = ByteBuffer.allocate( valueLength );
200 
201                 // Encode the SEQ
202                 buffer.put( UniversalTag.SEQUENCE.getValue() );
203                 buffer.put( TLV.getBytes( syncStateSeqLength ) );
204 
205                 // The mode
206                 buffer.put( UniversalTag.ENUMERATED.getValue() );
207                 buffer.put( ( byte ) 0x01 );
208                 buffer.put( BerValue.getBytes( getSyncStateType().getValue() ) );
209 
210                 // the entryUUID
211                 BerValue.encode( buffer, getEntryUUID() );
212 
213                 // The cookie
214                 if ( getCookie() != null )
215                 {
216                     BerValue.encode( buffer, getCookie() );
217                 }
218 
219                 value = buffer.array();
220             }
221             catch ( Exception e )
222             {
223                 return null;
224             }
225         }
226 
227         return value;
228     }
229 
230 
231     /**
232      * {@inheritDoc}
233      */
234     public Asn1Object decode( byte[] controlBytes ) throws DecoderException
235     {
236         ByteBuffer bb = ByteBuffer.wrap( controlBytes );
237         SyncStateValueContainer container = new SyncStateValueContainer( this );
238         decoder.decode( bb, container );
239         return this;
240     }
241 }