/*
 * XmlResourceTest class.
 *
 * Copyright (C) 2007 SATOH Takayuki All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package ts.util.resource;

import ts.tester.function.coverage.FunctionTester;
import ts.tester.function.print.*;
import java.io.*;
import java.util.*;
import java.text.*;
import org.w3c.dom.*;

/**
 * <code>XmlResource</code>クラスの機能試験クラス。
 *
 * @author  佐藤隆之. 
 * @version $Revision: 1.3 $, $Date: 2010-11-14 11:51:02 $
 */
public class XmlResourceTest extends FunctionTester
{
  public static void main(String[] args)
  {
    try {
      PrinterGroup group = new PrinterGroup();
      group.addPrinter(new ConsolePrinter());
      group.addPrinter(new HtmlPrinter("SATOH Takayuki"));
      setPrinter(group);

      run(XmlResourceTest.class, (args.length == 0) ? null : args[0]);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /* -- test case -- */

  public void constructor()
  {
    MSG("通常の場合");

    XmlResource res = new XmlResource();
    NOTNULL(res);
    NOTNULL(res.getDocument());
    EQUAL(res.getBaseNode(), res.getDocument());
    NULL(res.getPath());
  }

  public void constructor_path()
  {
    MSG("通常の場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample.xml";
    try {
      XmlResource res = new XmlResource(PATH);
      NOTNULL(res.getDocument());
      /*
      EQUAL(res.getBaseNode(), res.getDocument());
      */
      EQUAL(res.getPath(), PATH);
      OK();
    } catch (Exception e) {
      NG(e);
    }
  }

  public void constructor_path_1()
  {
    MSG("存在しないファイルを指定した場合");

    final String PATH2 = "test/sample.xml";
    try {
      XmlResource res = new XmlResource(PATH2);
      NG();
    } catch (FileNotFoundException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void constructor_path_2()
  {
    MSG("引数がヌルの場合");

    try {
      XmlResource res = new XmlResource((String) null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void load_path()
  {
    final String PATH = "test/data/ts/util/resource/XmlResource/sample.xml";

    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
      NOTNULL(res.getDocument());
      EQUAL(res.getBaseNode(), res.getDocument());
      OK();
    } catch (Exception e) {
      NG(e);
    }

    final String PATH2 = "test/sample.xml";
    try {
      res.load(PATH2);
      NG();
    } catch (FileNotFoundException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void load_path_1()
  {
    MSG("書式の不正なXMLファイルをロードした場合");

    XmlResource res = new XmlResource();

    final String PATH = "test/data/ts/util/resource/XmlResource/sample5.xml";
    try {
      res.load(PATH);
      NG();
    } catch (IOException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void copy_constructor()
  {
    MSG("コピーコンストラクタ");

    XmlResource res = new XmlResource();
    NOTNULL(res.getDocument());
    EQUAL(res.getBaseNode(), res.getDocument());
    NULL(res.getPath());

    XmlResource copyRes = new XmlResource(res);
    EQUAL(copyRes.getDocument(), res.getDocument());
    EQUAL(copyRes.getBaseNode(), res.getBaseNode());
    NULL(copyRes.getPath());

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    NOTNULL(res.getDocument());
    EQUAL(res.getBaseNode(), res.getDocument());
    EQUAL(res.getPath(), PATH);
    EQUAL(res.getFirstValue("sample.title"), "タイトル");
    FALSE(copyRes.getDocument().equals(res.getDocument()));
    FALSE(copyRes.getBaseNode().equals(res.getBaseNode()));
    NULL(copyRes.getPath());
    EQUAL(copyRes.getFirstValue("sample.title"), "");

    copyRes = new XmlResource(res);
    NOTNULL(res.getDocument());
    EQUAL(res.getBaseNode(), res.getDocument());
    EQUAL(res.getPath(), PATH);
    EQUAL(res.getFirstValue("sample.title"), "タイトル");
    EQUAL(copyRes.getDocument(), res.getDocument());
    EQUAL(copyRes.getBaseNode(), res.getBaseNode());
    EQUAL(copyRes.getPath(), PATH);
    EQUAL(copyRes.getFirstValue("sample.title"), "タイトル");
  }

  public void shortenWhitespace()
  {
    MSG("通常の操作の場合");

    XmlResource res = new XmlResource();
    EQUAL(res.shortenWhitespace("abc"), "abc");
    EQUAL(res.shortenWhitespace("a b c"), "a b c");
    EQUAL(res.shortenWhitespace(" a b c "), "a b c");
    EQUAL(res.shortenWhitespace("  a        b  \n c   "), "a b c");
    EQUAL(res.shortenWhitespace("  a\t\t\t\tb\n\nc   "), "a b c");
  }

  public void shortenWhitespace_1()
  {
    MSG("引数がヌルの場合");

    XmlResource res = new XmlResource();
    try {
      res.shortenWhitespace(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void shortenWhitespace_2()
  {
    MSG("引数が空文字列の場合");

    XmlResource res = new XmlResource();
    EQUAL(res.shortenWhitespace(""), "");
  }

  public void shortenWhitespace_3()
  {
    MSG("引数が空白文字だけの場合");

    XmlResource res = new XmlResource();
    EQUAL(res.shortenWhitespace(" "), "");
    EQUAL(res.shortenWhitespace("         "), "");
  }

  public void findFirstNode()
  {
    MSG("通常の操作の場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getBaseNode(), res.getDocument());
    EQUAL(res.getBaseNode().getNodeName(), "#document");
    EQUAL(res.findFirstNode("sample").getNodeName(), "sample");
    EQUAL(res.findFirstNode("sample.title").getNodeName(), "title");
  }

  public void findFirstNode_0()
  {
    MSG("存在しないキーの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    NULL(res.findFirstNode("example"));
    NULL(res.findFirstNode("sample.header"));
  }

  public void findFirstNode_1()
  {
    MSG("キーが空文字列の場合");
    
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.findFirstNode(""), res.getBaseNode());
    EQUAL(res.findFirstNode("").getNodeName(), "#document");
  }

  public void findFirstNode_2()
  {
    MSG("引数がヌルの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.findFirstNode(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void findFirstNode_3()
  {
    MSG("属性を持つキーの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.findFirstNode("sample.body(type=typeA)").getNodeName(), "body");
    EQUAL(res.findFirstNode("sample.body.a(id=a1)").getNodeName(), "a");
    EQUAL(res.findFirstNode("sample.body.b(id=b1)").getNodeName(), "b");
    EQUAL(res.findFirstNode("sample.body.c(id=c1)").getNodeName(), "c");
  }

  public void findFirstNode_4()
  {
    MSG("一つの要素に属性が複数ある場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.findFirstNode("sample.body.a(id=a1,name=A1)").getNodeName(), "a");
    EQUAL(res.findFirstNode("sample.body.b(name=B2,id=b2)").getNodeName(), "b");
    EQUAL(res.findFirstNode("sample.body.c(id=c1,name=C1)").getNodeName(), "c");

    NULL(res.findFirstNode("sample.body.a(id=a1,name=A2)"));
    NULL(res.findFirstNode("sample.body.b(name=B1,id=b2)"));
    NULL(res.findFirstNode("sample.body.c(id=c1,name=C2)"));
  }

  public void findFirstNode_5()
  {
    MSG("属性のない要素に対して属性をもつキーを指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    NULL(res.findFirstNode("sample.title(id=TTT)"));
  }

  public void findFirstNode_6()
  {
    MSG("不正なキーを指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    try {
      res.findFirstNode("sample.");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.findFirstNode("sample.body(");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void findFirstNode_7()
  {
    MSG("空のリソースの場合");
    XmlResource res = new XmlResource();
    NULL(res.findFirstNode("sample.title"));
  }

  public void findFirstNode_8()
  {
    MSG("キーの中に*が存在する場合");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }
    EQUAL(res.findFirstNode("*").getNodeName(), "sample");
    EQUAL(res.findFirstNode("sample.*").getNodeName(), "title");
    EQUAL(res.findFirstNode("sample.body.*").getNodeName(), "a");
    EQUAL(res.findFirstNode("sample.body.*(id=a1)").getNodeName(), "a");
    EQUAL(res.findFirstNode("sample.body.*(id=b1)").getNodeName(), "b");
    EQUAL(res.findFirstNode("sample.body.*(id=b2)").getNodeName(), "b");
    EQUAL(res.findFirstNode("sample.body.*(id=c1)").getNodeName(), "c");
    EQUAL(res.findFirstNode("sample.body.*(id=c2)").getNodeName(), "c");
  }

  public void getNodeText()
  {
    MSG("通常の操作");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.getNodeText(res.getBaseNode()), "");
    EQUAL(res.getNodeText(res.findFirstNode("")), "");

    EQUAL(res.getNodeText(res.findFirstNode("sample")), "");
    EQUAL(res.getNodeText(res.findFirstNode("sample.title")), "タイトル");
    EQUAL(res.getNodeText(res.findFirstNode("sample.body")), "本文。");

    EQUAL(res.getNodeText(res.findFirstNode("sample.body.a")), "あ");
    EQUAL(res.getNodeText(res.findFirstNode("sample.body.a(id=b1)")), "");

    EQUAL(res.getNodeText(res.findFirstNode("sample.body.b")), "び");
    EQUAL(res.getNodeText(res.findFirstNode("sample.body.b(id=b1)")), "び");
    EQUAL(res.getNodeText(res.findFirstNode("sample.body.b(id=b2)")), "びび");
    EQUAL(res.getNodeText(res.findFirstNode("sample.body.b(id=b5)")), "");

    EQUAL(res.getNodeText(res.findFirstNode("sample.body.c")), "し");
    EQUAL(res.getNodeText(res.findFirstNode("sample.body.c(id=c1)")), "し");
    EQUAL(res.getNodeText(res.findFirstNode("sample.body.c(id=c2)")), "しし");
    EQUAL(res.getNodeText(res.findFirstNode("sample.body.c(id=c6)")), "");
  }

  public void getNodeText_0()
  {
    MSG("CDATAセクションの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.getNodeText(res.findFirstNode("sample.body.c(id=c3)")),
      "\n   あい  う え    お\n   ");
  }

  public void getNodeText_1()
  {
    MSG("引数がヌルの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.getNodeText(null), "");
  }

  public void getNodeText_2()
  {
    MSG("引数が空の要素の場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.getNodeText(res.findFirstNode("sample.body.b(id=b3)")), "");
  }

  public void getNodeText_3()
  {
    MSG("引数が複数のテキスト要素から成る場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample4.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.getNodeText(res.findFirstNode("sample.body.d(id=d1)")),
      "あいうえお  かきく  けこ  なにぬねの");
  }

  public void getFirstValue()
  {
    MSG("通常の操作");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample4.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.getFirstValue(""), "");
    EQUAL(res.getFirstValue("sample.title"), "タイトル");
    EQUAL(res.getFirstValue("sample.body"), "本文。");
    EQUAL(res.getFirstValue("sample.body.a"), "あ");
    EQUAL(res.getFirstValue("sample.body.b"), "び");
    EQUAL(res.getFirstValue("sample.body.c"), "し");
    EQUAL(res.getFirstValue("sample.body.d"),
      "あいうえお  かきく  けこ  なにぬねの");
  }

  public void getFirstValue_0()
  {
    MSG("キーが属性を持つ場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample4.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {}

    EQUAL(res.getFirstValue("sample.body(type=typeA)"), "本文。");
    EQUAL(res.getFirstValue("sample.body.a(id=a1)"), "あ");
    EQUAL(res.getFirstValue("sample.body.a(name=A1)"), "あ");
    EQUAL(res.getFirstValue("sample.body.b(id=b1)"), "び");
    EQUAL(res.getFirstValue("sample.body.b(id=b2)"), "びび");
    EQUAL(res.getFirstValue("sample.body.b(id=b3)"), "");
    EQUAL(res.getFirstValue("sample.body.c(id=c1)"), "し");
    EQUAL(res.getFirstValue("sample.body.c(id=c2)"), "しし");
    EQUAL(res.getFirstValue("sample.body.c(id=c3)"),
      "\n   あい  う え    お\n   ");
    EQUAL(res.getFirstValue("sample.body.d(id=d1)"),
      "あいうえお  かきく  けこ  なにぬねの");
    EQUAL(res.getFirstValue("sample.body.d.e(id=e1)"), "さしすせそ");
    EQUAL(res.getFirstValue("sample.body.d.e(id=e2)"), "たちつてと");
  }

  public void getFirstValue_1()
  {
    MSG("引数がヌルの場合");

    XmlResource res = new XmlResource();
    try {
      res.getFirstValue(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getFirstValue_2()
  {
    MSG("存在しないキーを指定した場合");

    XmlResource res = new XmlResource();
    EQUAL(res.getFirstValue("AAAA.BBBB.CCCC"), "");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample4.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getFirstValue("AAAA.BBBB.CCCC"), "");
  }

  public void getFirstValue_3()
  {
    MSG("子リソースに対して実行した場合");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample4.xml";

    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }
    
    Resource res2 = res.getFirstChild("sample.body");
    EQUAL(res2.getFirstValue(""), "本文。");
    EQUAL(res2.getFirstValue("a"), "あ");
    EQUAL(res2.getFirstValue("b"), "び");
    EQUAL(res2.getFirstValue("c"), "し");
    EQUAL(res2.getFirstValue("d"),
      "あいうえお  かきく  けこ  なにぬねの");
    EQUAL(res2.getFirstValue("a(id=a1)"), "あ");
    EQUAL(res2.getFirstValue("a(name=A1)"), "あ");
    EQUAL(res2.getFirstValue("b(id=b1)"), "び");
    EQUAL(res2.getFirstValue("b(id=b2)"), "びび");
    EQUAL(res2.getFirstValue("b(id=b3)"), "");
    EQUAL(res2.getFirstValue("c(id=c1)"), "し");
    EQUAL(res2.getFirstValue("c(id=c2)"), "しし");
    EQUAL(res2.getFirstValue("c(id=c3)"),
      "\n   あい  う え    お\n   ");
    EQUAL(res2.getFirstValue("d(id=d1)"),
      "あいうえお  かきく  けこ  なにぬねの");
    EQUAL(res2.getFirstValue("d.e(id=e1)"), "さしすせそ");
    EQUAL(res2.getFirstValue("d.e(id=e2)"), "たちつてと");
  }

  public void getFirstValue_4()
  {
    MSG("キーに*が含まれている場合");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }
    EQUAL(res.getFirstValue("sample.*(type=typeA)"), "本文。");
    EQUAL(res.getFirstValue("*.*(type=typeA)"), "本文。");
    EQUAL(res.getFirstValue("*.body(type=typeA)"), "本文。");
    EQUAL(res.getFirstValue("*.*.*(id=a1)"), "あ");
    EQUAL(res.getFirstValue("*.body.a(id=a1)"), "あ");
    EQUAL(res.getFirstValue("sample.*.a(id=a1)"), "あ");
    EQUAL(res.getFirstValue("sample.body.*(id=a1)"), "あ");
  }

  public void findAllNodes()
  {
    MSG("通常の操作");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<Node> elemLst = res.findAllNodes("");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "#document");
    EQUAL(elemLst.get(0), res.getBaseNode());

    elemLst = res.findAllNodes("sample");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "sample");

    elemLst = res.findAllNodes("sample.title");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "title");

    elemLst = res.findAllNodes("sample.body.a");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "a");

    elemLst = res.findAllNodes("sample.body.b");
    EQUAL(elemLst.size(), 3);
    EQUAL(elemLst.get(0).getNodeName(), "b");
    EQUAL(elemLst.get(1).getNodeName(), "b");
    EQUAL(elemLst.get(2).getNodeName(), "b");

    elemLst = res.findAllNodes("sample.body.c");
    EQUAL(elemLst.size(), 3);
    EQUAL(elemLst.get(0).getNodeName(), "c");
    EQUAL(elemLst.get(1).getNodeName(), "c");
    EQUAL(elemLst.get(2).getNodeName(), "c");
  }

  public void findAllNodes_1()
  {
    MSG("引数がヌルの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.findAllNodes(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void findAllNodes_2()
  {
    MSG("引数が空文字列の場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<Node> elemLst = res.findAllNodes("");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0), res.getBaseNode());
  }

  public void findAllNodes_3()
  {
    MSG("存在しないキーの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<Node> elemLst = res.findAllNodes("abc");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.bb");
    EQUAL(elemLst.size(), 0);
  }

  public void findAllNode_4()
  {
    MSG("属性を持つキーの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<Node> elemLst = res.findAllNodes("sample.body(type=typeA)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "body");

    elemLst = res.findAllNodes("sample.body(type=typeB)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.a(id=a1)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "a");

    elemLst = res.findAllNodes("sample.body.a(id=a2)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.b(id=b1)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "b");

    elemLst = res.findAllNodes("sample.body.b(id=b2)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "b");

    elemLst = res.findAllNodes("sample.body.b(id=b3)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "b");

    elemLst = res.findAllNodes("sample.body.b(id=b4)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.c(id=c1)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "c");

    elemLst = res.findAllNodes("sample.body.c(id=c2)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "c");

    elemLst = res.findAllNodes("sample.body.c(id=c3)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "c");

    elemLst = res.findAllNodes("sample.body.c(id=c4)");
    EQUAL(elemLst.size(), 0);
  }

  public void findAllNode_5()
  {
    MSG("一つの要素の属性が複数ある場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<Node> elemLst;

    elemLst = res.findAllNodes("sample.body.a(id=a1,name=A1)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "a");

    elemLst = res.findAllNodes("sample.body.a(id=a1, name=A1)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.a(id=a1, name =A1)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.a(id=a1,name= A1)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.a(id=a1,name=A1 )");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.a(id=a1,name=A2)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.a(id=a2,name=A1)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.b(id=b1,name=B1)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "b");

    elemLst = res.findAllNodes("sample.body.b(id=b1,name=B2)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.b(id=b2,name=B1)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.c(id=c1,name=C1)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "c");

    elemLst = res.findAllNodes("sample.body.c(id=c1,name=C2)");
    EQUAL(elemLst.size(), 0);

    elemLst = res.findAllNodes("sample.body.c(id=c2,name=C1)");
    EQUAL(elemLst.size(), 0);
  }

  public void findAllNodes_6()
  {
    MSG("不正なキーの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    try {
      List<Node> elemLst = res.findAllNodes("sample.body.a(id=a1");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void findAllNodes_7()
  {
    MSG("空のリソースの場合");

    XmlResource res = new XmlResource();
    List<Node> elemLst = res.findAllNodes("sample.title");
    EQUAL(elemLst.size(), 0);
  }

  public void findAllNodes_8()
  {
    MSG("キーに*が含まれている場合");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }
    List<Node> elemLst;
    elemLst = res.findAllNodes("*");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "sample");
    elemLst = res.findAllNodes("sample.*");
    EQUAL(elemLst.size(), 2);
    EQUAL(elemLst.get(0).getNodeName(), "title");
    EQUAL(elemLst.get(1).getNodeName(), "body");
    elemLst = res.findAllNodes("sample.body.*");
    EQUAL(elemLst.size(), 7);
    EQUAL(elemLst.get(0).getNodeName(), "a");
    EQUAL(elemLst.get(1).getNodeName(), "b");
    EQUAL(elemLst.get(2).getNodeName(), "b");
    EQUAL(elemLst.get(3).getNodeName(), "b");
    EQUAL(elemLst.get(4).getNodeName(), "c");
    EQUAL(elemLst.get(5).getNodeName(), "c");
    EQUAL(elemLst.get(6).getNodeName(), "c");
    elemLst = res.findAllNodes("sample.body.*(id=a1)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "a");
    elemLst = res.findAllNodes("sample.body.*(id=b1)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "b");
    elemLst = res.findAllNodes("sample.body.*(id=c2)");
    EQUAL(elemLst.size(), 1);
    EQUAL(elemLst.get(0).getNodeName(), "c");
  }

  public void getValues()
  {
    MSG("通常の場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<String> lst = res.getValues("sample.title");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "タイトル");

    lst = res.getValues("sample.body");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "本文。");

    lst = res.getValues("sample.body.a");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "あ");

    lst = res.getValues("sample.body.b");
    EQUAL(lst.size(), 3);
    EQUAL(lst.get(0), "び");
    EQUAL(lst.get(1), "びび");
    EQUAL(lst.get(2), "");

    lst = res.getValues("sample.body.b(name=B2)");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "びび");

    lst = res.getValues("sample.body.c(id=c3)");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "\n   あい  う え    お\n   ");
  }

  public void getValues_1()
  {
    MSG("引数がヌルの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.getValues(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getValues_2()
  {
    MSG("引数が空文字列の場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<String> lst = res.getValues("");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "");
  }

  public void getValue_3()
  {
    MSG("存在しないキーを指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<String> lst = res.getValues("sample.aaa");
    EQUAL(lst.size(), 0);

    lst = res.getValues("sample.body.a(id=a4)");
    EQUAL(lst.size(), 0);
  }

  public void getValues_4()
  {
    MSG("キーに*が含まれている場合");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }
    List<String> lst = res.getValues("sample.body.*");
    EQUAL(lst.size(), 7);
    EQUAL(lst.get(0), "あ");
    EQUAL(lst.get(1), "び");
    EQUAL(lst.get(2), "びび");
    EQUAL(lst.get(3), "");
    EQUAL(lst.get(4), "し");
    EQUAL(lst.get(5), "しし");
    EQUAL(lst.get(6), "\n   あい  う え    お\n   ");

    lst = res.getValues("sample.body.*(id=a1)");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "あ");
    lst = res.getValues("sample.body.*(id=b1)");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "び");
    lst = res.getValues("sample.body.*(id=c2)");
    EQUAL(lst.size(), 1);
    EQUAL(lst.get(0), "しし");
  }

  public void findOrCreateFirstNode()
  {
    MSG("通常の操作の場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    Node e = res.findOrCreateFirstNode("sample.title");
    EQUAL(e.getNodeName(), "title");
    EQUAL(res.getNodeText(e), "タイトル");

    e = res.findOrCreateFirstNode("sample.header");
    EQUAL(e.getNodeName(), "header");
    EQUAL(res.getNodeText(e), "");

    e = res.findFirstNode("sample.header");
    EQUAL(e.getNodeName(), "header");
    EQUAL(res.getNodeText(e), "");
  }

  public void findOrCreateFirstNode_1()
  {
    MSG("キーが空文字列の場合");

    XmlResource res = new XmlResource();
    EQUAL(res.findOrCreateFirstNode(""), res.getBaseNode());

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    Node e = res.findOrCreateFirstNode("");
    EQUAL(e, res.getBaseNode());
    EQUAL(res.getNodeText(e), "");
  }

  public void findOrCreateFirstNode_2()
  {
    MSG("キーが属性を含む場合");

    XmlResource res = new XmlResource();
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    Node e = res.findOrCreateFirstNode("sample.body(type=typeA)");
    EQUAL(e.getNodeName(), "body");
    EQUAL(res.getNodeText(e), "本文。");

    e = res.findOrCreateFirstNode("sample.header(id=H)");
    EQUAL(e.getNodeName(), "header");
    EQUAL(res.getNodeText(e), "");

    e = res.findFirstNode("sample.header(id=H)");
    EQUAL(e.getNodeName(), "header");
    EQUAL(res.getNodeText(e), "");
  }

  public void findOrCreateFirstNode_3()
  {
    MSG("キーが不正な場合");

    XmlResource res = new XmlResource();
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    try {
      Node e = res.findOrCreateFirstNode("sample.");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void setFirstValue()
  {
    MSG("通常の場合");
    
    XmlResource res = new XmlResource();
    EQUAL(res.getFirstValue("sample.aaa"), "");
    EQUAL(res.getFirstValue("sample.bbb"), "");
    
    res.setFirstValue("sample.aaa", "あいうえお");
    EQUAL(res.getFirstValue("sample.aaa"), "あいうえお");
    EQUAL(res.getFirstValue("sample.bbb"), "");

    res.setFirstValue("sample.bbb", "かきくけこ");
    EQUAL(res.getFirstValue("sample.aaa"), "あいうえお");
    EQUAL(res.getFirstValue("sample.bbb"), "かきくけこ");

    res.setFirstValue("sample.aaa", "   あい  うえ    お");
    EQUAL(res.getFirstValue("sample.aaa"),  "   あい  うえ    お");
    EQUAL(res.getFirstValue("sample.bbb"), "かきくけこ");

    res.setFirstValue("sample.aaa", "");
    EQUAL(res.getFirstValue("sample.aaa"), "");
    EQUAL(res.getFirstValue("sample.bbb"), "かきくけこ");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getFirstValue("sample.title"), "タイトル");
    EQUAL(res.getFirstValue("sample.aaa"), "");
    EQUAL(res.getFirstValue("sample.bbb"), "");

    res.setFirstValue("sample.title", "あかさたな");
    EQUAL(res.getFirstValue("sample.title"), "あかさたな");
    EQUAL(res.getFirstValue("sample.aaa"), "");
    EQUAL(res.getFirstValue("sample.bbb"), "");

    res.setFirstValue("sample.title", "");
    EQUAL(res.getFirstValue("sample.title"), "");
    EQUAL(res.getFirstValue("sample.aaa"), "");
    EQUAL(res.getFirstValue("sample.bbb"), "");
  }

  public void setFirstValue_0()
  {
    MSG("引数がヌルの場合");

    XmlResource res = new XmlResource();
    try {
      res.setFirstValue(null, null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.setFirstValue(null, "あいうえお");
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.setFirstValue("sample.aaa", null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void setFirstValue_1()
  {
    MSG("引数が空の場合");

    XmlResource res = new XmlResource();
    EQUAL(res.getFirstValue(""), "");

    try {
      res.setFirstValue("", "あいうえお");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getFirstValue(""), "");
  }

  public void setFirstValue_2()
  {
    MSG("引数が不正の場合");

    XmlResource res = new XmlResource();

    try {
      res.setFirstValue("aaa.", "xyz");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.setFirstValue("aaa.bbb(X=", "あいうえお");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void setFirstValue_3()
  {
    MSG("複数の要素が該当するキーの場合");

    XmlResource res = new XmlResource();
    
    res.setFirstValue("aaa.bbb(x=0)", "XXX");
    EQUAL(res.getFirstValue("aaa.bbb"), "XXX");
    EQUAL(res.getFirstValue("aaa.bbb(x=0)"), "XXX");
    EQUAL(res.getFirstValue("aaa.bbb(x=1)"), "");
    EQUAL(res.getFirstValue("aaa.bbb(x=2)"), "");

    res.setFirstValue("aaa.bbb(x=1)", "YYY");
    EQUAL(res.getFirstValue("aaa.bbb"), "XXX");
    EQUAL(res.getFirstValue("aaa.bbb(x=0)"), "XXX");
    EQUAL(res.getFirstValue("aaa.bbb(x=1)"), "YYY");
    EQUAL(res.getFirstValue("aaa.bbb(x=2)"), "");

    res.setFirstValue("aaa.bbb(x=2)", "ZZZ");
    EQUAL(res.getFirstValue("aaa.bbb"), "XXX");
    EQUAL(res.getFirstValue("aaa.bbb(x=0)"), "XXX");
    EQUAL(res.getFirstValue("aaa.bbb(x=1)"), "YYY");
    EQUAL(res.getFirstValue("aaa.bbb(x=2)"), "ZZZ");

    res.setFirstValue("aaa.bbb", "ABC");
    EQUAL(res.getFirstValue("aaa.bbb"), "ABC");
    EQUAL(res.getFirstValue("aaa.bbb(x=0)"), "ABC");
    EQUAL(res.getFirstValue("aaa.bbb(x=1)"), "YYY");
    EQUAL(res.getFirstValue("aaa.bbb(x=2)"), "ZZZ");
  }

  public void removeChildren()
  {
    MSG("通常の操作の場合");

    XmlResource res = new XmlResource();
    EQUAL(res.getFirstValue("aaa"), "");
    EQUAL(res.getFirstValue("aaa.bbb"), "");
    EQUAL(res.getFirstChild("aaa"), Resource.EMPTY);
    EQUAL(res.getFirstChild("aaa.bbb"), Resource.EMPTY);

    res.setFirstValue("aaa.bbb", "あいうえお");
    EQUAL(res.getFirstValue("aaa"), "");
    EQUAL(res.getFirstValue("aaa.bbb"), "あいうえお");
    FALSE(res.getFirstChild("aaa") == Resource.EMPTY);
    FALSE(res.getFirstChild("aaa.bbb") == Resource.EMPTY);

    res.removeChildren("aaa.bbb");
    EQUAL(res.getFirstValue("aaa"), "");
    EQUAL(res.getFirstValue("aaa.bbb"), "");
    FALSE(res.getFirstChild("aaa") == Resource.EMPTY);
    EQUAL(res.getFirstChild("aaa.bbb"), Resource.EMPTY);

    res.setFirstValue("aaa.bbb", "あいうえお");
    EQUAL(res.getFirstValue("aaa"), "");
    EQUAL(res.getFirstValue("aaa.bbb"), "あいうえお");
    FALSE(res.getFirstChild("aaa") == Resource.EMPTY);
    FALSE(res.getFirstChild("aaa.bbb") == Resource.EMPTY);

    res.removeChildren("aaa");
    EQUAL(res.getFirstValue("aaa"), "");
    EQUAL(res.getFirstValue("aaa.bbb"), "");
    EQUAL(res.getFirstChild("aaa"), Resource.EMPTY);
    EQUAL(res.getFirstChild("aaa.bbb"), Resource.EMPTY);
  }

  public void removeChildren_1()
  {
    MSG("引数が空文字列の場合");

    XmlResource res = new XmlResource();
    EQUAL(res.getFirstValue(""), "");
    EQUAL(((XmlResource)res.getFirstChild("")).getBaseNode(),res.getDocument());

    res.removeChildren("");
    EQUAL(res.getFirstValue(""), "");
    EQUAL(((XmlResource)res.getFirstChild("")).getBaseNode(),res.getDocument());

    res.setFirstValue("abc", "XXX");

    Resource child = res.getFirstChild("abc");
    NOTNULL(child);
    EQUAL(child.getFirstValue(""), "XXX");
    EQUAL(res.getFirstValue("abc"), "XXX");

    child.removeChildren("");
    EQUAL(child.getFirstValue(""), "");
    EQUAL(res.getFirstValue("abc"), "");

    res.setFirstValue("abc", "XXX");

    XmlResource copy = new XmlResource(res);
    EQUAL(copy.getFirstValue("abc"), "XXX");
    EQUAL(res.getFirstValue("abc"), "XXX");

    copy.removeChildren("");
    EQUAL(copy.getFirstValue("abc"), "");
    EQUAL(res.getFirstValue("abc"), "XXX");
  }

  public void removeChildren_2()
  {
    MSG("引数がヌルの場合");

    XmlResource res = new XmlResource();
    try {
      res.removeChildren(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void removeChildren_3()
  {
    MSG("引数が不正な場合");

    XmlResource res = new XmlResource();
    try {
      res.removeChildren("aaa.");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
    try {
      res.removeChildren("aaa.bbb(X=");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void removeChildren_4()
  {
    MSG("複数の要素を削除する場合");

    XmlResource res = new XmlResource();
    EQUAL(res.getFirstValue("aaa.bbb"), "");
    EQUAL(res.getFirstChild("aaa.bbb"), Resource.EMPTY);

    res.removeChildren("aaa.bbb");

    res.setFirstValue("aaa.bbb(X=1)", "あいうえお");
    res.setFirstValue("aaa.bbb(X=2)", "かきくけこ");
    res.setFirstValue("aaa.bbb(X=3)", "さしすせそ");
    EQUAL(res.getFirstValue("aaa.bbb"), "あいうえお");
    EQUAL(res.getFirstValue("aaa.bbb(X=1)"), "あいうえお");
    EQUAL(res.getFirstValue("aaa.bbb(X=2)"), "かきくけこ");
    EQUAL(res.getFirstValue("aaa.bbb(X=3)"), "さしすせそ");

    res.removeChildren("aaa.bbb");
    EQUAL(res.getFirstValue("aaa.bbb"), "");
    EQUAL(res.getFirstChild("aaa.bbb"), Resource.EMPTY);

    EQUAL(res.getFirstValue("aaa.bbb(X=1)"), "");
    EQUAL(res.getFirstValue("aaa.bbb(X=2)"), "");
    EQUAL(res.getFirstValue("aaa.bbb(X=3)"), "");
  }

  public void getFirstChild()
  {
    MSG("通常の操作");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }
    EQUAL(res.getFirstValue("sample.title"), "タイトル");
    EQUAL(res.getFirstValue("sample.body"), "本文。");
    EQUAL(res.getFirstValue("sample.body.a(id=a1,name=A1)"), "あ");
    EQUAL(res.getFirstValue("sample.body.b(id=b1,name=B1)"), "び");
    EQUAL(res.getFirstValue("sample.body.b(id=b2,name=B2)"), "びび");
    EQUAL(res.getFirstValue("sample.body.b(id=b3)"), "");

    XmlResource child = (XmlResource) res.getFirstChild("");
    EQUAL(child.getBaseNode(), res.getDocument());
    EQUAL(child.getFirstValue("sample.title"), "タイトル");
    EQUAL(child.getFirstValue("sample.body"), "本文。");
    EQUAL(child.getFirstValue("sample.body.a(id=a1,name=A1)"), "あ");
    EQUAL(child.getFirstValue("sample.body.b(id=b1,name=B1)"), "び");
    EQUAL(child.getFirstValue("sample.body.b(id=b2,name=B2)"), "びび");
    EQUAL(child.getFirstValue("sample.body.b(id=b3)"), "");

    child = (XmlResource) res.getFirstChild("sample");
    EQUAL(child.getBaseNode().getNodeName(), "sample");
    EQUAL(child.getFirstValue("title"), "タイトル");
    EQUAL(child.getFirstValue("body"), "本文。");
    EQUAL(child.getFirstValue("body.a(id=a1,name=A1)"), "あ");
    EQUAL(child.getFirstValue("body.b(id=b1,name=B1)"), "び");
    EQUAL(child.getFirstValue("body.b(id=b2,name=B2)"), "びび");
    EQUAL(child.getFirstValue("body.b(id=b3)"), "");

    child = (XmlResource) child.getFirstChild("body.b");
    EQUAL(child.getFirstValue(""), "び");
  }

  public void getFirstChild_1()
  {
    MSG("引数がヌルの場合");

    XmlResource res = new XmlResource();
    try {
      res.getFirstChild(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getFirstChid_1a()
  {
    MSG("引数が空文字列の場合");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";

    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    XmlResource res2 = (XmlResource) res.getFirstChild("");
    EQUAL(res.getDocument(), res2.getDocument());
    EQUAL(res.getBaseNode(), res2.getBaseNode());
  }

  public void getFirstChild_2()
  {
    MSG("引数が不正の場合");

    XmlResource res = new XmlResource();
    try {
      res.getFirstChild("aaa.");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
    try {
      res.getFirstChild("aaa.bbb(X=");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getFirstChild_3()
  {
    MSG("存在しないキーを指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getFirstChild("sample.label"), Resource.EMPTY);
    EQUAL(res.getFirstChild("sample.body.b(id=A1)"), Resource.EMPTY);
  }

  public void getFirstChild_4()
  {
    MSG("キーに*が存在する場合");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    Resource child = res.getFirstChild("*");
    EQUAL(child.getBaseElementName(), "sample");

    child = res.getFirstChild("sample.*");
    EQUAL(child.getBaseElementName(), "title");

    child = res.getFirstChild("sample.body.*");
    EQUAL(child.getBaseElementName(), "a");

    child = res.getFirstChild("sample.body");
    child = child.getFirstChild("*");
    EQUAL(child.getBaseElementName(), "a");

    child = res.getFirstChild("sample");
    child = child.getFirstChild("*.*(id=b2)");
    EQUAL(child.getBaseElementName(), "b");
    EQUAL(child.getFirstValue(""), "びび");
  }

  public void getChildren()
  {
    MSG("通常の操作");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<Resource> children = res.getChildren("");
    EQUAL(children.size(), 1);
    EQUAL(((XmlResource)children.get(0)).getBaseNode(), res.getDocument());

    children = res.getChildren("sample.title");
    EQUAL(children.size(), 1);
    EQUAL(children.get(0).getFirstValue(""), "タイトル");

    children = res.getChildren("sample.body.b");
    EQUAL(children.size(), 3);
    EQUAL(children.get(0).getFirstValue(""), "び");
    EQUAL(children.get(1).getFirstValue(""), "びび");
    EQUAL(children.get(2).getFirstValue(""), "");

    children = res.getChildren("sample.body.b(id=b2)");
    EQUAL(children.size(), 1);
    EQUAL(children.get(0).getFirstValue(""), "びび");
  }

  public void getChildren_1()
  {
    MSG("引数がヌルの場合");

    XmlResource res = new XmlResource();
    try {
      res.getChildren(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getChildren_2()
  {
    MSG("引数が不正な場合");

    XmlResource res = new XmlResource();
    try {
      res.getChildren("sample.aaa.");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.getChildren("sample.bbb(id=");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getChildren_3()
  {
    MSG("存在しないキーを指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getChildren("sample.label").size(), 0);
    EQUAL(res.getChildren("sample.body.b(id=A1)").size(), 0);
  }

  public void getChildren_4()
  {
    MSG("キーに*が含まれている場合");

    XmlResource res = new XmlResource();
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<Resource> resL = res.getChildren("*");
    EQUAL(resL.size(), 1);
    EQUAL(resL.get(0).getBaseElementName(), "sample");

    resL = res.getChildren("sample.*");
    EQUAL(resL.size(), 2);
    EQUAL(resL.get(0).getBaseElementName(), "title");
    EQUAL(resL.get(1).getBaseElementName(), "body");

    resL = res.getChildren("sample.body.*");
    EQUAL(resL.size(), 7);
    EQUAL(resL.get(0).getBaseElementName(), "a");
    EQUAL(resL.get(1).getBaseElementName(), "b");
    EQUAL(resL.get(2).getBaseElementName(), "b");
    EQUAL(resL.get(3).getBaseElementName(), "b");
    EQUAL(resL.get(4).getBaseElementName(), "c");
    EQUAL(resL.get(5).getBaseElementName(), "c");
    EQUAL(resL.get(6).getBaseElementName(), "c");

    resL = res.getChildren("sample.body.*(id=a1)");
    EQUAL(resL.size(), 1);
    EQUAL(resL.get(0).getBaseElementName(), "a");

    resL = res.getChildren("sample.body.*(id=b1)");
    EQUAL(resL.size(), 1);
    EQUAL(resL.get(0).getBaseElementName(), "b");

    resL = res.getChildren("sample.body.*(id=c1)");
    EQUAL(resL.size(), 1);
    EQUAL(resL.get(0).getBaseElementName(), "c");
  }

  public void getOrCreateFirstChild()
  {
    MSG("存在するキーを指定した場合");

    XmlResource res = new XmlResource();
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    XmlResource c = (XmlResource) res.getOrCreateFirstChild("sample.body.a");
    List<Resource> l = res.getChildren("sample.body.a");
    EQUAL(l.size(), 1);
    EQUAL(c.getBaseNode(), ((XmlResource)l.get(0)).getBaseNode());
  }

  public void getOrCreateFirstChild_1()
  {
    MSG("存在しないキーを指定した場合");

    XmlResource res = new XmlResource();
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<Resource> bL = res.getChildren("sample.header.label");
    EQUAL(bL.size(), 0);

    XmlResource a = (XmlResource) res.getOrCreateFirstChild(
      "sample.header.label");
    EQUAL(a.getFirstValue(""), "");

    List<Resource> aL = res.getChildren("sample.header.label");
    EQUAL(aL.size(), 1);
    EQUAL(a.getBaseNode(), ((XmlResource)aL.get(0)).getBaseNode());
  }

  public void getOrCreateFirstChild_2()
  {
    MSG("引数がヌルの場合");

    XmlResource res = new XmlResource();
    try {
      res.getOrCreateFirstChild(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getOrCreateFirstChild_3()
  {
    MSG("引数が不正な場合");
    
    XmlResource res = new XmlResource();
    try {
      res.getOrCreateFirstChild("sample.bbb.");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
    try {
      res.getOrCreateFirstChild("sample.bbb(b=");
      NG();
    } catch (IllegalKeyException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void save()
  {
    MSG("通常の操作の場合");

    XmlResource res1 = new XmlResource();
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res1.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    final String PATH2 = "test/data/ts/util/resource/XmlResource/sampleS.xml";
    try {
      res1.save(PATH2);
    } catch (Exception e) {
      NG(e);
      e.printStackTrace();
    }

    XmlResource res2 = new XmlResource();
    try {
      res2.load(PATH2);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res1.getFirstValue("sample.title"),
          res2.getFirstValue("sample.title"));

    EQUAL(res1.getFirstValue("sample.body"),
          res2.getFirstValue("sample.body"));

    EQUAL(res1.getFirstValue("sample.body.a"),
          res2.getFirstValue("sample.body.a"));

    EQUAL(res1.getFirstValue("sample.body.b"),
          res2.getFirstValue("sample.body.b"));

    EQUAL(res1.getFirstValue("sample.body.b(id=B2)"),
          res2.getFirstValue("sample.body.b(id=B2)"));

    EQUAL(res1.getFirstValue("sample.body.b(id=B3)"),
          res2.getFirstValue("sample.body.b(id=B3)"));

    EQUAL(res1.getFirstValue("sample.body.c"),
          res2.getFirstValue("sample.body.c"));
  }

  public void save_1()
  {
    MSG("引数がヌルの場合");

    XmlResource res = new XmlResource();
    try {
      res.save((OutputStream) null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void save_2()
  {
    MSG("引数が空文字列の場合");

    XmlResource res = new XmlResource();
    try {
      res.save("");
      NG();
    } catch (IOException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void save_3()
  {
    MSG("子リソースの場合");

    XmlResource res1 = new XmlResource();
    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    try {
      res1.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    XmlResource res3 = (XmlResource) res1.getFirstChild("sample.body");

    final String PATH2 = "test/data/ts/util/resource/XmlResource/sampleS2.xml";
    try {
      res3.save(PATH2);
    } catch (UnsupportedOperationException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getFirstAttribute()
  {
    MSG("通常の操作");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getFirstAttribute("sample", "id"), "");
    EQUAL(res.getFirstAttribute("sample.body", "id"), "");
    EQUAL(res.getFirstAttribute("sample.body", "type"), "typeA");
    EQUAL(res.getFirstAttribute("sample.body.a", "id"), "a1");
    EQUAL(res.getFirstAttribute("sample.body.b", "id"), "b1");
    EQUAL(res.getFirstAttribute("sample.body.c", "id"), "c1");
    EQUAL(res.getFirstAttribute("sample.body.a(id=a1)", "name"), "A1");
    EQUAL(res.getFirstAttribute("sample.body.b(id=b2,name=B2)", "name"), "B2");
    EQUAL(res.getFirstAttribute("sample.body.c(name=C2)", "id"), "c2");
  }

  public void getFirstAttribute_1()
  {
    MSG("引数がヌルの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.getFirstAttribute(null, "id");
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
    try {
      res.getFirstAttribute("sample.body.a", null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getFirstAttribute_2()
  {
    MSG("属性名に空文字列を指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }
    EQUAL(res.getFirstAttribute("sample", ""), "");
    EQUAL(res.getFirstAttribute("", "type"), "");

    Resource child = res.getFirstChild("sample.body");
    EQUAL(child.getFirstAttribute("", "type"), "typeA");
  }

  public void getFirstAttribute_3()
  {
    MSG("存在しない属性名を指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getFirstAttribute("sample.body", "typeB"), "");
    EQUAL(res.getFirstAttribute("sample.body(type=typeB)", "type"), "");
  }

  public void getAttributes()
  {
    MSG("通常の操作");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<String> attrLst = null;
    attrLst = res.getAttributes("sample", "id");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "");

    attrLst = res.getAttributes("sample.body", "id");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "");

    attrLst = res.getAttributes("sample.body", "type");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "typeA");

    attrLst = res.getAttributes("sample.body.a", "id");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "a1");

    attrLst = res.getAttributes("sample.body.b", "id");
    EQUAL(attrLst.size(), 3);
    EQUAL(attrLst.get(0), "b1");
    EQUAL(attrLst.get(1), "b2");
    EQUAL(attrLst.get(2), "b3");

    attrLst = res.getAttributes("sample.body.b", "name");
    EQUAL(attrLst.size(), 3);
    EQUAL(attrLst.get(0), "B1");
    EQUAL(attrLst.get(1), "B2");
    EQUAL(attrLst.get(2), "");

    attrLst = res.getAttributes("sample.body.b(id=b3)", "name");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "");

    attrLst = res.getAttributes("sample.body.c", "id");
    EQUAL(attrLst.size(), 3);
    EQUAL(attrLst.get(0), "c1");
    EQUAL(attrLst.get(1), "c2");
    EQUAL(attrLst.get(2), "c3");

    attrLst = res.getAttributes("sample.body.c(id=c2,name=C2)", "name");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "C2");
  }

  public void getAttributes_1()
  {
    MSG("引数がヌルの場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    try {
      res.getAttributes(null, "id");
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
    try {
      res.getAttributes("sample.body.a", null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void getAttributes_2()
  {
    MSG("引数に空文字列を指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    List<String> attrLst = null;

    attrLst = res.getAttributes("", "type");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "");

    attrLst = res.getAttributes("sample", "");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "");

    attrLst = res.getAttributes("sample(id=)", "");
    EQUAL(attrLst.size(), 0);

    Resource child = res.getFirstChild("sample.body");
    attrLst = child.getAttributes("", "type");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "typeA");

    child = res.getFirstChild("sample.body.b");
    attrLst = child.getAttributes("", "name");
    EQUAL(attrLst.size(), 1);
    EQUAL(attrLst.get(0), "B1");
  }

  public void getAttributes_3()
  {
    MSG("存在しない属性名を指定した場合");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample3.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getAttributes("sample.body(type=typeB)", "type").size(), 0);

    List<String> attrs = res.getAttributes("sample.body.b", "type");
    EQUAL(attrs.size(), 3);
    EQUAL(attrs.get(0), "");
    EQUAL(attrs.get(1), "");
    EQUAL(attrs.get(2), "");

    List<String> attrs2 = res.getAttributes("sample.title", "type");
    EQUAL(attrs2.size(), 1);
    EQUAL(attrs2.get(0), "");
  }

  public void testOfNameSpace()
  {
    MSG("名前空間に対する試験（読込）");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample6.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getFirstValue("sample.title"), "タイトル");
    EQUAL(res.getFirstValue("sample.body(type=typeA)"), "本文。");
    EQUAL(res.getFirstValue("sample.body.a"), "あ");
    EQUAL(res.getFirstValue("sample.body.c(name=C2)"), "しし");
  }

  public void testOfNameSpace_1()
  {
    MSG("名前空間に対する試験（保存）");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample6.xml";
    XmlResource res = new XmlResource();
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    res.setFirstValue("sample.subtitle", "サブタイトル");
    res.setFirstValue("sample.body.p", "ぴぴぴぴ");
    res.setFirstValue("sample.body.b(id=b3).bb31", "びーびーびー");

    final String PATH2 = "test/data/ts/util/resource/XmlResource/sampleS6.xml";
    try {
      res.save(PATH2);
    } catch (Exception e) {
      NG(e);
    }

    XmlResource res2 = new XmlResource();
    try {
      res2.load(PATH2);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res2.getFirstValue("sample.title"), "タイトル");
    EQUAL(res2.getFirstValue("sample.subtitle"), "サブタイトル");
    EQUAL(res2.getFirstValue("sample.body(type=typeA)"), "本文。");
    EQUAL(res2.getFirstValue("sample.body.a"), "あ");
    EQUAL(res2.getFirstValue("sample.body.b(id=b3).bb31"), "びーびーびー");
    EQUAL(res2.getFirstValue("sample.body.c(name=C2)"), "しし");
    EQUAL(res2.getFirstValue("sample.body.p"), "ぴぴぴぴ");
  }

  public void testOfNameSpace_2()
  {
    MSG("名前空間に対する試験（読込、不明なDTD）");

    final String PATH = "test/data/ts/util/resource/XmlResource/sample7.xml";
    XmlResource res = new XmlResource();
    res.setValidating(false);
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    EQUAL(res.getFirstValue("sample.title"), "タイトル");
    EQUAL(res.getFirstValue("sample.body(type=typeA)"), "本文。");
    EQUAL(res.getFirstValue("sample.body.a"), "あ");
    EQUAL(res.getFirstValue("sample.body.c(name=C2)"), "しし");
  }

  public void getValuesAndChildren()
  {
    MSG("基底要素の全ての文字列値と子要素のリソースを取得するメソッドの確認");
    final String PATH = "test/data/ts/util/resource/XmlResource/sample8.xml";
    XmlResource res = new XmlResource();
    res.setValidating(false);
    try {
      res.load(PATH);
    } catch (Exception e) {
      NG(e);
    }

    XmlResource child;
    List<Object> objLst;
    child = XmlResource.class.cast(res.getFirstChild("sample.title"));
    objLst = child.getValuesAndChildren();
    EQUAL(objLst.size(), 1);
    EQUAL(objLst.get(0).getClass(), String.class);
    EQUAL(objLst.get(0).toString(), "タイトル");

    child = XmlResource.class.cast(res.getFirstChild("sample.body"));
    objLst = child.getValuesAndChildren();
    EQUAL(objLst.size(), 5);
    EQUAL(objLst.get(0), "あいうえお");
    EQUAL(objLst.get(1).getClass(), XmlResource.class);
    EQUAL(XmlResource.class.cast(objLst.get(1)).getBaseElementName(), "k");
    EQUAL(XmlResource.class.cast(objLst.get(1)).getFirstValue(""),"かきくけこ");
    EQUAL(objLst.get(2), "  さしすせそ  ");
    EQUAL(objLst.get(3).getClass(), XmlResource.class);
    EQUAL(XmlResource.class.cast(objLst.get(3)).getBaseElementName(), "t");
    EQUAL(XmlResource.class.cast(objLst.get(3)).getFirstValue(""),"たちつてと");
    EQUAL(objLst.get(4), "なにぬねの");

    child = XmlResource.class.cast(res.getFirstChild("sample.body(id=2)"));
    objLst = child.getValuesAndChildren();
    EQUAL(objLst.size(), 5);
    EQUAL(objLst.get(0), "はひふへほ");
    EQUAL(objLst.get(1).getClass(), XmlResource.class);
    EQUAL(XmlResource.class.cast(objLst.get(1)).getBaseElementName(), "m");
    EQUAL(XmlResource.class.cast(objLst.get(1)).getFirstValue(""),"まみむめも");
    EQUAL(objLst.get(2), "  やゆよ  ");
    EQUAL(objLst.get(3).getClass(), XmlResource.class);
    EQUAL(XmlResource.class.cast(objLst.get(3)).getBaseElementName(), "r");
    EQUAL(XmlResource.class.cast(objLst.get(3)).getFirstValue(""),"らりるれろ");
    EQUAL(objLst.get(4), "わをん");
  }
}
