001 package org.apache.fulcrum.yaafi.framework.container; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.io.File; 023 import java.io.InputStream; 024 import java.util.ArrayList; 025 import java.util.HashMap; 026 import java.util.List; 027 import java.util.Properties; 028 029 import org.apache.avalon.framework.configuration.Configuration; 030 import org.apache.avalon.framework.configuration.ConfigurationException; 031 import org.apache.avalon.framework.configuration.DefaultConfiguration; 032 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 033 import org.apache.avalon.framework.container.ContainerUtil; 034 import org.apache.avalon.framework.context.Context; 035 import org.apache.avalon.framework.context.ContextException; 036 import org.apache.avalon.framework.context.DefaultContext; 037 import org.apache.avalon.framework.logger.Logger; 038 import org.apache.avalon.framework.parameters.ParameterException; 039 import org.apache.avalon.framework.parameters.Parameters; 040 import org.apache.avalon.framework.service.ServiceException; 041 import org.apache.avalon.framework.service.ServiceManager; 042 import org.apache.fulcrum.yaafi.framework.component.AvalonServiceComponentImpl; 043 import org.apache.fulcrum.yaafi.framework.component.ServiceComponent; 044 import org.apache.fulcrum.yaafi.framework.configuration.ComponentConfigurationPropertiesResolver; 045 import org.apache.fulcrum.yaafi.framework.configuration.ComponentConfigurationPropertiesResolverImpl; 046 import org.apache.fulcrum.yaafi.framework.constant.AvalonYaafiConstants; 047 import org.apache.fulcrum.yaafi.framework.context.AvalonToYaafiContextMapper; 048 import org.apache.fulcrum.yaafi.framework.context.YaafiToAvalonContextMapper; 049 import org.apache.fulcrum.yaafi.framework.role.RoleConfigurationParser; 050 import org.apache.fulcrum.yaafi.framework.role.RoleConfigurationParserImpl; 051 import org.apache.fulcrum.yaafi.framework.role.RoleEntry; 052 import org.apache.fulcrum.yaafi.framework.util.ConfigurationUtil; 053 import org.apache.fulcrum.yaafi.framework.util.InputStreamLocator; 054 import org.apache.fulcrum.yaafi.framework.util.StringUtils; 055 import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder; 056 import org.apache.fulcrum.yaafi.framework.util.Validate; 057 import org.apache.fulcrum.yaafi.framework.crypto.CryptoStreamFactory; 058 059 /** 060 * Yet another avalon framework implementation (YAAFI). 061 * 062 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a> 063 */ 064 065 public class ServiceContainerImpl 066 implements ServiceContainer, ServiceConstants 067 { 068 /** the timeout before reconfiguring the container or services */ 069 private static final int RECONFIGURATION_DELAY = 2000; 070 071 /** The role configuration file to be used */ 072 private String componentRolesLocation; 073 074 /** is the component role file encrypted? */ 075 private String isComponentRolesEncrypted; 076 077 /** which flavour of component role file we have to parse? */ 078 private String componentRolesFlavour; 079 080 /** The service configuration file to be used */ 081 private String componentConfigurationLocation; 082 083 /** is the component configuration file encrypted? */ 084 private String isComponentConfigurationEncrypted; 085 086 /** The parameters file to be used */ 087 private String parametersLocation; 088 089 /** is the parameters file encrypted? */ 090 private String isParametersEncrypted; 091 092 /** The application directory aka the current woring directory */ 093 private File applicationRootDir; 094 095 /** The directory for storing temporary files */ 096 private File tempRootDir; 097 098 /** The logger to be used passed by the caller */ 099 private Logger logger; 100 101 /** The service manager passed to the container */ 102 private ServiceManager parentServiceManager; 103 104 /** The list of services instantiated */ 105 private List serviceList; 106 107 /** The map of services used for the lookup */ 108 private HashMap serviceMap; 109 110 /** The Avalon role configuration loaded by this class */ 111 private Configuration roleConfiguration; 112 113 /** The Avalon service configuration loaded by this class */ 114 private Configuration serviceConfiguration; 115 116 /** The temporary Avalon context passed to the implementation */ 117 private Context callerContext; 118 119 /** The default Avalon context passed to the services */ 120 private Context context; 121 122 /** The default Avalon parameters */ 123 private Parameters parameters; 124 125 /** Is this instance already disposed? */ 126 private boolean isDisposed; 127 128 /** The type of container where YAAFI is embedded */ 129 private String containerFlavour; 130 131 /** The ms to wait before triggering a reconfiguration of the container os service */ 132 private int reconfigurationDelay; 133 134 /** global flag for enabling/disabling dynamic proxies */ 135 private boolean hasDynamicProxies; 136 137 /** The list of interceptor services applied to all services */ 138 private ArrayList defaultInterceptorServiceList; 139 140 /** The list of ServiceManagers as fallback service lookup */ 141 private ArrayList fallbackServiceManagerList; 142 143 /** the configuration for running the ComponentConfigurationPropertiesResolver */ 144 private Configuration componentConfigurationPropertiesResolverConfig; 145 146 ///////////////////////////////////////////////////////////////////////// 147 // Avalon Service Lifecycle 148 ///////////////////////////////////////////////////////////////////////// 149 150 /** 151 * Constructor using sensible defaults. 152 */ 153 public ServiceContainerImpl() 154 { 155 super(); 156 157 this.reconfigurationDelay = RECONFIGURATION_DELAY; 158 this.containerFlavour = COMPONENT_CONTAINERFLAVOUR_VALUE; 159 this.componentRolesFlavour = COMPONENT_ROLECONFIGFLAVOUR_VALUE; 160 161 this.componentRolesLocation = COMPONENT_ROLE_VALUE; 162 this.componentConfigurationLocation = COMPONENT_CONFIG_VALUE; 163 this.parametersLocation = COMPONENT_PARAMETERS_VALUE; 164 165 this.isComponentConfigurationEncrypted = "false"; 166 this.isComponentRolesEncrypted = "false"; 167 this.isParametersEncrypted = "false"; 168 169 this.isDisposed = false; 170 this.serviceList = new ArrayList(); 171 this.serviceMap = new HashMap(); 172 173 this.applicationRootDir = new File( new File("").getAbsolutePath() ); 174 this.tempRootDir = new File( System.getProperty("java.io.tmpdir",".") ); 175 176 this.fallbackServiceManagerList = new ArrayList(); 177 this.defaultInterceptorServiceList = new ArrayList(); 178 179 this.reconfigurationDelay = RECONFIGURATION_DELAY; 180 } 181 182 /** 183 * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger) 184 */ 185 public void enableLogging(Logger logger) 186 { 187 Validate.notNull( logger, "logger" ); 188 this.logger = logger; 189 } 190 191 /** 192 * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context) 193 */ 194 public void contextualize(Context context) throws ContextException 195 { 196 Validate.notNull( context, "context" ); 197 // Argghhh - I need to to parse the Configuration before I can map the Context 198 this.callerContext = context; 199 } 200 201 202 /** 203 * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager) 204 */ 205 public void service(ServiceManager serviceManager) throws ServiceException 206 { 207 this.parentServiceManager = serviceManager; 208 } 209 210 /** 211 * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration) 212 */ 213 public void configure(Configuration configuration) throws ConfigurationException 214 { 215 Validate.notNull( configuration, "configuration" ); 216 217 // retrieve the reconfigurationDelay 218 219 this.reconfigurationDelay = 220 configuration.getChild(RECONFIGURATION_DELAY_KEY).getValueAsInteger( 221 RECONFIGURATION_DELAY 222 ); 223 224 // evaluate if we are using dynamic proxies 225 226 this.hasDynamicProxies = 227 configuration.getChild(DYNAMICPROXY_ENABLED_KEY).getValueAsBoolean(false); 228 229 // retrieve the container flavour 230 231 this.setContainerFlavour( 232 configuration.getChild(CONTAINERFLAVOUR_CONFIG_KEY).getValue( 233 COMPONENT_CONTAINERFLAVOUR_VALUE ) 234 ); 235 236 this.getLogger().debug( "Using the following container type : " + this.getContainerFlavour() ); 237 238 // process the caller-suppied context here 239 240 try 241 { 242 // instantiate a mapper using the existing context - it might 243 // contain application specific entries we are not aware of 244 245 AvalonToYaafiContextMapper mapper = new AvalonToYaafiContextMapper( 246 this.getTempRootDir(), 247 this.callerContext, 248 this.getClassLoader() 249 ); 250 251 // do the magic mapping 252 253 this.context = mapper.mapFrom( 254 this.callerContext, 255 this.getContainerFlavour() 256 ); 257 258 // don't keep a reference of the caller-supplide context 259 260 this.callerContext = null; 261 } 262 catch( ContextException e ) 263 { 264 String msg = "Failed to parse the caller-supplied context"; 265 this.getLogger().error( msg, e ); 266 throw new ConfigurationException( msg ); 267 } 268 269 // evaluate componentRoles 270 271 Configuration currComponentRoles = configuration.getChild(COMPONENT_ROLE_KEYS); 272 273 this.setComponentRolesLocation( 274 currComponentRoles.getChild(COMPONENT_LOCATION_KEY).getValue( 275 COMPONENT_ROLE_VALUE ) 276 ); 277 278 this.setComponentRolesFlavour( 279 currComponentRoles.getChild(CONTAINERFLAVOUR_CONFIG_KEY).getValue( 280 COMPONENT_ROLECONFIGFLAVOUR_VALUE ) 281 ); 282 283 this.setComponentRolesEncrypted( 284 currComponentRoles.getChild(COMPONENT_ISENCRYPTED_KEY).getValue( 285 "false" ) 286 ); 287 288 // evaluate componentConfiguraion 289 290 Configuration currComponentConfiguration = configuration.getChild(COMPONENT_CONFIG_KEY); 291 292 this.setComponentConfigurationLocation( 293 currComponentConfiguration.getChild(COMPONENT_LOCATION_KEY).getValue( 294 COMPONENT_CONFIG_VALUE ) 295 ); 296 297 this.setComponentConfigurationEncrypted( 298 currComponentConfiguration.getChild(COMPONENT_ISENCRYPTED_KEY).getValue( 299 "false" ) 300 ); 301 302 // get the configuration for componentConfigurationPropertiesResolver 303 304 this.componentConfigurationPropertiesResolverConfig = configuration.getChild( 305 COMPONENT_CONFIG_PROPERTIES_KEY 306 ); 307 308 // evaluate parameters 309 310 Configuration currParameters = configuration.getChild(COMPONENT_PARAMETERS_KEY); 311 312 this.setParametersLocation( 313 currParameters.getChild(COMPONENT_LOCATION_KEY).getValue( 314 COMPONENT_PARAMETERS_VALUE ) 315 ); 316 317 this.setParametersEncrypted( 318 currParameters.getChild(COMPONENT_ISENCRYPTED_KEY).getValue( 319 "false" ) 320 ); 321 322 // evaluate the default interceptors 323 324 Configuration currInterceptorList = configuration.getChild( 325 INTERCEPTOR_LIST_KEY 326 ); 327 328 Configuration[] interceptorConfigList = currInterceptorList.getChildren( 329 INTERCEPTOR_KEY 330 ); 331 332 for( int i=0; i<interceptorConfigList.length; i++ ) 333 { 334 String interceptorServiceName = interceptorConfigList[i].getValue(null); 335 336 if( !StringUtils.isEmpty(interceptorServiceName) && this.hasDynamicProxies()) 337 { 338 this.defaultInterceptorServiceList.add( interceptorServiceName ); 339 340 this.getLogger().debug("Using the following default interceptor service : " 341 + interceptorServiceName 342 ); 343 } 344 } 345 346 // evaluate a list of service managers managing their own set of services 347 // independent from the Avalon container. This service managers are used 348 // to find services implemented as Spring bean or remote webservices. 349 350 Configuration currServiceManagerList = configuration.getChild( 351 SERVICEMANAGER_LIST_KEY 352 ); 353 354 Configuration[] serviceManagerConfigList = currServiceManagerList.getChildren( 355 SERVICEMANAGER_KEY 356 ); 357 358 for( int i=0; i<serviceManagerConfigList.length; i++ ) 359 { 360 String serviceManagerName = serviceManagerConfigList[i].getValue(null); 361 362 if( !StringUtils.isEmpty(serviceManagerName) ) 363 { 364 this.fallbackServiceManagerList.add( serviceManagerName ); 365 366 this.getLogger().debug("Using the following fallback service manager : " 367 + serviceManagerName 368 ); 369 } 370 } 371 } 372 373 /** 374 * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters) 375 */ 376 public void parameterize(Parameters parameters) throws ParameterException 377 { 378 this.parameters = parameters; 379 } 380 381 /** 382 * @see org.apache.avalon.framework.activity.Initializable#initialize() 383 */ 384 public void initialize() throws Exception 385 { 386 this.getLogger().debug( "YAAFI Service Framework is starting up"); 387 388 // set the directories being used 389 390 this.setApplicationRootDir( 391 (File) this.getContext().get(AvalonYaafiConstants.URN_AVALON_HOME ) 392 ); 393 394 this.setTempRootDir( 395 (File) this.getContext().get(AvalonYaafiConstants.URN_AVALON_TEMP ) 396 ); 397 398 // get the configuration files 399 400 this.roleConfiguration = loadConfiguration( 401 this.componentRolesLocation, 402 this.isComponentRolesEncrypted() 403 ); 404 405 if( this.roleConfiguration == null ) 406 { 407 String msg = "Unable to locate the role configuration : " + this.componentRolesLocation; 408 this.getLogger().error( msg ); 409 throw new ConfigurationException( msg ); 410 } 411 412 this.serviceConfiguration = loadConfiguration( 413 this.componentConfigurationLocation, 414 this.isComponentConfigurationEncrypted() 415 ); 416 417 // create the configuration properties 418 419 Properties componentConfigurationProperties = this.loadComponentConfigurationProperties(); 420 421 // expand the componentConfiguration using the componentConfigurationProperties 422 423 ConfigurationUtil.expand( 424 this.getLogger(), 425 (DefaultConfiguration) this.serviceConfiguration, 426 componentConfigurationProperties 427 ); 428 429 // create the default parameters 430 431 if( this.getParameters() == null ) 432 { 433 this.parameters= this.loadParameters( 434 this.parametersLocation, 435 this.isParametersEncrypted() 436 ); 437 } 438 439 // create the service implementaion instances 440 441 List currServiceList = this.createServiceComponents( 442 this.roleConfiguration, 443 this.getLogger() 444 ); 445 446 this.setServiceList( currServiceList ); 447 448 // fill the service map mapping from a service name to an instance 449 450 for( int i=0; i<this.getServiceList().size(); i++ ) 451 { 452 ServiceComponent serviceComponent = (ServiceComponent) this.getServiceList().get(i); 453 this.getServiceMap().put( serviceComponent.getName(), serviceComponent ); 454 } 455 456 // ensure that fallback service managers are available 457 458 for(int i=0; i<this.fallbackServiceManagerList.size(); i++) 459 { 460 String currServiceManagerName = (String) this.fallbackServiceManagerList.get(i); 461 if(this.getServiceMap().get(currServiceManagerName) == null) 462 { 463 String msg = "The following fallback service manager was not found : " + currServiceManagerName; 464 throw new IllegalArgumentException(msg); 465 } 466 } 467 468 // run the various lifecycle stages 469 470 this.incarnateAll( this.getServiceList() ); 471 472 // we are up and running 473 474 this.isDisposed = false; 475 this.getLogger().debug( "YAAFI Avalon Service Container is up and running"); 476 } 477 478 479 /** 480 * Disposes the service container implementation. 481 * 482 * @see org.apache.avalon.framework.activity.Disposable#dispose() 483 */ 484 public synchronized void dispose() 485 { 486 if( this.isDisposed ) 487 { 488 return; 489 } 490 491 if( this.getLogger() != null ) 492 { 493 this.getLogger().debug("Disposing all services"); 494 } 495 496 // decommision all servcies 497 498 this.decommisionAll( this.getServiceList() ); 499 500 // dispose all servcies 501 502 this.disposeAll( this.getServiceList() ); 503 504 // clean up 505 506 this.getServiceList().clear(); 507 this.getServiceMap().clear(); 508 509 this.componentRolesLocation = null; 510 this.componentConfigurationLocation = null; 511 this.context = null; 512 this.parametersLocation = null; 513 this.roleConfiguration = null; 514 this.serviceConfiguration = null; 515 this.parameters = null; 516 this.fallbackServiceManagerList = null; 517 this.defaultInterceptorServiceList = null; 518 this.isDisposed = true; 519 520 if( this.getLogger() != null ) 521 { 522 this.getLogger().debug( "All services are disposed" ); 523 } 524 } 525 526 /** 527 * Reconfiguring the services. I'm not sure how to implement this properly since 528 * the Avalon docs is vague on this subject. For now we suspend, reconfigure and 529 * resume the services in the correct order. 530 * 531 * @see org.apache.avalon.framework.configuration.Reconfigurable#reconfigure(org.apache.avalon.framework.configuration.Configuration) 532 */ 533 public synchronized void reconfigure(Configuration configuration) 534 throws ConfigurationException 535 { 536 Validate.notNull( configuration, "configuration" ); 537 538 int exceptionCounter = 0; 539 ServiceComponent serviceComponent = null; 540 541 this.getLogger().warn("Reconfiguring all services ..."); 542 543 // 1) wait for some time 544 545 this.waitForReconfiguration(); 546 547 // 2) store the new configuration 548 549 this.serviceConfiguration = configuration; 550 551 Properties componentConfigurationProperties = this.loadComponentConfigurationProperties(); 552 553 ConfigurationUtil.expand( 554 this.getLogger(), 555 (DefaultConfiguration) this.serviceConfiguration, 556 componentConfigurationProperties 557 ); 558 559 // 3) reconfigure the services 560 561 for( int i=0; i<this.getServiceList().size(); i++ ) 562 { 563 serviceComponent = (ServiceComponent) this.getServiceList().get(i); 564 565 Configuration serviceComponentConfiguraton = this.getServiceConfiguration().getChild( 566 serviceComponent.getShorthand() 567 ); 568 569 try 570 { 571 serviceComponent.setConfiguration(serviceComponentConfiguraton); 572 serviceComponent.reconfigure(); 573 } 574 catch(Throwable t) 575 { 576 String msg = "Reconfiguring of " + serviceComponent.getShorthand() + " failed"; 577 this.getLogger().error(msg); 578 exceptionCounter++; 579 } 580 } 581 582 // 4) check the result 583 584 if( exceptionCounter > 0 ) 585 { 586 String msg = "The reconfiguration failed with " + exceptionCounter + " exception(s)"; 587 this.getLogger().error(msg); 588 throw new ConfigurationException(msg); 589 } 590 } 591 592 ///////////////////////////////////////////////////////////////////////// 593 // Server Interface Implementation 594 ///////////////////////////////////////////////////////////////////////// 595 596 /** 597 * @see org.apache.fulcrum.yaafi.framework.container.ServiceLifecycleManager#getRoleEntry(java.lang.String) 598 */ 599 public synchronized RoleEntry getRoleEntry(String name) 600 throws ServiceException 601 { 602 return this.getServiceComponentEx(name).getRoleEntry(); 603 } 604 605 /** 606 * @see org.apache.fulcrum.yaafi.framework.container.ServiceLifecycleManager#getRoleEntries() 607 */ 608 public synchronized RoleEntry[] getRoleEntries() 609 { 610 List serviceList = this.getServiceList(); 611 ServiceComponent serviceComponent = null; 612 RoleEntry[] result = new RoleEntry[serviceList.size()]; 613 614 for( int i=0; i<result.length; i++ ) 615 { 616 serviceComponent = (ServiceComponent) serviceList.get(i); 617 result[i] = serviceComponent.getRoleEntry(); 618 } 619 620 return result; 621 } 622 623 /** 624 * @see org.apache.fulcrum.yaafi.framework.container.ServiceLifecycleManager#reconfigure(java.lang.String[]) 625 */ 626 public synchronized void reconfigure(String[] names) throws ServiceException, 627 ConfigurationException 628 { 629 Validate.notNull(names,"names"); 630 Validate.noNullElements(names,"names"); 631 632 this.waitForReconfiguration(); 633 634 for( int i=0; i<names.length; i++ ) 635 { 636 // ensure that the service exists since during our reconfiguration 637 // we might use a stle recofniguration entry 638 639 if( this.getServiceMap().get(names[i]) != null ) 640 { 641 this.reconfigure(names[i]); 642 } 643 } 644 } 645 646 /** 647 * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String) 648 */ 649 public boolean hasService(String name) 650 { 651 Validate.notEmpty( name, "name" ); 652 653 boolean result = false; 654 655 synchronized(this) 656 { 657 // look at our available service 658 659 result = (this.getLocalServiceComponent(name) != null); 660 661 // look at fallback service managers 662 663 if(!result) 664 { 665 result = this.hasFallbackService(name); 666 } 667 } 668 669 // if we haven't found anything ask the parent ServiceManager 670 671 if( (!result) && ( this.hasParentServiceManager() ) ) 672 { 673 result = this.getParentServiceManager().hasService(name); 674 } 675 676 return result; 677 } 678 679 /** 680 * Lookup a service instance. The implementation uses the following 681 * mechanism 682 * <ul> 683 * <li>look for a matching local service 684 * <li>use the fallback service manager as they might know the service 685 * <li>ask the parent service manager 686 * </ul> 687 * 688 * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String) 689 */ 690 public Object lookup(String name) throws ServiceException 691 { 692 Validate.notEmpty( name, "name" ); 693 694 Object result = null; 695 ServiceComponent serviceManagerComponent = null; 696 697 try 698 { 699 synchronized (this) 700 { 701 // 1) check our local services 702 703 serviceManagerComponent = this.getLocalServiceComponent(name); 704 705 if( serviceManagerComponent != null ) 706 { 707 result = serviceManagerComponent.getInstance(); 708 709 if((result != null) && this.getLogger().isDebugEnabled()) 710 { 711 String msg = "Located the service '" + name + "' in the local container"; 712 this.getLogger().debug(msg); 713 } 714 } 715 716 // 2) look at fallback service managers 717 718 if(result == null) 719 { 720 result = this.getFallbackService(name); 721 } 722 } 723 } 724 catch(ServiceException e) 725 { 726 String msg = "Failed to lookup a service " + name; 727 this.getLogger().error( msg, e ); 728 throw e; 729 } 730 catch( Throwable t ) 731 { 732 String msg = "Failed to lookup a service " + name; 733 this.getLogger().error( msg, t ); 734 throw new ServiceException( name, msg, t ); 735 } 736 737 // 3) if we haven't found anything ask the parent ServiceManager 738 739 if( (result == null) && this.hasParentServiceManager() ) 740 { 741 result = this.getParentServiceManager().lookup(name); 742 743 if((result != null) && this.getLogger().isDebugEnabled()) 744 { 745 String msg = "Located the service '" + name + "' using the parent service manager"; 746 this.getLogger().debug(msg); 747 } 748 } 749 750 // if we still haven't found anything then complain 751 752 if( result == null ) 753 { 754 String msg = "The following component does not exist : " + name; 755 this.getLogger().error(msg); 756 throw new ServiceException( AvalonYaafiConstants.AVALON_CONTAINER_YAAFI, name ); 757 } 758 759 return result; 760 } 761 762 /** 763 * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object) 764 */ 765 public void release(Object object) 766 { 767 // AFAIK this is only useful for lifecycle management regarding 768 // lifestyle other than singleton. 769 } 770 771 /** 772 * @see org.apache.fulcrum.yaafi.framework.container.ServiceContainer#decommision(java.lang.String) 773 */ 774 public synchronized void decommision(String name) throws ServiceException 775 { 776 this.waitForReconfiguration(); 777 ServiceComponent serviceComponent = this.getServiceComponentEx(name); 778 this.decommision(serviceComponent); 779 } 780 781 /** 782 * @see org.apache.fulcrum.yaafi.framework.container.ServiceContainer#getParameters() 783 */ 784 public Parameters getParameters() 785 { 786 return this.parameters; 787 } 788 789 ///////////////////////////////////////////////////////////////////////// 790 // Service Implementation 791 ///////////////////////////////////////////////////////////////////////// 792 793 /** 794 * @see java.lang.Object#toString() 795 */ 796 public String toString() 797 { 798 ToStringBuilder toStringBuilder = new ToStringBuilder(this); 799 800 toStringBuilder.append("applicationRootDir", this.getApplicationRootDir()); 801 toStringBuilder.append("tempRootDir", this.getTempRootDir()); 802 toStringBuilder.append("componentRolesLocation", this.componentRolesLocation); 803 toStringBuilder.append("componentConfigurationLocation", this.componentConfigurationLocation); 804 toStringBuilder.append("parametersLocation", parametersLocation); 805 toStringBuilder.append("logger", this.getLogger().getClass().getName()); 806 toStringBuilder.append("hasDynamicProxies", this.hasDynamicProxies); 807 toStringBuilder.append("containerFlavour", this.containerFlavour); 808 toStringBuilder.append("componentRolesFlavour", this.componentRolesFlavour); 809 toStringBuilder.append("isComponentRolesEncrypted", this.isComponentRolesEncrypted); 810 toStringBuilder.append("isComponentConfigurationEncrypted", this.isComponentConfigurationEncrypted); 811 toStringBuilder.append("isParametersEncrypted", this.isParametersEncrypted); 812 813 return toStringBuilder.toString(); 814 } 815 816 /** 817 * Create a role configuration parser based on the container flavour. 818 * @return the role configuration parser 819 */ 820 private RoleConfigurationParser createRoleConfigurationParser() 821 { 822 return new RoleConfigurationParserImpl( 823 this.getComponentRolesFlavour() 824 ); 825 } 826 827 /** 828 * Reconfigure a single service 829 * 830 * @param name the name of the service to be reconfigured 831 * @throws ServiceException the service was not found 832 * @throws ConfigurationException the reconfiguration failed 833 */ 834 private void reconfigure(String name) 835 throws ServiceException, ConfigurationException 836 { 837 Validate.notEmpty( name, "name" ); 838 ServiceComponent serviceComponent = this.getServiceComponentEx(name); 839 840 // reconfigure the component 841 842 try 843 { 844 serviceComponent.reconfigure(); 845 } 846 catch(ConfigurationException e) 847 { 848 String msg = "Reconfiguring failed : " + serviceComponent.getShorthand(); 849 this.getLogger().error(msg,e); 850 throw new ConfigurationException(msg,e); 851 } 852 catch(Throwable t) 853 { 854 String msg = "Reconfiguring failed : " + serviceComponent.getShorthand(); 855 this.getLogger().error(msg,t); 856 throw new ConfigurationException(msg,t); 857 } 858 } 859 860 /** 861 * Enforce that a service is known to simplify error handling. 862 * 863 * @param name the name of the service component 864 * @return the service component 865 * @throws ServiceException the service was not found 866 */ 867 private ServiceComponent getServiceComponentEx(String name) 868 throws ServiceException 869 { 870 Validate.notEmpty( name, "name" ); 871 ServiceComponent result = (ServiceComponent) this. getServiceMap().get(name); 872 873 if( result == null ) 874 { 875 String msg = "The following component does not exist : " + name; 876 this.getLogger().error(msg); 877 throw new ServiceException( AvalonYaafiConstants.AVALON_CONTAINER_YAAFI, name ); 878 } 879 880 return result; 881 } 882 883 /** 884 * Try to get a local service component. 885 * 886 * @param name the name of the service component 887 * @return the service component if any 888 */ 889 private ServiceComponent getLocalServiceComponent(String name) 890 { 891 Validate.notEmpty( name, "name" ); 892 ServiceComponent result = (ServiceComponent) this. getServiceMap().get(name); 893 return result; 894 } 895 896 /** 897 * Try to get a service component provided by a fallback service 898 * manager. 899 * 900 * @param name the name of the service component 901 * @return the service component if any 902 * @throws Exception getting the service failed 903 */ 904 private Object getFallbackService(String name) throws Exception 905 { 906 907 Validate.notEmpty( name, "name" ); 908 909 Object result = null; 910 ServiceComponent serviceManagerComponent = null; 911 912 for(int i=0; i<this.fallbackServiceManagerList.size(); i++) 913 { 914 String serviceManagerComponentName = (String) fallbackServiceManagerList.get(i); 915 serviceManagerComponent = this.getLocalServiceComponent(serviceManagerComponentName); 916 917 if(serviceManagerComponent != null) 918 { 919 ServiceManager currServiceManager = (ServiceManager) serviceManagerComponent.getInstance(); 920 921 if (currServiceManager.hasService(name)) 922 { 923 result = currServiceManager.lookup(name); 924 925 if((result != null) && this.getLogger().isDebugEnabled()) 926 { 927 String msg = "Located the service '" + name + "' using the fallback service manager '" + serviceManagerComponentName + "'"; 928 this.getLogger().debug(msg); 929 } 930 } 931 } 932 } 933 934 return result; 935 } 936 937 /** 938 * Try to get a service provided by a fallback service manager. 939 * 940 * @param name the name of the service component 941 * @return the service component if any 942 */ 943 private boolean hasFallbackService(String name) 944 { 945 Validate.notEmpty( name, "name" ); 946 947 ServiceComponent serviceManagerComponent = null; 948 949 for(int i=0; i<this.fallbackServiceManagerList.size(); i++) 950 { 951 String serviceManagerComponentName = (String) fallbackServiceManagerList.get(i); 952 serviceManagerComponent = this.getLocalServiceComponent(serviceManagerComponentName); 953 954 if(serviceManagerComponent != null) 955 { 956 ServiceManager currServiceManager; 957 958 try 959 { 960 currServiceManager = (ServiceManager) serviceManagerComponent.getInstance(); 961 if (currServiceManager.hasService(name)) 962 { 963 return true; 964 } 965 } 966 catch (Exception e) 967 { 968 String msg = "Unable to invoke fallback service manager '" + serviceManagerComponentName + "'"; 969 this.getLogger().error(msg, e); 970 throw new RuntimeException(msg); 971 } 972 } 973 } 974 975 return false; 976 } 977 978 /** 979 * @param string The location of the component configuration file 980 */ 981 private void setComponentConfigurationLocation(String string) 982 { 983 this.componentConfigurationLocation = string; 984 } 985 986 /** 987 * @param string The location of the component role file 988 */ 989 private void setComponentRolesLocation(String string) 990 { 991 this.componentRolesLocation = string; 992 } 993 994 /** 995 * @param string The location of the parameters file 996 */ 997 private void setParametersLocation(String string) 998 { 999 this.parametersLocation = string; 1000 } 1001 1002 /** 1003 * @return The logger of the service containe 1004 */ 1005 private Logger getLogger() 1006 { 1007 return this.logger; 1008 } 1009 1010 /** 1011 * @return Returns the serviceMap. 1012 */ 1013 private HashMap getServiceMap() 1014 { 1015 return this.serviceMap; 1016 } 1017 1018 /** 1019 * Incarnation of a list of services. 1020 * 1021 * @param serviceList the list of available services 1022 * @throws Exception the incarnation of a service failed 1023 */ 1024 private void incarnateAll(List serviceList) 1025 throws Exception 1026 { 1027 ServiceComponent serviceComponent = null; 1028 1029 // configure all services 1030 1031 for( int i=0; i<serviceList.size(); i++ ) 1032 { 1033 serviceComponent = (ServiceComponent) this.getServiceList().get(i); 1034 this.configure( serviceComponent ); 1035 } 1036 1037 // incarnate all services 1038 1039 for( int i=0; i<serviceList.size(); i++ ) 1040 { 1041 serviceComponent = (ServiceComponent) this.getServiceList().get(i); 1042 this.incarnate( serviceComponent ); 1043 } 1044 1045 } 1046 1047 /** 1048 * Configure a single service component. After the invocation 1049 * the service component is ready to be incarnated. 1050 * 1051 * @param serviceComponent The service component to be configured 1052 * @throws Exception the configuration failed 1053 */ 1054 private void configure( ServiceComponent serviceComponent ) 1055 throws Exception 1056 { 1057 this.getLogger().debug( "Configuring the service component " 1058 + serviceComponent.getShorthand() 1059 ); 1060 1061 // map the context according to the Avalon component type 1062 1063 YaafiToAvalonContextMapper mapper = new YaafiToAvalonContextMapper( 1064 serviceComponent.getName(), 1065 this.getClassLoader() 1066 ); 1067 1068 RoleEntry roleEntry = serviceComponent.getRoleEntry(); 1069 String componentFlavour = roleEntry.getComponentFlavour(); 1070 1071 DefaultContext serviceComponentContext = mapper.mapTo( 1072 this.getContext(), 1073 componentFlavour 1074 ); 1075 1076 // create the remaining Avalon artifacts for the service component 1077 1078 Logger serviceComponentLogger = this.getLogger().getChildLogger( 1079 roleEntry.getLogCategory() 1080 ); 1081 1082 Configuration serviceComponentConfiguraton = this.getServiceConfiguration().getChild( 1083 roleEntry.getShorthand() 1084 ); 1085 1086 Parameters serviceComponentParameters = this.getParameters(); 1087 1088 // configure the service component with all the artifacts 1089 1090 serviceComponent.setLogger(serviceComponentLogger); 1091 serviceComponent.setServiceManager(this); 1092 serviceComponent.setContext(serviceComponentContext); 1093 serviceComponent.setConfiguration(serviceComponentConfiguraton); 1094 serviceComponent.setParameters(serviceComponentParameters); 1095 1096 // load the implementation class of the service 1097 1098 serviceComponent.loadImplemtationClass( 1099 this.getClassLoader() 1100 ); 1101 } 1102 1103 /** 1104 * Incarnation of a configured service component. After the 1105 * incarnation the service component is operational. 1106 * 1107 * @param serviceComponent The service component to incarnate 1108 * @exception Exception incarnating the service component failed 1109 */ 1110 private void incarnate( ServiceComponent serviceComponent ) 1111 throws Exception 1112 { 1113 this.getLogger().debug( "Incarnating the service " 1114 + serviceComponent.getShorthand() 1115 ); 1116 1117 serviceComponent.incarnate(); 1118 } 1119 1120 /** 1121 * Decommision a ist of services. 1122 * 1123 * @param serviceList the list of services to decommision 1124 */ 1125 private void decommisionAll(List serviceList) 1126 { 1127 ServiceComponent serviceComponent = null; 1128 1129 for( int i=serviceList.size()-1; i>=0; i-- ) 1130 { 1131 serviceComponent = (ServiceComponent) serviceList.get(i); 1132 this.decommision( serviceComponent ); 1133 } 1134 } 1135 1136 /** 1137 * Decommision of a single service component. Decommision consists of running the 1138 * whole Avalon decommision lifecycle process for a service component. After 1139 * decommision the service is not operational any longer. During decommisioning 1140 * we ignore any exceptions since it is quite common that something goes wrong. 1141 * 1142 * @param serviceComponent The service component to decommision 1143 */ 1144 private void decommision( ServiceComponent serviceComponent ) 1145 { 1146 this.getLogger().debug( "Decommision the service " + serviceComponent.getShorthand() ); 1147 1148 try 1149 { 1150 serviceComponent.decommision(); 1151 } 1152 catch (Throwable e) 1153 { 1154 String msg = "Decommisioning the following service failed : " + serviceComponent.getName(); 1155 this.getLogger().error( msg, e ); 1156 } 1157 } 1158 1159 /** 1160 * Disposing a ist of services 1161 * 1162 * @param serviceList the list of services to dispose 1163 */ 1164 private void disposeAll(List serviceList) 1165 { 1166 ServiceComponent serviceComponent = null; 1167 1168 for( int i=serviceList.size()-1; i>=0; i-- ) 1169 { 1170 serviceComponent = (ServiceComponent) serviceList.get(i); 1171 this.dispose( serviceComponent ); 1172 } 1173 } 1174 1175 /** 1176 * Disposing of a single service component. 1177 1178 * @param serviceComponent The service component to decommision 1179 */ 1180 private void dispose( ServiceComponent serviceComponent ) 1181 { 1182 this.getLogger().debug( "Disposing the service " + serviceComponent.getShorthand() ); 1183 1184 try 1185 { 1186 serviceComponent.dispose(); 1187 } 1188 catch (Throwable e) 1189 { 1190 String msg = "Disposing the following service failed : " + serviceComponent.getName(); 1191 this.getLogger().error( msg, e ); 1192 } 1193 } 1194 1195 /** 1196 * @return The list of currently know services 1197 */ 1198 private List getServiceList() 1199 { 1200 return this.serviceList; 1201 } 1202 1203 /** 1204 * @param list The list of known services 1205 */ 1206 private void setServiceList(List list) 1207 { 1208 this.serviceList = list; 1209 } 1210 1211 /** 1212 * @return The service configuration 1213 */ 1214 private Configuration getServiceConfiguration() 1215 { 1216 return this.serviceConfiguration; 1217 } 1218 1219 /** 1220 * Factory method for creating services. The service 1221 * instances are not initialized at this point. 1222 * 1223 * @param roleConfiguration the role configuration file 1224 * @param logger the logger 1225 * @return the list of service components 1226 * @throws ConfigurationException creating the service instance failed 1227 */ 1228 private List createServiceComponents(Configuration roleConfiguration, Logger logger ) 1229 throws ConfigurationException 1230 { 1231 Validate.notNull(roleConfiguration,"roleConfiguration"); 1232 Validate.notNull(logger,"logger"); 1233 1234 ArrayList result = new ArrayList(); 1235 ServiceComponent serviceComponent = null; 1236 1237 // create an appropriate instance of role configuration parser 1238 1239 RoleConfigurationParser roleConfigurationParser = this.createRoleConfigurationParser(); 1240 1241 // extract the role entries 1242 1243 RoleEntry[] roleEntryList = roleConfigurationParser.parse(roleConfiguration); 1244 1245 // get the default interceptors defined for the container 1246 1247 ArrayList defaultInterceptorList = this.getDefaultInterceptorServiceList(); 1248 1249 // create the service components based on the role entries 1250 1251 for ( int i=0; i<roleEntryList.length; i++ ) 1252 { 1253 try 1254 { 1255 // add the default interceptors to all role entries 1256 1257 RoleEntry roleEntry = roleEntryList[i]; 1258 1259 if( this.hasDynamicProxies() ) 1260 { 1261 roleEntry.addInterceptors(defaultInterceptorList); 1262 } 1263 else 1264 { 1265 roleEntry.setHasDynamicProxy(false); 1266 } 1267 1268 serviceComponent = new AvalonServiceComponentImpl( 1269 roleEntry, 1270 this.getLogger(), 1271 logger 1272 ); 1273 1274 result.add( serviceComponent ); 1275 } 1276 catch( Throwable t ) 1277 { 1278 String serviceComponentName = ( serviceComponent != null ? serviceComponent.getName() : "unknown" ); 1279 String msg = "Failed to load the service " + serviceComponentName; 1280 this.getLogger().error( msg, t ); 1281 throw new ConfigurationException( msg, t ); 1282 } 1283 } 1284 1285 return result; 1286 } 1287 1288 /** 1289 * Load a configuration file either from a file or using the class loader. 1290 * @param location the location of the file 1291 * @param isEncrypted is the configuration encryped 1292 * @return The loaded configuration 1293 * @throws Exception Something went wrong 1294 */ 1295 private Configuration loadConfiguration( String location, String isEncrypted ) 1296 throws Exception 1297 { 1298 Configuration result = null; 1299 InputStreamLocator locator = this.createInputStreamLocator(); 1300 InputStream is = locator.locate( location ); 1301 DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); 1302 1303 if( is != null ) 1304 { 1305 try 1306 { 1307 is = this.getDecryptingInputStream( is, isEncrypted ); 1308 result = builder.build( is ); 1309 is.close(); 1310 is = null; 1311 } 1312 catch ( Exception e ) 1313 { 1314 String msg = "Unable to parse the following file : " + location; 1315 this.getLogger().error( msg , e ); 1316 throw e; 1317 } 1318 } 1319 1320 return result; 1321 } 1322 1323 /** 1324 * Load a configuration property file either from a file or using the class loader. 1325 * 1326 * @return The loaded proeperty file 1327 * @throws ConfigurationException Something went wrong 1328 */ 1329 private Properties loadComponentConfigurationProperties() 1330 throws ConfigurationException 1331 { 1332 Properties result = new Properties(); 1333 ComponentConfigurationPropertiesResolver resolver = null; 1334 1335 String className = this.componentConfigurationPropertiesResolverConfig.getChild("resolver").getValue( 1336 ComponentConfigurationPropertiesResolverImpl.class.getName() 1337 ); 1338 1339 try 1340 { 1341 Class resolverClass = this.getClassLoader().loadClass( className ); 1342 resolver = (ComponentConfigurationPropertiesResolver) resolverClass.newInstance(); 1343 ContainerUtil.enableLogging(resolver, this.getLogger()); 1344 ContainerUtil.contextualize(resolver, this.getContext()); 1345 ContainerUtil.configure(resolver, this.componentConfigurationPropertiesResolverConfig); 1346 1347 result = resolver.resolve(null); 1348 1349 this.getLogger().debug("Using the following componentConfigurationProperties: " + result); 1350 } 1351 catch (Exception e) 1352 { 1353 String msg = "Resolving componentConfigurationProperties failed using the following class : " + className; 1354 this.getLogger().error(msg, e); 1355 throw new ConfigurationException(msg, e); 1356 } 1357 1358 return result; 1359 } 1360 1361 /** 1362 * Load the parameters 1363 * @param location The location as a file 1364 * @param isEncrypted is the file encrypted 1365 * @return The loaded configuration 1366 * @throws Exception Something went wrong 1367 */ 1368 private Parameters loadParameters( String location, String isEncrypted ) 1369 throws Exception 1370 { 1371 InputStreamLocator locator = this.createInputStreamLocator(); 1372 InputStream is = locator.locate( location ); 1373 Parameters result = new Parameters(); 1374 1375 if( is != null ) 1376 { 1377 is = this.getDecryptingInputStream( is, isEncrypted ); 1378 Properties props = new Properties(); 1379 props.load( is ); 1380 is.close(); 1381 is = null; 1382 result = Parameters.fromProperties( props ); 1383 } 1384 1385 return result; 1386 } 1387 1388 1389 /** 1390 * Creates a locator to find a resource either in the file system or in 1391 * the classpath. 1392 * 1393 * @return the locator 1394 */ 1395 private InputStreamLocator createInputStreamLocator() 1396 { 1397 return new InputStreamLocator( this.getApplicationRootDir(), this.getLogger() ); 1398 } 1399 1400 /** 1401 * Set the application directory of the container. 1402 * 1403 * @param dir The applicationRootDir to set. 1404 */ 1405 private void setApplicationRootDir(File dir) 1406 { 1407 this.getLogger().debug( "Setting applicationRootDir to " + dir.getAbsolutePath() ); 1408 1409 Validate.notNull(dir,"applicationRootDir is <null>"); 1410 Validate.isTrue(dir.exists(),"applicationRootDir does not exist"); 1411 1412 this.applicationRootDir = dir; 1413 } 1414 1415 /** 1416 * @return Returns the applicationRootDir. 1417 */ 1418 private File getApplicationRootDir() 1419 { 1420 return this.applicationRootDir; 1421 } 1422 1423 /** 1424 * @return Returns the serviceManager of the parent container 1425 */ 1426 private ServiceManager getParentServiceManager() 1427 { 1428 return this.parentServiceManager; 1429 } 1430 1431 /** 1432 * @return is a parent ServiceManager available 1433 */ 1434 private boolean hasParentServiceManager() 1435 { 1436 return (this.getParentServiceManager() != null); 1437 } 1438 /** 1439 * Set the temporary directory of the container. 1440 * 1441 * @param dir The tempRootDir to set. 1442 */ 1443 private void setTempRootDir(File dir) 1444 { 1445 this.getLogger().debug( "Setting tempRootDir to " + dir.getAbsolutePath() ); 1446 1447 Validate.notNull(dir,"tempRootDir is <null>"); 1448 Validate.isTrue(dir.exists(),"tempRootDir does not exist"); 1449 Validate.isTrue(dir.canWrite(),"tempRootDir is not writeable"); 1450 1451 this.tempRootDir = dir; 1452 } 1453 1454 /** 1455 * @return Returns the tempRootDir. 1456 */ 1457 private File getTempRootDir() 1458 { 1459 return tempRootDir; 1460 } 1461 1462 /** 1463 * @return Returns the isComponentConfigurationEncrypted. 1464 */ 1465 private String isComponentConfigurationEncrypted() 1466 { 1467 return isComponentConfigurationEncrypted; 1468 } 1469 1470 /** 1471 * @param isComponentConfigurationEncrypted The isComponentConfigurationEncrypted to set. 1472 */ 1473 private void setComponentConfigurationEncrypted( 1474 String isComponentConfigurationEncrypted) 1475 { 1476 this.isComponentConfigurationEncrypted = isComponentConfigurationEncrypted; 1477 } 1478 1479 /** 1480 * @return Returns the isComponentRolesEncrypted. 1481 */ 1482 private String isComponentRolesEncrypted() 1483 { 1484 return isComponentRolesEncrypted; 1485 } 1486 1487 /** 1488 * @param isComponentRolesEncrypted The isComponentRolesEncrypted to set. 1489 */ 1490 private void setComponentRolesEncrypted(String isComponentRolesEncrypted) 1491 { 1492 this.isComponentRolesEncrypted = isComponentRolesEncrypted; 1493 } 1494 1495 /** 1496 * @return Returns the isParametersEncrypted. 1497 */ 1498 private String isParametersEncrypted() 1499 { 1500 return isParametersEncrypted; 1501 } 1502 1503 /** 1504 * @param isParametersEncrypted The isParametersEncrypted to set. 1505 */ 1506 private void setParametersEncrypted(String isParametersEncrypted) 1507 { 1508 this.isParametersEncrypted = isParametersEncrypted; 1509 } 1510 1511 /** 1512 * Create a decrypting input stream using the default password. 1513 * 1514 * @param is the input stream to be decrypted 1515 * @param isEncrypted the encryption mode (true|false|auto) 1516 * @return an decrypting input stream 1517 * @throws Exception reading the input stream failed 1518 */ 1519 private InputStream getDecryptingInputStream( InputStream is, String isEncrypted ) 1520 throws Exception 1521 { 1522 return CryptoStreamFactory.getDecryptingInputStream(is, isEncrypted); 1523 } 1524 1525 /** 1526 * @return Returns the containerFlavour. 1527 */ 1528 private String getContainerFlavour() 1529 { 1530 return containerFlavour; 1531 } 1532 1533 /** 1534 * @param containerFlavour The containerFlavour to set. 1535 */ 1536 private void setContainerFlavour(String containerFlavour) 1537 { 1538 this.containerFlavour = containerFlavour; 1539 } 1540 1541 /** 1542 * @return Returns the componentRolesFlavour. 1543 */ 1544 private String getComponentRolesFlavour() 1545 { 1546 return componentRolesFlavour; 1547 } 1548 1549 /** 1550 * @param componentRolesFlavour The componentRolesFlavour to set. 1551 */ 1552 private void setComponentRolesFlavour(String componentRolesFlavour) 1553 { 1554 this.componentRolesFlavour = componentRolesFlavour; 1555 } 1556 1557 /** 1558 * @return Returns the context. 1559 */ 1560 private Context getContext() 1561 { 1562 return context; 1563 } 1564 1565 /** 1566 * @return Returns the hasDynamicProxies. 1567 */ 1568 private boolean hasDynamicProxies() 1569 { 1570 return this.hasDynamicProxies; 1571 } 1572 1573 /** 1574 * @return Returns the defaultInterceptorServiceList. 1575 */ 1576 private ArrayList getDefaultInterceptorServiceList() 1577 { 1578 return defaultInterceptorServiceList; 1579 } 1580 1581 /** 1582 * @return the containers class loader 1583 */ 1584 private ClassLoader getClassLoader() 1585 { 1586 return this.getClass().getClassLoader(); 1587 } 1588 1589 /** 1590 * Wait for the time configured as 'reconfigurationDelay' before 1591 * reconfiguring the container or services. 1592 */ 1593 private void waitForReconfiguration() 1594 { 1595 try 1596 { 1597 Thread.sleep(this.reconfigurationDelay); 1598 } 1599 catch(InterruptedException e) 1600 { 1601 // nothing to do 1602 } 1603 } 1604 }