2012-10-16 93 views
3

我正在使用org.simpleframework.xml(http://simple.sourceforge.net/)将Java对象序列化为XML。如何使用注释将org.simpleframework.xml扩展为将注释写入生成的XML

我想添加的是根据Java对象中的Annotations在生成的XML中添加注释区域。

因此,举例来说,我想写一些Java对象,如:

@Root(name = "myclass") 
public class MyClass { 
    @Element(required=true) 
    @Version(revision=1.1) 
    @Comment(text=This Element is new since, version 1.1, it is a MD5 encrypted value) 
    private String activateHash; 
} 

而生成的XML将如下所示:

<myclass version="1.1"> 
    <!-- This Element is new since, version 1.1, it is a MD5 encrypted value --> 
    <activateHash>129831923131s3jjs3s3jjk93jk1</activateHash> 
</myclass> 

上有HOWTO在他们的文档的例子写将在xml中撰写评论的访问者: http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#intercept

但是:如何将访问者附加到策略中?

此外,Simpleframework的Visitor概念不允许访问原始解析类。 在访问者只有覆盖的方法:

public void write(Type type, NodeMap<OutputNode> node) { ... } 

=> OutputNode不给我机会阅读,我解析元素的注释。那么应该如何访问属性的注释。

谢谢!

塞巴斯蒂安

回答

2

更新为2012年11月5日:

通过org.simpleframework.xml笔者答: 这工作

https://simple.svn.sourceforge.net/svnroot/simple/trunk/download/stream/src/test/java/org/simpleframework/xml/strategy/CommentTest.java

package org.simpleframework.xml.strategy; 

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

import org.simpleframework.xml.Default; 
import org.simpleframework.xml.Root; 
import org.simpleframework.xml.ValidationTestCase; 
import org.simpleframework.xml.core.Persister; 
import org.simpleframework.xml.stream.InputNode; 
import org.simpleframework.xml.stream.NodeMap; 
import org.simpleframework.xml.stream.OutputNode; 

public class CommentTest extends ValidationTestCase { 

    @Retention(RetentionPolicy.RUNTIME) 
    private static @interface Comment { 
     public String value(); 
    } 

    @Root 
    @Default 
    private static class CommentExample { 
     @Comment("This represents the name value") 
     private String name; 
     @Comment("This is a value to be used") 
     private String value; 
     @Comment("Yet another comment") 
     private Double price; 
    } 

    private static class CommentVisitor implements Visitor { 
     public void read(Type type, NodeMap<InputNode> node) throws Exception {} 
     public void write(Type type, NodeMap<OutputNode> node) throws Exception { 
     if(!node.getNode().isRoot()) { 
      Comment comment = type.getAnnotation(Comment.class); 
      if(comment != null) { 
       node.getNode().setComment(comment.value()); 
      } 
     } 
     } 
    } 

    public void testComment() throws Exception { 
     Visitor visitor = new CommentVisitor(); 
     Strategy strategy = new VisitorStrategy(visitor); 
     Persister persister = new Persister(strategy); 
     CommentExample example = new CommentExample(); 

     example.name = "Some Name"; 
     example.value = "A value to use"; 
     example.price = 9.99; 

     persister.write(example, System.out); 
    } 

} 

更新为2012-11-01 20:16

这是一个似乎得到预期的效果解决方法 - 在必要FieldHelper在(Get the value of a field, given the hierarchical path

/** 
    * write according to this visitor 
    */ 
    public void write(Type type, NodeMap<OutputNode> node) { 
     OutputNode element = node.getNode(); 
     Class ctype = type.getType(); 

     String comment = ctype.getName(); 
     if (!element.isRoot()) { 
      FieldHelper fh = new FieldHelper(); 
      element.setComment(comment); 
      try { 
       if (type.getClass().getSimpleName().startsWith("Override")) { 
        type = (Type) fh.getFieldValue(type, "type"); 
       } 
       if (type.getClass().getSimpleName().startsWith("Field")) { 
        Field field = (Field) fh.getFieldValue(type, "field"); 
        System.out.println(field.getName()); 
        Comment commentAnnotation = field.getAnnotation(Comment.class); 
        if (commentAnnotation != null) { 
         element.setComment(commentAnnotation.value()); 
        } 
       } 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

这是多远我这个有描述。不幸的是,它不能按预期工作。我写了一封电子邮件给Simpleframwork for XML的作者。

/** 
    * write according to this visitor 
    */ 
    public void write(Type type, NodeMap<OutputNode> node) { 
     OutputNode element = node.getNode(); 
     Class ctype = type.getType(); 

     String comment = ctype.getName(); 
     if (!element.isRoot()) { 
      Comment commentAnnotation = type.getAnnotation(Comment.class); 
      if (commentAnnotation!=null) 
       element.setComment(commentAnnotation.value()); 
      else 
       element.setComment(comment); 
     } 
    } 

    @Override 
    public void read(Type type, NodeMap<InputNode> nodeMap) throws Exception { 

    } 

} 

我声明的注释的注释这样的:

package com.bitplan.storage.simplexml; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
import java.lang.annotation.ElementType; 

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface Comment { 
String value(); 
} 

其然后可用这样的:

@Comment("this is the unique identifier") 
private long id; 

添加访问者是可能是这样的:

/** 
* get Serializer 
* 
* @return 
*/ 
public Serializer getSerializer() { 
    Serializer serializer = null; 
    Strategy strategy=null; 
    VisitorStrategy vstrategy=null; 
    if ((idname != null) && (refname != null)) { 
     strategy = new CycleStrategy(idname, refname); 
    } 
    CommentVisitor cv=new CommentVisitor(); 
    if (strategy==null) { 
     vstrategy=new VisitorStrategy(cv); 
    } else { 
     vstrategy=new VisitorStrategy(cv,strategy); 
    }  
    serializer = new Persister(vstrategy); 
    return serializer; 
} 
+0

谢谢,如果你能分享你的答案,如果你愿意,你会很酷你可以得到任何。 –

+0

自从sourceforge地址反弹后,我不得不将问题放在邮件列表中。您是否可以在另一篇文章中提出我的Fieldhelper答案 - 这是由编辑人员降低的,因为当我第一次发布它时,它已经有了我的公司网址。 –