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);
115 * @see java.lang.System#exit(int)
117 private static void exit(int code){
120 throw new AssertionError();
126 * @param text 個別メッセージ
128 private static void errMsg(String text){
129 String msg = MessageFormat.format(MSG_ERR, text);
138 * @param dumpStack スタックトレースを出力するならtrue
140 private static void thPrintln(Throwable ex, boolean dumpStack){
142 ex.printStackTrace(ERROUT);
144 String text = ex.toString();
145 ERROUT.println(text);
156 private static void thPrintln(Throwable ex){
157 thPrintln(ex, false);
167 private static void ioError(IOException ex){
178 private static void xmlError(Throwable ex){
184 * PMDファイルフォーマットエラー処理。
189 private static void pmdError(MmdFormatException ex){
200 private static void internalError(Throwable ex){
209 private static void checkJRE(){
210 Package jrePackage = java.lang.Object.class.getPackage();
211 if( ! jrePackage.isCompatibleWith(REQUIRED_JRE)){
212 String msg = MessageFormat.format(MSG_OLDJRE, REQUIRED_JRE);
222 private static void putHelp(){
224 MessageFormat.format(MSG_HELP,
225 APPNAME, APPVER, APPLICENSE, APPURL);
227 ERROUT.println(OptSwitch.getConsoleHelp());
234 * <p>ファイルが存在しなければなにもしない。
236 * <p>通常ファイルでなければなにもしない。
239 * @throws IOException 入出力エラー
241 private static void trunc(File file) throws IOException{
242 if( ! file.exists() ) return;
243 if( ! file.isFile() ) return;
245 if(file.length() <= 0L) return;
247 FileOutputStream foStream = new FileOutputStream(file);
249 FileChannel channnel = foStream.getChannel();
251 channnel.truncate(0L);
265 * <p>入力ファイルが通常ファイルとして存在しなければエラー終了。
267 * @param optInfo オプション情報
270 private static InputSource openInfile(OptInfo optInfo){
271 String fileName = optInfo.getInFilename();
272 File inFile = new File(fileName);
274 if( (! inFile.exists()) || (! inFile.isFile()) ){
275 String absPath = inFile.getAbsolutePath();
276 String msg = MessageFormat.format(MSG_NOINFILE, absPath);
281 InputSource source = XmlInputUtil.fileToSource(inFile);
289 * <p>出力ファイルが通常ファイルでない場合はエラー終了。
291 * <p>既存の出力ファイルに上書き指示が伴っていなければエラー終了。
293 * @param optInfo オプション情報
296 private static OutputStream openOutfile(OptInfo optInfo){
297 String outputFile = optInfo.getOutFilename();
298 boolean overwrite = optInfo.overwriteMode();
300 File outFile = new File(outputFile);
302 if(outFile.exists()){
303 String absPath = outFile.getAbsolutePath();
304 if( ! outFile.isFile() ){
305 String msg = MessageFormat.format(MSG_ABNFILE, absPath);
308 }else if( ! overwrite ){
309 String msg = MessageFormat.format(MSG_OWOUTFILE, absPath);
317 }catch(IOException e){
323 os = new FileOutputStream(outFile);
324 }catch(FileNotFoundException e){
327 throw new AssertionError(e);
330 os = new BufferedOutputStream(os);
336 * オプション情報に従いコンバータを生成する。
338 * @param optInfo オプション情報
341 private static Pmd2XmlConv buildConverter(OptInfo optInfo){
342 Pmd2XmlConv converter = new Pmd2XmlConv();
344 converter.setInType( optInfo.getInFileType());
345 converter.setOutType(optInfo.getOutFileType());
347 converter.setNewline(optInfo.getNewline());
348 converter.setGenerator(optInfo.getGenerator());
354 * 実際のコンバート作業と異常系処理を行う。
356 * <p>異常系が起きた場合、このメソッドは制御を戻さない。
358 * @param converter コンバータ
359 * @param source 入力ソース
360 * @param ostream 出力ストリーム
362 private static void doConvert(Pmd2XmlConv converter,
364 OutputStream ostream ){
366 converter.convert(source, ostream);
367 }catch(IOException e){
369 }catch(IllegalPmdDataException e){
371 }catch(MmdFormatException e){
373 }catch(TogaXmlException e){
375 }catch(SAXException e){
383 * コマンドライン文字列をオプション情報としてパースする。
385 * <p>異常系が起きた場合、このメソッドは制御を戻さない。
387 * @param args コマンドライン文字列群
390 private static OptInfo parseOption(String[] args){
394 optInfo = OptInfo.parseOption(args);
395 }catch(CmdLineException e){
396 String optErrMsg = e.getLocalizedMessage();
401 throw new AssertionError(e);
410 * @param args コマンドパラメータ
412 public static void main(String[] args){
415 OptInfo optInfo = parseOption(args);
416 if(optInfo.needHelp()){
421 Pmd2XmlConv converter = buildConverter(optInfo);
422 InputSource source = openInfile(optInfo);
423 OutputStream ostream = openOutfile(optInfo);
425 doConvert(converter, source, ostream);
429 }catch(IOException e){