001 package org.apache.fulcrum.yaafi.framework.factory; 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.IOException; 024 import java.io.InputStream; 025 import java.util.Enumeration; 026 import java.util.Hashtable; 027 028 import org.apache.avalon.framework.configuration.Configuration; 029 import org.apache.avalon.framework.configuration.DefaultConfiguration; 030 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 031 import org.apache.avalon.framework.context.Context; 032 import org.apache.avalon.framework.context.DefaultContext; 033 import org.apache.avalon.framework.logger.ConsoleLogger; 034 import org.apache.avalon.framework.logger.Logger; 035 import org.apache.avalon.framework.service.ServiceManager; 036 import org.apache.fulcrum.yaafi.framework.constant.AvalonMerlinConstants; 037 import org.apache.fulcrum.yaafi.framework.container.ServiceConstants; 038 import org.apache.fulcrum.yaafi.framework.util.InputStreamLocator; 039 import org.apache.fulcrum.yaafi.framework.util.Validate; 040 import org.apache.fulcrum.yaafi.framework.crypto.CryptoStreamFactory; 041 042 /** 043 * Helper class to capture configuration related stuff. The are two ways 044 * for setting up the configuration: 045 * <ul> 046 * <li>set all parameters manually</li> 047 * <li>use a containerConfiguration file and provide the remaining settings</li> 048 * </ul> 049 * 050 * The Avalon context and configuration are created by 051 * <ul> 052 * <li>createFinalContext()</li> 053 * <li>createFinalConfiguration()</li> 054 * </ul> 055 * 056 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a> 057 */ 058 059 public class ServiceContainerConfiguration 060 { 061 /** our default implementation class of the service container */ 062 private String serviceContainerClazzName; 063 064 /** the location of the component role file */ 065 private String componentRolesLocation; 066 067 /** is the component role file encrypted? */ 068 private String isComponentRolesEncrypted; 069 070 /** the location of the component configuration file */ 071 private String componentConfigurationLocation; 072 073 /** is the component configuration file encrypted? */ 074 private String isComponentConfigurationEncrypted; 075 076 /** the location of the paramaters file */ 077 private String parametersLocation; 078 079 /** is the parameters file encrypted? */ 080 private String isParametersEncrypted; 081 082 /** the user-supplied Avalon context */ 083 private DefaultContext context; 084 085 /** the Avalon logger */ 086 private Logger logger; 087 088 /** the application directory */ 089 private String applicationRootDir; 090 091 /** the temporary directory */ 092 private String tempRootDir; 093 094 /** the class loader passed in the Avalon Context */ 095 private ClassLoader componentClassLoader; 096 097 /** the type of container where YAAFI is embedded */ 098 private String containerFlavour; 099 100 /** the caller-supplied container configuration */ 101 private Configuration containerConfiguration; 102 103 /** to lookup service in the parent container */ 104 private ServiceManager parentServiceManager; 105 106 /** a list of ServiceManager maintaining their own services */ 107 private String[] serviceManagerList; 108 109 /** Constructor */ 110 public ServiceContainerConfiguration() 111 { 112 this.logger = new ConsoleLogger(); 113 this.containerFlavour = ServiceConstants.AVALON_CONTAINER_YAAFI; 114 this.serviceContainerClazzName = ServiceConstants.CLAZZ_NAME; 115 this.componentRolesLocation = ServiceConstants.COMPONENT_ROLE_VALUE; 116 this.isComponentRolesEncrypted = "false"; 117 this.componentConfigurationLocation = ServiceConstants.COMPONENT_CONFIG_VALUE; 118 this.isComponentConfigurationEncrypted = "false"; 119 this.parametersLocation = ServiceConstants.COMPONENT_PARAMETERS_VALUE; 120 this.isParametersEncrypted = "false"; 121 this.context = new DefaultContext(); 122 this.applicationRootDir = new File("").getAbsolutePath(); 123 this.tempRootDir = System.getProperty("java.io.tmpdir","."); 124 this.componentClassLoader = this.getClass().getClassLoader(); 125 } 126 127 /** 128 * Add a new entry to the context by creating a new one. 129 * @param name the name of the new entry 130 * @param value the value of the new entry 131 */ 132 public void addToContext( String name, Object value ) 133 { 134 Validate.notEmpty(name,"name"); 135 Validate.notNull(value,"value"); 136 this.getContext().put( name, value ); 137 } 138 139 /** 140 * Add a hashtable to the context 141 * @param hashtable the Hashtable to be added 142 */ 143 public void addToContext( Hashtable hashtable ) 144 { 145 Validate.notNull(hashtable,"hashtable"); 146 147 String name = null; 148 Object value = null; 149 Enumeration keys = hashtable.keys(); 150 151 while( keys.hasMoreElements() ) 152 { 153 name = (String) keys.nextElement(); 154 value = hashtable.get( name ); 155 this.addToContext( name, value ); 156 } 157 } 158 159 /** 160 * Create the final Avalon context passed to YAAFI containing 161 * <ul> 162 * <li>user-supplied context</li> 163 * <li>urn:avalon:home</li> 164 * <li>urn:avalon:temp</li> 165 * <li>urn:avalon:name</li> 166 * <li>urn:avalon:partition</li> 167 * <li>urn:avalon:classloader</li> 168 * </ul> 169 * 170 * @return the final Context 171 */ 172 173 public Context createFinalContext() 174 { 175 // 1) add the application root dir 176 177 this.addToContext( 178 AvalonMerlinConstants.URN_AVALON_HOME, 179 this.getApplicationRootDir() 180 ); 181 182 // 2) add the temp root dir 183 184 this.addToContext( 185 AvalonMerlinConstants.URN_AVALON_TEMP, 186 this.getTempRootDir() 187 ); 188 189 // 3) add the Avalon name 190 191 this.addToContext( 192 AvalonMerlinConstants.URN_AVALON_NAME, 193 ServiceConstants.ROLE_NAME 194 ); 195 196 // 4) add the Avalon partition name 197 198 this.addToContext( 199 AvalonMerlinConstants.URN_AVALON_PARTITION, 200 "root" 201 ); 202 203 // 5) add the class loader 204 205 this.addToContext( 206 AvalonMerlinConstants.URN_AVALON_CLASSLOADER, 207 this.getComponentClassLoader() 208 ); 209 210 return this.getContext(); 211 } 212 213 /** 214 * Create a final configuration. 215 * 216 * @return the configuration 217 */ 218 public Configuration createFinalConfiguration() 219 { 220 DefaultConfiguration result = null; 221 222 if( this.getContainerConfiguration() != null ) 223 { 224 return this.getContainerConfiguration(); 225 } 226 else 227 { 228 // the root element is "fulcrum-yaafi" 229 230 result = new DefaultConfiguration( 231 ServiceConstants.ROLE_NAME 232 ); 233 234 // add the following fragement 235 // 236 // <containerFlavour>merlin</containerFlavour> 237 238 DefaultConfiguration containerFlavourConfig = new DefaultConfiguration( 239 ServiceConstants.CONTAINERFLAVOUR_CONFIG_KEY 240 ); 241 242 containerFlavourConfig.setValue( this.getContainerFlavour() ); 243 244 result.addChild( containerFlavourConfig ); 245 246 // add the following fragement 247 // 248 // <containerClazzName>...</containerClazzName> 249 250 DefaultConfiguration containerClazzNameConfig = new DefaultConfiguration( 251 ServiceConstants.CONTAINERCLAZZNAME_CONFIG_KEY 252 ); 253 254 containerClazzNameConfig.setValue( this.getServiceContainerClazzName() ); 255 256 result.addChild( containerClazzNameConfig ); 257 258 259 // add the following fragement 260 // 261 // <componentRoles> 262 // <location>../conf/componentRoles.xml</location> 263 // <isEncrypted>true</isEncrypted> 264 // </componentRoles> 265 266 DefaultConfiguration componentRolesConfig = new DefaultConfiguration( 267 ServiceConstants.COMPONENT_ROLE_KEYS 268 ); 269 270 DefaultConfiguration componentRolesLocation = new DefaultConfiguration( 271 ServiceConstants.COMPONENT_LOCATION_KEY 272 ); 273 274 componentRolesLocation.setValue( 275 this.getComponentRolesLocation() 276 ); 277 278 DefaultConfiguration componentRolesIsEncrypted = new DefaultConfiguration( 279 ServiceConstants.COMPONENT_ISENCRYPTED_KEY 280 ); 281 282 componentRolesIsEncrypted.setValue( 283 this.isComponentRolesEncrypted() 284 ); 285 286 componentRolesConfig.addChild( componentRolesLocation ); 287 componentRolesConfig.addChild( componentRolesIsEncrypted ); 288 289 result.addChild( componentRolesConfig ); 290 291 // add the following fragement 292 // 293 // <componentConfiguration> 294 // <location>../conf/componentRoles.xml</location> 295 // <isEncrypted>true</isEncrypted> 296 // </componentConfiguration> 297 298 DefaultConfiguration componentConfigurationConfig = new DefaultConfiguration( 299 ServiceConstants.COMPONENT_CONFIG_KEY 300 ); 301 302 DefaultConfiguration componentConfigurationLocation = new DefaultConfiguration( 303 ServiceConstants.COMPONENT_LOCATION_KEY 304 ); 305 306 componentConfigurationLocation.setValue( 307 this.getComponentConfigurationLocation() 308 ); 309 310 DefaultConfiguration componentConfigurationIsEncrypted = new DefaultConfiguration( 311 ServiceConstants.COMPONENT_ISENCRYPTED_KEY 312 ); 313 314 componentConfigurationIsEncrypted.setValue( 315 this.isComponentConfigurationEncrypted() 316 ); 317 318 componentConfigurationConfig.addChild( componentConfigurationLocation ); 319 componentConfigurationConfig.addChild( componentConfigurationIsEncrypted ); 320 321 result.addChild( componentConfigurationConfig ); 322 323 // Add the following fragement 324 // 325 // <parameters> 326 // <location>../conf/parameters.properties</location> 327 // <isEncrypted>true</isEncrypted> 328 // </parameters> 329 330 DefaultConfiguration parameterConfigurationConfig = new DefaultConfiguration( 331 ServiceConstants.COMPONENT_PARAMETERS_KEY 332 ); 333 334 DefaultConfiguration parameterConfigurationLocation = new DefaultConfiguration( 335 ServiceConstants.COMPONENT_LOCATION_KEY 336 ); 337 338 parameterConfigurationLocation.setValue( 339 this.getParametersLocation() 340 ); 341 342 DefaultConfiguration parameterConfigurationIsEncrypted = new DefaultConfiguration( 343 ServiceConstants.COMPONENT_ISENCRYPTED_KEY 344 ); 345 346 parameterConfigurationIsEncrypted.setValue( 347 this.isParametersEncrypted() 348 ); 349 350 parameterConfigurationConfig.addChild( parameterConfigurationLocation ); 351 parameterConfigurationConfig.addChild( parameterConfigurationIsEncrypted ); 352 353 result.addChild( parameterConfigurationConfig ); 354 355 // Add the following fragement 356 // 357 // <serviceManagers> 358 // <serviceManagers>springFrameworkService</serviceManager> 359 // </serviceManagers> 360 361 if(this.hasServiceManagerList()) 362 { 363 DefaultConfiguration serviceManagerListConfig = new DefaultConfiguration( 364 ServiceConstants.SERVICEMANAGER_LIST_KEY 365 ); 366 367 for(int i=0; i<this.serviceManagerList.length; i++) 368 { 369 DefaultConfiguration serviceManagerConfig = new DefaultConfiguration( 370 ServiceConstants.SERVICEMANAGER_KEY 371 ); 372 373 serviceManagerConfig.setValue(this.serviceManagerList[i]); 374 375 serviceManagerListConfig.addChild(serviceManagerConfig); 376 } 377 378 result.addChild( serviceManagerListConfig ); 379 } 380 381 382 return result; 383 } 384 } 385 386 ///////////////////////////////////////////////////////////////////////// 387 // Generated Getters/Setters 388 ///////////////////////////////////////////////////////////////////////// 389 390 /** 391 * @return Returns the serviceContainerClazzName. 392 */ 393 private String getServiceContainerClazzName() 394 { 395 return this.serviceContainerClazzName; 396 } 397 398 /** 399 * @return Returns the componentConfigurationLocation. 400 */ 401 private String getComponentConfigurationLocation() 402 { 403 return componentConfigurationLocation; 404 } 405 406 /** 407 * @param componentConfigurationLocation The componentConfigurationLocation to set. 408 */ 409 public void setComponentConfigurationLocation( 410 String componentConfigurationLocation) 411 { 412 Validate.notNull(componentConfigurationLocation,"componentConfigurationLocation"); 413 this.componentConfigurationLocation = componentConfigurationLocation; 414 } 415 416 /** 417 * @return Returns the componentRolesLocation. 418 */ 419 private String getComponentRolesLocation() 420 { 421 return componentRolesLocation; 422 } 423 424 /** 425 * @param componentRolesLocation The componentRolesLocation to set. 426 */ 427 public void setComponentRolesLocation(String componentRolesLocation) 428 { 429 this.componentRolesLocation = componentRolesLocation; 430 } 431 432 /** 433 * @return Returns the context. 434 */ 435 private DefaultContext getContext() 436 { 437 return context; 438 } 439 440 /** 441 * @param context The context to set. 442 */ 443 public void setContext(Context context) 444 { 445 if( context instanceof DefaultContext ) 446 { 447 this.context = (DefaultContext) context; 448 } 449 else 450 { 451 this.context = new DefaultContext( context ); 452 } 453 } 454 455 /** 456 * @return Returns the isComponentConfigurationEncrypted. 457 */ 458 private String isComponentConfigurationEncrypted() 459 { 460 return isComponentConfigurationEncrypted; 461 } 462 463 /** 464 * @param isComponentConfigurationEncrypted The isComponentConfigurationEncrypted to set. 465 */ 466 public void setComponentConfigurationEncrypted( 467 String isComponentConfigurationEncrypted) 468 { 469 this.isComponentConfigurationEncrypted = isComponentConfigurationEncrypted; 470 } 471 472 /** 473 * @return Returns the isComponentRolesEncrypted. 474 */ 475 private String isComponentRolesEncrypted() 476 { 477 return isComponentRolesEncrypted; 478 } 479 /** 480 * @param isComponentRolesEncrypted The isComponentRolesEncrypted to set. 481 */ 482 public void setComponentRolesEncrypted(String isComponentRolesEncrypted) 483 { 484 this.isComponentRolesEncrypted = isComponentRolesEncrypted; 485 } 486 487 /** 488 * @return Returns the isParametersEncrypted. 489 */ 490 private String isParametersEncrypted() 491 { 492 return isParametersEncrypted; 493 } 494 495 /** 496 * @param isParametersEncrypted The isParametersEncrypted to set. 497 */ 498 public void setParametersEncrypted(String isParametersEncrypted) 499 { 500 Validate.notEmpty(isParametersEncrypted,"isParametersEncrypted"); 501 this.isParametersEncrypted = isParametersEncrypted; 502 } 503 504 /** 505 * @return Returns the logger. 506 */ 507 public Logger getLogger() 508 { 509 return logger; 510 } 511 512 /** 513 * @param logger The logger to set. 514 */ 515 public void setLogger(Logger logger) 516 { 517 this.logger = logger; 518 } 519 520 /** 521 * @return Returns the parametersLocation. 522 */ 523 private String getParametersLocation() 524 { 525 return parametersLocation; 526 } 527 528 /** 529 * @param parametersLocation The parametersLocation to set. 530 */ 531 public void setParametersLocation(String parametersLocation) 532 { 533 this.parametersLocation = parametersLocation; 534 } 535 536 /** 537 * @return Returns the applicationRootDir. 538 */ 539 private File getApplicationRootDir() 540 { 541 return new File(applicationRootDir); 542 } 543 544 /** 545 * @param applicationRootDir The applicationRootDir to set. 546 */ 547 public void setApplicationRootDir(String applicationRootDir) 548 { 549 Validate.notNull(applicationRootDir, "applicationRootDir"); 550 551 if( applicationRootDir.equals(".") ) 552 { 553 this.applicationRootDir = new File("").getAbsolutePath(); 554 } 555 else 556 { 557 this.applicationRootDir = new File( applicationRootDir ).getAbsolutePath(); 558 } 559 } 560 561 /** 562 * @return Returns the tempRootDir. 563 */ 564 private File getTempRootDir() 565 { 566 return makeAbsoluteFile(this.getApplicationRootDir(),this.tempRootDir); 567 } 568 569 /** 570 * @param tempRootDir The tempRootDir to set. 571 */ 572 public void setTempRootDir(String tempRootDir) 573 { 574 Validate.notNull(tempRootDir, "tempRootDir"); 575 this.tempRootDir = tempRootDir; 576 } 577 578 /** 579 * @return Returns the classLoader. 580 */ 581 private ClassLoader getComponentClassLoader() 582 { 583 return componentClassLoader; 584 } 585 586 /** 587 * @param componentClassLoader The classLoader to set. 588 */ 589 public void setComponentClassLoader(ClassLoader componentClassLoader) 590 { 591 Validate.notNull(componentClassLoader, "componentClassLoader"); 592 this.componentClassLoader = componentClassLoader; 593 } 594 595 /** 596 * @return Returns the containerFlavour. 597 */ 598 private String getContainerFlavour() 599 { 600 return containerFlavour; 601 } 602 /** 603 * @param containerFlavour The containerFlavour to set. 604 */ 605 public void setContainerFlavour(String containerFlavour) 606 { 607 this.containerFlavour = containerFlavour; 608 } 609 610 /** 611 * @return Returns the containerConfiguration. 612 */ 613 private Configuration getContainerConfiguration() 614 { 615 return containerConfiguration; 616 } 617 618 /** 619 * @param containerConfiguration The containerConfiguration to set. 620 */ 621 public void setContainerConfiguration(Configuration containerConfiguration) 622 { 623 this.containerConfiguration = containerConfiguration; 624 } 625 626 /** 627 * Get the parent service manager to find service managed by the 628 * parent container. 629 * 630 * @return the parent container 631 */ 632 633 public ServiceManager getParentServiceManager() { 634 return parentServiceManager; 635 } 636 637 /** 638 * Set the parent service manager to find service managed by the 639 * parent container. 640 * 641 * @param parentServiceManager the parent container 642 */ 643 public void setParentServiceManager(ServiceManager parentServiceManager) { 644 this.parentServiceManager = parentServiceManager; 645 } 646 647 /** 648 * Get a list of service manager managing their own set of services. 649 * 650 * @return a list of service implementing the ServiceManager interface 651 */ 652 public String[] getServiceManagerList() { 653 return serviceManagerList; 654 } 655 656 /** 657 * Set a list of service manager managing their own set of services. 658 * 659 * @param serviceManagerList a list of service implementing the ServiceManager interface 660 */ 661 public void setServiceManagerList(String[] serviceManagerList) { 662 this.serviceManagerList = serviceManagerList; 663 } 664 665 /** 666 * @return is a list of service manager managing their own set of services defined 667 */ 668 public boolean hasServiceManagerList() 669 { 670 return ((this.serviceManagerList != null) && (this.serviceManagerList.length > 0)); 671 } 672 673 /** 674 * Loads a containerConfiguration file and set is as the Avalon 675 * configuration to be used for Configurable.configure(). Take 676 * care that the implementation uses an InputStreamLocator to 677 * find the containerConfiguration which uses the previously 678 * set application root directory. 679 * 680 * @param location the location of the containerConfiguration 681 * @throws IOException loading the configuration failed 682 */ 683 public void loadContainerConfiguration( String location ) 684 throws IOException 685 { 686 this.loadContainerConfiguration( location, "false" ); 687 } 688 689 /** 690 * Loads a containerConfiguration file and set is as the Avalon 691 * configuration to be used for Configurable.configure(). Take 692 * care that the implementation uses an InputStreamLocator to 693 * find the containerConfiguration which uses the previously 694 * set application root directory. 695 * 696 * @param location the location of the containerConfiguration 697 * @param isEncrypted is the file encrypted 698 * @throws IOException loading the configuration failed 699 */ 700 public void loadContainerConfiguration( String location, String isEncrypted ) 701 throws IOException 702 { 703 Configuration result = null; 704 705 InputStreamLocator locator = new InputStreamLocator( 706 this.getApplicationRootDir(), 707 this.getLogger() 708 ); 709 710 DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); 711 InputStream is = locator.locate( location ); 712 713 if( is != null ) 714 { 715 try 716 { 717 is = CryptoStreamFactory.getDecryptingInputStream(is ,isEncrypted); 718 result = builder.build( is ); 719 this.setContainerConfiguration( result ); 720 } 721 catch ( Exception e ) 722 { 723 String msg = "Unable to parse the following file : " + location; 724 this.getLogger().error( msg , e ); 725 throw new IOException(msg); 726 } 727 } 728 else 729 { 730 String msg = "Unable to locate the containerConfiguration file : " + location; 731 this.getLogger().error(msg); 732 throw new IOException(msg); 733 } 734 } 735 736 /** 737 * Determines the absolute file. 738 * @param baseDir the base directory 739 * @param fileName the filename 740 * @return the absolute path 741 */ 742 private static File makeAbsoluteFile( File baseDir, String fileName ) 743 { 744 File result = new File(fileName); 745 746 if(!result.isAbsolute()) 747 { 748 result = new File( baseDir, fileName ); 749 } 750 751 return result; 752 } 753 }