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;
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;
/**
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";
APPLICENSE = verProps.getProperty("app.license");
APPURL = verProps.getProperty("app.url");
+ GENERATOR = APPNAME + ' ' + APPVER;
+
new Pmd2Xml().hashCode();
}
}
/**
- * å\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()) ){
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();
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);
}
/**
- * 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());
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){
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);
}
/**
* ファイル変換を行う。
+ * <p>XML入力の場合は{@link #convert(InputSource, OutputStream)}を
+ * 推奨する。
* @param is 入力ストリーム
* @param os 出力ストリーム
* @throws IOException 入力エラー
}
/**
+ * ファイル変換を行う。
+ * <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 入力エラー
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();
}
/**
* 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 入力エラー
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;
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;
/**
+ * 実在ファイルから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名前空間機能は有効になる。