読者です 読者をやめる 読者になる 読者になる

HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

Simpleライブラリの検証(2)

Java XML

ざっくりと試してみたSimpleライブラリ。

いろいろと気になる点もあったので、ざくっと検証してみる。の続き。

要素名や属性名は「JavaBean標準」固定なのか

Lureクラスなら"lure"という風になるということだが、それ以外の形式は不可なのか。
そこで、SimpleライブラリのJavaDocチュートリアルを見てみると、CamelCaseStyleやHyphenStyleというのが利用可能らしい。ということで次の検証コードを作成。

import java.io.File;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import org.simpleframework.xml.stream.CamelCaseStyle;
import org.simpleframework.xml.stream.Format;
import org.simpleframework.xml.stream.HyphenStyle;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("=== new Persister() ===");
        try {
            Serializer serializer = new Persister();
            TestPojo testPojo = newTestPojo();

            File result = new File("data/main-default.xml");
            System.out.println("      " + result);
            serializer.write(testPojo, result);
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
        System.out.println("=== new Persister(new Format(new CamelCaseStyle())) ===");
        try {
            Serializer serializer = new Persister(new Format(new CamelCaseStyle()));
            TestPojo testPojo = newTestPojo();

            File result = new File("data/main-CamelCase.xml");
            System.out.println("      " + result);
            serializer.write(testPojo, result);
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
        System.out.println("=== new Persister(new Format(new CamelCaseStyle(false, true))) ===");
        try {
            Serializer serializer = new Persister(new Format(new CamelCaseStyle(false, true)));
            TestPojo testPojo = newTestPojo();

            File result = new File("data/main-CamelCaseR.xml");
            System.out.println("      " + result);
            serializer.write(testPojo, result);
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
        System.out.println("=== new Persister(new Format(new HyphenStyle())) ===");
        try {
            Serializer serializer = new Persister(new Format(new HyphenStyle()));
            TestPojo testPojo = newTestPojo();

            File result = new File("data/main-Hyphen.xml");
            System.out.println("      " + result);
            serializer.write(testPojo, result);
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }

        String[] styles = {
                "default",
                "CamelCase",
                "CamelCaseR",
                "Hyphen",
        };
        System.out.println("=== new Persister() ===");
        for (String style : styles) {
            System.out.println("    === " + style + " ===");
            try {
                Serializer serializer = new Persister();

                File source = new File("data/main-" + style + ".xml");
                System.out.println("      " + source);
                TestPojo testPojo = serializer.read(TestPojo.class, source);
                dumpTestPojo(testPojo);
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
        System.out.println("=== new Persister(new Format(new CamelCaseStyle())) ===");
        for (String style : styles) {
            System.out.println("    === " + style + " ===");
            try {
                Serializer serializer = new Persister(new Format(new CamelCaseStyle()));

                File source = new File("data/main-" + style + ".xml");
                System.out.println("      " + source);
                TestPojo testPojo = serializer.read(TestPojo.class, source);
                dumpTestPojo(testPojo);
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
        System.out.println("=== new Persister(new Format(new CamelCaseStyle(false, true))) ===");
        for (String style : styles) {
            System.out.println("    === " + style + " ===");
            try {
                Serializer serializer = new Persister(new Format(new CamelCaseStyle(false, true)));

                File source = new File("data/main-" + style + ".xml");
                System.out.println("      " + source);
                TestPojo testPojo = serializer.read(TestPojo.class, source);
                dumpTestPojo(testPojo);
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
        System.out.println("=== new Persister(new Format(new HyphenStyle())) ===");
        for (String style : styles) {
            System.out.println("    === " + style + " ===");
            try {
                Serializer serializer = new Persister(new Format(new HyphenStyle()));

                File source = new File("data/main-" + style + ".xml");
                System.out.println("      " + source);
                TestPojo testPojo = serializer.read(TestPojo.class, source);
                dumpTestPojo(testPojo);
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    }

    private static TestPojo newTestPojo() {
        TestPojo testPojo = new TestPojo();
        testPojo.setFirstElement("firstElement");
        testPojo.setSecondElement("SecondElement");
        testPojo.setThirdElement("THIRDELEMENT");
        testPojo.setFourthElement("fourth_element");
        testPojo.setFifthElement("Fifth_Element");
        testPojo.setSixthElement("SIXTH_ELEMENT");

        testPojo.setFirstAttribute("firstAttribute");
        testPojo.setSecondAttribute("SecondAttribute");
        testPojo.setThirdAttribute("THIRDATTRIBUTE");
        testPojo.setFourthAttribute("fourth_attribute");
        testPojo.setFifthAttribute("Fifth_Attribute");
        testPojo.setSixthAttribute("SIXTH_ATTRIBUTE");
        return testPojo;
    }

    private static void dumpTestPojo(TestPojo testPojo) {
        System.out.println("        firstElement:    " + testPojo.getFirstElement());
        System.out.println("        secondElement:   " + testPojo.getSecondElement());
        System.out.println("        thirdElement:    " + testPojo.getThirdElement());
        System.out.println("        fourthElement:   " + testPojo.getFourthElement());
        System.out.println("        fifthElement:    " + testPojo.getFifthElement());
        System.out.println("        firstAttribute:  " + testPojo.getFirstAttribute());
        System.out.println("        secondAttribute: " + testPojo.getSecondAttribute());
        System.out.println("        thirdAttribute:  " + testPojo.getThirdAttribute());
        System.out.println("        fourthAttribute: " + testPojo.getFourthAttribute());
        System.out.println("        fifthAttribute:  " + testPojo.getFifthAttribute());
    }

}

Persisterクラスのコンストラクタに渡すFormatオブジェクトには、Styleオブジェクトを渡すことができる。Styleを何も渡さなければ「JavaBean標準」になるし、CamelCaseStyleオブジェクトやHyphenStyleオブジェクトを渡せば指定したとおりの動作になる。また、CamelCaseStyleでは要素名と属性名のそれぞれに対して先頭の文字を大文字にするか小文字にするかをコンストラクタの引数によって設定することができる。引数なしのコンストラクタでは要素名は大文字、属性名は小文字ということなので、「new CamelCaseStyle(false, true)」を使って要素名が小文字、属性名が大文字のケースも実行してみる。
TestPojoクラスは次のとおり。

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

@Root
public class TestPojo {

    @Element
    private String firstElement;

    @Element
    private String SecondElement;

    @Element
    private String THIRDELEMENT;

    @Element
    private String fourth_element;

    @Element
    private String Fifth_Element;

    @Element
    private String SIXTH_ELEMENT;

    @Attribute
    private String firstAttribute;

    @Attribute
    private String SecondAttribute;

    @Attribute
    private String THIRDATTRIBUTE;

    @Attribute
    private String fourth_attribute;

    @Attribute
    private String Fifth_Attribute;

    @Attribute
    private String SIXTH_ATTRIBUTE;

    public String getFirstElement() {
        return firstElement;
    }

    public void setFirstElement(String firstElement) {
        this.firstElement = firstElement;
    }

    public String getSecondElement() {
        return SecondElement;
    }

    public void setSecondElement(String secondElement) {
        this.SecondElement = secondElement;
    }

    public String getThirdElement() {
        return THIRDELEMENT;
    }

    public void setThirdElement(String thirdElement) {
        this.THIRDELEMENT = thirdElement;
    }

    public String getFourthElement() {
        return fourth_element;
    }

    public void setFourthElement(String fourthElement) {
        this.fourth_element = fourthElement;
    }

    public String getFifthElement() {
        return Fifth_Element;
    }

    public void setFifthElement(String fifthElement) {
        this.Fifth_Element = fifthElement;
    }

    public String getSixthElement() {
        return SIXTH_ELEMENT;
    }

    public void setSixthElement(String sixthElement) {
        this.SIXTH_ELEMENT = sixthElement;
    }

    public String getFirstAttribute() {
        return firstAttribute;
    }

    public void setFirstAttribute(String firstAttribute) {
        this.firstAttribute = firstAttribute;
    }

    public String getSecondAttribute() {
        return SecondAttribute;
    }
    public void setSecondAttribute(String secondAttribute) {

        this.SecondAttribute = secondAttribute;
    }

    public String getThirdAttribute() {
        return THIRDATTRIBUTE;
    }

    public void setThirdAttribute(String thirdAttribute) {
        this.THIRDATTRIBUTE = thirdAttribute;
    }

    public String getFourthAttribute() {
        return fourth_attribute;
    }

    public void setFourthAttribute(String fourthAttribute) {
        this.fourth_attribute = fourthAttribute;
    }

    public String getFifthAttribute() {
        return Fifth_Attribute;
    }

    public void setFifthAttribute(String fifthAttribute) {
        this.Fifth_Attribute = fifthAttribute;
    }

    public String getSixthAttribute() {
        return SIXTH_ATTRIBUTE;
    }

    public void setSixthAttribute(String sixthAttribute) {
        this.SIXTH_ATTRIBUTE = sixthAttribute;
    }

}

それぞれのスタイルでどのような変換が行われるのかを見るために、6つのパターンのフィールド名を持っている。中にはインスタンスフィールド名としては不適切だ、というものも含まれている。
これを実行してみると、次のファイルが生成される。

  • main-default.xml
  • main-CamelCase.xml
  • main-CamelCaseR.xml
  • main-Hyphen.xml

その内容そのものはここでは割愛するとして、それぞれのスタイルで要素名、属性名がどんな風になったのかを表にしてみた。

= =default =CamelCase(true) =CamelCase(false) =Hyphen
クラス名(TestPojo) testPojo TestPojo testPojo test-pojo
firstElement firstElement FirstElement firstElement first-element
SecondElement SecondElement SecondElement SecondElement second-element
THIRDELEMENT THIRDELEMENT THIRDELEMENT THIRDELEMENT THIRDELEMENT
fourth_element fourth_element FourthElement fourthelement fourth-element
Fifth_Element Fifth_Element FifthElement FifthElement fifth-element
SIXTH_ELEMENT SIXTH_ELEMENT SIXTHELEMENT SIXTHELEMENT SIXT-h-ELEMENT
firstAttribute firstAttribute FirstAttribute firstAttribute first-attribute
SecondAttribute SecondAttribute SecondAttribute SecondAttribute second-attribute
THIRDATTRIBUTE THIRDATTRIBUTE THIRDATTRIBUTE THIRDATTRIBUTE THIRDATTRIBUTE
fourth_attribute fourth_attribute FourthAttribute fourthattribute fourth-attribute
Fifth_Attribute Fifth_Attribute FifthAttribute FifthAttribute fifth-attribute
SIXTH_ATTRIBUTE SIXTH_ATTRIBUTE SIXTHATTRIBUTE SIXTHATTRIBUTE SIXT-h-ATTRIBUTE

"SIXTH_ELEMENT"、"SIXTH_ATTRIBUTE"だけが予想の範囲外の動作。まぁ、インスタンスフィールド名としては使用しないパターンだからいいんだけど。

また、実行結果のコンソール出力は次のような感じ。

=== new Persister() ===
      data\main-default.xml
=== new Persister(new Format(new CamelCaseStyle())) ===
      data\main-CamelCase.xml
=== new Persister(new Format(new CamelCaseStyle(false, true))) ===
      data\main-CamelCaseR.xml
=== new Persister(new Format(new CamelCaseStyle(true, false))) ===
      data\main-CamelCase2.xml
=== new Persister(new Format(new HyphenStyle())) ===
      data\main-Hyphen.xml
=== new Persister() ===
    === default ===
      data\main-default.xml
        firstElement:    firstElement
        secondElement:   SecondElement
        thirdElement:    THIRDELEMENT
        fourthElement:   fourth_element
        fifthElement:    Fifth_Element
        firstAttribute:  firstAttribute
        secondAttribute: SecondAttribute
        thirdAttribute:  THIRDATTRIBUTE
        fourthAttribute: fourth_attribute
        fifthAttribute:  Fifth_Attribute
    === CamelCase ===
      data\main-CamelCase.xml
org.simpleframework.xml.core.AttributeException: Attribute 'fourthattribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === CamelCaseR ===
      data\main-CamelCaseR.xml
org.simpleframework.xml.core.AttributeException: Attribute 'FirstAttribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === Hyphen ===
      data\main-Hyphen.xml
org.simpleframework.xml.core.AttributeException: Attribute 'first-attribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
=== new Persister(new Format(new CamelCaseStyle())) ===
    === default ===
      data\main-default.xml
org.simpleframework.xml.core.AttributeException: Attribute 'fourth_attribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === CamelCase ===
      data\main-CamelCase.xml
        firstElement:    firstElement
        secondElement:   SecondElement
        thirdElement:    THIRDELEMENT
        fourthElement:   fourth_element
        fifthElement:    Fifth_Element
        firstAttribute:  firstAttribute
        secondAttribute: SecondAttribute
        thirdAttribute:  THIRDATTRIBUTE
        fourthAttribute: fourth_attribute
        fifthAttribute:  Fifth_Attribute
    === CamelCaseR ===
      data\main-CamelCaseR.xml
org.simpleframework.xml.core.AttributeException: Attribute 'FirstAttribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === Hyphen ===
      data\main-Hyphen.xml
org.simpleframework.xml.core.AttributeException: Attribute 'first-attribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
=== new Persister(new Format(new CamelCaseStyle(false, true))) ===
    === default ===
      data\main-default.xml
org.simpleframework.xml.core.AttributeException: Attribute 'firstAttribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === CamelCase ===
      data\main-CamelCase.xml
org.simpleframework.xml.core.AttributeException: Attribute 'firstAttribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === CamelCaseR ===
      data\main-CamelCaseR.xml
        firstElement:    firstElement
        secondElement:   SecondElement
        thirdElement:    THIRDELEMENT
        fourthElement:   fourth_element
        fifthElement:    Fifth_Element
        firstAttribute:  firstAttribute
        secondAttribute: SecondAttribute
        thirdAttribute:  THIRDATTRIBUTE
        fourthAttribute: fourth_attribute
        fifthAttribute:  Fifth_Attribute
    === Hyphen ===
      data\main-Hyphen.xml
org.simpleframework.xml.core.AttributeException: Attribute 'first-attribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
=== new Persister(new Format(new HyphenStyle())) ===
    === default ===
      data\main-default.xml
org.simpleframework.xml.core.AttributeException: Attribute 'firstAttribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === CamelCase ===
      data\main-CamelCase.xml
org.simpleframework.xml.core.AttributeException: Attribute 'firstAttribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === CamelCaseR ===
      data\main-CamelCaseR.xml
org.simpleframework.xml.core.AttributeException: Attribute 'FirstAttribute' does not exist at line -1
    at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511)
        :
    === Hyphen ===
      data\main-Hyphen.xml
        firstElement:    firstElement
        secondElement:   SecondElement
        thirdElement:    THIRDELEMENT
        fourthElement:   fourth_element
        fifthElement:    Fifth_Element
        firstAttribute:  firstAttribute
        secondAttribute: SecondAttribute
        thirdAttribute:  THIRDATTRIBUTE
        fourthAttribute: fourth_attribute
        fifthAttribute:  Fifth_Attribute

見るとわかるとおり、write時のスタイルとread時のスタイルは同じでないと読み込みに失敗する。まぁ、これはどんなライブラリ/ツールを使ってもそうだろう。想定している要素が存在しなければ当然エラーにすべき。


ライブラリで提供されていないケースを要素名や属性名に対して適用したい場合は独自のスタイル(Styleインタフェースの実装)を作ればいいので、拡張性はあるといえる。