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
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.<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 import javax.enterprise.inject.Current; public class TestServlet extends GenericServlet { @Current AppConfig _appConfig; }
... 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 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-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. <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. <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.
|