From ceccd4a854175208e28020ab78e5015a60bb3a57 Mon Sep 17 00:00:00 2001 From: Olyutorskii Date: Mon, 2 Dec 2013 01:07:50 +0900 Subject: [PATCH] =?utf8?q?Vmd2Xml=E3=81=A8=E3=81=AE=E5=85=B1=E9=80=9A?= =?utf8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java | 7 +- .../java/jp/sfjp/mikutoga/pmd2xml/Pmd2Xml.java | 140 ++++++++++++--------- .../java/jp/sfjp/mikutoga/pmd2xml/Pmd2XmlConv.java | 82 +++++++++--- .../jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java | 62 +++++++++ 4 files changed, 210 insertions(+), 81 deletions(-) diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java index 64a6ea7..9fc99b0 100644 --- a/src/main/java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java +++ b/src/main/java/jp/sfjp/mikutoga/pmd2xml/OptInfo.java @@ -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: diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2Xml.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2Xml.java index 92f103a..addb9a6 100644 --- a/src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2Xml.java +++ b/src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2Xml.java @@ -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 { } /** - * 入力ストリームを準備する。 + * 入力ソースを準備する。 *

入力ファイルが通常ファイルとして存在しなければエラー終了。 - * @param fileName 入力ファイル名 - * @return 入力ストリーム + * @param optInfo オプション情報 + * @return 入力ソース */ - 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; } /** * 出力ストリームを準備する。 *

出力ファイルが通常ファイルでない場合はエラー終了。 *

既存の出力ファイルに上書き指示が伴っていなければエラー終了。 - * @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; + } + + /** + * 実際のコンバート作業と異常系処理を行う。 + *

異常系が起きた場合、このメソッドは制御を戻さない。 + * @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; + } + + /** + * コマンドライン文字列をオプション情報としてパースする。 + *

異常系が起きた場合、このメソッドは制御を戻さない。 + * @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); } diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2XmlConv.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2XmlConv.java index 9a12175..1b222f2 100644 --- a/src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2XmlConv.java +++ b/src/main/java/jp/sfjp/mikutoga/pmd2xml/Pmd2XmlConv.java @@ -131,6 +131,8 @@ public class Pmd2XmlConv { /** * ファイル変換を行う。 + *

XML入力の場合は{@link #convert(InputSource, OutputStream)}を + * 推奨する。 * @param is 入力ストリーム * @param os 出力ストリーム * @throws IOException 入力エラー @@ -151,7 +153,34 @@ public class Pmd2XmlConv { } /** + * ファイル変換を行う。 + *

PMD入力の場合は{@link InputStream}に + * バイトストリームが直接設定されていなければならない。 + *

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; + } + + /** * モデルファイルを読み込む。 + *

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 入力エラー diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java index 91d0406..f413cf1 100644 --- a/src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java +++ b/src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java @@ -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を得る。 + *

入力ソースには、少なくともバイトストリームか + * 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パーサファクトリを生成する。 *