View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     https://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  package org.apache.directory.api.ldap.codec.osgi;
21  
22  
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.Map;
27  
28  import javax.naming.NamingException;
29  import javax.naming.ldap.BasicControl;
30  
31  import org.apache.directory.api.asn1.DecoderException;
32  import org.apache.directory.api.asn1.EncoderException;
33  import org.apache.directory.api.asn1.util.Asn1Buffer;
34  import org.apache.directory.api.i18n.I18n;
35  import org.apache.directory.api.ldap.codec.BasicControlDecorator;
36  import org.apache.directory.api.ldap.codec.api.ControlFactory;
37  import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory;
38  import org.apache.directory.api.ldap.codec.api.IntermediateOperationFactory;
39  import org.apache.directory.api.ldap.codec.api.LdapApiService;
40  import org.apache.directory.api.ldap.codec.controls.cascade.CascadeFactory;
41  import org.apache.directory.api.ldap.codec.controls.manageDsaIT.ManageDsaITFactory;
42  import org.apache.directory.api.ldap.codec.controls.proxiedauthz.ProxiedAuthzFactory;
43  import org.apache.directory.api.ldap.codec.controls.search.entryChange.EntryChangeFactory;
44  import org.apache.directory.api.ldap.codec.controls.search.pagedSearch.PagedResultsFactory;
45  import org.apache.directory.api.ldap.codec.controls.search.persistentSearch.PersistentSearchFactory;
46  import org.apache.directory.api.ldap.codec.controls.search.subentries.SubentriesFactory;
47  import org.apache.directory.api.ldap.codec.controls.sort.SortRequestFactory;
48  import org.apache.directory.api.ldap.codec.controls.sort.SortResponseFactory;
49  import org.apache.directory.api.ldap.model.message.Control;
50  import org.apache.directory.api.ldap.model.message.ExtendedRequest;
51  import org.apache.directory.api.ldap.model.message.ExtendedResponse;
52  import org.apache.directory.api.ldap.model.message.OpaqueExtendedRequest;
53  import org.apache.directory.api.ldap.model.message.controls.Cascade;
54  import org.apache.directory.api.ldap.model.message.controls.EntryChange;
55  import org.apache.directory.api.ldap.model.message.controls.ManageDsaIT;
56  import org.apache.directory.api.ldap.model.message.controls.OpaqueControl;
57  import org.apache.directory.api.ldap.model.message.controls.PagedResults;
58  import org.apache.directory.api.ldap.model.message.controls.PersistentSearch;
59  import org.apache.directory.api.ldap.model.message.controls.ProxiedAuthz;
60  import org.apache.directory.api.ldap.model.message.controls.SortRequest;
61  import org.apache.directory.api.ldap.model.message.controls.SortResponse;
62  import org.apache.directory.api.ldap.model.message.controls.Subentries;
63  import org.apache.directory.api.ldap.model.name.DnFactory;
64  import org.apache.directory.api.util.Strings;
65  import org.apache.directory.api.util.exception.NotImplementedException;
66  import org.apache.mina.filter.codec.ProtocolCodecFactory;
67  import org.slf4j.Logger;
68  import org.slf4j.LoggerFactory;
69  
70  
71  /**
72   * The default {@link LdapApiService} implementation.
73   *
74   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
75   * @version $Rev$, $Date$
76   */
77  public class DefaultLdapCodecService implements LdapApiService
78  {
79      /** A logger */
80      private static final Logger LOG = LoggerFactory.getLogger( DefaultLdapCodecService.class );
81  
82      /** The map of registered request {@link ControlFactory}'s */
83      private Map<String, ControlFactory<? extends Control>> requestControlFactories = new HashMap<>();
84  
85      /** The map of registered response {@link ControlFactory}'s */
86      private Map<String, ControlFactory<? extends Control>> responseControlFactories = new HashMap<>();
87  
88      /** The map of registered {@link ExtendedOperationFactory}'s by request OID */
89      private Map<String, ExtendedOperationFactory> extendedRequestFactories = new HashMap<>();
90  
91      /** The map of registered {@link ExtendedOperationFactory}'s by request OID */
92      private Map<String, ExtendedOperationFactory> extendedResponseFactories = new HashMap<>();
93  
94      /** The map of registered {@link IntermediateOperationFactory}'s by request OID */
95      private Map<String, IntermediateOperationFactory> intermediateResponseFactories = new HashMap<>();
96  
97      /** The registered ProtocolCodecFactory */
98      private ProtocolCodecFactory protocolCodecFactory;
99      
100     /** The DN Factory */
101     private DnFactory dnFactory;
102 
103 
104     /**
105      * Creates a new instance of DefaultLdapCodecService.
106      */
107     public DefaultLdapCodecService()
108     {
109         loadStockControls();
110     }
111 
112 
113     /**
114      * Loads the Controls implement out of the box in the codec.
115      */
116     private void loadStockControls()
117     {
118         ControlFactory<Cascade> cascadeFactory = new CascadeFactory( this );
119         requestControlFactories.put( cascadeFactory.getOid(), cascadeFactory );
120 
121         if ( LOG.isInfoEnabled() )
122         {
123             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, cascadeFactory.getOid() ) );
124         }
125 
126         ControlFactory<EntryChange> entryChangeFactory = new EntryChangeFactory( this );
127         responseControlFactories.put( entryChangeFactory.getOid(), entryChangeFactory );
128 
129         if ( LOG.isInfoEnabled() )
130         {
131             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, entryChangeFactory.getOid() ) );
132         }
133 
134         ControlFactory<ManageDsaIT> manageDsaItFactory = new ManageDsaITFactory( this );
135         requestControlFactories.put( manageDsaItFactory.getOid(), manageDsaItFactory );
136 
137         if ( LOG.isInfoEnabled() )
138         {
139             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, manageDsaItFactory.getOid() ) );
140         }
141 
142         ControlFactory<PagedResults> pageResultsFactory = new PagedResultsFactory( this );
143         requestControlFactories.put( pageResultsFactory.getOid(), pageResultsFactory );
144         responseControlFactories.put( pageResultsFactory.getOid(), pageResultsFactory );
145 
146         if ( LOG.isInfoEnabled() )
147         {
148             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, pageResultsFactory.getOid() ) );
149         }
150 
151         ControlFactory<PersistentSearch> persistentSearchFactory = new PersistentSearchFactory( this );
152         requestControlFactories.put( persistentSearchFactory.getOid(), persistentSearchFactory );
153 
154         if ( LOG.isInfoEnabled() )
155         {
156             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, persistentSearchFactory.getOid() ) );
157         }
158 
159         ControlFactory<ProxiedAuthz> proxiedAuthzFactory = new ProxiedAuthzFactory( this );
160         requestControlFactories.put( proxiedAuthzFactory.getOid(), proxiedAuthzFactory );
161 
162         if ( LOG.isInfoEnabled() )
163         {
164             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, proxiedAuthzFactory.getOid() ) );
165         }
166 
167         ControlFactory<SortRequest> sortRequestFactory = new SortRequestFactory( this );
168         requestControlFactories.put( sortRequestFactory.getOid(), sortRequestFactory );
169 
170         if ( LOG.isInfoEnabled() )
171         {
172             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, sortRequestFactory.getOid() ) );
173         }
174 
175         ControlFactory<SortResponse> sortResponseFactory = new SortResponseFactory( this );
176         responseControlFactories.put( sortResponseFactory.getOid(), sortResponseFactory );
177 
178         if ( LOG.isInfoEnabled() )
179         {
180             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, sortResponseFactory.getOid() ) );
181         }
182 
183         ControlFactory<Subentries> subentriesFactory = new SubentriesFactory( this );
184         requestControlFactories.put( subentriesFactory.getOid(), subentriesFactory );
185 
186         if ( LOG.isInfoEnabled() )
187         {
188             LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, subentriesFactory.getOid() ) );
189         }
190     }
191 
192 
193     //-------------------------------------------------------------------------
194     // LdapCodecService implementation methods
195     //-------------------------------------------------------------------------
196 
197     /**
198      * {@inheritDoc}
199      */
200     @Override
201     public ControlFactory<?> registerRequestControl( ControlFactory<?> factory )
202     {
203         return requestControlFactories.put( factory.getOid(), factory );
204     }
205 
206     /**
207      * {@inheritDoc}
208      */
209     @Override
210     public ControlFactory<?> registerResponseControl( ControlFactory<?> factory )
211     {
212         return responseControlFactories.put( factory.getOid(), factory );
213     }
214 
215 
216     /**
217      * {@inheritDoc}
218      */
219     @Override
220     public ControlFactory<?> unregisterRequestControl( String oid )
221     {
222         return requestControlFactories.remove( oid );
223     }
224 
225 
226     /**
227      * {@inheritDoc}
228      */
229     @Override
230     public ControlFactory<?> unregisterResponseControl( String oid )
231     {
232         return responseControlFactories.remove( oid );
233     }
234 
235 
236     /**
237      * {@inheritDoc}
238      */
239     @Override
240     public Iterator<String> registeredRequestControls()
241     {
242         return Collections.unmodifiableSet( requestControlFactories.keySet() ).iterator();
243     }
244 
245 
246     /**
247      * {@inheritDoc}
248      */
249     @Override
250     public Iterator<String> registeredResponseControls()
251     {
252         return Collections.unmodifiableSet( responseControlFactories.keySet() ).iterator();
253     }
254 
255 
256     /**
257      * {@inheritDoc}
258      */
259     @Override
260     public boolean isControlRegistered( String oid )
261     {
262         return requestControlFactories.containsKey( oid ) || responseControlFactories.containsKey( oid );
263     }
264 
265 
266     /**
267      * {@inheritDoc}
268      */
269     @Override
270     public Iterator<String> registeredExtendedRequests()
271     {
272         return Collections.unmodifiableSet( extendedRequestFactories.keySet() ).iterator();
273     }
274 
275 
276     /**
277      * {@inheritDoc}
278      */
279     @Override
280     public Iterator<String> registeredExtendedResponses()
281     {
282         return Collections.unmodifiableSet( extendedResponseFactories.keySet() ).iterator();
283     }
284 
285 
286     /**
287      * {@inheritDoc}
288      */
289     @Override
290     public ExtendedOperationFactory registerExtendedRequest( ExtendedOperationFactory factory )
291     {
292         return extendedRequestFactories.put( factory.getOid(), factory );
293     }
294 
295 
296     /**
297      * {@inheritDoc}
298      */
299     @Override
300     public ExtendedOperationFactory registerExtendedResponse( ExtendedOperationFactory factory )
301     {
302         return extendedResponseFactories.put( factory.getOid(), factory );
303     }
304 
305 
306     /**
307      * {@inheritDoc}
308      */
309     @Override
310     public Iterator<String> registeredIntermediateResponses()
311     {
312         return Collections.unmodifiableSet( intermediateResponseFactories.keySet() ).iterator();
313     }
314 
315 
316     /**
317      * {@inheritDoc}
318      */
319     @Override
320     public IntermediateOperationFactory registerIntermediateResponse( IntermediateOperationFactory factory )
321     {
322         return intermediateResponseFactories.put( factory.getOid(), factory );
323     }
324 
325 
326     /**
327      * {@inheritDoc}
328      */
329     @Override
330     public ProtocolCodecFactory getProtocolCodecFactory()
331     {
332         return protocolCodecFactory;
333     }
334 
335 
336     /**
337      * {@inheritDoc}
338      */
339     @Override
340     public ProtocolCodecFactory registerProtocolCodecFactory( ProtocolCodecFactory protocolCodecFactory )
341     {
342         ProtocolCodecFactory oldFactory = this.protocolCodecFactory;
343         this.protocolCodecFactory = protocolCodecFactory;
344         return oldFactory;
345     }
346 
347 
348     /**
349      * {@inheritDoc}
350      */
351     @Override
352     public javax.naming.ldap.Control toJndiControl( Control control ) throws EncoderException
353     {
354         // We don't know if it's a request or a response control. Test with request contriols
355         ControlFactory<?> factory = requestControlFactories.get( control.getOid() );
356         
357         if ( factory == null )
358         {
359             if ( control instanceof OpaqueControl )
360             {
361                 return new BasicControl( control.getOid(), control.isCritical(), ( ( OpaqueControl ) control ).getEncodedValue() );
362             }
363             else
364             {
365                 return new BasicControl( control.getOid(), control.isCritical(), null );
366             }
367         }
368         else
369         {
370             Asn1Buffer asn1Buffer = new Asn1Buffer();
371             factory.encodeValue( asn1Buffer, control );
372     
373             return new BasicControl( control.getOid(), control.isCritical(), asn1Buffer.getBytes().array() );
374         }
375     }
376 
377 
378     /**
379      * {@inheritDoc}
380      */
381     @Override
382     public Control fromJndiRequestControl( javax.naming.ldap.Control control ) throws DecoderException
383     {
384         @SuppressWarnings("rawtypes")
385         ControlFactory factory = requestControlFactories.get( control.getID() );
386 
387         if ( factory == null )
388         {
389             OpaqueControl ourControl = new OpaqueControl( control.getID() );
390             ourControl.setCritical( control.isCritical() );
391             BasicControlDecorator decorator =
392                 new BasicControlDecorator( this, ourControl );
393             decorator.setValue( control.getEncodedValue() );
394             return decorator;
395         }
396 
397         Control ourControl = factory.newControl();
398         ourControl.setCritical( control.isCritical() );
399         factory.decodeValue( ourControl, control.getEncodedValue() );
400 
401         return ourControl;
402     }
403 
404 
405     /**
406      * {@inheritDoc}
407      */
408     @Override
409     public Control fromJndiResponseControl( javax.naming.ldap.Control control ) throws DecoderException
410     {
411         @SuppressWarnings("rawtypes")
412         ControlFactory factory = responseControlFactories.get( control.getID() );
413 
414         if ( factory == null )
415         {
416             OpaqueControl ourControl = new OpaqueControl( control.getID() );
417             ourControl.setCritical( control.isCritical() );
418             BasicControlDecorator decorator =
419                 new BasicControlDecorator( this, ourControl );
420             decorator.setValue( control.getEncodedValue() );
421             return decorator;
422         }
423 
424         Control ourControl = factory.newControl();
425         ourControl.setCritical( control.isCritical() );
426         factory.decodeValue( ourControl, control.getEncodedValue() );
427 
428         return ourControl;
429     }
430 
431 
432     /**
433      * {@inheritDoc}
434      */
435     @Override
436     public ExtendedOperationFactory unregisterExtendedRequest( String oid )
437     {
438         return extendedRequestFactories.remove( oid );
439     }
440 
441 
442     /**
443      * {@inheritDoc}
444      */
445     @Override
446     public ExtendedOperationFactory unregisterExtendedResponse( String oid )
447     {
448         return extendedResponseFactories.remove( oid );
449     }
450 
451 
452     /**
453      * {@inheritDoc}
454      */
455     @Override
456     public IntermediateOperationFactory unregisterIntermediateResponse( String oid )
457     {
458         return intermediateResponseFactories.remove( oid );
459     }
460 
461 
462     /**
463      * {@inheritDoc}
464      */
465     @Override
466     public javax.naming.ldap.ExtendedResponse toJndi( final ExtendedResponse modelResponse ) throws EncoderException
467     {
468         throw new NotImplementedException( I18n.err( I18n.ERR_05401_FIGURE_OUT_HOW_TO_TRANSFORM ) );
469     }
470 
471 
472     /**
473      * {@inheritDoc}
474      */
475     @Override
476     public ExtendedResponse fromJndi( javax.naming.ldap.ExtendedResponse jndiResponse ) throws DecoderException
477     {
478         throw new NotImplementedException( I18n.err( I18n.ERR_05401_FIGURE_OUT_HOW_TO_TRANSFORM ) );
479     }
480 
481 
482     /**
483      * {@inheritDoc}
484      */
485     @Override
486     public ExtendedRequest fromJndi( javax.naming.ldap.ExtendedRequest jndiRequest ) throws DecoderException
487     {
488         ExtendedOperationFactory extendedRequestFactory = extendedRequestFactories.get( jndiRequest
489             .getID() );
490 
491         if ( extendedRequestFactory != null )
492         {
493             return extendedRequestFactory.newRequest( jndiRequest.getEncodedValue() );
494         }
495         else
496         {
497             return new OpaqueExtendedRequest( jndiRequest.getID(), jndiRequest.getEncodedValue() );
498         }
499     }
500 
501 
502     /**
503      * {@inheritDoc}
504      */
505     @Override
506     public javax.naming.ldap.ExtendedRequest toJndi( final ExtendedRequest modelRequest ) throws EncoderException
507     {
508         final String oid = modelRequest.getRequestName();
509 
510         // have to ask the factory to decorate for us - can't do it ourselves
511         ExtendedOperationFactory extendedRequestFactory = extendedRequestFactories.get( modelRequest
512             .getRequestName() );
513         Asn1Buffer asn1Buffer = new Asn1Buffer();
514         extendedRequestFactory.encodeValue( asn1Buffer, modelRequest );
515         
516         final byte[] value = asn1Buffer.getBytes().array();
517 
518         return new javax.naming.ldap.ExtendedRequest()
519         {
520             private static final long serialVersionUID = -4160980385909987475L;
521 
522 
523             @Override
524             public String getID()
525             {
526                 return oid;
527             }
528 
529 
530             @Override
531             public byte[] getEncodedValue()
532             {
533                 return value;
534             }
535 
536 
537             @Override
538             public javax.naming.ldap.ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset,
539                 int length ) throws NamingException
540             {
541                 final ExtendedOperationFactory factory = extendedResponseFactories
542                     .get( modelRequest.getRequestName() );
543 
544                 try
545                 {
546                     final ExtendedResponse resp = factory.newResponse( berValue );
547                     
548                     return new javax.naming.ldap.ExtendedResponse()
549                     {
550                         private static final long serialVersionUID = -7686354122066100703L;
551 
552 
553                         @Override
554                         public String getID()
555                         {
556                             return oid;
557                         }
558 
559 
560                         @Override
561                         public byte[] getEncodedValue()
562                         {
563                             Asn1Buffer asn1Buffer = new Asn1Buffer();
564                             
565                             factory.encodeValue( asn1Buffer, resp );
566                             
567                             return asn1Buffer.getBytes().array();
568                         }
569                     };
570                 }
571                 catch ( DecoderException de )
572                 {
573                     NamingException ne = new NamingException( I18n.err( I18n.ERR_05402_UNABLE_TO_ENCODE_RESPONSE_VALUE,
574                         Strings.dumpBytes( berValue ) ) );
575                     ne.setRootCause( de );
576                     throw ne;
577                 }
578             }
579         };
580     }
581 
582 
583     /**
584      * {@inheritDoc}
585      */
586     @Override
587     public boolean isExtendedRequestRegistered( String oid )
588     {
589         return extendedRequestFactories.containsKey( oid );
590     }
591 
592 
593     /**
594      * {@inheritDoc}
595      */
596     @Override
597     public boolean isExtendedResponseRegistered( String oid )
598     {
599         return extendedResponseFactories.containsKey( oid );
600     }
601 
602 
603     /**
604      * {@inheritDoc}
605      */
606     @Override
607     public boolean isIntermediateResponseRegistered( String oid )
608     {
609         return intermediateResponseFactories.containsKey( oid );
610     }
611 
612 
613     /**
614      * {@inheritDoc}
615      */
616     @Override
617     public Map<String, ControlFactory<? extends Control>> getRequestControlFactories()
618     {
619         return requestControlFactories;
620     }
621 
622 
623     /**
624      * {@inheritDoc}
625      */
626     @Override
627     public Map<String, ControlFactory<? extends Control>> getResponseControlFactories()
628     {
629         return responseControlFactories;
630     }
631 
632 
633     /**
634      * @param requestControlFactories the request controlFactories to set
635      */
636     public void setRequestControlFactories( Map<String, ControlFactory<? extends Control>> requestControlFactories )
637     {
638         this.requestControlFactories = requestControlFactories;
639     }
640 
641 
642     /**
643      * @param responseControlFactories the response controlFactories to set
644      */
645     public void setResponseControlFactories( Map<String, ControlFactory<? extends Control>> responseControlFactories )
646     {
647         this.responseControlFactories = responseControlFactories;
648     }
649 
650 
651     /**
652      * @return the extendedRequestFactories
653      */
654     public Map<String, ExtendedOperationFactory> getExtendedRequestFactories()
655     {
656         return extendedRequestFactories;
657     }
658 
659 
660     /**
661      * @return the extendedResponseFactories
662      */
663     @Override
664     public Map<String, ExtendedOperationFactory> getExtendedResponseFactories()
665     {
666         return extendedResponseFactories;
667     }
668 
669 
670     /**
671      * @return the intermediateResponseFactories
672      */
673     public Map<String, IntermediateOperationFactory> getIntermediateResponseFactories()
674     {
675         return intermediateResponseFactories;
676     }
677 
678 
679     /**
680      * @param extendedOperationFactories the extendedOperationFactories to set
681      */
682     public void setExtendedRequestFactories( Map<String, ExtendedOperationFactory> extendedOperationFactories )
683     {
684         this.extendedRequestFactories = extendedOperationFactories;
685     }
686 
687 
688     /**
689      * @param extendedOperationFactories the extendedOperationFactories to set
690      */
691     public void setExtendedResponseFactories( Map<String, ExtendedOperationFactory> extendedOperationFactories )
692     {
693         this.extendedResponseFactories = extendedOperationFactories;
694     }
695 
696 
697     /**
698      * @param intermediateResponseFactories the intermediateResponseFactories to set
699      */
700     public void setIntermediateResponseFactories( Map<String, IntermediateOperationFactory> intermediateResponseFactories )
701     {
702         this.intermediateResponseFactories = intermediateResponseFactories;
703     }
704 
705 
706     /**
707      * @param protocolCodecFactory the protocolCodecFactory to set
708      */
709     public void setProtocolCodecFactory( ProtocolCodecFactory protocolCodecFactory )
710     {
711         this.protocolCodecFactory = protocolCodecFactory;
712     }
713     
714     
715     public String toString()
716     {
717         StringBuilder sb = new StringBuilder();
718         
719         sb.append( "Request controls       :\n" );
720         
721         for ( Map.Entry<String, ControlFactory<?>> element : requestControlFactories .entrySet() )
722         {
723             sb.append( "    " );
724             sb.append( element.getValue().getClass().getSimpleName() );
725             sb.append( "[" ).append( element.getKey() ).append( "]\n" );
726         }
727         
728         sb.append( "Response controls      :\n" );
729         
730         for ( Map.Entry<String, ControlFactory<?>> element : responseControlFactories .entrySet() )
731         {
732             sb.append( "    " );
733             sb.append( element.getValue().getClass().getSimpleName() );
734             sb.append( "[" ).append( element.getKey() ).append( "]\n" );
735         }
736         
737         sb.append( "Extended requests      :\n" );
738         
739         for ( Map.Entry<String, ExtendedOperationFactory> element : extendedRequestFactories .entrySet() )
740         {
741             sb.append( "    " );
742             sb.append( element.getValue().getClass().getSimpleName() );
743             sb.append( "[" ).append( element.getKey() ).append( "]\n" );
744         }
745         
746         sb.append( "Extended responses     :\n" );
747         
748         for ( Map.Entry<String, ExtendedOperationFactory> element : extendedResponseFactories.entrySet() )
749         {
750             sb.append( "    " );
751             sb.append( element.getValue().getClass().getSimpleName() );
752             sb.append( "[" ).append( element.getKey() ).append( "]\n" );
753         }
754         
755         sb.append( "Intermediate responses :\n" );
756         
757         for ( Map.Entry<String, IntermediateOperationFactory> element : intermediateResponseFactories .entrySet() )
758         {
759             sb.append( "    " );
760             sb.append( element.getValue().getClass().getSimpleName() );
761             sb.append( "[" ).append( element.getKey() ).append( "]\n" );
762         }
763 
764         return sb.toString();
765     }
766 
767 
768     /**
769      * {@inheritDoc}
770      */
771     @Override
772     public void setDnfactory( DnFactory dnfactory )
773     {
774         this.dnFactory = dnfactory;
775     }
776 
777     /**
778      * {@inheritDoc}
779      */
780     @Override
781     public DnFactory getDnFactory()
782     {
783         return dnFactory;
784     }
785 }