2012-02-28 67 views
2

請考慮下面的一段典型的VMware配置文件(* .vmx)所在:如何反序列化Java屬性文件中給出的bean?

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應用程序使用相同的模式。

回答

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(); 
} 
相關問題