OSDN Git Service

Vmd2Xmlとの共通化
authorOlyutorskii <olyutorskii@users.osdn.me>
Sun, 1 Dec 2013 16:07:50 +0000 (01:07 +0900)
committerOlyutorskii <olyutorskii@users.osdn.me>
Sun, 1 Dec 2013 16:07:50 +0000 (01:07 +0900)
src/main/java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java
src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2Xml.java
src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2XmlConv.java
src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java

index 64a6ea7..9fc99b0 100644 (file)
@@ -31,9 +31,6 @@ final class OptInfo {
     private static final String NL_LF   =   "lf";
     private static final String NL_CRLF = "crlf";
 
-    private static final String GENERATOR =
-            Pmd2Xml.APPNAME + ' ' + Pmd2Xml.APPVER;
-
     private static final String ERRMSG_UNKNOWN =
             "Unknown option : {0}";
     private static final String ERRMSG_MOREARG =
@@ -62,7 +59,7 @@ final class OptInfo {
     private String outFilename = null;
     private boolean overwrite = false;
     private String newline = EOL_DEFAULT;
-    private String generator = GENERATOR;
+    private String generator = Pmd2Xml.GENERATOR;
 
 
     /**
@@ -210,7 +207,7 @@ final class OptInfo {
                 break;
             case OPT_GENOUT:
                 boolean genout = decodeBoolean(exArg1);
-                if(genout) result.generator = GENERATOR;
+                if(genout) result.generator = Pmd2Xml.GENERATOR;
                 else       result.generator = null;
                 break;
             case OPT_IFORM:
index 92f103a..addb9a6 100644 (file)
@@ -7,10 +7,8 @@
 
 package jp.sfjp.mikutoga.pmd2xml;
 
-import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -23,6 +21,7 @@ import java.util.Properties;
 import jp.sfjp.mikutoga.bin.parser.MmdFormatException;
 import jp.sfjp.mikutoga.pmd.IllegalPmdDataException;
 import jp.sfjp.mikutoga.xml.TogaXmlException;
+import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 /**
@@ -53,6 +52,8 @@ public final class Pmd2Xml {
     public static final String APPLICENSE;
     /** 開発元URL。 */
     public static final String APPURL;
+    /** ジェネレータ名。 */
+    public static final String GENERATOR;
 
     private static final Class<?> THISCLASS;
     private static final String RES_VER = "resources/version.properties";
@@ -91,6 +92,8 @@ public final class Pmd2Xml {
         APPLICENSE = verProps.getProperty("app.license");
         APPURL     = verProps.getProperty("app.url");
 
+        GENERATOR = APPNAME + ' ' + APPVER;
+
         new Pmd2Xml().hashCode();
     }
 
@@ -246,12 +249,13 @@ public final class Pmd2Xml {
     }
 
     /**
-     * å\85¥å\8a\9bã\82¹ã\83\88ã\83ªã\83¼ã\83 を準備する。
+     * å\85¥å\8a\9bã\82½ã\83¼ã\82¹を準備する。
      * <p>入力ファイルが通常ファイルとして存在しなければエラー終了。
-     * @param fileName 入力ファイル名
-     * @return å\85¥å\8a\9bã\82¹ã\83\88ã\83ªã\83¼ã\83 
+     * @param optInfo オプション情報
+     * @return å\85¥å\8a\9bã\82½ã\83¼ã\82¹
      */
-    private static InputStream openInfile(String fileName){
+    private static InputSource openInfile(OptInfo optInfo){
+        String fileName = optInfo.getInFilename();
         File inFile = new File(fileName);
 
         if( (! inFile.exists()) || (! inFile.isFile()) ){
@@ -261,31 +265,23 @@ public final class Pmd2Xml {
             exit(EXIT_IOERR);
         }
 
-        InputStream is;
-        try{
-            is = new FileInputStream(inFile);
-        }catch(FileNotFoundException e){
-            ioError(e);
-            assert false;
-            throw new AssertionError(e);
-        }
-
-        is = new BufferedInputStream(is);
+        InputSource source = XmlInputUtil.fileToSource(inFile);
 
-        return is;
+        return source;
     }
 
     /**
      * 出力ストリームを準備する。
      * <p>出力ファイルが通常ファイルでない場合はエラー終了。
      * <p>既存の出力ファイルに上書き指示が伴っていなければエラー終了。
-     * @param fileName 出力ファイル名
-     * @param overWrite 頭から上書きして良ければtrue
+     * @param optInfo オプション情報
      * @return 出力ストリーム
      */
-    private static OutputStream openOutfile(String fileName,
-                                            boolean overWrite) {
-        File outFile = new File(fileName);
+    private static OutputStream openOutfile(OptInfo optInfo){
+        String outputFile = optInfo.getOutFilename();
+        boolean overwrite = optInfo.overwriteMode();
+
+        File outFile = new File(outputFile);
 
         if(outFile.exists()){
             String absPath = outFile.getAbsolutePath();
@@ -293,7 +289,7 @@ public final class Pmd2Xml {
                 String msg = MessageFormat.format(MSG_ABNFILE, absPath);
                 errMsg(msg);
                 exit(EXIT_IOERR);
-            }else if( ! overWrite ){
+            }else if( ! overwrite ){
                 String msg = MessageFormat.format(MSG_OWOUTFILE, absPath);
                 errMsg(msg);
                 exit(EXIT_IOERR);
@@ -321,34 +317,11 @@ public final class Pmd2Xml {
     }
 
     /**
-     * Mainエントリ。
-     * @param args コマンドパラメータ
+     * オプション情報に従いコンバータを生成する。
+     * @param optInfo オプション情報
+     * @return コンバータ
      */
-    public static void main(String[] args){
-        checkJRE();
-
-        OptInfo optInfo;
-        try{
-            optInfo = OptInfo.parseOption(args);
-        }catch(CmdLineException e){
-            String optErrMsg = e.getLocalizedMessage();
-            errMsg(optErrMsg);
-            exit(EXIT_OPTERR);
-            return;
-        }
-
-        if(optInfo.needHelp()){
-            putHelp();
-            exit(EXIT_OK);
-        }
-
-        String inputFile  = optInfo.getInFilename();
-        String outputFile = optInfo.getOutFilename();
-        boolean overwrite = optInfo.overwriteMode();
-
-        InputStream  is = openInfile(inputFile);
-        OutputStream os = openOutfile(outputFile, overwrite);
-
+    private static Pmd2XmlConv buildConverter(OptInfo optInfo){
         Pmd2XmlConv converter = new Pmd2XmlConv();
 
         converter.setInType (optInfo.getInFileType());
@@ -357,8 +330,21 @@ public final class Pmd2Xml {
         converter.setNewline(optInfo.getNewline());
         converter.setGenerator(optInfo.getGenerator());
 
+        return converter;
+    }
+
+    /**
+     * 実際のコンバート作業と異常系処理を行う。
+     * <p>異常系が起きた場合、このメソッドは制御を戻さない。
+     * @param converter コンバータ
+     * @param source 入力ソース
+     * @param ostream 出力ストリーム
+     */
+    private static void doConvert(Pmd2XmlConv converter,
+                                   InputSource source,
+                                   OutputStream ostream ){
         try{
-            converter.convert(is, os);
+            converter.convert(source, ostream);
         }catch(IOException e){
             ioError(e);
         }catch(IllegalPmdDataException e){
@@ -371,13 +357,53 @@ public final class Pmd2Xml {
             xmlError(e);
         }
 
+        return;
+    }
+
+    /**
+     * コマンドライン文字列をオプション情報としてパースする。
+     * <p>異常系が起きた場合、このメソッドは制御を戻さない。
+     * @param args コマンドライン文字列群
+     * @return オプション情報
+     */
+    private static OptInfo parseOption(String[] args){
+        OptInfo optInfo;
+
         try{
-            is.close();
-            try{
-                os.close();
-            }catch(IOException e){
-                ioError(e);
-            }
+            optInfo = OptInfo.parseOption(args);
+        }catch(CmdLineException e){
+            String optErrMsg = e.getLocalizedMessage();
+            errMsg(optErrMsg);
+            exit(EXIT_OPTERR);
+
+            assert false;
+            throw new AssertionError(e);
+        }
+
+        return optInfo;
+    }
+
+    /**
+     * Mainエントリ。
+     * @param args コマンドパラメータ
+     */
+    public static void main(String[] args){
+        checkJRE();
+
+        OptInfo optInfo = parseOption(args);
+        if(optInfo.needHelp()){
+            putHelp();
+            exit(EXIT_OK);
+        }
+
+        Pmd2XmlConv converter = buildConverter(optInfo);
+        InputSource source = openInfile(optInfo);
+        OutputStream ostream = openOutfile(optInfo);
+
+        doConvert(converter, source, ostream);
+
+        try{
+            ostream.close();
         }catch(IOException e){
             ioError(e);
         }
index 9a12175..1b222f2 100644 (file)
@@ -131,6 +131,8 @@ public class Pmd2XmlConv {
 
     /**
      * ファイル変換を行う。
+     * <p>XML入力の場合は{@link #convert(InputSource, OutputStream)}を
+     * 推奨する。
      * @param is 入力ストリーム
      * @param os 出力ストリーム
      * @throws IOException 入力エラー
@@ -151,7 +153,34 @@ public class Pmd2XmlConv {
     }
 
     /**
+     * ファイル変換を行う。
+     * <p>PMD入力の場合は{@link InputStream}に
+     * バイトストリームが直接設定されていなければならない。
+     * <p>XML入力の場合は{@link InputStream}に
+     * URL(systemId)のみの設定を推奨する。
+     * @param source 入力ソース
+     * @param os 出力ストリーム
+     * @throws IOException 入力エラー
+     * @throws MmdFormatException フォーマットエラー
+     * @throws SAXException XMLエラー
+     * @throws TogaXmlException XMLエラー
+     * @throws IllegalPmdDataException 内部エラー
+     */
+    public void convert(InputSource source, OutputStream os)
+            throws IOException,
+                   MmdFormatException,
+                   SAXException,
+                   TogaXmlException,
+                   IllegalPmdDataException {
+        PmdModel model = readModel(source);
+        writeModel(model, os);
+        return;
+    }
+
+    /**
      * モデルファイルを読み込む。
+     * <p>XML読み込みの場合は、
+     * こちらより{@link #readModel(InputSource)}版を推奨する。
      * @param is 入力ストリーム
      * @return モデルデータ
      * @throws IOException 入力エラー
@@ -164,12 +193,44 @@ public class Pmd2XmlConv {
                    MmdFormatException,
                    SAXException,
                    TogaXmlException {
+        InputSource source = new InputSource(is);
+
+        PmdModel model;
+
+        try{
+            model = readModel(source);
+        }finally{
+            is.close();
+        }
+
+        return model;
+    }
+
+    /**
+     * モデルファイルを読み込む。
+     * @param source 入力ソース
+     * @return モデルデータ
+     * @throws IOException 入力エラー
+     * @throws MmdFormatException フォーマットエラー
+     * @throws SAXException XMLエラー
+     * @throws TogaXmlException XMLエラー
+     */
+    public PmdModel readModel(InputSource source)
+            throws IOException,
+                   MmdFormatException,
+                   SAXException,
+                   TogaXmlException {
         PmdModel model = null;
 
         if(this.inTypes.isPmd()){
-            model = pmdRead(is);
+            InputStream is = XmlInputUtil.openInputSource(source);
+            try{
+                model = pmdRead(is);
+            }finally{
+                is.close();
+            }
         }else if(this.inTypes.isXml()){
-            model = xmlRead(is);
+            model = xmlRead(source);
         }else{
             throw new IllegalStateException();
         }
@@ -214,23 +275,6 @@ public class Pmd2XmlConv {
 
     /**
      * XMLファイルからモデルデータを読み込む。
-     * @param is 入力ストリーム
-     * @return モデルデータ
-     * @throws IOException 入力エラー
-     * @throws SAXException XML構文エラー
-     * @throws TogaXmlException 不正なXMLデータ
-     */
-    private PmdModel xmlRead(InputStream is)
-            throws IOException,
-                   SAXException,
-                   TogaXmlException {
-        InputSource source = new InputSource(is);
-        PmdModel result = xmlRead(source);
-        return result;
-    }
-
-    /**
-     * XMLファイルからモデルデータを読み込む。
      * @param source 入力ソース
      * @return モデルデータ
      * @throws IOException 入力エラー
index 91d0406..f413cf1 100644 (file)
@@ -7,6 +7,13 @@
 
 package jp.sfjp.mikutoga.pmd2xml;
 
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
@@ -17,6 +24,7 @@ import jp.sfjp.mikutoga.xml.BotherHandler;
 import jp.sfjp.mikutoga.xml.LocalXmlResource;
 import jp.sfjp.mikutoga.xml.SchemaUtil;
 import jp.sfjp.mikutoga.xml.XmlResourceResolver;
+import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
 
@@ -35,6 +43,60 @@ final class XmlInputUtil {
 
 
     /**
+     * 実在ファイルからXML入力ソースを得る。
+     * @param file 実在ファイル
+     * @return XML入力ソース
+     */
+    static InputSource fileToSource(File file){
+        assert file.exists();
+
+        URI uri = file.toURI();
+
+        URL url;
+        try{
+            url = uri.toURL();
+        }catch(MalformedURLException e){
+            // 実在File由来のURLでは起こりえない
+            assert false;
+            throw new AssertionError(e);
+        }
+
+        String systemId = url.toString();
+
+        InputSource source = new InputSource(systemId);
+
+        return source;
+    }
+
+    /**
+     * InputSourceからInputStreamを得る。
+     * <p>入力ソースには、少なくともバイトストリームか
+     * URL文字列(SystemId)のいずれかが設定されていなければならない。
+     * @param source 入力ソース
+     * @return 入力バイトストリーム
+     * @throws IllegalArgumentException 入力ソースの設定が足りない。
+     * @throws IOException 入力ソースにアクセス不能。
+     */
+    static InputStream openInputSource(InputSource source)
+            throws IllegalArgumentException, IOException{
+        InputStream is;
+
+        is = source.getByteStream();
+
+        if(is == null){
+            String systemId = source.getSystemId();
+            if(systemId == null) throw new IllegalArgumentException();
+
+            URL url = new URL(systemId);
+            is = url.openStream();
+        }
+
+        is = new BufferedInputStream(is);
+
+        return is;
+    }
+
+    /**
      * SAXパーサファクトリを生成する。
      * <ul>
      * <li>XML名前空間機能は有効になる。