请考虑以下典型的VMWare配置文件(* .vmx):
memsize = "2048"
MemTrimRate = "-1"
mks.enable3d = "TRUE"
nvram = "Windows Server 2003 Standard Edition.nvram"
pciBridge0.pciSlotNumber = "17"
pciBridge0.present = "TRUE"
pciBridge4.functions = "8"
pciBridge4.pciSlotNumber = "18"
pciBridge4.present = "TRUE"
pciBridge4.virtualDev = "pcieRootPort"
pciBridge5.functions = "8"
pciBridge5.pciSlotNumber = "19"
pciBridge5.present = "TRUE"
pciBridge5.virtualDev = "pcieRootPort"
pciBridge6.functions = "8"
pciBridge6.pciSlotNumber = "20"
pciBridge6.present = "TRUE"
pciBridge6.virtualDev = "pcieRootPort"
pciBridge7.functions = "8"
pciBridge7.pciSlotNumber = "32"
pciBridge7.present = "TRUE"
pciBridge7.virtualDev = "pcieRootPort"
replay.filename = ""
replay.supported = "FALSE"
roamingVM.exitBehavior = "go"
通过观察此配置,可以想象具有以下签名的PciBridge
java bean类型:
class PciBridge
{
public int pciSlotNumber; // or public int getPciSlotNumber(){...} and public void setPciSlotNumber(int v){...}
public boolean present; // or get/is/set methods
public int functions; // or get/set methods
public String virtualDev; // or get/set methods
}
此外,负责读取vmx文件的配置管理器可能会公开以下方法:
public <T> List<T> getObjects(final String prop, Class<T> clazz);
然后给出上述配置,调用getObjects("pciBridge", PciBridge.class)
将返回配置中指定的所有PciBridge
个对象的列表 - 在我们的案例中总共为5个。
如何实现此功能?当然,我在几个不同的产品中看到了相同的模式,所以我认为应该有一些准备好的东西来实现这个功能。
有什么想法吗?
感谢。
修改
更正 - 我没有声称VMWare使用java属性文件格式(双引号是多余的),但精神是相同的。此外,还有适当的Java应用程序使用相同的模式。
答案 0 :(得分:1)
我发布了自己的解决方案。代码依赖于http://commons.apache.org/beanutils/来反映bean和http://commons.apache.org/configuration/以管理基于属性的配置(因为它支持使用$ {}语法的属性引用)。
public static <T> Collection<T> getBeans(String prop, Class<T> clazz) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Pattern pattern = Pattern.compile("^" + prop.replace(".", "\\.") + "(\\d*)\\.(\\w+)$");
Map<String, T> beans = new TreeMap<String, T>();
@SuppressWarnings("rawtypes")
Map description = null;
T tmpBean = null;
Iterator<String> itKeys = m_propStore.getKeys();
while (itKeys.hasNext()) {
String key = itKeys.next();
Matcher matcher = pattern.matcher(key);
boolean matchFound = matcher.find();
if (matchFound) {
if (description == null) {
tmpBean = clazz.newInstance();
description = BeanUtils.describe(tmpBean);
}
String beanPropName = matcher.group(2);
if (description.containsKey(beanPropName)) {
String beanKey = matcher.group(1);
T bean = beans.get(beanKey);
if (bean == null) {
bean = tmpBean == null ? clazz.newInstance() : tmpBean;
tmpBean = null;
beans.put(beanKey, bean);
}
try {
BeanUtils.setProperty(bean, beanPropName, m_propStore.getString(key));
} catch (Exception e) {
m_logger.error(String.format("[SystemConfiguration]: failed to set the %s.%s bean property to the value of the %s configuration property - %s",
bean.getClass().getName(), beanPropName, key, e.getMessage()));
}
}
}
}
return beans.values();
}