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 }