是否有记录的Java“属性”文件的内容,包括一套行之有效的方法:最佳实践文档提供/所需的Java属性文件内容
- 指定数据类型/预期对于给定的重点内容
- 指定键是否是所必需的应用程序的功能
- 提供的键的含义的说明
目前,我维持(用手)一个.P这是默认的roperties文件,我在之前的评论中撰写了关于每个键的数据类型和描述的散文描述。这不会导致程序可访问的属性文件。
我猜我寻找的是一个 “getopt的” 等价物的属性文件...
[编辑:相关]
是否有记录的Java“属性”文件的内容,包括一套行之有效的方法:最佳实践文档提供/所需的Java属性文件内容
目前,我维持(用手)一个.P这是默认的roperties文件,我在之前的评论中撰写了关于每个键的数据类型和描述的散文描述。这不会导致程序可访问的属性文件。
我猜我寻找的是一个 “getopt的” 等价物的属性文件...
[编辑:相关]
我从来没有见过这样做的标准方式。我可能会做的是:
除了您可以用不同的方式管理信息之外,它不会为您提供任何有关手动操作的信息,例如您可以使用一个可以更容易处理的程序要阅读的评论。它可能会给你你需要的程序化访问,但它是一种自己动手的事情。
或者它可能只是太多的工作,为获得太少(这就是为什么没有明显的东西)。
如果你可以指定你想看到的评论类型,我可以采取一些措施,如果我觉得无聊:-)(这是我喜欢为乐趣而做的事情,生病我知道: - )。
好吧......我很无聊......这里是什么,至少是一个开始:-)
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
public class PropertiesVerifier
{
private final Map<String, PropertyInfo> optionalInfo;
private final Map<String, PropertyInfo> requiredInfo;
{
optionalInfo = new HashMap<String, PropertyInfo>();
requiredInfo = new HashMap<String, PropertyInfo>();
}
public PropertiesVerifier(final PropertyInfo[] infos)
{
for(final PropertyInfo info : infos)
{
final Map<String, PropertyInfo> infoMap;
if(info.isRequired())
{
infoMap = requiredInfo;
}
else
{
infoMap = optionalInfo;
}
infoMap.put(info.getName(), info);
}
}
public void verifyProperties(final Properties properties)
{
for(final Entry<Object, Object> property : properties.entrySet())
{
final String key;
final String value;
key = (String)property.getKey();
value = (String)property.getValue();
if(!(isValid(key, value)))
{
throw new IllegalArgumentException(value + " is not valid for: " + key);
}
}
}
public boolean isRequired(final String key)
{
return (requiredInfo.get(key) != null);
}
public boolean isOptional(final String key)
{
return (optionalInfo.get(key) != null);
}
public boolean isKnown(final String key)
{
return (isRequired(key) || isOptional(key));
}
public Class getType(final String key)
{
final PropertyInfo info;
info = getPropertyInfoFor(key);
return (info.getType());
}
public boolean isValid(final String key,
final String value)
{
final PropertyInfo info;
info = getPropertyInfoFor(key);
return (info.verify(value));
}
private PropertyInfo getPropertyInfoFor(final String key)
{
PropertyInfo info;
info = requiredInfo.get(key);
if(info == null)
{
info = optionalInfo.get(key);
if(info == null)
{
// should be a better exception maybe... depends on how you
// want to deal with it
throw new IllegalArgumentException(key + "
is not a valid property name");
}
}
return (info);
}
protected final static class PropertyInfo
{
private final String name;
private final boolean required;
private final Class clazz;
private final Verifier verifier;
protected PropertyInfo(final String nm,
final boolean mandatory,
final Class c)
{
this(nm, mandatory, c, getDefaultVerifier(c));
}
protected PropertyInfo(final String nm,
final boolean mandatory,
final Class c,
final Verifier v)
{
// check for null
name = nm;
required = mandatory;
clazz = c;
verifier = v;
}
@Override
public int hashCode()
{
return (getName().hashCode());
}
@Override
public boolean equals(final Object o)
{
final boolean retVal;
if(o instanceof PropertyInfo)
{
final PropertyInfo other;
other = (PropertyInfo)o;
retVal = getName().equals(other.getName());
}
else
{
retVal = false;
}
return (retVal);
}
public boolean verify(final String value)
{
return (verifier.verify(value));
}
public String getName()
{
return (name);
}
public boolean isRequired()
{
return (required);
}
public Class getType()
{
return (clazz);
}
}
private static Verifier getDefaultVerifier(final Class clazz)
{
final Verifier verifier;
if(clazz.equals(Boolean.class))
{
// shoudl use a singleton to save space...
verifier = new BooleanVerifier();
}
else
{
throw new IllegalArgumentException("Unknown property type: " +
clazz.getCanonicalName());
}
return (verifier);
}
public static interface Verifier
{
boolean verify(final String value);
}
public static class BooleanVerifier
implements Verifier
{
public boolean verify(final String value)
{
final boolean retVal;
if(value.equalsIgnoreCase("true") ||
value.equalsIgnoreCase("false"))
{
retVal = true;
}
else
{
retVal = false;
}
return (retVal);
}
}
}
和一个简单的测试吧:
import java.util.Properties;
public class Main
{
public static void main(String[] args)
{
final Properties properties;
final PropertiesVerifier verifier;
properties = new Properties();
properties.put("property.one", "true");
properties.put("property.two", "false");
// properties.put("property.three", "5");
verifier = new PropertiesVerifier(
new PropertiesVerifier.PropertyInfo[]
{
new PropertiesVerifier.PropertyInfo("property.one",
true,
Boolean.class),
new PropertiesVerifier.PropertyInfo("property.two",
false,
Boolean.class),
// new PropertiesVerifier.PropertyInfo("property.three",
// true,
// Boolean.class),
});
System.out.println(verifier.isKnown("property.one"));
System.out.println(verifier.isKnown("property.two"));
System.out.println(verifier.isKnown("property.three"));
System.out.println(verifier.isRequired("property.one"));
System.out.println(verifier.isRequired("property.two"));
System.out.println(verifier.isRequired("property.three"));
System.out.println(verifier.isOptional("property.one"));
System.out.println(verifier.isOptional("property.two"));
System.out.println(verifier.isOptional("property.three"));
System.out.println(verifier.getType("property.one"));
System.out.println(verifier.getType("property.two"));
// System.out.println(verifier.getType("property.tthree"));
System.out.println(verifier.isValid("property.one", "true"));
System.out.println(verifier.isValid("property.two", "false"));
// System.out.println(verifier.isValid("property.tthree", "5"));
verifier.verifyProperties(properties);
}
}
一个简单的方法是使用示例属性文件分发项目,例如我的项目在svn中有一个“build.properties.example”,其中的属性根据需要进行了评论。本地正确的属性不会进入svn。
既然你提到了“getopt”,但是,我想知道你是否真的在考虑cmd行参数?如果有一个需要特定属性的“主”,我通常会在“使用”消息中输入相关说明,如果参数不正确或“-h”则会打印出来。
你的第一段话告诉他要做他说他已经在做的事。你的第二段与问题无关(他明确表示他在谈论属性文件)。 – 2009-04-08 18:55:23
你可以在Apache Commons Configuration包中使用的一些功能。它至少提供了对你的属性的类型访问。
传统java属性文件中只有约定。我见过的一些包括提供,就像你说的,一个示例属性文件。另一个是提供所有属性的默认配置,但注释掉。
如果你真的想要一些东西,也许你不想寻找一个属性文件。您可以使用XML配置文件并指定具有数据类型和要求的模式。您可以使用jaxb将架构编译为java并以此方式读取它。通过验证,您可以确保所需的属性在那里。
您希望得到的最好结果是当您执行应用程序时,它会读取,解析和验证文件中的属性。如果你绝对必须保持基于属性,并不想去xml,但需要这个解析。您可以有一个辅助属性文件,列出可能包含的每个属性,类型以及是否需要。然后您必须编写一个属性文件验证程序,该验证程序将接受要验证的文件以及验证模式类属性文件。像
#list of required properties
required=prop1,prop2,prop3
#all properties and their types
prop1.type=Integer
prop2.type=String
我没有看过所有的Apache配置包,但他们经常有这样的有用的实用程序。如果你能在那里找到能简化这一点的东西,我不会感到惊讶。
另一个签出的选项是名为OWNER的项目。在那里,您使用类型和注释来定义用作应用程序中配置对象的接口。然后,OWNER发现并解析正确的Properties
文件。因此,您可以为您的界面编写一个javadoc并将其用作文档。
更新我的答案,包括应该让你开始的代码。 – TofuBeer 2009-04-09 16:37:51
哇,我刚刚得到了“热门问题”徽章,只有3个赞...奇怪...我仍然在为它工作一个令人满意的解决方案。 – andersoj 2010-11-30 16:56:20