2014-02-11 2 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> 

Это понятно. Данные в DTC User структурированы по-разному. Итак, я решил, что мне нужен 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

Возможно, немного поздно, как ответ ... В любом случае.

Вы можете определить

private class UserList extends ArrayList<User> {}; 
private class RoleList extends ArrayList<Role> {}; 

xstream.alias("users", UserList.class); 
xstream.alias("roles", RoleList.class); 
+0

Интересный подход, спасибо! – carlspring

Смежные вопросы