![]()  | ||||||||||||||||||||
application configuration files using a webbeans object
 Applications often need to read, and possibly write, configuration files. An excellent way to accomplish this is to implement a custom singleton, which is easily configured and easily obtained from anywhere in the application. This implementation of the concept allows you to configure a base
directory for configuration files.  An object of type
 
 A custom singleton is a standard java-bean (see Resin-IoC).  Setter methods like  In this case, a single setter is provided that matches the
configuration parameter "config-files-location".  The
 AppConfig.java 
import javax.annotations.PostConstruct;
public class AppConfig {
  ConfigFilesLocation _cfl = null;
  /**
   * Set the base for subsequent call's to openConfigFileRead()
   * and openConfigFileWrite()
   *
   * @param location a file path or url
   */
  public void setConfigFilesLocation(String location)
    throws Exception
  {
    _cfl = new ConfigFilesLocation();
    _cfl.setLocation(location);
  }
  @PostConstruct
  public void init()
    throws Exception
  {
    if (_cfl == null)
      throw new Exception("'config-files-location' must be set");
  }
  ...
Configuration of the singleton is done with the <example:AppConfig> tag. The example here configures the location of the configuration files
as  The EL configuration variable is used. Configuring the AppConfig singleton in resin-web.xml 
<web-app xmlns="http://caucho.com/ns/resin">
  <example:AppConfig xmlns:example="urn:java:example">
    <config-files-location>${webApp.root}/WEB-INF/config</config-files-location>
  </example:AppConfig>
</web-app>
An instance of the object is retrieved in the application using
dependency injection. In this example servlet, we'll use field-based
injection, marked by the  Resin will look in the WebBeans registry for the  Obtaining the AppConfig object 
import javax.enterprise.inject.Current;
public class TestServlet extends GenericServlet {
  @Current AppConfig _appConfig;
}
 Using the AppConfig object 
...
    InputStream is = _appConfig.openConfigFileRead(inputFile);
...
    OutputStream os = _appConfig.openConfigFileWrite(outputFile);
...
The example in this tutorial is easily modified to allow the hiding of the
configuration file behind  Hiding the configuration file with getters 
package example;
import java.util.*;
import java.io.*;
public class AppConfig {
  private final static String DEFAULT_PROPERTIES = "example/AppConfig.properties";
  private String _configFile;
  private Properties _properties;
  /**
   * Optionally set the name of a file that provides properties that override
   * the defaults.  The defaults are obtained from a file in the classpath 
   * named 'example/AppConfig.properties'
   *
   * For example, the file containing default properties might be in 
   * WEB-INF/classes/example/AppConfig.properties,
   * or if AppConfig.class is in a jar, the AppConfig.properties 
   * could be in the jar file alongside the AppConfig.class file.
   *
   * AppConfig.properties contains values placed there by the developer.
   * The <config-file> is used to indicate a file that specifies properties
   * that override the defaults, perhaps properties that change depending 
   * on the deployment environment.
   */
  public void setConfigFile(String configFile)
    throws Exception
  {
    _configFile = configFile;
  }
  @PostConstruct
  public void init()
    throws Exception
  {
    InputStream is = null;
    if (_configFile != null) {
      // the properties in _configFile override the defaults
      is = new FileInputStream(_configFile);
      _properties = new Properties(defaults);
      _properties.load(is);
    }
    else {
      // try to find a default configuration file in the classpath
      ClassLoader loader = Thread.currentThread().getContextClassLoader();
      is = loader.getResourceAsStream(DEFAULT_PROPERTIES);
      if (is != null)
        _properties = new Properties();
        _properties.load(is);
      }
      else {
        // throw an exception here to make the defaults required
        throw new FileNotFoundException(DEFAULT_PROPERTIES);
      }
    } 
  }
  public String getFoo()
  { 
    return _properties.getProperty("foo");
  }
  public String getBar()
  { 
    return _properties.getProperty("bar");
  }
}
<web-app xmlns="http://caucho.com/ns/resin">
 <example:AppConfig xmlns:example="urn:java:example"/>
</web-app>
or
<web-app xmlns="http://caucho.com/ns/resin">
 <example:AppConfig xmlns:example="urn:java:example">
    <config-file>${webApp.root}/WEB-INF/AppConfig-override.properties</config-file>
 </example:AppConfig>
</web-app>
package example;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.enterprise.inject.Current;
import java.io.*;
import java.util.*;
public class TestServlet extends HttpServlet {
  @Current AppConfig _appConfig;
  ...
  String foo = _appConfig.getFoo();
  String bar = _appConfig.getBar();
  ...
}
The availability of AppConfig to different web-apps depends upon the context that the <example:AppConfig> configuration is placed within. If the configuration is placed as a child of <web-app>, then that instance of AppConfig is available only to that web-app. WEB-INF/resin-web.xml local to web-app <web-app xmlns="http://caucho.com/ns/resin"> <example:AppConfig xmlns:example="urn:java:example"/> </web-app> If it is placed as a child of <host>, that instance of AppConfig is available to all web-apps within the host. shared host configuration in resin.conf 
<resin xmlns="http://caucho.com/ns/resin">
<cluster id="">
  <host id="">
    <example:AppConfig xmlns:example="urn:java:example"/>
    ...
  </host>
</cluster>
</resin>
If the <example:AppConfig> is placed as a child of <cluster>, that instance of AppConfig is available to all web-apps within all hosts within that cluster. shared cluster configuration in resin.conf 
<resin xmlns="http://caucho.com/ns/resin">
<cluster id="">
   <example:AppConfig xmlns:example="urn:java:example"/>
   <host id="">
      ...
   </host id="">
  ...
</cluster>
</resin>
In the case of <cluster> or <host>, the example.AppConfig class needs to be available in the classpath. The easiest way to accomplish that is to place a jar with that class in $RESIN_HOME/lib, or you can use an explicit <class-loader> tag. 
 
  | ||||||||||||||||||||