View Javadoc

1   package org.apache.fulcrum.yaafi.framework.factory;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.util.Enumeration;
26  import java.util.Hashtable;
27  
28  import org.apache.avalon.framework.configuration.Configuration;
29  import org.apache.avalon.framework.configuration.DefaultConfiguration;
30  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
31  import org.apache.avalon.framework.context.Context;
32  import org.apache.avalon.framework.context.DefaultContext;
33  import org.apache.avalon.framework.logger.ConsoleLogger;
34  import org.apache.avalon.framework.logger.Logger;
35  import org.apache.fulcrum.jce.crypto.CryptoStreamFactoryImpl;
36  import org.apache.fulcrum.yaafi.framework.constant.AvalonMerlinConstants;
37  import org.apache.fulcrum.yaafi.framework.container.ServiceConstants;
38  import org.apache.fulcrum.yaafi.framework.util.InputStreamLocator;
39  import org.apache.fulcrum.yaafi.framework.util.Validate;
40  
41  /**
42   * Helper class to capture configuration related stuff. The are two ways
43   * for setting up the configuration:
44   * <ul>
45   *  <li>set all parameters manually</li>
46   *  <li>use a containerConfiguration file and provide the remaining settings</li>
47   * </ul>
48   *
49   * The Avalon context and configuration are created by
50   * <ul>
51   *  <li>createFinalContext()</li>
52   *  <li>createFinalConfiguration()</li>
53   * </ul>
54   *
55   *  @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
56   */
57  
58  public class ServiceContainerConfiguration
59  {
60      /** our default implementation class of the service container */
61      private String serviceContainerClazzName;
62  
63      /** the location of the component role file */
64      private String componentRolesLocation;
65  
66      /** is the component role file encrypted? */
67      private String isComponentRolesEncrypted;
68  
69      /** the location of the component configuration file */
70      private String componentConfigurationLocation;
71  
72      /** is the component configuration file encrypted? */
73      private String isComponentConfigurationEncrypted;
74  
75      /** the location of the paramaters file */
76      private String parametersLocation;
77  
78      /** is the parameters file encrypted? */
79      private String isParametersEncrypted;
80  
81      /** the user-supplied Avalon context */
82      private DefaultContext context;
83  
84      /** the Avalon */
85      private Logger logger;
86  
87      /** the application directory */
88      private String applicationRootDir;
89  
90      /** the temporary directory */
91      private String tempRootDir;
92  
93      /** the class loader passed in the Avalon Context */
94      private ClassLoader componentClassLoader;
95  
96      /** the type of container where YAAFI is embedded */
97      private String containerFlavour;
98  
99      /** the caller-supplied container configuration */
100     private Configuration containerConfiguration;
101 
102     /** Constructor */
103     public ServiceContainerConfiguration()
104     {
105         this.logger = new ConsoleLogger();
106         this.containerFlavour = ServiceConstants.AVALON_CONTAINER_YAAFI;
107         this.serviceContainerClazzName = ServiceConstants.CLAZZ_NAME;
108         this.componentRolesLocation = ServiceConstants.COMPONENT_ROLE_VALUE;
109         this.isComponentRolesEncrypted = "false";
110         this.componentConfigurationLocation = ServiceConstants.COMPONENT_CONFIG_VALUE;
111         this.isComponentConfigurationEncrypted = "false";
112         this.parametersLocation = ServiceConstants.COMPONENT_PARAMETERS_VALUE;
113         this.isParametersEncrypted = "false";
114         this.context = new DefaultContext();
115         this.applicationRootDir = new File("").getAbsolutePath();
116         this.tempRootDir = System.getProperty("java.io.tmpdir",".");
117         this.componentClassLoader = this.getClass().getClassLoader();
118     }
119 
120     /**
121      * Add a new entry to the context by creating a new one.
122      * @param name the name of the new entry
123      * @param value the value of the new entry
124      */
125     public void addToContext( String name, Object value )
126     {
127         Validate.notEmpty(name,"name");
128         Validate.notNull(value,"value");
129         this.getContext().put( name, value );
130     }
131 
132     /**
133      * Add a hashtable to the context
134      * @param hashtable the Hashtable to be added
135      */
136     public void addToContext( Hashtable hashtable )
137     {
138         Validate.notNull(hashtable,"hashtable");
139 
140         String name = null;
141         Object value = null;
142         Enumeration keys = hashtable.keys();
143 
144         while( keys.hasMoreElements() )
145         {
146             name = (String) keys.nextElement();
147             value = hashtable.get( name );
148             this.addToContext( name, value );
149         }
150     }
151 
152     /**
153      * Create the final Avalon context passed to YAAFI containing
154      * <ul>
155      *   <li>user-supplied context</li>
156      *   <li>urn:avalon:home</li>
157      *   <li>urn:avalon:temp</li>
158      *   <li>urn:avalon:name</li>
159      *   <li>urn:avalon:partition</li>
160      *   <li>urn:avalon:classloader</li>
161      * </ul>
162      *
163      * @return the final Context
164      */
165 
166     public Context createFinalContext()
167     {
168         // 1) add the application root dir
169 
170         this.addToContext(
171             AvalonMerlinConstants.URN_AVALON_HOME,
172             this.getApplicationRootDir()
173             );
174 
175         // 2) add the temp root dir
176 
177         this.addToContext(
178             AvalonMerlinConstants.URN_AVALON_TEMP,
179             this.getTempRootDir()
180             );
181 
182         // 3) add the Avalon name
183 
184         this.addToContext(
185             AvalonMerlinConstants.URN_AVALON_NAME,
186             ServiceConstants.ROLE_NAME
187             );
188 
189         // 4) add the Avalon partition name
190 
191         this.addToContext(
192             AvalonMerlinConstants.URN_AVALON_PARTITION,
193             "root"
194             );
195 
196         // 5) add the class loader
197 
198         this.addToContext(
199             AvalonMerlinConstants.URN_AVALON_CLASSLOADER,
200             this.getComponentClassLoader()
201             );
202 
203         return this.getContext();
204     }
205 
206     /**
207      * Create a final configuration.
208      *
209      * @return the configuration
210      */
211     public Configuration createFinalConfiguration()
212     {
213         DefaultConfiguration result = null;
214 
215         if( this.getContainerConfiguration() != null )
216         {
217             return this.getContainerConfiguration();
218         }
219         else
220         {
221             // the root element is "fulcrum-yaafi"
222 
223             result = new DefaultConfiguration(
224                 ServiceConstants.ROLE_NAME
225                 );
226 
227             // add the following fragement
228             //
229             // <containerFlavour>merlin</containerFlavour>
230 
231             DefaultConfiguration containerFlavourConfig = new DefaultConfiguration(
232                 ServiceConstants.CONTAINERFLAVOUR_CONFIG_KEY
233                 );
234 
235             containerFlavourConfig.setValue( this.getContainerFlavour() );
236 
237             result.addChild( containerFlavourConfig );
238 
239             // add the following fragement
240             //
241             // <containerClazzName>...</containerClazzName>
242 
243             DefaultConfiguration containerClazzNameConfig = new DefaultConfiguration(
244                 ServiceConstants.CONTAINERCLAZZNAME_CONFIG_KEY
245                 );
246 
247             containerClazzNameConfig.setValue( this.getServiceContainerClazzName() );
248 
249             result.addChild( containerClazzNameConfig );
250 
251 
252             // add the following fragement
253             //
254             // <componentRoles>
255             //  <location>../conf/componentRoles.xml</location>
256             //  <isEncrypted>true</isEncrypted>
257             // </componentRoles>
258 
259             DefaultConfiguration componentRolesConfig = new DefaultConfiguration(
260                 ServiceConstants.COMPONENT_ROLE_KEYS
261                 );
262 
263             DefaultConfiguration componentRolesLocation = new DefaultConfiguration(
264                 ServiceConstants.COMPONENT_LOCATION_KEY
265                 );
266 
267             componentRolesLocation.setValue(
268                 this.getComponentRolesLocation()
269                 );
270 
271             DefaultConfiguration componentRolesIsEncrypted = new DefaultConfiguration(
272                 ServiceConstants.COMPONENT_ISENCRYPTED_KEY
273                 );
274 
275             componentRolesIsEncrypted.setValue(
276                 this.isComponentRolesEncrypted()
277                 );
278 
279             componentRolesConfig.addChild( componentRolesLocation );
280             componentRolesConfig.addChild( componentRolesIsEncrypted );
281 
282             result.addChild( componentRolesConfig );
283 
284             // add the following fragement
285             //
286             // <componentConfiguration>
287             //  <location>../conf/componentRoles.xml</location>
288             //  <isEncrypted>true</isEncrypted>
289             // </componentConfiguration>
290 
291             DefaultConfiguration componentConfigurationConfig = new DefaultConfiguration(
292                 ServiceConstants.COMPONENT_CONFIG_KEY
293                 );
294 
295             DefaultConfiguration componentConfigurationLocation = new DefaultConfiguration(
296                 ServiceConstants.COMPONENT_LOCATION_KEY
297                 );
298 
299             componentConfigurationLocation.setValue(
300                 this.getComponentConfigurationLocation()
301                 );
302 
303             DefaultConfiguration componentConfigurationIsEncrypted = new DefaultConfiguration(
304                 ServiceConstants.COMPONENT_ISENCRYPTED_KEY
305                 );
306 
307             componentConfigurationIsEncrypted.setValue(
308                 this.isComponentConfigurationEncrypted()
309                 );
310 
311             componentConfigurationConfig.addChild( componentConfigurationLocation );
312             componentConfigurationConfig.addChild( componentConfigurationIsEncrypted );
313 
314             result.addChild( componentConfigurationConfig );
315 
316             // Add the following fragement
317             //
318             // <parameters>
319             //   <location>../conf/parameters.properties</location>
320             //   <isEncrypted>true</isEncrypted>
321             // </parameters>
322 
323             DefaultConfiguration parameterConfigurationConfig = new DefaultConfiguration(
324                 ServiceConstants.COMPONENT_PARAMETERS_KEY
325                 );
326 
327             DefaultConfiguration parameterConfigurationLocation = new DefaultConfiguration(
328                 ServiceConstants.COMPONENT_LOCATION_KEY
329                 );
330 
331             parameterConfigurationLocation.setValue(
332                 this.getParametersLocation()
333                 );
334 
335             DefaultConfiguration parameterConfigurationIsEncrypted = new DefaultConfiguration(
336                 ServiceConstants.COMPONENT_ISENCRYPTED_KEY
337                 );
338 
339             parameterConfigurationIsEncrypted.setValue(
340                 this.isParametersEncrypted()
341                 );
342 
343             parameterConfigurationConfig.addChild( parameterConfigurationLocation );
344             parameterConfigurationConfig.addChild( parameterConfigurationIsEncrypted );
345 
346             result.addChild( parameterConfigurationConfig );
347 
348             return result;
349         }
350     }
351 
352     /////////////////////////////////////////////////////////////////////////
353     // Generated Getters/Setters
354     /////////////////////////////////////////////////////////////////////////
355 
356     /**
357      * @return Returns the serviceContainerClazzName.
358      */
359     private String getServiceContainerClazzName()
360     {
361         return this.serviceContainerClazzName;
362     }
363 
364     /**
365      * @return Returns the componentConfigurationLocation.
366      */
367     private String getComponentConfigurationLocation()
368     {
369         return componentConfigurationLocation;
370     }
371 
372     /**
373      * @param componentConfigurationLocation The componentConfigurationLocation to set.
374      */
375     public void setComponentConfigurationLocation(
376         String componentConfigurationLocation)
377     {
378         Validate.notNull(componentConfigurationLocation,"componentConfigurationLocation");
379         this.componentConfigurationLocation = componentConfigurationLocation;
380     }
381 
382     /**
383      * @return Returns the componentRolesLocation.
384      */
385     private String getComponentRolesLocation()
386     {
387         return componentRolesLocation;
388     }
389 
390     /**
391      * @param componentRolesLocation The componentRolesLocation to set.
392      */
393     public void setComponentRolesLocation(String componentRolesLocation)
394     {
395         this.componentRolesLocation = componentRolesLocation;
396     }
397 
398     /**
399      * @return Returns the context.
400      */
401     private DefaultContext getContext()
402     {
403         return context;
404     }
405 
406     /**
407      * @param context The context to set.
408      */
409     public void setContext(Context context)
410     {
411         if( context instanceof DefaultContext )
412         {
413             this.context = (DefaultContext) context;
414         }
415         else
416         {
417             this.context = new DefaultContext( context );
418         }
419     }
420 
421     /**
422      * @return Returns the isComponentConfigurationEncrypted.
423      */
424     private String isComponentConfigurationEncrypted()
425     {
426         return isComponentConfigurationEncrypted;
427     }
428 
429     /**
430      * @param isComponentConfigurationEncrypted The isComponentConfigurationEncrypted to set.
431      */
432     public void setComponentConfigurationEncrypted(
433         String isComponentConfigurationEncrypted)
434     {
435         this.isComponentConfigurationEncrypted = isComponentConfigurationEncrypted;
436     }
437 
438     /**
439      * @return Returns the isComponentRolesEncrypted.
440      */
441     private String isComponentRolesEncrypted()
442     {
443         return isComponentRolesEncrypted;
444     }
445     /**
446      * @param isComponentRolesEncrypted The isComponentRolesEncrypted to set.
447      */
448     public void setComponentRolesEncrypted(String isComponentRolesEncrypted)
449     {
450         this.isComponentRolesEncrypted = isComponentRolesEncrypted;
451     }
452 
453     /**
454      * @return Returns the isParametersEncrypted.
455      */
456     private String isParametersEncrypted()
457     {
458         return isParametersEncrypted;
459     }
460 
461     /**
462      * @param isParametersEncrypted The isParametersEncrypted to set.
463      */
464     public void setParametersEncrypted(String isParametersEncrypted)
465     {
466         Validate.notEmpty(isParametersEncrypted,"isParametersEncrypted");
467         this.isParametersEncrypted = isParametersEncrypted;
468     }
469 
470     /**
471      * @return Returns the logger.
472      */
473     public Logger getLogger()
474     {
475         return logger;
476     }
477 
478     /**
479      * @param logger The logger to set.
480      */
481     public void setLogger(Logger logger)
482     {
483         this.logger = logger;
484     }
485 
486     /**
487      * @return Returns the parametersLocation.
488      */
489     private String getParametersLocation()
490     {
491         return parametersLocation;
492     }
493 
494     /**
495      * @param parametersLocation The parametersLocation to set.
496      */
497     public void setParametersLocation(String parametersLocation)
498     {
499         this.parametersLocation = parametersLocation;
500     }
501 
502     /**
503      * @return Returns the applicationRootDir.
504      */
505     private File getApplicationRootDir()
506     {
507         return new File(applicationRootDir);
508     }
509 
510     /**
511      * @param applicationRootDir The applicationRootDir to set.
512      */
513     public void setApplicationRootDir(String applicationRootDir)
514     {
515         Validate.notNull(applicationRootDir, "applicationRootDir");
516 
517         if( applicationRootDir.equals(".") )
518         {
519             this.applicationRootDir = new File("").getAbsolutePath();
520         }
521         else
522         {
523             this.applicationRootDir = new File( applicationRootDir ).getAbsolutePath();
524         }
525     }
526 
527     /**
528      * @return Returns the tempRootDir.
529      */
530     private File getTempRootDir()
531     {
532         return makeAbsoluteFile(this.getApplicationRootDir(),this.tempRootDir);
533     }
534 
535     /**
536      * @param tempRootDir The tempRootDir to set.
537      */
538     public void setTempRootDir(String tempRootDir)
539     {
540         Validate.notNull(tempRootDir, "tempRootDir");
541         this.tempRootDir = tempRootDir;
542     }
543 
544     /**
545      * @return Returns the classLoader.
546      */
547     private ClassLoader getComponentClassLoader()
548     {
549         return componentClassLoader;
550     }
551 
552     /**
553      * @param componentClassLoader The classLoader to set.
554      */
555     public void setComponentClassLoader(ClassLoader componentClassLoader)
556     {
557         Validate.notNull(componentClassLoader, "componentClassLoader");
558         this.componentClassLoader = componentClassLoader;
559     }
560 
561     /**
562      * @return Returns the containerFlavour.
563      */
564     private String getContainerFlavour()
565     {
566         return containerFlavour;
567     }
568     /**
569      * @param containerFlavour The containerFlavour to set.
570      */
571     public void setContainerFlavour(String containerFlavour)
572     {
573         this.containerFlavour = containerFlavour;
574     }
575 
576     /**
577      * @return Returns the containerConfiguration.
578      */
579     private Configuration getContainerConfiguration()
580     {
581         return containerConfiguration;
582     }
583 
584     /**
585      * @param containerConfiguration The containerConfiguration to set.
586      */
587     public void setContainerConfiguration(Configuration containerConfiguration)
588     {
589         this.containerConfiguration = containerConfiguration;
590     }
591 
592     /**
593      * Loads a containerConfiguration file and set is as the Avalon
594      * configuration to be used for Configurable.configure(). Take
595      * care that the implementation uses an InputStreamLocator to
596      * find the containerConfiguration which uses the previously
597      * set application root directory.
598      *
599      * @param location the location of the containerConfiguration
600      * @throws IOException loading the configuration failed
601      */
602     public void loadContainerConfiguration( String location )
603         throws IOException
604     {
605         this.loadContainerConfiguration( location, "false" );
606     }
607 
608     /**
609      * Loads a containerConfiguration file and set is as the Avalon
610      * configuration to be used for Configurable.configure(). Take
611      * care that the implementation uses an InputStreamLocator to
612      * find the containerConfiguration which uses the previously
613      * set application root directory.
614      *
615      * @param location the location of the containerConfiguration
616      * @param isEncrypted is the file encrypted
617      * @throws IOException loading the configuration failed
618      */
619     public void loadContainerConfiguration( String location, String isEncrypted )
620         throws IOException
621     {
622         Configuration result = null;
623 
624         InputStreamLocator locator = new InputStreamLocator(
625             this.getApplicationRootDir(),
626             this.getLogger()
627             );
628 
629         DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
630         InputStream is = locator.locate( location );
631         InputStream cis = is;
632 
633         if( is != null )
634         {
635             try
636             {
637                 if( isEncrypted.equalsIgnoreCase("true") )
638                 {
639                     cis = CryptoStreamFactoryImpl.getInstance().getInputStream(is);
640                     result = builder.build( cis );
641                     cis.close();
642                 }
643                 if( isEncrypted.equalsIgnoreCase("auto") )
644                 {
645                     cis = CryptoStreamFactoryImpl.getInstance().getSmartInputStream(is);
646                     result = builder.build( cis );
647                     cis.close();
648                 }
649                 else
650                 {
651                     result = builder.build( is );
652                     is.close();
653                 }
654 
655                 this.setContainerConfiguration( result );
656             }
657             catch ( Exception e )
658             {
659                 String msg = "Unable to parse the following file : " + location;
660                 this.getLogger().error( msg , e );
661                 throw new IOException(msg);
662             }
663         }
664         else
665         {
666             String msg = "Unable to locate the containerConfiguration file : " + location;
667             this.getLogger().error(msg);
668             throw new IOException(msg);
669         }
670     }
671 
672     /**
673      * Determines the absolute file.
674      * @param baseDir the base directory
675      * @param fileName the filename
676      * @return the absolute path
677      */
678     private static File makeAbsoluteFile( File baseDir, String fileName )
679     {
680         File result = new File(fileName);
681 
682         if( result.isAbsolute() == false )
683         {
684             result = new File( baseDir, fileName );
685         }
686 
687         return result;
688     }
689 }