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