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.osgi;
21
22
23 import java.nio.ByteBuffer;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.Map;
28
29 import javax.naming.NamingException;
30 import javax.naming.ldap.BasicControl;
31
32 import org.apache.directory.api.asn1.DecoderException;
33 import org.apache.directory.api.asn1.EncoderException;
34 import org.apache.directory.api.asn1.ber.Asn1Container;
35 import org.apache.directory.api.ldap.codec.BasicControlDecorator;
36 import org.apache.directory.api.ldap.codec.api.CodecControl;
37 import org.apache.directory.api.ldap.codec.api.ControlFactory;
38 import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory;
39 import org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator;
40 import org.apache.directory.api.ldap.codec.api.ExtendedResponseDecorator;
41 import org.apache.directory.api.ldap.codec.api.LdapApiService;
42 import org.apache.directory.api.ldap.codec.api.LdapMessageContainer;
43 import org.apache.directory.api.ldap.codec.api.MessageDecorator;
44 import org.apache.directory.api.ldap.codec.controls.cascade.CascadeFactory;
45 import org.apache.directory.api.ldap.codec.controls.manageDsaIT.ManageDsaITFactory;
46 import org.apache.directory.api.ldap.codec.controls.search.entryChange.EntryChangeFactory;
47 import org.apache.directory.api.ldap.codec.controls.search.pagedSearch.PagedResultsFactory;
48 import org.apache.directory.api.ldap.codec.controls.search.persistentSearch.PersistentSearchFactory;
49 import org.apache.directory.api.ldap.codec.controls.search.subentries.SubentriesFactory;
50 import org.apache.directory.api.ldap.model.message.Control;
51 import org.apache.directory.api.ldap.model.message.ExtendedRequest;
52 import org.apache.directory.api.ldap.model.message.ExtendedRequestImpl;
53 import org.apache.directory.api.ldap.model.message.ExtendedResponse;
54 import org.apache.directory.api.ldap.model.message.ExtendedResponseImpl;
55 import org.apache.directory.api.ldap.model.message.Message;
56 import org.apache.directory.api.ldap.model.message.controls.Cascade;
57 import org.apache.directory.api.ldap.model.message.controls.EntryChange;
58 import org.apache.directory.api.ldap.model.message.controls.ManageDsaIT;
59 import org.apache.directory.api.ldap.model.message.controls.OpaqueControl;
60 import org.apache.directory.api.ldap.model.message.controls.PagedResults;
61 import org.apache.directory.api.ldap.model.message.controls.PersistentSearch;
62 import org.apache.directory.api.ldap.model.message.controls.Subentries;
63 import org.apache.directory.api.util.Strings;
64 import org.apache.directory.api.util.exception.NotImplementedException;
65 import org.apache.mina.filter.codec.ProtocolCodecFactory;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68
69
70
71
72
73
74
75
76 public class DefaultLdapCodecService implements LdapApiService
77 {
78
79 private static final Logger LOG = LoggerFactory.getLogger( DefaultLdapCodecService.class );
80
81
82 protected Map<String, ControlFactory<? extends Control>> controlFactories = new HashMap<String, ControlFactory<? extends Control>>();
83
84
85 protected Map<String, ExtendedOperationFactory> extendedOperationsFactories = new HashMap<String, ExtendedOperationFactory>();
86
87
88 protected ProtocolCodecFactory protocolCodecFactory;
89
90
91
92
93
94 public DefaultLdapCodecService()
95 {
96 loadStockControls();
97 }
98
99
100
101
102
103 private void loadStockControls()
104 {
105 ControlFactory<Cascade> cascadeFactory = new CascadeFactory( this );
106 controlFactories.put( cascadeFactory.getOid(), cascadeFactory );
107 LOG.info( "Registered pre-bundled control factory: {}", cascadeFactory.getOid() );
108
109 ControlFactory<EntryChange> entryChangeFactory = new EntryChangeFactory( this );
110 controlFactories.put( entryChangeFactory.getOid(), entryChangeFactory );
111 LOG.info( "Registered pre-bundled control factory: {}", entryChangeFactory.getOid() );
112
113 ControlFactory<ManageDsaIT> manageDsaItFactory = new ManageDsaITFactory( this );
114 controlFactories.put( manageDsaItFactory.getOid(), manageDsaItFactory );
115 LOG.info( "Registered pre-bundled control factory: {}", manageDsaItFactory.getOid() );
116
117 ControlFactory<PagedResults> pageResultsFactory = new PagedResultsFactory( this );
118 controlFactories.put( pageResultsFactory.getOid(), pageResultsFactory );
119 LOG.info( "Registered pre-bundled control factory: {}", pageResultsFactory.getOid() );
120
121 ControlFactory<PersistentSearch> persistentSearchFactory = new PersistentSearchFactory( this );
122 controlFactories.put( persistentSearchFactory.getOid(), persistentSearchFactory );
123 LOG.info( "Registered pre-bundled control factory: {}", persistentSearchFactory.getOid() );
124
125 ControlFactory<Subentries> subentriesFactory = new SubentriesFactory( this );
126 controlFactories.put( subentriesFactory.getOid(), subentriesFactory );
127 LOG.info( "Registered pre-bundled control factory: {}", subentriesFactory.getOid() );
128 }
129
130
131
132
133
134
135
136
137
138 public ControlFactory<?> registerControl( ControlFactory<?> factory )
139 {
140 return controlFactories.put( factory.getOid(), factory );
141 }
142
143
144
145
146
147 public ControlFactory<?> unregisterControl( String oid )
148 {
149 return controlFactories.remove( oid );
150 }
151
152
153
154
155
156 public Iterator<String> registeredControls()
157 {
158 return Collections.unmodifiableSet( controlFactories.keySet() ).iterator();
159 }
160
161
162
163
164
165 public boolean isControlRegistered( String oid )
166 {
167 return controlFactories.containsKey( oid );
168 }
169
170
171
172
173
174 public Iterator<String> registeredExtendedRequests()
175 {
176 return Collections.unmodifiableSet( extendedOperationsFactories.keySet() ).iterator();
177 }
178
179
180
181
182
183 public ExtendedOperationFactory registerExtendedRequest( ExtendedOperationFactory factory )
184 {
185 return extendedOperationsFactories.put( factory.getOid(), factory );
186 }
187
188
189
190
191
192 public ProtocolCodecFactory getProtocolCodecFactory()
193 {
194 return protocolCodecFactory;
195 }
196
197
198 public ProtocolCodecFactory registerProtocolCodecFactory( ProtocolCodecFactory protocolCodecFactory )
199 {
200 ProtocolCodecFactory oldFactory = this.protocolCodecFactory;
201 this.protocolCodecFactory = protocolCodecFactory;
202 return oldFactory;
203 }
204
205
206
207
208
209 public CodecControl<? extends Control> newControl( String oid )
210 {
211 ControlFactory<?> factory = controlFactories.get( oid );
212
213 if ( factory == null )
214 {
215 return new BasicControlDecorator<Control>( this, new OpaqueControl( oid ) );
216 }
217
218 return factory.newCodecControl();
219 }
220
221
222
223
224
225 @SuppressWarnings("unchecked")
226 public CodecControl<? extends Control> newControl( Control control )
227 {
228 if ( control == null )
229 {
230 throw new NullPointerException( "Control argument was null." );
231 }
232
233
234 if ( control instanceof CodecControl )
235 {
236 return ( CodecControl<?> ) control;
237 }
238
239 @SuppressWarnings("rawtypes")
240 ControlFactory factory = controlFactories.get( control.getOid() );
241
242 if ( factory == null )
243 {
244 return new BasicControlDecorator<Control>( this, control );
245 }
246
247 return factory.newCodecControl( control );
248 }
249
250
251
252
253
254 public javax.naming.ldap.Control toJndiControl( Control control ) throws EncoderException
255 {
256 CodecControl<? extends Control> decorator = newControl( control );
257 ByteBuffer bb = ByteBuffer.allocate( decorator.computeLength() );
258 decorator.encode( bb );
259 bb.flip();
260 BasicControl jndiControl =
261 new BasicControl( control.getOid(), control.isCritical(), bb.array() );
262 return jndiControl;
263 }
264
265
266
267
268
269 public Control fromJndiControl( javax.naming.ldap.Control control ) throws DecoderException
270 {
271 @SuppressWarnings("rawtypes")
272 ControlFactory factory = controlFactories.get( control.getID() );
273
274 if ( factory == null )
275 {
276 OpaqueControl ourControl = new OpaqueControl( control.getID() );
277 ourControl.setCritical( control.isCritical() );
278 BasicControlDecorator<Control> decorator =
279 new BasicControlDecorator<Control>( this, ourControl );
280 decorator.setValue( control.getEncodedValue() );
281 return decorator;
282 }
283
284 @SuppressWarnings("unchecked")
285 CodecControl<? extends Control> ourControl = factory.newCodecControl();
286 ourControl.setCritical( control.isCritical() );
287 ourControl.setValue( control.getEncodedValue() );
288 ourControl.decode( control.getEncodedValue() );
289
290 return ourControl;
291 }
292
293
294
295
296
297 public Asn1Container newMessageContainer()
298 {
299 return new LdapMessageContainer<MessageDecorator<? extends Message>>( this );
300 }
301
302
303
304
305
306 public ExtendedOperationFactory unregisterExtendedRequest( String oid )
307 {
308 return extendedOperationsFactories.remove( oid );
309 }
310
311
312
313
314
315 public javax.naming.ldap.ExtendedResponse toJndi( final ExtendedResponse modelResponse ) throws EncoderException
316 {
317 throw new NotImplementedException( "Figure out how to transform" );
318 }
319
320
321
322
323
324 public ExtendedResponse fromJndi( javax.naming.ldap.ExtendedResponse jndiResponse ) throws DecoderException
325 {
326 throw new NotImplementedException( "Figure out how to transform" );
327 }
328
329
330
331
332
333 public ExtendedRequest fromJndi( javax.naming.ldap.ExtendedRequest jndiRequest ) throws DecoderException
334 {
335 ExtendedRequestDecorator<?> decorator =
336 ( ExtendedRequestDecorator<?> ) newExtendedRequest( jndiRequest.getID(), jndiRequest.getEncodedValue() );
337 return decorator;
338 }
339
340
341
342
343
344 public javax.naming.ldap.ExtendedRequest toJndi( final ExtendedRequest modelRequest ) throws EncoderException
345 {
346 final String oid = modelRequest.getRequestName();
347 final byte[] value;
348
349 if ( modelRequest instanceof ExtendedRequestDecorator )
350 {
351 ExtendedRequestDecorator<?> decorator = ( ExtendedRequestDecorator<?> ) modelRequest;
352 value = decorator.getRequestValue();
353 }
354 else
355 {
356
357 ExtendedOperationFactory extendedRequestFactory = extendedOperationsFactories.get( modelRequest
358 .getRequestName() );
359 ExtendedRequestDecorator<?> decorator = ( ExtendedRequestDecorator<?> ) extendedRequestFactory
360 .decorate( modelRequest );
361 value = decorator.getRequestValue();
362 }
363
364 javax.naming.ldap.ExtendedRequest jndiRequest = new javax.naming.ldap.ExtendedRequest()
365 {
366 private static final long serialVersionUID = -4160980385909987475L;
367
368
369 public String getID()
370 {
371 return oid;
372 }
373
374
375 public byte[] getEncodedValue()
376 {
377 return value;
378 }
379
380
381 public javax.naming.ldap.ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset,
382 int length ) throws NamingException
383 {
384 ExtendedOperationFactory factory = extendedOperationsFactories
385 .get( modelRequest.getRequestName() );
386
387 try
388 {
389 final ExtendedResponseDecorator<?> resp = ( ExtendedResponseDecorator<?> ) factory
390 .newResponse( berValue );
391 javax.naming.ldap.ExtendedResponse jndiResponse = new javax.naming.ldap.ExtendedResponse()
392 {
393 private static final long serialVersionUID = -7686354122066100703L;
394
395
396 public String getID()
397 {
398 return oid;
399 }
400
401
402 public byte[] getEncodedValue()
403 {
404 return resp.getResponseValue();
405 }
406 };
407
408 return jndiResponse;
409 }
410 catch ( DecoderException e )
411 {
412 NamingException ne = new NamingException( "Unable to decode encoded response value: " +
413 Strings.dumpBytes( berValue ) );
414 ne.setRootCause( e );
415 throw ne;
416 }
417 }
418 };
419
420 return jndiRequest;
421 }
422
423
424
425
426
427
428 @SuppressWarnings("unchecked")
429 public <E extends ExtendedResponse> E newExtendedResponse( String responseName, int messageId,
430 byte[] serializedResponse )
431 throws DecoderException
432 {
433 ExtendedResponseDecorator<ExtendedResponse> resp;
434
435 ExtendedOperationFactory extendedRequestFactory = extendedOperationsFactories.get( responseName );
436
437 if ( extendedRequestFactory != null )
438 {
439 resp = ( ExtendedResponseDecorator<ExtendedResponse> ) extendedRequestFactory
440 .newResponse( serializedResponse );
441 }
442 else
443 {
444 resp = new ExtendedResponseDecorator<ExtendedResponse>( this,
445 new ExtendedResponseImpl( responseName ) );
446 resp.setResponseValue( serializedResponse );
447 resp.setResponseName( responseName );
448 }
449
450 resp.setMessageId( messageId );
451
452 return ( E ) resp;
453 }
454
455
456
457
458
459 public ExtendedRequest newExtendedRequest( String oid, byte[] value )
460 {
461 ExtendedRequest req = null;
462
463 ExtendedOperationFactory extendedRequestFactory = extendedOperationsFactories.get( oid );
464
465 if ( extendedRequestFactory != null )
466 {
467 req = extendedRequestFactory.newRequest( value );
468 }
469 else
470 {
471 ExtendedRequestDecorator<ExtendedRequest> decorator =
472 new ExtendedRequestDecorator<ExtendedRequest>( this,
473 new ExtendedRequestImpl() );
474 decorator.setRequestName( oid );
475 decorator.setRequestValue( value );
476 req = decorator;
477 }
478
479 return req;
480 }
481
482
483
484
485
486 public ExtendedRequestDecorator<?> decorate( ExtendedRequest decoratedMessage )
487 {
488 ExtendedRequestDecorator<?> req = null;
489
490 ExtendedOperationFactory extendedRequestFactory = extendedOperationsFactories.get( decoratedMessage
491 .getRequestName() );
492
493 if ( extendedRequestFactory != null )
494 {
495 req = ( ExtendedRequestDecorator<?> ) extendedRequestFactory.decorate( decoratedMessage );
496 }
497 else
498 {
499 req = new ExtendedRequestDecorator<ExtendedRequest>( this, decoratedMessage );
500 }
501
502 return req;
503 }
504
505
506
507
508
509 public ExtendedResponseDecorator<?> decorate( ExtendedResponse decoratedMessage )
510 {
511 ExtendedResponseDecorator<?> resp = null;
512
513 ExtendedOperationFactory extendedRequestFactory = extendedOperationsFactories.get( decoratedMessage
514 .getResponseName() );
515
516 if ( extendedRequestFactory != null )
517 {
518 resp = ( ExtendedResponseDecorator<?> ) extendedRequestFactory.decorate( decoratedMessage );
519 }
520 else
521 {
522 resp = new ExtendedResponseDecorator<ExtendedResponse>( this, decoratedMessage );
523 }
524
525 return resp;
526 }
527
528
529
530
531
532 public boolean isExtendedOperationRegistered( String oid )
533 {
534 return extendedOperationsFactories.containsKey( oid );
535 }
536 }