OSDN Git Service

130128版スキーマ対応
authorOlyutorskii <olyutorskii@users.osdn.me>
Sun, 27 Jan 2013 22:28:46 +0000 (07:28 +0900)
committerOlyutorskii <olyutorskii@users.osdn.me>
Sun, 27 Jan 2013 22:28:46 +0000 (07:28 +0900)
125 files changed:
CHANGELOG.txt
pom.xml
src/main/java/jp/sfjp/mikutoga/pmd/binio/BoneBuilder.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/BoneBuilder.java with 92% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/JointBuilder.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/JointBuilder.java with 95% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/MaterialBuilder.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/MaterialBuilder.java with 93% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/MorphBuilder.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/MorphBuilder.java with 94% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/PmdExporter.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/PmdExporter.java with 93% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/PmdExporterBase.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/PmdExporterBase.java with 96% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/PmdExporterExt1.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/PmdExporterExt1.java with 95% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/PmdExporterExt2.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/PmdExporterExt2.java with 93% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/PmdExporterExt3.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/PmdExporterExt3.java with 94% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/PmdLoader.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/PmdLoader.java with 95% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/RigidBuilder.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/RigidBuilder.java with 93% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/ShapeBuilder.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/ShapeBuilder.java with 95% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/TextBuilder.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/TextBuilder.java with 96% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/ToonBuilder.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/ToonBuilder.java with 91% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/binio/package-info.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/package-info.java with 78% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/BoneGroup.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/BoneGroup.java with 94% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/BoneInfo.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/BoneInfo.java with 86% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/DynamicsInfo.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/DynamicsInfo.java with 98% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/IKChain.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/IKChain.java with 96% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/JointInfo.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/JointInfo.java with 98% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/ListUtil.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/ListUtil.java with 99% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/Material.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/Material.java with 99% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/MorphPart.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/MorphPart.java with 98% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/MorphVertex.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/MorphVertex.java with 98% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/PmdModel.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/PmdModel.java with 99% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/RigidGroup.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/RigidGroup.java with 97% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/RigidInfo.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/RigidInfo.java with 99% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/RigidShape.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/RigidShape.java with 98% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/SerialNumbered.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/SerialNumbered.java with 97% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/ShadeInfo.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/ShadeInfo.java with 98% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/Surface.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/Surface.java with 98% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/ToonMap.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/ToonMap.java with 94% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/model/Vertex.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/Vertex.java with 99% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/xml/BotherHandler.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd2xml/XmlHandler.java with 86% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/xml/LocalSchema.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd/xml/Schema101009.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd/xml/Schema130128.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd/xml/XmlExporter.java [moved from src/main/java/jp/sfjp/mikutoga/pmd/xml101009/Xml101009Exporter.java with 88% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/xml/XmlLoader.java [moved from src/main/java/jp/sfjp/mikutoga/pmd/xml101009/Xml101009Loader.java with 81% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/xml/XmlModelFileType.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd/xml/package-info.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd/xml101009/Xml101009Resources.java [deleted file]
src/main/java/jp/sfjp/mikutoga/pmd/xml101009/package-info.java [deleted file]
src/main/java/jp/sfjp/mikutoga/pmd2xml/CmdLine.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd2xml/CmdLineException.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd2xml/ModelFileType.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd2xml/OptSwitch.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2Xml.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd2xml/Pmd2Xml.java with 97% similarity]
src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2XmlConv.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd2xml/Pmd2XmlConv.java with 67% similarity]
src/main/java/jp/sfjp/mikutoga/pmd2xml/package-info.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd2xml/package-info.java with 86% similarity]
src/main/java/jp/sourceforge/mikutoga/pmd2xml/OptInfo.java [deleted file]
src/main/resources/jp/sfjp/mikutoga/pmd/xml/resources/pmdxml-101009.xsd [moved from src/main/resources/jp/sfjp/mikutoga/pmd/xml101009/resources/pmdxml-101009.xsd with 100% similarity]
src/main/resources/jp/sfjp/mikutoga/pmd/xml/resources/pmdxml-130128.xsd [new file with mode: 0644]
src/main/resources/jp/sfjp/mikutoga/pmd/xml101009/resources/pmdxml-101009.dtd [deleted file]
src/main/resources/jp/sfjp/mikutoga/pmd2xml/resources/version.properties [moved from src/main/resources/jp/sourceforge/mikutoga/pmd2xml/resources/version.properties with 100% similarity]
src/test/java/jp/sfjp/mikutoga/pmd2xml/CmdLineTest.java [new file with mode: 0644]
src/test/java/jp/sfjp/mikutoga/pmd2xml/ModelFileTypeTest.java [new file with mode: 0644]
src/test/java/jp/sfjp/mikutoga/pmd2xml/OptInfoTest.java [new file with mode: 0644]
src/test/java/jp/sfjp/mikutoga/pmd2xml/OptSwitchTest.java [new file with mode: 0644]
src/test/java/testdata/CnvAssert.java
src/test/java/testdata/pmd101009/xml/XmlTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/bone/BoneTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/charset/CharsetTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/group/GroupTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/i18n/I18nTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/ik/IkBoneTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/material/MaterialTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/minimum/MinimumTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/morph/MorphTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/numeric/NumericTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/rigid/RigidTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/small/SmallTest.java [new file with mode: 0644]
src/test/java/testdata/pmd130128/xml/XmlTest.java [new file with mode: 0644]
src/test/resources/testdata/pmd101009/xml/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/xml/minimum.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/xml/namespace.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/bone/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/bone/allbone.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/bone/allbone.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/charset/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/charset/charset.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/charset/result.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/charset/source.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/group/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/group/boneGroup.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/group/boneGroup.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/i18n/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/i18n/i18n.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/i18n/i18n.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/ik/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/ik/ikBone.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/ik/ikBone.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/material/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/material/material.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/material/material.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/minimum/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/minimum/minimum.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/minimum/minimum.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/morph/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/morph/allmorph.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/morph/allmorph.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/numeric/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/numeric/numeric.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/numeric/result.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/numeric/source.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/rigid/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/rigid/allrigid.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/rigid/allrigid.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlybone.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlybone.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlyjoint.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlyjoint.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlymorph.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlymorph.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlyrigid.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlyrigid.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlytriangle.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/small/onlytriangle.xml [new file with mode: 0644]
src/test/resources/testdata/pmd130128/xml/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd130128/xml/minimum.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd130128/xml/namespace.xml [new file with mode: 0644]

index 44148b5..47f2ff5 100644 (file)
@@ -6,8 +6,12 @@ Pmd2XML 変更履歴
 
 X.XXX.X (20XX-XX-XX)
     ・Maven3対応。
+    ・コマンドラインオプションを刷新。
     ・XML出力改行コードの指定が可能になる。
     ・モーフ数0のモデルデータを読み書きできないバグに対処。(チケット#23394)
+    ・130128版新スキーマで同じIKボーンからの複数IKチェーンを可能に。
+     (チケット#30587)
+    ・130128版新スキーマで「ikBone」タグを「sourceBone」タグに変更
 
 1.102.4 (2010-10-09)
     ・TogaGem1.105.2のバグ修正(接続ボーンを持たない剛体の件)に対処。
diff --git a/pom.xml b/pom.xml
index a47130c..b2d4a3c 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -94,7 +94,7 @@
         <checkstyle.config.location>${project.mainconf}/checks.xml</checkstyle.config.location>
         <checkstyle.enable.rss>false</checkstyle.enable.rss>
 
-        <project.mainentry>jp.sourceforge.mikutoga.pmd2xml.Pmd2Xml</project.mainentry>
+        <project.mainentry>jp.sfjp.mikutoga.pmd2xml.Pmd2Xml</project.mainentry>
 
     </properties>
 
         <dependency>
             <groupId>jp.sourceforge.mikutoga</groupId>
             <artifactId>togagem</artifactId>
-            <version>2.101.3-SNAPSHOT</version>
+            <version>2.102.2</version>
             <scope>compile</scope>
         </dependency>
 
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-enforcer-plugin</artifactId>
-                <version>1.1.1</version>
+                <version>1.2</version>
                 <configuration>
                     <rules>
                         <requireMavenVersion>
-                            <version>[2.2,)</version>
+                            <version>[3.0,)</version>
                         </requireMavenVersion>
                         <requireJavaVersion>
                             <version>[1.6,)</version>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
-                <version>2.12.4</version>
+                <version>2.13</version>
                 <configuration>
                     <skipTests>false</skipTests>
                     <enableAssertions>true</enableAssertions>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-pmd-plugin</artifactId>
-                <version>2.7.1</version>
+                <version>2.7.1</version>  <!-- 3.0 is buggy -->
                 <configuration>
                     <targetJdk>${maven.compiler.target}</targetJdk>
                     <rulesets>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-report-plugin</artifactId>
-                <version>2.12.4</version>
+                <version>2.13</version>
                 <configuration>
                     <showSuccess>false</showSuccess>
                 </configuration>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-pmd-plugin</artifactId>
-                <version>2.7.1</version>
+                <version>2.7.1</version>  <!-- 3.0 is buggy -->
                 <configuration>
                     <skip>false</skip>
                     <targetJdk>${maven.compiler.target}</targetJdk>
@@ -5,19 +5,19 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import jp.sourceforge.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.BoneGroup;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.IKChain;
+import jp.sfjp.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.math.MkPos3D;
 import jp.sourceforge.mikutoga.parser.ParseStage;
 import jp.sourceforge.mikutoga.pmd.BoneType;
-import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.IKChain;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.pmd.parser.PmdBoneHandler;
 import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
 
@@ -187,10 +187,10 @@ class BoneBuilder implements PmdBoneHandler {
      * {@inheritDoc}
      * @param parentId {@inheritDoc}
      * @param tailId {@inheritDoc}
-     * @param ikId {@inheritDoc}
+     * @param srcId {@inheritDoc}
      */
     @Override
-    public void pmdBoneLink(int parentId, int tailId, int ikId){
+    public void pmdBoneLink(int parentId, int tailId, int srcId){
         BoneInfo prevBone = null;
         if(0 <= parentId && parentId < PmdLimits.MAX_BONE){
             prevBone = this.boneList.get(parentId);
@@ -201,18 +201,18 @@ class BoneBuilder implements PmdBoneHandler {
             nextBone = this.boneList.get(tailId);
         }
 
-        BoneInfo ikBone = null;
+        BoneInfo srcBone = null;
         if(this.currentBone.getBoneType() == BoneType.LINKEDROT){
-            ikBone = null;
-            int ratio = ikId;
+            srcBone = null;
+            int ratio = srcId;
             this.currentBone.setRotationRatio(ratio);
-        }else if(0 < ikId && ikId < PmdLimits.MAX_BONE){
-            ikBone = this.boneList.get(ikId);
+        }else if(0 < srcId && srcId < PmdLimits.MAX_BONE){
+            srcBone = this.boneList.get(srcId);
         }
 
         this.currentBone.setPrevBone(prevBone);
         this.currentBone.setNextBone(nextBone);
-        this.currentBone.setIKBone(ikBone);
+        this.currentBone.setSrcBone(srcBone);
 
         return;
     }
@@ -5,19 +5,19 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.util.Iterator;
 import java.util.List;
-import jp.sourceforge.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.JointInfo;
+import jp.sfjp.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.RigidInfo;
 import jp.sourceforge.mikutoga.math.MkPos3D;
 import jp.sourceforge.mikutoga.parser.ParseStage;
 import jp.sourceforge.mikutoga.pmd.Deg3d;
 import jp.sourceforge.mikutoga.pmd.Rad3d;
 import jp.sourceforge.mikutoga.pmd.TripletRange;
-import jp.sourceforge.mikutoga.pmd.model.JointInfo;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.RigidInfo;
 import jp.sourceforge.mikutoga.pmd.parser.PmdJointHandler;
 
 /**
@@ -5,18 +5,18 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.awt.Color;
 import java.util.Iterator;
 import java.util.List;
-import jp.sourceforge.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.Material;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.ShadeInfo;
+import jp.sfjp.mikutoga.pmd.model.Surface;
+import jp.sfjp.mikutoga.pmd.model.ToonMap;
 import jp.sourceforge.mikutoga.parser.ParseStage;
-import jp.sourceforge.mikutoga.pmd.model.Material;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.ShadeInfo;
-import jp.sourceforge.mikutoga.pmd.model.Surface;
-import jp.sourceforge.mikutoga.pmd.model.ToonMap;
 import jp.sourceforge.mikutoga.pmd.parser.PmdMaterialHandler;
 
 /**
@@ -5,21 +5,21 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import jp.sourceforge.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.MorphPart;
+import jp.sfjp.mikutoga.pmd.model.MorphVertex;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.math.MkPos3D;
 import jp.sourceforge.mikutoga.parser.ParseStage;
 import jp.sourceforge.mikutoga.pmd.MorphType;
-import jp.sourceforge.mikutoga.pmd.model.MorphPart;
-import jp.sourceforge.mikutoga.pmd.model.MorphVertex;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.pmd.parser.PmdMorphHandler;
 
 /**
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.io.OutputStream;
 
@@ -5,9 +5,8 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
-import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import java.awt.Color;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -16,24 +15,25 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import jp.sfjp.mikutoga.pmd.model.BoneGroup;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.IKChain;
+import jp.sfjp.mikutoga.pmd.model.Material;
+import jp.sfjp.mikutoga.pmd.model.MorphPart;
+import jp.sfjp.mikutoga.pmd.model.MorphVertex;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.SerialNumbered;
+import jp.sfjp.mikutoga.pmd.model.ShadeInfo;
+import jp.sfjp.mikutoga.pmd.model.Surface;
+import jp.sfjp.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.binio.BinaryExporter;
 import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
 import jp.sourceforge.mikutoga.math.MkPos2D;
 import jp.sourceforge.mikutoga.math.MkPos3D;
 import jp.sourceforge.mikutoga.math.MkVec3D;
 import jp.sourceforge.mikutoga.pmd.BoneType;
+import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import jp.sourceforge.mikutoga.pmd.MorphType;
-import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.IKChain;
-import jp.sourceforge.mikutoga.pmd.model.Material;
-import jp.sourceforge.mikutoga.pmd.model.MorphPart;
-import jp.sourceforge.mikutoga.pmd.model.MorphVertex;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.SerialNumbered;
-import jp.sourceforge.mikutoga.pmd.model.ShadeInfo;
-import jp.sourceforge.mikutoga.pmd.model.Surface;
-import jp.sourceforge.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
 
 /**
@@ -384,9 +384,9 @@ public class PmdExporterBase extends BinaryExporter{
             int ratio = bone.getRotationRatio();
             dumpLeShort(ratio);
         }else{
-            BoneInfo ik = bone.getIKBone();
-            if(ik != null) dumpSerialIdAsShort(ik);
-            else           dumpLeShort(NOIKBONE_ID);
+            BoneInfo srcBone = bone.getSrcBone();
+            if(srcBone != null) dumpSerialIdAsShort(srcBone);
+            else                dumpLeShort(NOIKBONE_ID);
         }
 
         MkPos3D position = bone.getPosition();
@@ -5,19 +5,19 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
-import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
+import jp.sfjp.mikutoga.pmd.model.BoneGroup;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.MorphPart;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
+import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import jp.sourceforge.mikutoga.pmd.MorphType;
-import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.MorphPart;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
 
 /**
@@ -5,14 +5,14 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
-import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import java.io.IOException;
 import java.io.OutputStream;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.ToonMap;
 import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.ToonMap;
+import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
 
 /**
@@ -5,24 +5,24 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
-import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.DynamicsInfo;
+import jp.sfjp.mikutoga.pmd.model.JointInfo;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.RigidGroup;
+import jp.sfjp.mikutoga.pmd.model.RigidInfo;
+import jp.sfjp.mikutoga.pmd.model.RigidShape;
 import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
 import jp.sourceforge.mikutoga.pmd.Deg3d;
+import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import jp.sourceforge.mikutoga.pmd.Rad3d;
 import jp.sourceforge.mikutoga.pmd.RigidShapeType;
 import jp.sourceforge.mikutoga.pmd.TripletRange;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.DynamicsInfo;
-import jp.sourceforge.mikutoga.pmd.model.JointInfo;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.RigidGroup;
-import jp.sourceforge.mikutoga.pmd.model.RigidInfo;
-import jp.sourceforge.mikutoga.pmd.model.RigidShape;
 import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
 
 /**
@@ -5,15 +5,15 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
+import jp.sfjp.mikutoga.pmd.model.MorphPart;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.pmd.model.MorphPart;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.pmd.parser.PmdParser;
 
 /**
@@ -5,22 +5,22 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.util.Iterator;
 import java.util.List;
-import jp.sourceforge.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.DynamicsInfo;
+import jp.sfjp.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.RigidGroup;
+import jp.sfjp.mikutoga.pmd.model.RigidInfo;
+import jp.sfjp.mikutoga.pmd.model.RigidShape;
 import jp.sourceforge.mikutoga.math.MkPos3D;
 import jp.sourceforge.mikutoga.parser.ParseStage;
 import jp.sourceforge.mikutoga.pmd.Rad3d;
 import jp.sourceforge.mikutoga.pmd.RigidBehaviorType;
 import jp.sourceforge.mikutoga.pmd.RigidShapeType;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.DynamicsInfo;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.RigidGroup;
-import jp.sourceforge.mikutoga.pmd.model.RigidInfo;
-import jp.sourceforge.mikutoga.pmd.model.RigidShape;
 import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
 import jp.sourceforge.mikutoga.pmd.parser.PmdRigidHandler;
 
@@ -5,20 +5,20 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.util.Iterator;
 import java.util.List;
 import java.util.RandomAccess;
-import jp.sourceforge.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.Surface;
+import jp.sfjp.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.math.MkPos2D;
 import jp.sourceforge.mikutoga.math.MkPos3D;
 import jp.sourceforge.mikutoga.math.MkVec3D;
 import jp.sourceforge.mikutoga.parser.ParseStage;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.Surface;
-import jp.sourceforge.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.pmd.parser.PmdShapeHandler;
 
 /**
@@ -5,16 +5,16 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
 import java.util.Iterator;
 import java.util.List;
+import jp.sfjp.mikutoga.pmd.model.BoneGroup;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.MorphPart;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.corelib.I18nText;
 import jp.sourceforge.mikutoga.parser.ParseStage;
-import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.MorphPart;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.pmd.parser.PmdBasicHandler;
 import jp.sourceforge.mikutoga.pmd.parser.PmdEngHandler;
 
@@ -5,11 +5,11 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.binio;
+package jp.sfjp.mikutoga.pmd.binio;
 
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.ToonMap;
 import jp.sourceforge.mikutoga.parser.ParseStage;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.ToonMap;
 import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
 import jp.sourceforge.mikutoga.pmd.parser.PmdToonHandler;
 
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -15,7 +15,8 @@ import jp.sourceforge.mikutoga.corelib.I18nText;
 /**
  * ボーングループ。
  * ボーングループ名と0個以上のボーンを配下に持つ。
- * 通し番号0のボーングループは、暗黙に用意される「デフォルトボーングループ」とする。
+ * 通し番号0のボーングループは、
+ * 暗黙に用意される「デフォルトボーングループ」とする。
  */
 public class BoneGroup implements SerialNumbered , Iterable<BoneInfo> {
 
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import jp.sourceforge.mikutoga.corelib.I18nText;
 import jp.sourceforge.mikutoga.math.MkPos3D;
@@ -21,7 +21,7 @@ public class BoneInfo implements SerialNumbered {
 
     private BoneInfo prevBone;
     private BoneInfo nextBone;
-    private BoneInfo ikBone;
+    private BoneInfo srcBone;
 
     private final MkPos3D position = new MkPos3D();
 
@@ -103,20 +103,20 @@ public class BoneInfo implements SerialNumbered {
     }
 
     /**
-     * このボーンが影響を受けるIKボーンを設定する。
-     * @param ikBoneArg IKボーン。ない場合はnullを指定。
+     * このボーンが影響を受けるIK元、回転元のソースボーンを設定する。
+     * @param ikBoneArg ソースボーン。ない場合はnullを指定。
      */
-    public void setIKBone(BoneInfo ikBoneArg){
-        this.ikBone = ikBoneArg;
+    public void setSrcBone(BoneInfo ikBoneArg){
+        this.srcBone = ikBoneArg;
         return;
     }
 
     /**
-     * このボーンが影響を受けるIKボーンを返す。
-     * @return IKボーン。ない場合はnull
+     * このボーンが影響を受けるIK元、回転元のソースボーンを返す。
+     * @return ソースボーン。ない場合はnull
      */
-    public BoneInfo getIKBone(){
-        return this.ikBone;
+    public BoneInfo getSrcBone(){
+        return this.srcBone;
     }
 
     /**
@@ -193,8 +193,11 @@ public class BoneInfo implements SerialNumbered {
             result.append(" rotraio=").append(this.rotationRatio);
         }else{
             result.append(" ik=");
-            if(this.ikBone != null) result.append(this.ikBone.getBoneName());
-            else                    result.append("NONE");
+            if(this.srcBone != null){
+                result.append(this.srcBone.getBoneName());
+            }else{
+                result.append("NONE");
+            }
         }
 
         result.append(" ").append(this.position);
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 /**
  * 剛体間力学演算の各種パラメータ。
@@ -5,9 +5,8 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import jp.sourceforge.mikutoga.corelib.I18nText;
 import jp.sourceforge.mikutoga.math.MkPos3D;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.awt.Color;
 import java.awt.Transparency;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.Comparator;
 import jp.sourceforge.mikutoga.math.MkPos3D;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import jp.sourceforge.mikutoga.pmd.RigidShapeType;
 
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.Comparator;
 
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 /**
  * シェーディング情報。
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import java.util.Collections;
 import java.util.Map;
@@ -80,7 +80,8 @@ public class ToonMap {
     }
 
     /**
-     * このトゥーンファイル構成がデフォルトのトゥーンファイル構成と等しいか判定する。
+     * このトゥーンファイル構成が
+     * デフォルトのトゥーンファイル構成と等しいか判定する。
      * @return 等しければtrue
      */
     public boolean isDefaultMap(){
@@ -113,7 +114,8 @@ public class ToonMap {
     }
 
     /**
-     * 指定インデックスのトゥーンファイル名をデフォルトのトゥーンファイル名にリセットする。
+     * 指定インデックスのトゥーンファイル名を
+     * デフォルトのトゥーンファイル名にリセットする。
      * @param idx インデックス値
      */
     public void resetIndexedToon(int idx){
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model;
+package jp.sfjp.mikutoga.pmd.model;
 
 import jp.sourceforge.mikutoga.math.MkPos2D;
 import jp.sourceforge.mikutoga.math.MkPos3D;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd2xml;
+package jp.sfjp.mikutoga.pmd.xml;
 
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.SAXException;
@@ -15,17 +15,17 @@ import org.xml.sax.SAXParseException;
  * 自製エラーハンドラ。
  * 例外を渡されれば即投げる。
  */
-final class XmlHandler implements ErrorHandler{
+public final class BotherHandler implements ErrorHandler{
 
     /**
      * 唯一のシングルトン。
      */
-    static final ErrorHandler HANDLER = new XmlHandler();
+    public static final ErrorHandler HANDLER = new BotherHandler();
 
     /**
      * 隠しコンストラクタ。
      */
-    private XmlHandler(){
+    private BotherHandler(){
         super();
         return;
     }
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd/xml/LocalSchema.java b/src/main/java/jp/sfjp/mikutoga/pmd/xml/LocalSchema.java
new file mode 100644 (file)
index 0000000..a167e86
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * local xml schema for PMD-XML
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd.xml;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.LinkedList;
+import java.util.List;
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import jp.sourceforge.mikutoga.xml.XmlResourceResolver;
+import org.xml.sax.SAXException;
+
+/**
+ * XML用各種スキーマのローカル参照解決基盤。
+ */
+public abstract class LocalSchema {
+
+    /**
+     * コンストラクタ。
+     */
+    protected LocalSchema(){
+        super();
+        return;
+    }
+
+
+    /**
+     * XML Schema 用のスキーマファクトリを返す。
+     * @return スキーマファクトリ
+     */
+    private static SchemaFactory newSchemaFactory(){
+        SchemaFactory schemaFactory =
+                SchemaFactory.newInstance(
+                    XMLConstants.W3C_XML_SCHEMA_NS_URI
+                );
+
+//      schemaFactory.setFeature(name, value);
+//      schemaFactory.setProperty(name, object);
+
+        schemaFactory.setErrorHandler(BotherHandler.HANDLER);
+
+        return schemaFactory;
+    }
+
+    /**
+     * ローカルスキーマをロードする。
+     * <p>任意のリゾルバを指定可能
+     * @param resolver リゾルバ
+     * @param lscs ローカルスキーマ情報の配列
+     * @return スキーマ
+     */
+    public static Schema newSchema(XmlResourceResolver resolver,
+                                    LocalSchema... lscs ){
+        List<Source> sourceList = new LinkedList<Source>();
+        for(LocalSchema lsc : lscs){
+            if(lsc == null) continue;
+            lsc.appendToUriMap(resolver);
+
+            Source local = lsc.getLocalSchemaSource();
+            if(local == null) continue;
+            sourceList.add(local);
+        }
+
+        SchemaFactory schemaFactory = newSchemaFactory();
+        schemaFactory.setResourceResolver(resolver);
+
+        Source[] sources = new Source[sourceList.size()];
+        sourceList.toArray(sources);
+
+        Schema result;
+        try{
+            if(sources.length <= 0){
+                result = schemaFactory.newSchema();
+            }else{
+                result = schemaFactory.newSchema(sources);
+            }
+        }catch(SAXException e){   // Build error
+            assert false;
+            throw new AssertionError(e);
+        }
+
+        return result;
+    }
+
+    /**
+     * オリジナル版スキーマ定義のURIを返す。
+     * <p>nullを返す場合は
+     * スキーマの自動判定&ダウンロードが求められていると見なされる。
+     * <p>このクラスの実装では常にnullを返す。
+     * @return オリジナル版スキーマのURL。
+     */
+    public abstract URI getOriginalSchema();
+
+    /**
+     * ローカルリソース版スキーマ定義のURIを返す。
+     * <p>nullを返す場合は
+     * スキーマの自動判定&ダウンロードが求められていると見なされる。
+     * <p>このクラスの実装では常にnullを返す。
+     * @return ローカルリソース版スキーマのURL。
+     */
+    public abstract URI getLocalSchema();
+
+    /**
+     * スキーマのSourceを返す。
+     * <p>ローカルスキーマのSourceを返す。
+     * @return Source 見つからなければnull
+     */
+    public Source getLocalSchemaSource(){
+        URI uri;
+
+        uri = getLocalSchema();
+        if(uri == null) return null;
+
+        URL url;
+        try{
+            url = uri.toURL();
+        }catch(MalformedURLException e){      // Build error
+            assert false;
+            throw new AssertionError(e);
+        }
+
+        InputStream is;
+        try{
+            is = url.openStream();
+        }catch(IOException e){              // Build error
+            assert false;
+            throw new AssertionError(e);
+        }
+        is = new BufferedInputStream(is);
+
+        Source result = new StreamSource(is);
+
+        return result;
+    }
+
+    /**
+     * ローカルで解決可能なリソース参照をリゾルバに追加登録する。
+     * @param resolver リゾルバ
+     */
+    public void appendToUriMap(XmlResourceResolver resolver){
+        URI original = getOriginalSchema();
+        URI local    = getLocalSchema();
+
+        if(original == null) return;
+
+        resolver.putRedirected(original, local);
+
+        return;
+    }
+
+}
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd/xml/Schema101009.java b/src/main/java/jp/sfjp/mikutoga/pmd/xml/Schema101009.java
new file mode 100644 (file)
index 0000000..7ff1f59
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * xml resources for PMD-XML
+ *
+ * License : The MIT License
+ * Copyright(c) 2010 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd.xml;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * 101009形式XML各種リソースの定義。
+ */
+public class Schema101009 extends LocalSchema{
+
+    /** 名前空間。 */
+    public static final String NS_PMDXML =
+            "http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009";
+    /** 公開スキーマ。 */
+    public static final String SCHEMA_PMDXML =
+            "http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd";
+    /** 版数。 */
+    public static final String VER_PMDXML =
+            "101009";
+    /** 代替リソースの相対名。 */
+    public static final String LOCAL_SCHEMA_PMDXML =
+            "resources/pmdxml-101009.xsd";
+
+    private static final URI URI_SCHEMA_PMDXML = URI.create(SCHEMA_PMDXML);
+    private static final URI RES_SCHEMA_PMDXML;
+
+    private static final Class<?> THISCLASS = Schema101009.class;
+
+    static{
+        try{
+            RES_SCHEMA_PMDXML =
+                    THISCLASS.getResource(LOCAL_SCHEMA_PMDXML).toURI();
+        }catch(URISyntaxException e){
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+
+    /**
+     * 隠しコンストラクタ。
+     */
+    public Schema101009(){
+        super();
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * @return {@inheritDoc}
+     */
+    @Override
+    public URI getOriginalSchema(){
+        return URI_SCHEMA_PMDXML;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return {@inheritDoc}
+     */
+    @Override
+    public URI getLocalSchema(){
+        return RES_SCHEMA_PMDXML;
+    }
+
+}
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd/xml/Schema130128.java b/src/main/java/jp/sfjp/mikutoga/pmd/xml/Schema130128.java
new file mode 100644 (file)
index 0000000..ef5fcf1
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * xml resources for PMD-XML
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd.xml;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * 130128形式XML各種リソースの定義。
+ */
+public class Schema130128 extends LocalSchema{
+
+    /** 名前空間。 */
+    public static final String NS_PMDXML =
+            "http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128";
+    /** 公開スキーマ。 */
+    public static final String SCHEMA_PMDXML =
+            "http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-130128.xsd";
+    /** 版数。 */
+    public static final String VER_PMDXML =
+            "130128";
+    /** 代替リソースの相対名。 */
+    public static final String LOCAL_SCHEMA_PMDXML =
+            "resources/pmdxml-130128.xsd";
+
+    private static final URI URI_SCHEMA_PMDXML = URI.create(SCHEMA_PMDXML);
+    private static final URI RES_SCHEMA_PMDXML;
+
+    private static final Class<?> THISCLASS = Schema130128.class;
+
+    static{
+        try{
+            RES_SCHEMA_PMDXML =
+                    THISCLASS.getResource(LOCAL_SCHEMA_PMDXML).toURI();
+        }catch(URISyntaxException e){
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+
+    /**
+     * 隠しコンストラクタ。
+     */
+    public Schema130128(){
+        super();
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * @return {@inheritDoc}
+     */
+    @Override
+    public URI getOriginalSchema(){
+        return URI_SCHEMA_PMDXML;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return {@inheritDoc}
+     */
+    @Override
+    public URI getLocalSchema(){
+        return RES_SCHEMA_PMDXML;
+    }
+
+}
@@ -5,13 +5,30 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sfjp.mikutoga.pmd.xml101009;
+package jp.sfjp.mikutoga.pmd.xml;
 
 import java.awt.Color;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
+import jp.sfjp.mikutoga.pmd.model.BoneGroup;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.DynamicsInfo;
+import jp.sfjp.mikutoga.pmd.model.IKChain;
+import jp.sfjp.mikutoga.pmd.model.JointInfo;
+import jp.sfjp.mikutoga.pmd.model.Material;
+import jp.sfjp.mikutoga.pmd.model.MorphPart;
+import jp.sfjp.mikutoga.pmd.model.MorphVertex;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.RigidGroup;
+import jp.sfjp.mikutoga.pmd.model.RigidInfo;
+import jp.sfjp.mikutoga.pmd.model.RigidShape;
+import jp.sfjp.mikutoga.pmd.model.SerialNumbered;
+import jp.sfjp.mikutoga.pmd.model.ShadeInfo;
+import jp.sfjp.mikutoga.pmd.model.Surface;
+import jp.sfjp.mikutoga.pmd.model.ToonMap;
+import jp.sfjp.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.corelib.I18nText;
 import jp.sourceforge.mikutoga.math.MkPos2D;
 import jp.sourceforge.mikutoga.math.MkPos3D;
@@ -22,30 +39,13 @@ import jp.sourceforge.mikutoga.pmd.MorphType;
 import jp.sourceforge.mikutoga.pmd.Rad3d;
 import jp.sourceforge.mikutoga.pmd.RigidShapeType;
 import jp.sourceforge.mikutoga.pmd.TripletRange;
-import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.DynamicsInfo;
-import jp.sourceforge.mikutoga.pmd.model.IKChain;
-import jp.sourceforge.mikutoga.pmd.model.JointInfo;
-import jp.sourceforge.mikutoga.pmd.model.Material;
-import jp.sourceforge.mikutoga.pmd.model.MorphPart;
-import jp.sourceforge.mikutoga.pmd.model.MorphVertex;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.RigidGroup;
-import jp.sourceforge.mikutoga.pmd.model.RigidInfo;
-import jp.sourceforge.mikutoga.pmd.model.RigidShape;
-import jp.sourceforge.mikutoga.pmd.model.SerialNumbered;
-import jp.sourceforge.mikutoga.pmd.model.ShadeInfo;
-import jp.sourceforge.mikutoga.pmd.model.Surface;
-import jp.sourceforge.mikutoga.pmd.model.ToonMap;
-import jp.sourceforge.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.xml.BasicXmlExporter;
 import jp.sourceforge.mikutoga.xml.XmlResourceResolver;
 
 /**
  * 101009形式XMLでPMDモデルデータを出力する。
  */
-public class Xml101009Exporter extends BasicXmlExporter{
+public class XmlExporter extends BasicXmlExporter{
 
     private static final String TOP_COMMENT =
               "  MikuMikuDance\n"
@@ -93,17 +93,51 @@ public class Xml101009Exporter extends BasicXmlExporter{
 
     private String generator = null;
 
+    private XmlModelFileType xmlType = XmlModelFileType.XML_101009;
+
+
     /**
      * コンストラクタ。
      * 文字エンコーディングはUTF-8が用いられる。
      * @param stream 出力ストリーム
      */
-    public Xml101009Exporter(OutputStream stream){
+    public XmlExporter(OutputStream stream){
         super(stream);
         return;
     }
 
     /**
+     * 出力XMLファイル種別を返す。
+     * @return ファイル種別
+     */
+    public XmlModelFileType getXmlFileType(){
+        return this.xmlType;
+    }
+
+    /**
+     * 出力XMLファイル種別を設定する。
+     * @param type ファイル種別
+     */
+    public void setXmlFileType(XmlModelFileType type){
+        switch(type){
+        case XML_101009:
+        case XML_130128:
+            this.xmlType = type;
+            break;
+        case XML_AUTO:
+            this.xmlType = XmlModelFileType.XML_130128;
+            break;
+        default:
+            throw new IllegalArgumentException();
+        }
+
+        assert this.xmlType == XmlModelFileType.XML_101009
+            || this.xmlType == XmlModelFileType.XML_130128;
+
+        return;
+    }
+
+    /**
      * Generatorメタ情報を設定する。
      * @param generatorArg Generatorメタ情報。表示したくないときはnull
      */
@@ -133,7 +167,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @throws IOException {@inheritDoc}
      */
     @Override
-    public Xml101009Exporter ind() throws IOException{
+    public XmlExporter ind() throws IOException{
         super.ind();
         return this;
     }
@@ -144,7 +178,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected Xml101009Exporter putUnescapedComment(CharSequence seq)
+    protected XmlExporter putUnescapedComment(CharSequence seq)
             throws IOException{
         if( ! isBasicLatinOnlyOut() ) return this;
         if(hasOnlyBasicLatin(seq)) return this;
@@ -159,7 +193,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected Xml101009Exporter putI18nName(I18nText text) throws IOException{
+    protected XmlExporter putI18nName(I18nText text) throws IOException{
         for(String lang639 : text.lang639CodeList()){
             if(lang639.equals(I18nText.CODE639_PRIMARY)) continue;
             String name = text.getI18nText(lang639);
@@ -181,7 +215,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected Xml101009Exporter putNumberedIdAttr(CharSequence attrName,
+    protected XmlExporter putNumberedIdAttr(CharSequence attrName,
                                                  CharSequence prefix,
                                                  int num )
             throws IOException{
@@ -199,7 +233,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected Xml101009Exporter putNumberedIdAttr(CharSequence attrName,
+    protected XmlExporter putNumberedIdAttr(CharSequence attrName,
                                                  CharSequence prefix,
                                                  SerialNumbered numbered )
             throws IOException{
@@ -213,7 +247,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected Xml101009Exporter putPosition(MkPos3D position)
+    protected XmlExporter putPosition(MkPos3D position)
             throws IOException{
         putRawText("<position ");
         putFloatAttr("x", (float) position.getXpos()).sp();
@@ -229,7 +263,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected Xml101009Exporter putRadRotation(Rad3d rotation)
+    protected XmlExporter putRadRotation(Rad3d rotation)
             throws IOException{
         putRawText("<radRotation ");
         putFloatAttr("xRad", rotation.getXRad()).sp();
@@ -245,7 +279,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected Xml101009Exporter putLocalNameComment(I18nText name)
+    protected XmlExporter putLocalNameComment(I18nText name)
             throws IOException{
         String localName = name.getText();
         if(localName.isEmpty()){
@@ -262,7 +296,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected Xml101009Exporter putPrimaryNameAttr(CharSequence attrName,
+    protected XmlExporter putPrimaryNameAttr(CharSequence attrName,
                                                    I18nText name)
             throws IOException{
         String primaryName = name.getPrimaryText();
@@ -288,16 +322,33 @@ public class Xml101009Exporter extends BasicXmlExporter{
         ind().putRawText("<pmdModel").ln();
         pushNest();
 
-        ind().putAttr("xmlns", Xml101009Resources.NS_PMDXML).ln();
+        String defns;
+        String xsduri;
+        String version;
+        if(this.xmlType == XmlModelFileType.XML_101009){
+            defns   = Schema101009.NS_PMDXML;
+            xsduri  = Schema101009.SCHEMA_PMDXML;
+            version = Schema101009.VER_PMDXML;
+        }else if(this.xmlType == XmlModelFileType.XML_130128){
+            defns   = Schema130128.NS_PMDXML;
+            xsduri  = Schema130128.SCHEMA_PMDXML;
+            version = Schema130128.VER_PMDXML;
+        }else{
+            assert false;
+            throw new AssertionError();
+        }
+
+        ind().putAttr("xmlns", defns).ln();
+
         ind().putAttr("xmlns:xsi", XmlResourceResolver.NS_XSD).ln();
 
         ind().putRawText("xsi:schemaLocation").putRawText("=\"");
-        putRawText(Xml101009Resources.NS_PMDXML).ln();
+        putRawText(defns).ln();
         pushNest();
-        ind().putRawText(Xml101009Resources.SCHEMA_PMDXML).putRawCh('"').ln();
+        ind().putRawText(xsduri).putRawCh('"').ln();
         popNest();
 
-        ind().putAttr("schemaVersion", Xml101009Resources.VER_PMDXML).ln(2);
+        ind().putAttr("schemaVersion", version).ln(2);
         ind().putPrimaryNameAttr("name", modelName).ln();
 
         popNest();
@@ -329,7 +380,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putModelInfo(PmdModel model)
+    private XmlExporter putModelInfo(PmdModel model)
             throws IOException{
         I18nText modelName = model.getModelName();
         putI18nName(modelName);
@@ -352,7 +403,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putDescription(CharSequence lang639,
+    private XmlExporter putDescription(CharSequence lang639,
                                               CharSequence content)
             throws IOException{
         String text = content.toString();
@@ -414,7 +465,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putMetaInfo(PmdModel model) throws IOException{
+    private XmlExporter putMetaInfo(PmdModel model) throws IOException{
         ind().putRawText("<license>").ln();
         ind().putRawText("</license>").ln(2);
 
@@ -444,7 +495,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putMaterialList(PmdModel model)
+    private XmlExporter putMaterialList(PmdModel model)
             throws IOException{
         ind().putRawText("<materialList>").ln();
 
@@ -471,7 +522,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putMaterial(Material material, int no)
+    private XmlExporter putMaterial(Material material, int no)
             throws IOException{
         String bool;
         if(material.getEdgeAppearance()) bool = "true";
@@ -565,7 +616,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putToonMap(PmdModel model)
+    private XmlExporter putToonMap(PmdModel model)
             throws IOException{
         ind().putRawText("<toonMap>").ln();
         pushNest();
@@ -587,7 +638,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putToon(ToonMap map, int index)
+    private XmlExporter putToon(ToonMap map, int index)
             throws IOException{
         putRawText("<toonDef ");
         putNumberedIdAttr("toonFileId", PFX_TOONFILE, index).sp();
@@ -605,7 +656,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putSurfaceGroupList(PmdModel model)
+    private XmlExporter putSurfaceGroupList(PmdModel model)
             throws IOException{
         ind().putRawText("<surfaceGroupList>").ln();
 
@@ -633,7 +684,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putSurfaceList(List<Surface> surfaceList,
+    private XmlExporter putSurfaceList(List<Surface> surfaceList,
                                               int index)
             throws IOException{
         ind().putRawText("<surfaceGroup ");
@@ -657,7 +708,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putSurface(Surface surface)
+    private XmlExporter putSurface(Surface surface)
             throws IOException{
         ind().putRawText("<surface ");
 
@@ -679,7 +730,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putVertexList(PmdModel model)
+    private XmlExporter putVertexList(PmdModel model)
             throws IOException{
         ind().putRawText("<vertexList>").ln();
 
@@ -704,7 +755,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putVertex(Vertex vertex)
+    private XmlExporter putVertex(Vertex vertex)
             throws IOException{
         String bool;
         if(vertex.getEdgeAppearance()) bool = "true";
@@ -753,7 +804,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putBoneList(PmdModel model)
+    private XmlExporter putBoneList(PmdModel model)
             throws IOException{
         ind().putRawText("<boneList>").ln();
         pushNest();
@@ -779,7 +830,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putBone(BoneInfo bone)
+    private XmlExporter putBone(BoneInfo bone)
             throws IOException{
         I18nText i18nName = bone.getBoneName();
         BoneType type = bone.getBoneType();
@@ -806,16 +857,28 @@ public class Xml101009Exporter extends BasicXmlExporter{
         MkPos3D position = bone.getPosition();
         ind().putPosition(position).ln();
 
-        BoneInfo ikBone = bone.getIKBone();
+        BoneInfo srcBone = bone.getSrcBone();
         if(bone.getBoneType() == BoneType.LINKEDROT){
             ind().putRawText("<rotationRatio ");
             putIntAttr("ratio", bone.getRotationRatio());
             putRawText(" />").ln();
-        }else if(ikBone != null){
-            ind().putRawText("<ikBone ");
-            putNumberedIdAttr("boneIdRef", PFX_BONE, ikBone);
+        }else if(srcBone != null){
+            String iktag;
+            switch(getXmlFileType()){
+            case XML_101009:
+                iktag = "<ikBone ";
+                break;
+            case XML_130128:
+                iktag = "<sourceBone ";
+                break;
+            default:
+                assert false;
+                throw new AssertionError();
+            }
+            ind().putRawText(iktag);
+            putNumberedIdAttr("boneIdRef", PFX_BONE, srcBone);
             putRawText(" /> ");
-            String ikBoneName = "Ref:" + ikBone.getBoneName().getText();
+            String ikBoneName = "Ref:" + srcBone.getBoneName().getText();
             putLineComment(ikBoneName);
             ln();
         }
@@ -865,7 +928,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putBoneGroupList(PmdModel model)
+    private XmlExporter putBoneGroupList(PmdModel model)
             throws IOException{
         ind().putRawText("<boneGroupList>").ln();
 
@@ -891,7 +954,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putBoneGroup(BoneGroup group)
+    private XmlExporter putBoneGroup(BoneGroup group)
             throws IOException{
         I18nText i18nName = group.getGroupName();
 
@@ -923,7 +986,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putIKChainList(PmdModel model)
+    private XmlExporter putIKChainList(PmdModel model)
             throws IOException{
         ind().putRawText("<ikChainList>").ln();
 
@@ -948,7 +1011,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putIKChain(IKChain chain)
+    private XmlExporter putIKChain(IKChain chain)
             throws IOException{
         int depth = chain.getIKDepth();
         float weight = chain.getIKWeight();
@@ -982,7 +1045,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putMorphList(PmdModel model)
+    private XmlExporter putMorphList(PmdModel model)
             throws IOException{
         ind().putRawText("<morphList>").ln();
         pushNest();
@@ -1014,7 +1077,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putMorphPart(MorphPart part)
+    private XmlExporter putMorphPart(MorphPart part)
             throws IOException{
         I18nText i18nName = part.getMorphName();
         String primary = i18nName.getPrimaryText();
@@ -1054,7 +1117,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putRigidList(PmdModel model)
+    private XmlExporter putRigidList(PmdModel model)
             throws IOException{
         ind().putRawText("<rigidList>").ln();
         pushNest();
@@ -1080,7 +1143,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putRigid(RigidInfo rigid)
+    private XmlExporter putRigid(RigidInfo rigid)
             throws IOException{
         BoneInfo linkedBone = rigid.getLinkedBone();
         I18nText i18nName = rigid.getRigidName();
@@ -1136,7 +1199,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putRigidShape(RigidShape shape)
+    private XmlExporter putRigidShape(RigidShape shape)
             throws IOException{
         RigidShapeType type = shape.getShapeType();
 
@@ -1172,7 +1235,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putDynamics(DynamicsInfo dynamics)
+    private XmlExporter putDynamics(DynamicsInfo dynamics)
             throws IOException{
         ind().putRawText("<dynamics").ln();
         pushNest();
@@ -1195,7 +1258,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putRigidGroupList(PmdModel model)
+    private XmlExporter putRigidGroupList(PmdModel model)
             throws IOException{
         ind().putRawText("<rigidGroupList>").ln(2);
         pushNest();
@@ -1248,7 +1311,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putJointList(PmdModel model)
+    private XmlExporter putJointList(PmdModel model)
             throws IOException{
         ind().putRawText("<jointList>").ln();
 
@@ -1273,7 +1336,7 @@ public class Xml101009Exporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private Xml101009Exporter putJoint(JointInfo joint)
+    private XmlExporter putJoint(JointInfo joint)
             throws IOException{
         I18nText i18nName = joint.getJointName();
 
@@ -5,18 +5,36 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sfjp.mikutoga.pmd.xml101009;
+package jp.sfjp.mikutoga.pmd.xml;
 
 import java.awt.Color;
 import java.io.IOException;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import javax.xml.parsers.DocumentBuilder;
+import jp.sfjp.mikutoga.pmd.model.BoneGroup;
+import jp.sfjp.mikutoga.pmd.model.BoneInfo;
+import jp.sfjp.mikutoga.pmd.model.DynamicsInfo;
+import jp.sfjp.mikutoga.pmd.model.IKChain;
+import jp.sfjp.mikutoga.pmd.model.JointInfo;
+import jp.sfjp.mikutoga.pmd.model.ListUtil;
+import jp.sfjp.mikutoga.pmd.model.Material;
+import jp.sfjp.mikutoga.pmd.model.MorphPart;
+import jp.sfjp.mikutoga.pmd.model.MorphVertex;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.model.RigidGroup;
+import jp.sfjp.mikutoga.pmd.model.RigidInfo;
+import jp.sfjp.mikutoga.pmd.model.RigidShape;
+import jp.sfjp.mikutoga.pmd.model.ShadeInfo;
+import jp.sfjp.mikutoga.pmd.model.Surface;
+import jp.sfjp.mikutoga.pmd.model.ToonMap;
+import jp.sfjp.mikutoga.pmd.model.Vertex;
 import jp.sourceforge.mikutoga.corelib.I18nText;
-import jp.sourceforge.mikutoga.pmd.model.ListUtil;
 import jp.sourceforge.mikutoga.math.MkPos2D;
 import jp.sourceforge.mikutoga.math.MkPos3D;
 import jp.sourceforge.mikutoga.math.MkVec3D;
@@ -27,37 +45,25 @@ import jp.sourceforge.mikutoga.pmd.Rad3d;
 import jp.sourceforge.mikutoga.pmd.RigidBehaviorType;
 import jp.sourceforge.mikutoga.pmd.RigidShapeType;
 import jp.sourceforge.mikutoga.pmd.TripletRange;
-import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
-import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
-import jp.sourceforge.mikutoga.pmd.model.DynamicsInfo;
-import jp.sourceforge.mikutoga.pmd.model.IKChain;
-import jp.sourceforge.mikutoga.pmd.model.JointInfo;
-import jp.sourceforge.mikutoga.pmd.model.Material;
-import jp.sourceforge.mikutoga.pmd.model.MorphPart;
-import jp.sourceforge.mikutoga.pmd.model.MorphVertex;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.RigidGroup;
-import jp.sourceforge.mikutoga.pmd.model.RigidInfo;
-import jp.sourceforge.mikutoga.pmd.model.RigidShape;
-import jp.sourceforge.mikutoga.pmd.model.ShadeInfo;
-import jp.sourceforge.mikutoga.pmd.model.Surface;
-import jp.sourceforge.mikutoga.pmd.model.ToonMap;
-import jp.sourceforge.mikutoga.pmd.model.Vertex;
+import jp.sourceforge.mikutoga.xml.DomNsUtils;
 import jp.sourceforge.mikutoga.xml.DomUtils;
 import jp.sourceforge.mikutoga.xml.TogaXmlException;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 /**
- * 101009形式XML形式でのモデルファイルを読み込む。
+ * XML形式でのモデルファイルを読み込む。
  */
-public class Xml101009Loader {
+public class XmlLoader {
+
+    private static final String ERR_INVROOT =
+            "invalid root element[{0}]";
+    private static final String ERR_UKVER =
+            "unknown schema version[{0}]";
 
-    private final DocumentBuilder builder;
 
     private PmdModel model;
 
@@ -74,17 +80,19 @@ public class Xml101009Loader {
     private final Map<String, RigidGroup> rigidGroupMap =
             new HashMap<String, RigidGroup>();
 
+    private String rootNamespace = Schema130128.NS_PMDXML;
+    private XmlModelFileType fileType = XmlModelFileType.XML_AUTO;
+
 
     /**
      * コンストラクタ。
-     * @param builder ビルダ
      */
-    public Xml101009Loader(DocumentBuilder builder){
+    public XmlLoader(){
         super();
-        this.builder = builder;
         return;
     }
 
+
     /**
      * 要素からxsd:string型属性値を読み取る。
      * @param elem 要素
@@ -147,62 +155,8 @@ public class Xml101009Loader {
     }
 
     /**
-     * 指定された名前の子要素を1つだけ返す。
-     * @param parent 親要素
-     * @param tagName 子要素名
-     * @return 子要素
-     * @throws TogaXmlException 1つも見つからなかった
-     */
-    private static Element getChild(Element parent, String tagName)
-            throws TogaXmlException{
-        return DomUtils.getChild(parent, tagName);
-    }
-
-    /**
-     * 親要素が指定された名前の子要素を持つか判定する。
-     * @param parent 親要素
-     * @param tagName 子要素名
-     * @return 指定名の子要素が存在すればtrue
-     */
-    private static boolean hasChild(Element parent, String tagName){
-        return DomUtils.hasChild(parent, tagName);
-    }
-
-    /**
-     * 指定された名前の子要素のforeachを返す。
-     * @param parent 親要素
-     * @param childTag 子要素名
-     * @return 子要素のforeach
-     */
-    private static Iterable<Element> eachChild(Element parent,
-                                                    String childTag){
-        return DomUtils.getEachChild(parent, childTag);
-    }
-
-    /**
-     * グローバル名を取得する。
-     * 元要素のname属性及びi18nNameタグを持つ子要素が検索対象
-     * @param parent 元要素
-     * @return グローバル名。なければnull
-     */
-    private static String getGlobalName(Element parent){
-        NodeList nodeList = parent.getElementsByTagName("i18nName");
-        int length = nodeList.getLength();
-        for(int idx = 0; idx < length; idx++){
-            Node i18nNameNode = nodeList.item(idx);
-            Element i18nNameElem = (Element)i18nNameNode;
-            String lang = i18nNameElem.getAttribute("lang");
-            if(lang == null || lang.length() <= 0) continue;
-            if(lang.equals("en")){
-                String name = i18nNameElem.getAttribute("name");
-                return name;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * brタグで区切られた文字列内容(Mixed content)を改行付き文字列に変換する。
+     * brタグで区切られた文字列内容(Mixed content)を
+     * 改行付き文字列に変換する。
      * brタグはその出現回数だけ\nに変換される。
      * 生文字列コンテンツ中の\n,\rは削除される。
      * 改行文字以外のホワイトスペースは保持される。
@@ -238,13 +192,89 @@ public class Xml101009Loader {
         return result.toString();
     }
 
+
+    /**
+     * パース中のXMLファイル種別を返す。
+     * @return ファイル種別
+     */
+    private XmlModelFileType getFileType(){
+        return this.fileType;
+    }
+
+    /**
+     * パース中のXMLファイル種別を設定する。
+     * @param type 具体的なファイル種別
+     */
+    private void setFileType(XmlModelFileType type){
+        if(   type != XmlModelFileType.XML_101009
+           && type != XmlModelFileType.XML_130128 ){
+            throw new IllegalArgumentException();
+        }
+        this.fileType = type;
+        return;
+    }
+
+    /**
+     * ルート要素の名前空間URIを返す。
+     * @return 名前空間URI。nullなら名前空間が無いと見なされる
+     */
+    private String getRootNamespace(){
+        return this.rootNamespace;
+    }
+
+    /**
+     * ルート要素の名前空間URIを設定する。
+     * @param name 名前空間URI。nullなら名前空間が無いと見なされる
+     */
+    private void setRootNamespace(String name){
+        this.rootNamespace = name;
+        return;
+    }
+
+    /**
+     * 指定された名前の子要素を1つだけ返す。
+     * @param parent 親要素
+     * @param tagName 子要素名
+     * @return 子要素
+     * @throws TogaXmlException 1つも見つからなかった
+     */
+    private Element getChild(Element parent, String tagName)
+            throws TogaXmlException{
+        String ns = getRootNamespace();
+        Element result = DomNsUtils.getFirstChild(parent, ns, tagName);
+        return result;
+    }
+
+    /**
+     * 親要素が指定された名前の子要素を持つか判定する。
+     * @param parent 親要素
+     * @param tagName 子要素名
+     * @return 指定名の子要素が存在すればtrue
+     */
+    private boolean hasChild(Element parent, String tagName){
+        String ns = getRootNamespace();
+        return DomNsUtils.hasChild(parent, ns, tagName);
+    }
+
+    /**
+     * 指定された名前の子要素のforeachを返す。
+     * @param parent 親要素
+     * @param childTag 子要素名
+     * @return 子要素のforeach
+     */
+    private Iterable<Element> eachChild(Element parent,
+                                         String childTag){
+        String ns = getRootNamespace();
+        return DomNsUtils.getEachChild(parent, ns, childTag);
+    }
+
     /**
      * 多言語名を取得する。
      * @param baseElement 元要素
-     * @param text 多言語名
+     * @param text 多言語名格納先
      * @throws TogaXmlException あるべき属性が存在しない。
      */
-    private static void buildI18nName(Element baseElement, I18nText text)
+    private void buildI18nName(Element baseElement, I18nText text)
             throws TogaXmlException{
         String primaryText;
         primaryText = getStringAttr(baseElement, "name");
@@ -265,19 +295,33 @@ public class Xml101009Loader {
 
     /**
      * XMLのパースを開始する。
+     * @param builder ドキュメントビルダ
      * @param source XML入力
      * @return モデルデータ
      * @throws SAXException 構文エラー
      * @throws IOException 入力エラー
      * @throws TogaXmlException 構文エラー
      */
-    public PmdModel parse(InputSource source)
+    public PmdModel parse(DocumentBuilder builder, InputSource source)
             throws SAXException, IOException, TogaXmlException{
-        Document document = this.builder.parse(source);
+        Document document = builder.parse(source);
+        PmdModel result = parse(document);
+        return result;
+    }
 
+    /**
+     * XMLのパースを開始する。
+     * @param document DOMドキュメント
+     * @return モデルデータ
+     * @throws TogaXmlException 構文エラー
+     */
+    public PmdModel parse(Document document)
+            throws TogaXmlException{
         this.model = new PmdModel();
 
         Element pmdModelElem = document.getDocumentElement();
+        String namespace = pmdModelElem.getNamespaceURI();
+        setRootNamespace(namespace);
 
         buildBasicInfo(pmdModelElem);
 
@@ -300,14 +344,33 @@ public class Xml101009Loader {
         return this.model;
     }
 
+    /**
+     * DOMからモデル基本情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildBasicInfo(Element pmdModelElem)
             throws TogaXmlException{
-        String primaryName = getStringAttr(pmdModelElem, "name");
-        String globalName = getGlobalName(pmdModelElem);
+        if( ! DomNsUtils.hasNsLocalNameElem(pmdModelElem,
+                                            getRootNamespace(),
+                                            "pmdModel") ){
+            String tagName = pmdModelElem.getTagName();
+            String msg = MessageFormat.format(ERR_INVROOT, tagName);
+            throw new TogaXmlException(msg);
+        }
+
+        String version = getStringAttr(pmdModelElem, "schemaVersion");
+        if(Schema101009.VER_PMDXML.equals(version)){
+            setFileType(XmlModelFileType.XML_101009);
+        }else if(Schema130128.VER_PMDXML.equals(version)){
+            setFileType(XmlModelFileType.XML_130128);
+        }else{
+            String msg = MessageFormat.format(ERR_UKVER, version);
+            throw new TogaXmlException(msg);
+        }
 
         I18nText modelName = this.model.getModelName();
-        modelName.setPrimaryText(primaryName);
-        modelName.setGlobalText(globalName);
+        buildI18nName(pmdModelElem, modelName);
 
         String primaryDescription = null;
         String globalDescription = null;
@@ -333,24 +396,11 @@ public class Xml101009Loader {
         return;
     }
 
-    private void buildToonMap(Element pmdModelElem)
-            throws TogaXmlException{
-        ToonMap toonMap = this.model.getToonMap();
-
-        Element toonMapElem = getChild(pmdModelElem, "toonMap");
-
-        for(Element toonDefElem : eachChild(toonMapElem, "toonDef")){
-            String toonFileId = getStringAttr(toonDefElem, "toonFileId");
-            int toonIndex = getIntegerAttr(toonDefElem, "index");
-            String toonFile = getSjisFileNameAttr(toonDefElem, "winFileName");
-
-            toonMap.setIndexedToon(toonIndex, toonFile);
-            this.toonIdxMap.put(toonFileId, toonIndex);
-        }
-
-        return;
-    }
-
+    /**
+     * DOMからボーンリスト情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildBoneList(Element pmdModelElem)
             throws TogaXmlException{
         Element boneListElem = getChild(pmdModelElem, "boneList");
@@ -383,18 +433,23 @@ public class Xml101009Loader {
 
         ListUtil.assignIndexedSerial(boneList);
 
-        int serial = 0;
+        Iterator<BoneInfo> bit = boneList.iterator();
         for(Element boneElem : eachChild(boneListElem, "bone")){
-            BoneInfo boneInfo = boneList.get(serial++);
+            BoneInfo boneInfo = bit.next();
 
-            if(hasChild(boneElem, "ikBone")){
+            if(hasChild(boneElem, "ikBone")){            // 101009 only
                 Element ikBoneElem = getChild(boneElem, "ikBone");
                 String ikBoneId = getStringAttr(ikBoneElem, "boneIdRef");
                 BoneInfo ikBone = this.boneMap.get(ikBoneId);
-                boneInfo.setIKBone(ikBone);
+                boneInfo.setSrcBone(ikBone);
+            }else if(hasChild(boneElem, "sourceBone")){  // 130128 only
+                Element srcBoneElem = getChild(boneElem, "sourceBone");
+                String srcBoneId = getStringAttr(srcBoneElem, "boneIdRef");
+                BoneInfo srcBone = this.boneMap.get(srcBoneId);
+                boneInfo.setSrcBone(srcBone);
             }else if(hasChild(boneElem, "rotationRatio")){
-                Element ikBoneElem = getChild(boneElem, "rotationRatio");
-                int ratio = getIntegerAttr(ikBoneElem, "ratio");
+                Element rotElem = getChild(boneElem, "rotationRatio");
+                int ratio = getIntegerAttr(rotElem, "ratio");
                 boneInfo.setRotationRatio(ratio);
             }
 
@@ -414,6 +469,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOMから頂点リスト情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildVertexList(Element pmdModelElem)
             throws TogaXmlException{
         Element vertexListElem = getChild(pmdModelElem, "vertexList");
@@ -474,6 +534,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOMからポリゴンリスト情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildSurfaceList(Element pmdModelElem)
             throws TogaXmlException{
         Element surfaceGroupListElem =
@@ -488,8 +553,16 @@ public class Xml101009Loader {
 
             this.surfaceGroupMap.put(groupId, surfaceList);
         }
+
+        return;
     }
 
+    /**
+     * DOMからポリゴン情報を組み立てる。
+     * @param surfaceGroupElem surfaceGroup要素
+     * @return ポリゴンリスト
+     * @throws TogaXmlException 構文エラー
+     */
     private List<Surface> buildSurface(Element surfaceGroupElem)
             throws TogaXmlException{
         List<Surface> result = new ArrayList<Surface>();
@@ -512,6 +585,34 @@ public class Xml101009Loader {
         return result;
     }
 
+    /**
+     * DOMからトゥーンマップ情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
+    private void buildToonMap(Element pmdModelElem)
+            throws TogaXmlException{
+        ToonMap toonMap = this.model.getToonMap();
+
+        Element toonMapElem = getChild(pmdModelElem, "toonMap");
+
+        for(Element toonDefElem : eachChild(toonMapElem, "toonDef")){
+            String toonFileId = getStringAttr(toonDefElem, "toonFileId");
+            int toonIndex = getIntegerAttr(toonDefElem, "index");
+            String toonFile = getSjisFileNameAttr(toonDefElem, "winFileName");
+
+            toonMap.setIndexedToon(toonIndex, toonFile);
+            this.toonIdxMap.put(toonFileId, toonIndex);
+        }
+
+        return;
+    }
+
+    /**
+     * DOMからマテリアル情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildMaterialList(Element pmdModelElem)
             throws TogaXmlException{
         Element materialListElem =
@@ -596,6 +697,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOMからIKチェーンリスト情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildIkChainList(Element pmdModelElem)
             throws TogaXmlException{
         Element ikChainListElem =
@@ -629,6 +735,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOMからモーフリスト情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildMorphList(Element pmdModelElem)
             throws TogaXmlException{
         Element morphListElem =
@@ -690,6 +801,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOMからボーングループ情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildBoneGroupList(Element pmdModelElem)
             throws TogaXmlException{
         Element boneGroupListElem =
@@ -721,6 +837,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOMから剛体リスト情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildRigidList(Element pmdModelElem)
             throws TogaXmlException{
         Element rigidListElem =
@@ -821,6 +942,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOMから剛体グループリスト情報を組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildRigidGroupList(Element pmdModelElem)
             throws TogaXmlException{
         Element rigidGroupListElem =
@@ -856,6 +982,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOM内の剛体衝突情報を解決する。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void resolveThroughRigidGroup(Element pmdModelElem)
             throws TogaXmlException{
         Element rigidListElem =
@@ -863,9 +994,9 @@ public class Xml101009Loader {
 
         List<RigidInfo> rigidList = this.model.getRigidList();
 
-        int serialNum = 0;
+        Iterator<RigidInfo> rit = rigidList.iterator();
         for(Element rigidElem : eachChild(rigidListElem, "rigid")){
-            RigidInfo rigid = rigidList.get(serialNum++);
+            RigidInfo rigid = rit.next();
             for(Element groupElem
                     : eachChild(rigidElem, "throughRigidGroup")){
                 String groupId = getStringAttr(groupElem, "rigidGroupIdRef");
@@ -877,6 +1008,11 @@ public class Xml101009Loader {
         return;
     }
 
+    /**
+     * DOMからジョイントリストを組み立てる。
+     * @param pmdModelElem ルート要素
+     * @throws TogaXmlException 構文エラー
+     */
     private void buildJointList(Element pmdModelElem)
             throws TogaXmlException{
         Element jointListElem =
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd/xml/XmlModelFileType.java b/src/main/java/jp/sfjp/mikutoga/pmd/xml/XmlModelFileType.java
new file mode 100644 (file)
index 0000000..981e693
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * MMD model xml file types.
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd.xml;
+
+/**
+ * XMLファイルスキーマ種別。
+ */
+public enum XmlModelFileType {
+
+    /**
+     * XMLファイル。
+     * <p>読み込み時のスキーマ判別は自動。
+     * 出力時のスキーマ種別は最新。
+     */
+    XML_AUTO,
+
+    /**
+     * スキーマ
+     * http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd
+     * で定義されたXMLファイル。
+     */
+    XML_101009,
+
+    /**
+     * スキーマ
+     * http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-130128.xsd
+     * で定義されたXMLファイル。
+     */
+    XML_130128,
+
+}
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd/xml/package-info.java b/src/main/java/jp/sfjp/mikutoga/pmd/xml/package-info.java
new file mode 100644 (file)
index 0000000..848c3f0
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * package information for Javadoc
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+/**
+ * PMDモデル内容をXMLで出力するためのライブラリ。
+ */
+
+package jp.sfjp.mikutoga.pmd.xml;
+
+/* EOF */
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd/xml101009/Xml101009Resources.java b/src/main/java/jp/sfjp/mikutoga/pmd/xml101009/Xml101009Resources.java
deleted file mode 100644 (file)
index b9985fc..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * xml resources for PMD-XML
- *
- * License : The MIT License
- * Copyright(c) 2010 MikuToga Partners
- */
-
-package jp.sfjp.mikutoga.pmd.xml101009;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import jp.sourceforge.mikutoga.xml.XmlResourceResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-
-/**
- * 101009形式XML各種リソースの定義。
- */
-public final class Xml101009Resources {
-
-    public static final String NS_PMDXML =
-            "http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009";
-    public static final String SCHEMA_PMDXML =
-            "http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd";
-    public static final String DTD_PMDXML =
-            "http://mikutoga.sourceforge.jp/xml/dtd/pmdxml-101009.dtd";
-    public static final String VER_PMDXML =
-            "101009";
-    public static final String LOCAL_SCHEMA_PMDXML =
-            "resources/pmdxml-101009.xsd";
-    public static final String LOCAL_DTD_PMDXML =
-            "resources/pmdxml-101009.dtd";
-
-    public static final URI URI_SCHEMA_PMDXML = URI.create(SCHEMA_PMDXML);
-    public static final URI URI_DTD_PMDXML = URI.create(DTD_PMDXML);
-    public static final URI RES_SCHEMA_PMDXML;
-    public static final URI RES_DTD_PMDXML;
-
-    private static final Class THISCLASS = Xml101009Resources.class;
-
-    static{
-        Object dummy = new Xml101009Resources();
-
-        try{
-            RES_SCHEMA_PMDXML =
-                    THISCLASS.getResource(LOCAL_SCHEMA_PMDXML).toURI();
-            RES_DTD_PMDXML =
-                    THISCLASS.getResource(LOCAL_DTD_PMDXML).toURI();
-        }catch(URISyntaxException e){
-            throw new ExceptionInInitializerError(e);
-        }
-    }
-
-    /**
-     * 隠しコンストラクタ。
-     */
-    private Xml101009Resources(){
-        super();
-        assert this.getClass().equals(THISCLASS);
-        return;
-    }
-
-    /**
-     * ビルダの生成。
-     * @param handler エラーハンドラ
-     * @return ビルダ
-     * @throws SAXException パースエラー
-     * @throws ParserConfigurationException 構成エラー
-     */
-    public static DocumentBuilder newBuilder(ErrorHandler handler)
-            throws SAXException, ParserConfigurationException {
-        XmlResourceResolver resolver = new XmlResourceResolver();
-        resolver.putURIMap(URI_SCHEMA_PMDXML, RES_SCHEMA_PMDXML);
-        resolver.putURIMap(URI_DTD_PMDXML, RES_DTD_PMDXML);
-
-        SchemaFactory schemaFactory =
-                SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        schemaFactory.setResourceResolver(resolver);
-        schemaFactory.setErrorHandler(handler);
-        Schema schema = schemaFactory.newSchema();
-
-        DocumentBuilderFactory builderFactory =
-                DocumentBuilderFactory.newInstance();
-        builderFactory.setCoalescing(true);
-        builderFactory.setExpandEntityReferences(true);
-        builderFactory.setIgnoringComments(true);
-        builderFactory.setIgnoringElementContentWhitespace(false);
-        builderFactory.setNamespaceAware(true);
-        builderFactory.setValidating(false);
-        builderFactory.setSchema(schema);
-
-        DocumentBuilder builder = builderFactory.newDocumentBuilder();
-        builder.setEntityResolver(resolver);
-        builder.setErrorHandler(handler);
-
-        return builder;
-    }
-
-}
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd/xml101009/package-info.java b/src/main/java/jp/sfjp/mikutoga/pmd/xml101009/package-info.java
deleted file mode 100644 (file)
index fce5203..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * package information for Javadoc
- *
- * License : The MIT License
- * Copyright(c) 2010 MikuToga Partners
- */
-
-/**
- * PMDモデル内容を101009版XMLで出力するためのライブラリ。
- */
-
-package jp.sfjp.mikutoga.pmd.xml101009;
-
-/* EOF */
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/CmdLine.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/CmdLine.java
new file mode 100644 (file)
index 0000000..584f177
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * command line parser
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * コマンドラインの1オプションとその引数群に相当。
+ */
+class CmdLine {
+
+    private OptSwitch opt;
+    private List<String> optArgs;
+
+
+    /**
+     * コンストラクタ。
+     */
+    private CmdLine() {
+        super();
+        return;
+    }
+
+
+    /**
+     * コマンドライン解析を行う。
+     * @param args コマンドライン
+     * @return 解析されたコマンドライン並び
+     */
+    static List<CmdLine> parse(String... args){
+        List<String> list = Arrays.asList(args);
+        return parse(list);
+    }
+
+    /**
+     * コマンドライン解析を行う。
+     * @param argList コマンドライン
+     * @return 解析されたコマンドライン並び
+     */
+    static List<CmdLine> parse(List<String> argList){
+        List<CmdLine> result = new LinkedList<CmdLine>();
+
+        Iterator<String> it = argList.iterator();
+        while (it.hasNext()) {
+            String arg = it.next();
+
+            CmdLine info = new CmdLine();
+            result.add(info);
+
+            info.opt = OptSwitch.parse(arg);
+
+            int exArgNum = 0;
+            if (info.opt != null) {
+                exArgNum = info.opt.getExArgNum();
+            }
+            info.optArgs = new ArrayList<String>(exArgNum + 1);
+
+            info.optArgs.add(arg);
+
+            for (int argCt = 0; argCt < exArgNum; argCt++) {
+                if ( ! it.hasNext()) {
+                    break;
+                }
+                String exarg = it.next();
+                info.optArgs.add(exarg);
+            }
+        }
+
+        return result;
+    }
+
+
+    /**
+     * オプション識別子を返す。
+     * @return オプション識別子。
+     * オプションを伴わない単純なコマンドライン引数の場合はnullを返す。
+     */
+    OptSwitch getOptSwitch() {
+        return this.opt;
+    }
+
+    /**
+     * オプションに付随する引数群を返す。
+     * @return オプションに付随する引数群。
+     * 先頭要素はオプション識別子。
+     * 単純なコマンドライン引数の場合は自身が1要素のみを占める。
+     */
+    List<String> getOptArgs() {
+        return this.optArgs;
+    }
+
+}
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/CmdLineException.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/CmdLineException.java
new file mode 100644 (file)
index 0000000..066f886
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * command line exception
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+/**
+ * コマンドライン引数の不備による異常系。
+ */
+@SuppressWarnings("serial")
+class CmdLineException extends Exception{
+
+    /**
+     * コンストラクタ。
+     * @param message {@inheritDoc}
+     */
+    public CmdLineException(String message) {
+        super(message);
+        return;
+    }
+
+}
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/ModelFileType.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/ModelFileType.java
new file mode 100644 (file)
index 0000000..ae2c411
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * MMD model file types.
+ *
+ * License : The MIT License
+ * Copyright(c) 2012 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+import jp.sfjp.mikutoga.pmd.xml.XmlModelFileType;
+
+/**
+ * モデルファイル種別。
+ */
+public enum ModelFileType {
+
+    /**
+     * 不明。
+     */
+    NONE,
+
+    /**
+     * MikuMikuDance ver7 前後で読み書きが可能なPMDファイル。
+     */
+    PMD,
+
+    /**
+     * XMLファイル。
+     * <p>読み込み時のスキーマ判別は自動。
+     * <p>書き込み時のスキーマは最新。
+     */
+    XML_AUTO,
+
+    /**
+     * スキーマ
+     * http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd
+     * で定義されたXMLファイル。
+     */
+    XML_101009,
+
+    /**
+     * スキーマ
+     * http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-130128.xsd
+     * で定義されたXMLファイル。
+     */
+    XML_130128,
+
+    ;
+
+
+    /**
+     * コンストラクタ。
+     */
+    private ModelFileType(){
+        return;
+    }
+
+    /**
+     * ファイル種別をXMLファイル種別に変換する。
+     * <p>未定義の場合はXML_AUTOを返す。
+     * @return XMLファイル種別
+     */
+    public XmlModelFileType toXmlType(){
+        XmlModelFileType result;
+
+        switch(this){
+        case XML_101009:
+            result = XmlModelFileType.XML_101009;
+            break;
+        case XML_130128:
+            result = XmlModelFileType.XML_130128;
+            break;
+        case XML_AUTO:
+            result = XmlModelFileType.XML_AUTO;
+            break;
+        default:
+            result = XmlModelFileType.XML_AUTO;
+            break;
+        }
+
+        return result;
+    }
+
+    /**
+     * ファイル種別がXMLか判定する。
+     * @return XMLならtrue
+     */
+    public boolean isXml(){
+        boolean result;
+
+        switch(this){
+        case XML_101009:
+        case XML_130128:
+        case XML_AUTO:
+            result = true;
+            break;
+        default:
+            result = false;
+            break;
+        }
+
+        return result;
+    }
+
+    /**
+     * ファイル種別がPMDか判定する。
+     * @return PMDならtrue
+     */
+    public boolean isPmd(){
+        boolean result;
+
+        switch(this){
+        case PMD:
+            result = true;
+            break;
+        default:
+            result = false;
+            break;
+        }
+
+        return result;
+    }
+
+}
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java
new file mode 100644 (file)
index 0000000..f9c4bc8
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * command line argument info
+ *
+ * License : The MIT License
+ * Copyright(c) 2012 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+/**
+ * コマンドラインオプション情報。
+ */
+final class OptInfo {
+
+    private static final String EOL_LF = "\n";
+    private static final String EOL_CRLF = "\r\n";
+    private static final String EOL_DEFAULT = EOL_LF;
+
+    private static final String FORMAT_PMD       = "pmd";
+    private static final String FORMAT_XML       = "xml";
+    private static final String FORMAT_XML101009 = "xml101009";
+    private static final String FORMAT_XML130128 = "xml130128";
+
+    private static final String SFX_PMD = ".pmd";
+    private static final String SFX_XML = ".xml";
+
+    private static final String NL_LF   =   "lf";
+    private static final String NL_CRLF = "crlf";
+
+    private static final String GENERATOR =
+            Pmd2Xml.APPNAME + ' ' + Pmd2Xml.APPVER;
+
+    private static final String ERRMSG_UNKNOWN =
+            "Unknown option : {0}";
+    private static final String ERRMSG_MOREARG =
+            "You need option arg with : {0}";
+    private static final String ERRMSG_INTYPE =
+            "You must specify input format with -iform.";
+    private static final String ERRMSG_OUTTYPE =
+            "You must specify output format with -oform.";
+    private static final String ERRMSG_NOINFILE =
+            "You must specify input file with -i.";
+    private static final String ERRMSG_NOOUTFILE =
+            "You must specify output file with -o.";
+    private static final String ERRMSG_INVFORM =
+            "Unknown format : \"{0}\" must be \"pmd\" or \"xml\" "
+            + "or \"xml101009\" or \"xml130128\"";
+    private static final String ERRMSG_INVNL =
+            "Unknown newline : \"{0}\" must be \"lf\" or \"crlf\"";
+    private static final String ERRMSG_INVBOOL =
+            "Unknown switch : \"{0}\" must be \"on\" or \"off\"";
+
+
+    private boolean needHelp = false;
+    private ModelFileType inTypes  = ModelFileType.NONE;
+    private ModelFileType outTypes = ModelFileType.NONE;
+    private String inFilename = null;
+    private String outFilename = null;
+    private boolean overwrite = false;
+    private String newline = EOL_DEFAULT;
+    private String generator = GENERATOR;
+
+
+    /**
+     * コンストラクタ。
+     */
+    private OptInfo(){
+        super();
+        return;
+    }
+
+
+    /**
+     * フォーマット種別指定子をデコードする。
+     * @param arg 文字列
+     * @return デコード結果。
+     * @throws CmdLineException 不正なフォーマット種別
+     */
+    private static ModelFileType decodeFormatType(String arg)
+            throws CmdLineException{
+        ModelFileType result;
+
+        if      (FORMAT_PMD.equals(arg)){
+            result = ModelFileType.PMD;
+        }else if(FORMAT_XML.equals(arg)){
+            result = ModelFileType.XML_AUTO;
+        }else if(FORMAT_XML101009.equals(arg)){
+            result = ModelFileType.XML_101009;
+        }else if(FORMAT_XML130128.equals(arg)){
+            result = ModelFileType.XML_130128;
+        }else{
+            String errMsg = MessageFormat.format(ERRMSG_INVFORM, arg);
+            throw new CmdLineException(errMsg);
+        }
+
+        return result;
+    }
+
+    /**
+     * 改行文字指定子をデコードする。
+     * @param arg 文字列
+     * @return デコード結果。
+     * @throws CmdLineException 不正なフォーマット種別
+     */
+    private static String decodeNewline(String arg)
+            throws CmdLineException{
+        String result;
+
+        if      (NL_LF.equals(arg)){
+            result = EOL_LF;
+        }else if(NL_CRLF.equals(arg)){
+            result = EOL_CRLF;
+        }else{
+            String errMsg = MessageFormat.format(ERRMSG_INVNL, arg);
+            throw new CmdLineException(errMsg);
+        }
+
+        return result;
+    }
+
+    /**
+     * ブール指定子をデコードする。
+     * @param arg 文字列
+     * @return デコード結果。
+     * @throws CmdLineException 不正なフォーマット種別
+     */
+    private static boolean decodeBoolean(String arg)
+            throws CmdLineException{
+        boolean result;
+
+        if(   "on"  .equals(arg)
+           || "true".equals(arg)
+           || "yes" .equals(arg) ){
+            result = true;
+        }else if(   "off"  .equals(arg)
+                 || "false".equals(arg)
+                 || "no"   .equals(arg) ){
+            result = false;
+        }else{
+            String errMsg = MessageFormat.format(ERRMSG_INVBOOL, arg);
+            throw new CmdLineException(errMsg);
+        }
+
+        return result;
+    }
+
+    /**
+     * ファイル名からファイル種別を類推する。
+     * <p>拡張子が「pmd」ならPMDファイル、「xml」ならXMLファイル。
+     * @param fileName ファイル名
+     * @return ファイル種別
+     */
+    private static ModelFileType getFileType(String fileName){
+        ModelFileType result = ModelFileType.NONE;
+        if(fileName == null) return result;
+
+        String lower = fileName.toLowerCase();
+        if     (lower.endsWith(SFX_PMD)) result = ModelFileType.PMD;
+        else if(lower.endsWith(SFX_XML)) result = ModelFileType.XML_AUTO;
+
+        return result;
+    }
+
+    /**
+     * コマンドラインを解析する。
+     * @param args コマンドライン
+     * @return オプション情報
+     * @throws CmdLineException 不正なコマンドライン
+     */
+    static OptInfo parseOption(String... args) throws CmdLineException{
+        OptInfo result = new OptInfo();
+
+        List<CmdLine> cmdLines = CmdLine.parse(args);
+        for(CmdLine cmd : cmdLines){
+            OptSwitch opt = cmd.getOptSwitch();
+            if(opt == OptSwitch.OPT_HELP){
+                result.needHelp = true;
+                return result;
+            }
+        }
+
+        checkCmdLineList(cmdLines);
+
+        for(CmdLine cmd : cmdLines){
+            List<String> optArgs = cmd.getOptArgs();
+            String exArg1 = null;
+            if(optArgs.size() >= 2){
+                exArg1 = optArgs.get(1);
+            }
+
+            OptSwitch opt = cmd.getOptSwitch();
+            switch(opt){
+            case OPT_HELP:
+                break;
+            case OPT_FORCE:
+                result.overwrite = true;
+                break;
+            case OPT_INFILE:
+                result.inFilename = exArg1;
+                break;
+            case OPT_OUTFILE:
+                result.outFilename = exArg1;
+                break;
+            case OPT_NEWLINE:
+                result.newline = decodeNewline(exArg1);
+                break;
+            case OPT_GENOUT:
+                boolean genout = decodeBoolean(exArg1);
+                if(genout) result.generator = GENERATOR;
+                else       result.generator = null;
+                break;
+            case OPT_IFORM:
+                ModelFileType itype = decodeFormatType(exArg1);
+                result.inTypes  = itype;
+                break;
+            case OPT_OFORM:
+                ModelFileType otype = decodeFormatType(exArg1);
+                result.outTypes  = otype;
+                break;
+            default:
+                assert false;
+                throw new AssertionError();
+            }
+        }
+
+        fixFormat(result);
+
+        checkResult(result);
+
+        return result;
+    }
+
+    /**
+     * 単純なコマンドラインエラーを検出する。
+     * <p>検出項目は未知のオプションおよび不正な引数の個数
+     * @param cmdLines コマンドライン
+     * @throws CmdLineException 異常系
+     */
+    private static void checkCmdLineList(List<CmdLine> cmdLines)
+            throws CmdLineException{
+        for(CmdLine cmd : cmdLines){
+            List<String> optArgs = cmd.getOptArgs();
+            assert optArgs.size() > 0;
+
+            String optTxt = optArgs.get(0);
+            assert optTxt != null;
+
+            OptSwitch opt = cmd.getOptSwitch();
+            if(opt == null){
+                String errMsg =
+                        MessageFormat.format(ERRMSG_UNKNOWN, optTxt);
+                throw new CmdLineException(errMsg);
+            }
+
+            int exArgNum = opt.getExArgNum();
+            if(optArgs.size() != 1 + exArgNum){
+                String errMsg =
+                        MessageFormat.format(ERRMSG_MOREARG, optTxt);
+                throw new CmdLineException(errMsg);
+            }
+        }
+
+        return;
+    }
+
+    /**
+     * ファイルフォーマット情報の推測を行う。
+     * @param result オプション情報
+     */
+    private static void fixFormat(OptInfo result){
+        if(result.inTypes == ModelFileType.NONE){
+            result.inTypes = getFileType(result.inFilename);
+        }
+
+        if(result.outTypes == ModelFileType.NONE){
+            result.outTypes = getFileType(result.outFilename);
+        }
+
+        return;
+    }
+
+    /**
+     * オプション整合性の事後検査。
+     * @param result オプション情報
+     * @throws CmdLineException 不正なオプション設定
+     */
+    private static void checkResult(OptInfo result)
+            throws CmdLineException{
+        if(result.getInFilename() == null){
+            throw new CmdLineException(ERRMSG_NOINFILE);
+        }
+
+        if(result.getOutFilename() == null){
+            throw new CmdLineException(ERRMSG_NOOUTFILE);
+        }
+
+        if(result.getInFileType()  == ModelFileType.NONE){
+            throw new CmdLineException(ERRMSG_INTYPE);
+        }
+
+        if(result.getOutFileType()  == ModelFileType.NONE){
+            throw new CmdLineException(ERRMSG_OUTTYPE);
+        }
+
+        return;
+    }
+
+
+    /**
+     * ヘルプ表示が必要か否か判定する。
+     * @return 必要ならtrue
+     */
+    boolean needHelp(){
+        return this.needHelp;
+    }
+
+    /**
+     * 入力ファイル種別を返す。
+     * @return 入力ファイル種別
+     */
+    ModelFileType getInFileType(){
+        return this.inTypes;
+    }
+
+    /**
+     * 出力ファイル種別を返す。
+     * @return 出力ファイル種別
+     */
+    ModelFileType getOutFileType(){
+        return this.outTypes;
+    }
+
+    /**
+     * 入力ファイル名を返す。
+     * @return 入力ファイル名
+     */
+    String getInFilename(){
+        return this.inFilename;
+    }
+
+    /**
+     * 出力ファイル名を返す。
+     * @return 出力ファイル名
+     */
+    String getOutFilename(){
+        return this.outFilename;
+    }
+
+    /**
+     * 上書きモードか否か返す。
+     * @return 上書きモードならtrue
+     */
+    boolean overwriteMode(){
+        return this.overwrite;
+    }
+
+    /**
+     * XML改行文字を返す。
+     * @return 改行文字
+     */
+    String getNewline(){
+        return this.newline;
+    }
+
+    /**
+     * ジェネレータ名を返す。
+     * @return ジェネレータ名。表示したくない時はnull
+     */
+    String getGenerator(){
+        return this.generator;
+    }
+
+}
diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/OptSwitch.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/OptSwitch.java
new file mode 100644 (file)
index 0000000..1035a63
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * command line option definition
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * オプションスイッチ群定義。
+ */
+enum OptSwitch {
+
+    OPT_HELP    (0, "-h", "-help", "-?"),
+    OPT_INFILE  (1, "-i"),
+    OPT_OUTFILE (1, "-o"),
+    OPT_FORCE   (0, "-f"),
+    OPT_NEWLINE (1, "-nl"),
+    OPT_GENOUT  (1, "-genout"),
+    OPT_IFORM   (1, "-iform"),
+    OPT_OFORM   (1, "-oform"),
+    ;
+
+    private static final String HELP_CONSOLE =
+              "-h               : put help message\n\n"
+            + "-i <file>        : specify input file\n"
+            + "-o <file>        : specify output file\n"
+            + "-f               : force overwriting\n\n"
+            + "-nl <newline>    : specify XML-newline character"
+            +                     " (default:lf)\n"
+            + "-genout <bool>   : mark generator-name to XML"
+            +                     " (default:on)\n\n"
+            + "-iform <format>  : specify input format explicitly\n"
+            + "-oform <format>  : specify output format explicitly\n\n"
+            + "   bool : \"on\" or \"off\""
+            +     " or \"true\" or \"false\""
+            +      " or \"yes\" or \"no\"\n"
+            + "   format : \"pmd\" or \"xml\" or"
+            +            " \"xml101009\" or \"xml130128\"\n"
+            + "   newline : \"lf\" or \"crlf\"\n"
+            ;
+
+    private static final Map<String, OptSwitch> MAP_OPT;
+
+    static{
+        Map<String, OptSwitch> map = new HashMap<String, OptSwitch>();
+
+        for(OptSwitch opt : values()){
+            for(String cmdarg : opt.cmdopts){
+                map.put(cmdarg, opt);
+            }
+        }
+
+        map = Collections.unmodifiableMap(map);
+        MAP_OPT = map;
+    }
+
+
+    private final int exArgNum;
+    private final List<String> cmdopts;
+
+
+    /**
+     * コンストラクタ。
+     * @patam argnum 必要な引数の数
+     * @param cmdopts オプションスイッチパターン群
+     */
+    private OptSwitch(int argnum, String... cmdopts) {
+        this.exArgNum = argnum;
+
+        List<String> optlist;
+        optlist = Arrays.asList(cmdopts);
+        optlist = Collections.unmodifiableList(optlist);
+        this.cmdopts = optlist;
+
+        return;
+    }
+
+
+    /**
+     * コンソール提示用ヘルプ出力文字列を返す。
+     * @return オプションヘルプ文字列
+     */
+    static String getConsoleHelp(){
+        return HELP_CONSOLE;
+    }
+
+    /**
+     * 文字列に合致するオプションを返す。
+     * <p>一つのオプションが複数の表記に合致する場合がある。
+     * @param cmd 文字列
+     * @return オプション種別。合致する物が見つからなければnull
+     */
+    static OptSwitch parse(String cmd){
+        OptSwitch result = MAP_OPT.get(cmd);
+        return result;
+    }
+
+
+    /**
+     * 各オプションに後続する引数の数を返す。
+     * <p>引数をとらないオプションは0を返す。
+     * @return 引数の数
+     */
+    int getExArgNum(){
+        return this.exArgNum;
+    }
+
+}
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd2xml;
+package jp.sfjp.mikutoga.pmd2xml;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -203,7 +203,7 @@ public final class Pmd2Xml {
                .append('\n');
 
         ERROUT.println(appInfo.toString());
-        ERROUT.println(OptInfo.getConsoleHelp());
+        ERROUT.println(OptSwitch.getConsoleHelp());
 
         return;
     }
@@ -307,14 +307,19 @@ public final class Pmd2Xml {
 
         Pmd2XmlConv converter = new Pmd2XmlConv();
 
-        OptInfo optInfo = OptInfo.parseOption(args);
+        OptInfo optInfo;
+        try{
+            optInfo = OptInfo.parseOption(args);
+        }catch(CmdLineException e){
+            String optErrMsg = e.getLocalizedMessage();
+            errMsg(optErrMsg);
+            exit(EXIT_OPT);
+            return;
+        }
+
         if(optInfo.needHelp()){
             putHelp();
             exit(EXIT_OK);
-        }else if(optInfo.hasError()){
-            String optErrMsg = optInfo.getErrorMessage();
-            errMsg(optErrMsg);
-            exit(EXIT_OPT);
         }
 
         String inputFile = optInfo.getInFilename();
@@ -5,23 +5,29 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd2xml;
+package jp.sfjp.mikutoga.pmd2xml;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
-import jp.sfjp.mikutoga.pmd.xml101009.Xml101009Exporter;
-import jp.sfjp.mikutoga.pmd.xml101009.Xml101009Loader;
-import jp.sfjp.mikutoga.pmd.xml101009.Xml101009Resources;
+import javax.xml.validation.Schema;
+import jp.sfjp.mikutoga.pmd.binio.PmdExporter;
+import jp.sfjp.mikutoga.pmd.binio.PmdLoader;
+import jp.sfjp.mikutoga.pmd.model.PmdModel;
+import jp.sfjp.mikutoga.pmd.xml.BotherHandler;
+import jp.sfjp.mikutoga.pmd.xml.LocalSchema;
+import jp.sfjp.mikutoga.pmd.xml.Schema101009;
+import jp.sfjp.mikutoga.pmd.xml.Schema130128;
+import jp.sfjp.mikutoga.pmd.xml.XmlExporter;
+import jp.sfjp.mikutoga.pmd.xml.XmlLoader;
+import jp.sfjp.mikutoga.pmd.xml.XmlModelFileType;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
 import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
-import jp.sourceforge.mikutoga.pmd.ModelFileType;
-import jp.sourceforge.mikutoga.pmd.model.PmdModel;
-import jp.sourceforge.mikutoga.pmd.model.binio.PmdExporter;
-import jp.sourceforge.mikutoga.pmd.model.binio.PmdLoader;
 import jp.sourceforge.mikutoga.xml.TogaXmlException;
+import jp.sourceforge.mikutoga.xml.XmlResourceResolver;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
@@ -35,33 +41,87 @@ public class Pmd2XmlConv {
     private String newLine = "\r\n";
     private String generator = null;
 
-    private final DocumentBuilder builder;
-
 
     /**
      * コンストラクタ。
      */
     public Pmd2XmlConv(){
         super();
+        return;
+    }
+
+
+    /**
+     * ドキュメントビルダファクトリを初期化する。
+     * @param builderFactory ドキュメントビルダファクトリ
+     */
+    private static void initBuilderFactory(
+            DocumentBuilderFactory builderFactory ){
+        builderFactory.setCoalescing(true);
+        builderFactory.setExpandEntityReferences(true);
+        builderFactory.setIgnoringComments(true);
+        builderFactory.setIgnoringElementContentWhitespace(false);
+        builderFactory.setNamespaceAware(true);
+        builderFactory.setValidating(false);
+        builderFactory.setXIncludeAware(false);
 
+//      builderFactory.setFeature(name, value);
+//      builderFactory.setAttribute(name, value);
+
+        return;
+    }
+
+    /**
+     * DOMビルダ生成。
+     * @return DOMビルダ
+     */
+    private DocumentBuilder buildBuilder(){
+        XmlResourceResolver resolver = new XmlResourceResolver();
+
+        Schema schema;
+
+        switch(this.inTypes){
+        case XML_101009:
+            schema = LocalSchema.newSchema(resolver, new Schema101009());
+            break;
+        case XML_130128:
+            schema = LocalSchema.newSchema(resolver, new Schema130128());
+            break;
+        case XML_AUTO:
+            schema = LocalSchema.newSchema(resolver,
+                    new Schema101009(), new Schema130128());
+            break;
+        default:
+            throw new IllegalStateException();
+        }
+
+        DocumentBuilderFactory builderFactory =
+                DocumentBuilderFactory.newInstance();
+        initBuilderFactory(builderFactory);
+        builderFactory.setSchema(schema);
+
+        DocumentBuilder result;
         try{
-            this.builder = Xml101009Resources.newBuilder(XmlHandler.HANDLER);
-        }catch(SAXException e){
-            throw new AssertionError(e);
+            result = builderFactory.newDocumentBuilder();
         }catch(ParserConfigurationException e){
+            assert false;
             throw new AssertionError(e);
         }
+        result.setEntityResolver(resolver);
+        result.setErrorHandler(BotherHandler.HANDLER);
 
-        return;
+        return result;
     }
 
 
     /**
      * 入力ファイル種別を設定する。
      * @param type ファイル種別
+     * @throws IllegalArgumentException 具体的な種別を渡さなかった
      */
     public void setInType(ModelFileType type){
         if(type == null) throw new NullPointerException();
+        if(type == ModelFileType.NONE) throw new IllegalArgumentException();
         this.inTypes = type;
         return;
     }
@@ -77,9 +137,11 @@ public class Pmd2XmlConv {
     /**
      * 出力ファイル種別を設定する。
      * @param type ファイル種別
+     * @throws IllegalArgumentException 具体的な種別を渡さなかった
      */
     public void setOutType(ModelFileType type){
         if(type == null) throw new NullPointerException();
+        if(type == ModelFileType.NONE) throw new IllegalArgumentException();
         this.outTypes = type;
         return;
     }
@@ -155,6 +217,7 @@ public class Pmd2XmlConv {
      * @throws MmdFormatException フォーマットエラー
      * @throws SAXException XMLエラー
      * @throws TogaXmlException XMLエラー
+     * @throws IllegalStateException ファイル種別がまた指定されていない
      */
     public PmdModel readModel(InputStream is)
             throws IOException,
@@ -162,17 +225,15 @@ public class Pmd2XmlConv {
                    SAXException,
                    TogaXmlException {
         PmdModel model = null;
-        switch(this.inTypes){
-        case PMD:
+
+        if(this.inTypes.isPmd()){
             model = pmdRead(is);
-            break;
-        case XML_101009:
+        }else if(this.inTypes.isXml()){
             model = xmlRead(is);
-            break;
-        default:
-            assert false;
-            break;
+        }else{
+            throw new IllegalStateException();
         }
+
         return model;
     }
 
@@ -182,21 +243,20 @@ public class Pmd2XmlConv {
      * @param os 出力ストリーム
      * @throws IOException 出力エラー
      * @throws IllegalPmdDataException データの不備
+     * @throws IllegalStateException ファイル種別がまた指定されていない
      */
     public void writeModel(PmdModel model, OutputStream os)
             throws IOException,
                    IllegalPmdDataException {
-        switch(this.outTypes){
-        case PMD:
+        if(this.outTypes.isPmd()){
             pmdOut(model, os);
-            break;
-        case XML_101009:
+        }else if(this.outTypes.isXml()){
             xmlOut(model, os);
-            break;
-        default:
-            assert false;
-            break;
+        }else{
+            throw new IllegalStateException();
         }
+
+        return;
     }
 
     /**
@@ -242,8 +302,9 @@ public class Pmd2XmlConv {
             throws IOException,
                    SAXException,
                    TogaXmlException {
-        Xml101009Loader loader = new Xml101009Loader(this.builder);
-        PmdModel model = loader.parse(source);
+        DocumentBuilder builder = buildBuilder();
+        XmlLoader loader = new XmlLoader();
+        PmdModel model = loader.parse(builder, source);
         return model;
     }
 
@@ -271,11 +332,17 @@ public class Pmd2XmlConv {
      */
     private void xmlOut(PmdModel model, OutputStream ostream)
             throws IOException, IllegalPmdDataException{
-        Xml101009Exporter exporter = new Xml101009Exporter(ostream);
+        XmlExporter exporter = new XmlExporter(ostream);
+
+        XmlModelFileType xmlType = this.outTypes.toXmlType();
+        exporter.setXmlFileType(xmlType);
         exporter.setNewLine(this.newLine);
         exporter.setGenerator(this.generator);
+
         exporter.putPmdModel(model);
+
         exporter.close();
+
         return;
     }
 
@@ -10,6 +10,6 @@
  * Mainエントリは、クラスPmd2Xml。
  */
 
-package jp.sourceforge.mikutoga.pmd2xml;
+package jp.sfjp.mikutoga.pmd2xml;
 
 /* EOF */
diff --git a/src/main/java/jp/sourceforge/mikutoga/pmd2xml/OptInfo.java b/src/main/java/jp/sourceforge/mikutoga/pmd2xml/OptInfo.java
deleted file mode 100644 (file)
index 7b8cf71..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * command line argument info
- *
- * License : The MIT License
- * Copyright(c) 2012 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.pmd2xml;
-
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-import jp.sourceforge.mikutoga.pmd.ModelFileType;
-
-/**
- * コマンドラインオプション情報。
- */
-final class OptInfo {
-
-    private static final String EOL_LF = "\n";
-    private static final String EOL_CRLF = "\r\n";
-    private static final String EOL_DEFAULT = EOL_LF;
-
-    private static final String GENERATOR =
-            Pmd2Xml.APPNAME + ' ' + Pmd2Xml.APPVER;
-
-    private static final String HELP_CONSOLE =
-              "-h       : put help message\n"
-            + "-pmd2xml : convert *.pmd to *.xml\n"
-            + "-xml2pmd : convert *.xml to *.pmd\n"
-            + "-i file  : specify input file\n"
-            + "-o file  : specify output file\n"
-            + "-f       : force overwriting\n"
-            + "-lf      : use LF as XML-newline (default)\n"
-            + "-crlf    : use CR+LF as XML-newline\n"
-            + "-gen     : print generator to XML (default)\n"
-            + "-nogen   : do not print generator to XML\n"
-            ;
-
-    private static final String ERRMSG_UNKNOWN =
-            "Unknown option : {0}";
-    private static final String ERRMSG_NODIR =
-            "You must specify -pmd2xml or -xml2pmd.";
-    private static final String ERRMSG_NOINFILE =
-            "You must specify input file with -i.";
-    private static final String ERRMSG_NOOUTFILE =
-            "You must specify output file with -o.";
-
-
-    private boolean hasError = false;
-    private String errMsg = null;
-
-    private boolean needHelp = false;
-    private ModelFileType inTypes  = ModelFileType.NONE;
-    private ModelFileType outTypes = ModelFileType.NONE;
-    private String inFilename = null;
-    private String outFilename = null;
-    private boolean overwrite = false;
-    private String newline = EOL_DEFAULT;
-    private String generator = GENERATOR;
-
-
-    /**
-     * コンストラクタ。
-     */
-    private OptInfo(){
-        super();
-        return;
-    }
-
-
-    /**
-     * コマンドラインを解析する。
-     * @param args コマンドライン
-     * @return オプション情報
-     */
-    static OptInfo parseOption(String... args){
-        OptInfo result = new OptInfo();
-
-        int argIdx = 0;
-        int argLength = args.length;
-
-        argline: while(argIdx < argLength){
-            String arg = args[argIdx];
-
-            OptSwitch opt = OptSwitch.find(arg);
-            if(opt == null){
-                String errMsg = MessageFormat.format(ERRMSG_UNKNOWN, arg);
-                result.putErrMsg(errMsg);
-                break argline;
-            }
-
-            switch(opt){
-            case OPT_HELP:
-                result.needHelp = true;
-                break argline;
-            case OPT_FORCE:
-                result.overwrite = true;
-                break;
-            case OPT_PMD2XML:
-                result.inTypes  = ModelFileType.PMD;
-                result.outTypes = ModelFileType.XML_101009;
-                break;
-            case OPT_XML2PMD:
-                result.inTypes  = ModelFileType.XML_101009;
-                result.outTypes = ModelFileType.PMD;
-                break;
-            case OPT_INFILE:
-                argIdx++;
-                if(argIdx >= argLength){
-                    result.putErrMsg(ERRMSG_NOINFILE);
-                    break argline;
-                }
-                result.inFilename = args[argIdx];
-                break;
-            case OPT_OUTFILE:
-                argIdx++;
-                if(argIdx >= argLength){
-                    result.putErrMsg(ERRMSG_NOOUTFILE);
-                    break argline;
-                }
-                result.outFilename = args[argIdx];
-                break;
-            case OPT_LF:
-                result.newline = EOL_LF;
-                break;
-            case OPT_CRLF:
-                result.newline = EOL_CRLF;
-                break;
-            case OPT_GEN:
-                result.generator = GENERATOR;
-                break;
-            case OPT_NOGEN:
-                result.generator = null;
-                break;
-            default:
-                assert false;
-                String errMsg = MessageFormat.format(ERRMSG_UNKNOWN, arg);
-                result.putErrMsg(errMsg);
-                break argline;
-            }
-
-            if(result.hasError()) return result;
-
-            argIdx++;
-        }
-
-        if(result.hasError()) return result;
-        if(result.needHelp()) return result;
-
-        checkResult(result);
-
-        return result;
-    }
-
-    /**
-     * オプション整合性の事後検査。
-     * @param result オプション情報
-     */
-    private static void checkResult(OptInfo result){
-        if(   result.getInFileType()  == ModelFileType.NONE
-           || result.getOutFileType() == ModelFileType.NONE ){
-            result.putErrMsg(ERRMSG_NODIR);
-            return;
-        }
-
-        if(result.getInFilename() == null){
-            result.putErrMsg(ERRMSG_NOINFILE);
-            return;
-        }
-
-        if(result.getOutFilename() == null){
-            result.putErrMsg(ERRMSG_NOOUTFILE);
-            return;
-        }
-
-        return;
-    }
-
-    /**
-     * コンソール提示用ヘルプ出力文字列を返す。
-     * @return オプションヘルプ文字列
-     */
-    static String getConsoleHelp(){
-        return HELP_CONSOLE;
-    }
-
-
-    /**
-     * 解析中にエラーが起きたか判定する。
-     * @return エラーが起きていればtrue
-     */
-    boolean hasError(){
-        return this.hasError;
-    }
-
-    /**
-     * エラーメッセージを返す。
-     * @return エラーメッセージ。なければnull
-     */
-    String getErrorMessage(){
-        return this.errMsg;
-    }
-
-    /**
-     * ヘルプ表示が必要か否か判定する。
-     * @return 必要ならtrue
-     */
-    boolean needHelp(){
-        return this.needHelp;
-    }
-
-    /**
-     * 入力ファイル種別を返す。
-     * @return 入力ファイル種別
-     */
-    ModelFileType getInFileType(){
-        return this.inTypes;
-    }
-
-    /**
-     * 出力ファイル種別を返す。
-     * @return 出力ファイル種別
-     */
-    ModelFileType getOutFileType(){
-        return this.outTypes;
-    }
-
-    /**
-     * 入力ファイル名を返す。
-     * @return 入力ファイル名
-     */
-    String getInFilename(){
-        return this.inFilename;
-    }
-
-    /**
-     * 出力ファイル名を返す。
-     * @return 出力ファイル名
-     */
-    String getOutFilename(){
-        return this.outFilename;
-    }
-
-    /**
-     * 上書きモードか否か返す。
-     * @return 上書きモードならtrue
-     */
-    boolean overwriteMode(){
-        return this.overwrite;
-    }
-
-    /**
-     * XML改行文字を返す。
-     * @return 改行文字
-     */
-    String getNewline(){
-        return this.newline;
-    }
-
-    /**
-     * ジェネレータ名を返す。
-     * @return ジェネレータ名。表示したくない時はnull
-     */
-    String getGenerator(){
-        return this.generator;
-    }
-
-    /**
-     * オプション解析エラー情報を設定する。
-     * @param txt エラー文字列
-     */
-    private void putErrMsg(String txt){
-        this.hasError = true;
-        this.errMsg = txt;
-        return;
-    }
-
-
-    /**
-     * オプションスイッチ群。
-     */
-    static enum OptSwitch{
-        OPT_HELP    ("-h", "-help", "-?"),
-        OPT_XML2PMD ("-xml2pmd"),
-        OPT_PMD2XML ("-pmd2xml"),
-        OPT_INFILE  ("-i"),
-        OPT_OUTFILE ("-o"),
-        OPT_FORCE   ("-f"),
-        OPT_LF      ("-lf"),
-        OPT_CRLF    ("-crlf"),
-        OPT_GEN     ("-gen"),
-        OPT_NOGEN   ("-nogen"),
-        ;
-
-
-        /**
-         * コンストラクタ。
-         * @param cmdargs オプションスイッチパターン群
-         */
-        private OptSwitch(String... cmdargs){
-            for(String cmdarg : cmdargs){
-                MapHolder.MAP_OPT.put(cmdarg, this);
-            }
-            return;
-        }
-
-        /**
-         * パターンに合致するオプションを見つける。
-         * @param cmd パターン
-         * @return オプション。見つからなければnull
-         */
-        static OptSwitch find(String cmd){
-            OptSwitch result = MapHolder.MAP_OPT.get(cmd);
-            return result;
-        }
-
-
-        /**
-         * enumコンストラクタからクラス変数にアクセスできない文法を回避。
-         */
-        private static class MapHolder{
-            static final Map<String, OptSwitch> MAP_OPT =
-                    new HashMap<String, OptSwitch>();
-        }
-
-    }
-
-}
diff --git a/src/main/resources/jp/sfjp/mikutoga/pmd/xml/resources/pmdxml-130128.xsd b/src/main/resources/jp/sfjp/mikutoga/pmd/xml/resources/pmdxml-130128.xsd
new file mode 100644 (file)
index 0000000..6577541
--- /dev/null
@@ -0,0 +1,1513 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+    schema definition
+
+  License : The MIT License
+  Copyright(c) 2013 MikuToga Partners
+-->
+
+
+<xsd:schema
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
+    targetNamespace="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128"
+    xmlns:tns      ="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128"
+
+    elementFormDefault="qualified"
+    version="130128"
+>
+
+    <xsd:annotation>
+        <xsd:documentation>
+            MikuMikuDance model-data(*.pmd) on XML.
+            License : The MIT License
+            Copyright(c) 2013 MikuToga Partners
+        </xsd:documentation>
+    </xsd:annotation>
+
+
+    <xsd:import
+        namespace="http://www.w3.org/XML/1998/namespace"
+        schemaLocation="http://www.w3.org/2001/xml.xsd" />
+
+
+    <!-- ROOT -->
+    <xsd:element name="pmdModel">
+        <xsd:annotation>
+            <xsd:documentation>
+                Root element.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="tns:i18nName"
+                    minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element ref="tns:description"
+                    minOccurs="1" maxOccurs="unbounded" />
+                <xsd:element ref="tns:license"
+                    minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element ref="tns:credits"
+                    minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element ref="tns:meta"
+                    minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element ref="tns:materialList" />
+                <xsd:element ref="tns:toonMap" />
+                <xsd:element ref="tns:boneList" />
+                <xsd:element ref="tns:boneGroupList" />
+                <xsd:element ref="tns:ikChainList" />
+                <xsd:element ref="tns:morphList" />
+                <xsd:element ref="tns:rigidList" />
+                <xsd:element ref="tns:rigidGroupList" />
+                <xsd:element ref="tns:jointList" />
+                <xsd:element ref="tns:surfaceGroupList" />
+                <xsd:element ref="tns:vertexList" />
+            </xsd:sequence>
+            <xsd:attribute name="name" type="xsd:string" use="required" />
+            <xsd:attribute
+                name="schemaVersion"
+                type="xsd:string"
+                use="required"
+                fixed="130128" />
+        </xsd:complexType>
+
+        <xsd:unique name="ModelLang">
+            <xsd:selector xpath="./tns:i18nName" />
+            <xsd:field xpath="@lang" />
+        </xsd:unique>
+
+        <xsd:unique name="DescriptionLang">
+            <xsd:selector xpath="./tns:description" />
+            <xsd:field xpath="@lang" />
+        </xsd:unique>
+
+        <xsd:unique name="LicenseLang">
+            <xsd:selector xpath="./tns:license" />
+            <xsd:field xpath="@lang" />
+        </xsd:unique>
+
+        <xsd:unique name="CreditsLang">
+            <xsd:selector xpath="./tns:credits" />
+            <xsd:field xpath="@lang" />
+        </xsd:unique>
+
+        <xsd:keyref name="Material-SurfaceGroup" refer="tns:SurfaceGroup-Id">
+            <xsd:selector xpath="./tns:materialList/tns:material" />
+            <xsd:field xpath="@surfaceGroupIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Material-Toon" refer="tns:Toon-Id">
+            <xsd:selector xpath="./tns:materialList/tns:material/tns:toon" />
+            <xsd:field xpath="@toonFileIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Bone-prev" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:boneList/tns:bone/tns:boneChain" />
+            <xsd:field xpath="@prevBoneIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Bone-next" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:boneList/tns:bone/tns:boneChain" />
+            <xsd:field xpath="@nextBoneIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Bone-source" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:boneList/tns:bone/tns:sourceBone" />
+            <xsd:field xpath="@boneIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="BoneGroup-Bone" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:boneGroupList/tns:boneGroup/tns:boneGroupMember" />
+            <xsd:field xpath="@boneIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="IkChain-Bone" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:ikChainList/tns:ikChain" />
+            <xsd:field xpath="@ikBoneIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="IkChainPart-Bone" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:ikChainList/tns:ikChain/tns:chainOrder" />
+            <xsd:field xpath="@boneIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Morph-Vertex" refer="tns:Vertex-Id">
+            <xsd:selector xpath="./tns:morphList/tns:morph/tns:morphVertex" />
+            <xsd:field xpath="@vtxIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Rigid-Bone" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:rigidList/tns:rigid/tns:linkedBone" />
+            <xsd:field xpath="@boneIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Rigid-RigidGroup" refer="tns:RigidGroup-Id">
+            <xsd:selector xpath="./tns:rigidList/tns:rigid/tns:throughRigidGroup" />
+            <xsd:field xpath="@rigidGroupIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="RigidGroup-Rigid" refer="tns:Rigid-Id">
+            <xsd:selector xpath="./tns:rigidGroupList/tns:rigidGroup/tns:rigidGroupMember" />
+            <xsd:field xpath="@rigidIdRef" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Joint-Rigid1" refer="tns:Rigid-Id">
+            <xsd:selector xpath="./tns:jointList/tns:joint/tns:jointedRigidPair" />
+            <xsd:field xpath="@rigidIdRef1" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Joint-Rigid2" refer="tns:Rigid-Id">
+            <xsd:selector xpath="./tns:jointList/tns:joint/tns:jointedRigidPair" />
+            <xsd:field xpath="@rigidIdRef2" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Surface-Vertex1" refer="tns:Vertex-Id">
+            <xsd:selector xpath="./tns:surfaceGroupList/tns:surfaceGroup/tns:surface" />
+            <xsd:field xpath="@vtxIdRef1" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Surface-Vertex2" refer="tns:Vertex-Id">
+            <xsd:selector xpath="./tns:surfaceGroupList/tns:surfaceGroup/tns:surface" />
+            <xsd:field xpath="@vtxIdRef2" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Surface-Vertex3" refer="tns:Vertex-Id">
+            <xsd:selector xpath="./tns:surfaceGroupList/tns:surfaceGroup/tns:surface" />
+            <xsd:field xpath="@vtxIdRef3" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Vertex-Bone1" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:vertexList/tns:vertex/tns:skinning" />
+            <xsd:field xpath="@boneIdRef1" />
+        </xsd:keyref>
+
+        <xsd:keyref name="Vertex-Bone2" refer="tns:Bone-Id">
+            <xsd:selector xpath="./tns:vertexList/tns:vertex/tns:skinning" />
+            <xsd:field xpath="@boneIdRef2" />
+        </xsd:keyref>
+
+    </xsd:element>
+
+
+    <xsd:simpleType name="NonJaLanguage">
+        <xsd:annotation>
+            <xsd:documentation>
+                xsd:language except "ja" (Primary-language in MMD)
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:restriction base="xsd:language">
+            <xsd:pattern value="([^jJ].*)|([jJ][^aA].*)|([jJ][aA].+)" />
+        </xsd:restriction>
+
+    </xsd:simpleType>
+
+
+    <xsd:element name="i18nName">
+        <xsd:annotation>
+            <xsd:documentation>
+                Multilingual name.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="lang"
+                type="tns:NonJaLanguage"
+                use="required" />
+            <xsd:attribute
+                name="name"
+                type="xsd:string"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="br">
+        <xsd:annotation>
+            <xsd:documentation>
+                Break line.
+            </xsd:documentation>
+        </xsd:annotation>
+    </xsd:element>
+
+
+    <xsd:complexType name="bredContent" mixed="true">
+        <xsd:annotation>
+            <xsd:documentation>
+                Free paragraph with break-line.
+                Any raw-newline(CR,CRLF) will be ignored later.
+                But, other white-spaces will be preserved.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:sequence>
+            <xsd:element ref="tns:br" minOccurs="0" maxOccurs="unbounded" />
+        </xsd:sequence>
+
+        <xsd:attribute
+            name="lang"
+            type="xsd:language"
+            use="optional"
+            default="ja" />
+        <xsd:attribute ref="xml:space" use="optional" fixed="preserve" />
+
+    </xsd:complexType>
+
+
+    <xsd:element name="description" type="tns:bredContent">
+        <xsd:annotation>
+            <xsd:documentation>
+                Description note about model.
+            </xsd:documentation>
+        </xsd:annotation>
+    </xsd:element>
+
+
+    <xsd:element name="license" type="tns:bredContent">
+        <xsd:annotation>
+            <xsd:documentation>
+                License term of usage.
+            </xsd:documentation>
+        </xsd:annotation>
+    </xsd:element>
+
+
+    <xsd:element name="credits" type="tns:bredContent">
+        <xsd:annotation>
+            <xsd:documentation>
+                Credits for someone.
+            </xsd:documentation>
+        </xsd:annotation>
+    </xsd:element>
+
+
+    <xsd:element name="meta">
+        <xsd:annotation>
+            <xsd:documentation>
+                Meta-information of model.
+                Use free.
+                but, some meta-name has recommended usage.
+                + "generator" (Generator application name)
+                + "siteURL" (Website URL)
+                + "imageURL" (Thumbnail image URL)
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="name"
+                type="xsd:NCName"
+                use="required" />
+            <xsd:attribute
+                name="content"
+                type="xsd:string"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="materialList">
+        <xsd:annotation>
+            <xsd:documentation>
+                Material list.
+                All visual things can be tracked from here.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:material"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+        <xsd:unique name="SurfaceGroupRef">
+            <xsd:selector xpath="./tns:material" />
+            <xsd:field xpath="@surfaceGroupIdRef" />
+        </xsd:unique>
+
+    </xsd:element>
+
+
+    <xsd:element name="material">
+        <xsd:annotation>
+            <xsd:documentation>
+                Material definition.
+                Colors, shading, any other definitions.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="tns:i18nName" minOccurs="0" maxOccurs="unbounded"/>
+                <xsd:element ref="tns:diffuse" />
+                <xsd:element ref="tns:specular" />
+                <xsd:element ref="tns:ambient" />
+                <xsd:element ref="tns:toon" minOccurs="0" />
+                <xsd:element ref="tns:textureFile" minOccurs="0" />
+                <xsd:element ref="tns:spheremapFile" minOccurs="0" />
+            </xsd:sequence>
+
+            <xsd:attribute
+                name="name"
+                type="xsd:string"
+                use="optional" />
+            <xsd:attribute
+                name="showEdge"
+                type="xsd:boolean"
+                use="required" />
+            <xsd:attribute
+                name="surfaceGroupIdRef"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:simpleType name="SrgbCompo">
+        <xsd:annotation>
+            <xsd:documentation>
+                sRGB component value. (0.0 - 1.0)
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:restriction base="xsd:float">
+            <xsd:minInclusive value="0.0" />
+            <xsd:maxInclusive value="1.0" />
+        </xsd:restriction>
+
+    </xsd:simpleType>
+
+
+    <xsd:element name="diffuse">
+        <xsd:annotation>
+            <xsd:documentation>
+                Diffuse color definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="r" type="tns:SrgbCompo" use="required" />
+            <xsd:attribute name="g" type="tns:SrgbCompo" use="required" />
+            <xsd:attribute name="b" type="tns:SrgbCompo" use="required" />
+            <xsd:attribute name="alpha" type="tns:SrgbCompo" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="specular">
+        <xsd:annotation>
+            <xsd:documentation>
+                Specular color definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="r" type="tns:SrgbCompo" use="required" />
+            <xsd:attribute name="g" type="tns:SrgbCompo" use="required" />
+            <xsd:attribute name="b" type="tns:SrgbCompo" use="required" />
+            <xsd:attribute name="shininess" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="ambient">
+        <xsd:annotation>
+            <xsd:documentation>
+                Ambient color definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="r" type="tns:SrgbCompo" use="required" />
+            <xsd:attribute name="g" type="tns:SrgbCompo" use="required" />
+            <xsd:attribute name="b" type="tns:SrgbCompo" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="toon">
+        <xsd:annotation>
+            <xsd:documentation>
+                Reference for Toon-image.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="toonFileIdRef"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="textureFile">
+        <xsd:annotation>
+            <xsd:documentation>
+                Texture file information.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="winFileName"
+                type="xsd:string"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="spheremapFile">
+        <xsd:annotation>
+            <xsd:documentation>
+                Sphere-map file information.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="winFileName"
+                type="xsd:string"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="toonMap">
+        <xsd:annotation>
+            <xsd:documentation>
+                Toon-file mappings.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:toonDef"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+        <xsd:unique name="ToonIndex">
+            <xsd:selector xpath="./tns:toonDef" />
+            <xsd:field xpath="@index" />
+        </xsd:unique>
+
+        <xsd:key name="Toon-Id">
+            <xsd:selector xpath="./tns:toonDef" />
+            <xsd:field xpath="@toonFileId" />
+        </xsd:key>
+
+    </xsd:element>
+
+
+    <xsd:element name="toonDef">
+        <xsd:annotation>
+            <xsd:documentation>
+                Toon-file information.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="toonFileId"
+                type="xsd:NCName"
+                use="required" />
+            <xsd:attribute
+                name="index"
+                type="xsd:nonNegativeInteger"
+                use="required" />
+            <xsd:attribute
+                name="winFileName"
+                type="xsd:string"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="boneList">
+        <xsd:annotation>
+            <xsd:documentation>
+                List of bone information.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="tns:bone" minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+        <xsd:key name="Bone-Id">
+            <xsd:selector xpath="./tns:bone" />
+            <xsd:field xpath="@boneId" />
+        </xsd:key>
+<!--
+        <xsd:unique name="BoneName">
+            <xsd:selector xpath="./tns:bone" />
+            <xsd:field xpath="@name" />
+        </xsd:unique>
+-->
+    </xsd:element>
+
+
+    <xsd:simpleType name="BoneType">
+        <xsd:annotation>
+            <xsd:documentation>
+                bone types.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:restriction base="xsd:string">
+            <xsd:enumeration value="ROTATE" />      <!-- 回転 -->
+            <xsd:enumeration value="ROTMOV" />      <!-- 回転/移動 -->
+            <xsd:enumeration value="IK" />          <!-- IK -->
+            <xsd:enumeration value="UNKNOWN" />     <!-- 不明 -->
+            <xsd:enumeration value="UNDERIK" />     <!-- IK影響下(回転) -->
+            <xsd:enumeration value="UNDERROT" />    <!-- 回転影響下 -->
+            <xsd:enumeration value="IKCONNECTED" /> <!-- IK接続先 -->
+            <xsd:enumeration value="HIDDEN" />      <!-- 非表示 -->
+            <xsd:enumeration value="TWIST" />       <!-- 捩り -->
+            <xsd:enumeration value="LINKEDROT" />   <!-- 回転連動 -->
+        </xsd:restriction>
+
+    </xsd:simpleType>
+
+
+    <xsd:element name="bone">
+        <xsd:annotation>
+            <xsd:documentation>
+                Bone definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="tns:i18nName" minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element ref="tns:position" />
+                <xsd:choice minOccurs="0">
+                    <xsd:element ref="tns:rotationRatio" />
+                    <xsd:element ref="tns:sourceBone" />
+                </xsd:choice>
+                <xsd:element ref="tns:boneChain" />
+            </xsd:sequence>
+
+            <xsd:attribute name="name" type="xsd:string" use="required" />
+            <xsd:attribute name="boneId" type="xsd:NCName" use="required" />
+            <xsd:attribute name="type" type="tns:BoneType" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="boneChain">
+        <xsd:annotation>
+            <xsd:documentation>
+                Relationship-info between bones.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="prevBoneIdRef"
+                type="xsd:NCName"
+                use="optional" />
+            <xsd:attribute
+                name="nextBoneIdRef"
+                type="xsd:NCName"
+                use="optional" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="rotationRatio">
+        <xsd:annotation>
+            <xsd:documentation>
+                Rotation ratio between Linked-rotationed bones.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="ratio"
+                type="xsd:integer"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="sourceBone">
+        <xsd:annotation>
+            <xsd:documentation>
+                Reference to source-Bone (UNDERIK, IKCONNECTED, UNDERROT)
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="boneIdRef"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="boneGroupList">
+        <xsd:annotation>
+            <xsd:documentation>
+                List of Bone-group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:boneGroup"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+<!--
+        <xsd:unique name="BoneGroupName">
+            <xsd:selector xpath="./tns:boneGroup" />
+            <xsd:field xpath="@name" />
+        </xsd:unique>
+-->
+    </xsd:element>
+
+
+    <xsd:element name="boneGroup">
+        <xsd:annotation>
+            <xsd:documentation>
+                Bone-group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:i18nName"
+                    minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element
+                    ref="tns:boneGroupMember"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+            <xsd:attribute
+                name="name"
+                type="xsd:string"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="boneGroupMember">
+        <xsd:annotation>
+            <xsd:documentation>
+                Member of Bone-group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="boneIdRef"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="ikChainList">
+        <xsd:annotation>
+            <xsd:documentation>
+                List of IK chain.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:ikChain"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+<!--
+        <xsd:unique name="IkChainBone">
+            <xsd:selector xpath="./tns:ikChain" />
+            <xsd:field xpath="@ikBoneIdRef" />
+        </xsd:unique>
+-->
+
+    </xsd:element>
+
+
+    <xsd:element name="ikChain">
+        <xsd:annotation>
+            <xsd:documentation>
+                IK chained bones definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:chainOrder"
+                    minOccurs="1" maxOccurs="unbounded" />
+            </xsd:sequence>
+
+            <xsd:attribute
+                name="ikBoneIdRef"
+                type="xsd:NCName"
+                use="required" />
+            <xsd:attribute
+                name="recursiveDepth"
+                type="xsd:integer"
+                use="required" />
+            <xsd:attribute
+                name="weight"
+                type="xsd:float"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="chainOrder">
+        <xsd:annotation>
+            <xsd:documentation>
+                Part of IK chained bones.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="boneIdRef"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="morphList">
+        <xsd:annotation>
+            <xsd:documentation>
+                List of morphing definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:morph"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+<!--
+        <xsd:unique name="MorphName">
+            <xsd:selector xpath="./tns:morph" />
+            <xsd:field xpath="@name" />
+        </xsd:unique>
+-->
+    </xsd:element>
+
+
+    <xsd:simpleType name="MorphType">
+        <xsd:annotation>
+            <xsd:documentation>
+                Morph types.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:restriction base="xsd:string">
+            <xsd:enumeration value="EYEBROW" /> <!-- まゆ -->
+            <xsd:enumeration value="EYE" />     <!-- 目 -->
+            <xsd:enumeration value="LIP" />     <!-- リップ -->
+            <xsd:enumeration value="EXTRA" />   <!-- その他 -->
+        </xsd:restriction>
+
+    </xsd:simpleType>
+
+
+    <xsd:element name="morph">
+        <xsd:annotation>
+            <xsd:documentation>
+                Morphing definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:i18nName"
+                    minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element
+                    ref="tns:morphVertex"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+            <xsd:attribute
+                name="name"
+                type="xsd:string"
+                use="required" />
+            <xsd:attribute name="type" type="tns:MorphType" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="morphVertex">
+        <xsd:annotation>
+            <xsd:documentation>
+                Morphing vertex information.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="vtxIdRef" type="xsd:NCName" use="required" />
+            <xsd:attribute name="xOff" type="xsd:float" use="required" />
+            <xsd:attribute name="yOff" type="xsd:float" use="required" />
+            <xsd:attribute name="zOff" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="rigidList">
+        <xsd:annotation>
+            <xsd:documentation>
+                list of Rigid-body definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:rigid"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+        <xsd:key name="Rigid-Id">
+            <xsd:selector xpath="./tns:rigid" />
+            <xsd:field xpath="@rigidId" />
+        </xsd:key>
+<!--
+        <xsd:unique name="RigidName">
+            <xsd:selector xpath="./tns:rigid" />
+            <xsd:field xpath="@name" />
+        </xsd:unique>
+-->
+    </xsd:element>
+
+
+    <xsd:simpleType name="RigidBehaviorType">
+        <xsd:annotation>
+            <xsd:documentation>
+                Rigid bahavior types.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:restriction base="xsd:string">
+            <xsd:enumeration value="FOLLOWBONE" />    <!-- ボーン追従 -->
+            <xsd:enumeration value="ONLYDYNAMICS" />  <!-- 物理 -->
+            <xsd:enumeration value="BONEDDYNAMICS" /> <!-- 物理+ボーン -->
+        </xsd:restriction>
+
+    </xsd:simpleType>
+
+
+    <xsd:element name="rigid">
+        <xsd:annotation>
+            <xsd:documentation>
+                Rigid-body definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:i18nName"
+                    minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element ref="tns:linkedBone" minOccurs="0" />
+
+                <xsd:choice>
+                    <xsd:element ref="tns:rigidShapeSphere" />
+                    <xsd:element ref="tns:rigidShapeBox" />
+                    <xsd:element ref="tns:rigidShapeCapsule" />
+                </xsd:choice>
+
+                <xsd:element ref="tns:position" />
+                <xsd:element ref="tns:radRotation" />
+                <xsd:element ref="tns:dynamics" />
+                <xsd:element
+                    ref="tns:throughRigidGroup"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+
+            <xsd:attribute name="name" type="xsd:string" use="required" />
+            <xsd:attribute name="rigidId" type="xsd:NCName" use="required" />
+            <xsd:attribute
+                name="behavior"
+                type="tns:RigidBehaviorType"
+                use="required" />
+        </xsd:complexType>
+
+        <xsd:unique name="ThroughRigidGroup">
+            <xsd:selector xpath="./tns:throughRigidGroup" />
+            <xsd:field xpath="@rigidGroupIdRef" />
+        </xsd:unique>
+
+    </xsd:element>
+
+
+    <xsd:element name="linkedBone">
+        <xsd:annotation>
+            <xsd:documentation>
+                Referenced Bone from Rigid-body.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="boneIdRef"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="rigidShapeSphere">
+        <xsd:annotation>
+            <xsd:documentation>
+                Sphere shape of Rigid-body.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="radius" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="rigidShapeBox">
+        <xsd:annotation>
+            <xsd:documentation>
+                Box shape of Rigid-body.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="width"  type="xsd:float" use="required" />
+            <xsd:attribute name="height" type="xsd:float" use="required" />
+            <xsd:attribute name="depth"  type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="rigidShapeCapsule">
+        <xsd:annotation>
+            <xsd:documentation>
+                Capsule shape of Rigid-body.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="height" type="xsd:float" use="required" />
+            <xsd:attribute name="radius" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="radRotation">
+        <xsd:annotation>
+            <xsd:documentation>
+                Rotaion information by radian.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="xRad" type="xsd:float" use="required" />
+            <xsd:attribute name="yRad" type="xsd:float" use="required" />
+            <xsd:attribute name="zRad" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="dynamics">
+        <xsd:annotation>
+            <xsd:documentation>
+                Dynamics parameters.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="mass"
+                type="xsd:float"
+                use="required" />
+            <xsd:attribute
+                name="dampingPosition"
+                type="xsd:float"
+                use="required" />
+            <xsd:attribute
+                name="dampingRotation"
+                type="xsd:float"
+                use="required" />
+            <xsd:attribute
+                name="restitution"
+                type="xsd:float"
+                use="required" />
+            <xsd:attribute
+                name="friction"
+                type="xsd:float"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="throughRigidGroup">
+        <xsd:annotation>
+            <xsd:documentation>
+                Reference for non-collision rigid-group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="rigidGroupIdRef"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="rigidGroupList">
+        <xsd:annotation>
+            <xsd:documentation>
+                List of Rigid-body group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:rigidGroup"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+        <xsd:key name="RigidGroup-Id">
+            <xsd:selector xpath="./tns:rigidGroup" />
+            <xsd:field xpath="@rigidGroupId" />
+        </xsd:key>
+
+    </xsd:element>
+
+
+    <xsd:element name="rigidGroup">
+        <xsd:annotation>
+            <xsd:documentation>
+                Rigid-body group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:rigidGroupMember"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+
+            <xsd:attribute
+                name="rigidGroupId"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+        <xsd:unique name="RigidGroupMember">
+            <xsd:selector xpath="./tns:rigidGroupMember" />
+            <xsd:field xpath="@rigidIdRef" />
+        </xsd:unique>
+
+    </xsd:element>
+
+
+    <xsd:element name="rigidGroupMember">
+        <xsd:annotation>
+            <xsd:documentation>
+                Member of Rigid-body group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="rigidIdRef"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="jointList">
+        <xsd:annotation>
+            <xsd:documentation>
+                List of joint definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:joint"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="joint">
+        <xsd:annotation>
+            <xsd:documentation>
+                Joint definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:i18nName"
+                    minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element ref="tns:jointedRigidPair" />
+                <xsd:element ref="tns:position" />
+                <xsd:element ref="tns:limitPosition" />
+                <xsd:element ref="tns:radRotation" />
+                <xsd:element ref="tns:limitRotation" />
+                <xsd:element ref="tns:elasticPosition" />
+                <xsd:element ref="tns:elasticRotation" />
+            </xsd:sequence>
+
+            <xsd:attribute
+                name="name"
+                type="xsd:string"
+                use="required" />
+        </xsd:complexType>
+
+<!--
+        <xsd:unique name="JointName">
+            <xsd:selector xpath="./tns:joint" />
+            <xsd:field xpath="@name" />
+        </xsd:unique>
+-->
+    </xsd:element>
+
+
+    <xsd:element name="jointedRigidPair">
+        <xsd:annotation>
+            <xsd:documentation>
+                Jointed-bones information.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="rigidIdRef1"
+                type="xsd:NCName"
+                use="required" />
+            <xsd:attribute
+                name="rigidIdRef2"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="limitPosition">
+        <xsd:annotation>
+            <xsd:documentation>
+                Limit of Position.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="xFrom" type="xsd:float" use="required" />
+            <xsd:attribute name="xTo"   type="xsd:float" use="required" />
+            <xsd:attribute name="yFrom" type="xsd:float" use="required" />
+            <xsd:attribute name="yTo"   type="xsd:float" use="required" />
+            <xsd:attribute name="zFrom" type="xsd:float" use="required" />
+            <xsd:attribute name="zTo"   type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="limitRotation">
+        <xsd:annotation>
+            <xsd:documentation>
+                Limit of Rotation.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="xFrom" type="xsd:float" use="required" />
+            <xsd:attribute name="xTo"   type="xsd:float" use="required" />
+            <xsd:attribute name="yFrom" type="xsd:float" use="required" />
+            <xsd:attribute name="yTo"   type="xsd:float" use="required" />
+            <xsd:attribute name="zFrom" type="xsd:float" use="required" />
+            <xsd:attribute name="zTo"   type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="elasticPosition">
+        <xsd:annotation>
+            <xsd:documentation>
+                Elastic position of joint.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="x" type="xsd:float" use="required" />
+            <xsd:attribute name="y" type="xsd:float" use="required" />
+            <xsd:attribute name="z" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="elasticRotation">
+        <xsd:annotation>
+            <xsd:documentation>
+                Elastic rotation of joint by degree.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="xDeg" type="xsd:float" use="required" />
+            <xsd:attribute name="yDeg" type="xsd:float" use="required" />
+            <xsd:attribute name="zDeg" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="surfaceGroupList">
+        <xsd:annotation>
+            <xsd:documentation>
+                List of surface group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element
+                    ref="tns:surfaceGroup"
+                    minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+        <xsd:key name="SurfaceGroup-Id">
+            <xsd:selector xpath="./tns:surfaceGroup" />
+            <xsd:field xpath="@surfaceGroupId" />
+        </xsd:key>
+
+    </xsd:element>
+
+
+    <xsd:element name="surfaceGroup">
+        <xsd:annotation>
+            <xsd:documentation>
+                Surface group.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="tns:surface" minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+
+            <xsd:attribute
+                name="surfaceGroupId"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="surface">
+        <xsd:annotation>
+            <xsd:documentation>
+                Each surface with Triangle.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute
+                name="vtxIdRef1"
+                type="xsd:NCName"
+                use="required" />
+            <xsd:attribute
+                name="vtxIdRef2"
+                type="xsd:NCName"
+                use="required" />
+            <xsd:attribute
+                name="vtxIdRef3"
+                type="xsd:NCName"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="vertexList">
+        <xsd:annotation>
+            <xsd:documentation>
+                List of vertex.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="tns:vertex" minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+
+        <xsd:key name="Vertex-Id">
+            <xsd:selector xpath="./tns:vertex" />
+            <xsd:field xpath="@vtxId" />
+        </xsd:key>
+
+    </xsd:element>
+
+
+    <xsd:element name="vertex">
+        <xsd:annotation>
+            <xsd:documentation>
+                Vertex definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="tns:position" />
+                <xsd:element ref="tns:normal" />
+                <xsd:element ref="tns:uvMap" />
+                <xsd:element ref="tns:skinning" />
+            </xsd:sequence>
+
+            <xsd:attribute
+                name="vtxId"
+                type="xsd:NCName"
+                use="required" />
+            <xsd:attribute
+                name="showEdge"
+                type="xsd:boolean"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="position">
+        <xsd:annotation>
+            <xsd:documentation>
+                Position definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="x" type="xsd:float" use="required" />
+            <xsd:attribute name="y" type="xsd:float" use="required" />
+            <xsd:attribute name="z" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="normal">
+        <xsd:annotation>
+            <xsd:documentation>
+                Normal vector definition.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="x" type="xsd:float" use="required" />
+            <xsd:attribute name="y" type="xsd:float" use="required" />
+            <xsd:attribute name="z" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="uvMap">
+        <xsd:annotation>
+            <xsd:documentation>
+                UV-mapping information.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="u" type="xsd:float" use="required" />
+            <xsd:attribute name="v" type="xsd:float" use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+    <xsd:element name="skinning">
+        <xsd:annotation>
+            <xsd:documentation>
+                Skinning definition from vertex to bone.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:attribute name="boneIdRef1" type="xsd:NCName" use="required" />
+            <xsd:attribute name="boneIdRef2" type="xsd:NCName" use="required" />
+            <xsd:attribute
+                name="weightBalance"
+                type="xsd:nonNegativeInteger"
+                use="required" />
+        </xsd:complexType>
+
+    </xsd:element>
+
+
+</xsd:schema>
+
+
+<!-- EOF -->
diff --git a/src/main/resources/jp/sfjp/mikutoga/pmd/xml101009/resources/pmdxml-101009.dtd b/src/main/resources/jp/sfjp/mikutoga/pmd/xml101009/resources/pmdxml-101009.dtd
deleted file mode 100644 (file)
index 851f3aa..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<!--
-  MikuMikuDance
-    model-data(*.pmd) on XML
-    DTD definition
-
-  License : The MIT License
-  Copyright(c) 2010 MikuToga Partners
-
-  SYSTEM ID: http://mikutoga.sourceforge.jp/xml/dtd/pmdxml-101009.dtd
--->
-
-
-<!-- ROOT -->
-<!ELEMENT pmdModel (
-    i18nName*, description+, license*, credits*, meta*,
-    materialList,
-    toonMap,
-    boneList,
-    boneGroupList,
-    ikChainList,
-    morphList,
-    rigidList,
-    rigidGroupList,
-    jointList,
-    surfaceGroupList,
-    vertexList
-) >
-<!ATTLIST pmdModel
-    xmlns              CDATA #IMPLIED
-    xmlns:xsi          CDATA #IMPLIED
-    xsi:schemaLocation CDATA #IMPLIED
-    schemaVersion      CDATA #FIXED "100923"
-    name               CDATA #REQUIRED
->
-
-
-<!-- Multilingual name. -->
-<!ELEMENT i18nName EMPTY>
-<!ATTLIST i18nName
-    lang CDATA #REQUIRED
-    name CDATA #REQUIRED
->
-
-
-<!-- Break line. -->
-<!ELEMENT br EMPTY>
-
-
-<!-- Description note about model. -->
-<!ELEMENT description (#PCDATA | br)* >
-<!ATTLIST description
-    lang      CDATA "ja"
-    xml:space CDATA #FIXED "preserve"
->
-
-
-<!-- License term of usage. -->
-<!ELEMENT license (#PCDATA | br)* >
-<!ATTLIST license
-    lang      CDATA "ja"
-    xml:space CDATA #FIXED "preserve"
->
-
-
-<!-- Credits for someone. -->
-<!ELEMENT credits (#PCDATA | br)* >
-<!ATTLIST credits
-    lang      CDATA "ja"
-    xml:space CDATA #FIXED "preserve"
->
-
-
-<!--
-Meta-information of model.
-Use free.
-but, some meta-name has recommended usage.
-+ "generator" (Generator application name)
-+ "siteURL" (Website URL)
-+ "imageURL" (Thumbnail image URL)
--->
-<!ELEMENT meta EMPTY>
-<!ATTLIST meta
-    name    CDATA #REQUIRED
-    content CDATA #REQUIRED
->
-
-
-<!--
-Material list.
-All visual things can be tracked from here.
--->
-<!ELEMENT materialList (material)* >
-
-
-<!--
-Material definition.
-Colors, shading, any other definitions.
--->
-<!ELEMENT material (
-    i18nName*,
-    diffuse,
-    specular,
-    ambient,
-    toon?,
-    textureFile?,
-    spheremapFile?
-)*>
-<!ATTLIST material
-    name              CDATA #IMPLIED
-    showEdge          CDATA #REQUIRED
-    surfaceGroupIdRef CDATA #REQUIRED
->
-
-
-<!-- Diffuse color definition. -->
-<!ELEMENT diffuse EMPTY>
-<!ATTLIST diffuse
-    r     CDATA #REQUIRED
-    g     CDATA #REQUIRED
-    b     CDATA #REQUIRED
-    alpha CDATA #REQUIRED
->
-
-
-<!-- Specular color definition. -->
-<!ELEMENT specular EMPTY>
-<!ATTLIST specular
-    r         CDATA #REQUIRED
-    g         CDATA #REQUIRED
-    b         CDATA #REQUIRED
-    shininess CDATA #REQUIRED
->
-
-
-<!-- Ambient color definition. -->
-<!ELEMENT ambient EMPTY>
-<!ATTLIST ambient
-    r CDATA #REQUIRED
-    g CDATA #REQUIRED
-    b CDATA #REQUIRED
->
-
-
-<!-- Reference for Toon-image. -->
-<!ELEMENT toon EMPTY>
-<!ATTLIST toon
-    toonFileIdRef CDATA #REQUIRED
->
-
-
-<!-- Texture file information. -->
-<!ELEMENT textureFile EMPTY>
-<!ATTLIST textureFile
-    winFileName CDATA #REQUIRED
->
-
-
-<!-- Sphere-map file information. -->
-<!ELEMENT spheremapFile EMPTY>
-<!ATTLIST spheremapFile
-    winFileName CDATA #REQUIRED
->
-
-
-<!-- Toon-file mappings. -->
-<!ELEMENT toonMap (toonDef)* >
-
-
-<!-- Toon-file information. -->
-<!ELEMENT toonDef EMPTY>
-<!ATTLIST toonDef
-    toonFileId  CDATA #REQUIRED
-    index       CDATA #REQUIRED
-    winFileName CDATA #REQUIRED
->
-
-
-<!-- List of bone information. -->
-<!ELEMENT boneList (bone)* >
-
-
-<!-- Bone definition. -->
-<!ELEMENT bone (
-    i18nName*,
-    position,
-    (rotationRatio | ikBone)?,
-    boneChain
-) >
-<!ATTLIST bone
-    name   CDATA #REQUIRED
-    boneId CDATA #REQUIRED
-    type   (
-          ROTATE
-        | ROTMOV
-        | IK
-        | UNKNOWN
-        | UNDERIK
-        | UNDERROT
-        | IKCONNECTED
-        | HIDDEN
-        | TWIST
-        | LINKEDROT
-    ) #REQUIRED
->
-
-
-<!-- position information. -->
-<!ELEMENT position EMPTY>
-<!ATTLIST position
-    x CDATA #REQUIRED
-    y CDATA #REQUIRED
-    z CDATA #REQUIRED
->
-
-
-<!-- Relationship-info between bones. -->
-<!ELEMENT boneChain EMPTY>
-<!ATTLIST boneChain
-    prevBoneIdRef CDATA #IMPLIED
-    nextBoneIdRef CDATA #IMPLIED
->
-
-
-<!-- Rotation ratio between Linked-rotationed bones. -->
-<!ELEMENT rotationRatio EMPTY>
-<!ATTLIST rotationRatio
-    ratio CDATA #REQUIRED
->
-
-
-<!-- Reference to IK-Bone. -->
-<!ELEMENT ikBone EMPTY>
-<!ATTLIST ikBone
-    boneIdRef CDATA #REQUIRED
->
-
-
-<!-- List of Bone-group. -->
-<!ELEMENT boneGroupList (boneGroup)* >
-
-
-<!-- Bone-group. -->
-<!ELEMENT boneGroup (i18nName*, boneGroupMember*) >
-<!ATTLIST boneGroup
-    name CDATA #REQUIRED
->
-
-
-<!-- Member of Bone-group. -->
-<!ELEMENT boneGroupMember EMPTY>
-<!ATTLIST boneGroupMember
-    boneIdRef CDATA #REQUIRED
->
-
-
-<!-- List of IK chain. -->
-<!ELEMENT ikChainList (ikChain)* >
-
-
-<!-- IK chained bones definition. -->
-<!ELEMENT ikChain (chainOrder)+ >
-<!ATTLIST ikChain
-    ikBoneIdRef    CDATA #REQUIRED
-    recursiveDepth CDATA #REQUIRED
-    weight         CDATA #REQUIRED
->
-
-
-<!-- Part of IK chained bones. -->
-<!ELEMENT chainOrder EMPTY>
-<!ATTLIST chainOrder
-    boneIdRef CDATA #REQUIRED
->
-
-
-<!-- List of morphing definition. -->
-<!ELEMENT morphList (morph)* >
-
-
-<!-- Morphing definition. -->
-<!ELEMENT morph (i18nName*, morphVertex*) >
-<!ATTLIST morph
-    name CDATA #REQUIRED
-    type (
-          EYEBROW
-        | EYE
-        | LIP
-        | EXTRA
-    ) #REQUIRED
->
-
-
-<!-- Morphing vertex information. -->
-<!ELEMENT morphVertex EMPTY>
-<!ATTLIST morphVertex
-    vtxIdRef CDATA #REQUIRED
-    xOff     CDATA #REQUIRED
-    yOff     CDATA #REQUIRED
-    zOff     CDATA #REQUIRED
->
-
-
-<!-- list of Rigid-body definition. -->
-<!ELEMENT rigidList (rigid)* >
-
-
-<!-- Rigid-body definition. -->
-<!ELEMENT rigid (
-    i18nName*,
-    linkedBone?,
-    (rigidShapeSphere | rigidShapeBox | rigidShapeCapsule),
-    position,
-    radRotation,
-    dynamics,
-    throughRigidGroup*
-) >
-<!ATTLIST rigid
-    name     CDATA #REQUIRED
-    rigidId  CDATA #REQUIRED
-    behavior (
-          FOLLOWBONE
-        | ONLYDYNAMICS
-        | BONEDDYNAMICS
-    ) #REQUIRED
->
-
-
-<!-- Referenced Bone from Rigid-body. -->
-<!ELEMENT linkedBone EMPTY>
-<!ATTLIST linkedBone
-    boneIdRef CDATA #REQUIRED
->
-
-
-<!-- Sphere shape of Rigid-body. -->
-<!ELEMENT rigidShapeSphere EMPTY>
-<!ATTLIST rigidShapeSphere
-    radius CDATA #REQUIRED
->
-
-
-<!-- Box shape of Rigid-body. -->
-<!ELEMENT rigidShapeBox EMPTY>
-<!ATTLIST rigidShapeBox
-    width  CDATA #REQUIRED
-    height CDATA #REQUIRED
-    depth  CDATA #REQUIRED
->
-
-
-<!-- Capsule shape of Rigid-body. -->
-<!ELEMENT rigidShapeCapsule EMPTY>
-<!ATTLIST rigidShapeCapsule
-    height CDATA #REQUIRED
-    radius CDATA #REQUIRED
->
-
-
-<!-- Rotaion information by radian. -->
-<!ELEMENT radRotation EMPTY>
-<!ATTLIST radRotation
-    xRad CDATA #REQUIRED
-    yRad CDATA #REQUIRED
-    zRad CDATA #REQUIRED
->
-
-
-<!-- Dynamics parameters. -->
-<!ELEMENT dynamics EMPTY>
-<!ATTLIST dynamics
-    mass            CDATA #REQUIRED
-    dampingPosition CDATA #REQUIRED
-    dampingRotation CDATA #REQUIRED
-    restitution     CDATA #REQUIRED
-    friction        CDATA #REQUIRED
->
-
-
-<!-- Reference for non-collision rigid-group. -->
-<!ELEMENT throughRigidGroup EMPTY>
-<!ATTLIST throughRigidGroup
-    rigidGroupIdRef CDATA #REQUIRED
->
-
-
-<!-- List of Rigid-body group. -->
-<!ELEMENT rigidGroupList (rigidGroup)* >
-
-
-<!-- Rigid-body group. -->
-<!ELEMENT rigidGroup (rigidGroupMember)* >
-<!ATTLIST rigidGroup
-    rigidGroupId CDATA #REQUIRED
->
-
-
-<!-- Member of Rigid-body group. -->
-<!ELEMENT rigidGroupMember EMPTY>
-<!ATTLIST rigidGroupMember
-    rigidIdRef CDATA #REQUIRED
->
-
-
-<!-- List of joint definition. -->
-<!ELEMENT jointList (joint)* >
-
-
-<!-- Joint definition. -->
-<!ELEMENT joint (
-    i18nName*,
-    jointedRigidPair,
-    position,    limitPosition,
-    radRotation, limitRotation,
-    elasticPosition,
-    elasticRotation
-) >
-<!ATTLIST joint
-    name CDATA #REQUIRED
->
-
-
-<!-- Jointed-bones information. -->
-<!ELEMENT jointedRigidPair EMPTY>
-<!ATTLIST jointedRigidPair
-    rigidIdRef2 CDATA #REQUIRED
-    rigidIdRef1 CDATA #REQUIRED
->
-
-
-<!-- Limit of Position. -->
-<!ELEMENT limitPosition EMPTY>
-<!ATTLIST limitPosition
-    xFrom CDATA #REQUIRED
-    xTo   CDATA #REQUIRED
-    yFrom CDATA #REQUIRED
-    yTo   CDATA #REQUIRED
-    zFrom CDATA #REQUIRED
-    zTo   CDATA #REQUIRED
->
-
-
-<!-- Limit of Rotation. -->
-<!ELEMENT limitRotation EMPTY>
-<!ATTLIST limitRotation
-    xFrom CDATA #REQUIRED
-    xTo   CDATA #REQUIRED
-    yFrom CDATA #REQUIRED
-    yTo   CDATA #REQUIRED
-    zFrom CDATA #REQUIRED
-    zTo   CDATA #REQUIRED
->
-
-
-<!-- Elastic position of joint. -->
-<!ELEMENT elasticPosition EMPTY>
-<!ATTLIST elasticPosition
-    x CDATA #REQUIRED
-    y CDATA #REQUIRED
-    z CDATA #REQUIRED
->
-
-
-<!-- Elastic rotation of joint by degree. -->
-<!ELEMENT elasticRotation EMPTY>
-<!ATTLIST elasticRotation
-    xDeg CDATA #REQUIRED
-    yDeg CDATA #REQUIRED
-    zDeg CDATA #REQUIRED
->
-
-
-<!-- List of surface group. -->
-<!ELEMENT surfaceGroupList (surfaceGroup)* >
-
-
-<!-- Surface group. -->
-<!ELEMENT surfaceGroup (surface)* >
-<!ATTLIST surfaceGroup
-    surfaceGroupId CDATA #REQUIRED
->
-
-
-<!-- Each surface with Triangle. -->
-<!ELEMENT surface EMPTY>
-<!ATTLIST surface
-    vtxIdRef1 CDATA #REQUIRED
-    vtxIdRef2 CDATA #REQUIRED
-    vtxIdRef3 CDATA #REQUIRED
->
-
-
-<!-- List of vertex. -->
-<!ELEMENT vertexList (vertex)* >
-
-
-<!-- Vertex definition. -->
-<!ELEMENT vertex (position, normal, uvMap, skinning) >
-<!ATTLIST vertex
-    vtxId    CDATA #REQUIRED
-    showEdge CDATA #REQUIRED
->
-
-
-<!-- Normal vector definition. -->
-<!ELEMENT normal EMPTY>
-<!ATTLIST normal
-    x CDATA #REQUIRED
-    y CDATA #REQUIRED
-    z CDATA #REQUIRED
->
-
-
-<!-- UV-mapping information. -->
-<!ELEMENT uvMap EMPTY>
-<!ATTLIST uvMap
-    u CDATA #REQUIRED
-    v CDATA #REQUIRED
->
-
-
-<!-- Skinning definition from vertex to bone. -->
-<!ELEMENT skinning EMPTY>
-<!ATTLIST skinning
-    boneIdRef1    CDATA #REQUIRED
-    boneIdRef2    CDATA #REQUIRED
-    weightBalance CDATA #REQUIRED
->
-
-
-<!-- EOF -->
diff --git a/src/test/java/jp/sfjp/mikutoga/pmd2xml/CmdLineTest.java b/src/test/java/jp/sfjp/mikutoga/pmd2xml/CmdLineTest.java
new file mode 100644 (file)
index 0000000..2e4b794
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class CmdLineTest {
+
+    public CmdLineTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of parse method, of class CmdLine.
+     */
+    @Test
+    public void testParse_StringArr() {
+        System.out.println("parse");
+
+        List<CmdLine> list;
+        List<String> args;
+        CmdLine cmd;
+
+        list = CmdLine.parse();
+        assertEquals(0, list.size());
+
+        list = CmdLine.parse("-h", "-nl", "crlf");
+        assertEquals(2, list.size());
+        cmd = list.get(0);
+        assertSame(OptSwitch.OPT_HELP, cmd.getOptSwitch());
+
+        args = cmd.getOptArgs();
+        assertEquals(1, args.size());
+        assertEquals("-h", args.get(0));
+
+        cmd = list.get(1);
+        assertSame(OptSwitch.OPT_NEWLINE, cmd.getOptSwitch());
+
+        args = cmd.getOptArgs();
+        assertEquals(2, args.size());
+        assertEquals("-nl", args.get(0));
+        assertEquals("crlf", args.get(1));
+
+        list = CmdLine.parse("XXX");
+        assertEquals(1, list.size());
+        cmd = list.get(0);
+        assertNull(cmd.getOptSwitch());
+        args = cmd.getOptArgs();
+        assertEquals(1, args.size());
+        assertEquals("XXX", args.get(0));
+
+        return;
+    }
+
+    /**
+     * Test of parse method, of class CmdLine.
+     */
+    @Test
+    public void testParse_List() {
+        System.out.println("parse");
+
+        List<CmdLine> list;
+        CmdLine cmd;
+
+        list = CmdLine.parse(Arrays.asList("-h"));
+        assertEquals(1, list.size());
+        cmd = list.get(0);
+        assertSame(OptSwitch.OPT_HELP, cmd.getOptSwitch());
+
+        return;
+    }
+
+}
diff --git a/src/test/java/jp/sfjp/mikutoga/pmd2xml/ModelFileTypeTest.java b/src/test/java/jp/sfjp/mikutoga/pmd2xml/ModelFileTypeTest.java
new file mode 100644 (file)
index 0000000..53a2dbb
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+import jp.sfjp.mikutoga.pmd.xml.XmlModelFileType;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class ModelFileTypeTest {
+
+    public ModelFileTypeTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of values method, of class ModelFileType.
+     */
+    @Test
+    public void testValues() {
+        System.out.println("values");
+
+        assertEquals(5, ModelFileType.values().length);
+
+        return;
+    }
+
+    /**
+     * Test of toXmlType method, of class ModelFileType.
+     */
+    @Test
+    public void testToXmlType() {
+        System.out.println("toXmlType");
+
+        assertSame(XmlModelFileType.XML_AUTO, ModelFileType.NONE.toXmlType());
+        assertSame(XmlModelFileType.XML_AUTO, ModelFileType.PMD.toXmlType());
+        assertSame(XmlModelFileType.XML_AUTO, ModelFileType.XML_AUTO.toXmlType());
+        assertSame(XmlModelFileType.XML_101009, ModelFileType.XML_101009.toXmlType());
+        assertSame(XmlModelFileType.XML_130128, ModelFileType.XML_130128.toXmlType());
+
+        return;
+    }
+
+    /**
+     * Test of isXml method, of class ModelFileType.
+     */
+    @Test
+    public void testIsXml() {
+        System.out.println("isXml");
+
+        assertFalse(ModelFileType.NONE.isXml());
+        assertFalse(ModelFileType.PMD.isXml());
+        assertTrue(ModelFileType.XML_AUTO.isXml());
+        assertTrue(ModelFileType.XML_101009.isXml());
+        assertTrue(ModelFileType.XML_130128.isXml());
+
+        return;
+    }
+
+    /**
+     * Test of isPmd method, of class ModelFileType.
+     */
+    @Test
+    public void testIsPmd() {
+        System.out.println("isPmd");
+
+        assertFalse(ModelFileType.NONE.isPmd());
+        assertTrue(ModelFileType.PMD.isPmd());
+        assertFalse(ModelFileType.XML_AUTO.isPmd());
+        assertFalse(ModelFileType.XML_101009.isPmd());
+        assertFalse(ModelFileType.XML_130128.isPmd());
+
+        return;
+    }
+
+}
diff --git a/src/test/java/jp/sfjp/mikutoga/pmd2xml/OptInfoTest.java b/src/test/java/jp/sfjp/mikutoga/pmd2xml/OptInfoTest.java
new file mode 100644 (file)
index 0000000..5efa270
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class OptInfoTest {
+
+    public OptInfoTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of parseOption method, of class OptInfo.
+     */
+    @Test
+    public void testParseOption() throws Exception {
+        System.out.println("parseOption");
+
+        OptInfo info;
+
+        info = OptInfo.parseOption("-i", "ifile.xml", "-o", "ofile.pmd");
+        assertFalse(info.needHelp());
+        assertSame(ModelFileType.XML_AUTO, info.getInFileType());
+        assertSame(ModelFileType.PMD, info.getOutFileType());
+        assertEquals("ifile.xml", info.getInFilename());
+        assertEquals("ofile.pmd", info.getOutFilename());
+        assertFalse(info.overwriteMode());
+        assertEquals("\n", info.getNewline());
+        assertNotNull(info.getGenerator());
+
+        info = OptInfo.parseOption("-i", "ifile.pmd", "-o", "ofile.xml");
+        assertSame(ModelFileType.PMD, info.getInFileType());
+        assertSame(ModelFileType.XML_AUTO, info.getOutFileType());
+
+        info = OptInfo.parseOption("-i", "ifile.xml", "-o", "ofile.pmd", "-f");
+        assertTrue(info.overwriteMode());
+
+        info = OptInfo.parseOption("-i", "ifile.xml", "-o", "ofile.pmd",
+                "-nl", "crlf");
+        assertEquals("\r\n", info.getNewline());
+
+        info = OptInfo.parseOption("-i", "ifile.xml", "-o", "ofile.pmd",
+                "-genout", "off");
+        assertNull(info.getGenerator());
+
+        return;
+    }
+
+    /**
+     * Test of needHelp method, of class OptInfo.
+     */
+    @Test
+    public void testNeedHelp() throws Exception{
+        System.out.println("needHelp");
+
+        OptInfo info;
+
+        info = OptInfo.parseOption("-h");
+        assertTrue(info.needHelp());
+
+        return;
+    }
+
+}
diff --git a/src/test/java/jp/sfjp/mikutoga/pmd2xml/OptSwitchTest.java b/src/test/java/jp/sfjp/mikutoga/pmd2xml/OptSwitchTest.java
new file mode 100644 (file)
index 0000000..4eedbce
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ */
+
+package jp.sfjp.mikutoga.pmd2xml;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class OptSwitchTest {
+
+    public OptSwitchTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of values method, of class OptSwitch.
+     */
+    @Test
+    public void testValues() {
+        System.out.println("values");
+
+        assertEquals(8, OptSwitch.values().length);
+
+        return;
+    }
+
+    /**
+     * Test of valueOf method, of class OptSwitch.
+     */
+    @Test
+    public void testValueOf() {
+        System.out.println("valueOf");
+
+        OptSwitch sw = OptSwitch.valueOf("OPT_HELP");
+        assertSame(OptSwitch.OPT_HELP, sw);
+
+        return;
+    }
+
+    /**
+     * Test of getConsoleHelp method, of class OptSwitch.
+     */
+    @Test
+    public void testGetConsoleHelp() {
+        System.out.println("getConsoleHelp");
+
+        String help = OptSwitch.getConsoleHelp();
+        assertNotNull(help);
+
+        return;
+    }
+
+    /**
+     * Test of parse method, of class OptSwitch.
+     */
+    @Test
+    public void testParse() {
+        System.out.println("parse");
+
+        OptSwitch sw;
+
+        sw = OptSwitch.parse(null);
+        assertNull(sw);
+        sw = OptSwitch.parse("");
+        assertNull(sw);
+        sw = OptSwitch.parse("help");
+        assertNull(sw);
+
+        sw = OptSwitch.parse("-h");
+        assertSame(OptSwitch.OPT_HELP, sw);
+        sw = OptSwitch.parse("-help");
+        assertSame(OptSwitch.OPT_HELP, sw);
+        sw = OptSwitch.parse("-?");
+        assertSame(OptSwitch.OPT_HELP, sw);
+
+        sw = OptSwitch.parse("-i");
+        assertSame(OptSwitch.OPT_INFILE, sw);
+        sw = OptSwitch.parse("-o");
+        assertSame(OptSwitch.OPT_OUTFILE, sw);
+        sw = OptSwitch.parse("-f");
+        assertSame(OptSwitch.OPT_FORCE, sw);
+
+        sw = OptSwitch.parse("-nl");
+        assertSame(OptSwitch.OPT_NEWLINE, sw);
+        sw = OptSwitch.parse("-genout");
+        assertSame(OptSwitch.OPT_GENOUT, sw);
+
+        sw = OptSwitch.parse("-iform");
+        assertSame(OptSwitch.OPT_IFORM, sw);
+        sw = OptSwitch.parse("-oform");
+        assertSame(OptSwitch.OPT_OFORM, sw);
+
+        return;
+    }
+
+    /**
+     * Test of getExArgNum method, of class OptSwitch.
+     */
+    @Test
+    public void testGetExArgNum() {
+        System.out.println("getExArgNum");
+
+        assertEquals(0, OptSwitch.OPT_HELP.getExArgNum());
+        assertEquals(1, OptSwitch.OPT_INFILE.getExArgNum());
+        assertEquals(1, OptSwitch.OPT_OUTFILE.getExArgNum());
+        assertEquals(0, OptSwitch.OPT_FORCE.getExArgNum());
+        assertEquals(1, OptSwitch.OPT_NEWLINE.getExArgNum());
+        assertEquals(1, OptSwitch.OPT_GENOUT.getExArgNum());
+        assertEquals(1, OptSwitch.OPT_IFORM.getExArgNum());
+        assertEquals(1, OptSwitch.OPT_OFORM.getExArgNum());
+
+        return;
+    }
+
+}
index 8416560..1d73e22 100644 (file)
@@ -11,8 +11,8 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import jp.sourceforge.mikutoga.pmd.ModelFileType;
-import jp.sourceforge.mikutoga.pmd2xml.Pmd2XmlConv;
+import jp.sfjp.mikutoga.pmd2xml.ModelFileType;
+import jp.sfjp.mikutoga.pmd2xml.Pmd2XmlConv;
 
 import static org.junit.Assert.*;
 
@@ -21,6 +21,9 @@ import static org.junit.Assert.*;
  */
 public class CnvAssert {
 
+    private CnvAssert(){
+    }
+
     /**
      * テスト出力用テンポラリファイルの生成。
      * テスト終了時(VM終了時)に消える。
@@ -56,7 +59,7 @@ public class CnvAssert {
         destOut = new BufferedOutputStream(destOut);
 
         Pmd2XmlConv converter = new Pmd2XmlConv();
-        converter.setInType(ModelFileType.XML_101009);
+        converter.setInType(ModelFileType.XML_AUTO);
         converter.setOutType(ModelFileType.PMD);
         converter.setNewline("\n");
 
@@ -109,6 +112,44 @@ public class CnvAssert {
     }
 
     /**
+     * PMDリソースをXMLに変換した結果がXMLリソースに等しいと表明する。
+     * @param klass リソース元クラス
+     * @param pmdResource PMDリソース名
+     * @param expXmlResource XMLリソース名
+     * @throws Exception エラー
+     */
+    public static void assertPmd2Xml13(
+            Class<?> klass,
+            String pmdResource,
+            String expXmlResource )
+            throws Exception{
+        InputStream pmdis =
+                klass.getResourceAsStream(pmdResource);
+        assertNotNull(pmdis);
+        pmdis = new BufferedInputStream(pmdis);
+
+        File destFile = openTempFile();
+        OutputStream destOut;
+        destOut = new FileOutputStream(destFile);
+        destOut = new BufferedOutputStream(destOut);
+
+        Pmd2XmlConv converter = new Pmd2XmlConv();
+        converter.setInType(ModelFileType.PMD);
+        converter.setOutType(ModelFileType.XML_130128);
+        converter.setNewline("\n");
+        converter.setGenerator(null);
+
+        converter.convert(pmdis, destOut);
+
+        pmdis.close();
+        destOut.close();
+
+        assertSameFile(klass, expXmlResource, destFile);
+
+        return;
+    }
+
+    /**
      * リソースとファイルの内容が等しいと表明する。
      * @param klass リソース元クラス
      * @param resourceName リソース名
diff --git a/src/test/java/testdata/pmd101009/xml/XmlTest.java b/src/test/java/testdata/pmd101009/xml/XmlTest.java
new file mode 100644 (file)
index 0000000..d988fda
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ */
+
+package testdata.pmd101009.xml;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class XmlTest {
+
+    static Class<?> THISCLASS = XmlTest.class;
+
+    public XmlTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "namespace.xml", "minimum.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/bone/BoneTest.java b/src/test/java/testdata/pmd130128/bone/BoneTest.java
new file mode 100644 (file)
index 0000000..4915d7d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.bone;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class BoneTest {
+
+    static Class<?> THISCLASS = BoneTest.class;
+
+    public BoneTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "allbone.pmd", "allbone.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "allbone.xml", "allbone.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/charset/CharsetTest.java b/src/test/java/testdata/pmd130128/charset/CharsetTest.java
new file mode 100644 (file)
index 0000000..06cb0e3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.charset;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class CharsetTest {
+
+    static Class<?> THISCLASS = CharsetTest.class;
+
+    public CharsetTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "charset.pmd", "result.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "source.xml", "charset.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/group/GroupTest.java b/src/test/java/testdata/pmd130128/group/GroupTest.java
new file mode 100644 (file)
index 0000000..460ec66
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.group;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class GroupTest {
+
+    static Class<?> THISCLASS = GroupTest.class;
+
+    public GroupTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "boneGroup.pmd", "boneGroup.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "boneGroup.xml", "boneGroup.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/i18n/I18nTest.java b/src/test/java/testdata/pmd130128/i18n/I18nTest.java
new file mode 100644 (file)
index 0000000..5d2f8e6
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.i18n;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class I18nTest {
+
+    static Class<?> THISCLASS = I18nTest.class;
+
+    public I18nTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "i18n.pmd", "i18n.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "i18n.xml", "i18n.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/ik/IkBoneTest.java b/src/test/java/testdata/pmd130128/ik/IkBoneTest.java
new file mode 100644 (file)
index 0000000..af6b174
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.ik;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class IkBoneTest {
+
+    static Class<?> THISCLASS = IkBoneTest.class;
+
+    public IkBoneTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "ikBone.pmd", "ikBone.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "ikBone.xml", "ikBone.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/material/MaterialTest.java b/src/test/java/testdata/pmd130128/material/MaterialTest.java
new file mode 100644 (file)
index 0000000..6c3a5b4
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.material;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class MaterialTest {
+
+    static Class<?> THISCLASS = MaterialTest.class;
+
+    public MaterialTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "material.pmd", "material.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "material.xml", "material.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/minimum/MinimumTest.java b/src/test/java/testdata/pmd130128/minimum/MinimumTest.java
new file mode 100644 (file)
index 0000000..5112c84
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.minimum;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class MinimumTest {
+
+    static Class<?> THISCLASS = MinimumTest.class;
+
+    public MinimumTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "minimum.pmd", "minimum.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "minimum.xml", "minimum.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/morph/MorphTest.java b/src/test/java/testdata/pmd130128/morph/MorphTest.java
new file mode 100644 (file)
index 0000000..618f889
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.morph;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class MorphTest {
+
+    static Class<?> THISCLASS = MorphTest.class;
+
+    public MorphTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "allmorph.pmd", "allmorph.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "allmorph.xml", "allmorph.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/numeric/NumericTest.java b/src/test/java/testdata/pmd130128/numeric/NumericTest.java
new file mode 100644 (file)
index 0000000..3b97130
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.numeric;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class NumericTest {
+
+    static Class<?> THISCLASS = NumericTest.class;
+
+    public NumericTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "numeric.pmd", "result.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "source.xml", "numeric.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/rigid/RigidTest.java b/src/test/java/testdata/pmd130128/rigid/RigidTest.java
new file mode 100644 (file)
index 0000000..085cb31
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd130128.rigid;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class RigidTest {
+
+    static Class<?> THISCLASS = RigidTest.class;
+
+    public RigidTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml13(THISCLASS, "allrigid.pmd", "allrigid.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "allrigid.xml", "allrigid.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/small/SmallTest.java b/src/test/java/testdata/pmd130128/small/SmallTest.java
new file mode 100644 (file)
index 0000000..25ac86d
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ */
+
+package testdata.pmd130128.small;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class SmallTest {
+
+    static Class<?> THISCLASS = SmallTest.class;
+
+    public SmallTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xmlBone() throws Exception{
+        System.out.println("pmd2xmlBone");
+        assertPmd2Xml13(THISCLASS, "onlybone.pmd", "onlybone.xml");
+        return;
+    }
+
+    @Test
+    public void pmd2xmlTriangle() throws Exception{
+        System.out.println("pmd2xmlTriangle");
+        assertPmd2Xml13(THISCLASS, "onlytriangle.pmd", "onlytriangle.xml");
+        return;
+    }
+
+    @Test
+    public void pmd2xmlMorph() throws Exception{
+        System.out.println("pmd2xmlMorph");
+        assertPmd2Xml13(THISCLASS, "onlymorph.pmd", "onlymorph.xml");
+        return;
+    }
+
+    @Test
+    public void pmd2xmlRigid() throws Exception{
+        System.out.println("pmd2xmlRigid");
+        assertPmd2Xml13(THISCLASS, "onlyrigid.pmd", "onlyrigid.xml");
+        return;
+    }
+
+    @Test
+    public void pmd2xmlJoint() throws Exception{
+        System.out.println("pmd2xmlJoint");
+        assertPmd2Xml13(THISCLASS, "onlyjoint.pmd", "onlyjoint.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmdBone() throws Exception{
+        System.out.println("xml2pmdBone");
+        assertXml2Pmd(THISCLASS, "onlybone.xml", "onlybone.pmd");
+        return;
+    }
+
+    @Test
+    public void xml2pmdTriangle() throws Exception{
+        System.out.println("xml2pmdTriangle");
+        assertXml2Pmd(THISCLASS, "onlytriangle.xml", "onlytriangle.pmd");
+        return;
+    }
+
+    @Test
+    public void xml2pmdMorph() throws Exception{
+        System.out.println("xml2pmdMorph");
+        assertXml2Pmd(THISCLASS, "onlymorph.xml", "onlymorph.pmd");
+        return;
+    }
+
+    @Test
+    public void xml2pmdRigid() throws Exception{
+        System.out.println("xml2pmdRigid");
+        assertXml2Pmd(THISCLASS, "onlyrigid.xml", "onlyrigid.pmd");
+        return;
+    }
+
+    @Test
+    public void xml2pmdJoint() throws Exception{
+        System.out.println("xml2pmdJoint");
+        assertXml2Pmd(THISCLASS, "onlyjoint.xml", "onlyjoint.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd130128/xml/XmlTest.java b/src/test/java/testdata/pmd130128/xml/XmlTest.java
new file mode 100644 (file)
index 0000000..2001cb7
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ */
+
+package testdata.pmd130128.xml;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class XmlTest {
+
+    static Class<?> THISCLASS = XmlTest.class;
+
+    public XmlTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "namespace.xml", "minimum.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/resources/testdata/pmd101009/xml/Readme.txt b/src/test/resources/testdata/pmd101009/xml/Readme.txt
new file mode 100644 (file)
index 0000000..43f179c
--- /dev/null
@@ -0,0 +1,13 @@
+[UTF8 Japanese]
+
+
+各種XML機能検証用のテストデータ。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- minimum.pmd 最小構成のテストデータ。
+- namespace.xml 名前空間「testns」を用いたXMLファイル。
+
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/xml/minimum.pmd b/src/test/resources/testdata/pmd101009/xml/minimum.pmd
new file mode 100644 (file)
index 0000000..c2fb71c
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/xml/minimum.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/xml/namespace.xml b/src/test/resources/testdata/pmd101009/xml/namespace.xml
new file mode 100644 (file)
index 0000000..88ce941
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<testns:pmdModel
+  xmlns:testns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<testns:description>
+</testns:description>
+
+<testns:license>
+</testns:license>
+
+<testns:credits>
+</testns:credits>
+
+<testns:meta name="siteURL" content="" />
+<testns:meta name="imageURL" content="" />
+
+<testns:materialList>
+</testns:materialList>
+
+<testns:toonMap>
+  <testns:toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <testns:toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <testns:toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <testns:toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <testns:toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <testns:toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <testns:toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <testns:toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <testns:toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <testns:toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</testns:toonMap>
+
+<testns:boneList>
+</testns:boneList>
+
+<testns:boneGroupList>
+</testns:boneGroupList>
+
+<testns:ikChainList>
+</testns:ikChainList>
+
+<testns:morphList>
+</testns:morphList>
+
+<testns:rigidList>
+</testns:rigidList>
+
+<testns:rigidGroupList>
+
+  <testns:rigidGroup rigidGroupId="rg1" />
+  <testns:rigidGroup rigidGroupId="rg2" />
+  <testns:rigidGroup rigidGroupId="rg3" />
+  <testns:rigidGroup rigidGroupId="rg4" />
+  <testns:rigidGroup rigidGroupId="rg5" />
+  <testns:rigidGroup rigidGroupId="rg6" />
+  <testns:rigidGroup rigidGroupId="rg7" />
+  <testns:rigidGroup rigidGroupId="rg8" />
+  <testns:rigidGroup rigidGroupId="rg9" />
+  <testns:rigidGroup rigidGroupId="rg10" />
+  <testns:rigidGroup rigidGroupId="rg11" />
+  <testns:rigidGroup rigidGroupId="rg12" />
+  <testns:rigidGroup rigidGroupId="rg13" />
+  <testns:rigidGroup rigidGroupId="rg14" />
+  <testns:rigidGroup rigidGroupId="rg15" />
+  <testns:rigidGroup rigidGroupId="rg16" />
+
+</testns:rigidGroupList>
+
+<testns:jointList>
+</testns:jointList>
+
+<testns:surfaceGroupList>
+</testns:surfaceGroupList>
+
+<testns:vertexList>
+</testns:vertexList>
+
+</testns:pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd130128/bone/Readme.txt b/src/test/resources/testdata/pmd130128/bone/Readme.txt
new file mode 100644 (file)
index 0000000..5b53910
--- /dev/null
@@ -0,0 +1,13 @@
+[UTF8 Japanese]
+
+
+10種類全てのボーンを含むPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- allbone.pmd 10種類全てのボーンを含むテストデータ。
+- allbone.xml モデルデータのソースとなったXMLファイル。
+
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd130128/bone/allbone.pmd b/src/test/resources/testdata/pmd130128/bone/allbone.pmd
new file mode 100644 (file)
index 0000000..1e76145
Binary files /dev/null and b/src/test/resources/testdata/pmd130128/bone/allbone.pmd differ
diff --git a/src/test/resources/testdata/pmd130128/bone/allbone.xml b/src/test/resources/testdata/pmd130128/bone/allbone.xml
new file mode 100644 (file)
index 0000000..b8142a1
--- /dev/null
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-130128.xsd"
+  schemaVersion="130128"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- base [回転/移動] -->
+  <bone name="base" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- #>> [anchor] -->
+    <boneChain nextBoneIdRef="bn1" />
+  </bone>
+
+  <!-- anchor [非表示] -->
+  <bone name="anchor" boneId="bn1" type="HIDDEN" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [base] >># -->
+    <boneChain prevBoneIdRef="bn0" />
+  </bone>
+
+  <!-- hub [回転] -->
+  <bone name="hub" boneId="bn2" type="ROTATE" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [base] >>#>> [hinge1] -->
+    <boneChain prevBoneIdRef="bn0" nextBoneIdRef="bn3" />
+  </bone>
+
+  <!-- hinge1 [IK影響下(回転)] -->
+  <bone name="hinge1" boneId="bn3" type="UNDERIK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <sourceBone boneIdRef="bn7" /> <!-- Ref:ik -->
+
+    <!-- [hub] >>#>> [hinge2] -->
+    <boneChain prevBoneIdRef="bn2" nextBoneIdRef="bn4" />
+  </bone>
+
+  <!-- hinge2 [IK影響下(回転)] -->
+  <bone name="hinge2" boneId="bn4" type="UNDERIK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <sourceBone boneIdRef="bn7" /> <!-- Ref:ik -->
+
+    <!-- [hinge1] >>#>> [iktarget] -->
+    <boneChain prevBoneIdRef="bn3" nextBoneIdRef="bn5" />
+  </bone>
+
+  <!-- iktarget [IK影響下(回転)] -->
+  <bone name="iktarget" boneId="bn5" type="UNDERIK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <sourceBone boneIdRef="bn7" /> <!-- Ref:ik -->
+
+    <!-- [hinge2] >>#>> [toe] -->
+    <boneChain prevBoneIdRef="bn4" nextBoneIdRef="bn6" />
+  </bone>
+
+  <!-- toe [IK接続先] -->
+  <bone name="toe" boneId="bn6" type="IKCONNECTED" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <sourceBone boneIdRef="bn7" /> <!-- Ref:ik -->
+
+    <!-- [iktarget] >># -->
+    <boneChain prevBoneIdRef="bn5" />
+  </bone>
+
+  <!-- ik [IK] -->
+  <bone name="ik" boneId="bn7" type="IK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- toeik [IK] -->
+  <bone name="toeik" boneId="bn8" type="IK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- botheye [回転] -->
+  <bone name="botheye" boneId="bn9" type="ROTATE" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [hub] >># -->
+    <boneChain prevBoneIdRef="bn2" />
+  </bone>
+
+  <!-- monoeye [回転影響下] -->
+  <bone name="monoeye" boneId="bn10" type="UNDERROT" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <sourceBone boneIdRef="bn9" /> <!-- Ref:botheye -->
+
+    <!-- [hub] >># -->
+    <boneChain prevBoneIdRef="bn2" />
+  </bone>
+
+  <!-- arm [回転] -->
+  <bone name="arm" boneId="bn11" type="ROTATE" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [hub] >>#>> [elbow] -->
+    <boneChain prevBoneIdRef="bn2" nextBoneIdRef="bn13" />
+  </bone>
+
+  <!-- twist [捩り] -->
+  <bone name="twist" boneId="bn12" type="TWIST" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [arm] >># -->
+    <boneChain prevBoneIdRef="bn11" />
+  </bone>
+
+  <!-- elbow [回転] -->
+  <bone name="elbow" boneId="bn13" type="ROTATE" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [twist] >># -->
+    <boneChain prevBoneIdRef="bn12" />
+  </bone>
+
+  <!-- lr [回転連動] -->
+  <bone name="lr" boneId="bn14" type="LINKEDROT" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <rotationRatio ratio="25" />
+
+    <!-- [arm] >>#>> [twist] -->
+    <boneChain prevBoneIdRef="bn11" nextBoneIdRef="bn12" />
+  </bone>
+
+  <!-- unknown [不明] -->
+  <bone name="unknown" boneId="bn15" type="UNKNOWN" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+
+  <!-- Ref:ik -->
+  <ikChain ikBoneIdRef="bn7" recursiveDepth="10" weight="0.1" >
+    <chainOrder boneIdRef="bn5" /> <!-- Ref:iktarget -->
+    <chainOrder boneIdRef="bn4" /> <!-- Ref:hinge2 -->
+    <chainOrder boneIdRef="bn3" /> <!-- Ref:hinge1 -->
+  </ikChain>
+
+  <!-- Ref:toeik -->
+  <ikChain ikBoneIdRef="bn8" recursiveDepth="10" weight="0.1" >
+    <chainOrder boneIdRef="bn6" /> <!-- Ref:toe -->
+    <chainOrder boneIdRef="bn5" /> <!-- Ref:iktarget -->
+  </ikChain>
+
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd130128/charset/Readme.txt b/src/test/resources/testdata/pmd130128/charset/Readme.txt
new file mode 100644 (file)
index 0000000..f003f87
--- /dev/null
@@ -0,0 +1,27 @@
+[UTF8 Japanese]
+
+
+文字集合、エンコーディング、空白文字に関するPMDテストデータ。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- charset.pmd モデル名とモデル説明文に色々な字が書き込まれたテストデータ。
+- source.xml モデルデータのソースとなったXMLファイル。
+- result.xml モデルデータをXML化したときのあるべきXMLファイル。
+
+
+PMDモデルファイル内の文字データは
+文字集合「JIS X 0208-1990」に
+マイクロソフトによる追加文字を加えた物を
+シフトJISで符号化したものと仮定する。
+
+この文字コード形式の一般的な規格名は
+・Windows-31J
+・CP932
+など
+
+MMDでは、濁点を伴う半角カタカナなどをそのまま識別子に使う機会も多い。
+Unicodeデータとの交換時には、不用意な正規化を行わないよう注意が必要。
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd130128/charset/charset.pmd b/src/test/resources/testdata/pmd130128/charset/charset.pmd
new file mode 100644 (file)
index 0000000..cd33fe5
Binary files /dev/null and b/src/test/resources/testdata/pmd130128/charset/charset.pmd differ
diff --git a/src/test/resources/testdata/pmd130128/charset/result.xml b/src/test/resources/testdata/pmd130128/charset/result.xml
new file mode 100644 (file)
index 0000000..b47d8bf
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- a A  9 亜'" -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-130128.xsd"
+  schemaVersion="130128"
+
+  name="a A &#x20;9&#x3000;&#x4E9C;&apos;&quot;"
+>
+
+
+<description>
+azAZ09&#xFF71;<br/>
+&#xFF21;&#xFF3A;&#xFF10;&#xFF19;&#x3042;&#x30A2;&#x3091;&#x30F5;&#x30F6;<br/>
+&#x30F4;&#x30A6;&#x309B;&#xFF73;&#xFF9E;&#x30D1;&#x30CF;&#x309C;&#xFF8A;&#xFF9F;<br/>
+&#x03A9;&#x03C9;&#x0416;&#x0436;&#x2534;<br/>
+&#x5CE0;&#x58FA;&#x58F7;&#x5C2D;&#x582F;&#x51DC;&#x7199;<br/>
+\&#xFF3C;\&#xFFE5;<br/>
+&#x9AD9;&#x2468;&#x2252;&#x2235;&#xFFE2;&#x3231;&#x03A3;<br/>
+#$[\]^{|}~<br/>
+&apos;&quot;&amp;&lt;&gt;<br/>
+&lt;!--fake comment--&gt;<br/>
+A B &#x20;C<br/>
+A&#x09;B&#x09;&#x09;C<br/>
+A&#x3000;B&#x3000;&#x3000;C<br/>
+AB<br/>
+</description>
+<!--
+azAZ09ア
+AZ09あアゑヵヶ
+ヴウ゛ヴパハ゜パ
+ΩωЖж┴
+峠壺壷尭堯凜熙
+\\\¥
+髙⑨≒∵¬㈱Σ
+#$[\]^{|}~
+'"&<>
+<!- -fake comment- ->
+A B  C
+A␉B␉␉C
+A B  C
+AB
+-->
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd130128/charset/source.xml b/src/test/resources/testdata/pmd130128/charset/source.xml
new file mode 100644 (file)
index 0000000..eb60933
--- /dev/null
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-130128.xsd"
+  schemaVersion="130128"
+
+  name="a A  9 亜&apos;&quot;"
+>
+
+
+<description>
+azAZ09ア<br/><!--                           半角 -->
+AZ09あアゑヵヶ<br/><!--                全角 -->
+ヴウ゛ヴパハ゜パ<br/><!--                  濁点 & 半濁点 -->
+ΩωЖж┴<br/><!--                        ギリシャ & ロシア & 罫線 -->
+峠壺壷尭堯凜熙<br/><!--                    国字 JIS78 → JIS83 → JIS90 -->
+\\¥¥<br/><!--                            円通貨 & バックスラッシュ -->
+髙⑨≒∵¬㈱Σ<br/><!--                    IBM漢字 & NEC漢字 & MS漢字 -->
+#$[\]^{|}~<br/><!--                        ISO-646 バリアント -->
+<![CDATA['"&<>]]><br/><!--                 XML 特殊文字 -->
+<![CDATA[<!--fake comment-->]]><br/><!--   コメントのCDATA化 -->
+A B  C<br/><!--                            半角スペース -->
+A&#x09;B&#x09;&#x09;C<br/><!--           タブ -->
+A B  C<br/><!--                         全角スペース -->
+A&#x0A;B<br/><!--                          無視される改行 -->
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+</boneList>
+
+<boneGroupList>
+
+</boneGroupList>
+
+<ikChainList>
+
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+
+</jointList>
+
+<surfaceGroupList>
+
+</surfaceGroupList>
+
+<vertexList>
+
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd130128/group/Readme.txt b/src/test/resources/testdata/pmd130128/group/Readme.txt
new file mode 100644 (file)
index 0000000..1f9a2d1
--- /dev/null
@@ -0,0 +1,18 @@
+[UTF8 Japanese]
+
+
+ボーンをグループ分けしたPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- boneGroup.pmd グループ分けされたボーンを有するテストデータ。
+- boneGroup.xml モデルデータのソースとなったXMLファイル。
+
+
+test0からtest3までの名が付けられた4ボーンが
+ボーン枠「偶数ボーン」とボーン枠「奇数ボーン」に2つずつ振り分けられる。
+
+ボーン名「test」は0番ボーン扱い。
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd130128/group/boneGroup.pmd b/src/test/resources/testdata/pmd130128/group/boneGroup.pmd
new file mode 100644 (file)
index 0000000..5e7ba42
Binary files /dev/null and b/src/test/resources/testdata/pmd130128/group/boneGroup.pmd differ
diff --git a/src/test/resources/testdata/pmd130128/group/boneGroup.xml b/src/test/resources/testdata/pmd130128/group/boneGroup.xml
new file mode 100644 (file)
index 0000000..273d44b
--- /dev/null
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/130128
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-130128.xsd"
+  schemaVersion="130128"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- test [回転/移動] -->
+  <bone name="test" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test0 [回転/移動] -->
+  <bone name="test0" boneId="bn1" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test1 [回転/移動] -->
+  <bone name="test1" boneId="bn2" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test2 [回転/移動] -->
+  <bone name="test2" boneId="bn3" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test3 [回転/移動] -->
+  <bone name="test3" boneId="bn4" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+
+  <!-- 偶数グループ -->
+  <boneGroup name="&#x5076;&#x6570;&#x30B0;&#x30EB;&#x30FC;&#x30D7;" >
+    <boneGroupMember boneIdRef="bn1" /> <!-- Ref:test0 -->
+    <boneGroupMember boneIdRef="bn3" /> <!-- Ref:test2 -->
+  </boneGroup>
+
+  <!-- 奇数グループ -->
+  <boneGroup name="&#x5947;&#x6570;&#x30B0;&#x30EB;&#x30FC;&#x30D7;" >
+    <boneGroupMember boneIdRef="bn2" /> <!-- Ref:test1 -->
+    <boneGroupMember boneIdRef="bn4" /> <!-- Ref:test3 -->
+  </boneGroup>
+
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd130128/i18n/Readme.txt b/src/test/resources/testdata/pmd130128/i18n/Readme.txt
new file mode 100644 (file)
index 0000000..31897a9
--- /dev/null
@@ -0,0 +1,21 @@
+[UTF8 Japanese]
+
+
+各種英語名を記述したPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- i18n.pmd 英語名が記述されたテストデータ。
+- i18n.xml モデルデータのソースと