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.codec.decorators;
21
22
23 import java.nio.BufferOverflowException;
24 import java.nio.ByteBuffer;
25 import java.util.LinkedList;
26 import java.util.List;
27
28 import org.apache.directory.api.asn1.EncoderException;
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.LdapApiService;
34 import org.apache.directory.api.ldap.codec.api.LdapCodecConstants;
35 import org.apache.directory.api.ldap.model.entry.Attribute;
36 import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
37 import org.apache.directory.api.ldap.model.entry.Entry;
38 import org.apache.directory.api.ldap.model.entry.Value;
39 import org.apache.directory.api.ldap.model.exception.LdapException;
40 import org.apache.directory.api.ldap.model.message.AddRequest;
41 import org.apache.directory.api.ldap.model.message.Control;
42 import org.apache.directory.api.ldap.model.name.Dn;
43 import org.apache.directory.api.util.Strings;
44
45
46
47
48
49
50
51 public final class AddRequestDecorator extends SingleReplyRequestDecorator<AddRequest> implements
52 AddRequest
53 {
54
55 private int addRequestLength;
56
57
58 private int entryLength;
59
60
61 private List<Integer> attributesLength;
62
63
64 private List<byte[]> attributeIds;
65
66
67 private List<Integer> valuesLength;
68
69
70 private Attribute currentAttribute;
71
72
73 private byte[] dnBytes;
74
75
76
77
78
79
80
81 public AddRequestDecorator( LdapApiService codec, AddRequest decoratedMessage )
82 {
83 super( codec, decoratedMessage );
84 }
85
86
87
88
89
90
91 public void setAddRequestLength( int addRequestLength )
92 {
93 this.addRequestLength = addRequestLength;
94 }
95
96
97
98
99
100 public int getAddRequestLength()
101 {
102 return addRequestLength;
103 }
104
105
106
107
108
109
110 public void setEntryLength( int entryLength )
111 {
112 this.entryLength = entryLength;
113 }
114
115
116
117
118
119 public int getEntryLength()
120 {
121 return entryLength;
122 }
123
124
125
126
127
128
129 public void setAttributesLength( List<Integer> attributesLength )
130 {
131 this.attributesLength = attributesLength;
132 }
133
134
135
136
137
138 public List<Integer> getAttributesLength()
139 {
140 return attributesLength;
141 }
142
143
144
145
146
147
148 public void setValuesLength( List<Integer> valuesLength )
149 {
150 this.valuesLength = valuesLength;
151 }
152
153
154
155
156
157 public List<Integer> getValuesLength()
158 {
159 return valuesLength;
160 }
161
162
163
164
165
166 public AddRequest setMessageId( int messageId )
167 {
168 super.setMessageId( messageId );
169
170 return this;
171 }
172
173
174
175
176
177 public AddRequest addControl( Control control )
178 {
179 return ( AddRequest ) super.addControl( control );
180 }
181
182
183
184
185
186 public AddRequest addAllControls( Control[] controls )
187 {
188 return ( AddRequest ) super.addAllControls( controls );
189 }
190
191
192
193
194
195 public AddRequest removeControl( Control control )
196 {
197 return ( AddRequest ) super.removeControl( control );
198 }
199
200
201
202
203
204
205
206
207
208 public Dn getEntryDn()
209 {
210 return getDecorated().getEntryDn();
211 }
212
213
214
215
216
217 public AddRequest setEntryDn( Dn entry )
218 {
219 getDecorated().setEntryDn( entry );
220
221 return this;
222 }
223
224
225
226
227
228 public Entry getEntry()
229 {
230 return getDecorated().getEntry();
231 }
232
233
234
235
236
237 public AddRequest setEntry( Entry entry )
238 {
239 getDecorated().setEntry( entry );
240
241 return this;
242 }
243
244
245
246
247
248
249
250 public void addAttributeType( String type ) throws LdapException
251 {
252
253 if ( getDecorated().getEntry().get( type ) != null )
254 {
255 currentAttribute = getDecorated().getEntry().get( type );
256 return;
257 }
258
259
260 currentAttribute = new DefaultAttribute( type );
261 getDecorated().getEntry().put( currentAttribute );
262 }
263
264
265
266
267
268 public String getCurrentAttributeType()
269 {
270 return currentAttribute.getUpId();
271 }
272
273
274
275
276
277
278
279 public void addAttributeValue( String value ) throws LdapException
280 {
281 currentAttribute.add( value );
282 }
283
284
285
286
287
288
289
290 public void addAttributeValue( Value<?> value ) throws LdapException
291 {
292 currentAttribute.add( value );
293 }
294
295
296
297
298
299
300
301 public void addAttributeValue( byte[] value ) throws LdapException
302 {
303 currentAttribute.add( value );
304 }
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 public int computeLength()
350 {
351 AddRequest addRequest = getDecorated();
352 Entry entry = addRequest.getEntry();
353
354 if ( entry == null )
355 {
356 throw new IllegalArgumentException( I18n.err( I18n.ERR_04481_ENTRY_NULL_VALUE ) );
357 }
358
359 dnBytes = Strings.getBytesUtf8( entry.getDn().getName() );
360 int dnLen = dnBytes.length;
361
362
363 int addRequestLength = 1 + TLV.getNbBytes( dnLen ) + dnLen;
364
365
366 int entryLength = 0;
367
368 if ( entry.size() != 0 )
369 {
370 attributesLength = new LinkedList<Integer>();
371 attributeIds = new LinkedList<byte[]>();
372 valuesLength = new LinkedList<Integer>();
373
374
375 for ( Attribute attribute : entry )
376 {
377 int localAttributeLength = 0;
378 int localValuesLength = 0;
379
380
381 byte[] attributeIdBytes = Strings.getBytesUtf8( attribute.getUpId() );
382 attributeIds.add( attributeIdBytes );
383
384 int idLength = attributeIdBytes.length;
385 localAttributeLength = 1 + TLV.getNbBytes( idLength ) + idLength;
386
387
388 if ( attribute.size() != 0 )
389 {
390 localValuesLength = 0;
391
392 for ( Value<?> value : attribute )
393 {
394 if ( value.getBytes() == null )
395 {
396 localValuesLength += 1 + 1;
397 }
398 else
399 {
400 int valueLength = value.getBytes().length;
401 localValuesLength += 1 + TLV.getNbBytes( valueLength ) + valueLength;
402 }
403 }
404
405 localAttributeLength += 1 + TLV.getNbBytes( localValuesLength ) + localValuesLength;
406 }
407 else
408 {
409
410 localValuesLength = 1 + 1;
411 localAttributeLength += 1 + 1 + localValuesLength;
412 }
413
414
415 entryLength += 1 + TLV.getNbBytes( localAttributeLength ) + localAttributeLength;
416
417 attributesLength.add( localAttributeLength );
418 valuesLength.add( localValuesLength );
419 }
420
421 setAttributesLength( attributesLength );
422 setValuesLength( valuesLength );
423 setEntryLength( entryLength );
424 }
425
426 addRequestLength += 1 + TLV.getNbBytes( entryLength ) + entryLength;
427 setAddRequestLength( addRequestLength );
428
429
430 return 1 + TLV.getNbBytes( addRequestLength ) + addRequestLength;
431 }
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
459 {
460 try
461 {
462
463 buffer.put( LdapCodecConstants.ADD_REQUEST_TAG );
464 buffer.put( TLV.getBytes( getAddRequestLength() ) );
465
466
467 BerValue.encode( buffer, dnBytes );
468
469
470 buffer.put( UniversalTag.SEQUENCE.getValue() );
471 buffer.put( TLV.getBytes( getEntryLength() ) );
472
473
474 Entry entry = getEntry();
475
476 if ( entry.size() != 0 )
477 {
478 int attributeNumber = 0;
479
480
481 for ( Attribute attribute : entry )
482 {
483
484 buffer.put( UniversalTag.SEQUENCE.getValue() );
485 int localAttributeLength = attributesLength.get( attributeNumber );
486 buffer.put( TLV.getBytes( localAttributeLength ) );
487
488
489 BerValue.encode( buffer, attributeIds.get( attributeNumber ) );
490
491
492 buffer.put( UniversalTag.SET.getValue() );
493 int localValuesLength = valuesLength.get( attributeNumber );
494 buffer.put( TLV.getBytes( localValuesLength ) );
495
496 if ( attribute.size() != 0 )
497 {
498 for ( Value<?> value : attribute )
499 {
500 BerValue.encode( buffer, value.getBytes() );
501 }
502 }
503 else
504 {
505 BerValue.encode( buffer, Strings.EMPTY_BYTES );
506 }
507
508
509 attributeNumber++;
510 }
511 }
512
513 return buffer;
514 }
515 catch ( BufferOverflowException boe )
516 {
517 throw new EncoderException( "The PDU buffer size is too small !" );
518 }
519 }
520 }