2 * pmd 2 xml converter main entry
4 * License : The MIT License
5 * Copyright(c) 2010 MikuToga Partners
8 package jp.sfjp.mikutoga.pmd2xml;
10 import java.io.BufferedOutputStream;
12 import java.io.FileNotFoundException;
13 import java.io.FileOutputStream;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.io.OutputStream;
17 import java.io.PrintStream;
18 import java.nio.channels.FileChannel;
19 import java.text.MessageFormat;
20 import java.util.Properties;
21 import jp.sfjp.mikutoga.bin.parser.MmdFormatException;
22 import jp.sfjp.mikutoga.pmd.IllegalPmdDataException;
23 import jp.sfjp.mikutoga.xml.TogaXmlException;
24 import org.xml.sax.InputSource;
25 import org.xml.sax.SAXException;
28 * PMDモデルファイルとXMLとの間で変換を行うアプリケーション。
30 public final class Pmd2Xml {
33 public static final int EXIT_OK = 0;
35 public static final int EXIT_INTERR = 1;
37 public static final int EXIT_ENVERR = 2;
38 /** オプション指定に起因するエラー。 */
39 public static final int EXIT_OPTERR = 3;
40 /** ファイル入出力に起因するエラー。 */
41 public static final int EXIT_IOERR = 4;
42 /** XMLフォーマットに起因するエラー。 */
43 public static final int EXIT_XMLERR = 5;
44 /** PMDフォーマットに起因するエラー。 */
45 public static final int EXIT_PMDERR = 6;
48 public static final String APPNAME;
50 public static final String APPVER;
52 public static final String APPLICENSE;
54 public static final String APPURL;
56 public static final String GENERATOR;
58 private static final Class<?> THISCLASS;
59 private static final String RES_VER = "resources/version.properties";
61 private static final PrintStream ERROUT = System.err;
62 private static final String MSG_ERR = "ERROR:\n{0}\n(-h for help)";
63 private static final String MSG_HELP =
65 + "\u0020\u0020License\u0020:\u0020{2}\n"
66 + "\u0020\u0020{3}\n";
67 private static final String MSG_NOINFILE = "Can't find input file:{0}";
68 private static final String MSG_ABNFILE = "{0} is not file.";
69 private static final String MSG_OWOUTFILE =
70 "{0} already exists.\n"
71 + "If you want to overwrite, use -f.";
73 private static final String MSG_OLDJRE = "You need JRE {0} or later.";
74 private static final String REQUIRED_JRE = "1.8";
77 THISCLASS = Pmd2Xml.class;
78 InputStream ver = THISCLASS.getResourceAsStream(RES_VER);
79 Properties verProps = new Properties();
86 }catch(IOException e){
87 throw new ExceptionInInitializerError(e);
90 APPNAME = verProps.getProperty("app.name");
91 APPVER = verProps.getProperty("app.version");
92 APPLICENSE = verProps.getProperty("app.license");
93 APPURL = verProps.getProperty("app.url");
95 GENERATOR = APPNAME + ' ' + APPVER;
97 new Pmd2Xml().hashCode();
106 assert this.getClass().equals(THISCLASS);
114 * @see java.lang.System#exit(int)
116 private static void exit(int code){
119 throw new AssertionError();
124 * @param text 個別メッセージ
126 private static void errMsg(String text){
127 String msg = MessageFormat.format(MSG_ERR, text);
135 * @param dumpStack スタックトレースを出力するならtrue
137 private static void thPrintln(Throwable ex, boolean dumpStack){
139 ex.printStackTrace(ERROUT);
141 String text = ex.toString();
142 ERROUT.println(text);
152 private static void thPrintln(Throwable ex){
153 thPrintln(ex, false);
162 private static void ioError(IOException ex){
172 private static void xmlError(Throwable ex){
178 * PMDファイルフォーマットエラー処理。
182 private static void pmdError(MmdFormatException ex){
192 private static void internalError(Throwable ex){
201 private static void checkJRE(){
202 Package jrePackage = java.lang.Object.class.getPackage();
203 if( ! jrePackage.isCompatibleWith(REQUIRED_JRE)){
204 String msg = MessageFormat.format(MSG_OLDJRE, REQUIRED_JRE);
214 private static void putHelp(){
216 MessageFormat.format(MSG_HELP,
217 APPNAME, APPVER, APPLICENSE, APPURL);
219 ERROUT.println(OptSwitch.getConsoleHelp());
225 * <p>ファイルが存在しなければなにもしない。
226 * <p>通常ファイルでなければなにもしない。
228 * @throws IOException 入出力エラー
230 private static void trunc(File file) throws IOException{
231 if( ! file.exists() ) return;
232 if( ! file.isFile() ) return;
234 if(file.length() <= 0L) return;
236 FileOutputStream foStream = new FileOutputStream(file);
238 FileChannel channnel = foStream.getChannel();
240 channnel.truncate(0L);
253 * <p>入力ファイルが通常ファイルとして存在しなければエラー終了。
254 * @param optInfo オプション情報
257 private static InputSource openInfile(OptInfo optInfo){
258 String fileName = optInfo.getInFilename();
259 File inFile = new File(fileName);
261 if( (! inFile.exists()) || (! inFile.isFile()) ){
262 String absPath = inFile.getAbsolutePath();
263 String msg = MessageFormat.format(MSG_NOINFILE, absPath);
268 InputSource source = XmlInputUtil.fileToSource(inFile);
275 * <p>出力ファイルが通常ファイルでない場合はエラー終了。
276 * <p>既存の出力ファイルに上書き指示が伴っていなければエラー終了。
277 * @param optInfo オプション情報
280 private static OutputStream openOutfile(OptInfo optInfo){
281 String outputFile = optInfo.getOutFilename();
282 boolean overwrite = optInfo.overwriteMode();
284 File outFile = new File(outputFile);
286 if(outFile.exists()){
287 String absPath = outFile.getAbsolutePath();
288 if( ! outFile.isFile() ){
289 String msg = MessageFormat.format(MSG_ABNFILE, absPath);
292 }else if( ! overwrite ){
293 String msg = MessageFormat.format(MSG_OWOUTFILE, absPath);
301 }catch(IOException e){
307 os = new FileOutputStream(outFile);
308 }catch(FileNotFoundException e){
311 throw new AssertionError(e);
314 os = new BufferedOutputStream(os);
320 * オプション情報に従いコンバータを生成する。
321 * @param optInfo オプション情報
324 private static Pmd2XmlConv buildConverter(OptInfo optInfo){
325 Pmd2XmlConv converter = new Pmd2XmlConv();
327 converter.setInType (optInfo.getInFileType());
328 converter.setOutType(optInfo.getOutFileType());
330 converter.setNewline(optInfo.getNewline());
331 converter.setGenerator(optInfo.getGenerator());
337 * 実際のコンバート作業と異常系処理を行う。
338 * <p>異常系が起きた場合、このメソッドは制御を戻さない。
339 * @param converter コンバータ
340 * @param source 入力ソース
341 * @param ostream 出力ストリーム
343 private static void doConvert(Pmd2XmlConv converter,
345 OutputStream ostream ){
347 converter.convert(source, ostream);
348 }catch(IOException e){
350 }catch(IllegalPmdDataException e){
352 }catch(MmdFormatException e){
354 }catch(TogaXmlException e){
356 }catch(SAXException e){
364 * コマンドライン文字列をオプション情報としてパースする。
365 * <p>異常系が起きた場合、このメソッドは制御を戻さない。
366 * @param args コマンドライン文字列群
369 private static OptInfo parseOption(String[] args){
373 optInfo = OptInfo.parseOption(args);
374 }catch(CmdLineException e){
375 String optErrMsg = e.getLocalizedMessage();
380 throw new AssertionError(e);
388 * @param args コマンドパラメータ
390 public static void main(String[] args){
393 OptInfo optInfo = parseOption(args);
394 if(optInfo.needHelp()){
399 Pmd2XmlConv converter = buildConverter(optInfo);
400 InputSource source = openInfile(optInfo);
401 OutputStream ostream = openOutfile(optInfo);
403 doConvert(converter, source, ostream);
407 }catch(IOException e){