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