Package com.objectwave.configuration

Provide a mechanism for allowing run time configuration of an application.

See:
          Description

Interface Summary
ConfigurationService The abstract set of features provided by the configuration service.
CreationStrategy Different ways to get a Properties object.
PropertySource The basic interface of the bridge between the user of properties, and the object that actually holds the property values.
 

Class Summary
BasicPropertySource Common behavior that should help all PropertySource concrete classes.
ConfigurationServiceFactory Usage of these classes are hidden within a finder object created for your properties.
DefaultConfigurationService Set the values of the property object from the properties provided by the property factory.
DefaultConfigurationService.Test  
DefaultCreationStrategy This class will first look for a system property called .properties.
PropertyFactory Locate and use the appropriate Properties source for values.
PropertyObjects Hold on to the list of property that we create.
PropertyObjects.Test  
 

Package com.objectwave.configuration Description

Provide a mechanism for allowing run time configuration of an application.

Almost any application has a runtime configuration. This could be the location of log files, or a license key. Property files and XML files have been put to work solving these types of problems, but they only solve half the problem.

Requirements of a Configuration Solution

There are several traits of sucessful configuration solutions. While a tall order, the code in this package strives to accomplish all of these goals.

General Approach

The configuration problem is broken apart into to separate solutions by these classes. The first half of the problem with the 'what' and the second is the 'how'. What needs to be configured and how to locate the configuration values.
There are three classes collaborating in the configuration process.

Implementation

A developer must create a PropertyDetail and PropertySource to make use of the configuration service. ex.
import com.objectwave.exceptions.*;
public class MyProperties
{
   int max = 200;
   String name;
   String fileName;
   File theFile;
   public void setName( String aName ){ name = aName; }
   public void setMax( int limit ){ max = limit; }
   public void setFileName( String fName ) throws ConfigurationException
   {
      theFile = new File( fName );
      if( ! file.exists() )
      {
         throw ExceptionBuilder.configuration( "Invalid file name! " + fName );
      }
      fileName = fName;
   }
   public File getOutputFile() { return theFile; }
   public String getName() { return name; }
   public int getMax() { return max; }
}
The property detail not only holds the values, but should also validate the values when set. Remember we are trying to avoid having problems with our application at some unknown point in the future. We can be reasonably sure that by the time getOutputFile() is called, the file exists.
When the configuration service populates this object, it attempt to call setName, setMax, and setFileName with values of the correct type. max has been defaulted to a limit of 200. The current implementations of the configuration service will only set values that are specified by the configuration mechanism. So, if max is not configured, it won't get set, and the default of 200 will stand.

public class MyPropertySource extends BasicPropertySource
{
   MyProperties props;
   /**
    * When using a source to locate property detail, the config service will ask for the
    * 'expected class' of the detail object.
    */
   public Class getExpectedClass(){ return MyProperties.class; }
   public void initialize() throws ConfigurationException
   {
      props = (MyProperties)getConfigurationInstance(); 
   }
   public int getMax(){ return props.getMax(); }
   public String getName(){ return props.getName(); }
   public FileOutputStream getOutuptStream()
   {
      return new FileOutputStream( props.getOutputFile() );
   }
   public void setMax( int max ) { props.setMax( max ); }
}
So, the property source pretty much delegates values from the detail object. The exceptions being the initialize method and the getOutputStream method. Initialize uses a method inherited from BasicPropertySource to create (or locate and existing) MyProperty object. When the Property Detail object is returned it will be populated with any and all values deemed relevant by the Configuration Service concrete implementation.

When you want to use to get a property configuration value simply new MyPropertySource().getMax(); . You could chose to cache the property source or not. The concrete configuration service may actually cache the detail objects. This, by the way, is also how you could programmatically set the values. new MyPropertySource().setMax( 100 );

For details on how a concrete implementation works, please consult the documentation for that class.