OSDN Git Service

Merge develop into pomconfig
authorOlyutorskii <olyutorskii@users.osdn.me>
Tue, 2 Jul 2019 06:37:25 +0000 (15:37 +0900)
committerOlyutorskii <olyutorskii@users.osdn.me>
Tue, 2 Jul 2019 06:37:25 +0000 (15:37 +0900)
82 files changed:
CHANGELOG.txt
config/checkstyle/checkstyle-suppressions.xml
config/checkstyle/checkstyle.xml
config/pmd/pmdrules.xml
pom.xml
src/main/java/jp/sfjp/mikutoga/bin/export/BinaryExporter.java
src/main/java/jp/sfjp/mikutoga/bin/export/IllegalTextExportException.java
src/main/java/jp/sfjp/mikutoga/bin/export/TextExporter.java
src/main/java/jp/sfjp/mikutoga/bin/parser/BinParser.java
src/main/java/jp/sfjp/mikutoga/bin/parser/CommonParser.java
src/main/java/jp/sfjp/mikutoga/bin/parser/LoopHandler.java
src/main/java/jp/sfjp/mikutoga/bin/parser/MmdEofException.java
src/main/java/jp/sfjp/mikutoga/bin/parser/MmdFormatException.java
src/main/java/jp/sfjp/mikutoga/bin/parser/ParseStage.java
src/main/java/jp/sfjp/mikutoga/bin/parser/ProxyParser.java
src/main/java/jp/sfjp/mikutoga/bin/parser/TextDecoder.java
src/main/java/jp/sfjp/mikutoga/bin/parser/package-info.java
src/main/java/jp/sfjp/mikutoga/corelib/EmptyProxyFactory.java
src/main/java/jp/sfjp/mikutoga/corelib/I18nText.java
src/main/java/jp/sfjp/mikutoga/math/EulerYXZ.java
src/main/java/jp/sfjp/mikutoga/math/MkPos2D.java
src/main/java/jp/sfjp/mikutoga/math/MkPos3D.java
src/main/java/jp/sfjp/mikutoga/math/MkQuat.java
src/main/java/jp/sfjp/mikutoga/math/package-info.java
src/main/java/jp/sfjp/mikutoga/pmd/BoneType.java
src/main/java/jp/sfjp/mikutoga/pmd/MorphType.java
src/main/java/jp/sfjp/mikutoga/pmd/PmdConst.java
src/main/java/jp/sfjp/mikutoga/pmd/RigidBehaviorType.java
src/main/java/jp/sfjp/mikutoga/pmd/RigidShapeType.java
src/main/java/jp/sfjp/mikutoga/pmd/ShadingUtil.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdBasicHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdBoneHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdEngHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdJointHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdMaterialHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdMorphHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdParser.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdParserBase.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdParserExt1.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdParserExt2.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdParserExt3.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdRigidHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdShapeHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdToonHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/PmdUnifiedHandler.java
src/main/java/jp/sfjp/mikutoga/pmd/parser/package-info.java
src/main/java/jp/sfjp/mikutoga/typical/AliasMap.java
src/main/java/jp/sfjp/mikutoga/typical/I18nAlias.java
src/main/java/jp/sfjp/mikutoga/typical/TypicalBone.java
src/main/java/jp/sfjp/mikutoga/typical/TypicalMorph.java
src/main/java/jp/sfjp/mikutoga/typical/UniqBone.java
src/main/java/jp/sfjp/mikutoga/typical/package-info.java
src/main/java/jp/sfjp/mikutoga/vmd/FrameNumbered.java
src/main/java/jp/sfjp/mikutoga/vmd/VmdConst.java
src/main/java/jp/sfjp/mikutoga/vmd/VmdUniq.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdBasicHandler.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdBasicParser.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdBoolHandler.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdBoolParser.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdCameraHandler.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdCameraParser.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdLightingHandler.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdLightingParser.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdParser.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/VmdUnifiedHandler.java
src/main/java/jp/sfjp/mikutoga/vmd/parser/package-info.java
src/main/java/jp/sfjp/mikutoga/xml/AbstractXmlExporter.java
src/main/java/jp/sfjp/mikutoga/xml/DatatypeIo.java
src/main/java/jp/sfjp/mikutoga/xml/DomNsUtils.java [deleted file]
src/main/java/jp/sfjp/mikutoga/xml/DomUtils.java [deleted file]
src/main/java/jp/sfjp/mikutoga/xml/LocalXmlResource.java [deleted file]
src/main/java/jp/sfjp/mikutoga/xml/NoopEntityResolver.java [new file with mode: 0644]
src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java
src/main/java/jp/sfjp/mikutoga/xml/SiblingElemIterator.java [deleted file]
src/main/java/jp/sfjp/mikutoga/xml/XmlExporter.java
src/main/java/jp/sfjp/mikutoga/xml/XmlResourceResolver.java
src/test/java/jp/sfjp/mikutoga/math/MkPos2DTest.java
src/test/java/jp/sfjp/mikutoga/math/MkPos3DTest.java
src/test/java/jp/sfjp/mikutoga/math/MkQuatTest.java
src/test/java/jp/sfjp/mikutoga/xml/BasicXmlExporterTest.java
src/test/java/jp/sfjp/mikutoga/xml/DomUtilsTest.java [deleted file]
src/test/java/jp/sfjp/mikutoga/xml/XmlResourceResolverTest.java [new file with mode: 0644]

index 8577d10..c5293d0 100644 (file)
@@ -4,6 +4,12 @@
 TogaGem 変更履歴
 
 
+X.XXX.X (XXXX-XX-XX)
+    * Prevent XXE vulnerabilities.
+    * Split entity resolver from resource resolver to prevent XXE vulnerability.
+    * Make Schema-factory safe to prevent XXE vulnerability.
+    * Move out xml-xsd info from resolver.
+
 3.121.2 (2019-06-06)
     ・DatatypeIo is public now, for replacing JAXB.
 
index 9b0570a..3860edf 100644 (file)
@@ -6,7 +6,7 @@
 
 <!--
     Checkstyle suppressions
-    for Checkstyle 8.20 or later
+    for Checkstyle 8.22 or later
 
     [ https://checkstyle.org/ ]
 
     <suppress files="" checks="ImportControl" />
 
     <!-- Javadoc Comments -->
-    <suppress files="" checks="JavadocParagraph" />
-    <suppress files="" checks="JavadocTagContinuationIndentation" />
     <suppress files="" checks="SummaryJavadocCheck" />
 
     <!-- Miscellaneous -->
     <suppress files="" checks="FinalParameters" />
+    <suppress files="" checks="OrderedProperties" />
     <suppress files="" checks="TrailingComment" />
 
     <!-- Modifier -->
-    <suppress files="" checks="InterfaceMemberImpliedModifier" />
+    <suppress files="" checks="RedundantModifier" />
 
     <!-- Whitespace -->
+    <suppress files="" checks="ParenPad" />
     <suppress files="" checks="SingleSpaceSeparator" />
 
 </suppressions>
index 7d19930..0b1ceb5 100644 (file)
@@ -6,7 +6,7 @@
 
 <!--
     Checkstyle modules
-    for Checkstyle 8.21 or later
+    for Checkstyle 8.22 or later
 
     [ https://checkstyle.org/ ]
 
@@ -39,6 +39,7 @@
         <property name="fileExtensions" value="xml" />
     </module>
     <module name="RegexpHeader">
+        <!-- /* ... */ -->
         <property name="header" value="^/\*$\n^ \*( .*)?$\n^ \*/$\n" />
         <property name="multiLines" value="2" />
         <property name="fileExtensions" value="java" />
@@ -55,6 +56,7 @@
     <module name="NewlineAtEndOfFile">
         <property name="fileExtensions" value="java, properties, xml, xsd, md, txt" />
     </module>
+    <module name="OrderedProperties" />
     <module name="Translation" />
     <module name="UniqueProperties" />
 
         <module name="RequireThis">
             <property name="checkMethods" value="false" />
         </module>
-        <module name="ReturnCount" />
+        <module name="ReturnCount">
+            <property name="max" value="5" />
+            <property name="maxForVoid" value="5" />
+        </module>
         <module name="SimplifyBooleanExpression" />
         <module name="SimplifyBooleanReturn" />
         <module name="StringLiteralEquality" />
         <module name="SuperClone" />
         <module name="SuperFinalize" />
         <module name="UnnecessaryParentheses" />
+        <module name="UnnecessarySemicolonInEnumeration" />
+        <module name="UnnecessarySemicolonInTryWithResources" />
         <module name="VariableDeclarationUsageDistance">
             <property name="allowedDistance" value="5"/>
         </module>
             <property name="scope" value="protected" />
         </module>
         <module name="MissingJavadocMethod" />
+        <module name="MissingJavadocPackage" />
         <module name="MissingJavadocType" />
         <module name="NonEmptyAtclauseDescription" />
         <module name="SingleLineJavadoc" />
         <module name="GenericWhitespace" />
         <module name="MethodParamPad" />
         <module name="NoLineWrap" />
-        <module name="NoWhitespaceAfter" />
-        <module name="NoWhitespaceBefore" />
-        <module name="OperatorWrap" />
-        <module name="ParenPad">
-            <property name="option" value="nospace" />
+        <module name="NoWhitespaceAfter">
             <property
                 name="tokens"
-                value="CTOR_CALL, METHOD_CALL, SUPER_CTOR_CALL"
+                value="AT, INC, DEC, UNARY_MINUS, UNARY_PLUS, DOT"
             />
         </module>
+        <module name="NoWhitespaceBefore">
+            <property name="allowLineBreaks" value="true" />
+        </module>
+        <module name="OperatorWrap" />
+        <module name="ParenPad" />
         <module name="SeparatorWrap">
             <property name="tokens" value="DOT"/>
             <property name="option" value="nl"/>
     </module>
 
 
-    </module>
+</module>
 
 <!-- EOF -->
index ccc7751..63af443 100644 (file)
@@ -11,7 +11,7 @@
   xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0
-  http://pmd.sourceforge.net/ruleset_2_0_0.xsd"
+  https://pmd.sourceforge.io/ruleset_2_0_0.xsd"
   name="Custom ruleset"
 >
 
         <exclude name="OnlyOneReturn" />
         <exclude name="ShortVariable" />
         <exclude name="UnnecessaryLocalBeforeReturn" />
+        <exclude name="UnnecessaryModifier" />
         <exclude name="UnnecessaryReturn" />
     </rule>
+    <rule ref="category/java/codestyle.xml/ClassNamingConventions" >
+        <properties>
+            <property name="utilityClassPattern" value="[A-Z][a-zA-Z0-9]*"/>
+        </properties>
+    </rule>
     <rule ref="category/java/codestyle.xml/ControlStatementBraces" >
         <properties>
             <property name="checkIfElseStmt" value="false"/>
             <property name="checkSingleIfStmt" value="false"/>
         </properties>
     </rule>
+    <rule ref="category/java/codestyle.xml/LongVariable" >
+        <properties>
+            <property name="minimum" value="25"/>
+        </properties>
+    </rule>
 
     <rule ref="category/java/design.xml" >
         <exclude name="AvoidThrowingNullPointerException" />
         <exclude name="AvoidUncheckedExceptionsInSignatures" />
         <exclude name="LawOfDemeter" />
         <exclude name="LoosePackageCoupling" />
+        <exclude name="SimplifyBooleanReturns" />
     </rule>
 
     <rule ref="category/java/documentation.xml" />
@@ -66,6 +78,7 @@
     <rule ref="category/java/multithreading.xml" />
 
     <rule ref="category/java/performance.xml" >
+        <exclude name="AvoidUsingShortType" />
         <exclude name="ConsecutiveAppendsShouldReuse" />
         <exclude name="RedundantFieldInitializer" />
     </rule>
diff --git a/pom.xml b/pom.xml
index 40617d3..f27b07e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-        <locale>en</locale>
-        <site.locales>${locale}</site.locales>
-        <javadoc.locale>${locale}</javadoc.locale>
-        <spotbugs.jvmArgs>-Duser.language=${locale}</spotbugs.jvmArgs>
-
-        <!-- Walk around: JDK 11 javadoc + Maven -->
-        <detectJavaApiLink>false</detectJavaApiLink>
+        <!-- DO NOT USE ${locale} with site-plugin -->
+        <site.locales>en</site.locales>
+        <javadoc.locale>en</javadoc.locale>
+        <spotbugs.jvmArgs>-Duser.language=en</spotbugs.jvmArgs>
 
         <surefire-plugin.version>3.0.0-M3</surefire-plugin.version>
         <jacoco-plugin.version>0.8.4</jacoco-plugin.version>
 
         <checkstyle-plugin.version>3.1.0</checkstyle-plugin.version>
-        <checkstyleruntime.version>8.21</checkstyleruntime.version>
-        <checkstyle.config.location>${project.basedir}/config/checkstyle/checkstyle.xml</checkstyle.config.location>
-        <checkstyle.suppressions.location>${project.basedir}/config/checkstyle/checkstyle-suppressions.xml</checkstyle.suppressions.location>
+        <checkstyleruntime.version>8.22</checkstyleruntime.version>
+        <checkstyle.config.location>config/checkstyle/checkstyle.xml</checkstyle.config.location>
+        <checkstyle.suppressions.location>config/checkstyle/checkstyle-suppressions.xml</checkstyle.suppressions.location>
         <checkstyle.enable.rss>false</checkstyle.enable.rss>
 
         <pmd-plugin.version>3.12.0</pmd-plugin.version>
 
-        <spotbugs-plugin.version>3.1.11</spotbugs-plugin.version>
+        <spotbugs-plugin.version>3.1.12</spotbugs-plugin.version>
         <spotbugs.effort>Max</spotbugs.effort>
         <spotbugs.threshold>Low</spotbugs.threshold>
         <!-- for Jenkins -->
                         <id>attach-sources</id>
                         <phase>verify</phase>
                         <goals>
-                          <goal>jar-no-fork</goal>
+                            <goal>jar-no-fork</goal>
                         </goals>
                     </execution>
                 </executions>
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <version>3.1.0</version>
                 <configuration>
+                    <locale>${javadoc.locale}</locale>
+                    <source>${maven.compiler.source}</source>
                     <author>false</author>
                     <notimestamp>true</notimestamp>
                     <quiet>true</quiet>
                     <show>protected</show>
                     <header>${project.name} ${project.version} API</header>
                     <version>true</version>
-                    <locale>${javadoc.locale}</locale>
                     <!-- for JDK11 javadoc -->
                     <additionalJOption>-J-Duser.language=${javadoc.locale}</additionalJOption>
                 </configuration>
                 <version>${pmd-plugin.version}</version>
                 <configuration>
                     <rulesets>
-                        <ruleset>${project.basedir}/config/pmd/pmdrules.xml</ruleset>
+                        <ruleset>config/pmd/pmdrules.xml</ruleset>
                     </rulesets>
                 </configuration>
                 <reportSets>
index bdb53dd..63bcf7c 100644 (file)
@@ -18,6 +18,7 @@ import java.text.MessageFormat;
 
 /**
  * バイナリデータの出力を行う汎用エクスポーター。
+ *
  * <p>基本的にリトルエンディアン形式で出力される。
  */
 public class BinaryExporter implements Closeable, Flushable{
@@ -69,8 +70,8 @@ public class BinaryExporter implements Closeable, Flushable{
 
     private final byte[] barray;
 
-    private final TextExporter texporter_w31j;
-    private final TextExporter texporter_u16le;
+    private final TextExporter texporterW31j;
+    private final TextExporter texporterU16le;
     private final ByteArrayOutputStream xos;
 
 
@@ -87,8 +88,8 @@ public class BinaryExporter implements Closeable, Flushable{
 
         this.barray = new byte[BUFSZ_PRIM];
 
-        this.texporter_w31j  = new TextExporter(CS_WIN31J);
-        this.texporter_u16le = new TextExporter(CS_UTF16LE);
+        this.texporterW31j  = new TextExporter(CS_WIN31J);
+        this.texporterU16le = new TextExporter(CS_UTF16LE);
         this.xos = new ByteArrayOutputStream();
 
         return;
@@ -257,12 +258,19 @@ public class BinaryExporter implements Closeable, Flushable{
 
     /**
      * 詰め物パディングを出力する。
+     *
      * @param filler byte型配列によるパディングデータの並び。
-     * <p>指定パディング長より長い部分は出力されない。
-     * 指定パディング長に満たない場合は最後の要素が繰り返し出力される。
-     * <p>配列長が0の場合は何も出力されない。
+     *
+     *     <p>指定パディング長より長い部分は出力されない。
+     *     指定パディング長に満たない場合は
+     *     最後の要素が繰り返し出力される。</p>
+     *
+     *     <p>配列長が0の場合は何も出力されない。</p>
+     *
      * @param fillerLength パディング長。
-     * <p>パディング長が0以下の場合は何も出力されない。
+     *
+     *     <p>パディング長が0以下の場合は何も出力されない。</p>
+     *
      * @return this
      * @throws IOException 出力エラー
      */
@@ -294,8 +302,8 @@ public class BinaryExporter implements Closeable, Flushable{
      * @return this
      * @throws IOException 出力エラー
      * @throws IllegalTextExportException テキスト出力エラー。
-     * 出力が固定長を超えようとした、
-     * もしくは不正なエンコードが行われたかのいずれか。
+     *     出力が固定長を超えようとした、
+     *     もしくは不正なエンコードが行われたかのいずれか。
      */
     public BinaryExporter dumpFixedW31j(CharSequence text,
                                           int fixedLength,
@@ -306,7 +314,7 @@ public class BinaryExporter implements Closeable, Flushable{
         int encodedSize;
         try{
             encodedSize =
-                    this.texporter_w31j.encodeToByteStream(text, this.xos);
+                    this.texporterW31j.encodeToByteStream(text, this.xos);
         }catch(CharacterCodingException e){
             throw new IllegalTextExportException(ERRMSG_ILLENC, e);
         }
@@ -338,8 +346,8 @@ public class BinaryExporter implements Closeable, Flushable{
      * @return エンコードバイト列長
      * @throws IOException 出力エラー
      * @throws IllegalTextExportException テキスト出力エラー。
-     * 出力が固定長を超えようとした、
-     * もしくは不正なエンコードが行われたかのいずれか。
+     *     出力が固定長を超えようとした、
+     *     もしくは不正なエンコードが行われたかのいずれか。
      */
     public int dumpHollerithUtf16LE(CharSequence text)
             throws IOException, IllegalTextExportException{
@@ -348,7 +356,7 @@ public class BinaryExporter implements Closeable, Flushable{
         int encodedSize;
         try{
             encodedSize =
-                    this.texporter_u16le.encodeToByteStream(text, this.xos);
+                    this.texporterU16le.encodeToByteStream(text, this.xos);
         }catch(CharacterCodingException e){
             assert false;  // これはない
             throw new IllegalTextExportException(ERRMSG_ILLENC, e);
index 5c99d1e..7903783 100644 (file)
@@ -11,11 +11,11 @@ import java.nio.charset.CharacterCodingException;
 
 /**
  * バイナリファイルへの不正なテキスト情報の出力が検出された場合の例外。
- * <p>
- * {@link java.nio.charset.CharacterCodingException}に由来する異常系を
+ *
+ * <p>{@link java.nio.charset.CharacterCodingException}に由来する異常系を
  * {@link java.io.IOException}から分離するために設計された。
- * <p>
- * 異常系の発生した理由としては
+ *
+ * <p>異常系の発生した理由としては
  * <ul>
  * <li>所定のフォーマットに対し文字列が長すぎる。
  * <li>文字エンコーディングできない文字が含まれている
index bba9017..3495f9d 100644 (file)
@@ -28,13 +28,15 @@ public class TextExporter {
     /** デフォルトの出力バッファサイズ(単位:byte)。 */
     public static final int DEFBUFSZ_BYTE = 128;
 
+    private static final String DUMMYTXT = "";
+
 
     private final CharsetEncoder encoder;
     private CharBuffer cbuf = CharBuffer.allocate(DEFBUFSZ_CHAR);
     private byte[] barray = new byte[DEFBUFSZ_BYTE];
     private ByteBuffer bbuf = ByteBuffer.wrap(this.barray);
 
-    private CharSequence textData;
+    private CharSequence textData = DUMMYTXT;
     private int textLength;
     private int inPos;
 
@@ -126,7 +128,7 @@ public class TextExporter {
         try{
             total = dumpTextImpl(os);
         }finally{
-            this.textData = null;
+            this.textData = DUMMYTXT;
         }
 
         return total;
@@ -193,6 +195,7 @@ public class TextExporter {
 
     /**
      * 入力バッファに文字を埋める。
+     *
      * <p>入力バッファが一杯になるか
      * 入力文字列がなくなるまでバッファが埋められる。
      */
@@ -261,7 +264,9 @@ public class TextExporter {
 
     /**
      * 与えられた文字列のエンコード結果を格納先バイトストリームへ格納する。
+     *
      * <p>エンコード結果は格納先ストリームに追記される。
+     *
      * @param text 文字列
      * @param bos 格納先ストリーム
      * @return エンコードしたバイト数。
index 3ce9f21..a17b13f 100644 (file)
@@ -11,35 +11,42 @@ import java.io.IOException;
 
 /**
  * バイナリパーサの共通インタフェース。
+ *
  * <p>バイト列、各種プリミティブ型値およびエンコードされた文字列を読み込む。
+ *
  * <p>long,double、およびビッグエンディアン形式のデータは未サポート。
  */
 public interface BinParser {
 
     /**
      * 入力ソースの読み込み位置を返す。
+     *
      * @return 入力ソースの読み込み位置。単位はbyte。
      */
-    long getPosition();
+    public abstract long getPosition();
 
     /**
      * 入力ソースにまだデータが残っているか判定する。
+     *
      * @return まだ読み込んでいないデータが残っていればtrue
      * @throws IOException IOエラー
      */
-    boolean hasMore() throws IOException;
+    public abstract boolean hasMore() throws IOException;
 
     /**
      * 入力ソースを読み飛ばす。
+     *
      * @param skipLength 読み飛ばすバイト数。
      * @throws IOException IOエラー
      * @throws MmdEofException 読み飛ばす途中でストリーム終端に達した。
      * @see java.io.InputStream#skip(long)
      */
-    void skip(long skipLength) throws IOException, MmdEofException;
+    public abstract void skip(long skipLength)
+            throws IOException, MmdEofException;
 
     /**
      * byte配列を読み込む。
+     *
      * @param dst 格納先配列
      * @param off 読み込み開始オフセット
      * @param length 読み込みバイト数
@@ -49,7 +56,7 @@ public interface BinParser {
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      * @see java.io.InputStream#read(byte[], int, int)
      */
-    void parseByteArray(byte[] dst, int off, int length)
+    public abstract void parseByteArray(byte[] dst, int off, int length)
             throws NullPointerException,
                    IndexOutOfBoundsException,
                    IOException,
@@ -57,78 +64,96 @@ public interface BinParser {
 
     /**
      * byte配列を読み込む。
+     *
      * <p>配列要素全ての読み込みが試みられる。
+     *
      * @param dst 格納先配列
      * @throws NullPointerException 配列がnull
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      * @see java.io.InputStream#read(byte[])
      */
-    void parseByteArray(byte[] dst)
+    public abstract void parseByteArray(byte[] dst)
             throws NullPointerException, IOException, MmdEofException;
 
     /**
      * byte値を読み込む。
+     *
      * @return 読み込んだbyte値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      */
-    byte parseByte() throws IOException, MmdEofException;
+    public abstract byte parseByte() throws IOException, MmdEofException;
 
     /**
      * 符号無し値としてbyte値を読み込み、int型に変換して返す。
+     *
      * <p>符号は拡張されない。(0xffは0x000000ffとなる)
+     *
      * @return 読み込まれた値のint値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      */
-    int parseUByteAsInt() throws IOException, MmdEofException;
+    public abstract int parseUByteAsInt() throws IOException, MmdEofException;
 
     /**
      * byte値を読み込み、boolean型に変換して返す。
+     *
      * <p>0x00は偽、それ以外は真と解釈される。
+     *
      * @return 読み込まれた値のboolean値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      */
-    boolean parseBoolean() throws IOException, MmdEofException;
+    public abstract boolean parseBoolean()
+            throws IOException, MmdEofException;
 
     /**
      * short値を読み込む。
+     *
      * <p>short値はリトルエンディアンで格納されていると仮定される。
+     *
      * @return 読み込んだshort値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      */
-    short parseLeShort() throws IOException, MmdEofException;
+    public abstract short parseLeShort() throws IOException, MmdEofException;
 
     /**
      * 符号無し値としてshort値を読み込み、int型に変換して返す。
+     *
      * <p>符号は拡張されない。(0xffffは0x0000ffffとなる)
+     *
      * <p>short値はリトルエンディアンで格納されていると仮定される。
+     *
      * @return 読み込まれた値のint値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      */
-    int parseLeUShortAsInt() throws IOException, MmdEofException;
+    public abstract int parseLeUShortAsInt()
+            throws IOException, MmdEofException;
 
     /**
      * int値を読み込む。
+     *
      * <p>int値はリトルエンディアンで格納されていると仮定される。
+     *
      * @return 読み込んだint値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      */
-    int parseLeInt() throws IOException, MmdEofException;
+    public abstract int parseLeInt() throws IOException, MmdEofException;
 
     /**
      * float値を読み込む。
+     *
      * <p>float値はリトルエンディアンで格納されていると仮定される。
+     *
      * @return 読み込んだfloat値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
      */
-    float parseLeFloat() throws IOException, MmdEofException;
+    public abstract float parseLeFloat() throws IOException, MmdEofException;
 
     /**
      * 固定バイト長の文字列を読み込む。
@@ -139,7 +164,7 @@ public interface BinParser {
      * @throws MmdEofException 固定長バイト列を読む前に末端に達した。
      * @throws MmdFormatException 文字エンコーディングに関するエラー
      */
-    String parseString(TextDecoder decoder, int byteLen)
+    public abstract String parseString(TextDecoder decoder, int byteLen)
             throws IOException, MmdEofException, MmdFormatException;
 
 }
index ceedad5..dc7ae00 100644 (file)
@@ -45,7 +45,7 @@ public class CommonParser implements BinParser{
     private final PushbackInputStream is;
 
     private final byte[] readBuffer;
-//  private final ByteBuffer beBuf;
+    // private final ByteBuffer beBuf;
     private final ByteBuffer leBuf;
 
     private long position = 0L;
@@ -64,10 +64,10 @@ public class CommonParser implements BinParser{
 
         this.readBuffer = new byte[BYTES_PRIM];
 
-//      this.beBuf = ByteBuffer.wrap(this.readBuffer);
+        // this.beBuf = ByteBuffer.wrap(this.readBuffer);
         this.leBuf = ByteBuffer.wrap(this.readBuffer);
 
-//      this.beBuf.order(ByteOrder.BIG_ENDIAN);
+        // this.beBuf.order(ByteOrder.BIG_ENDIAN);
         this.leBuf.order(ByteOrder.LITTLE_ENDIAN);
 
         return;
index 9843357..e144be1 100644 (file)
@@ -9,37 +9,47 @@ package jp.sfjp.mikutoga.bin.parser;
 
 /**
  * バイナリファイル中ループ構造の通知用ハンドラ。
+ *
  * <p>ステージ指定により、多重ネストループをもサポートする。
  */
 public interface LoopHandler {
 
     /**
      * ループ構造開始の通知を受け取る。
+     *
      * <p>0回ループの場合も含め一度呼ばれる。
+     *
      * @param stage ループ種別
      * @param loops ループ予定回数。未知の場合は負の値。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void loopStart(ParseStage stage, int loops) throws MmdFormatException;
+    public abstract void loopStart(ParseStage stage, int loops)
+            throws MmdFormatException;
 
     /**
      * ループ構造の1イテレーション終了の通知を受け取る。
+     *
      * <p>1度しか回らないループでも呼ばれる。
      * 0回ループでは決して呼ばれない。
+     *
      * @param stage ループ種別
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void loopNext(ParseStage stage) throws MmdFormatException;
+    public abstract void loopNext(ParseStage stage)
+            throws MmdFormatException;
 
     /**
      * ループ構造終了の通知を受け取る。
+     *
      * <p>0回ループの場合も含め一度呼ばれる。
+     *
      * @param stage ループ種別
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void loopEnd(ParseStage stage) throws MmdFormatException;
+    public abstract void loopEnd(ParseStage stage)
+            throws MmdFormatException;
 
 }
index a0eb2de..8210c14 100644 (file)
@@ -33,7 +33,7 @@ public class MmdEofException extends MmdFormatException {
     /**
      * コンストラクタ。
      * @param position 入力ソース先頭からのエラー位置。(バイト単位)
-     * 負の値を与えると、エラー位置は無効と解釈される。
+     *     負の値を与えると、エラー位置は無効と解釈される。
      */
     public MmdEofException(long position){
         this(null, position);
@@ -44,7 +44,7 @@ public class MmdEofException extends MmdFormatException {
      * コンストラクタ。
      * @param message エラーメッセージ
      * @param position 入力ソース先頭からのエラー位置。(バイト単位)
-     * 負の値を与えると、エラー位置は無効と解釈される。
+     *     負の値を与えると、エラー位置は無効と解釈される。
      */
     public MmdEofException(String message, long position){
         super(message, position);
index 95178aa..c048dea 100644 (file)
@@ -9,6 +9,7 @@ package jp.sfjp.mikutoga.bin.parser;
 
 /**
  * MMD関連ファイルのパース異常系。
+ *
  * <p>必要に応じて、パースに失敗した位置を保持する。
  */
 @SuppressWarnings("serial")
@@ -36,7 +37,7 @@ public class MmdFormatException extends Exception {
     /**
      * コンストラクタ。
      * @param position 入力ソース先頭から数えたエラー位置。(バイト単位)
-     * 負の値を与えると、エラー位置は無効と解釈される。
+     *     負の値を与えると、エラー位置は無効と解釈される。
      */
     public MmdFormatException(long position){
         this(null, position);
@@ -47,7 +48,7 @@ public class MmdFormatException extends Exception {
      * コンストラクタ。
      * @param message エラーメッセージ
      * @param position 入力ソース先頭から数えたエラー位置。(バイト単位)
-     * 負の値を与えると、エラー位置は無効と解釈される。
+     *     負の値を与えると、エラー位置は無効と解釈される。
      */
     public MmdFormatException(String message, long position){
         super(message);
@@ -83,7 +84,7 @@ public class MmdFormatException extends Exception {
     /**
      * エラー位置を取得する。
      * @return 入力ソース先頭からのバイト数で表されるエラー位置。
-     * 負なら無効なエラー位置。
+     *     負なら無効なエラー位置。
      */
     public long getPosition(){
         return this.position;
index 638422a..ed61529 100644 (file)
@@ -11,7 +11,9 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * パース処理の進行ステージ種別を表す。
+ *
  * <p>ループ構造の識別に用いられる。
+ *
  * <p>enum型と異なり、実行時での要素の追加が可能。
  */
 public class ParseStage {
index 578f768..ae7e0c9 100644 (file)
@@ -11,6 +11,7 @@ import java.io.IOException;
 
 /**
  * 委譲パーサ。
+ *
  * <p>別のパーサにパース処理を委譲する。
  */
 public class ProxyParser implements BinParser{
index 20095fb..7410bab 100644 (file)
@@ -17,10 +17,13 @@ import java.nio.charset.CodingErrorAction;
 
 /**
  * 文字デコーダー。
+ *
  * <p>あらかじめバイト長が既知であるバイトバッファを読み取り、
  * 文字列へのデコード結果を返す。
+ *
  * <p>デコード対象のバイト列が全てメモリ上に展開される必要があるので、
  * 巨大なテキストのデコードには不適当。
+ *
  * <p>入力バイト値0x00以降をデコード処理の対象から外す
  * 「ゼロチョップモード」を備える。
  * デフォルトではゼロチョップモードはオフ。
@@ -53,7 +56,7 @@ public class TextDecoder {
 
         this.decoder = decoder;
         this.decoder.reset();
-        this.decoder.onMalformedInput     (CodingErrorAction.REPORT);
+        this.decoder.onMalformedInput(     CodingErrorAction.REPORT);
         this.decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
 
         return;
@@ -61,7 +64,9 @@ public class TextDecoder {
 
     /**
      * 指定されたバイト長のデコードに必要な出力バッファを用意する。
+     *
      * <p>既存バッファで足りなければ新たに確保し直す。
+     *
      * @param byteLength 入力バイト長
      * @return 出力バッファ長。(キャラクタ単位)
      */
index 5166afd..485aa57 100644 (file)
@@ -7,8 +7,8 @@
 
 /**
  * MMD用各種バイナリファイルパーサ共通ライブラリ。
- * <p>
- * PMDモデルファイルやVMDモーションファイルなどの個別のパーサは
+ *
+ * <p>PMDモデルファイルやVMDモーションファイルなどの個別のパーサは
  * 別パッケージにより提供される。
  */
 
index bbfba54..3139b11 100644 (file)
@@ -31,16 +31,31 @@ public final class EmptyProxyFactory {
 
     /**
      * 何もしないインタフェース実装のインスタンスを生成する。
+     *
      * <p>インタフェースの各メソッド戻り値はvoidでなければならない。
+     *
      * @param types インタフェース群
      * @return インタフェースを実装したインスタンス。
      */
     public static Object buildEmptyProxy(Class<?>... types){
-        ClassLoader loader = types[0].getClassLoader();
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        Object proxy = buildEmptyProxy(loader, types);
+        return proxy;
+    }
 
+    /**
+     * 何もしないインタフェース実装のインスタンスを生成する。
+     *
+     * <p>インタフェースの各メソッド戻り値はvoidでなければならない。
+     *
+     * @param loader class-loader
+     * @param types インタフェース群
+     * @return インタフェースを実装したインスタンス。
+     */
+    public static Object buildEmptyProxy(
+            ClassLoader loader, Class<?>... types){
         Object proxy =
                 Proxy.newProxyInstance(loader, types, NOTHING_INVOKER);
-
         return proxy;
     }
 
index 6b48658..930a858 100644 (file)
@@ -48,8 +48,7 @@ public class I18nText implements CharSequence {
     /**
      * キーはISO639、値は多言語テキスト。
      */
-    private final Map<String, String> nameMap =
-            new HashMap<String, String>();
+    private final Map<String, String> nameMap = new HashMap<>();
 
 
     /**
@@ -155,9 +154,12 @@ public class I18nText implements CharSequence {
 
     /**
      * プライマリ文字列を返す。
+     *
      * <p>見つからなければグローバル文字列を返す。
      * それでも見つからなければ長さ0の空文字列を返す。
+     *
      * <p>※決してnullは返さない。
+     *
      * @return 文字列
      */
     public String getText(){
@@ -178,11 +180,15 @@ public class I18nText implements CharSequence {
 
     /**
      * 実行環境のデフォルトロケールに応じた文字列を返す。
+     *
      * <p>見つからなければグローバル文字列、プライマリ文字列の順に返す。
      * それでも見つからなければ適当な言語コードの文字列を返す。
      * それでも見つからなければ長さ0の空文字列を返す。
+     *
      * <p>デフォルトロケールの確認はその都度行われる。
+     *
      * <p>※決してnullは返さない。
+     *
      * @return 文字列
      */
     public String getLocalizedText(){
@@ -231,7 +237,7 @@ public class I18nText implements CharSequence {
      */
     public List<String> lang639CodeList(){
         Set<String> set = this.nameMap.keySet();
-        List<String> result = new ArrayList<String>(set.size());
+        List<String> result = new ArrayList<>(set.size());
 
         for(String lang : set){
             if(lang.equals(CODE639_PRIMARY)) result.add(lang);
index 028fce6..343172f 100644 (file)
@@ -10,7 +10,9 @@ package jp.sfjp.mikutoga.math;
 /**
  * YXZオイラー角。
  * 三次元空間での方向及び姿勢を定義する。
+ *
  * <p>回転量はラジアンで表される。
+ *
  * <p>※XYZオイラー角ではない。
  */
 public strictfp class EulerYXZ {
@@ -22,6 +24,7 @@ public strictfp class EulerYXZ {
 
     /**
      * コンストラクタ。
+     *
      * <p>三軸とも回転量0の状態になる。
      */
     public EulerYXZ(){
@@ -31,6 +34,7 @@ public strictfp class EulerYXZ {
 
     /**
      * コンストラクタ。
+     *
      * @param xRot X軸回転量。(ラジアン)
      * @param yRot Y軸回転量。(ラジアン)
      * @param zRot Z軸回転量。(ラジアン)
@@ -45,6 +49,7 @@ public strictfp class EulerYXZ {
 
     /**
      * X軸回転量を返す。
+     *
      * @return X軸回転量を返す。(ラジアン)
      */
     public double getXRot(){
@@ -53,6 +58,7 @@ public strictfp class EulerYXZ {
 
     /**
      * Y軸回転量を返す。
+     *
      * @return Y軸回転量を返す。(ラジアン)
      */
     public double getYRot(){
@@ -61,6 +67,7 @@ public strictfp class EulerYXZ {
 
     /**
      * Z軸回転量を返す。
+     *
      * @return Z軸回転量を返す。(ラジアン)
      */
     public double getZRot(){
@@ -69,6 +76,7 @@ public strictfp class EulerYXZ {
 
     /**
      * X軸回転量を設定する。
+     *
      * @param xRotArg X軸回転量。(ラジアン)
      */
     public void setXRot(double xRotArg){
@@ -78,6 +86,7 @@ public strictfp class EulerYXZ {
 
     /**
      * Y軸回転量を設定する。
+     *
      * @param yRotArg Y軸回転量。(ラジアン)
      */
     public void setYRot(double yRotArg){
@@ -87,6 +96,7 @@ public strictfp class EulerYXZ {
 
     /**
      * Z軸回転量を設定する。
+     *
      * @param zRotArg Z軸回転量。(ラジアン)
      */
     public void setZRot(double zRotArg){
@@ -96,6 +106,7 @@ public strictfp class EulerYXZ {
 
     /**
      * 三軸の回転量を設定する。
+     *
      * @param xRotArg X軸回転量。(ラジアン)
      * @param yRotArg Y軸回転量。(ラジアン)
      * @param zRotArg Z軸回転量。(ラジアン)
@@ -109,6 +120,7 @@ public strictfp class EulerYXZ {
 
     /**
      * パラメータ情報の文字列化。
+     *
      * @param x x値
      * @param y y値
      * @param z z値
index 04c7bc7..dc05c20 100644 (file)
@@ -9,7 +9,9 @@ package jp.sfjp.mikutoga.math;
 
 /**
  * 二次元空間座標及び変量を表す。
+ *
  * <p>直交座標を二つの倍精度値で表す。
+ *
  * <p>主な用途はUVマッピングなど。
  */
 public strictfp class MkPos2D {
@@ -28,6 +30,7 @@ public strictfp class MkPos2D {
 
     /**
      * コンストラクタ。
+     *
      * @param xPosArg X座標
      * @param yPosArg Y座標
      */
@@ -40,6 +43,7 @@ public strictfp class MkPos2D {
 
     /**
      * X座標を設定する。
+     *
      * @param xPosArg X座標
      */
     public void setXpos(double xPosArg){
@@ -49,6 +53,7 @@ public strictfp class MkPos2D {
 
     /**
      * X座標を返す。
+     *
      * @return X座標
      */
     public double getXpos(){
@@ -57,6 +62,7 @@ public strictfp class MkPos2D {
 
     /**
      * Y座標を設定する。
+     *
      * @param yPosArg Y座標
      */
     public void setYpos(double yPosArg){
@@ -66,6 +72,7 @@ public strictfp class MkPos2D {
 
     /**
      * Y座標を返す。
+     *
      * @return Y座標
      */
     public double getYpos(){
@@ -74,6 +81,7 @@ public strictfp class MkPos2D {
 
     /**
      * 座標を設定する。
+     *
      * @param xPosArg X軸座標
      * @param yPosArg Y軸座標
      */
@@ -85,12 +93,13 @@ public strictfp class MkPos2D {
 
     /**
      * この点が原点(0,0)か否か判定する。
+     *
      * @return 原点ならtrue
      */
     public boolean isOriginPoint(){
-        if(this.xPos != 0.0) return false;
-        if(this.yPos != 0.0) return false;
-        return true;
+        boolean result =
+                this.xPos == 0.0 && this.yPos == 0.0;
+        return result;
     }
 
     /**
index 20616a0..9c80c3c 100644 (file)
@@ -9,7 +9,9 @@ package jp.sfjp.mikutoga.math;
 
 /**
  * 三次元位置情報。
+ *
  * <p>直交座標を三つの倍精度値で表す。
+ *
  * <p>具体的にはボーン位置やカメラターゲット位置など。
  */
 public strictfp class MkPos3D {
@@ -29,6 +31,7 @@ public strictfp class MkPos3D {
 
     /**
      * コンストラクタ。
+     *
      * @param xPosArg X軸座標
      * @param yPosArg Y軸座標
      * @param zPosArg Z軸座標
@@ -42,6 +45,7 @@ public strictfp class MkPos3D {
 
     /**
      * X軸座標を返す。
+     *
      * @return X軸座標
      */
     public double getXpos() {
@@ -50,6 +54,7 @@ public strictfp class MkPos3D {
 
     /**
      * Y軸座標を返す。
+     *
      * @return Y軸座標
      */
     public double getYpos() {
@@ -58,6 +63,7 @@ public strictfp class MkPos3D {
 
     /**
      * Z軸座標を返す。
+     *
      * @return Z軸座標
      */
     public double getZpos() {
@@ -66,6 +72,7 @@ public strictfp class MkPos3D {
 
     /**
      * X軸座標を設定する。
+     *
      * @param xPosArg X軸座標
      */
     public void setXpos(double xPosArg){
@@ -75,6 +82,7 @@ public strictfp class MkPos3D {
 
     /**
      * Y軸座標を設定する。
+     *
      * @param yPosArg Y軸座標
      */
     public void setYpos(double yPosArg){
@@ -84,6 +92,7 @@ public strictfp class MkPos3D {
 
     /**
      * Z軸座標を設定する。
+     *
      * @param zPosArg Z軸座標
      */
     public void setZpos(double zPosArg){
@@ -93,6 +102,7 @@ public strictfp class MkPos3D {
 
     /**
      * 座標を設定する。
+     *
      * @param xPosArg X軸座標
      * @param yPosArg Y軸座標
      * @param zPosArg Z軸座標
@@ -106,13 +116,13 @@ public strictfp class MkPos3D {
 
     /**
      * この点が原点(0,0,0)か否か判定する。
+     *
      * @return 原点ならtrue
      */
     public boolean isOriginPoint(){
-        if(this.xPos != 0.0) return false;
-        if(this.yPos != 0.0) return false;
-        if(this.zPos != 0.0) return false;
-        return true;
+        boolean result =
+                this.xPos == 0.0 && this.yPos == 0.0 && this.zPos == 0.0;
+        return result;
     }
 
     /**
index d00b175..c815027 100644 (file)
@@ -9,6 +9,7 @@ package jp.sfjp.mikutoga.math;
 
 /**
  * クォータニオンによる回転表現。
+ *
  * <p>虚部q1,q2,q3と実部qwから構成される。
  */
 public strictfp class MkQuat {
@@ -37,6 +38,7 @@ public strictfp class MkQuat {
 
     /**
      * コンストラクタ。
+     *
      * <p>虚部が全て0.0、実部が1.0となる。
      */
     public MkQuat(){
@@ -46,6 +48,7 @@ public strictfp class MkQuat {
 
     /**
      * コンストラクタ。
+     *
      * @param q コピー元クォータニオン
      */
     public MkQuat(MkQuat q){
@@ -55,6 +58,7 @@ public strictfp class MkQuat {
 
     /**
      * コンストラクタ。
+     *
      * @param q1 虚部1
      * @param q2 虚部2
      * @param q3 虚部3
@@ -72,8 +76,11 @@ public strictfp class MkQuat {
 
     /**
      * クォータニオン積を求め格納する。
+     *
      * <p>クォータニオン積では交換則が成り立たない。
+     *
      * <p>引数は同一インスタンスを含んでもよい。
+     *
      * @param qA 積前項
      * @param qB 積後項
      * @param result 積の格納先
@@ -111,7 +118,9 @@ public strictfp class MkQuat {
 
     /**
      * 共役(共軛)クォータニオンを求め格納する。
+     *
      * <p>引数は同一インスタンスでもよい。
+     *
      * @param q クォータニオン
      * @param result 格納先
      */
@@ -125,7 +134,9 @@ public strictfp class MkQuat {
 
     /**
      * 単位クォータニオンを求め格納する。
+     *
      * <p>引数は同一インスタンスでもよい。
+     *
      * @param q クォータニオン
      * @param result 格納先
      */
@@ -147,9 +158,12 @@ public strictfp class MkQuat {
 
     /**
      * 逆元クォータニオンを求め格納する。
+     *
      * <p>対象クォータニオンの絶対値が小さい場合、
      * 無限大が虚部実部に入る可能性がある。
+     *
      * <p>引数は同一インスタンスでもよい。
+     *
      * @param q クォータニオン
      * @param result 格納先
      */
@@ -274,8 +288,11 @@ public strictfp class MkQuat {
 
     /**
      * 位置情報を読み込む。
+     *
      * <p>虚部q1,q2,q3にX,Y,Z軸の変量が入る。
+     *
      * <p>実部には0が入る。
+     *
      * @param xPos X位置
      * @param yPos Y位置
      * @param zPos Z位置
@@ -290,8 +307,11 @@ public strictfp class MkQuat {
 
     /**
      * 位置情報を読み込む。
+     *
      * <p>虚部q1,q2,q3にX,Y,Z軸の変量が入る。
+     *
      * <p>実部には0が入る。
+     *
      * @param pos 位置情報
      */
     public void setPos3D(MkPos3D pos){
@@ -301,8 +321,10 @@ public strictfp class MkQuat {
 
     /**
      * YXZオイラー角を読み込む。
+     *
      * <p>Y軸回転、X軸回転、Z軸回転の順に
      * 個別回転クォータニオンの積をとったものと等しい。
+     *
      * @param xRot X軸回転量(ラジアン)。第2軸
      * @param yRot Y軸回転量(ラジアン)。第1軸
      * @param zRot Z軸回転量(ラジアン)。第3軸
@@ -330,8 +352,10 @@ public strictfp class MkQuat {
 
     /**
      * YXZオイラー角を読み込む。
+     *
      * <p>Y軸回転、X軸回転、Z軸回転の順に
      * 個別回転クォータニオンの積をとったものと等しい。
+     *
      * @param rot YXZオイラー角
      */
     public void setEulerYXZ(EulerYXZ rot){
@@ -341,10 +365,12 @@ public strictfp class MkQuat {
 
     /**
      * クォータニオンをYXZオイラー角へと変換する。
+     *
      * <p>ジンバルロック時のYZ配分が指定可能。
+     *
      * @param result YXZオイラー角
      * @param oldY ジンバルロック時(オイラー角Xが直角etc.)
-     * に使われるY軸回転量
+     *     に使われるY軸回転量
      */
     public void toEulerYXZ(EulerYXZ result, double oldY){
         double qx = this.q1;
@@ -372,8 +398,8 @@ public strictfp class MkQuat {
         double m11 = 1.0 - 2.0 * (qx2 + qz2);
         double m12 = 2.0 * (qyz - qwx);
 
-//      double m20 = 2.0 * (qxz - qwy);
-//      double m21 = 2.0 * (qwx + qyz);
+        // double m20 = 2.0 * (qxz - qwy);
+        // double m21 = 2.0 * (qwx + qyz);
         double m22 = 1.0 - 2.0 * (qx2 + qy2);
 
         double resultX;
@@ -461,14 +487,14 @@ public strictfp class MkQuat {
         double rprrQ1;
         double rprrQ2;
         double rprrQ3;
-//      double rprrQW;
 
         rprrQ1 = rpQ2 * rrQ3 - rpQ3 * rrQ2 + rpQW * rrQ1 + rpQ1 * rrQW;
         rprrQ2 = rpQ3 * rrQ1 - rpQ1 * rrQ3 + rpQW * rrQ2 + rpQ2 * rrQW;
         rprrQ3 = rpQ1 * rrQ2 - rpQ2 * rrQ1 + rpQW * rrQ3 + rpQ3 * rrQW;
-//      rprrQW = rpQW * rrQW - rpQ1 * rrQ1 - rpQ2 * rrQ2 - rpQ3 * rrQ3;
 
-//      assert rprrQW == 0.0;
+        // double rprrQW;
+        // rprrQW = rpQW * rrQW - rpQ1 * rrQ1 - rpQ2 * rrQ2 - rpQ3 * rrQ3;
+        // assert rprrQW == 0.0;
 
         result.setXpos(rprrQ1);
         result.setYpos(rprrQ2);
index eba00b5..9c28d74 100644 (file)
@@ -7,7 +7,9 @@
 
 /**
  * MMDにおける数学的な各種概念。
+ *
  * <p>基本的には左手系直交座標のユークリッド三次元空間を基盤とする。
+ *
  * <p>javax.vecmathの代替品。
  */
 
index 8a4e6b8..a809ea4 100644 (file)
@@ -69,7 +69,7 @@ public enum BoneType {
      * コンストラクタ。
      * @param code 符号化int値
      */
-    private BoneType(int code){
+    BoneType(int code){
         this((byte)code);
         return;
     }
@@ -78,7 +78,7 @@ public enum BoneType {
      * コンストラクタ。
      * @param code 符号化byte値
      */
-    private BoneType(byte code){
+    BoneType(byte code){
         this.encoded = code;
         return;
     }
index cc2be38..168376a 100644 (file)
@@ -54,7 +54,7 @@ public enum MorphType {
      * コンストラクタ。
      * @param code 符号化int値
      */
-    private MorphType(int code){
+    MorphType(int code){
         this((byte)code);
         return;
     }
@@ -63,7 +63,7 @@ public enum MorphType {
      * コンストラクタ。
      * @param code 符号化byte値
      */
-    private MorphType(byte code){
+    MorphType(byte code){
         this.encoded = code;
         return;
     }
index 07f2b44..3693e30 100644 (file)
@@ -43,6 +43,7 @@ public final class PmdConst {
     /**
      * ボーン最大数。
      * (Id : 0 - 0xfffe)
+     *
      * <p>MMDがいくつまで受け入れるかはまた別の話だよ。
      */
     public static final int MAX_BONE = 65535;
index 3522ca3..16ee464 100644 (file)
@@ -48,7 +48,7 @@ public enum RigidBehaviorType {
      * コンストラクタ。
      * @param code 符号化int値
      */
-    private RigidBehaviorType(int code){
+    RigidBehaviorType(int code){
         this((byte)code);
         return;
     }
@@ -57,7 +57,7 @@ public enum RigidBehaviorType {
      * コンストラクタ。
      * @param code 符号化byte値
      */
-    private RigidBehaviorType(byte code){
+    RigidBehaviorType(byte code){
         this.encoded = code;
         return;
     }
index f1bceb3..80815da 100644 (file)
@@ -48,7 +48,7 @@ public enum RigidShapeType {
      * コンストラクタ。
      * @param code 符号化int値
      */
-    private RigidShapeType(int code){
+    RigidShapeType(int code){
         this((byte)code);
         return;
     }
@@ -57,7 +57,7 @@ public enum RigidShapeType {
      * コンストラクタ。
      * @param code 符号化byte値
      */
-    private RigidShapeType(byte code){
+    RigidShapeType(byte code){
         this.encoded = code;
         return;
     }
index 9fe2e35..212375e 100644 (file)
@@ -11,7 +11,9 @@ import java.util.regex.Pattern;
 
 /**
  * シェーディング情報の各種ユーティリティ。
+ *
  * <p>※ スフィアマップファイルの中身はBMP(DIB)形式。
+ *
  * <p><a href="http://en.wikipedia.org/wiki/BMP_file_format">
  * BMP file format </a>
  */
@@ -37,8 +39,10 @@ public final class ShadingUtil {
 
     /**
      * スフィアマップファイル名か否か判定する。
+     *
      * <p>拡張子が「.sph」(乗算)もしくは「.spa」(加算)なら
      * スフィアマップファイル名と判定する。
+     *
      * @param fname ファイル名
      * @return スフィアマップファイルならtrue
      */
@@ -51,14 +55,16 @@ public final class ShadingUtil {
     /**
      * シェーディング用ファイル情報文字列から
      * テクスチャファイル名とスフィアマップファイル名を分離する。
+     *
      * <p>2つのファイル名は単一の「*」で区切られ、
      * 前部がテクスチャファイル名、後部がスフィアマップファイル名となる。
      * 「*」がなく末尾が「.sph」か「.spa」なら
      * スフィアマップファイル名のみ、
      * 末尾がどちらでもなければテクスチャファイル名のみとなる。
+     *
      * @param shadingFile シェーディング用ファイル情報
      * @return [0]:テクスチャファイル名 [1]:スフィアマップファイル名。
-     * 該当ファイル名が無い場合は空文字列。
+     *     該当ファイル名が無い場合は空文字列。
      */
     public static String[] splitShadingFileInfo(String shadingFile) {
         String[] result;
index 4210a9e..bb85e7c 100644 (file)
@@ -16,39 +16,39 @@ public interface PmdBasicHandler {
 
     /**
      * PMDファイルのパース処理開始の通知を受け取る。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdParseStart()
+    public abstract void pmdParseStart()
             throws MmdFormatException;
 
     /**
      * PMDファイルのパース処理終了の通知を受け取る。
-     * @param hasMoreData 入力ソースに
-     * まだ読み込まれていないデータがあればtrue
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @param hasMoreData
+     *     入力ソースにまだ読み込まれていないデータがあればtrue
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdParseEnd(boolean hasMoreData)
+    public abstract void pmdParseEnd(boolean hasMoreData)
             throws MmdFormatException;
 
     /**
      * PMDファイルのヘッダ情報の通知を受け取る。
      * @param header ヘッダ情報バイト列。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdHeaderInfo(byte[] header)
+    public abstract void pmdHeaderInfo(byte[] header)
             throws MmdFormatException;
 
     /**
      * PMDファイルのモデル基本情報の通知を受け取る。
      * @param modelName モデル名
      * @param description モデルの説明文。改行CRLFは"\n"に変換される。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdModelInfo(String modelName, String description)
+    public abstract void pmdModelInfo(String modelName, String description)
             throws MmdFormatException;
 
 }
index 527bb54..2ae5048 100644 (file)
@@ -18,23 +18,25 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 public interface PmdBoneHandler extends LoopHandler {
 
     /** ボーン定義抽出ループ。 */
-    ParseStage BONE_LIST = new ParseStage();
+    public static final ParseStage BONE_LIST = new ParseStage();
 
     /** IKリスト抽出ループ。 */
-    ParseStage IK_LIST = new ParseStage();
+    public static final ParseStage IK_LIST = new ParseStage();
 
     /** IKチェーンリスト抽出ループ。 */
-    ParseStage IKCHAIN_LIST = new ParseStage();
+    public static final ParseStage IKCHAIN_LIST = new ParseStage();
 
     /** ボーングループ名抽出ループ。 */
-    ParseStage BONEGROUP_LIST = new ParseStage();
+    public static final ParseStage BONEGROUP_LIST = new ParseStage();
 
     /** ボーングループ内訳抽出ループ。 */
-    ParseStage GROUPEDBONE_LIST = new ParseStage();
+    public static final ParseStage GROUPEDBONE_LIST = new ParseStage();
 
     /**
      * ボーン定義情報の通知を受け取る。
+     *
      * <p>{@link #BONE_LIST}ループの構成要素。
+     *
      * @param boneName ボーン名
      * @param boneKind ボーン種別。
      * <ul>
@@ -49,81 +51,96 @@ public interface PmdBoneHandler extends LoopHandler {
      * <li>8:捩り
      * <li>9:回転連動
      * </ul>
-     * ※8,9はMMD4.0から?
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     ※8,9はMMD4.0から?
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdBoneInfo(String boneName, byte boneKind)
+    public abstract void pmdBoneInfo(String boneName, byte boneKind)
             throws MmdFormatException;
 
     /**
      * ボーン間接続情報の通知を受け取る。
+     *
      * <p>{@link #BONE_LIST}ループの構成要素。
+     *
      * @param parentId 親(前)ボーンID。無い場合は0xffff。
      * @param tailId 子(次)ボーンID。末端の場合は0。
-     * 捩りボーンの場合は軸方向のボーンID、
-     * 回転連動ボーンの場合は影響元ボーンID
+     *     捩りボーンの場合は軸方向のボーンID、
+     *     回転連動ボーンの場合は影響元ボーンID
      * @param ikId 影響IKボーンID。未指定の場合は0。
-     * ※回転連動では影響度(0-100)、負や100以上もOK!
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     ※回転連動では影響度(0-100)、負や100以上もOK!
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdBoneLink(int parentId, int tailId, int ikId)
+    public abstract void pmdBoneLink(int parentId, int tailId, int ikId)
             throws MmdFormatException;
 
     /**
      * ボーン位置情報の通知を受け取る。
+     *
      * <p>{@link #BONE_LIST}ループの構成要素。
+     *
      * @param xPos X座標
      * @param yPos Y座標
      * @param zPos Z座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdBonePosition(float xPos, float yPos, float zPos)
+    public abstract void pmdBonePosition(float xPos, float yPos, float zPos)
             throws MmdFormatException;
 
     /**
      * IKボーン情報の通知を受け取る。
+     *
      * <p>{@link #IK_LIST}ループの構成要素。
+     *
      * @param boneId IKボーンID
      * @param targetId IKボーンが最初に接続するIK接続先ボーンID
      * @param depth 再帰演算の深さ
      * @param weight 制限角度強度
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdIKInfo(int boneId, int targetId, int depth, float weight)
+    public abstract void pmdIKInfo(
+            int boneId, int targetId,
+            int depth, float weight)
             throws MmdFormatException;
 
     /**
      * IKチェイン要素の通知を受け取る。
+     *
      * <p>{@link #IK_LIST}ループの下位{@link #IKCHAIN_LIST}ループの構成要素。
+     *
      * @param childId IK影響下ボーンID
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdIKChainInfo(int childId)
+    public abstract void pmdIKChainInfo(int childId)
             throws MmdFormatException;
 
     /**
      * ボーングループ名定義の通知を受け取る。
+     *
      * <p>{@link #BONEGROUP_LIST}ループの構成要素。
+     *
      * @param groupName ボーングループ名。末尾のLF(0x0a)は削除される。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdBoneGroupInfo(String groupName) throws MmdFormatException;
+    public abstract void pmdBoneGroupInfo(String groupName)
+            throws MmdFormatException;
 
     /**
      * ボーングループ内訳の通知を受け取る。
+     *
      * <p>{@link #GROUPEDBONE_LIST}ループの構成要素。
+     *
      * @param boneId グループに所属するボーンのID
      * @param groupId ボーンが所属するボーングループIDに1を足した数
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdGroupedBoneInfo(int boneId, int groupId)
+    public abstract void pmdGroupedBoneInfo(int boneId, int groupId)
             throws MmdFormatException;
 
 }
index b11b38c..89a0a1f 100644 (file)
@@ -17,58 +17,68 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 public interface PmdEngHandler extends LoopHandler {
 
     /** ボーン英語名抽出ループ。 */
-    ParseStage ENGBONE_LIST = new ParseStage();
+    public static final ParseStage ENGBONE_LIST = new ParseStage();
 
     /** モーフ英語名抽出ループ。 */
-    ParseStage ENGMORPH_LIST = new ParseStage();
+    public static final ParseStage ENGMORPH_LIST = new ParseStage();
 
     /** ボーングループ英語名抽出ループ。 */
-    ParseStage ENGBONEGROUP_LIST = new ParseStage();
+    public static final ParseStage ENGBONEGROUP_LIST = new ParseStage();
 
     /**
      * PMD英語情報の有無の通知を受け取る。
      * @param hasEnglishInfo 英語情報が含まれればtrue
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdEngEnabled(boolean hasEnglishInfo) throws MmdFormatException;
+    public abstract void pmdEngEnabled(boolean hasEnglishInfo)
+            throws MmdFormatException;
 
     /**
      * PMD英語基本情報の通知を受け取る。
      * @param modelName モデル名
      * @param description モデルの説明文。改行CRLFは"\n"に変換される。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdEngModelInfo(String modelName, String description)
+    public abstract void pmdEngModelInfo(String modelName, String description)
             throws MmdFormatException;
 
     /**
      * 英語ボーン名の通知を受け取る。
+     *
      * <p>{@link #ENGBONE_LIST}ループの構成要素
+     *
      * @param boneName 英語ボーン名
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdEngBoneInfo(String boneName) throws MmdFormatException;
+    public abstract void pmdEngBoneInfo(String boneName)
+            throws MmdFormatException;
 
     /**
      * 英語モーフ名の通知を受け取る。
      * 特殊モーフ名「base」に対応する英語名は通知されない。
+     *
      * <p>{@link #ENGMORPH_LIST}ループの構成要素
+     *
      * @param morphName 英語モーフ名
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdEngMorphInfo(String morphName) throws MmdFormatException;
+    public abstract void pmdEngMorphInfo(String morphName)
+            throws MmdFormatException;
 
     /**
      * 英語ボーングループ名の通知を受け取る。
+     *
      * <p>{@link #ENGBONEGROUP_LIST}ループの構成要素
+     *
      * @param groupName 英語ボーングループ名
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdEngBoneGroupInfo(String groupName) throws MmdFormatException;
+    public abstract void pmdEngBoneGroupInfo(String groupName)
+            throws MmdFormatException;
 
 }
index 0fca5bf..55966a4 100644 (file)
@@ -17,113 +17,131 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 public interface PmdJointHandler extends LoopHandler {
 
     /** ジョイント情報抽出ループ。 */
-    ParseStage JOINT_LIST = new ParseStage();
+    public static final ParseStage JOINT_LIST = new ParseStage();
 
     /**
      * ジョイント名の通知を受け取る。
+     *
      * <p>{@link #JOINT_LIST}ループの構成要素。
+     *
      * @param jointName ジョイント名
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示。
      */
-    void pmdJointName(String jointName)
+    public abstract void pmdJointName(String jointName)
         throws MmdFormatException;
 
     /**
      * ジョイントが繋ぐ接続剛体IDの通知を受け取る。
+     *
      * <p>{@link #JOINT_LIST}ループの構成要素。
+     *
      * @param rigidIdA 接続剛体AのID
      * @param rigidIdB 接続剛体BのID
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示。
      */
-    void pmdJointLink(int rigidIdA, int rigidIdB)
+    public abstract void pmdJointLink(int rigidIdA, int rigidIdB)
         throws MmdFormatException;
 
     /**
      * ジョイント位置の通知を受け取る。
+     *
      * <p>{@link #JOINT_LIST}ループの構成要素。
+     *
      * @param posX X座標
      * @param posY Y座標
      * @param posZ Z座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示。
      */
-    void pmdJointPosition(float posX, float posY, float posZ)
+    public abstract void pmdJointPosition(float posX, float posY, float posZ)
         throws MmdFormatException;
 
     /**
      * ジョイント回転姿勢の通知を受け取る。
+     *
      * <p>{@link #JOINT_LIST}ループの構成要素。
+     *
      * @param radX X軸回転量(radian)
      * @param radY Y軸回転量(radian)
      * @param radZ Z軸回転量(radian)
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示。
      */
-    void pmdJointRotation(float radX, float radY, float radZ)
+    public abstract void pmdJointRotation(float radX, float radY, float radZ)
         throws MmdFormatException;
 
     /**
      * ジョイント移動制限の通知を受け取る。
+     *
      * <p>{@link #JOINT_LIST}ループの構成要素。
+     *
      * <p>※ [制限端 その1 &lt;= その2] 条件を満たす必要はあるか?
+     *
      * @param posXlim1 X座標制限端その1
      * @param posXlim2 X座標制限端その2
      * @param posYlim1 Y座標制限端その1
      * @param posYlim2 Y座標制限端その2
      * @param posZlim1 Z座標制限端その1
      * @param posZlim2 Z座標制限端その2
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示。
      */
-    void pmdPositionLimit(float posXlim1, float posXlim2,
+    public abstract void pmdPositionLimit(float posXlim1, float posXlim2,
                             float posYlim1, float posYlim2,
                             float posZlim1, float posZlim2 )
         throws MmdFormatException;
 
     /**
      * ジョイント回転制限の通知を受け取る。
+     *
      * <p>{@link #JOINT_LIST}ループの構成要素。
+     *
      * <p>※ [制限端 その1 &lt;= その2] 条件を満たす必要はあるか?
+     *
      * @param radXlim1 X軸制限端その1(radian)
      * @param radXlim2 X軸制限端その2(radian)
      * @param radYlim1 Y軸制限端その1(radian)
      * @param radYlim2 Y軸制限端その2(radian)
      * @param radZlim1 Z軸制限端その1(radian)
      * @param radZlim2 Z軸制限端その2(radian)
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示。
      */
-    void pmdRotationLimit(float radXlim1, float radXlim2,
+    public abstract void pmdRotationLimit(float radXlim1, float radXlim2,
                             float radYlim1, float radYlim2,
                             float radZlim1, float radZlim2 )
         throws MmdFormatException;
 
     /**
      * ジョイントのばね移動情報の通知を受け取る。
+     *
      * <p>{@link #JOINT_LIST}ループの構成要素。
+     *
      * @param elasticPosX X座標
      * @param elasticPosY Y座標
      * @param elasticPosZ Z座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示。
      */
-    void pmdElasticPosition(float elasticPosX,
+    public abstract void pmdElasticPosition(float elasticPosX,
                                float elasticPosY,
                                float elasticPosZ )
         throws MmdFormatException;
 
     /**
      * ジョイントのばね回転情報の通知を受け取る。
+     *
      * <p>{@link #JOINT_LIST}ループの構成要素。
+     *
      * @param elasticDegX X軸変量(degree)
      * @param elasticDegY Y軸変量(degree)
      * @param elasticDegZ Z軸変量(degree)
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示。
      */
-    void pmdElasticRotation(float elasticDegX,
+    public abstract void pmdElasticRotation(float elasticDegX,
                                float elasticDegY,
                                float elasticDegZ )
         throws MmdFormatException;
index 4a1c56f..69f7d4a 100644 (file)
@@ -18,78 +18,91 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 public interface PmdMaterialHandler extends LoopHandler {
 
     /** 材質抽出ループ。 */
-    ParseStage MATERIAL_LIST = new ParseStage();
+    public static final ParseStage MATERIAL_LIST = new ParseStage();
 
     /**
      * 材質の拡散光成分の通知を受け取る。
+     *
      * <p>{@link #MATERIAL_LIST}ループの構成要素。
+     *
      * @param red 0.0~1.0の範囲の赤成分
      * @param green 0.0~1.0の範囲の緑成分
      * @param blue 0.0~1.0の範囲の青成分
      * @param alpha 0.0(透明)~1.0(不透明)のアルファ値。
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdMaterialDiffuse(float red, float green, float blue,
-                               float alpha )
+    public abstract void pmdMaterialDiffuse(
+            float red, float green, float blue, float alpha)
             throws MmdFormatException;
 
     /**
      * 材質の反射光成分の通知を受け取る。
+     *
      * <p>{@link #MATERIAL_LIST}ループの構成要素。
+     *
      * @param red 0.0~1.0の範囲の赤成分
      * @param green 0.0~1.0の範囲の緑成分
      * @param blue 0.0~1.0の範囲の青成分
      * @param shininess 光沢強度(1~15ぐらい)
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdMaterialSpecular(float red, float green, float blue,
-                                float shininess)
+    public abstract void pmdMaterialSpecular(
+            float red, float green, float blue, float shininess)
             throws MmdFormatException;
 
     /**
      * 材質の環境色成分の通知を受け取る。
+     *
      * <p>{@link #MATERIAL_LIST}ループの構成要素。
+     *
      * @param red 0.0~1.0の範囲の赤成分
      * @param green 0.0~1.0の範囲の緑成分
      * @param blue 0.0~1.0の範囲の青成分
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdMaterialAmbient(float red, float green, float blue)
+    public abstract void pmdMaterialAmbient(
+            float red, float green, float blue)
             throws MmdFormatException;
 
     /**
      * シェーディング情報の通知を受け取る。
+     *
      * <p>{@link #MATERIAL_LIST}ループの構成要素。
+     *
      * @param toonIdx トゥーンファイル番号。
-     * 0ならtoon01.bmp。9ならtoon10.bmp。0xffならtoon0.bmp。
+     *     0ならtoon01.bmp。9ならtoon10.bmp。0xffならtoon0.bmp。
      * @param textureFile テクスチャファイル名。
-     * 無ければ空文字。
+     *     無ければ空文字。
      * @param sphereFile スフィアマップファイル名。
-     * 無ければ空文字。
+     *     無ければ空文字。
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdMaterialShading(int toonIdx,
+    public abstract void pmdMaterialShading(int toonIdx,
                                String textureFile, String sphereFile )
             throws MmdFormatException;
 
     /**
      * 材質情報の通知を受け取る。
+     *
      * <p>{@link #MATERIAL_LIST}ループの構成要素。
+     *
      * @param hasEdge エッジを表示するならtrue
      * @param vertexNum 面頂点数。
-     * 3の倍数のはず。
-     * 3で割ると、材質に属する面の数を表す。
-     * <p>通算した面数を面情報通知順と突き合わせることにより、
-     * 材質に属する面の集合を得ることが可能。
+     *     3の倍数のはず。
+     *     3で割ると、材質に属する面の数を表す。
+     *
+     *     <p>通算した面数を面情報通知順と突き合わせることにより、
+     *     材質に属する面の集合を得ることが可能。</p>
+     *
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      * @see PmdShapeHandler#pmdSurfaceTriangle(int, int, int)
      */
-    void pmdMaterialInfo(boolean hasEdge, int vertexNum)
+    public abstract void pmdMaterialInfo(boolean hasEdge, int vertexNum)
             throws MmdFormatException;
 
 }
index 8e17bd7..969f458 100644 (file)
@@ -17,17 +17,19 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 public interface PmdMorphHandler extends LoopHandler {
 
     /** モーフ抽出ループ。 */
-    ParseStage MORPH_LIST = new ParseStage();
+    public static final ParseStage MORPH_LIST = new ParseStage();
 
     /** モーフ頂点抽出ループ。 */
-    ParseStage MORPHVERTEX_LIST = new ParseStage();
+    public static final ParseStage MORPHVERTEX_LIST = new ParseStage();
 
     /** モーフ出現順抽出ループ。 */
-    ParseStage MORPHORDER_LIST = new ParseStage();
+    public static final ParseStage MORPHORDER_LIST = new ParseStage();
 
     /**
      * モーフ情報の通知を受け取る。
+     *
      * <p>{@link #MORPH_LIST}ループの構成要素
+     *
      * @param morphName モーフ名
      * @param morphType モーフ種別。
      * <ul>
@@ -37,34 +39,40 @@ public interface PmdMorphHandler extends LoopHandler {
      * <li>3:リップ
      * <li>4:その他
      * </ul>
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdMorphInfo(String morphName, byte morphType)
+    public abstract void pmdMorphInfo(String morphName, byte morphType)
             throws MmdFormatException;
 
     /**
      * モーフ形状の通知を受け取る。
+     *
      * <p>{@link #MORPH_LIST}ループの下位{@link #MORPHVERTEX_LIST}の構成要素。
+     *
      * <p>※ base型頂点IDの出現順がモーフ頂点IDとなる。
+     *
      * @param serialId base型の場合は頂点ID、それ以外はモーフ頂点ID
      * @param xPos base型の場合はX座標、それ以外はX軸変位
      * @param yPos base型の場合はY座標、それ以外はY軸変位
      * @param zPos base型の場合はZ座標、それ以外はZ軸変位
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdMorphVertexInfo(int serialId,
+    public abstract void pmdMorphVertexInfo(int serialId,
                                float xPos, float yPos, float zPos)
             throws MmdFormatException;
 
     /**
      * 各モーフ種別内のGUI表示順の通知を受け取る。
+     *
      * <p>{@link #MORPHORDER_LIST}ループの構成要素
+     *
      * @param morphId モーフ通し番号。同一モーフ種別内の大小関係のみ意味がある。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdMorphOrderInfo(int morphId) throws MmdFormatException;
+    public abstract void pmdMorphOrderInfo(int morphId)
+            throws MmdFormatException;
 
 }
index fb499b3..cbf6fd7 100644 (file)
@@ -11,6 +11,7 @@ import java.io.InputStream;
 
 /**
  * PMDモデルファイルのパーサ最新版。
+ *
  * <p>将来のリリースにおいて、
  * 常に最新のPMDモデルファイルフォーマットに対応したパーサの
  * 別名であることが保証される。つもり。
index ca41f78..6896871 100644 (file)
@@ -78,7 +78,9 @@ public class PmdParserBase extends CommonParser {
 
     /**
      * 文字列の最後がLF(0x0a)の場合削除する。
+     *
      * <p>ボーングループ名対策。
+     *
      * @param name 文字列
      * @return 末尾LFが削除された文字列
      */
@@ -185,11 +187,14 @@ public class PmdParserBase extends CommonParser {
 
     /**
      * 指定されたバイト長に収まるゼロ終端(0x00)文字列を読み込む。
+     *
      * <p>入力バイト列はwindows-31jエンコーディングとして解釈される。
+     *
      * <p>ゼロ終端以降のデータは無視されるが、
      * IO入力は指定バイト数だけ読み進められる。
      * ゼロ終端が見つからないまま指定バイト数が読み込み終わった場合、
      * そこまでのデータから文字列を構成する。
+     *
      * @param byteLen 読み込みバイト数
      * @return デコードされた文字列
      * @throws IOException IOエラー
index 680c83f..568dbe9 100644 (file)
@@ -14,6 +14,7 @@ import jp.sfjp.mikutoga.pmd.PmdConst;
 
 /**
  * PMDモデルファイルのパーサ拡張その1。
+ *
  * <p>※ 英名対応
  */
 public class PmdParserExt1 extends PmdParserBase {
index 3e9dd3c..5e3d3af 100644 (file)
@@ -14,6 +14,7 @@ import jp.sfjp.mikutoga.pmd.PmdConst;
 
 /**
  * PMDモデルファイルのパーサ拡張その2。
+ *
  * <p>※ 独自トゥーンテクスチャファイル名対応
  */
 public class PmdParserExt2 extends PmdParserExt1 {
index eb4f6f4..e984e32 100644 (file)
@@ -14,6 +14,7 @@ import jp.sfjp.mikutoga.pmd.PmdConst;
 
 /**
  * PMDモデルファイルのパーサ拡張その3。
+ *
  * <p>※ 剛体情報対応
  */
 public class PmdParserExt3 extends PmdParserExt2 {
@@ -143,15 +144,15 @@ public class PmdParserExt3 extends PmdParserExt2 {
      */
     private void parseRigidDynamics()
         throws IOException, MmdFormatException{
-            float mass        = parseLeFloat();
-            float dampingPos  = parseLeFloat();
-            float dampingRot  = parseLeFloat();
-            float restitution = parseLeFloat();
-            float friction    = parseLeFloat();
+        float mass        = parseLeFloat();
+        float dampingPos  = parseLeFloat();
+        float dampingRot  = parseLeFloat();
+        float restitution = parseLeFloat();
+        float friction    = parseLeFloat();
 
-            this.rigidHandler.pmdRigidPhysics(
-                mass, dampingPos, dampingRot, restitution, friction
-            );
+        this.rigidHandler.pmdRigidPhysics(
+            mass, dampingPos, dampingRot, restitution, friction
+        );
 
         return;
     }
@@ -225,7 +226,7 @@ public class PmdParserExt3 extends PmdParserExt2 {
                 posXlim1, posXlim2,
                 posYlim1, posYlim2,
                 posZlim1, posZlim2
-                );
+        );
 
         float rotXlim1 = parseLeFloat();
         float rotYlim1 = parseLeFloat();
@@ -238,7 +239,7 @@ public class PmdParserExt3 extends PmdParserExt2 {
                 rotXlim1, rotXlim2,
                 rotYlim1, rotYlim2,
                 rotZlim1, rotZlim2
-                );
+        );
 
         return;
     }
@@ -258,7 +259,7 @@ public class PmdParserExt3 extends PmdParserExt2 {
                 elasticPosX,
                 elasticPosY,
                 elasticPosZ
-                );
+        );
 
         float elasticRotX = parseLeFloat();
         float elasticRotY = parseLeFloat();
@@ -268,7 +269,7 @@ public class PmdParserExt3 extends PmdParserExt2 {
                 elasticRotX,
                 elasticRotY,
                 elasticRotZ
-                );
+        );
 
         return;
     }
index 65fcf8a..6cbe736 100644 (file)
@@ -13,40 +13,48 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 
 /**
  * PMDモデルの各種剛体情報の通知用ハンドラ。
+ *
  * <p>MMDでの剛体力学では「Bullet Physics Library」が用いられる。
+ *
  * @see <a href="http://www.bulletphysics.org/">Bullet Physics Library</a>
  */
 public interface PmdRigidHandler extends LoopHandler {
 
     /** 剛体情報抽出ループ。 */
-    ParseStage RIGID_LIST = new ParseStage();
+    public static final ParseStage RIGID_LIST = new ParseStage();
 
     /**
      * 剛体名の通知を受け取る。
+     *
      * <p>{@link #RIGID_LIST}ループの構成要素。
+     *
      * @param rigidName 剛体名
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdRigidName(String rigidName)
+    public abstract void pmdRigidName(String rigidName)
         throws MmdFormatException;
 
     /**
      * 剛体基本情報の通知を受け取る。
+     *
      * <p>{@link #RIGID_LIST}ループの構成要素。
+     *
      * @param rigidGroupId 剛体グループ番号から1引いた数。(0-15)
      * @param linkedBoneId 接続先ボーンID。
-     * [ 0x0000 - 0xfffe ] に収まらない場合は接続先ボーン無し。
+     *     [ 0x0000 - 0xfffe ] に収まらない場合は接続先ボーン無し。
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdRigidInfo(int rigidGroupId,
+    public abstract void pmdRigidInfo(int rigidGroupId,
                         int linkedBoneId)
         throws MmdFormatException;
 
     /**
      * 剛体形状の通知を受け取る。
+     *
      * <p>{@link #RIGID_LIST}ループの構成要素。
+     *
      * @param shapeType 形状種別。
      * <ul>
      * <li>0x00:球
@@ -57,55 +65,63 @@ public interface PmdRigidHandler extends LoopHandler {
      * @param height 箱orカプセルの高さ
      * @param depth 箱の奥行き
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdRigidShape(byte shapeType,
+    public abstract void pmdRigidShape(byte shapeType,
                          float width, float height, float depth)
         throws MmdFormatException;
 
     /**
      * 剛体位置の通知を受け取る。
+     *
      * <p>{@link #RIGID_LIST}ループの構成要素。
+     *
      * @param posX X座標
      * @param posY Y座標
      * @param posZ Z座標
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdRigidPosition(float posX, float posY, float posZ)
+    public abstract void pmdRigidPosition(float posX, float posY, float posZ)
         throws MmdFormatException;
 
     /**
      * 剛体姿勢の通知を受け取る。
+     *
      * <p>{@link #RIGID_LIST}ループの構成要素。
+     *
      * @param radX X軸回転量(radian)
      * @param radY Y軸回転量(radian)
      * @param radZ Z軸回転量(radian)
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdRigidRotation(float radX, float radY, float radZ)
+    public abstract void pmdRigidRotation(float radX, float radY, float radZ)
         throws MmdFormatException;
 
     /**
      * 剛体物理系数の通知を受け取る。
+     *
      * <p>{@link #RIGID_LIST}ループの構成要素。
+     *
      * @param mass 質量
      * @param dampingPos 移動減衰率
      * @param dampingRot 回転減衰率
      * @param restitution 反発力
      * @param friction 摩擦力
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdRigidPhysics(float mass,
+    public abstract void pmdRigidPhysics(float mass,
                            float dampingPos, float dampingRot,
                            float restitution, float friction )
         throws MmdFormatException;
 
     /**
      * 剛体の振る舞い情報の通知を受け取る。
+     *
      * <p>{@link #RIGID_LIST}ループの構成要素。
+     *
      * @param behaveType 剛体タイプ。
      * <ul>
      * <li>0:ボーン追従
@@ -113,14 +129,13 @@ public interface PmdRigidHandler extends LoopHandler {
      * <li>2:物理演算+ボーン位置合わせ
      * </ul>
      * @param collisionMap 非衝突剛体グループビットマップ。
-     * <p>
-     * (衝突グループ番号-1)位置のビット位置は1に、
-     * (非衝突グループ番号-1)位置のビット位置は0になる。
-     * 例)グループ1と8のみが非衝突指定の場合、0xff7eになる。
+     *     <p>(衝突グループ番号-1)位置のビット位置は1に、
+     *     (非衝突グループ番号-1)位置のビット位置は0になる。
+     *     例)グループ1と8のみが非衝突指定の場合、0xff7eになる。</p>
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void pmdRigidBehavior(byte behaveType, short collisionMap)
+    public abstract void pmdRigidBehavior(byte behaveType, short collisionMap)
         throws MmdFormatException;
 
 }
index 21d0bf6..502b959 100644 (file)
@@ -13,88 +13,106 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 
 /**
  * PMDモデルの各種形状(頂点、面)の通知用ハンドラ。
+ *
  * <p>0から始まる頂点ID順に頂点は出現する。
+ *
  * <p>0から始まる面ID順に面は出現する。
  */
 public interface PmdShapeHandler extends LoopHandler {
 
     /** 頂点抽出ループ。 */
-    ParseStage VERTEX_LIST = new ParseStage();
+    public static final ParseStage VERTEX_LIST = new ParseStage();
     /** 面抽出ループ。 */
-    ParseStage SURFACE_LIST = new ParseStage();
+    public static final ParseStage SURFACE_LIST = new ParseStage();
 
     /**
      * 頂点の座標の通知を受け取る。
+     *
      * <p>{@link #VERTEX_LIST}ループの構成要素
+     *
      * @param xPos X座標
      * @param yPos Y座標
      * @param zPos Z座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdVertexPosition(float xPos, float yPos, float zPos)
+    public abstract void pmdVertexPosition(float xPos, float yPos, float zPos)
             throws MmdFormatException;
 
     /**
      * 頂点の法線情報の通知を受け取る。
+     *
      * <p>{@link #VERTEX_LIST}ループの構成要素
+     *
      * <p>※単位ベクトル化必須?
+     *
      * @param xVec 法線ベクトルX成分
      * @param yVec 法線ベクトルY成分
      * @param zVec 法線ベクトルZ成分
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdVertexNormal(float xVec, float yVec, float zVec)
+    public abstract void pmdVertexNormal(float xVec, float yVec, float zVec)
             throws MmdFormatException;
 
     /**
      * 頂点のUVマッピング情報の通知を受け取る。
      * (頂点UV)
+     *
      * <p>{@link #VERTEX_LIST}ループの構成要素
+     *
      * @param uVal テクスチャのU座標
      * @param vVal テクスチャのV座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdVertexUV(float uVal, float vVal )
+    public abstract void pmdVertexUV(float uVal, float vVal )
             throws MmdFormatException;
 
     /**
      * 頂点のボーン間ウェイトバランス情報の通知を受け取る。
+     *
      * <p>{@link #VERTEX_LIST}ループの構成要素
+     *
      * @param boneId1 ボーンその1識別ID
      * @param boneId2 ボーンその2識別ID
      * @param weightForB1 ボーンその1への影響度。0(min)~100(max)
-     * ボーンその2への影響度は100からの引き算で求める。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     ボーンその2への影響度は100からの引き算で求める。
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdVertexWeight(int boneId1, int boneId2, int weightForB1)
+    public abstract void pmdVertexWeight(
+            int boneId1, int boneId2, int weightForB1)
             throws MmdFormatException;
 
     /**
      * 頂点のエッジ表現情報の通知を受け取る。
      * 材質単位でのエッジ表現指定に優先される。
+     *
      * <p>{@link #VERTEX_LIST}ループの構成要素
+     *
      * @param hideEdge エッジ無効ならtrue
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdVertexEdge(boolean hideEdge)
+    public abstract void pmdVertexEdge(boolean hideEdge)
             throws MmdFormatException;
 
     /**
      * 3つの頂点から構成される面情報の通知を受け取る。
+     *
      * <p>{@link #SURFACE_LIST}ループの構成要素。
+     *
      * <p>3頂点の指定順は、面カリングにおいて意味を持つ。
+     *
      * @param vertexId1 頂点IDその1
      * @param vertexId2 頂点IDその1
      * @param vertexId3 頂点IDその1
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdSurfaceTriangle(int vertexId1, int vertexId2, int vertexId3)
+    public abstract void pmdSurfaceTriangle(
+            int vertexId1, int vertexId2, int vertexId3)
             throws MmdFormatException;
 
 }
index dddec4f..d2b8209 100644 (file)
@@ -17,15 +17,18 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 public interface PmdToonHandler extends LoopHandler {
 
     /** トゥーンテクスチャファイル名抽出ループ。 */
-    ParseStage TOON_LIST = new ParseStage();
+    public static final ParseStage TOON_LIST = new ParseStage();
 
     /**
      * 独自トゥーンテクスチャファイル名の通知を受け取る。
+     *
      * <p>{@link #TOON_LIST}ループの構成要素
+     *
      * @param toonName 独自トゥーンテクスチャファイル名
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void pmdToonFileInfo(String toonName) throws MmdFormatException;
+    public abstract void pmdToonFileInfo(String toonName)
+            throws MmdFormatException;
 
 }
index c849e89..56a0c37 100644 (file)
@@ -24,7 +24,7 @@ public interface PmdUnifiedHandler
             PmdJointHandler {
 
     /** 何もしない統合ハンドラ。 */
-    PmdUnifiedHandler EMPTY =
+    public static final PmdUnifiedHandler EMPTY =
             (PmdUnifiedHandler)
             ( EmptyProxyFactory.buildEmptyProxy(PmdUnifiedHandler.class) );
 
index 1585488..9d0418d 100644 (file)
@@ -7,6 +7,7 @@
 
 /**
  * PMDモデルファイル(*.pmd)用パーサライブラリ。
+ *
  * <p>コールバックインタフェースを実装したオブジェクトをパーサに渡し、
  * PMDモデルファイルのパースを開始すると、
  * 各種データの出現に応じてコールバックメソッドを次々と呼び出してくれる。
index bd33ba7..a59c749 100644 (file)
@@ -32,8 +32,8 @@ class AliasMap<T extends I18nAlias> {
     AliasMap(){
         super();
 
-        this.primaryAliasMap = new HashMap<String, T>();
-        this.globalAliasMap  = new HashMap<String, T>();
+        this.primaryAliasMap = new HashMap<>();
+        this.globalAliasMap  = new HashMap<>();
 
         return;
     }
@@ -41,11 +41,13 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * NFKC正規化されたUnicode文字列を返す。
+     *
      * <p>等価な全半角、濁点、丸付き数字などの表現の正規化を目的とする。
      * <ul>
      * <li>「ボーン」は「ボーン」になる
      * <li>「ホ゛ーン9」は「ボーン9」になる
      * </ul>
+     *
      * @param name 正規化対象文字列
      * @return 正規化済み文字列
      */
@@ -58,9 +60,12 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * 別名管理オブジェクトを登録。
+     *
      * <p>キーとなる名前は、事前にNFKC正規化で
      * 揺らぎ表記が吸収されたプライマリ名およびグローバル名。
+     *
      * <p>登録キーが衝突した時は後の方が有効となる。
+     *
      * @param alias 別名管理オブジェクト
      */
     void addAlias(T alias){
@@ -71,8 +76,11 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * 別名管理オブジェクトと正規化プライマリ名を対応づける。
+     *
      * <p>事前にNFKC正規化されたプライマリ名が登録キーとなる。
+     *
      * <p>登録キーが衝突した時は後の方が有効となる。
+     *
      * @param alias 別名管理オブジェクト
      */
     private void addPrimary(T alias){
@@ -86,8 +94,11 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * 別名管理オブジェクトと正規化グローバル名を対応づける。
+     *
      * <p>事前にNFKC正規化されたグローバル名が登録キーとなる。
+     *
      * <p>登録キーが衝突した時は後の方が有効となる。
+     *
      * @param alias 別名管理オブジェクト
      */
     private void addGlobal(T alias){
@@ -101,8 +112,11 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * 名前から別名管理オブジェクトを得る。
+     *
      * <p>プライマリ名、グローバル名の順で検索される。
+     *
      * <p>名前は事前にNFKC正規化された後、検索キーとなる。
+     *
      * @param name 名前
      * @return 別名管理オブジェクト。見つからなければnull
      */
@@ -117,7 +131,9 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * プライマリ名から別名管理オブジェクトを得る。
+     *
      * <p>プライマリ名は事前にNFKC正規化された後、検索キーとなる。
+     *
      * @param primaryName プライマリ名
      * @return 別名管理オブジェクト。見つからなければnull
      */
@@ -129,7 +145,9 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * グローバル名から別名管理オブジェクトを得る。
+     *
      * <p>グローバル名は事前にNFKC正規化された後、検索キーとなる。
+     *
      * @param globalName グローバル名
      * @return 別名管理オブジェクト。見つからなければnull
      */
@@ -141,7 +159,9 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * プライマリ名から代表グローバル名を得る。
+     *
      * <p>プライマリ名は事前にNFKC正規化された後、検索キーとなる。
+     *
      * @param primaryName プライマリ名
      * @return 代表グローバル名。見つからなければnull
      */
@@ -154,11 +174,13 @@ class AliasMap<T extends I18nAlias> {
 
     /**
      * グローバル名から代表プライマリ名を得る。
+     *
      * <p>グローバル名は事前にNFKC正規化された後、検索キーとなる。
+     *
      * @param globalName グローバル名
      * @return 代表プライマリ名。見つからなければnull
      */
-     String global2primary(String globalName){
+    String global2primary(String globalName){
         T alias = getAliasByGlobal(globalName);
         if(alias == null) return null;
         String primary = alias.getTopPrimaryName();
index e6e8c29..5942a41 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.LinkedList;
 import java.util.List;
+import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
@@ -23,13 +24,17 @@ import org.xml.sax.SAXException;
 
 /**
  * 国際化&amp;別名管理オブジェクトの実装基板。
+ *
  * <p>別名管理オブジェクトは、
  * 各々のリストの先頭が代表名となる、
  * プライマリ名の不変リストとグローバル名の不変リストを持つ。
+ *
  * <p>国産モデルではプライマリ名に日本語名が収められることが多い。
  * プライマリ名は必ず一つ以上なければならない。
+ *
  * <p>国産モデルではグローバル名に英語名が収められることが多いが、
  * プライマリ名と同一の日本語名が収められている場合も多い。
+ *
  * <p>別名管理オブジェクトは、
  * インスタンス間での順序を定義するためのオーダー番号を持つ。
  */
@@ -39,6 +44,15 @@ class I18nAlias {
     public static final Comparator<I18nAlias> ORDER_COMPARATOR =
             new OrderComparator();
 
+    private static final String F_DISALLOW_DOCTYPE_DECL =
+            "http://apache.org/xml/features/disallow-doctype-decl";
+    private static final String F_EXTERNAL_GENERAL_ENTITIES =
+            "http://xml.org/sax/features/external-general-entities";
+    private static final String F_EXTERNAL_PARAMETER_ENTITIES =
+            "http://xml.org/sax/features/external-parameter-entities";
+    private static final String F_LOAD_EXTERNAL_DTD =
+            "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+
 
     private int orderNo;
 
@@ -51,8 +65,10 @@ class I18nAlias {
 
     /**
      * コンストラクタ。
+     *
      * <p>各初期数が0以下の場合は、
      * 状況に応じて伸長する連結リストが用意される。
+     *
      * @param primaryNum プライマリ名初期数。
      * @param globalNum グローバル名初期数。
      */
@@ -60,15 +76,15 @@ class I18nAlias {
         super();
 
         if(primaryNum <= 0){
-            this.primaryNameList = new LinkedList<String>();
+            this.primaryNameList = new LinkedList<>();
         }else{
-            this.primaryNameList = new ArrayList<String>(primaryNum);
+            this.primaryNameList = new ArrayList<>(primaryNum);
         }
 
         if(globalNum <= 0){
-            this.globalNameList  = new LinkedList<String>();
+            this.globalNameList  = new LinkedList<>();
         }else{
-            this.globalNameList  = new ArrayList<String>(globalNum);
+            this.globalNameList  = new ArrayList<>(globalNum);
         }
 
         this.umodPrimaryNameList =
@@ -81,6 +97,7 @@ class I18nAlias {
 
     /**
      * コンストラクタ。
+     *
      * <p>プライマリ名、グローバル名共、
      * 状況に応じて伸長する連結リストが用意される。
      */
@@ -103,6 +120,20 @@ class I18nAlias {
         DocumentBuilderFactory factory;
         factory = DocumentBuilderFactory.newInstance();
 
+        factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        factory.setFeature(F_EXTERNAL_GENERAL_ENTITIES, false);
+        factory.setFeature(F_EXTERNAL_PARAMETER_ENTITIES, false);
+        factory.setFeature(F_LOAD_EXTERNAL_DTD, false);
+
+        // unsafe but we use DOCTYPE
+        factory.setFeature(F_DISALLOW_DOCTYPE_DECL, false);
+
+        factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+        factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
+
+        factory.setXIncludeAware(false);
+        factory.setExpandEntityReferences(false);
+
         DocumentBuilder builder = factory.newDocumentBuilder();
         Document doc = builder.parse(is);
 
@@ -131,7 +162,9 @@ class I18nAlias {
 
     /**
      * プライマリ名の代表をひとつ返す。
+     *
      * <p>必ず存在しなければならない。
+     *
      * @return 最初のプライマリ名
      */
     public String getTopPrimaryName(){
index d97a752..c463fc1 100644 (file)
@@ -19,9 +19,12 @@ import org.xml.sax.SAXException;
 
 /**
  * 一般的な標準ボーン構成に関する情報。
+ *
  * <p>各ボーン情報はひとつ以上のプライマリ名(≒日本語名)と
  * ゼロ個以上のグローバル名(≒英語名)を持つ。
+ *
  * <p>選択基準は独断。
+ *
  * <p>和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。
  */
 public final class TypicalBone extends I18nAlias {
@@ -36,9 +39,9 @@ public final class TypicalBone extends I18nAlias {
     private static final String ATTR_NAME    = "name";
 
     private static final List<TypicalBone> BONE_LIST =
-            new LinkedList<TypicalBone>();
+            new LinkedList<>();
     private static final AliasMap<TypicalBone> BONE_ALIAS_MAP =
-            new AliasMap<TypicalBone>();
+            new AliasMap<>();
 
     private static final List<TypicalBone> BONE_UNMODLIST =
             Collections.unmodifiableList(BONE_LIST);
@@ -49,11 +52,7 @@ public final class TypicalBone extends I18nAlias {
         Element top;
         try{
             top = I18nAlias.loadXml(is);
-        }catch(ParserConfigurationException e){
-            throw new ExceptionInInitializerError(e);
-        }catch(SAXException e){
-            throw new ExceptionInInitializerError(e);
-        }catch(IOException e){
+        }catch(ParserConfigurationException | SAXException | IOException e){
             throw new ExceptionInInitializerError(e);
         }
 
@@ -68,8 +67,10 @@ public final class TypicalBone extends I18nAlias {
 
     /**
      * コンストラクタ。
+     *
      * <p>各初期数が0以下の場合は、
      * 状況に応じて伸長する連結リストが用意される。
+     *
      * @param primaryNum プライマリ名初期数。
      * @param globalNum グローバル名初期数。
      */
@@ -136,6 +137,7 @@ public final class TypicalBone extends I18nAlias {
 
     /**
      * 全ボーン情報に通し番号を付ける。
+     *
      * <p>XMLでの定義順が反映される。
      */
     private static void numbering(){
@@ -201,7 +203,9 @@ public final class TypicalBone extends I18nAlias {
     /**
      * このボーンが親を持たないルートボーンとして扱われる慣習なのか
      * 判定する。
+     *
      * <p>※「全親」ボーンに関する慣習は無視される。
+     *
      * @return 親を持たなければtrue
      */
     public boolean isRoot(){
index 2581ac3..d67de8e 100644 (file)
@@ -23,9 +23,12 @@ import org.xml.sax.SAXException;
 
 /**
  * 一般的な標準モーフに関する情報。
+ *
  * <p>各モーフ情報はひとつ以上のプライマリ名(≒日本語名)と
  * ゼロ個以上のグローバル名(≒英語名)を持つ。
+ *
  * <p>選択基準は独断。
+ *
  * <p>和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。
  */
 public final class TypicalMorph extends I18nAlias {
@@ -43,10 +46,10 @@ public final class TypicalMorph extends I18nAlias {
     private static final List<TypicalMorph> EMPTY = Collections.emptyList();
 
     private static final Map<MorphType, List<TypicalMorph>> TYPED_MAP =
-            new EnumMap<MorphType, List<TypicalMorph>>(MorphType.class);
+            new EnumMap<>(MorphType.class);
 
     private static final AliasMap<TypicalMorph> MORPH_ALIAS_MAP =
-            new AliasMap<TypicalMorph>();
+            new AliasMap<>();
 
 
     static{
@@ -55,11 +58,7 @@ public final class TypicalMorph extends I18nAlias {
         Element top;
         try{
             top = I18nAlias.loadXml(is);
-        }catch(ParserConfigurationException e){
-            throw new ExceptionInInitializerError(e);
-        }catch(SAXException e){
-            throw new ExceptionInInitializerError(e);
-        }catch(IOException e){
+        }catch(ParserConfigurationException | SAXException | IOException e){
             throw new ExceptionInInitializerError(e);
         }
 
@@ -74,8 +73,10 @@ public final class TypicalMorph extends I18nAlias {
 
     /**
      * コンストラクタ。
+     *
      * <p>各初期数が0以下の場合は、
      * 状況に応じて伸長する連結リストが用意される。
+     *
      * @param type モーフ種別
      * @param primaryNum プライマリ名初期数。
      * @param globalNum グローバル名初期数。
@@ -124,7 +125,7 @@ public final class TypicalMorph extends I18nAlias {
         NodeList morphList = groupElem.getElementsByTagName(ELEM_MORPH);
         int morphNo = morphList.getLength();
         List<TypicalMorph> groupedList =
-                new ArrayList<TypicalMorph>(morphNo);
+                new ArrayList<>(morphNo);
 
         for(int idx = 0; idx < morphNo; idx++){
             Element morphElem = (Element) morphList.item(idx);
@@ -173,6 +174,7 @@ public final class TypicalMorph extends I18nAlias {
 
     /**
      * 全モーフ情報に通し番号を付ける。
+     *
      * <p>同一グループ内ではXMLでの定義順が反映される。
      */
     private static void numbering(){
index af171c5..3328e8c 100644 (file)
@@ -39,13 +39,16 @@ public final class UniqBone {
     /**
      * IK演算時の回転方向に制限を受ける「ひざボーン」か否か、
      * ボーン名で判定する。
+     *
      * <p>ボーンのプライマリ名が「左ひざ」もしくは「右ひざ」で始まれば
      * ひざボーンとする。
+     *
      * <p>ひざボーン名の例
      * <ul>
      * <li>「左ひざ」
      * <li>「左ひざげり」
      * </ul>
+     *
      * <p>ひざボーン名ではない例
      * <ul>
      * <li>「左ひ」
@@ -57,6 +60,7 @@ public final class UniqBone {
      * <li>「左膝」
      * <li>「Knee_L」
      * </ul>
+     *
      * @param boneNameJp プライマリボーン名
      * @return ひざボーンならtrue
      */
index 128bf08..156d617 100644 (file)
@@ -7,7 +7,9 @@
 
 /**
  * MMDコミュニティにおける一般的な慣例に関する情報を提供する。
+ *
  * <p>例)ボーン名やモーフ名の一般的な名前、対訳など
+ *
  * <p>MikuMikuDance Ver.7.39同梱のモデルなどが主な情報源。
  */
 
index 0adc470..c322a12 100644 (file)
@@ -15,19 +15,20 @@ import java.util.Comparator;
 public interface FrameNumbered {
 
     /** 昇順での比較子。 */
-    Comparator<FrameNumbered> COMPARATOR = new FrameComparator();
+    public static final Comparator<FrameNumbered> COMPARATOR =
+            new FrameComparator();
 
     /**
      * フレーム番号を設定する。
      * @param num フレーム番号
      */
-    void setFrameNumber(int num);
+    public abstract void setFrameNumber(int num);
 
     /**
      * フレーム番号を返す。
      * @return フレーム番号
      */
-    int getFrameNumber();
+    public abstract int getFrameNumber();
 
 
     /**
@@ -35,7 +36,7 @@ public interface FrameNumbered {
      * フレーム番号の昇順を定義づける。
      */
     @SuppressWarnings("serial")
-    class FrameComparator
+    public static class FrameComparator
             implements Comparator<FrameNumbered> {
 
         /**
index 076d309..7af1e03 100644 (file)
@@ -39,7 +39,9 @@ public final class VmdConst {
 
     /**
      * IK ON/OFFスイッチ用ボーン名最大長。バイト単位。
+     *
      * <p>※MikuMikuDance Ver7.40からの機能。
+     *
      * <p>モーション指定用ボーン名と長さが違うので注意。
      */
     public static final int IKSWBONENAME_MAX = 20;
index 44faede..4659fd8 100644 (file)
@@ -52,9 +52,11 @@ public final class VmdUniq {
     /**
      * カメラやライティングなどのステージ演出データの可能性があるか、
      * モデル名から推測する。
+     *
      * <p>モデル名が「カメラ・照明」である場合、
      * そのモーションファイルはほぼ
      * カメラ・ライティング用ステージ演出データであると推測される。
+     *
      * @param modelName モデル名
      * @return モデル名にカメラもしくはライティングの可能性があるならtrue
      */
index 08b8ba0..8a5d1c9 100644 (file)
@@ -14,173 +14,210 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 /**
  * VMDモーションファイルの基本情報(ボーンモーション/モーフモーション)
  * の通知用ハンドラ。
+ *
  * <p>フレーム番号は相対的なものとなる。
  * 一番若いモーションのフレーム番号が0となる模様。
+ *
  * <p>位置情報の座標基準は左手系ワールド座標で表される。
+ *
  * <p>モーション補間情報は三次ベジェ曲線により記述される。
  * 三次ベジェ曲線は4つの制御点P0,P1,P2,P3により定義される。
  * P0は(0,0)、P3は(127,127)で固定。
  * P1,P2はP0,P3を対角線とする正方形の内部になければならない。
  * 直線補間の場合、P1には(20,20)、P2には(107,107)が使われることが多い。
+ *
  * <p>補間情報は直後のボーンモーション情報との差分に関するもの。
  */
 public interface VmdBasicHandler extends LoopHandler {
 
     /** ボーンモーション抽出ループ識別子。 */
-    ParseStage BONEMOTION_LIST = new ParseStage();
+    public static final ParseStage BONEMOTION_LIST = new ParseStage();
 
     /** モーフ抽出ループ識別子。 */
-    ParseStage MORPH_LIST = new ParseStage();
+    public static final ParseStage MORPH_LIST = new ParseStage();
 
 
     /**
      * VMDファイルのパース処理開始の通知を受け取る。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdParseStart()
+    public abstract void vmdParseStart()
             throws MmdFormatException;
 
     /**
      * VMDファイルのパース処理終了の通知を受け取る。
-     * @param hasMoreData 入力ソースに
-     * まだ読み込まれていないデータがあればtrue
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @param hasMoreData
+     *     入力ソースにまだ読み込まれていないデータがあればtrue
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdParseEnd(boolean hasMoreData)
+    public abstract void vmdParseEnd(boolean hasMoreData)
             throws MmdFormatException;
 
     /**
      * VMDファイルの固定長ヘッダを通知する。
      * @param header ヘッダ情報
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdHeaderInfo(byte[] header)
+    public abstract void vmdHeaderInfo(byte[] header)
             throws MmdFormatException;
 
 
     /**
      * モーションの適用先モデル名に関する情報を通知する。
+     *
      * <p>カメラやライティングなどの演出データには
      * 特殊なモデル名が使われる。
+     *
      * @param modelName モデル名
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdModelName(String modelName)
+    public abstract void vmdModelName(String modelName)
             throws MmdFormatException;
 
     /**
      * ボーンモーションのボーン名及びキーフレーム番号に関する情報を通知する。
+     *
      * <p>{@link #BONEMOTION_LIST}ループの構成要素。
+     *
      * @param boneName ボーン名
      * @param keyFrameNo キーフレーム番号
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdBoneMotion(String boneName, int keyFrameNo)
+    public abstract void vmdBoneMotion(String boneName, int keyFrameNo)
             throws MmdFormatException;
 
     /**
      * ボーン移動モーション情報の通知を受け取る。
+     *
      * <p>座標基準は親ボーンもしくはワールド座標。
+     *
      * <p>{@link #BONEMOTION_LIST}ループの構成要素。
+     *
      * @param xPos X座標
      * @param yPos Y座標
      * @param zPos Z座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdBonePosition(float xPos, float yPos, float zPos)
+    public abstract void vmdBonePosition(float xPos, float yPos, float zPos)
             throws MmdFormatException;
 
     /**
      * ボーン回転モーション情報の通知を受け取る。
+     *
      * <p>回転及び姿勢はクォータニオンによって記述される。
      * MMDUI上のボーン数値入力YXZオイラー角と等価な回転。
+     *
      * <p>座標基準は親ボーンもしくはワールド座標。
+     *
      * <p>※ボーン種別によっては、無意味な情報。
+     *
      * <p>{@link #BONEMOTION_LIST}ループの構成要素。
+     *
      * @param qx クォータニオン虚部 X
      * @param qy クォータニオン虚部 Y
      * @param qz クォータニオン虚部 Z
      * @param qw クォータニオン実部 W
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdBoneRotationQt(float qx, float qy, float qz, float qw)
+    public abstract void vmdBoneRotationQt(
+            float qx, float qy, float qz, float qw)
             throws MmdFormatException;
 
     /**
      * ボーンモーションX軸移動補間情報の通知を受け取る。
+     *
      * <p>三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #BONEMOTION_LIST}ループの構成要素。
+     *
      * @param xP1x P1点のX座標
      * @param xP1y P1点のY座標
      * @param xP2x P2点のX座標
      * @param xP2y P2点のY座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdBoneIntpltXpos(byte xP1x, byte xP1y, byte xP2x, byte xP2y)
+    public abstract void vmdBoneIntpltXpos(
+            byte xP1x, byte xP1y, byte xP2x, byte xP2y)
             throws MmdFormatException;
 
     /**
      * ボーンモーションY軸移動補間情報の通知を受け取る。
+     *
      * <p>三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #BONEMOTION_LIST}ループの構成要素。
+     *
      * @param yP1x P1点のX座標
      * @param yP1y P1点のY座標
      * @param yP2x P2点のX座標
      * @param yP2y P2点のY座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdBoneIntpltYpos(byte yP1x, byte yP1y, byte yP2x, byte yP2y)
+    public abstract void vmdBoneIntpltYpos(
+            byte yP1x, byte yP1y, byte yP2x, byte yP2y)
             throws MmdFormatException;
 
     /**
      * ボーンモーションZ軸移動補間情報の通知を受け取る。
+     *
      * <p>三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #BONEMOTION_LIST}ループの構成要素。
+     *
      * @param zP1x P1点のX座標
      * @param zP1y P1点のY座標
      * @param zP2x P2点のX座標
      * @param zP2y P2点のY座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdBoneIntpltZpos(byte zP1x, byte zP1y, byte zP2x, byte zP2y)
+    public abstract void vmdBoneIntpltZpos(
+            byte zP1x, byte zP1y, byte zP2x, byte zP2y)
             throws MmdFormatException;
 
     /**
      * ボーンモーション回転量補間情報の通知を受け取る。
+     *
      * <p>三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #BONEMOTION_LIST}ループの構成要素。
+     *
      * <p>クォータニオン間のslerp処理に利用される。
+     *
      * @param rP1x P1点のX座標
      * @param rP1y P1点のY座標
      * @param rP2x P2点のX座標
      * @param rP2y P2点のY座標
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdBoneIntpltRot(byte rP1x, byte rP1y, byte rP2x, byte rP2y)
+    public abstract void vmdBoneIntpltRot(
+            byte rP1x, byte rP1y, byte rP2x, byte rP2y)
             throws MmdFormatException;
 
 
     /**
      * モーフモーション情報の通知を受け取る。
+     *
      * <p>{@link #MORPH_LIST}ループの構成要素。
+     *
      * @param morphName モーフ名。特殊モーフ名「base」は無視してもよい?
      * @param keyFrameNo フレーム番号
      * @param flex モーフ変量。通常は0.0以上1.0以下。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdMorphMotion(String morphName, int keyFrameNo, float flex)
+    public abstract void vmdMorphMotion(
+            String morphName, int keyFrameNo, float flex)
             throws MmdFormatException;
 
 }
index 5316461..cf74a12 100644 (file)
@@ -19,6 +19,7 @@ import jp.sfjp.mikutoga.vmd.VmdUniq;
 
 /**
  * VMDモーションファイルの基本部パーサ。
+ *
  * <p>ボーンのモーション情報およびモーフモーション情報のパース処理を含む。
  */
 class VmdBasicParser extends ProxyParser{
@@ -249,14 +250,16 @@ class VmdBasicParser extends ProxyParser{
         this.handler.vmdBoneIntpltXpos(xP1x, xP1y, xP2x, xP2y);
         this.handler.vmdBoneIntpltYpos(yP1x, yP1y, yP2x, yP2y);
         this.handler.vmdBoneIntpltZpos(zP1x, zP1y, zP2x, zP2y);
-        this.handler.vmdBoneIntpltRot (rP1x, rP1y, rP2x, rP2y);
+        this.handler.vmdBoneIntpltRotrP1x, rP1y, rP2x, rP2y);
 
         return;
     }
 
     /**
      * 補間情報の冗長箇所の整合性チェックを行う。
+     *
      * <p>※ MMDの版数によって微妙に詳細が異なる場合がある。
+     *
      * @throws MmdFormatException 冗長箇所の不整合を検出した。
      */
     private void checkIntpltStrict() throws MmdFormatException{
index c5af766..bb46bda 100644 (file)
@@ -14,39 +14,45 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 /**
  * VMDモーションファイルの各種ON/OFF情報(モデル表示・IK有効無効)
  * の通知用ハンドラ。
+ *
  * <p>MikuMikuDance Ver7.40よりVMDファイルに導入された新仕様。
  */
 public interface VmdBoolHandler extends LoopHandler {
 
     /** モデル表示スイッチ抽出ループ識別子。 */
-    ParseStage MODELSIGHT_LIST = new ParseStage();
+    public static final ParseStage MODELSIGHT_LIST = new ParseStage();
 
     /** IK有効スイッチ抽出ループ識別子。 */
-    ParseStage IKSW_LIST = new ParseStage();
+    public static final ParseStage IKSW_LIST = new ParseStage();
 
 
     /**
      * モデルの表示フラグを通知する。
+     *
      * <p>{@link #MODELSIGHT_LIST}ループの構成要素。
+     *
      * @param show モデルの表示が行われる場合true
      * @param keyFrameNo キーフレーム番号
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdModelSight(boolean show, int keyFrameNo)
+    public abstract void vmdModelSight(boolean show, int keyFrameNo)
             throws MmdFormatException;
 
     /**
      * IKボーン別のIK処理のON/OFFを通知する。
+     *
      * <p>{@link #MODELSIGHT_LIST}ループの下位
      * {@link #IKSW_LIST}ループの構成要素。
+     *
      * @param boneName IKボーン名
      * @param validIk IK処理が無効になる場合false
      * @param keyFrameNo キーフレーム番号
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdIkSwitch(String boneName, boolean validIk, int keyFrameNo)
+    public abstract void vmdIkSwitch(
+            String boneName, boolean validIk, int keyFrameNo)
             throws MmdFormatException;
 
 }
index daffc6d..041439c 100644 (file)
@@ -17,6 +17,7 @@ import jp.sfjp.mikutoga.vmd.VmdConst;
 /**
  * VMDモーションファイルの各種ON/OFF情報(モデル表示・IK有効無効)
  * パーサ。
+ *
  * <p>MikuMikuDance Ver7.40以降でサポート
  */
 class VmdBoolParser extends ProxyParser {
index 7fbef1f..1c519d3 100644 (file)
@@ -13,176 +13,227 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 
 /**
  * VMDモーションファイルのカメラワーク情報の通知用ハンドラ。
+ *
  * <p>フレーム番号は相対的なものとなる。
  * カメラ・照明・シャドウのうち
  * 一番若いモーションのフレーム番号が0となる模様。
+ *
  * <p>ターゲット位置、カメラ回転量とも、座標基準はワールド座標。
+ *
  * <p>カメラターゲットの座標は左手系で表される。
+ *
  * <p>ターゲットに対するカメラ位置は極座標で表される。
+ *
  * <p>補間情報は直前カメラ情報との差分に関するもの。
  */
 public interface VmdCameraHandler extends LoopHandler {
 
     /** カメラデータ抽出ループ識別子。 */
-    ParseStage CAMERA_LIST = new ParseStage();
+    public static final ParseStage CAMERA_LIST = new ParseStage();
 
 
     /**
      * カメラモーションのキーフレーム番号に関する情報を通知する。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param keyFrameNo キーフレーム番号
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdCameraMotion(int keyFrameNo)
+    public abstract void vmdCameraMotion(int keyFrameNo)
             throws MmdFormatException;
 
     /**
      * ターゲットとカメラ間の距離情報を通知する。
+     *
      * <p>球座標(極座標)の動径に相当する。
      * 通常はターゲットより手前に位置するカメラまでの距離が負の値で渡される。
+     *
      * <p>カメラ位置がターゲットを突き抜けた場合は正の値もとりうる。
      * ※MMDのUIと符号が逆なので注意。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param range 距離
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraRange(float range)
+    public abstract void vmdCameraRange(float range)
             throws MmdFormatException;
 
     /**
      * カメラのターゲット位置情報を通知する。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param xPos ターゲットのX座標
      * @param yPos ターゲットのY座標
      * @param zPos ターゲットのZ座標
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraPosition(float xPos, float yPos, float zPos)
+    public abstract void vmdCameraPosition(float xPos, float yPos, float zPos)
             throws MmdFormatException;
 
     /**
      * カメラの回転および回転量情報を通知する。
+     *
      * <p>極座標(球座標)が用いられる。
+     *
      * <p>180度を超える値も回転量として意味を持つ。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param latitude ターゲットから見たカメラの仰俯角(≒緯度)。
-     * 単位はラジアン。
-     * <p>Y軸回転量が0の時のZ正軸がY正軸へ倒れる方向が正回転。
-     * (MMDのUIとは符号が逆になるので注意)
-     * <p>仰俯角が0の場合、
-     * カメラはターゲットに対しXZ平面(水平)と平行な箇所に位置する。
+     *     単位はラジアン。
+     *
+     *     <p>Y軸回転量が0の時のZ正軸がY正軸へ倒れる方向が正回転。
+     *     (MMDのUIとは符号が逆になるので注意)</p>
+     *
+     *     <p>仰俯角が0の場合、
+     *     カメラはターゲットに対しXZ平面(水平)と平行な箇所に位置する。</p>
+     *
      * @param longitude Y軸周りの回転量(≒経度)。単位はラジアン。
-     * <p>X正軸がZ正軸へ倒れる方向が正回転。(ボーン回転と逆)
-     * <p>仰俯角およびY軸回転量が0の場合、
-     * カメラレンズはZ軸-∞方向からZ軸+∞方向を向く。
+     *
+     *     <p>X正軸がZ正軸へ倒れる方向が正回転。(ボーン回転と逆)</p>
+     *
+     *     <p>仰俯角およびY軸回転量が0の場合、
+     *     カメラレンズはZ軸-∞方向からZ軸+∞方向を向く。</p>
+     *
      * @param roll レンズをターゲットを向けたカメラのロール回転量。
-     * <p>仰俯角とY軸回転量が0の時にY正軸がX正軸に倒れる方向が正回転。
-     * <p>仰俯角およびロール回転量が0の場合、カメラ上部はY軸+∞の方を向く。
+     *
+     *     <p>仰俯角とY軸回転量が0の時に
+     *     Y正軸がX正軸に倒れる方向が正回転。</p>
+     *
+     *     <p>仰俯角およびロール回転量が0の場合、
+     *     カメラ上部はY軸+∞の方を向く。</p>
+     *
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraRotation(float latitude, float longitude, float roll)
+    public abstract void vmdCameraRotation(
+            float latitude, float longitude, float roll)
             throws MmdFormatException;
 
     /**
      * カメラを通じたスクリーン座標への投影に関する情報を通知する。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param angle 縦画角。単位は度数法。MMDのUIでは1から125が指定可能。
      * @param hasPerspective パースペクティブスイッチがONならtrue。
-     * スイッチがOFFの場合、画角は無視され遠近感処理が行われなくなる。
-     * (平行投影?)
+     *     スイッチがOFFの場合、画角は無視され遠近感処理が行われなくなる。
+     *     (平行投影?)
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraProjection(int angle, boolean hasPerspective)
+    public abstract void vmdCameraProjection(
+            int angle, boolean hasPerspective)
             throws MmdFormatException;
 
     /**
      * カメラターゲットX軸移動補間情報の通知を受け取る。
      * 三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param p1x P1点のX座標
      * @param p1y P1点のY座標
      * @param p2x P2点のX座標
      * @param p2y P2点のY座標
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraIntpltXpos(byte p1x, byte p1y, byte p2x, byte p2y)
+    public abstract void vmdCameraIntpltXpos(
+            byte p1x, byte p1y, byte p2x, byte p2y)
             throws MmdFormatException;
 
     /**
      * カメラターゲットY軸移動補間情報の通知を受け取る。
      * 三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param p1x P1点のX座標
      * @param p1y P1点のY座標
      * @param p2x P2点のX座標
      * @param p2y P2点のY座標
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraIntpltYpos(byte p1x, byte p1y, byte p2x, byte p2y)
+    public abstract void vmdCameraIntpltYpos(
+            byte p1x, byte p1y, byte p2x, byte p2y)
             throws MmdFormatException;
 
     /**
      * カメラターゲットZ軸移動補間情報の通知を受け取る。
      * 三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param p1x P1点のX座標
      * @param p1y P1点のY座標
      * @param p2x P2点のX座標
      * @param p2y P2点のY座標
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraIntpltZpos(byte p1x, byte p1y, byte p2x, byte p2y)
+    public abstract void vmdCameraIntpltZpos(
+            byte p1x, byte p1y, byte p2x, byte p2y)
             throws MmdFormatException;
 
     /**
      * カメラ回転量補間情報の通知を受け取る。
      * 三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * <p>カメラ回転でクォータニオン補間は使われない。
+     *
      * @param p1x P1点のX座標
      * @param p1y P1点のY座標
      * @param p2x P2点のX座標
      * @param p2y P2点のY座標
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraIntpltRotation(byte p1x, byte p1y, byte p2x, byte p2y)
+    public abstract void vmdCameraIntpltRotation(
+            byte p1x, byte p1y, byte p2x, byte p2y)
             throws MmdFormatException;
 
     /**
      * カメラ-ターゲット間距離補間情報の通知を受け取る。
      * 三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param p1x P1点のX座標
      * @param p1y P1点のY座標
      * @param p2x P2点のX座標
      * @param p2y P2点のY座標
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraIntpltRange(byte p1x, byte p1y, byte p2x, byte p2y)
+    public abstract void vmdCameraIntpltRange(
+            byte p1x, byte p1y, byte p2x, byte p2y)
             throws MmdFormatException;
 
     /**
      * スクリーン投影補間情報の通知を受け取る。
      * 三次ベジェ曲線のP1,P2点に関する情報を受け取る。
+     *
      * <p>{@link #CAMERA_LIST}ループの構成要素。
+     *
      * @param p1x P1点のX座標
      * @param p1y P1点のY座標
      * @param p2x P2点のX座標
      * @param p2y P2点のY座標
      * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     *     パース処理の中断をパーサに指示
      */
-    void vmdCameraIntpltProjection(byte p1x, byte p1y, byte p2x, byte p2y)
+    public abstract void vmdCameraIntpltProjection(
+            byte p1x, byte p1y, byte p2x, byte p2y)
             throws MmdFormatException;
 
 }
index 57e7e64..8273a13 100644 (file)
@@ -157,8 +157,8 @@ class VmdCameraParser extends ProxyParser{
 
         assert idx == this.etcIntplt.length;
 
-        this.handler.vmdCameraIntpltRotation  (rP1x, rP1y, rP2x, rP2y);
-        this.handler.vmdCameraIntpltRange     (dP1x, dP1y, dP2x, dP2y);
+        this.handler.vmdCameraIntpltRotation(  rP1x, rP1y, rP2x, rP2y);
+        this.handler.vmdCameraIntpltRange(     dP1x, dP1y, dP2x, dP2y);
         this.handler.vmdCameraIntpltProjection(pP1x, pP1y, pP2x, pP2y);
 
         return;
index 065be3a..25bc30b 100644 (file)
@@ -14,6 +14,7 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 /**
  * VMDモーションファイルのライティング情報(照明光源・セルフシャドウ)
  * の通知用ハンドラ。
+ *
  * <p>フレーム番号は相対的なものとなる。
  * カメラ・照明・シャドウのうち
  * 一番若いモーションのフレーム番号が0となる模様。
@@ -21,25 +22,29 @@ import jp.sfjp.mikutoga.bin.parser.ParseStage;
 public interface VmdLightingHandler extends LoopHandler {
 
     /** 照明光源データ抽出ループ識別子。 */
-    ParseStage LUMINOUS_LIST = new ParseStage();
+    public static final ParseStage LUMINOUS_LIST = new ParseStage();
 
     /** セルフシャドウデータ抽出ループ識別子。 */
-    ParseStage SHADOW_LIST = new ParseStage();
+    public static final ParseStage SHADOW_LIST = new ParseStage();
 
 
     /**
      * 照明情報のキーフレーム番号に関する情報を通知する。
+     *
      * <p>{@link #LUMINOUS_LIST}ループの構成要素。
+     *
      * @param keyFrameNo キーフレーム番号
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdLuminousMotion(int keyFrameNo)
+    public abstract void vmdLuminousMotion(int keyFrameNo)
             throws MmdFormatException;
 
     /**
      * 光源の色情報を通知する。
+     *
      * <p>色情報はRGB色空間で記述される。
+     *
      * <p>MMDのUI上の各色成分指定0~255定義域に便宜上256を追加したものが、
      * 0.0以上1.0以下にマップされる。
      * <ul>
@@ -47,49 +52,62 @@ public interface VmdLightingHandler extends LoopHandler {
      * <li>128は正しく0.5にマップされる。
      * <li>255は1.0より少しだけ小さい数にマップされる。
      * </ul>
+     *
      * <p>{@link #LUMINOUS_LIST}ループの構成要素。
+     *
      * @param rVal 赤成分(0.0以上1.0以下)
      * @param gVal 緑成分(0.0以上1.0以下)
      * @param bVal 青成分(0.0以上1.0以下)
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdLuminousColor(float rVal, float gVal, float bVal)
+    public abstract void vmdLuminousColor(float rVal, float gVal, float bVal)
             throws MmdFormatException;
 
     /**
      * 光源の方向情報を通知する。
+     *
      * <p>照明方向は、
      * ワールド座標原点から伸びる方向ベクトルとして記述される。
      * この方向ベクトルに向けて、無限遠の光源から照明が当たる。
+     *
      * <p>MMDのスライダUI上では各軸成分の定義域は-1.0以上+1.0以下だが、
      * さらに絶対値の大きな値を指定することも可能。
+     *
      * <p>方向ベクトルの長さは演出上の意味を持たないが、
      * キーフレーム間の照明方向の補間に影響を及ぼすかもしれない。
+     *
      * <p>方向ベクトルが零ベクトル(0,0,0)の場合、全ポリゴンに影が落ちる。
+     *
      * <p>{@link #LUMINOUS_LIST}ループの構成要素。
+     *
      * @param xVec 方向ベクトルX軸成分
      * @param yVec 方向ベクトルY軸成分
      * @param zVec 方向ベクトルZ軸成分
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdLuminousDirection(float xVec, float yVec, float zVec)
+    public abstract void vmdLuminousDirection(
+            float xVec, float yVec, float zVec)
             throws MmdFormatException;
 
     /**
      * シャドウ演出情報のキーフレーム番号に関する情報を通知する。
+     *
      * <p>{@link #SHADOW_LIST}ループの構成要素。
+     *
      * @param keyFrameNo キーフレーム番号
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdShadowMotion(int keyFrameNo)
+    public abstract void vmdShadowMotion(int keyFrameNo)
             throws MmdFormatException;
 
     /**
      * セルフシャドウモードを通知する。
+     *
      * <p>{@link #SHADOW_LIST}ループの構成要素。
+     *
      * @param shadowMode シャドウモード指定。
      * <ul>
      * <li>0 : シャドウOFF
@@ -97,24 +115,27 @@ public interface VmdLightingHandler extends LoopHandler {
      * <li>2 : mode2 影描画の質をカメラからの距離に応じて劣化させる
      * ことにより、カメラに近いオブジェクトの影描画の質を向上させる。
      * </ul>
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdShadowMode(byte shadowMode)
+    public abstract void vmdShadowMode(byte shadowMode)
             throws MmdFormatException;
 
     /**
      * セルフシャドウの描画対象となるオブジェクトの範囲(カメラからの距離)
      * を通知する。
+     *
      * <p>通知されるのは幾何的な距離ではない。
      * MMDのUI値(カメラからの距離の100倍?)を
      * 10万で割った商を0.1から引いた値が通知される。
+     *
      * <p>{@link #SHADOW_LIST}ループの構成要素。
+     *
      * @param shadowScope 距離情報。
-     * @throws MmdFormatException 不正フォーマットによる
-     * パース処理の中断をパーサに指示
+     * @throws MmdFormatException
+     *     不正フォーマットによるパース処理の中断をパーサに指示
      */
-    void vmdShadowScopeRaw(float shadowScope)
+    public abstract void vmdShadowScopeRaw(float shadowScope)
             throws MmdFormatException;
 
 }
index 49a51d9..957579b 100644 (file)
@@ -15,6 +15,7 @@ import jp.sfjp.mikutoga.bin.parser.ProxyParser;
 /**
  * VMDモーションファイルのライティング情報パーサ。
  * 照明光源演出データと影演出データを含む。
+ *
  * <p>古い版のVMDファイルには影演出データが記述されていない場合がある。
  */
 class VmdLightingParser extends ProxyParser {
@@ -48,7 +49,9 @@ class VmdLightingParser extends ProxyParser {
 
     /**
      * ライティングデータのパースと通知。
+     *
      * <p>影演出データが無ければ読みに行かない。
+     *
      * @throws IOException IOエラー
      * @throws MmdFormatException フォーマットエラー
      */
index 14bdc5d..110b828 100644 (file)
@@ -106,9 +106,12 @@ public class VmdParser {
     /**
      * ボーンモーション補間情報冗長部のチェックを行うか否か設定する。
      * デフォルトではチェックを行わない。
+     *
      * <p>※MMDVer7.30前後のVMD出力不具合を回避したい場合は、
      * オフにするとパースに成功する場合がある。
+     *
      * <p>※MMD Ver7.39x64以降はチェック回避必須。
+     *
      * @param mode チェックさせたければtrue
      */
     public void setRedundantCheck(boolean mode){
index fb80155..661e01a 100644 (file)
@@ -19,7 +19,7 @@ public interface VmdUnifiedHandler
             VmdBoolHandler {
 
     /** 何もしない統合ハンドラ。 */
-    VmdUnifiedHandler EMPTY =
+    public static final VmdUnifiedHandler EMPTY =
             (VmdUnifiedHandler)
             ( EmptyProxyFactory.buildEmptyProxy(VmdUnifiedHandler.class) );
 
index 79a9c01..f63a4e8 100644 (file)
@@ -7,6 +7,7 @@
 
 /**
  * VMDモーションファイル(*.vmd)用パーサライブラリ。
+ *
  * <p>コールバックインタフェースを実装したオブジェクトをパーサに渡し、
  * VMDモーションファイルのパースを開始すると、
  * 各種データの出現に応じてコールバックメソッドを次々と呼び出してくれる。
index a6c1c0e..4bbf4ad 100644 (file)
@@ -64,7 +64,9 @@ abstract class AbstractXmlExporter implements XmlExporter{
 
     /**
      * ASCIIコード相当(UCS:Basic-Latin)の文字か否か判定する。
+     *
      * <p>※ Basic-Latinには各種制御文字も含まれる。
+     *
      * @param ch 判定対象文字
      * @return Basic-Latin文字ならtrue
      * <a href="http://www.unicode.org/charts/PDF/U0000.pdf">
@@ -377,14 +379,10 @@ abstract class AbstractXmlExporter implements XmlExporter{
         case CH_GT: escTxt = "&gt;";   break;
         case CH_DQ: escTxt = "&quot;"; break;
         case CH_SQ: escTxt = "&apos;"; break;
-        default:    escTxt = null;     break;
+        default:    return putRawCh(ch);
         }
 
-        if(escTxt != null){
-            putRawText(escTxt);
-        }else{
-            putRawCh(ch);
-        }
+        putRawText(escTxt);
 
         return this;
     }
index 000c43e..1b45fa8 100644 (file)
@@ -22,6 +22,11 @@ package jp.sfjp.mikutoga.xml;
  */
 public final class DatatypeIo {
 
+    private static final String XSD_POS_INF = "INF";
+    private static final String XSD_NEG_INF = "-INF";
+    private static final String JAVA_INF = "Infinity";
+
+
     /**
      * Hidden constructor.
      */
@@ -53,9 +58,9 @@ public final class DatatypeIo {
         String result;
 
         if(fVal == Float.POSITIVE_INFINITY){
-            result = "INF";
+            result = XSD_POS_INF;
         }else if(fVal == Float.NEGATIVE_INFINITY){
-            result = "-INF";
+            result = XSD_NEG_INF;
         }else{
             result = String.valueOf(fVal);
         }
@@ -202,11 +207,11 @@ public final class DatatypeIo {
         String trimmed = xsdTrim(xsdVal).toString();
 
         float result;
-        if("INF".equals(trimmed)){
+        if(XSD_POS_INF.equals(trimmed)){
             result = Float.POSITIVE_INFINITY;
-        }else if("-INF".equals(trimmed)){
+        }else if(XSD_NEG_INF.equals(trimmed)){
             result = Float.NEGATIVE_INFINITY;
-        }else if(trimmed.endsWith("Infinity")){
+        }else if(trimmed.endsWith(JAVA_INF)){
             throw new NumberFormatException(trimmed);
         }else if(trimmed.contains("x") || trimmed.contains("X")){
             // HexFloatingPointLiteral
diff --git a/src/main/java/jp/sfjp/mikutoga/xml/DomNsUtils.java b/src/main/java/jp/sfjp/mikutoga/xml/DomNsUtils.java
deleted file mode 100644 (file)
index 0bda046..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * XML DOM utilities with namespace
- *
- * License : The MIT License
- * Copyright(c) 2011 MikuToga Partners
- */
-
-package jp.sfjp.mikutoga.xml;
-
-import java.text.MessageFormat;
-import java.util.Iterator;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * DOMユーティリティ(名前空間対応)。
- * <p>各種名前空間引数にnullが渡された場合、全ての名前空間にマッチする。
- * <p>各種ローカル名引数にnullが渡された場合、全てのローカル名にマッチする。
- * <p>ノードの持つ名前空間がnullの場合、全ての名前空間引数にマッチする。
- */
-public final class DomNsUtils {
-
-    private static final String ERRMSG_NOELEM =
-            "Elem:[{0}] was not found in Elem:[{1}]";
-    private static final String ERRMSG_NOATTR =
-            "Attr:[{0}] was not found in Elem:[{1}]";
-    private static final String ERRMSG_INVATTR =
-            "Invalid attribute form Attr[{0}] Value[{1}]";
-
-
-    /**
-     * 隠しコンストラクタ。
-     */
-    private DomNsUtils(){
-        assert false;
-        throw new AssertionError();
-    }
-
-
-    /**
-     * 名前空間とローカル名が一致するノードか判定する。
-     * @param node ノード
-     * @param nsuri 名前空間URI
-     * @param localName ローカル名。
-     * @return ノードの名前空間およびローカル名が一致したらtrue
-     */
-    public static boolean hasNsLocalNameNode(Node node,
-                                                String nsuri,
-                                                String localName ){
-        String nodeLocalName = node.getLocalName();
-        String nodeNsUri     = node.getNamespaceURI();
-
-        if(localName != null){
-            if( ! localName.equals(nodeLocalName) ) return false;
-        }
-
-        if(nsuri != null && nodeNsUri != null){
-            if( ! nsuri.equals(nodeNsUri) ) return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 名前空間とローカル名が一致する要素か判定する。
-     * @param node ノード
-     * @param nsuri 名前空間URI
-     * @param localName ローカル名。
-     * @return 名前空間およびローカル名が一致する要素であればtrue
-     */
-    public static boolean hasNsLocalNameElem(Node node,
-                                             String nsuri,
-                                             String localName ){
-        if(node.getNodeType() != Node.ELEMENT_NODE) return false;
-        if( ! hasNsLocalNameNode(node, nsuri, localName) ) return false;
-        return true;
-    }
-
-    /**
-     * 親要素が指定された名前の子要素を持つか判定する。
-     * @param parent 親要素
-     * @param nsuri 名前空間URI
-     * @param localName ローカル名
-     * @return 指定名の子要素が存在すればtrue
-     */
-    public static boolean hasChild(Element parent,
-                                    String nsuri,
-                                    String localName ){
-        for(Node node = parent.getFirstChild();
-            node != null;
-            node = node.getNextSibling() ){
-
-            if(hasNsLocalNameElem(node, nsuri, localName)){
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * 指定された名前空間とローカル名に合致する最初の直下子要素を返す。
-     * @param parent 親要素
-     * @param nsuri 名前空間URI
-     * @param localName ローカル名
-     * @return 最初の直下子要素。見つからなければnull。
-     */
-    public static Element pickFirstChild(Node parent,
-                                         String nsuri,
-                                         String localName ){
-        Node node = parent.getFirstChild();
-        while(node != null){
-            if(hasNsLocalNameElem(node, nsuri, localName)){
-                break;
-            }
-            node = node.getNextSibling();
-        }
-        return (Element) node;
-    }
-
-    /**
-     * 指定された名前空間とローカル名に合致する最初の直下子要素を返す。
-     * <p>見つからなければ例外を投げる。
-     * @param parent 親要素
-     * @param nsuri 名前空間URI
-     * @param localName ローカル名
-     * @return 最初の直下子要素。
-     * @throws TogaXmlException 1つも見つからなかった
-     */
-    public static Element getFirstChild(Element parent,
-                                        String nsuri,
-                                        String localName )
-            throws TogaXmlException{
-        Element elem = pickFirstChild(parent, nsuri, localName);
-
-        if(elem == null){
-            String message = MessageFormat.format(ERRMSG_NOELEM,
-                                                  localName,
-                                                  parent.getLocalName() );
-            throw new TogaXmlException(message);
-        }
-
-        return elem;
-    }
-
-    /**
-     * 指定された名前の子要素のforeachを返す。
-     * @param parent 親要素
-     * @param nsuri 名前空間URI
-     * @param localName 子要素名
-     * @return 子要素のforeach
-     */
-    public static Iterable<Element> getEachChild(final Element parent,
-                                                 final String nsuri,
-                                                 final String localName ){
-        Iterable<Element> result = new Iterable<Element>(){
-            @Override
-            public Iterator<Element> iterator(){
-                return new SiblingElemIterator(parent, nsuri, localName);
-            }
-        };
-        return result;
-    }
-
-    /**
-     * 要素に属性が存在するか判定する。
-     * @param elem 要素
-     * @param nsuri 名前空間URI
-     * @param localName ローカル名
-     * @return 存在するならtrue
-     */
-    public static boolean hasAttrNS(Element elem,
-                                    String nsuri,
-                                    String localName ){
-        return elem.hasAttributeNS(nsuri, localName);
-    }
-
-    /**
-     * 要素からxsd:string型属性値を読み取る。
-     * @param elem 要素
-     * @param nsuri 名前空間URI
-     * @param localName 属性名
-     * @return 文字列
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static String getStringAttrNS(Element elem,
-                                         String nsuri,
-                                         String localName )
-            throws TogaXmlException{
-        if( ! hasAttrNS(elem, nsuri, localName) ){
-            String message = MessageFormat.format(ERRMSG_NOATTR,
-                                                  localName,
-                                                  elem.getLocalName() );
-            throw new TogaXmlException(message);
-        }
-
-        String result;
-        try{
-            result = elem.getAttributeNS(nsuri, localName);
-        }catch(DOMException e){
-            assert false;
-            throw new AssertionError(e);
-        }
-
-        return result;
-    }
-
-    /**
-     * 要素からxsd:boolean型属性値を読み取る。
-     * @param elem 要素
-     * @param nsuri 名前空間URI
-     * @param localName 属性名
-     * @return 真ならtrue
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static boolean getBooleanAttrNS(Element elem,
-                                           String nsuri,
-                                           String localName )
-            throws TogaXmlException{
-        String value = getStringAttrNS(elem, nsuri, localName);
-
-        boolean result;
-        try{
-            result = DatatypeIo.parseBoolean(value);
-        }catch(IllegalArgumentException e){
-            String message = MessageFormat.format(ERRMSG_INVATTR,
-                                                  localName,
-                                                  value );
-            throw new TogaXmlException(message, e);
-        }
-
-        return result;
-    }
-
-    /**
-     * 要素からxsd:integer型属性値を読み取る。
-     * @param elem 要素
-     * @param nsuri 名前空間URI
-     * @param localName 属性名
-     * @return int値
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static int getIntegerAttrNS(Element elem,
-                                       String nsuri,
-                                       String localName )
-            throws TogaXmlException{
-        String value = getStringAttrNS(elem, nsuri, localName);
-
-        int result;
-        try{
-            result = DatatypeIo.parseInt(value);
-        }catch(NumberFormatException e){
-            String message = MessageFormat.format(ERRMSG_INVATTR,
-                                                  localName,
-                                                  value );
-            throw new TogaXmlException(message, e);
-        }
-
-        return result;
-    }
-
-    /**
-     * 要素からxsd:float型属性値を読み取る。
-     * @param elem 要素
-     * @param nsuri 名前空間URI
-     * @param localName 属性名
-     * @return float値
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static float getFloatAttrNS(Element elem,
-                                       String nsuri,
-                                       String localName )
-            throws TogaXmlException{
-        String value = getStringAttrNS(elem, nsuri, localName);
-
-        float result;
-        try{
-            result = DatatypeIo.parseFloat(value);
-        }catch(NumberFormatException e){
-            String message = MessageFormat.format(ERRMSG_INVATTR,
-                                                  localName,
-                                                  value );
-            throw new TogaXmlException(message, e);
-        }
-
-        return result;
-    }
-
-}
diff --git a/src/main/java/jp/sfjp/mikutoga/xml/DomUtils.java b/src/main/java/jp/sfjp/mikutoga/xml/DomUtils.java
deleted file mode 100644 (file)
index 465c3f5..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * XML DOM utilities
- *
- * License : The MIT License
- * Copyright(c) 2010 MikuToga Partners
- */
-
-package jp.sfjp.mikutoga.xml;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.NoSuchElementException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * DOMユーティリティ。
- */
-public final class DomUtils {
-
-    // 構文解析バグ回避。
-    private static final char BS_CHAR = (char) 0x005c;
-
-    /**
-     * 隠しコンストラクタ。
-     */
-    private DomUtils(){
-        super();
-        assert false;
-        throw new AssertionError();
-    }
-
-    /**
-     * 要素からxsd:string型属性値を読み取る。
-     * @param elem 要素
-     * @param attrName 属性名
-     * @return 文字列
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static String getStringAttr(Element elem, String attrName)
-            throws TogaXmlException{
-        if( ! elem.hasAttribute(attrName) ){
-            String message = "Attr:[" + attrName + "] "
-                    + "was not found in "
-                    + "Elem:[" + elem.getTagName()+"]";
-            throw new TogaXmlException(message);
-        }
-
-        String result;
-        try{
-            result = elem.getAttribute(attrName);
-        }catch(IllegalArgumentException e){
-            String message = "Invalid attribute form [" + attrName + "]";
-            throw new TogaXmlException(message, e);
-        }
-
-        return result;
-    }
-
-    /**
-     * 要素からxsd:boolean型属性値を読み取る。
-     * @param elem 要素
-     * @param attrName 属性名
-     * @return 真ならtrue
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static boolean getBooleanAttr(Element elem, String attrName)
-            throws TogaXmlException{
-        String value = getStringAttr(elem, attrName);
-
-        boolean result;
-        try{
-            result = DatatypeIo.parseBoolean(value);
-        }catch(IllegalArgumentException e){
-            String message =
-                    "Invalid boolean attribute form "
-                    + "[" + attrName + "][" + value + "]";
-            throw new TogaXmlException(message, e);
-        }
-
-        return result;
-    }
-
-    /**
-     * 要素からxsd:integer型属性値を読み取る。
-     * @param elem 要素
-     * @param attrName 属性名
-     * @return int値
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static int getIntegerAttr(Element elem, String attrName)
-            throws TogaXmlException{
-        String value = getStringAttr(elem, attrName);
-
-        int result;
-        try{
-            result = DatatypeIo.parseInt(value);
-        }catch(IllegalArgumentException e){
-            String message =
-                    "Invalid integer attribute form "
-                    + "[" + attrName + "][" + value + "]";
-            throw new TogaXmlException(message, e);
-        }
-
-        return result;
-    }
-
-    /**
-     * 要素からxsd:float型属性値を読み取る。
-     * @param elem 要素
-     * @param attrName 属性名
-     * @return float値
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static float getFloatAttr(Element elem, String attrName)
-            throws TogaXmlException{
-        String value = getStringAttr(elem, attrName);
-
-        float result;
-        try{
-            result = DatatypeIo.parseFloat(value);
-        }catch(IllegalArgumentException e){
-            String message =
-                    "Invalid float attribute form "
-                    + "[" + attrName + "][" + value + "]";
-            throw new TogaXmlException(message, e);
-        }
-
-        return result;
-    }
-
-    /**
-     * 要素から日本語Windows用ファイル名を属性値として読み取る。
-     * 念のため文字U+00A5は文字U-005Cに変換される。
-     * @param elem 要素
-     * @param attrName 属性名
-     * @return ファイル名
-     * @throws TogaXmlException 属性値が見つからなかった。
-     */
-    public static String getSjisFileNameAttr(Element elem, String attrName)
-            throws TogaXmlException{
-        String result;
-        try{
-            result = getStringAttr(elem, attrName);
-        }catch(IllegalArgumentException e){
-            String message =
-                    "Invalid winfile attribute form "
-                    + "[" + attrName + "]";
-            throw new TogaXmlException(message, e);
-        }
-
-        result = result.replace("" + '\u00a5', "" + BS_CHAR);
-
-        return result;
-    }
-
-    /**
-     * 指定された名前の子要素を1つだけ返す。
-     * @param parent 親要素
-     * @param tagName 子要素名
-     * @return 子要素
-     * @throws TogaXmlException 1つも見つからなかった
-     */
-    public static Element getChild(Element parent, String tagName)
-            throws TogaXmlException{
-        Element result = null;
-
-        for(Node node = parent.getFirstChild();
-            node != null;
-            node = node.getNextSibling() ){
-
-            if(node.getNodeType() != Node.ELEMENT_NODE) continue;
-            Element elem = (Element) node;
-
-            String elemTagName = elem.getTagName();
-            if( tagName.equals(elemTagName) ){
-                result = elem;
-                break;
-            }
-        }
-
-        if(result == null){
-            String message =
-                    "Elem:[" + tagName + "] was not found in "
-                    +"Elem:[" + parent.getTagName() + "]";
-            throw new TogaXmlException(message);
-        }
-
-        return result;
-    }
-
-    /**
-     * 親要素が指定された名前の子要素を持つか判定する。
-     * @param parent 親要素
-     * @param tagName 子要素名
-     * @return 指定名の子要素が存在すればtrue
-     */
-    public static boolean hasChild(Element parent, String tagName){
-        for(Node node = parent.getFirstChild();
-            node != null;
-            node = node.getNextSibling() ){
-
-            if(node.getNodeType() != Node.ELEMENT_NODE) continue;
-            Element elem = (Element) node;
-
-            String elemTagName = elem.getTagName();
-            if( tagName.equals(elemTagName) ) return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 指定された名前の子要素のリストを返す。
-     * @param parent 親要素
-     * @param childTag 子要素名
-     * @return 子要素のリスト
-     */
-    public static List<Element> getChildList(Element parent,
-                                               String childTag){
-        List<Element> result = new LinkedList<Element>();
-
-        for(Node node = parent.getFirstChild();
-            node != null;
-            node = node.getNextSibling() ){
-
-            if(node.getNodeType() != Node.ELEMENT_NODE) continue;
-            Element elem = (Element) node;
-
-            String tagName = elem.getTagName();
-            if( ! childTag.equals(tagName) ) continue;
-
-            result.add(elem);
-        }
-
-        return result;
-    }
-
-    /**
-     * 指定された名前の子要素の列挙子を返す。
-     * @param parent 親要素
-     * @param childTag 子要素名
-     * @return 子要素の列挙子
-     */
-    public static Iterator<Element> getChildIterator(Element parent,
-                                                       String childTag){
-        Element firstElem;
-        try{
-            firstElem = getChild(parent, childTag);
-        }catch(TogaXmlException e){
-            firstElem = null;
-        }
-
-        Iterator<Element> result = new ElemIterator(firstElem);
-
-        return result;
-    }
-
-    /**
-     * 指定された名前の子要素のforeachを返す。
-     * @param parent 親要素
-     * @param childTag 子要素名
-     * @return 子要素のforeach
-     */
-    public static Iterable<Element> getEachChild(Element parent,
-                                                   String childTag){
-        final Iterator<Element> iterator = getChildIterator(parent, childTag);
-        Iterable<Element> result = new Iterable<Element>(){
-            @Override
-            public Iterator<Element> iterator(){
-                return iterator;
-            }
-        };
-        return result;
-    }
-
-    /**
-     * 要素の次の要素を返す。
-     * @param elem 要素
-     * @return 次の要素。なければnull
-     */
-    public static Element nextElement(Element elem){
-        Node nextNode = elem;
-        for(;;){
-            nextNode = nextNode.getNextSibling();
-            if(nextNode == null) break;
-            if(nextNode.getNodeType() == Node.ELEMENT_NODE){
-                break;
-            }
-        }
-
-        return (Element) nextNode;
-    }
-
-    /**
-     * 同じ要素名を持つ次の要素を返す。
-     * @param elem 要素
-     * @return 次の要素。なければnull
-     */
-    public static Element nextNamedElement(Element elem){
-        String tagName = elem.getTagName();
-        Element nextElem = elem;
-        for(;;){
-            nextElem = nextElement(nextElem);
-            if(nextElem == null) break;
-            if(tagName.equals(nextElem.getTagName())) break;
-        }
-
-        return nextElem;
-    }
-
-    /**
-     * 同じ親要素と同じ要素名を持つ兄弟要素を列挙する列挙子。
-     */
-    private static final class ElemIterator implements Iterator<Element> {
-        private Element next;
-
-        /**
-         * コンストラクタ。
-         * @param elem 最初の要素。nullを指定すれば空列挙子となる。
-         */
-        ElemIterator(Element elem){
-            super();
-            this.next = elem;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public boolean hasNext(){
-            if(this.next == null) return false;
-            return true;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         * @throws NoSuchElementException {@inheritDoc}
-         */
-        @Override
-        public Element next() throws NoSuchElementException{
-            if(this.next == null) throw new NoSuchElementException();
-            Element result = this.next;
-            this.next = nextNamedElement(this.next);
-            return result;
-        }
-
-        /**
-         * {@inheritDoc}
-         * ※ 未サポート。
-         */
-        @Override
-        public void remove(){
-            throw new UnsupportedOperationException();
-        }
-
-    }
-
-}
diff --git a/src/main/java/jp/sfjp/mikutoga/xml/LocalXmlResource.java b/src/main/java/jp/sfjp/mikutoga/xml/LocalXmlResource.java
deleted file mode 100644 (file)
index bacab5f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * xml local resource map
- *
- * License : The MIT License
- * Copyright(c) 2013 olyutorskii
- */
-
-package jp.sfjp.mikutoga.xml;
-
-import java.net.URI;
-
-/**
- * 代用ローカルリソースの管理を行う。
- * <p>ネットワークを介したグローバルなリソースと、
- * アプリ上のローカルな代用リソースとを対応付ける。
- */
-public interface LocalXmlResource {
-
-    /**
-     * オリジナル版XMLリソースのURIを返す。
-     * @return オリジナル版リソースのURL。
-     */
-    URI getOriginalResource();
-
-    /**
-     * ローカル版XMLリソースのURIを返す。
-     * @return ローカル版リソースのURL。
-     */
-    URI getLocalResource();
-
-}
diff --git a/src/main/java/jp/sfjp/mikutoga/xml/NoopEntityResolver.java b/src/main/java/jp/sfjp/mikutoga/xml/NoopEntityResolver.java
new file mode 100644 (file)
index 0000000..7048e0e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * No-operation Entity Resolver for XML.
+ *
+ * License : The MIT License
+ * Copyright(c) 2019 olyutorskii
+ */
+
+package jp.sfjp.mikutoga.xml;
+
+import java.io.Reader;
+import java.io.StringReader;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+/**
+ * No-operation Entity Resolver implementation for preventing XXE.
+ *
+ * @see <a href="https://en.wikipedia.org/wiki/XML_external_entity_attack">
+ *     XML external entity attack (Wikipedia)
+ *     </a>
+ */
+public final class NoopEntityResolver implements EntityResolver{
+
+    /** Singleton resolver. */
+    public static final EntityResolver NOOP_RESOLVER =
+            new NoopEntityResolver();
+
+
+    /**
+     * Constructor.
+     */
+    private NoopEntityResolver(){
+        super();
+        return;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>Prevent any external entity reference XXE.
+     *
+     * @param publicId {@inheritDoc}
+     * @param systemId {@inheritDoc}
+     * @return empty input source
+     */
+    @Override
+    public InputSource resolveEntity(String publicId, String systemId){
+        Reader emptyReader = new StringReader("");
+        InputSource source = new InputSource(emptyReader);
+
+        source.setPublicId(publicId);
+        source.setSystemId(systemId);
+
+        return source;
+    }
+
+}
index d40e628..c0f9eb2 100644 (file)
@@ -10,11 +10,9 @@ package jp.sfjp.mikutoga.xml;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.MalformedURLException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
 import javax.xml.XMLConstants;
 import javax.xml.transform.Source;
 import javax.xml.transform.stream.StreamSource;
@@ -22,14 +20,54 @@ import javax.xml.validation.Schema;
 import javax.xml.validation.SchemaFactory;
 import org.w3c.dom.ls.LSResourceResolver;
 import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
 
 /**
- * XMLスキーマの各種ビルダ。
+ * XML schema (XSD) utilities.
+ *
+ * <p>RELAX NG is not supported.
  */
 public final class SchemaUtil {
 
+
+    /** XML Schema. */
+    public static final String SCHEMA_XML =
+            "http://www.w3.org/2001/xml.xsd";
+
+    /** XSD namespace. */
+    public static final String NS_XSD =
+            "http://www.w3.org/2001/XMLSchema-instance";
+
+    private static final String LOCAL_SCHEMA_XML =
+            "resources/xmlspace.xsd";
+
+    private static final URI URI_XSD_ORIG;
+    private static final URI URI_XSD_LOCAL;
+
+    private static final String ALLOWED_USCHEMA = "http";
+
+    private static final Class<?> THISCLASS = SchemaUtil.class;
+
+
+    static{
+        URL localXsdUrl = THISCLASS.getResource(LOCAL_SCHEMA_XML);
+        URI localXsdUri;
+        try{
+            localXsdUri = localXsdUrl.toURI();
+        }catch(URISyntaxException e){
+            throw new ExceptionInInitializerError(e);
+        }
+
+        URI_XSD_ORIG  = URI.create(SCHEMA_XML);
+        URI_XSD_LOCAL = localXsdUri;
+
+        assert ALLOWED_USCHEMA.equalsIgnoreCase(URI_XSD_ORIG.getScheme());
+    }
+
+
     /**
-     * 隠しコンストラクタ。
+     * Hidden constructor.
      */
     private SchemaUtil(){
         assert false;
@@ -38,113 +76,110 @@ public final class SchemaUtil {
 
 
     /**
-     * XML Schema 用のスキーマファクトリを返す。
-     * @return スキーマファクトリ
+     * build xml.xsd redirection info.
+     *
+     * @return resolver
      */
-    public static SchemaFactory newSchemaFactory(){
-        SchemaFactory result = newSchemaFactory(null);
+    public static XmlResourceResolver buildXmlXsdResolver(){
+        XmlResourceResolver result = new XmlResourceResolver();
+        result.putRedirected(URI_XSD_ORIG, URI_XSD_LOCAL);
         return result;
     }
 
     /**
-     * XML Schema 用のスキーマファクトリを返す。
-     * @param resolver カスタムリゾルバ。nullも可。
-     * @return スキーマファクトリ
+     * Build SchemaFactory for XML Schema but safety.
+     *
+     * <p>Includes some considerations for XXE vulnerabilities.
+     *
+     * <p>Restrict access to
+     * External Entity Reference &amp; external DTDs
+     * in xml schema file.
+     *
+     * <p>Restrict access to External schema file access in xml schema file,
+     * but HTTP access is allowed.
+     * This special limit considers access to
+     * importing http://www.w3.org/2001/xml.xsd
+     * in top of common xml schema file.
+     *
+     * @return schema factory
      */
-    public static SchemaFactory newSchemaFactory(
-            LSResourceResolver resolver ){
-        SchemaFactory schemaFactory =
-                SchemaFactory.newInstance(
-                    XMLConstants.W3C_XML_SCHEMA_NS_URI
-                );
-
-//      schemaFactory.setFeature(name, value);
-//      schemaFactory.setProperty(name, object);
+    public static SchemaFactory newSchemaFactory(){
+        SchemaFactory schemaFactory;
+        schemaFactory = SchemaFactory.newInstance(
+                XMLConstants.W3C_XML_SCHEMA_NS_URI);
 
-        schemaFactory.setErrorHandler(BotherHandler.HANDLER);
-        schemaFactory.setResourceResolver(resolver);
+        try{
+            // Prevent denial-of-service attack.
+            schemaFactory.setFeature(
+                    XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        }catch(SAXNotRecognizedException | SAXNotSupportedException e){
+            // THIS FEATURE MUST BE SUPPORTED
+            assert false;
+        }
 
-        return schemaFactory;
-    }
+        try{
+            // Disallow external entity reference & external DTD access.
+            schemaFactory.setProperty(
+                    XMLConstants.ACCESS_EXTERNAL_DTD, "");
+            // Allow only HTTP external schema file.
+            schemaFactory.setProperty(
+                    XMLConstants.ACCESS_EXTERNAL_SCHEMA, ALLOWED_USCHEMA);
+        }catch(SAXNotRecognizedException | SAXNotSupportedException e){
+            // THIS PROPERTY MUST BE SUPPORTED JAXP1.5 or later
+            assert false;
+        }
 
-    /**
-     * ローカルリソースをSourceに変換する。
-     * @param resource ローカルリソース
-     * @return XML Source
-     * @throws MalformedURLException 不正なURI
-     * @throws IOException オープンエラー
-     */
-    private static Source toLocalSource(LocalXmlResource resource)
-            throws MalformedURLException, IOException{
-        URI localUri = resource.getLocalResource();
-        URL localUrl = localUri.toURL();
+        LSResourceResolver resolver = buildXmlXsdResolver();
+        schemaFactory.setResourceResolver(resolver);
 
-        InputStream is = localUrl.openStream();
-        is = new BufferedInputStream(is);
+        schemaFactory.setErrorHandler(BotherHandler.HANDLER);
 
-        Source result = new StreamSource(is);
-        return result;
+        return schemaFactory;
     }
 
     /**
-     * ローカルリソース群をSource群に変換する。
-     * @param resArray ローカルリソースURI並び
-     * @return XML Source並び
-     * @throws MalformedURLException 不正なURI
-     * @throws IOException オープンエラー
+     * pre-load &amp; pre-compile local schema files.
+     *
+     * @param localSchemaUris local schema resources.
+     * @return schema
+     * @throws SAXException invalid schema definition
+     * @throws IOException local resource i/o error
      */
-    private static Source[] toLocalSourceArray(LocalXmlResource[] resArray)
-            throws MalformedURLException, IOException{
-        List<Source> sourceList = new ArrayList<Source>(resArray.length);
-
-        for(LocalXmlResource resource : resArray){
-            Source localSource = toLocalSource(resource);
-            sourceList.add(localSource);
+    public static Schema newSchema(URI... localSchemaUris)
+            throws SAXException, IOException{
+        SchemaFactory schemaFactory = newSchemaFactory();
+
+        int uris = localSchemaUris.length;
+        if(uris <= 0){
+            // on-demand xml-schema with schemaLocation attribute.
+            return schemaFactory.newSchema();
         }
 
-        Source[] result = new Source[sourceList.size()];
-        result = sourceList.toArray(result);
-        return result;
-    }
-
-    /**
-     * ローカルスキーマをロードする。
-     * <p>任意のリゾルバを指定可能
-     * @param resolver リゾルバ
-     * @param resArray ローカルスキーマ情報並び
-     * @return スキーマ
-     */
-    public static Schema newSchema(XmlResourceResolver resolver,
-                                    LocalXmlResource... resArray ){
-        for(LocalXmlResource resource : resArray){
-            resolver.putRedirected(resource);
+        InputStream[] iss = new InputStream[uris];
+        for(int idx = 0; idx < uris; idx++){
+            URI localUri = localSchemaUris[idx];
+            URL localUrl = localUri.toURL();
+            InputStream is;
+            is = localUrl.openStream();
+            is = new BufferedInputStream(is);
+            iss[idx] = is;
         }
 
-        Source[] sources;
-        try{
-            sources = toLocalSourceArray(resArray);
-        }catch(IOException e){                   // ビルド障害
-            assert false;
-            throw new AssertionError(e);
+        Source[] sources = new Source[uris];
+        for(int idx = 0; idx < uris; idx++){
+            InputStream is = iss[idx];
+            sources[idx] = new StreamSource(is);
         }
 
-        SchemaFactory schemaFactory = newSchemaFactory(resolver);
-
         Schema result;
         try{
-            if(sources.length <= 0){
-                // ドキュメント埋め込みスキーマURLにリゾルバ経由でアクセス
-                result = schemaFactory.newSchema();
-            }else{
-                result = schemaFactory.newSchema(sources);
+            result = schemaFactory.newSchema(sources);
+        }finally{
+            for(InputStream is : iss){
+                is.close();
             }
-        }catch(SAXException e){   // Build error
-            assert false;
-            throw new AssertionError(e);
         }
 
-        // TODO: Sourceを閉めるのは誰の責務?
-
         return result;
     }
 
diff --git a/src/main/java/jp/sfjp/mikutoga/xml/SiblingElemIterator.java b/src/main/java/jp/sfjp/mikutoga/xml/SiblingElemIterator.java
deleted file mode 100644 (file)
index 51bd806..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * sibling element iterator on DOM tree
- *
- * License : The MIT License
- * Copyright(c) 2011 MikuToga Partners
- */
-
-package jp.sfjp.mikutoga.xml;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * 兄弟要素間用Iterator。
- * <p>同じ親と名前空間とローカル名を持つ要素同士を「兄弟要素」とする。
- * <p>ノードの持つ名前空間がnullの場合、全ての名前空間引数にマッチする。
- * <p>削除操作は未サポート。
- */
-public class SiblingElemIterator implements Iterator<Element> {
-
-    private Element next;
-    private final String nsuri;
-    private final String localName;
-
-
-    /**
-     * コンストラクタ。
-     * @param first 最初の兄弟要素。nullだと一度もiterateしない。
-     */
-    public SiblingElemIterator(Element first){
-        super();
-
-        this.next = first;
-
-        if(this.next == null){
-            this.nsuri     = null;
-            this.localName = null;
-        }else{
-            this.nsuri     = this.next.getNamespaceURI();
-            this.localName = this.next.getLocalName();
-        }
-
-        return;
-    }
-
-    /**
-     * コンストラクタ。
-     * <p>名前空間引数にnullが渡された場合、全ての名前空間にマッチする。
-     * <p>ローカル名引数にnullが渡された場合、全てのローカル名にマッチする。
-     * @param parent 親要素
-     * @param nsuri 子要素の名前空間URI
-     * @param localName 子要素のローカル名
-     */
-    public SiblingElemIterator(Element parent,
-                               String nsuri,
-                               String localName ){
-        super();
-
-        this.next = DomNsUtils.pickFirstChild(parent, nsuri, localName);
-
-        if(this.next == null){
-            this.nsuri     = null;
-            this.localName = null;
-        }else{
-            this.nsuri     = nsuri;
-            this.localName = localName;
-        }
-
-        return;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     * @return {@inheritDoc}
-     */
-    @Override
-    public boolean hasNext(){
-        if(this.next != null) return true;
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @return {@inheritDoc}
-     * @throws NoSuchElementException {@inheritDoc}
-     */
-    @Override
-    public Element next() throws NoSuchElementException {
-        if(this.next == null) throw new NoSuchElementException();
-
-        Element result = this.next;
-
-        Node sibNode = result;
-        do{
-            sibNode = sibNode.getNextSibling();
-            if(sibNode == null) break;
-        }while( ! matchElemName(sibNode) );
-        this.next = (Element) sibNode;
-
-        return result;
-    }
-
-    /**
-     * 兄弟要素にふさわしい名前を持つか判定する。
-     * @param node 判定対象
-     * @return 兄弟にふさわしい名前を持つならtrue
-     */
-    private boolean matchElemName(Node node){
-        return DomNsUtils.hasNsLocalNameElem(node,
-                                             this.nsuri, this.localName );
-    }
-
-    /**
-     * {@inheritDoc}
-     * ※削除不可。
-     * @throws UnsupportedOperationException 削除を試みたので失敗した
-     */
-    @Override
-    public void remove() throws UnsupportedOperationException {
-        throw new UnsupportedOperationException();
-    }
-
-}
index fe52571..ae11217 100644 (file)
@@ -22,7 +22,7 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putRawCh(char ch) throws IOException;
+    public abstract XmlExporter putRawCh(char ch) throws IOException;
 
     /**
      * 文字列を生出力する。
@@ -30,14 +30,15 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putRawText(CharSequence seq) throws IOException;
+    public abstract XmlExporter putRawText(CharSequence seq)
+            throws IOException;
 
     /**
      * 空白を出力する。
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter sp() throws IOException;
+    public abstract XmlExporter sp() throws IOException;
 
     /**
      * 空白を指定回数出力する。
@@ -45,27 +46,28 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter sp(int count) throws IOException;
+    public abstract XmlExporter sp(int count) throws IOException;
 
     /**
      * 改行文字列を返す。
      * @return 改行文字列
      */
-    String getNewLine();
+    public abstract String getNewLine();
 
     /**
      * 改行文字列を設定する。
      * @param newLine 改行文字列
      * @throws NullPointerException 引数がnull
      */
-    void setNewLine(String newLine) throws NullPointerException;
+    public abstract void setNewLine(String newLine)
+            throws NullPointerException;
 
     /**
      * 改行を出力する。
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter ln() throws IOException;
+    public abstract XmlExporter ln() throws IOException;
 
     /**
      * 改行を指定回数出力する。
@@ -73,39 +75,44 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter ln(int count) throws IOException;
+    public abstract XmlExporter ln(int count) throws IOException;
 
     /**
      * インデント単位文字列を返す。
      * @return インデント単位文字列
      */
-    String getIndentUnit();
+    public abstract String getIndentUnit();
 
     /**
      * インデント単位文字列を設定する。
+     *
      * <p>デフォルトでは空白2個。
+     *
      * @param indUnit インデント単位文字列。
      * @throws NullPointerException 引数がnull
      */
-    void setIndentUnit(String indUnit) throws NullPointerException;
+    public abstract void setIndentUnit(String indUnit)
+            throws NullPointerException;
 
     /**
      * インデントレベルを一段下げる。
      */
-    void pushNest();
+    public abstract void pushNest();
 
     /**
      * インデントレベルを一段上げる。
      * インデントレベル0の状態をさらに上げようとした場合、何も起こらない。
      */
-    void popNest();
+    public abstract void popNest();
 
     /**
      * インデントレベルを返す。
+     *
      * <p>深さ1の場合1を返す。
+     *
      * @return インデントレベル
      */
-    int getIndentLevel();
+    public abstract int getIndentLevel();
 
     /**
      * インデントを出力する。
@@ -113,28 +120,36 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter ind() throws IOException;
+    public abstract XmlExporter ind() throws IOException;
 
     /**
      * BasicLatin文字だけを出力する状態か判定する。
+     *
      * <p>コメント部中身は対象外。
+     *
      * @return BasicLatin文字だけで出力するならtrue
      */
-    boolean isBasicLatinOnlyOut();
+    public abstract boolean isBasicLatinOnlyOut();
 
     /**
      * BasicLatin文字だけで出力するか設定する。
+     *
      * <p>BasicLatin以外の文字(≒日本語)を、そのまま出力するか、
      * 文字参照で出力するか、の設定が可能。
+     *
      * <p>コメント部中身は対象外。
+     *
      * @param bool BasicLatin文字だけで出力するならtrue
      */
-    void setBasicLatinOnlyOut(boolean bool);
+    public abstract void setBasicLatinOnlyOut(boolean bool);
 
     /**
      * 指定された文字を16進2桁の文字参照形式で出力する。
+     *
      * <p>「A」は「&amp;#x41;」になる。
+     *
      * <p>2桁で出力できない場合(&gt;0x00ff)は4桁で出力する。
+     *
      * @param ch 文字
      * @return this本体
      * @throws IOException 出力エラー
@@ -142,12 +157,15 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * W3C XML1.1 Character Reference
      * </a>
      */
-    XmlExporter putCharRef2Hex(char ch) throws IOException;
+    public abstract XmlExporter putCharRef2Hex(char ch) throws IOException;
 
     /**
      * 指定された文字を16進4桁の文字参照形式で出力する。
+     *
      * <p>「亜」は「&amp;#x4E9C;」になる。
+     *
      * <p>UCS4に伴うサロゲートペアは未サポート
+     *
      * @param ch 文字
      * @return this本体
      * @throws IOException 出力エラー
@@ -155,38 +173,51 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * W3C XML1.1 Character Reference
      * </a>
      */
-    XmlExporter putCharRef4Hex(char ch) throws IOException;
+    public abstract XmlExporter putCharRef4Hex(char ch) throws IOException;
 
     /**
      * 要素の中身および属性値中身を出力する。
+     *
      * <p>XMLの構文規則を守る上で必要な各種エスケープ処理が行われる。
+     *
      * @param ch 文字
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putCh(char ch) throws IOException;
+    public abstract XmlExporter putCh(char ch) throws IOException;
 
     /**
      * 要素の中身および属性値中身を出力する。
+     *
      * <p>必要に応じてXML定義済み実体文字が割り振られた文字、
      * コントロールコード、および非BasicLatin文字がエスケープされる。
+     *
      * <p>半角円通貨記号U+00A5はバックスラッシュU+005Cに置換される。
+     *
      * <p>連続するスペースU+0020の2文字目以降は文字参照化される。
+     *
      * <p>全角スペースその他空白文字は無条件に文字参照化される。
+     *
      * @param content 内容
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putContent(CharSequence content) throws IOException;
+    public abstract XmlExporter putContent(CharSequence content)
+            throws IOException;
 
     /**
      * コメントの内容を出力する。
+     *
      * <p>コメント中の'\n'記号出現に伴い、
      * あらかじめ指定された改行文字が出力される。
+     *
      * <p>コメント中の'\n'以外のコントロールコードは
      * Control Pictures(U+2400〜)で代替される。
+     *
      * <p>それ以外の非BasicLatin文字はそのまま出力される。
+     *
      * <p>連続するハイフン(-)記号間には強制的にスペースが挿入される。
+     *
      * @param comment コメント内容
      * @return this本体
      * @throws IOException 出力エラー
@@ -194,7 +225,8 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * Unicode 6.2 Controll Pictures
      * </a>
      */
-    XmlExporter putCommentContent(CharSequence comment) throws IOException;
+    public abstract XmlExporter putCommentContent(CharSequence comment)
+            throws IOException;
 
     /**
      * 1行コメントを出力する。
@@ -203,19 +235,26 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putLineComment(CharSequence comment) throws IOException;
+    public abstract XmlExporter putLineComment(CharSequence comment)
+            throws IOException;
 
     /**
      * ブロックコメントを出力する。
+     *
      * <p>コメント内部の頭の前に改行が出力される。
+     *
      * <p>コメント内部の末尾が改行でない場合、改行が挿入される。
+     *
      * <p>ブロックコメント末尾は改行で終わる。
+     *
      * <p>インデント設定は無視される。
+     *
      * @param comment コメント内容
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putBlockComment(CharSequence comment) throws IOException;
+    public abstract XmlExporter putBlockComment(CharSequence comment)
+            throws IOException;
 
     /**
      * 開始タグ開き表記を出力する。
@@ -223,14 +262,15 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putOpenSTag(CharSequence tagName) throws IOException;
+    public abstract XmlExporter putOpenSTag(CharSequence tagName)
+            throws IOException;
 
     /**
      * 開始タグ閉じ表記を出力する。
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putCloseSTag() throws IOException;
+    public abstract XmlExporter putCloseSTag() throws IOException;
 
     /**
      * 属性の無いシンプルな開始タグ表記を出力する。
@@ -238,7 +278,8 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putSimpleSTag(CharSequence tagName) throws IOException;
+    public abstract XmlExporter putSimpleSTag(CharSequence tagName)
+            throws IOException;
 
     /**
      * 終了タグ表記を出力する。
@@ -246,7 +287,8 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putETag(CharSequence tagName) throws IOException;
+    public abstract XmlExporter putETag(CharSequence tagName)
+            throws IOException;
 
     /**
      * 属性の無い単出タグ表記を出力する。
@@ -254,14 +296,15 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putSimpleEmpty(CharSequence tagName) throws IOException;
+    public abstract XmlExporter putSimpleEmpty(CharSequence tagName)
+            throws IOException;
 
     /**
      * 単出タグ閉じ表記を出力する。
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putCloseEmpty() throws IOException;
+    public abstract XmlExporter putCloseEmpty() throws IOException;
 
     /**
      * xsd:int値をXMLスキーマ準拠の形式で出力する。
@@ -272,7 +315,7 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * XML Schema 1.1 Datatypes int
      * </a>
      */
-    XmlExporter putXsdInt(int iVal) throws IOException;
+    public abstract XmlExporter putXsdInt(int iVal) throws IOException;
 
     /**
      * xsd:float値をXMLスキーマ準拠の形式で出力する。
@@ -283,7 +326,7 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * XML Schema 1.1 Datatypes float Lexical Mapping
      * </a>
      */
-    XmlExporter putXsdFloat(float fVal) throws IOException;
+    public abstract XmlExporter putXsdFloat(float fVal) throws IOException;
 
     /**
      * int型属性値を出力する。
@@ -292,7 +335,7 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putIntAttr(CharSequence attrName, int iVal)
+    public abstract XmlExporter putIntAttr(CharSequence attrName, int iVal)
             throws IOException;
 
     /**
@@ -302,7 +345,8 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putFloatAttr(CharSequence attrName, float fVal)
+    public abstract XmlExporter putFloatAttr(
+            CharSequence attrName, float fVal)
             throws IOException;
 
     /**
@@ -312,7 +356,8 @@ public interface XmlExporter extends Appendable, Flushable, Closeable{
      * @return this本体
      * @throws IOException 出力エラー
      */
-    XmlExporter putAttr(CharSequence attrName, CharSequence content)
+    public abstract XmlExporter putAttr(
+            CharSequence attrName, CharSequence content)
             throws IOException;
 
 }
index e103268..bf5ba8e 100644 (file)
 
 package jp.sfjp.mikutoga.xml;
 
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.Reader;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
 import org.w3c.dom.ls.LSInput;
 import org.w3c.dom.ls.LSResourceResolver;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
 
 /**
- * URL変換マップに従い、XML文書からの外部参照をリダイレクトする。
- * 相対URIはこのクラスをベースに解決される。
- * 主な用途は外部スキーマのリソース化など。
+ * register &amp; redirect original URI to local resource contents.
  */
 public class XmlResourceResolver
-        implements LSResourceResolver, EntityResolver {
-
-    /** XML Schema. */
-    public static final String SCHEMA_XML =
-            "http://www.w3.org/2001/xml.xsd";
-
-    /** XSD名前空間。 */
-    public static final String NS_XSD =
-            "http://www.w3.org/2001/XMLSchema-instance";
-
-    private static final String LOCAL_SCHEMA_XML =
-            "resources/xmlspace.xsd";
+        implements LSResourceResolver{
 
     private static final URI EMPTY_URI = URI.create("");
 
-    private static final Class<?> THISCLASS = XmlResourceResolver.class;
+    private static final DOMImplementationLS DOM_LS;
 
 
     private final Map<URI, URI> uriMap;
 
 
+    static{
+        try{
+            DOM_LS = buildDomImplLS();
+        }catch(   ClassNotFoundException
+                | IllegalAccessException
+                | InstantiationException e){
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+
     /**
-     * コンストラクタ。
+     * Constructor.
      */
     public XmlResourceResolver(){
         super();
 
-        assert this.getClass().equals(THISCLASS);
-
         Map<URI, URI> map;
-        map = new HashMap<URI, URI>();
+        map = new HashMap<>();
         map = Collections.synchronizedMap(map);
         this.uriMap = map;
 
-        URL redirectRes = THISCLASS.getResource(LOCAL_SCHEMA_XML);
-        String redirectResName = redirectRes.toString();
-
-        URI originalURI = URI.create(SCHEMA_XML);
-        URI redirectURI = URI.create(redirectResName);
+        return;
+    }
 
-        putRedirectedImpl(originalURI, redirectURI);
 
-        return;
+    /**
+     * return DOMImplementationLS implement.
+     *
+     * @return DOMImplementationLS implement
+     * @throws ClassNotFoundException no class
+     * @throws InstantiationException no object
+     * @throws IllegalAccessException no grant
+     */
+    private static DOMImplementationLS buildDomImplLS() throws
+            ClassNotFoundException,
+            InstantiationException,
+            IllegalAccessException {
+        DOMImplementationRegistry domReg;
+        DOMImplementation         domImp;
+        DOMImplementationLS       domImpLs;
+
+        domReg = DOMImplementationRegistry.newInstance();
+        domImp = domReg.getDOMImplementation("LS 3.0");
+
+        Object feature = domImp.getFeature("LS", "3.0");
+        assert feature instanceof DOMImplementationLS;
+        domImpLs = (DOMImplementationLS) feature;
+
+        return domImpLs;
     }
 
+    /**
+     * return LSInput implement.
+     *
+     * @return LSInput implement
+     */
+    public static LSInput createLSInput(){
+        LSInput input = DOM_LS.createLSInput();
+        return input;
+    }
 
     /**
-     * 絶対URIと相対URIを合成したURIを返す。
-     * 正規化も行われる。
-     * @param base 絶対URIでなければならない。nullでもよい。
-     * @param relative 絶対URIでもよいがその場合baseは無視される。null可。
-     * @return 合成結果のURLオブジェクト。必ず絶対URIになる。
-     * @throws java.net.URISyntaxException URIとして変。
-     * @throws java.lang.IllegalArgumentException 絶対URIが生成できない。
+     * merge base-uri text &amp; relative URI text.
+     *
+     * @param base base URI text must be absolute or null.
+     * @param relative relative URI text.
+     *     If absolute, base is ignored.
+     *     Ignored if null.
+     * @return merged absolute URI.
+     * @throws java.net.URISyntaxException illegal URI
+     * @throws java.lang.IllegalArgumentException result is not Absolute.
      */
     protected static URI buildBaseRelativeURI(String base, String relative)
             throws URISyntaxException,
@@ -103,7 +130,22 @@ public class XmlResourceResolver
             relativeURI = EMPTY_URI;
         }
 
+        URI result = buildBaseRelativeURI(baseURI, relativeURI);
+        return result;
+    }
+
+    /**
+     * merge base-uri &amp; relative URI.
+     *
+     * @param baseURI base URI must be absolute or null.
+     * @param relativeURI relative URI. If absolute, baseURI is ignored.
+     * @return merged absolute URI.
+     * @throws java.lang.IllegalArgumentException result is not Absolute.
+     */
+    private static URI buildBaseRelativeURI(URI baseURI, URI relativeURI)
+            throws IllegalArgumentException {
         URI resultURI;
+
         if(baseURI == null || relativeURI.isAbsolute()){
             resultURI = relativeURI;
         }else{
@@ -119,23 +161,14 @@ public class XmlResourceResolver
         return resultURI;
     }
 
-    /**
-     * LSInput実装を生成する。
-     * @return LSInput実装
-     */
-    public static LSInput createLSInput(){
-        LSInput input = new LSInputImpl();
-        return input;
-    }
-
 
     /**
-     * オリジナルURIとリダイレクト先のURIを登録する。
-     * オリジナルURIへのアクセスはリダイレクトされる。
-     * @param original オリジナルURI
-     * @param redirect リダイレクトURI
+     * map original URI &amp; local resource URI.
+     *
+     * @param original original URI
+     * @param redirect local resource URI
      */
-    private void putRedirectedImpl(URI original, URI redirect){
+    public void putRedirected(URI original, URI redirect){
         URI oridinalNorm = original.normalize();
         URI redirectNorm = redirect.normalize();
 
@@ -145,34 +178,9 @@ public class XmlResourceResolver
     }
 
     /**
-     * オリジナルURIとリダイレクト先のURIを登録する。
-     * オリジナルURIへのアクセスはリダイレクトされる。
-     * @param original オリジナルURI
-     * @param redirect リダイレクトURI
-     */
-    public void putRedirected(URI original, URI redirect){
-        putRedirectedImpl(original, redirect);
-        return;
-    }
-
-    /**
-     * ローカル版リソース参照解決を登録する。
-     * @param lsc ローカル版リソース参照解決
-     */
-    public void putRedirected(LocalXmlResource lsc){
-        URI original = lsc.getOriginalResource();
-        if(original == null) return;
-
-        URI local = lsc.getLocalResource();
-
-        putRedirected(original, local);
-
-        return;
-    }
-
-    /**
-     * 別リゾルバの登録内容を追加登録する。
-     * @param other 別リゾルバ
+     * add other resolver mapping.
+     *
+     * @param other resolver
      */
     public void putRedirected(XmlResourceResolver other){
         this.uriMap.putAll(other.uriMap);
@@ -180,9 +188,10 @@ public class XmlResourceResolver
     }
 
     /**
-     * 登録済みリダイレクト先URIを返す。
-     * @param original オリジナルURI
-     * @return リダイレクト先URI。未登録の場合はnull
+     * get redirected local resource URI.
+     *
+     * @param original original URI
+     * @return mapped local resource URI. null if unmapped.
      */
     public URI getRedirected(URI original){
         URI keyURI = original.normalize();
@@ -191,66 +200,67 @@ public class XmlResourceResolver
     }
 
     /**
-     * 登録済みリダイレクト先URIを返す。
-     * @param original オリジナルURI
-     * @return リダイレクト先URI。未登録の場合はオリジナルを返す
-     */
-    public URI resolveRedirected(URI original){
-        URI result = getRedirected(original);
-        if(result == null) result = original;
-        return result;
-    }
-
-    /**
-     * 登録済みリダイレクト先リソースの入力ストリームを得る。
-     * @param originalURI オリジナルURI
-     * @return 入力ストリーム。リダイレクト先が未登録の場合はnull
-     * @throws java.io.IOException 入出力エラー。
-     * もしくはリソースが見つからない。
+     * get redirected local input stream.
+     *
+     * @param originalURI original URI
+     * @return mapped local resource input stream.
+     *     If no mapping, return zero-length data stream.
+     * @throws java.io.IOException local resource i/o error
      */
     private InputStream getXMLResourceAsStream(URI originalURI)
             throws IOException{
+        InputStream result;
+
         URI resourceURI = getRedirected(originalURI);
-        if(resourceURI == null) return null;
+        if(resourceURI == null){
+            result = new ByteArrayInputStream(new byte[0]);
+        }else{
+            URL resourceURL = resourceURI.toURL();
+            result = resourceURL.openStream();
+        }
 
-        URL resourceURL = resourceURI.toURL();
-        InputStream is = resourceURL.openStream();
+        result = new BufferedInputStream(result);
 
-        return is;
+        return result;
     }
 
     /**
      * {@inheritDoc}
-     * URL変換したあとの入力ソースを返す。
+     *
+     * <p>Return redirected local resource data.
+     *
      * @param type {@inheritDoc}
      * @param namespaceURI {@inheritDoc}
      * @param publicId {@inheritDoc}
      * @param systemId {@inheritDoc}
      * @param baseURI {@inheritDoc}
-     * @return {@inheritDoc}
+     * @return {@inheritDoc} LSInput of local resource.
+     *     If no mapping, return zero-length data.
      */
     @Override
-    public LSInput resolveResource(String type,
-                                     String namespaceURI,
-                                     String publicId,
-                                     String systemId,
-                                     String baseURI ){
+    public LSInput resolveResource(
+            String type,
+            String namespaceURI,
+            String publicId,
+            String systemId,
+            String baseURI ){
         if(systemId == null) return null;
 
         URI originalURI;
         try{
             originalURI = buildBaseRelativeURI(baseURI, systemId);
         }catch(URISyntaxException e){
-            return null;
+            assert false;
+            throw new AssertionError(e);
         }
 
         InputStream is;
         try{
             is = getXMLResourceAsStream(originalURI);
         }catch(IOException e){
-            return null;
+            assert false;
+            throw new AssertionError(e);
         }
-        if(is == null) return null;
 
         LSInput input = createLSInput();
         input.setBaseURI(baseURI);
@@ -261,212 +271,4 @@ public class XmlResourceResolver
         return input;
     }
 
-    /**
-     * {@inheritDoc}
-     * URL変換したあとの入力ソースを返す。
-     * @param publicId {@inheritDoc}
-     * @param systemId {@inheritDoc}
-     * @return {@inheritDoc}
-     * @throws org.xml.sax.SAXException {@inheritDoc}
-     * @throws java.io.IOException {@inheritDoc}
-     */
-    @Override
-    public InputSource resolveEntity(String publicId, String systemId)
-            throws SAXException, IOException{
-        if(systemId == null) return null;
-
-        URI originalUri;
-        try{
-            originalUri = new URI(systemId);
-        }catch(URISyntaxException e){
-            return null;
-        }
-
-        InputStream is = getXMLResourceAsStream(originalUri);
-        if(is == null) return null;
-
-        InputSource source = new InputSource(is);
-        source.setPublicId(publicId);
-        source.setSystemId(systemId);
-
-        return source;
-    }
-
-    /**
-     * JRE1.5用LSInput実装。
-     * JRE1.6なら
-     * org.w3c.dom.ls.DOMImplementationLS#createLSInput()
-     * で生成可能かも。
-     */
-    private static final class LSInputImpl implements LSInput {
-
-        private String baseURI = null;
-        private InputStream byteStream = null;
-        private boolean certifiedText = false;
-        private Reader characterStream = null;
-        private String encoding = null;
-        private String publicId = null;
-        private String stringData = null;
-        private String systemId = null;
-
-        /**
-         * コンストラクタ。
-         */
-        LSInputImpl(){
-            super();
-            return;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public String getBaseURI(){
-            return this.baseURI;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @param baseURI {@inheritDoc}
-         */
-        @Override
-        public void setBaseURI(String baseURI){
-            this.baseURI = baseURI;
-            return;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public InputStream getByteStream(){
-            return this.byteStream;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @param byteStream {@inheritDoc}
-         */
-        @Override
-        public void setByteStream(InputStream byteStream){
-            this.byteStream = byteStream;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public boolean getCertifiedText(){
-            return this.certifiedText;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @param certifiedText {@inheritDoc}
-         */
-        @Override
-        public void setCertifiedText(boolean certifiedText){
-            this.certifiedText = certifiedText;
-            return;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public Reader getCharacterStream(){
-            return this.characterStream;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @param characterStream {@inheritDoc}
-         */
-        @Override
-        public void setCharacterStream(Reader characterStream){
-            this.characterStream = characterStream;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public String getEncoding(){
-            return this.encoding;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @param encoding {@inheritDoc}
-         */
-        @Override
-        public void setEncoding(String encoding){
-            this.encoding = encoding;
-            return;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public String getPublicId(){
-            return this.publicId;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @param publicId {@inheritDoc}
-         */
-        @Override
-        public void setPublicId(String publicId){
-            this.publicId = publicId;
-            return;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public String getStringData(){
-            return this.stringData;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @param stringData {@inheritDoc}
-         */
-        @Override
-        public void setStringData(String stringData){
-            this.stringData = stringData;
-            return;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @return {@inheritDoc}
-         */
-        @Override
-        public String getSystemId(){
-            return this.systemId;
-        }
-
-        /**
-         * {@inheritDoc}
-         * @param systemId {@inheritDoc}
-         */
-        @Override
-        public void setSystemId(String systemId){
-            this.systemId = systemId;
-            return;
-        }
-
-    }
-
 }
index 6d5ab13..d339e96 100644 (file)
@@ -61,6 +61,18 @@ public strictfp class MkPos2DTest {
         assertEquals(3.0, pos.getXpos(), 0.0);
         assertEquals(4.0, pos.getYpos(), 0.0);
 
+        pos.setPosition(1.0, 0.0);
+        assertFalse(pos.isOriginPoint());
+
+        pos.setPosition(0.0, 1.0);
+        assertFalse(pos.isOriginPoint());
+
+        pos.setPosition(0.0, 0.0);
+        assertTrue(pos.isOriginPoint());
+
+        pos.setPosition(-0.0, -0.0);
+        assertTrue(pos.isOriginPoint());
+
         pos = new MkPos2D(5.0, 6.0);
         assertEquals(5.0, pos.getXpos(), 0.0);
         assertEquals(6.0, pos.getYpos(), 0.0);
index 92ac94b..5ac6944 100644 (file)
@@ -70,6 +70,21 @@ public strictfp class MkPos3DTest {
         assertEquals(5.0, pos.getYpos(), 0.0);
         assertEquals(6.0, pos.getZpos(), 0.0);
 
+        pos.setPosition(0.0, 0.0, 0.0);
+        assertTrue(pos.isOriginPoint());
+
+        pos.setPosition(1.0, 0.0, 0.0);
+        assertFalse(pos.isOriginPoint());
+
+        pos.setPosition(0.0, 1.0, 0.0);
+        assertFalse(pos.isOriginPoint());
+
+        pos.setPosition(0.0, 0.0, 1.0);
+        assertFalse(pos.isOriginPoint());
+
+        pos.setPosition(-0.0, -0.0, -0.0);
+        assertTrue(pos.isOriginPoint());
+
         pos = new MkPos3D(7.0, 8.0, 9.0);
         assertEquals(7.0, pos.getXpos(), 0.0);
         assertEquals(8.0, pos.getYpos(), 0.0);
index 216c3ec..235b8e7 100644 (file)
@@ -491,6 +491,15 @@ public strictfp class MkQuatTest {
         assert0UlpEquals(yRad, eu.getYRot());
         assertUlpEquals(zRad, eu.getZRot(), 1);
 
+        xRad = toRadians(90);
+        yRad = toRadians(-120);
+        zRad = toRadians(120);
+        qq.setEulerYXZ(xRad, yRad, zRad);
+        qq.toEulerYXZ(eu, yRad);
+        assert0UlpEquals(xRad, eu.getXRot());
+        assert0UlpEquals(yRad, eu.getYRot());
+        assertUlpEquals(zRad, eu.getZRot(), 1);
+
         xRad = toRadians(89.999);
         yRad = toRadians(89.999);
         zRad = toRadians(89.999);
index 61edcc4..30781e2 100644 (file)
@@ -36,6 +36,78 @@ public class BasicXmlExporterTest {
     }
 
     /**
+     * Test of putCharRef2Hex method, of class BasicXmlExporter.
+     * @throws IOException
+     */
+    @Test
+    public void testPutCharRef2Hex() throws IOException{
+        System.out.println("putCharRef2Hex");
+
+        BasicXmlExporter instance;
+        StringBuffer buf;
+
+        instance = new BasicXmlExporter();
+
+        buf = new StringBuffer();
+        instance.setAppendable(buf);
+        instance.putCharRef2Hex('\u0000');
+        assertEquals("&#x00;", buf.toString());
+
+        buf = new StringBuffer();
+        instance.setAppendable(buf);
+        instance.putCharRef2Hex('A');
+        assertEquals("&#x41;", buf.toString());
+
+        buf = new StringBuffer();
+        instance.setAppendable(buf);
+        instance.putCharRef2Hex('\u00ff');
+        assertEquals("&#xFF;", buf.toString());
+
+        buf = new StringBuffer();
+        instance.setAppendable(buf);
+        instance.putCharRef2Hex('\u0100');
+        assertEquals("&#x0100;", buf.toString());
+
+        return;
+    }
+
+    /**
+     * Test of putCh method, of class BasicXmlExporter.
+     * @throws IOException
+     */
+    @Test
+    public void testPutCh() throws IOException{
+        System.out.println("putCh");
+
+        BasicXmlExporter instance;
+        StringBuffer buf;
+
+        instance = new BasicXmlExporter();
+
+        buf = new StringBuffer();
+        instance.setAppendable(buf);
+        instance.putCh('A');
+        assertEquals("A", buf.toString());
+
+        buf = new StringBuffer();
+        instance.setAppendable(buf);
+        instance.putCh('B').putCh('7').putCh('あ');
+        assertEquals("B7あ", buf.toString());
+
+        buf = new StringBuffer();
+        instance.setAppendable(buf);
+        instance.putCh('&').putCh('<').putCh('>').putCh('"').putCh('\'');
+        assertEquals("&amp;&lt;&gt;&quot;&apos;", buf.toString());
+
+        buf = new StringBuffer();
+        instance.setAppendable(buf);
+        instance.putCh('\b');
+        assertEquals("&#x08;", buf.toString());
+
+        return;
+    }
+
+    /**
      * Test of append method, of class BasicXmlExporter.
      */
     @Test
diff --git a/src/test/java/jp/sfjp/mikutoga/xml/DomUtilsTest.java b/src/test/java/jp/sfjp/mikutoga/xml/DomUtilsTest.java
deleted file mode 100644 (file)
index f319a31..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
-@see https://www.w3.org/TR/xmlschema-2/
- */
-
-package jp.sfjp.mikutoga.xml;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-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.*;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- *
- */
-public class DomUtilsTest {
-
-    private static final DocumentBuilderFactory FACTORY =
-            DocumentBuilderFactory.newInstance();
-    private static final DocumentBuilder BUILDER;
-
-    private static final String TESTELEM = "testelem";
-    private static final String TESTATTR = "testattr";
-
-    private static Element getTestAttredElem(String attrVal){
-        Document doc = BUILDER.newDocument();
-        Element elem = doc.createElement(TESTELEM);
-        elem.setAttribute(TESTATTR, attrVal);
-        return elem;
-    }
-
-    static{
-        try{
-            BUILDER = FACTORY.newDocumentBuilder();
-        }catch(ParserConfigurationException e){
-            throw new ExceptionInInitializerError(e);
-        }
-    }
-
-    public DomUtilsTest() {
-    }
-
-    @BeforeClass
-    public static void setUpClass() throws ParserConfigurationException{
-    }
-
-    @AfterClass
-    public static void tearDownClass() {
-    }
-
-    @Before
-    public void setUp() {
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    /**
-     * Test of getBooleanAttr method, of class DomUtils.
-     */
-    @Test
-    public void testGetBooleanAttr() throws Exception {
-        System.out.println("getBooleanAttr");
-
-        boolean result;
-        Element elem;
-
-        elem = getTestAttredElem("true");
-        result = DomUtils.getBooleanAttr(elem, TESTATTR);
-        assertTrue(result);
-
-        elem = getTestAttredElem("false");
-        result = DomUtils.getBooleanAttr(elem, TESTATTR);
-        assertFalse(result);
-
-        elem = getTestAttredElem("0");
-        result = DomUtils.getBooleanAttr(elem, TESTATTR);
-        assertFalse(result);
-
-        elem = getTestAttredElem("1");
-        result = DomUtils.getBooleanAttr(elem, TESTATTR);
-        assertTrue(result);
-
-        elem = getTestAttredElem("\n\rtrue\u0020\t");
-        result = DomUtils.getBooleanAttr(elem, TESTATTR);
-        assertTrue(result);
-
-        elem = getTestAttredElem("?");
-        try{
-            DomUtils.getBooleanAttr(elem, TESTATTR);
-            fail();
-        }catch(TogaXmlException e){
-            assert true;
-        }
-
-        return;
-    }
-
-    /**
-     * Test of getIntegerAttr method, of class DomUtils.
-     */
-    @Test
-    public void testGetIntegerAttr() throws TogaXmlException {
-        System.out.println("getIntegerAttr");
-
-        int result;
-        Element elem;
-
-        elem = getTestAttredElem("0");
-        result = DomUtils.getIntegerAttr(elem, TESTATTR);
-        assertEquals(0, result);
-
-        elem = getTestAttredElem("1");
-        result = DomUtils.getIntegerAttr(elem, TESTATTR);
-        assertEquals(1, result);
-
-        elem = getTestAttredElem("-1");
-        result = DomUtils.getIntegerAttr(elem, TESTATTR);
-        assertEquals(-1, result);
-
-        elem = getTestAttredElem("999");
-        result = DomUtils.getIntegerAttr(elem, TESTATTR);
-        assertEquals(999, result);
-
-        elem = getTestAttredElem("-9999");
-        result = DomUtils.getIntegerAttr(elem, TESTATTR);
-        assertEquals(-9999, result);
-
-        elem = getTestAttredElem("\n\r999\u0020\t");
-        result = DomUtils.getIntegerAttr(elem, TESTATTR);
-        assertEquals(999, result);
-
-        elem = getTestAttredElem("?");
-        try{
-            result = DomUtils.getIntegerAttr(elem, TESTATTR);
-            fail();
-        }catch(TogaXmlException e){
-            assert true;
-        }
-
-        return;
-    }
-
-    /**
-     * Test of getFloatAttr method, of class DomUtils.
-     */
-    @Test
-    public void testGetFloatAttr() throws TogaXmlException {
-        System.out.println("getFloatAttr");
-
-        float result;
-        Element elem;
-
-        elem = getTestAttredElem("0.0");
-        result = DomUtils.getFloatAttr(elem, TESTATTR);
-        assertEquals(0.0f, result, 0.0f);
-
-        elem = getTestAttredElem("-0.0");
-        result = DomUtils.getFloatAttr(elem, TESTATTR);
-        assertEquals(0.0f, result, 0.0f);
-        assertEquals("-0.0", Float.toString(result));
-
-        elem = getTestAttredElem("-123.456");
-        result = DomUtils.getFloatAttr(elem, TESTATTR);
-        assertEquals(-123.456f, result, 0.0f);
-
-        elem = getTestAttredElem("654.321");
-        result = DomUtils.getFloatAttr(elem, TESTATTR);
-        assertEquals(654.321f, result, 0.0f);
-
-        elem = getTestAttredElem("2.3E4");
-        result = DomUtils.getFloatAttr(elem, TESTATTR);
-        assertEquals(23000.0f, result, 0.0f);
-
-        elem = getTestAttredElem("INF");
-        result = DomUtils.getFloatAttr(elem, TESTATTR);
-        assertEquals(Float.POSITIVE_INFINITY, result, 0.0f);
-
-        elem = getTestAttredElem("+INF");
-        try{
-            DomUtils.getFloatAttr(elem, TESTATTR);
-            fail();
-        }catch(TogaXmlException e){
-            assert true;
-        }
-
-        elem = getTestAttredElem("NaN");
-        result = DomUtils.getFloatAttr(elem, TESTATTR);
-        assertTrue(Float.isNaN(result));
-
-        elem = getTestAttredElem("\n\r123.456\u0020\t");
-        result = DomUtils.getFloatAttr(elem, TESTATTR);
-        assertEquals(123.456f, result, 0.0f);
-
-        elem = getTestAttredElem("?");
-        try{
-            DomUtils.getFloatAttr(elem, TESTATTR);
-            fail();
-        }catch(TogaXmlException e){
-            assert true;
-        }
-
-        return;
-    }
-
-}
diff --git a/src/test/java/jp/sfjp/mikutoga/xml/XmlResourceResolverTest.java b/src/test/java/jp/sfjp/mikutoga/xml/XmlResourceResolverTest.java
new file mode 100644 (file)
index 0000000..4b54030
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ */
+
+package jp.sfjp.mikutoga.xml;
+
+import java.net.URI;
+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 XmlResourceResolverTest {
+
+    public XmlResourceResolverTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of buildBaseRelativeURI method, of class XmlResourceResolver.
+     */
+    @Test
+    public void testBuildBaseRelativeURI() throws Exception {
+        System.out.println("buildBaseRelativeURI");
+
+        URI result;
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com", "/a");
+        assertEquals("http://example.com/a", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com/", "a");
+        assertEquals("http://example.com/a", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com/", "/a");
+        assertEquals("http://example.com/a", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com/a", "/b");
+        assertEquals("http://example.com/b", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com/a/", "b");
+        assertEquals("http://example.com/a/b", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com/a/", "/b");
+        assertEquals("http://example.com/b", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com/a", "http://example.org/b");
+        assertEquals("http://example.org/b", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI(null, "http://example.org/b");
+        assertEquals("http://example.org/b", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com/a", null);
+        assertEquals("http://example.com/", result.toASCIIString());
+
+        result = XmlResourceResolver.buildBaseRelativeURI("http://example.com/a/b/", "../c");
+        assertEquals("http://example.com/a/c", result.toASCIIString());
+
+        try{
+            XmlResourceResolver.buildBaseRelativeURI("a/b/", "c/d");
+            fail();
+        }catch(IllegalArgumentException e){
+            assert true;
+        }
+
+        try{
+            XmlResourceResolver.buildBaseRelativeURI(null, "c/d");
+            fail();
+        }catch(IllegalArgumentException e){
+            assert true;
+        }
+
+        return;
+    }
+
+}