001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.shared.ldap.codec.standalone; 021 022 023import java.lang.reflect.Constructor; 024import java.nio.ByteBuffer; 025import java.util.Collections; 026import java.util.HashMap; 027import java.util.Iterator; 028import java.util.Map; 029 030import javax.naming.NamingException; 031import javax.naming.ldap.BasicControl; 032 033import org.apache.directory.shared.asn1.DecoderException; 034import org.apache.directory.shared.asn1.EncoderException; 035import org.apache.directory.shared.asn1.ber.Asn1Container; 036import org.apache.directory.shared.ldap.codec.BasicControlDecorator; 037import org.apache.directory.shared.ldap.codec.api.CodecControl; 038import org.apache.directory.shared.ldap.codec.api.ControlFactory; 039import org.apache.directory.shared.ldap.codec.api.ExtendedRequestDecorator; 040import org.apache.directory.shared.ldap.codec.api.ExtendedRequestFactory; 041import org.apache.directory.shared.ldap.codec.api.ExtendedResponseDecorator; 042import org.apache.directory.shared.ldap.codec.api.LdapApiService; 043import org.apache.directory.shared.ldap.codec.api.LdapMessageContainer; 044import org.apache.directory.shared.ldap.codec.api.MessageDecorator; 045import org.apache.directory.shared.ldap.codec.api.UnsolicitedResponseFactory; 046import org.apache.directory.shared.ldap.model.message.Control; 047import org.apache.directory.shared.ldap.model.message.ExtendedRequest; 048import org.apache.directory.shared.ldap.model.message.ExtendedRequestImpl; 049import org.apache.directory.shared.ldap.model.message.ExtendedResponse; 050import org.apache.directory.shared.ldap.model.message.ExtendedResponseImpl; 051import org.apache.directory.shared.ldap.model.message.Message; 052import org.apache.directory.shared.ldap.model.message.controls.OpaqueControl; 053import org.apache.directory.shared.util.Strings; 054import org.apache.directory.shared.util.exception.NotImplementedException; 055import org.apache.mina.filter.codec.ProtocolCodecFactory; 056import org.slf4j.Logger; 057import org.slf4j.LoggerFactory; 058 059 060/** 061 * The default {@link org.apache.directory.shared.ldap.codec.api.LdapApiService} implementation. 062 * 063 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 064 * @version $Rev$, $Date$ 065 */ 066public class StandaloneLdapApiService implements LdapApiService 067{ 068 /** A logger */ 069 private static final Logger LOG = LoggerFactory.getLogger( StandaloneLdapApiService.class ); 070 071 /** The map of registered {@link org.apache.directory.shared.ldap.codec.api.ControlFactory}'s */ 072 private Map<String,ControlFactory<?,?>> controlFactories = new HashMap<String, ControlFactory<?,?>>(); 073 074 /** The map of registered {@link org.apache.directory.shared.ldap.codec.api.ExtendedRequestFactory}'s by request OID */ 075 private Map<String,ExtendedRequestFactory<?,?>> extReqFactories = new HashMap<String, ExtendedRequestFactory<?,?>>(); 076 077 /** The map of registered {@link UnsolicitedResponseFactory}'s by request OID */ 078 private Map<String,UnsolicitedResponseFactory<?>> unsolicitedFactories = new HashMap<String, UnsolicitedResponseFactory<?>>(); 079 080 /** The LDAP {@link ProtocolCodecFactory} implementation used */ 081 private ProtocolCodecFactory protocolCodecFactory; 082 083 /** The list of default controls to load at startup */ 084 public static String DEFAULT_CONTROLS_LIST = "default.controls"; 085 086 /** The list of extra controls to load at startup */ 087 public static String EXTRA_CONTROLS_LIST = "extra.controls"; 088 089 /** The list of default extended operation requests to load at startup */ 090 public static String DEFAULT_EXTENDED_OPERATION_REQUESTS_LIST = "default.extendedOperation.requests"; 091 092 /** The list of default extended operation responses to load at startup */ 093 public static String DEFAULT_EXTENDED_OPERATION_RESPONSES_LIST = "default.extendedOperation.responses"; 094 095 /** The list of extra controls to load at startup */ 096 public static String EXTRA_EXTENDED_OPERATION_LIST = "extra.extendedOperations"; 097 098 /** 099 * Creates a new instance of StandaloneLdapCodecService. Optionally checks for 100 * system property {@link #PLUGIN_DIRECTORY_PROPERTY}. Intended for use by 101 * unit test running tools like Maven's surefire: 102 * <pre> 103 * <properties> 104 * <codec.plugin.directory>${project.build.directory}/pluginDirectory</codec.plugin.directory> 105 * </properties> 106 * 107 * <build> 108 * <plugins> 109 * <plugin> 110 * <artifactId>maven-surefire-plugin</artifactId> 111 * <groupId>org.apache.maven.plugins</groupId> 112 * <configuration> 113 * <systemPropertyVariables> 114 * <workingDirectory>${basedir}/target</workingDirectory> 115 * <felix.cache.rootdir> 116 * ${project.build.directory} 117 * </felix.cache.rootdir> 118 * <felix.cache.locking> 119 * true 120 * </felix.cache.locking> 121 * <org.osgi.framework.storage.clean> 122 * onFirstInit 123 * </org.osgi.framework.storage.clean> 124 * <org.osgi.framework.storage> 125 * osgi-cache 126 * </org.osgi.framework.storage> 127 * <codec.plugin.directory> 128 * ${codec.plugin.directory} 129 * </codec.plugin.directory> 130 * </systemPropertyVariables> 131 * </configuration> 132 * </plugin> 133 * 134 * <plugin> 135 * <groupId>org.apache.maven.plugins</groupId> 136 * <artifactId>maven-dependency-plugin</artifactId> 137 * <executions> 138 * <execution> 139 * <id>copy</id> 140 * <phase>compile</phase> 141 * <goals> 142 * <goal>copy</goal> 143 * </goals> 144 * <configuration> 145 * <artifactItems> 146 * <artifactItem> 147 * <groupId>${project.groupId}</groupId> 148 * <artifactId>shared-ldap-extras-codec</artifactId> 149 * <version>${project.version}</version> 150 * <outputDirectory>${codec.plugin.directory}</outputDirectory> 151 * </artifactItem> 152 * </artifactItems> 153 * </configuration> 154 * </execution> 155 * </executions> 156 * </plugin> 157 * </plugins> 158 * </build> 159 * </pre> 160 */ 161 public StandaloneLdapApiService() throws Exception 162 { 163 // Load the controls 164 loadControls(); 165 166 // Load the extended operations 167 loadExtendedOperations(); 168 169 // Load the schema elements 170 //loadSchemaElements(); 171 172 // Load the network layer 173 //loadNetworkLayer() 174 175 if ( protocolCodecFactory == null ) 176 { 177 try 178 { 179 @SuppressWarnings("unchecked") 180 Class<? extends ProtocolCodecFactory> clazz = ( Class<? extends ProtocolCodecFactory> ) 181 Class.forName( DEFAULT_PROTOCOL_CODEC_FACTORY ); 182 protocolCodecFactory = clazz.newInstance(); 183 } 184 catch( Exception cause ) 185 { 186 throw new RuntimeException( "Failed to load default codec factory.", cause ); 187 } 188 } 189 } 190 191 192 /** 193 * Load the controls 194 * 195 * @throws Exception 196 */ 197 private void loadControls() throws Exception 198 { 199 // first load the default controls 200 loadDefaultControls(); 201 202 // The load the extra controls 203 loadExtraControls(); 204 } 205 206 207 /** 208 * Loads the Controls implemented out of the box in the codec. 209 */ 210 private void loadDefaultControls() throws Exception 211 { 212 // Load defaults from command line properties if it exists 213 String defaultControlsList = System.getProperty( DEFAULT_CONTROLS_LIST ); 214 215 if ( Strings.isEmpty( defaultControlsList ) ) 216 { 217 return; 218 } 219 220 for ( String control : defaultControlsList.split( "," ) ) 221 { 222 Class<?>[] types = new Class<?>[] { LdapApiService.class }; 223 Class<? extends ControlFactory<?, ?>> clazz = ( Class<? extends ControlFactory<?, ?>> )Class.forName( control ); 224 Constructor<?> constructor = clazz.getConstructor(types); 225 226 ControlFactory<?, ?> factory = (ControlFactory<?, ?>)constructor.newInstance( new Object[]{ this } ); 227 controlFactories.put( factory.getOid(), factory ); 228 LOG.info( "Registered pre-bundled control factory: {}", factory.getOid() ); 229 } 230 } 231 232 233 /** 234 * Loads the extra Controls 235 */ 236 private void loadExtraControls() throws Exception 237 { 238 // Load extra from command line properties if it exists 239 String extraControlsList = System.getProperty( EXTRA_CONTROLS_LIST ); 240 241 if ( Strings.isEmpty( extraControlsList ) ) 242 { 243 return; 244 } 245 246 for ( String control : extraControlsList.split( "," ) ) 247 { 248 Class<?>[] types = new Class<?>[] { LdapApiService.class }; 249 Class<? extends ControlFactory<?, ?>> clazz = ( Class<? extends ControlFactory<?, ?>> )Class.forName( control ); 250 Constructor<?> constructor = clazz.getConstructor(types); 251 252 ControlFactory<?, ?> factory = (ControlFactory<?, ?>)constructor.newInstance( new Object[]{ this } ); 253 controlFactories.put( factory.getOid(), factory ); 254 LOG.info( "Registered pre-bundled control factory: {}", factory.getOid() ); 255 } 256 } 257 258 259 /** 260 * Load the extended operations 261 * 262 * @throws Exception 263 */ 264 private void loadExtendedOperations() throws Exception 265 { 266 loadDefaultExtendedOperationRequests(); 267 loadDefaultExtendedOperationResponses(); 268 loadExtraExtendedOperations(); 269 } 270 271 272 /** 273 * Loads the default extended operation requests 274 */ 275 private void loadDefaultExtendedOperationRequests() throws Exception 276 { 277 // Load from command line properties if it exists 278 String defaultExtendedOperationsList = System.getProperty( DEFAULT_EXTENDED_OPERATION_REQUESTS_LIST ); 279 280 if ( Strings.isEmpty( defaultExtendedOperationsList ) ) 281 { 282 return; 283 } 284 285 for ( String extendedOperation : defaultExtendedOperationsList.split( "," ) ) 286 { 287 Class<?>[] types = new Class<?>[] { LdapApiService.class }; 288 Class<? extends ExtendedRequestFactory<?,?>> clazz = ( Class<? extends ExtendedRequestFactory<?,?>> )Class.forName( extendedOperation ); 289 Constructor<?> constructor = clazz.getConstructor(types); 290 291 ExtendedRequestFactory<?,?> factory = (ExtendedRequestFactory<?,?>)constructor.newInstance( new Object[]{ this } ); 292 extReqFactories.put( factory.getOid(), factory ); 293 LOG.info( "Registered pre-bundled extended operation factory: {}", factory.getOid() ); 294 } 295 } 296 297 298 /** 299 * Loads the default extended operation responses 300 */ 301 private void loadDefaultExtendedOperationResponses() throws Exception 302 { 303 // Load from command line properties if it exists 304 String defaultExtendedOperationsList = System.getProperty( DEFAULT_EXTENDED_OPERATION_RESPONSES_LIST ); 305 306 if ( Strings.isEmpty( defaultExtendedOperationsList ) ) 307 { 308 return; 309 } 310 311 for ( String extendedOperation : defaultExtendedOperationsList.split( "," ) ) 312 { 313 Class<?>[] types = new Class<?>[] { LdapApiService.class }; 314 Class<? extends UnsolicitedResponseFactory<?>> clazz = ( Class<? extends UnsolicitedResponseFactory<?>> )Class.forName( extendedOperation ); 315 Constructor<?> constructor = clazz.getConstructor(types); 316 317 UnsolicitedResponseFactory<?> factory = (UnsolicitedResponseFactory<?>)constructor.newInstance( new Object[]{ this } ); 318 unsolicitedFactories.put( factory.getOid(), factory ); 319 LOG.info( "Registered pre-bundled extended operation factory: {}", factory.getOid() ); 320 } 321 } 322 323 324 /** 325 * Loads the extra extended operations 326 */ 327 private void loadExtraExtendedOperations() 328 { 329 330 } 331 332 333 //------------------------------------------------------------------------- 334 // LdapCodecService implementation methods 335 //------------------------------------------------------------------------- 336 /** 337 * {@inheritDoc} 338 */ 339 public ControlFactory<?,?> registerControl( ControlFactory<?,?> factory ) 340 { 341 return controlFactories.put( factory.getOid(), factory ); 342 } 343 344 345 /** 346 * {@inheritDoc} 347 */ 348 public ControlFactory<?,?> unregisterControl( String oid ) 349 { 350 return controlFactories.remove( oid ); 351 } 352 353 354 /** 355 * {@inheritDoc} 356 */ 357 public Iterator<String> registeredControls() 358 { 359 return Collections.unmodifiableSet( controlFactories.keySet() ).iterator(); 360 } 361 362 363 /** 364 * {@inheritDoc} 365 */ 366 public boolean isControlRegistered( String oid ) 367 { 368 return controlFactories.containsKey( oid ); 369 } 370 371 372 /** 373 * {@inheritDoc} 374 */ 375 public Iterator<String> registeredExtendedRequests() 376 { 377 return Collections.unmodifiableSet( extReqFactories.keySet() ).iterator(); 378 } 379 380 381 /** 382 * {@inheritDoc} 383 */ 384 public ExtendedRequestFactory<?, ?> registerExtendedRequest( ExtendedRequestFactory<?,?> factory ) 385 { 386 return extReqFactories.put( factory.getOid(), factory ); 387 } 388 389 390 /** 391 * {@inheritDoc} 392 */ 393 public ProtocolCodecFactory getProtocolCodecFactory() 394 { 395 return protocolCodecFactory; 396 } 397 398 399 /** 400 * {@inheritDoc} 401 */ 402 public ProtocolCodecFactory registerProtocolCodecFactory( ProtocolCodecFactory protocolCodecFactory ) 403 { 404 ProtocolCodecFactory old = this.protocolCodecFactory; 405 this.protocolCodecFactory = protocolCodecFactory; 406 return old; 407 } 408 409 410 /** 411 * {@inheritDoc} 412 */ 413 public CodecControl<? extends Control> newControl( String oid ) 414 { 415 ControlFactory<?,?> factory = controlFactories.get( oid ); 416 417 if ( factory == null ) 418 { 419 return new BasicControlDecorator<Control>( this, new OpaqueControl( oid ) ); 420 } 421 422 return factory.newCodecControl(); 423 } 424 425 426 /** 427 * {@inheritDoc} 428 */ 429 @SuppressWarnings("unchecked") 430 public CodecControl<? extends Control> newControl( Control control ) 431 { 432 if ( control == null ) 433 { 434 throw new NullPointerException( "Control argument was null." ); 435 } 436 437 // protect agains being multiply decorated 438 if ( control instanceof CodecControl ) 439 { 440 return (org.apache.directory.shared.ldap.codec.api.CodecControl<?> )control; 441 } 442 443 @SuppressWarnings("rawtypes") 444 ControlFactory factory = controlFactories.get( control.getOid() ); 445 446 if ( factory == null ) 447 { 448 return new BasicControlDecorator<Control>( this, control ); 449 } 450 451 return factory.newCodecControl( control ); 452 } 453 454 455 /** 456 * {@inheritDoc} 457 */ 458 public javax.naming.ldap.Control toJndiControl( Control control ) throws EncoderException 459 { 460 CodecControl<? extends Control> decorator = newControl( control ); 461 ByteBuffer bb = ByteBuffer.allocate( decorator.computeLength() ); 462 decorator.encode( bb ); 463 bb.flip(); 464 BasicControl jndiControl = 465 new BasicControl( control.getOid(), control.isCritical(), bb.array() ); 466 return jndiControl; 467 } 468 469 470 /** 471 * {@inheritDoc} 472 */ 473 public Control fromJndiControl( javax.naming.ldap.Control control ) throws DecoderException 474 { 475 @SuppressWarnings("rawtypes") 476 ControlFactory factory = controlFactories.get( control.getID() ); 477 478 if ( factory == null ) 479 { 480 OpaqueControl ourControl = new OpaqueControl( control.getID() ); 481 ourControl.setCritical( control.isCritical() ); 482 BasicControlDecorator<Control> decorator = 483 new BasicControlDecorator<Control>( this, ourControl ); 484 decorator.setValue( control.getEncodedValue() ); 485 return decorator; 486 } 487 488 @SuppressWarnings("unchecked") 489 CodecControl<? extends Control> ourControl = factory.newCodecControl(); 490 ourControl.setCritical( control.isCritical() ); 491 ourControl.setValue( control.getEncodedValue() ); 492 ourControl.decode( control.getEncodedValue() ); 493 494 return ourControl; 495 } 496 497 498 /** 499 * {@inheritDoc} 500 */ 501 public Asn1Container newMessageContainer() 502 { 503 return new LdapMessageContainer<MessageDecorator<? extends Message>>( this ); 504 } 505 506 507 /** 508 * {@inheritDoc} 509 */ 510 public Iterator<String> registeredUnsolicitedResponses() 511 { 512 return Collections.unmodifiableSet( unsolicitedFactories.keySet() ).iterator(); 513 } 514 515 516 /** 517 * {@inheritDoc} 518 */ 519 public UnsolicitedResponseFactory<?> registerUnsolicitedResponse( UnsolicitedResponseFactory<?> factory ) 520 { 521 return unsolicitedFactories.put( factory.getOid(), factory ); 522 } 523 524 525 /** 526 * {@inheritDoc} 527 */ 528 public javax.naming.ldap.ExtendedResponse toJndi( final ExtendedResponse modelResponse ) throws EncoderException 529 { 530 throw new NotImplementedException( "Figure out how to transform" ); 531 } 532 533 534 /** 535 * {@inheritDoc} 536 */ 537 public ExtendedResponse fromJndi( javax.naming.ldap.ExtendedResponse jndiResponse ) throws DecoderException 538 { 539 throw new NotImplementedException( "Figure out how to transform" ); 540 } 541 542 543 /** 544 * {@inheritDoc} 545 */ 546 public ExtendedRequestFactory<?, ?> unregisterExtendedRequest( String oid ) 547 { 548 return extReqFactories.remove( oid ); 549 } 550 551 552 /** 553 * {@inheritDoc} 554 */ 555 public UnsolicitedResponseFactory<?> unregisterUnsolicitedResponse( String oid ) 556 { 557 return unsolicitedFactories.remove( oid ); 558 } 559 560 561 /** 562 * {@inheritDoc} 563 */ 564 public ExtendedRequest<?> fromJndi( javax.naming.ldap.ExtendedRequest jndiRequest ) throws DecoderException 565 { 566 ExtendedRequestDecorator<?,?> decorator = 567 ( ExtendedRequestDecorator<?, ?> ) newExtendedRequest( jndiRequest.getID(), jndiRequest.getEncodedValue() ); 568 return decorator; 569 } 570 571 572 /** 573 * {@inheritDoc} 574 */ 575 public javax.naming.ldap.ExtendedRequest toJndi( final ExtendedRequest<?> modelRequest ) throws EncoderException 576 { 577 final String oid = modelRequest.getRequestName(); 578 final byte[] value; 579 580 if ( modelRequest instanceof ExtendedRequestDecorator ) 581 { 582 ExtendedRequestDecorator<?, ?> decorator = ( ExtendedRequestDecorator<?, ?> ) modelRequest; 583 value = decorator.getRequestValue(); 584 } 585 else 586 { 587 // have to ask the factory to decorate for us - can't do it ourselves 588 ExtendedRequestFactory<?,?> extendedRequestFactory = extReqFactories.get( modelRequest.getRequestName() ); 589 ExtendedRequestDecorator<?, ?> decorator = extendedRequestFactory.decorate( modelRequest ); 590 value = decorator.getRequestValue(); 591 } 592 593 594 javax.naming.ldap.ExtendedRequest jndiRequest = new javax.naming.ldap.ExtendedRequest() 595 { 596 private static final long serialVersionUID = -4160980385909987475L; 597 598 public String getID() 599 { 600 return oid; 601 } 602 603 public byte[] getEncodedValue() 604 { 605 return value; 606 } 607 608 public javax.naming.ldap.ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset, 609 int length ) throws NamingException 610 { 611 ExtendedRequestFactory<?,?> factory = extReqFactories.get( modelRequest.getRequestName() ); 612 613 try 614 { 615 final ExtendedResponseDecorator<?> resp = ( ExtendedResponseDecorator<?> ) factory.newResponse( berValue ); 616 javax.naming.ldap.ExtendedResponse jndiResponse = new javax.naming.ldap.ExtendedResponse() 617 { 618 private static final long serialVersionUID = -7686354122066100703L; 619 620 public String getID() 621 { 622 return oid; 623 } 624 625 public byte[] getEncodedValue() 626 { 627 return resp.getResponseValue(); 628 } 629 }; 630 631 return jndiResponse; 632 } 633 catch ( DecoderException e ) 634 { 635 NamingException ne = new NamingException( "Unable to decode encoded response value: " + 636 Strings.dumpBytes( berValue ) ); 637 ne.setRootCause( e ); 638 throw ne; 639 } 640 } 641 }; 642 643 return jndiRequest; 644 } 645 646 647 /** 648 * {@inheritDoc} 649 * @throws DecoderException 650 */ 651 @SuppressWarnings("unchecked") 652 public <E extends ExtendedResponse> E newExtendedResponse( ExtendedRequest<E> req, byte[] serializedResponse ) throws DecoderException 653 { 654 ExtendedResponseDecorator<ExtendedResponse> resp; 655 656 ExtendedRequestFactory<?,?> extendedRequestFactory = extReqFactories.get( req.getRequestName() ); 657 658 if ( extendedRequestFactory != null ) 659 { 660 resp = ( ExtendedResponseDecorator<ExtendedResponse> ) extendedRequestFactory.newResponse( serializedResponse ); 661 } 662 else 663 { 664 resp = new ExtendedResponseDecorator<ExtendedResponse>( this, 665 new ExtendedResponseImpl( req.getRequestName() ) ); 666 resp.setResponseValue( serializedResponse ); 667 resp.setResponseName( req.getRequestName() ); 668 } 669 670 resp.setMessageId( req.getMessageId() ); 671 672 return ( E ) resp; 673 } 674 675 676 /** 677 * {@inheritDoc} 678 */ 679 public ExtendedRequest<?> newExtendedRequest( String oid, byte[] value ) 680 { 681 ExtendedRequest<?> req = null; 682 683 ExtendedRequestFactory<?,?> extendedRequestFactory = extReqFactories.get( oid ); 684 685 if ( extendedRequestFactory != null ) 686 { 687 if ( value == null ) 688 { 689 req = extendedRequestFactory.newRequest(); 690 } 691 else 692 { 693 req = extendedRequestFactory.newRequest( value ); 694 } 695 } 696 else 697 { 698 ExtendedRequestDecorator<ExtendedRequest<ExtendedResponse>, ExtendedResponse> decorator = 699 new ExtendedRequestDecorator<ExtendedRequest<ExtendedResponse>, ExtendedResponse>( this, 700 new ExtendedRequestImpl() ); 701 decorator.setRequestName( oid ); 702 decorator.setRequestValue( value ); 703 req = decorator; 704 } 705 706 return req; 707 } 708 709 710 /** 711 * {@inheritDoc} 712 */ 713 @SuppressWarnings("unchecked") 714 public ExtendedRequestDecorator<?, ?> decorate( ExtendedRequest<?> decoratedMessage ) 715 { 716 ExtendedRequestDecorator<?,?> req = null; 717 718 ExtendedRequestFactory<?,?> extendedRequestFactory = extReqFactories.get( decoratedMessage.getRequestName() ); 719 720 if ( extendedRequestFactory != null ) 721 { 722 req = extendedRequestFactory.decorate( decoratedMessage ); 723 } 724 else 725 { 726 req = new ExtendedRequestDecorator<ExtendedRequest<ExtendedResponse>, ExtendedResponse>( this, 727 ( ExtendedRequest<ExtendedResponse> ) decoratedMessage ); 728 } 729 730 return req; 731 } 732 733 734 /** 735 * {@inheritDoc} 736 */ 737 public ExtendedResponseDecorator<?> decorate( ExtendedResponse decoratedMessage ) 738 { 739 ExtendedResponseDecorator<?> resp = null; 740 741 UnsolicitedResponseFactory<?> unsolicitedResponseFactory = unsolicitedFactories.get( decoratedMessage.getResponseName() ); 742 ExtendedRequestFactory<?,?> extendedRequestFactory = extReqFactories.get( decoratedMessage.getResponseName() ); 743 744 if ( extendedRequestFactory != null ) 745 { 746 resp = extendedRequestFactory.decorate( decoratedMessage ); 747 } 748 else if ( unsolicitedResponseFactory != null ) 749 { 750 resp = unsolicitedResponseFactory.decorate( decoratedMessage ); 751 } 752 else 753 { 754 resp = new ExtendedResponseDecorator<ExtendedResponse>( this, decoratedMessage ); 755 } 756 757 return resp; 758 } 759 760 761 /** 762 * {@inheritDoc} 763 */ 764 public boolean isExtendedOperationRegistered( String oid ) 765 { 766 return extReqFactories.containsKey( oid ) || unsolicitedFactories.containsKey( oid ); 767 } 768}