2014-02-11 28 views
0

在我的場景中,我使用XStream,我需要能夠以不同的變體存儲/解析相同的數據。如何將XStream與相同數據的變體一起使用?

考慮下面的類:

用戶:

public class User implements Serializable 
{ 

    @XStreamAlias(value = "roles") 
    private List<Role> roles = new ArrayList<Role>(); 

    ... 
} 

角色:

public class Role implements Serializable 
{ 

    @XStreamAlias(value = "name") 
    private String name; 

    @XStreamAlias(value = "description") 
    private String description; 

    ... 
} 

我需要能夠產生以下的輸出:

users.xml中

<users> 
    <user> 
     <username>admin</username> 
     <password>password</password> 
     <roles> 
      <role>administrator</role> 
     </roles> 
    </user> 
    <user> 
     <username>deployer</username> 
     <password>password</password> 
     <roles> 
      <role>deploy</role> 
     </roles> 
    </user> 
</users> 

roles.xml:

<roles> 
    <role> 
     <name>admin<name> 
     <description>Administrative role</description? 
    </role> 
    <role> 
     <name>deploy<name> 
     <description>Deployment role</description? 
    </role> 
    ... 
</roles> 

但是,我堅持:

<users> 
    <user> 
     <username>admin</username> 
     <password>password</password> 
     <roles> 
      <role> 
       <name>admin</name> 
      </role> 
     </roles> 
    </user> 
    <user> 
     <username>deployer</username> 
     <password>password</password> 
     <roles> 
      <role> 
       <name>deploy</name> 
      </role> 
      <role> 
       <name>read</name> 
      </role> 
      <role> 
       <name>delete</name> 
      </role> 
     </roles> 
    </user> 
</users> 

......然而,我想是得到:

<users> 
    ... 
    <user> 
     <username>deployer</username> 
     <password>password</password> 
     <roles> 
      <role> 
       <name>deploy</name> 
       <name>read</name> 
       <name>delete</name> 
      </role> 
     </roles> 
    </user> 
    ... 
</users> 

這是可以理解的。 User DTO中的數據結構不同。所以,我想我需要一個Converter。所以,我敲了以下內容:

public class RoleListConverter 
     implements Converter 
{ 

    public boolean canConvert(Class clazz) 
    { 
     return AbstractList.class.isAssignableFrom(clazz); 
    } 

    public void marshal(Object value, 
         HierarchicalStreamWriter writer, 
         MarshallingContext context) 
    { 
     if (value instanceof List) 
     { 
      //noinspection unchecked 
      List<Role> roles = (List<Role>) value; 

      for (Role role : roles) 
      { 
       writer.startNode("role"); 
       writer.setValue(role.getName()); 
       writer.endNode(); 
      } 
     } 
    } 

    public Object unmarshal(HierarchicalStreamReader reader, 
          UnmarshallingContext context) 
    { 
     List<Role> roles = new ArrayList<Role>(); 

     while (reader.hasMoreChildren()) 
     { 
      reader.moveDown(); 

      Role role = new Role(); 

      final String nodeName = reader.getNodeName(); 
      if (nodeName.equals("role")) 
      { 
       role.setName(reader.getValue().trim()); 
       roles.add(role); 
      } 

      reader.moveUp(); 
     } 

     return roles; 
    } 

} 

我的分析器類是這樣的:

public class UserParser 
     extends GenericParser<User> 
{ 
    ... 
    public XStream getXStreamInstance() 
    { 
     XStream xstream = new XStream(); 
     xstream.autodetectAnnotations(true); 
     xstream.alias("user", User.class); 
     xstream.alias("users", List.class); 
     xstream.alias("role", Role.class); 
     xstream.alias("credentials", Credentials.class); 
     xstream.registerConverter(new RoleListConverter()); 

     return xstream; 
    } 
    ... 
} 

嘗試存儲並顯示以下錯誤的XML時,這種失敗:

java.lang.ClassCastException: org.foo.User cannot be cast to org.foo.Role 
    at org.foo.RoleListConverter.marshal(RoleListConverter.java:35) 

顯然,當我註冊這個轉換器時,它會嘗試攔截所有列表並將其鎖定。我在這裏做錯了什麼,以及如何實現我的目標?

在此先感謝!

回答

1

大概有點晚,因爲答案... 任何方式。

您可以定義

​​
+0

有趣的方法,謝謝! – carlspring

相關問題