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.codec.controls.search.persistentSearch;
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.model.message.controls.ChangeType;
36  import org.apache.directory.api.ldap.model.message.controls.PersistentSearch;
37  import org.apache.directory.api.ldap.model.message.controls.PersistentSearchImpl;
38  
39  
40  /**
41   * A persistence search object
42   * 
43   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
44   */
45  public class PersistentSearchDecorator extends ControlDecorator<PersistentSearch> implements PersistentSearch
46  {
47      /** A temporary storage for a psearch length */
48      private int psearchSeqLength;
49  
50      /** An instance of this decoder */
51      private static final Asn1Decoder DECODER = new Asn1Decoder();
52  
53  
54      /**
55       * Default constructor creates a PersistentSearch Control automatically
56       * wrapped in a decorator object inside this container.
57       * 
58       * @param codec The LDAP service instance
59       */
60      public PersistentSearchDecorator( LdapApiService codec )
61      {
62          this( codec, new PersistentSearchImpl() );
63      }
64  
65  
66      /**
67       * Creates a PersistentSearch Control wrapping a supplied PersistentSearch
68       * Control.
69       *
70       * @param codec The LDAP service instance
71       * @param control The PersistentSearch Control to wrap.
72       */
73      public PersistentSearchDecorator( LdapApiService codec, PersistentSearch control )
74      {
75          super( codec, control );
76      }
77  
78  
79      /**
80       * Compute the PagedSearchControl length, which is the sum
81       * of the control length and the value length.
82       * 
83       * <pre>
84       * PersistentSearchDecorator value length :
85       * 
86       * 0x30 L1 
87       *   | 
88       *   +--&gt; 0x02 0x0(1-4) [0..2^31-1] (changeTypes) 
89       *   +--&gt; 0x01 0x01 [0x00 | 0xFF] (changeOnly) 
90       *   +--&gt; 0x01 0x01 [0x00 | 0xFF] (returnRCs)
91       * </pre>
92       *  
93       * @return the control length.
94       */
95      @Override
96      public int computeLength()
97      {
98          int changeTypesLength = 1 + 1 + BerValue.getNbBytes( getChangeTypes() );
99          int changesOnlyLength = 1 + 1 + 1;
100         int returnRCsLength = 1 + 1 + 1;
101 
102         psearchSeqLength = changeTypesLength + changesOnlyLength + returnRCsLength;
103         
104         return 1 + TLV.getNbBytes( psearchSeqLength ) + psearchSeqLength;
105     }
106 
107 
108     /**
109      * Encodes the persistent search control.
110      * 
111      * @param buffer The encoded sink
112      * @return A ByteBuffer that contains the encoded PDU
113      * @throws EncoderException If anything goes wrong.
114      */
115     @Override
116     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
117     {
118         if ( buffer == null )
119         {
120             throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
121         }
122 
123         // Now encode the PagedSearch specific part
124         buffer.put( UniversalTag.SEQUENCE.getValue() );
125         buffer.put( TLV.getBytes( psearchSeqLength ) );
126 
127         BerValue.encode( buffer, getChangeTypes() );
128         BerValue.encode( buffer, isChangesOnly() );
129         BerValue.encode( buffer, isReturnECs() );
130 
131         return buffer;
132     }
133 
134 
135     /**
136      * {@inheritDoc}
137      */
138     @Override
139     public byte[] getValue()
140     {
141         if ( value == null )
142         {
143             try
144             {
145                 valueLength = computeLength();
146                 ByteBuffer buffer = ByteBuffer.allocate( valueLength );
147 
148                 // Now encode the PagedSearch specific part
149                 buffer.put( UniversalTag.SEQUENCE.getValue() );
150                 buffer.put( TLV.getBytes( psearchSeqLength ) );
151 
152                 BerValue.encode( buffer, getChangeTypes() );
153                 BerValue.encode( buffer, isChangesOnly() );
154                 BerValue.encode( buffer, isReturnECs() );
155 
156                 value = buffer.array();
157             }
158             catch ( EncoderException ee )
159             {
160                 return null;
161             }
162         }
163 
164         return value;
165     }
166 
167 
168     private PersistentSearch getPersistentSearch()
169     {
170         return getDecorated();
171     }
172 
173 
174     /**
175      * {@inheritDoc}
176      */
177     @Override
178     public void setChangesOnly( boolean changesOnly )
179     {
180         getPersistentSearch().setChangesOnly( changesOnly );
181     }
182 
183 
184     /**
185      * {@inheritDoc}
186      */
187     @Override
188     public boolean isChangesOnly()
189     {
190         return getPersistentSearch().isChangesOnly();
191     }
192 
193 
194     /**
195      * {@inheritDoc}
196      */
197     @Override
198     public void setReturnECs( boolean returnECs )
199     {
200         getPersistentSearch().setReturnECs( returnECs );
201     }
202 
203 
204     /**
205      * {@inheritDoc}
206      */
207     @Override
208     public boolean isReturnECs()
209     {
210         return getPersistentSearch().isReturnECs();
211     }
212 
213 
214     /**
215      * {@inheritDoc}
216      */
217     @Override
218     public void setChangeTypes( int changeTypes )
219     {
220         getPersistentSearch().setChangeTypes( changeTypes );
221     }
222 
223 
224     /**
225      * {@inheritDoc}
226      */
227     @Override
228     public int getChangeTypes()
229     {
230         return getPersistentSearch().getChangeTypes();
231     }
232 
233 
234     /**
235      * {@inheritDoc}
236      */
237     @Override
238     public boolean isNotificationEnabled( ChangeType changeType )
239     {
240         return getPersistentSearch().isNotificationEnabled( changeType );
241     }
242 
243 
244     /**
245      * {@inheritDoc}
246      */
247     @Override
248     public void enableNotification( ChangeType changeType )
249     {
250         getPersistentSearch().enableNotification( changeType );
251     }
252 
253 
254     /**
255      * {@inheritDoc}
256      */
257     @Override
258     public void disableNotification( ChangeType changeType )
259     {
260         getPersistentSearch().disableNotification( changeType );
261     }
262 
263 
264     /**
265      * {@inheritDoc}
266      */
267     @Override
268     public Asn1Object decode( byte[] controlBytes ) throws DecoderException
269     {
270         ByteBuffer bb = ByteBuffer.wrap( controlBytes );
271         PersistentSearchContainer container = new PersistentSearchContainer( getCodecService(), this );
272         DECODER.decode( bb, container );
273         return this;
274     }
275 }