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