OSDN Git Service

TogaGemからのパッケージ移管。
[mikutoga/Pmd2XML.git] / src / main / java / jp / sourceforge / mikutoga / pmd2xml / Pmd2Xml.java
1 /*
2  * pmd 2 xml converter main entry
3  *
4  * License : The MIT License
5  * Copyright(c) 2010 MikuToga Partners
6  */
7
8 package jp.sourceforge.mikutoga.pmd2xml;
9
10 import java.io.BufferedInputStream;
11 import java.io.BufferedOutputStream;
12 import java.io.File;
13 import java.io.FileInputStream;
14 import java.io.FileOutputStream;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.nio.channels.FileChannel;
19 import java.util.Properties;
20 import javax.xml.parsers.DocumentBuilder;
21 import javax.xml.parsers.ParserConfigurationException;
22 import jp.sourceforge.mikutoga.parser.MmdFormatException;
23 import jp.sourceforge.mikutoga.parser.MmdSource;
24 import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
25 import jp.sourceforge.mikutoga.pmd.model.PmdModel;
26 import jp.sourceforge.mikutoga.pmd.model.binio.PmdExporter;
27 import jp.sourceforge.mikutoga.pmd.model.binio.PmdLoader;
28 import jp.sourceforge.mikutoga.pmd.model.xml.PmdXmlExporter;
29 import jp.sourceforge.mikutoga.pmd.model.xml.PmdXmlResources;
30 import jp.sourceforge.mikutoga.pmd.model.xml.Xml2PmdLoader;
31 import jp.sourceforge.mikutoga.xml.TogaXmlException;
32 import org.xml.sax.InputSource;
33 import org.xml.sax.SAXException;
34
35 /**
36  * PMDモデルファイルとXMLとの間で変換を行うアプリケーション。
37  */
38 public final class Pmd2Xml {
39
40     private static final Class<?> THISCLASS;
41     private static final String APPNAME;
42     private static final String APPVER;
43     private static final String APPLICENSE;
44
45     static{
46         THISCLASS = Pmd2Xml.class;
47         InputStream ver =
48                 THISCLASS.getResourceAsStream("resources/version.properties");
49         Properties verProps = new Properties();
50         try{
51             verProps.load(ver);
52         }catch(IOException e){
53             throw new ExceptionInInitializerError(e);
54         }
55
56         APPNAME    = verProps.getProperty("app.name");
57         APPVER     = verProps.getProperty("app.version");
58         APPLICENSE = verProps.getProperty("app.license");
59
60         Object dummy = new Pmd2Xml();
61     }
62
63     /**
64      * 隠しコンストラクタ。
65      */
66     private Pmd2Xml(){
67         super();
68         assert this.getClass().equals(THISCLASS);
69         return;
70     }
71
72     /**
73      * Mainエントリ。
74      * @param args コマンドパラメータ
75      */
76     public static void main(String[] args){
77         checkJRE();
78
79         String inputFile = null;
80         String outputFile = null;
81         boolean pmd2xml = false;
82         boolean xml2pmd = false;
83         boolean force = false;
84         int argsLen = args.length;
85         for(int argIdx = 0; argIdx < argsLen; argIdx++){
86             String arg = args[argIdx];
87
88             if(arg.equals("-h")){
89                 putHelp();
90             }else if(arg.equals("-pmd2xml")){
91                 pmd2xml = true;
92                 xml2pmd = false;
93             }else if(arg.equals("-xml2pmd")){
94                 pmd2xml = false;
95                 xml2pmd = true;
96             }else if(arg.equals("-i")){
97                 if(++argIdx >= argsLen){
98                     System.err.println("ERROR:");
99                     System.err.println("You need -i argument.");
100                     System.err.println("(-h for help)");
101                     System.exit(5);
102                 }
103                 inputFile = args[argIdx];
104             }else if(arg.equals("-o")){
105                 if(++argIdx >= argsLen){
106                     System.err.println("ERROR:");
107                     System.err.println("You need -o argument.");
108                     System.err.println("(-h for help)");
109                     System.exit(5);
110                 }
111                 outputFile = args[argIdx];
112             }else if(arg.equals("-f")){
113                 force = true;
114             }else{
115                 System.err.println("ERROR:");
116                 System.err.println("Unknown option:"+arg);
117                 System.err.println("(-h for help)");
118                 System.exit(5);
119             }
120         }
121
122         if( ( ! pmd2xml) && ( ! xml2pmd) ){
123             System.err.println("ERROR:");
124             System.err.println("You must specify -pmd2xml or -xml2pmd.");
125             System.err.println("(-h for help)");
126             System.exit(5);
127         }
128
129         if(inputFile == null){
130             System.err.println("ERROR:");
131             System.err.println("You must specify input file with -i.");
132             System.err.println("(-h for help)");
133             System.exit(5);
134         }
135
136         if(outputFile == null){
137             System.err.println("ERROR:");
138             System.err.println("You must specify output file with -o.");
139             System.err.println("(-h for help)");
140             System.exit(5);
141         }
142
143         File iFile = new File(inputFile);
144         if( (! iFile.exists()) || (! iFile.isFile()) ){
145             System.err.println("ERROR:");
146             System.err.println("Can't find input file:"
147                     + iFile.getAbsolutePath());
148             System.err.println("(-h for help)");
149             System.exit(1);
150         }
151
152         if( ! force ){
153             File oFile = new File(outputFile);
154             if(oFile.exists()){
155                 System.err.println("ERROR:");
156                 System.err.println(oFile.getAbsolutePath()
157                         + " already exists.");
158                 System.err.println("If you want to overwrite, use -f.");
159                 System.err.println("(-h for help)");
160                 System.exit(1);
161             }
162         }else{
163             File oFile = new File(outputFile);
164             if(oFile.exists()){
165                 if( ! oFile.isFile()){
166                     System.err.println("ERROR:");
167                     System.err.println(oFile.getAbsolutePath()
168                             + " is not file.");
169                     System.err.println("(-h for help)");
170                     System.exit(1);
171                 }
172             }
173         }
174
175         try{
176             if(pmd2xml) pmd2xml(inputFile, outputFile);
177             else        xml2pmd(inputFile, outputFile);
178         }catch(IOException e){
179             ioError(e);
180         }catch(ParserConfigurationException e){
181             internalError(e);
182         }catch(IllegalPmdDataException e){
183             internalError(e);
184         }catch(MmdFormatException e){
185             pmdError(e);
186         }catch(TogaXmlException e){
187             xmlError(e);
188         }catch(SAXException e){
189             xmlError(e);
190         }
191
192         System.exit(0);
193
194         return;
195     }
196
197     /**
198      * 入出力エラー処理。
199      * 例外を出力してVM終了する。
200      * @param ex 例外
201      */
202     private static void ioError(Throwable ex){
203         System.err.println(ex);
204         System.exit(1);
205     }
206
207     /**
208      * XML構文エラー処理。
209      * 例外を出力してVM終了する。
210      * @param ex 例外
211      */
212     private static void xmlError(Throwable ex){
213         System.err.println(ex);
214         System.exit(2);
215     }
216
217     /**
218      * PMDファイルフォーマットエラー処理。
219      * 例外を出力してVM終了する。
220      * @param ex 例外
221      */
222     private static void pmdError(Throwable ex){
223         System.err.println(ex);
224         ex.printStackTrace(System.err);
225         System.exit(3);
226     }
227
228     /**
229      * 内部エラー処理。
230      * 例外を出力してVM終了する。
231      * @param ex 例外
232      */
233     private static void internalError(Throwable ex){
234         System.err.println(ex);
235         ex.printStackTrace(System.err);
236         System.exit(4);
237     }
238
239     /**
240      * JREのバージョン判定を行う。
241      * 不適切ならVMごと終了。
242      */
243     private static void checkJRE(){
244         Package jrePackage = java.lang.Object.class.getPackage();
245         if( ! jrePackage.isCompatibleWith("1.6")){
246             System.err.println("You need JRE 1.6 or later.");
247             System.exit(4);
248         }
249         return;
250     }
251
252     /**
253      * ヘルプメッセージを出力してVMを終了させる。
254      */
255     private static void putHelp(){
256         System.err.println(APPNAME + ' ' + APPVER );
257         System.err.println("  License : " + APPLICENSE);
258         System.err.println("  http://mikutoga.sourceforge.jp/");
259         System.err.println();
260         System.err.println("-h       : put help massage");
261         System.err.println("-pmd2xml : convert *.pmd to *.xml");
262         System.err.println("-xml2pmd : convert *.xml to *.pmd");
263         System.err.println("-i file  : specify input file");
264         System.err.println("-o file  : specify output file");
265         System.err.println("-f       : force overwriting");
266         System.exit(0);
267         return;
268     }
269
270     /**
271      * PMD->XML変換を行う。
272      * @param inputFile 入力ファイル名
273      * @param outputFile 出力ファイル名
274      * @throws IOException 入出力エラー
275      * @throws MmdFormatException 不正なPMDファイル
276      * @throws IllegalPmdDataException 不正なモデルデータ
277      */
278     private static void pmd2xml(String inputFile, String outputFile)
279             throws IOException, MmdFormatException, IllegalPmdDataException{
280         File iFile = new File(inputFile);
281         InputStream is = new FileInputStream(iFile);
282         is = new BufferedInputStream(is);
283         PmdModel model = pmdRead(is);
284         is.close();
285
286         File oFile = new File(outputFile);
287         trunc(oFile);
288         OutputStream ostream;
289         ostream = new FileOutputStream(oFile, false);
290         ostream = new BufferedOutputStream(ostream);
291         xmlOut(model, ostream);
292         ostream.close();
293
294         return;
295     }
296
297     /**
298      * XML->PMD変換を行う。
299      * @param inputFile 入力ファイル名
300      * @param outputFile 出力ファイル名
301      * @throws IOException 入出力エラー
302      * @throws ParserConfigurationException XML構成のエラー
303      * @throws SAXException 不正なXMLファイル
304      * @throws TogaXmlException 不正なXMLファイル
305      * @throws IllegalPmdDataException 不正なPMDモデルデータ
306      */
307     private static void xml2pmd(String inputFile, String outputFile)
308             throws IOException,
309                    ParserConfigurationException,
310                    SAXException,
311                    TogaXmlException,
312                    IllegalPmdDataException {
313         File iFile = new File(inputFile);
314         InputStream is = new FileInputStream(iFile);
315         is = new BufferedInputStream(is);
316         InputSource source = new InputSource(is);
317         PmdModel model = xmlRead(source);
318         is.close();
319
320         File oFile = new File(outputFile);
321         trunc(oFile);
322         OutputStream ostream;
323         ostream = new FileOutputStream(oFile, false);
324         ostream = new BufferedOutputStream(ostream);
325         pmdOut(model, ostream);
326         ostream.close();
327
328         return;
329     }
330
331     /**
332      * ファイルサイズを0に切り詰める。
333      * @param file ファイル
334      * @throws IOException 入出力エラー
335      */
336     private static void trunc(File file) throws IOException{
337         if( ! file.exists() ) return;
338         if( ! file.isFile() ) return;
339
340         FileOutputStream foStream = new FileOutputStream(file);
341         FileChannel channnel = foStream.getChannel();
342         channnel.truncate(0);
343
344         channnel.close();
345         foStream.close();
346
347         return;
348     }
349
350     /**
351      * PMDファイルからモデルデータを読み込む。
352      * @param is 入力ストリーム
353      * @return モデルデータ
354      * @throws IOException 入力エラー
355      * @throws MmdFormatException 不正なPMDファイルフォーマット
356      */
357     private static PmdModel pmdRead(InputStream is)
358             throws IOException, MmdFormatException{
359         MmdSource source = new MmdSource(is);
360         PmdLoader loader = new PmdLoader(source);
361
362         PmdModel model = loader.load();
363
364         return model;
365     }
366
367     /**
368      * XMLファイルからモデルデータを読み込む。
369      * @param source 入力ソース
370      * @return モデルデータ
371      * @throws IOException 入力エラー
372      * @throws ParserConfigurationException XML構成エラー
373      * @throws SAXException XML構文エラー
374      * @throws TogaXmlException 不正なXMLデータ
375      */
376     private static PmdModel xmlRead(InputSource source)
377             throws IOException,
378                    ParserConfigurationException,
379                    SAXException,
380                    TogaXmlException {
381         DocumentBuilder builder =
382                 PmdXmlResources.newBuilder(XmlHandler.HANDLER);
383         Xml2PmdLoader loader = new Xml2PmdLoader(builder);
384
385         PmdModel model = loader.parse(source);
386
387         return model;
388     }
389
390     /**
391      * モデルデータをPMDファイルに出力する。
392      * @param model モデルデータ
393      * @param ostream 出力ストリーム
394      * @throws IOException 出力エラー
395      * @throws IllegalPmdDataException 不正なモデルデータ
396      */
397     private static void pmdOut(PmdModel model, OutputStream ostream)
398             throws IOException, IllegalPmdDataException{
399         PmdExporter exporter = new PmdExporter(ostream);
400         exporter.dumpPmdModel(model);
401         ostream.close();
402         return;
403     }
404
405     /**
406      * モデルデータをXMLファイルに出力する。
407      * @param model モデルデータ
408      * @param ostream 出力ストリーム
409      * @throws IOException 出力エラー
410      * @throws IllegalPmdDataException 不正なモデルデータ
411      */
412     private static void xmlOut(PmdModel model, OutputStream ostream)
413             throws IOException, IllegalPmdDataException{
414         PmdXmlExporter exporter = new PmdXmlExporter(ostream);
415         exporter.setNewLine("\r\n");
416         exporter.setGenerator(APPNAME + ' ' + APPVER);
417         exporter.putPmdModel(model);
418         exporter.close();
419         return;
420     }
421
422 }