1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.extras.controls.syncrepl_impl;
21
22
23 import java.nio.ByteBuffer;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.apache.directory.api.asn1.Asn1Object;
28 import org.apache.directory.api.asn1.DecoderException;
29 import org.apache.directory.api.asn1.EncoderException;
30 import org.apache.directory.api.asn1.ber.Asn1Decoder;
31 import org.apache.directory.api.asn1.ber.tlv.BerValue;
32 import org.apache.directory.api.asn1.ber.tlv.TLV;
33 import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
34 import org.apache.directory.api.i18n.I18n;
35 import org.apache.directory.api.ldap.codec.api.ControlDecorator;
36 import org.apache.directory.api.ldap.codec.api.LdapApiService;
37 import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SyncInfoValue;
38 import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SyncInfoValueImpl;
39 import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SynchronizationInfoEnum;
40 import org.apache.directory.api.util.Strings;
41
42
43
44
45
46
47
48 public class SyncInfoValueDecorator extends ControlDecorator<SyncInfoValue> implements SyncInfoValue
49 {
50
51 private int syncUUIDsLength;
52
53
54 private static final Asn1Decoder decoder = new Asn1Decoder();
55
56
57
58
59
60 public SyncInfoValueDecorator( LdapApiService codec )
61 {
62 super( codec, new SyncInfoValueImpl() );
63 }
64
65
66
67
68
69 public SyncInfoValueDecorator( LdapApiService codec, SyncInfoValue control )
70 {
71 super( codec, control );
72 }
73
74
75
76
77
78
79
80 public SyncInfoValueDecorator( LdapApiService codec, SynchronizationInfoEnum type )
81 {
82 this( codec );
83
84 setType( type );
85 }
86
87
88 private int syncInfoValueLength;
89
90
91
92
93
94 public SynchronizationInfoEnum getType()
95 {
96 return getDecorated().getType();
97 }
98
99
100
101
102
103 public void setType( SynchronizationInfoEnum type )
104 {
105 this.getDecorated().setType( type );
106
107
108 if ( ( type == SynchronizationInfoEnum.SYNC_ID_SET ) && ( getDecorated().getSyncUUIDs() == null ) )
109 {
110 getDecorated().setSyncUUIDs( new ArrayList<byte[]>() );
111 }
112 }
113
114
115
116
117
118 public byte[] getCookie()
119 {
120 return getDecorated().getCookie();
121 }
122
123
124
125
126
127 public void setCookie( byte[] cookie )
128 {
129
130 if ( !Strings.isEmpty( cookie ) )
131 {
132 byte[] copy = new byte[cookie.length];
133 System.arraycopy( cookie, 0, copy, 0, cookie.length );
134 getDecorated().setCookie( copy );
135 }
136 else
137 {
138 getDecorated().setCookie( null );
139 }
140 }
141
142
143
144
145
146 public boolean isRefreshDone()
147 {
148 return getDecorated().isRefreshDone();
149 }
150
151
152
153
154
155 public void setRefreshDone( boolean refreshDone )
156 {
157 getDecorated().setRefreshDone( refreshDone );
158 }
159
160
161
162
163
164 public boolean isRefreshDeletes()
165 {
166 return getDecorated().isRefreshDeletes();
167 }
168
169
170
171
172
173 public void setRefreshDeletes( boolean refreshDeletes )
174 {
175 getDecorated().setRefreshDeletes( refreshDeletes );
176 }
177
178
179
180
181
182 public List<byte[]> getSyncUUIDs()
183 {
184 return getDecorated().getSyncUUIDs();
185 }
186
187
188
189
190
191 public void setSyncUUIDs( List<byte[]> syncUUIDs )
192 {
193 getDecorated().setSyncUUIDs( syncUUIDs );
194 }
195
196
197
198
199
200 public void addSyncUUID( byte[] syncUUID )
201 {
202 getDecorated().addSyncUUID( syncUUID );
203 }
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235 @Override
236 public int computeLength()
237 {
238
239 syncInfoValueLength = 0;
240
241 switch ( getType() )
242 {
243 case NEW_COOKIE:
244 if ( getCookie() != null )
245 {
246 syncInfoValueLength = 1 + TLV.getNbBytes( getCookie().length ) + getCookie().length;
247 }
248 else
249 {
250 syncInfoValueLength = 1 + 1;
251 }
252
253 valueLength = syncInfoValueLength;
254
255
256 return valueLength;
257
258 case REFRESH_DELETE:
259 case REFRESH_PRESENT:
260 if ( getCookie() != null )
261 {
262 syncInfoValueLength = 1 + TLV.getNbBytes( getCookie().length ) + getCookie().length;
263 }
264
265
266 if ( !isRefreshDone() )
267 {
268 syncInfoValueLength += 1 + 1 + 1;
269 }
270
271 valueLength = 1 + TLV.getNbBytes( syncInfoValueLength ) + syncInfoValueLength;
272
273
274 return valueLength;
275
276 case SYNC_ID_SET:
277 if ( getCookie() != null )
278 {
279 syncInfoValueLength = 1 + TLV.getNbBytes( getCookie().length ) + getCookie().length;
280 }
281
282
283 if ( isRefreshDeletes() )
284 {
285 syncInfoValueLength += 1 + 1 + 1;
286 }
287
288
289 syncUUIDsLength = 0;
290
291 if ( getSyncUUIDs().size() != 0 )
292 {
293 for ( byte[] syncUUID : getSyncUUIDs() )
294 {
295 int uuidLength = 1 + TLV.getNbBytes( syncUUID.length ) + syncUUID.length;
296
297 syncUUIDsLength += uuidLength;
298 }
299 }
300
301 syncInfoValueLength += 1 + TLV.getNbBytes( syncUUIDsLength ) + syncUUIDsLength;
302 valueLength = 1 + TLV.getNbBytes( syncInfoValueLength ) + syncInfoValueLength;
303
304
305 return valueLength;
306
307 default:
308
309 }
310
311 return 1 + TLV.getNbBytes( syncInfoValueLength ) + syncInfoValueLength;
312 }
313
314
315
316
317
318
319
320
321
322 @Override
323 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
324 {
325 if ( buffer == null )
326 {
327 throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
328 }
329
330 switch ( getType() )
331 {
332 case NEW_COOKIE:
333
334 buffer.put( ( byte ) SyncInfoValueTags.NEW_COOKIE_TAG.getValue() );
335
336
337
338 if ( ( getCookie() == null ) || ( getCookie().length == 0 ) )
339 {
340 buffer.put( ( byte ) 0 );
341 }
342 else
343 {
344 buffer.put( TLV.getBytes( getCookie().length ) );
345 buffer.put( getCookie() );
346 }
347
348 break;
349
350 case REFRESH_DELETE:
351
352 buffer.put( ( byte ) SyncInfoValueTags.REFRESH_DELETE_TAG.getValue() );
353 buffer.put( TLV.getBytes( syncInfoValueLength ) );
354
355
356 if ( getCookie() != null )
357 {
358 BerValue.encode( buffer, getCookie() );
359 }
360
361
362 if ( !isRefreshDone() )
363 {
364 BerValue.encode( buffer, isRefreshDone() );
365 }
366
367 break;
368
369 case REFRESH_PRESENT:
370
371 buffer.put( ( byte ) SyncInfoValueTags.REFRESH_PRESENT_TAG.getValue() );
372 buffer.put( TLV.getBytes( syncInfoValueLength ) );
373
374
375 if ( getCookie() != null )
376 {
377 BerValue.encode( buffer, getCookie() );
378 }
379
380
381 if ( !isRefreshDone() )
382 {
383 BerValue.encode( buffer, isRefreshDone() );
384 }
385
386 break;
387
388 case SYNC_ID_SET:
389
390 buffer.put( ( byte ) SyncInfoValueTags.SYNC_ID_SET_TAG.getValue() );
391 buffer.put( TLV.getBytes( syncInfoValueLength ) );
392
393
394 if ( getCookie() != null )
395 {
396 BerValue.encode( buffer, getCookie() );
397 }
398
399
400 if ( isRefreshDeletes() )
401 {
402 BerValue.encode( buffer, isRefreshDeletes() );
403 }
404
405
406 buffer.put( UniversalTag.SET.getValue() );
407 buffer.put( TLV.getBytes( syncUUIDsLength ) );
408
409
410 if ( getSyncUUIDs().size() != 0 )
411 {
412 for ( byte[] syncUUID : getSyncUUIDs() )
413 {
414 BerValue.encode( buffer, syncUUID );
415 }
416 }
417 }
418
419 return buffer;
420 }
421
422
423
424
425
426 @Override
427 public byte[] getValue()
428 {
429 if ( value == null )
430 {
431 try
432 {
433 computeLength();
434 ByteBuffer buffer = ByteBuffer.allocate( valueLength );
435
436 switch ( getType() )
437 {
438 case NEW_COOKIE:
439
440 buffer.put( ( byte ) SyncInfoValueTags.NEW_COOKIE_TAG.getValue() );
441
442
443
444 if ( ( getCookie() == null ) || ( getCookie().length == 0 ) )
445 {
446 buffer.put( ( byte ) 0 );
447 }
448 else
449 {
450 buffer.put( TLV.getBytes( getCookie().length ) );
451 buffer.put( getCookie() );
452 }
453
454 break;
455
456 case REFRESH_DELETE:
457
458 buffer.put( ( byte ) SyncInfoValueTags.REFRESH_DELETE_TAG.getValue() );
459 buffer.put( TLV.getBytes( syncInfoValueLength ) );
460
461
462 if ( getCookie() != null )
463 {
464 BerValue.encode( buffer, getCookie() );
465 }
466
467
468 if ( !isRefreshDone() )
469 {
470 BerValue.encode( buffer, isRefreshDone() );
471 }
472
473 break;
474
475 case REFRESH_PRESENT:
476
477 buffer.put( ( byte ) SyncInfoValueTags.REFRESH_PRESENT_TAG.getValue() );
478 buffer.put( TLV.getBytes( syncInfoValueLength ) );
479
480
481 if ( getCookie() != null )
482 {
483 BerValue.encode( buffer, getCookie() );
484 }
485
486
487 if ( !isRefreshDone() )
488 {
489 BerValue.encode( buffer, isRefreshDone() );
490 }
491
492 break;
493
494 case SYNC_ID_SET:
495
496 buffer.put( ( byte ) SyncInfoValueTags.SYNC_ID_SET_TAG.getValue() );
497 buffer.put( TLV.getBytes( syncInfoValueLength ) );
498
499
500 if ( getCookie() != null )
501 {
502 BerValue.encode( buffer, getCookie() );
503 }
504
505
506 if ( isRefreshDeletes() )
507 {
508 BerValue.encode( buffer, isRefreshDeletes() );
509 }
510
511
512 buffer.put( UniversalTag.SET.getValue() );
513 buffer.put( TLV.getBytes( syncUUIDsLength ) );
514
515
516 if ( getSyncUUIDs().size() != 0 )
517 {
518 for ( byte[] syncUUID : getSyncUUIDs() )
519 {
520 BerValue.encode( buffer, syncUUID );
521 }
522 }
523 }
524
525 value = buffer.array();
526 }
527 catch ( EncoderException e )
528 {
529 return null;
530 }
531 }
532
533 return value;
534 }
535
536
537
538
539
540 public Asn1Object decode( byte[] controlBytes ) throws DecoderException
541 {
542 ByteBuffer bb = ByteBuffer.wrap( controlBytes );
543 SyncInfoValueContainer container = new SyncInfoValueContainer( getCodecService(), this );
544 decoder.decode( bb, container );
545 return this;
546 }
547
548
549
550
551
552 public String toString()
553 {
554 return getDecorated().toString();
555 }
556 }