Castor 中用 Integer 作为 Map key 的 bug

[Castor] 是一个 Java 的 XML binding 的工具,可以在 XML 和 Java Object 之间很方便地互相转换。现在在使用中发现了一个问题,如下所示:

  1. mapping.xml
  2.  
  3. <mapping>
  4.   <class name="com.Parent">
  5.     <map-to xml="parent" />
  6.     <field name="children" type="com.Child" collection="map">
  7.       <bind-xml name="child">
  8.       </bind-xml>
  9.     </field>
  10.   </class>
  11.  
  12.   <class name="com.Child" identity="id">
  13.     <map-to xml="child" />
  14.     <field name="id" type="java.lang.Integer">
  15.       <bind-xml name="id" node="attribute">
  16.       </bind-xml>
  17.     </field>
  18.   </class>
  19. </mapping>
  20.  
  21. test.xml
  22.  
  23. <?xml version="1.0"?>
  24.  
  25. <parent>
  26.   <child id="1"/>
  27.   <child id="2"/>
  28. </parent>
  29.  
  30. Parent.java :
  31.  
  32. package com;
  33.  
  34. import javax.xml.xpath.XPathFactory;
  35. import javax.xml.xpath.XPath;
  36. import javax.xml.xpath.XPathExpression;
  37. import javax.xml.xpath.XPathConstants;
  38.  
  39. import javax.xml.parsers.DocumentBuilder;
  40. import javax.xml.parsers.DocumentBuilderFactory;
  41.  
  42. import org.xml.sax.InputSource;
  43.  
  44. import org.w3c.dom.Document;
  45. import org.w3c.dom.Node;
  46. import org.w3c.dom.Element;
  47.  
  48. import org.exolab.castor.xml.Unmarshaller;
  49. import org.exolab.castor.mapping.Mapping;
  50. import org.exolab.castor.mapping.MappingException;
  51.  
  52. import java.io.InputStream;
  53. import java.util.Map;
  54. import java.util.HashMap;
  55.  
  56. public class Parent {
  57.  
  58.     private HashMap<Integer, Child> children;
  59.  
  60.     public Map<Integer, Child> getChildren() {
  61.         return children;
  62.     }
  63.  
  64.     public void setChildren(Map<Integer, Child> children) {
  65.         this.children = new HashMap<Integer, Child>(children);
  66.     }
  67.  
  68.     public void test() {
  69.         try {
  70.             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  71.             dbf.setValidating(false);
  72.             dbf.setNamespaceAware(true);
  73.  
  74.             XPathFactory factory = XPathFactory.newInstance();
  75.             XPath xpath = factory.newXPath();
  76.  
  77.             InputStream is = getClass().getResourceAsStream("/m.xml");
  78.             Mapping mapping = new Mapping(getClass().getClassLoader());
  79.             mapping.loadMapping(new InputSource(is));
  80.             Unmarshaller unmar = new Unmarshaller(mapping);
  81.             unmar.setIgnoreExtraElements(true);
  82.  
  83.             InputStream stream = getClass().getResourceAsStream("/t.xml");
  84.             DocumentBuilder builder = dbf.newDocumentBuilder();
  85.             Document doc = builder.parse(stream, "parent");
  86.             doc.getDocumentElement().normalize();
  87.  
  88.             String exprStr = "/parent";
  89.             XPathExpression expr = xpath.compile(exprStr);
  90.             Node node = (Node)expr.evaluate(doc, XPathConstants.NODE);
  91.  
  92.             Parent parent = (Parent)unmar.unmarshal((Element)node);
  93.             System.err.println(parent.getChildren());
  94.             for (Map.Entry entry : parent.getChildren().entrySet()) {
  95.                 System.err.println("key class = " + entry.getKey().getClass());
  96.             }
  97.  
  98.             Child child = parent.getChildren().get(1);
  99.             // Child with id 1 should be returned.
  100.             System.err.println("child 1 = " + child);
  101.         } catch (Exception e) {
  102.             e.printStackTrace();
  103.         }
  104.     }
  105.  
  106.     public static void main(String[] argv) {
  107.         Parent parent = new Parent();
  108.         parent.test();
  109.     }
  110. }
  111.  
  112. Child.java :
  113.  
  114. package com;
  115.  
  116. public class Child {
  117.     private int id;
  118.  
  119.     public int getId() {
  120.         return id;
  121.     }
  122.  
  123.     public void setId(int id) {
  124.         this.id = id;
  125.     }
  126. }
  127.  
  128. The Result is :
  129.  
  130.     [junit] ------------- Standard Error -----------------
  131.     [junit] {2=com.Child@6c585a, 1=com.Child@11ca803}
  132.     [junit] key class = class java.lang.String
  133.     [junit] key class = class java.lang.String
  134.     [junit] ------------- ---------------- ---------------

按理说作为 Map 的 key 应该是 java.lang.Integer,但是现在打出来的却是 java.lang.String,不知道是什么问题。已经看过[它的 HOWTO],但它会多加一层标签,和我想要的并不一致。由于没时间细看并提供补丁,只好先发了一个 [bug report],等开发者解决或者以后再看。现在只能先把 int 改成 String 先用着再说。

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • You can use BBCode tags in the text.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. The supported tag styles are: <foo>, [foo].
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
          ____    ____                        _____              _ 
_ _ | _ \ | _ \ _ __ _ __ ___ | ___| __ __ __| |
| | | | | |_) | | |_) | | '_ \ | '_ ` _ \ | |_ \ \/ / / _` |
| |_| | | __/ | __/ | | | | | | | | | | | _| > < | (_| |
\__,_| |_| |_| |_| |_| |_| |_| |_| |_| /_/\_\ \__,_|
Enter the code depicted in ASCII art style.