<component name="paramBean" class="com.ipil.PropertyBean" scope="application" auto-create="true" startup="true">Then the PropertyBean class (this can be extended and more logic can be added such as caching of properties):
<property name="filename">myproject.properties</property>
<property name="reload">@debug@</property>
</component>
public class PropertyBean {In glassfish the same can be achieve, but there's no component.xml where we could define the property bean, so instead we need to define a producer class, but first we need an annotation:
private static final Logger log = Logger.getLogger(PropertyBean.class);
private String _propertyFile;
private Properties properties;
private static PropertyBean instance = null;
private PropertyBean(String name) {
super();
if (System.getProperty(name) != null) {
_propertyFile = System.getProperty(name);
} else {
//load from jboss.server.config.url
_propertyFile = System.getProperty("jboss.server.config.url") + name;
}
initialize();
}
public static PropertyBean getInstance(String propertiesName) {
setInstance(new PropertyBean(propertiesName));
}
public void initialize() {
if (_propertyFile.startsWith("file:")) {
_propertyFile = _propertyFile.substring(5);
}
FileInputStream propertyFile = null;
try {
Properties pr = new Properties();
pr.load(new FileInputStream(_propertyFile));
setProperties(pr);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (propertyFile != null) {
try {
propertyFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void setProperties(Properties new_properties) {
properties = new_properties;
}
}
package com.ipiel.commons.web;Then the producer class:
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.enterprise.util.Nonbinding;
import javax.inject.Qualifier;
/**
* @author Edward P. Legaspi
* @since Jun 15, 2012
*/
@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
public @interface ConfiguredBy {
@Nonbinding
public String value();
}
package com.ipiel.commons.web;The ConfigBean where we will inject the property file:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Properties;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;
import org.slf4j.Logger;
/**
* Property file loader.
*
* @author Edward P. Legaspi
* @since Jun 15, 2012
*/
public class PropertyProducer {
@Inject
Logger log;
Properties propertyCache;
/**
* Glassfish instace root. The glassfish domain where the application is running.
*/
private static String glassfishInstanceRootPropertyName = "com.sun.aas.instanceRoot";
/**
* Glassfish configuration folder.
*/
private static String glassfishDomainConfigurationFolderName = "config";
/**
* Reads a property file from glassfish config folder.
* @param fileName
* @return
* @throws FileNotFoundException
*/
private static File readFileFromGlassfishDomainConfigFolder(
final String fileName) throws FileNotFoundException {
// Instance Root folder
final String instanceRoot = System
.getProperty(glassfishInstanceRootPropertyName);
if (instanceRoot == null) {
throw new FileNotFoundException(
"Cannot find Glassfish instanceRoot. Is the com.sun.aas.instanceRoot system property set?");
}
// Instance Root + /config folder
File configurationFolder = new File(instanceRoot + File.separator
+ glassfishDomainConfigurationFolderName);
File configFile = new File(configurationFolder, fileName);
// return the given file
return configFile;
}
/**
* Produces a java.util.Properties object based on the qualifier
* ConfiguredBy and the injection point.
*
* Behavior is as follows: - the value can be a System property or a path. -
* If it's a system property, we convert it to the value of that property
* first
*
* - Then we check to see if the value now is an absolute path or a
* classpath entry - We try both.
*/
@Produces
@ConfiguredBy("")
public Properties produceProperties(InjectionPoint ip) {
Properties props;
props = createProperties(ip);
return props;
}
/**
* Read the application configuration property.
* @param ip
* @return
*/
private Properties createProperties(InjectionPoint ip) {
Properties p = new Properties();
String value = ip.getAnnotated().getAnnotation(ConfiguredBy.class)
.value();
try {
File configFile = readFileFromGlassfishDomainConfigFolder(value);
InputStream is = new FileInputStream(configFile);
p.load(is);
is.close();
} catch (Exception e) {
log.debug("Problem reading the file, ignoring.");
}
return p;
}
}
package com.ipiel.pg;Then we can inject ConfigBean on any class we have to access the properties, example:
import java.util.Properties;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.slf4j.Logger;
import com.ipiel.commons.web.ConfiguredBy;
@ApplicationScoped
public class ConfigBean {
@Inject
@ConfiguredBy("/ipiel.properties")
private Properties properties;
@Inject
private Logger log;
public String getProperty(String propertyName) {
String result = properties.getProperty(propertyName);
if (result == null) {
log.warn("No property value found for a propety {}", propertyName);
}
return result;
}
}
public class Foo {
@Inject
private ConfigBean configBean;
}