The evry first step is to define an interface and a corresponding implementation class.
The interface exposes only business methods and never ever one of the various Avalon interfaces.
public interface SystemPropertyService { // This interface doesn't exposes any other methods }
The Avalon Service Container interacts with an Avalon service through a bunch of interfaces also known as Avalon Lifecycle Management Specification. Finding the right interface might be challenge in the beginning but it is not an unsurmountable task. Our service needs access to the logging infrastructure, to the component configuration and needs to tell the Avalon Service Container that it is reconfigurable. To make things more interesting we want to dump the updated system properties into the temp directory of the application during service initialization.
public class SystemPropertyServiceImpl extends AbstractLogEnabled implements SystemPropertyService, Reconfigurable, Contextualizable, Initializable { // here comes the implementation ... }
Our service derives from "AbstractLogEnabled" which takes care of getting access to the logger. The implementation class also implements the "Reconfigurable" interface which tells the Avalon Service Container that the service implements
The information about the application context is provided by the "Contextualizable" interface while the service initialization needs the "Initializable" interface.
The Avalon Context contains environment settings such as the current working directory, the temporary directory or the name of the service.
public void contextualize(Context context) throws ContextException { this.tempDir = (File) context.get("urn:avalon:temp"); }
In the Role Configuration file we defined "SystemPropertyService" as shorthand for accessing the Component Configuration. The Component Configuration we use is shown below
<SystemPropertyService> <property name="FOO">BAR</property> </SystemPropertyService>
Let's access the configuration to set the system properties - we get all childrem from the configuration instance and process them. Each child consists of an attribute containing the name and text for the value of the system property to be set. We also write some diagnostic ouptut by requesting the logger instance from "AbstractLogEnabled".
public void configure(Configuration configuration) throws ConfigurationException { Configuration[] systemProperties = configuration.getChildren("property"); for( int i=0; i<systemProperties.length; i++ ) { String key = systemProperties[i].getAttribute("name"); String value = systemProperties[i].getValue(); this.getLogger().debug( "Setting the value of " + key + " to " + value ); System.setProperty( key, value ); } }
Since we have done most of our work already we use the service initialization to dump the current system properties into the temporary directory.
public void initialize() throws Exception { FileOutputStream fos = new FileOutputStream( new File(this.tempDir,"system.properties") ); System.getProperties().store( fos, "system.properties" ); fos.flush(); fos.close(); }
Making our service reconfigurable is simple. When the service is reconfigured a new configuration instance is passed. We just reuse the configure() method to reinitalize our service - that's it.
public void reconfigure(Configuration configuration) throws ConfigurationException { this.configure(configuration); }
Below you find your first complete and fully functional Avalon service.
public interface SystemPropertyService { // This interface doesn't exposes any other methods } public class SystemPropertyServiceImpl extends AbstractLogEnabled implements SystemPropertyService, Reconfigurable, Contextualizable, Initializable { /** the Avalon temp directory */ private File tempDir; /** * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context) */ public void contextualize(Context context) throws ContextException { this.tempDir = (File) context.get("urn:avalon:temp"); } /** * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration) */ public void configure(Configuration configuration) throws ConfigurationException { Configuration[] systemProperties = configuration.getChildren("property"); for( int i=0; i<systemProperties.length; i++ ) { String key = systemProperties[i].getAttribute("name"); String value = systemProperties[i].getValue(); this.getLogger().debug( "Setting the value of " + key + " to " + value ); System.setProperty( key, value ); } } /** * @see org.apache.avalon.framework.activity.Initializable#initialize() */ public void initialize() throws Exception { FileOutputStream fos = new FileOutputStream( new File(this.tempDir,"system.properties") ); System.getProperties().store( fos, "system.properties" ); fos.flush(); fos.close(); } /** * @see org.apache.avalon.framework.configuration.Reconfigurable#reconfigure(org.apache.avalon.framework.configuration.Configuration) */ public void reconfigure(Configuration configuration) throws ConfigurationException { this.configure(configuration); } }