Is it possible to convert a property file into an enum.
I have a propoerty file wit开发者_StackOverflowh lot of settings. for example
equipment.height
equipment.widht
equipment.depth
and many more like this and not all are as simple as the example
The developer has to know the key in order to get the value of the property. instead is it possible to do something, where the developer would type MyPropertyEnum. and the list of keys will show up in the IDE, like it shows up for an Enum
MyPropertyEnum.height
I often use property file + enum combination. Here is an example:
public enum Constants {
PROP1,
PROP2;
private static final String PATH = "/constants.properties";
private static final Logger logger = LoggerFactory.getLogger(Constants.class);
private static Properties properties;
private String value;
private void init() {
if (properties == null) {
properties = new Properties();
try {
properties.load(Constants.class.getResourceAsStream(PATH));
}
catch (Exception e) {
logger.error("Unable to load " + PATH + " file from classpath.", e);
System.exit(1);
}
}
value = (String) properties.get(this.toString());
}
public String getValue() {
if (value == null) {
init();
}
return value;
}
}
Now you also need a property file (I ofter place it in src, so it is packaged into JAR), with properties just as you used in enum. For example:
constants.properties:
#This is property file...
PROP1=some text
PROP2=some other text
Now I very often use static import in classes where I want to use my constants:
import static com.some.package.Constants.*;
And an example usage
System.out.println(PROP1);
Java has static typing. That means, you can't create types dynamically. So, the answer is no. You can't convert a property file into a enum.
What you could do is generate an enum
from that properties file. Or, use a Dictionary (Map) to access your properties with something like:
equipment.get("height");
no, I don't think so. Enums are creating in compile time and thus their number of elements cannot vary depending on whatever it is in the property file.
It's more likely that you would need an structure that is flexible to be constructed in runtime - maybe an associative array.
One way, I could imagine, to get all the properties in your IDE can be to define an Enum with all of them, like this :
public enum Settings
{
EQUIPMENT_HEIGHT("equipment.height", "0"),
EQUIPMENT_WIDTH("equipment.width", "0"),
EQUIPMENT_DEPTH("equipment.depth", "0");
private String property;
private String value;
Settings(final String aProperty, final String aValue)
{
property = aProperty;
value = aValue;
}
public String getProperty()
{
return property;
}
public String getValue()
{
return value;
}
private void setValue(final String aValue)
{
value = aValue;
}
public static void initialize(final Properties aPropertyTable)
{
for(final Settings setting : values())
{
final String key = setting.getProperty();
final String defaultValue = setting.getValue();
setting.setValue(aPropertyTable.getProperty(key, defaultValue));
}
}
}
The initialization of the enum is self explained (method initialize()).
After that, you can use it like this :
Settings.EQUIPMENT_HEIGHT.getValue();
Adding new property is just adding new enum-Constant.
public enum ErrorCode{
DB_ERROR( PropertiesUtil.getProperty("DB_ERRROR_CODE"), PropertiesUtil.getProperty("DB_ERROR")),
APP_ERROR(PropertiesUtil.getProperty("APPLICATION_ERROR_CODE"), PropertiesUtil.getProperty("APPLICATION_ERROR")),
ERROR_FOUND(PropertiesUtil.getProperty("ERROR_FOUND_CODE"), PropertiesUtil.getProperty("ERROR_FOUND"));
private final String errorCode;
private final String errorDesc;
private ErrorCode(String errorCode, String errorDesc) {
this.errorCode = errorCode;
this.errorDesc = errorDesc;
}
public String getErrorDesc() {
return errorDesc;
}
public String getErrorCode() {
return errorCode;
}
public static String getError(String errorCode)
{
System.out.println("errorCode in Enum"+errorCode);
System.out.println(java.util.Arrays.asList(ErrorCode.values()));
for (ErrorCode errorEnum : ErrorCode.values()) {
System.out.println(errorEnum.errorCode);
System.out.println(errorEnum.errorDesc);
if ((errorEnum.errorCode).equals(errorCode)) {
return errorEnum.getErrorDesc();
}
}
return ERROR_FOUND.getErrorDesc();
}
public class PropertiesUtil {
static Properties prop = new Properties();
static{
try {
InputStream inputStream =
PropertiesUtil.class.getClassLoader().getResourceAsStream("db.properties");
prop.load(inputStream);
}catch(Exception e)
{
e.printStackTrace();
}
}
public static PropertiesUtil getInstance()
{
return new PropertiesUtil();
}
public Properties getProperties()
{
return prop;
}
public static String getProperty(String key)
{
return prop.getProperty(key);
}
}
No. Well, I suppose you could if you could compile a properties file into a Java class (or enum). I can't find anything like that (but would be extremely cool)
You can turn a properties file into an enum with generated code. You can do this staticly before the program is compiled and optionally at runtime by using the Compiler API. Doing this adds a a lot of complexity and usually its simpler to use a Map as has been suggested.
The question was asked about enum, I wanted to create an enum based on property. I gave up the idea, because this enum needed to be dynamic, if we get a new error code, it should be added to property file. Sadly I see no way to do that with enum so I chose different path as I read everybody suggests Map based solution. Instead of enum I created a singleton which just reads a property file, and responds on the keywords to give back the value.
the property file:
C102 = Blablabla1
C103 = Blablabla2
C104 = Blablabla3
the singleton code:
package mypackage;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Properties;
public class ResponseValidationTypeCodes {
private final HashMap<String, String> codes;
private static ResponseValidationTypeCodes instance;
public static ResponseValidationTypeCodes getInstance() {
if (instance == null) {
instance = new ResponseValidationTypeCodes();
}
return instance;
}
private ResponseValidationTypeCodes() {
super();
codes = new HashMap<String, String>();
initEntry();
}
private void initEntry() {
Properties prop = new Properties();
try {
prop.load(new FileInputStream(
"src/main/resources/validationcodes.properties"));
for (Entry<Object, Object> element : prop.entrySet()) {
codes.put(element.getKey().toString(), element.getValue()
.toString());
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public String getValueByCode(String code) {
return codes.get(code);
}
}
to get the values, simply call:
ResponseValidationTypeCodes.getInstance()
.getValueByCode("C102");
the initial property reading runs only once. So you just expand the property when some change comes in, and redeploy your stuffs that time. I hope it helps for somebody who is open to use some alternative to enum.
精彩评论