Как получить доступ к полевым аннотациям из пользовательского конвертера с помощью Simple? - PullRequest
2 голосов
/ 18 февраля 2012

Я использую библиотеку Simple (http://simple.sourceforge.net/)) для маршаллизации / демаршаллизации XML-данных в Java. Для некоторых из моих более сложных структур данных мне нужно написать свои собственные конвертеры. Например, скажем, у меня есть List<List<String>> что мне нужно сделать маршалл. Я написал следующее:

class WorldObject {

   @Element(name="vector-names")
   @Convert(ListListConverter.class)
   private List<List<String>> vectorNames;

   /** Constructor and other details ... **/

}

Наряду с ListListConverter (на данный момент я оставил демаршаллер):

class ListListConverter implements Converter<List<List<String>>> {

   @Override
   public List<List<String>> read(InputNode node) throws Exception {
      // stub
      return null;
   }   

   @Override
   public void write(OutputNode node, List<List<String>> value)
         throws Exception {

      node.setName("list-list-string");

      for (List<String> list : value) {
         OutputNode subList = node.getChild("list-string");

         for (String str : list) {
            OutputNode stringNode = subList.getChild("string");
            stringNode.setValue(str);
         }

         subList.commit();
      }

      node.commit();

   }

}

Эта установка отлично работает и выдает XML, который я хочу. Однако я хотел бы получить доступ к полю name аннотации @Element, чтобы я мог присвоить тегам указанное имя (в данном случае "vector-names"), а не имя по умолчанию ("list-list-string"). Вот как маршаллинг работает для всех типов, которые Simple обрабатывает из коробки, поэтому должен быть способ доступа к этим данным из пользовательского конвертера.

Как мне это сделать?

1 Ответ

1 голос
/ 12 февраля 2013

Вы не можете получить аннотацию таким образом, потому что она не доступна через поле в поле -конвертера.
решение - написать WorldObject -конвертер - даже если вы хотите написать только одно поле.

WorldObject класс:

@Root
@Convert(WorldObjectConverter.class) // specify converter for this class
public class WorldObject
{
    @Element(name = "vector-names")
    private List<List<String>> vectorNames;

    // only for the example below - write whatever constructor(s) you need
    public WorldObject()
    {
        this.vectorNames = new ArrayList<>();
    }

    // constructor, getter / setter, etc.


    // a getter is required to access the field in the converter.
    public List<List<String>> getVectorNames()
    {
        return vectorNames;
    }
}

WorldObjectConverter класс:

public class WorldObjectConverter implements Converter<WorldObject>
{
    @Override
    public WorldObject read(InputNode node) throws Exception
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }


    @Override
    public void write(OutputNode node, WorldObject value) throws Exception
    {
        final Field f = value.getClass().getDeclaredField("vectorNames"); // get the field 'vectorNames' of the 'WorldObject' class
        final Element elementAnnotation = f.getAnnotation(Element.class); // get the 'Element' annotation of the Field

        final String name = elementAnnotation.name(); // get the 'name'-value of the annotation
        node.setName(name); // set Nodename


        for( List<String> list : value.getVectorNames() )
        {
            OutputNode subList = node.getChild("list-string");

            for( String str : list )
            {
                OutputNode stringNode = subList.getChild("string");
                stringNode.setValue(str);
            }

            subList.commit();
        }

        node.commit();
    }
}

Пример: * * один тысяча двадцать-одна final File f = new File("test.xml"); // output file WorldObject wo = new WorldObject(); // the object to serialize // some testdata ... List<String> l = new ArrayList<>(); l.add("a"); l.add("b"); wo.getVectorNames().add(l); l = new ArrayList<>(); l.add("c"); l.add("d"); wo.getVectorNames().add(l); // create the serializer - dont forget the AnnotationStrategy! Serializer ser = new Persister(new AnnotationStrategy()); ser.write(wo, f); // serialize it to file Выход:

<vector-names>
   <list-string>
      <string>a</string>
      <string>b</string>
   </list-string>
   <list-string>
      <string>c</string>
      <string>d</string>
   </list-string>
</vector-names>

Готово!

...