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