OSDN Git Service

パッケージ移動
[mikutoga/Pmd2XML.git] / src / main / java / jp / sfjp / mikutoga / pmd2xml / Pmd2XmlConv.java
1 /*
2  * pmd 2 xml converter
3  *
4  * License : The MIT License
5  * Copyright(c) 2010 MikuToga Partners
6  */
7
8 package jp.sfjp.mikutoga.pmd2xml;
9
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.OutputStream;
13 import javax.xml.parsers.DocumentBuilder;
14 import javax.xml.parsers.DocumentBuilderFactory;
15 import javax.xml.parsers.ParserConfigurationException;
16 import javax.xml.validation.Schema;
17 import jp.sfjp.mikutoga.bin.parser.MmdFormatException;
18 import jp.sfjp.mikutoga.pmd.IllegalPmdDataException;
19 import jp.sfjp.mikutoga.pmd.binio.PmdExporter;
20 import jp.sfjp.mikutoga.pmd.binio.PmdLoader;
21 import jp.sfjp.mikutoga.pmd.model.PmdModel;
22 import jp.sfjp.mikutoga.pmd.xml.Schema101009;
23 import jp.sfjp.mikutoga.pmd.xml.Schema130128;
24 import jp.sfjp.mikutoga.pmd.xml.XmlExporter;
25 import jp.sfjp.mikutoga.pmd.xml.XmlLoader;
26 import jp.sfjp.mikutoga.pmd.xml.XmlModelFileType;
27 import jp.sourceforge.mikutoga.xml.BotherHandler;
28 import jp.sourceforge.mikutoga.xml.LocalSchema;
29 import jp.sourceforge.mikutoga.xml.TogaXmlException;
30 import jp.sourceforge.mikutoga.xml.XmlResourceResolver;
31 import org.xml.sax.InputSource;
32 import org.xml.sax.SAXException;
33
34 /**
35  * PMD-XML間コンバータ本体。
36  */
37 public class Pmd2XmlConv {
38
39     private ModelFileType inTypes  = ModelFileType.NONE;
40     private ModelFileType outTypes = ModelFileType.NONE;
41     private String newLine = "\r\n";
42     private String generator = null;
43
44
45     /**
46      * コンストラクタ。
47      */
48     public Pmd2XmlConv(){
49         super();
50         return;
51     }
52
53
54     /**
55      * ドキュメントビルダファクトリを初期化する。
56      * @param builderFactory ドキュメントビルダファクトリ
57      */
58     private static void initBuilderFactory(
59             DocumentBuilderFactory builderFactory ){
60         builderFactory.setCoalescing(true);
61         builderFactory.setExpandEntityReferences(true);
62         builderFactory.setIgnoringComments(true);
63         builderFactory.setIgnoringElementContentWhitespace(false);
64         builderFactory.setNamespaceAware(true);
65         builderFactory.setValidating(false);
66         builderFactory.setXIncludeAware(false);
67
68 //      builderFactory.setFeature(name, value);
69 //      builderFactory.setAttribute(name, value);
70
71         return;
72     }
73
74     /**
75      * DOMビルダ生成。
76      * @return DOMビルダ
77      */
78     private DocumentBuilder buildBuilder(){
79         XmlResourceResolver resolver = new XmlResourceResolver();
80
81         Schema schema;
82
83         switch(this.inTypes){
84         case XML_101009:
85             schema = LocalSchema.newSchema(resolver, new Schema101009());
86             break;
87         case XML_130128:
88             schema = LocalSchema.newSchema(resolver, new Schema130128());
89             break;
90         case XML_AUTO:
91             schema = LocalSchema.newSchema(resolver,
92                     new Schema101009(), new Schema130128());
93             break;
94         default:
95             throw new IllegalStateException();
96         }
97
98         DocumentBuilderFactory builderFactory =
99                 DocumentBuilderFactory.newInstance();
100         initBuilderFactory(builderFactory);
101         builderFactory.setSchema(schema);
102
103         DocumentBuilder result;
104         try{
105             result = builderFactory.newDocumentBuilder();
106         }catch(ParserConfigurationException e){
107             assert false;
108             throw new AssertionError(e);
109         }
110         result.setEntityResolver(resolver);
111         result.setErrorHandler(BotherHandler.HANDLER);
112
113         return result;
114     }
115
116
117     /**
118      * 入力ファイル種別を設定する。
119      * @param type ファイル種別
120      * @throws IllegalArgumentException 具体的な種別を渡さなかった
121      */
122     public void setInType(ModelFileType type){
123         if(type == null) throw new NullPointerException();
124         if(type == ModelFileType.NONE) throw new IllegalArgumentException();
125         this.inTypes = type;
126         return;
127     }
128
129     /**
130      * 入力ファイル種別を返す。
131      * @return ファイル種別
132      */
133     public ModelFileType getInTypes(){
134         return this.inTypes;
135     }
136
137     /**
138      * 出力ファイル種別を設定する。
139      * @param type ファイル種別
140      * @throws IllegalArgumentException 具体的な種別を渡さなかった
141      */
142     public void setOutType(ModelFileType type){
143         if(type == null) throw new NullPointerException();
144         if(type == ModelFileType.NONE) throw new IllegalArgumentException();
145         this.outTypes = type;
146         return;
147     }
148
149     /**
150      * 出力ファイル種別を返す。
151      * @return ファイル種別
152      */
153     public ModelFileType getOutTypes(){
154         return this.outTypes;
155     }
156
157     /**
158      * XML出力用改行文字列を設定する。
159      * @param newline 改行文字
160      */
161     public void setNewline(String newline){
162         this.newLine = newline;
163         return;
164     }
165
166     /**
167      * XML出力用改行文字列を返す。
168      * @return 改行文字
169      */
170     public String getNewLine(){
171         return this.newLine;
172     }
173
174     /**
175      * ジェネレータ名を設定する。
176      * @param generator ジェネレータ名。表示したくない場合はnull
177      */
178     public void setGenerator(String generator){
179         this.generator = generator;
180         return;
181     }
182
183     /**
184      * ジェネレータ名を返す。
185      * @return ジェネレータ名。非表示の場合はnullを返す。
186      */
187     public String getGenerator(){
188         return this.generator;
189     }
190
191     /**
192      * ファイル変換を行う。
193      * @param is 入力ストリーム
194      * @param os 出力ストリーム
195      * @throws IOException 入力エラー
196      * @throws MmdFormatException フォーマットエラー
197      * @throws SAXException XMLエラー
198      * @throws TogaXmlException XMLエラー
199      * @throws IllegalPmdDataException 内部エラー
200      */
201     public void convert(InputStream is, OutputStream os)
202             throws IOException,
203                    MmdFormatException,
204                    SAXException,
205                    TogaXmlException,
206                    IllegalPmdDataException {
207         PmdModel model = readModel(is);
208         writeModel(model, os);
209         return;
210     }
211
212     /**
213      * モデルファイルを読み込む。
214      * @param is 入力ストリーム
215      * @return モデルデータ
216      * @throws IOException 入力エラー
217      * @throws MmdFormatException フォーマットエラー
218      * @throws SAXException XMLエラー
219      * @throws TogaXmlException XMLエラー
220      * @throws IllegalStateException ファイル種別がまた指定されていない
221      */
222     public PmdModel readModel(InputStream is)
223             throws IOException,
224                    MmdFormatException,
225                    SAXException,
226                    TogaXmlException {
227         PmdModel model = null;
228
229         if(this.inTypes.isPmd()){
230             model = pmdRead(is);
231         }else if(this.inTypes.isXml()){
232             model = xmlRead(is);
233         }else{
234             throw new IllegalStateException();
235         }
236
237         return model;
238     }
239
240     /**
241      * モデルファイルを出力する。
242      * @param model モデルデータ
243      * @param os 出力ストリーム
244      * @throws IOException 出力エラー
245      * @throws IllegalPmdDataException データの不備
246      * @throws IllegalStateException ファイル種別がまた指定されていない
247      */
248     public void writeModel(PmdModel model, OutputStream os)
249             throws IOException,
250                    IllegalPmdDataException {
251         if(this.outTypes.isPmd()){
252             pmdOut(model, os);
253         }else if(this.outTypes.isXml()){
254             xmlOut(model, os);
255         }else{
256             throw new IllegalStateException();
257         }
258
259         return;
260     }
261
262     /**
263      * PMDファイルからモデルデータを読み込む。
264      * @param is 入力ストリーム
265      * @return モデルデータ
266      * @throws IOException 入力エラー
267      * @throws MmdFormatException 不正なPMDファイルフォーマット
268      */
269     private PmdModel pmdRead(InputStream is)
270             throws IOException, MmdFormatException{
271         PmdLoader loader = new PmdLoader(is);
272         PmdModel model = loader.load();
273         return model;
274     }
275
276     /**
277      * XMLファイルからモデルデータを読み込む。
278      * @param is 入力ストリーム
279      * @return モデルデータ
280      * @throws IOException 入力エラー
281      * @throws SAXException XML構文エラー
282      * @throws TogaXmlException 不正なXMLデータ
283      */
284     private PmdModel xmlRead(InputStream is)
285             throws IOException,
286                    SAXException,
287                    TogaXmlException {
288         InputSource source = new InputSource(is);
289         PmdModel result = xmlRead(source);
290         return result;
291     }
292
293     /**
294      * XMLファイルからモデルデータを読み込む。
295      * @param source 入力ソース
296      * @return モデルデータ
297      * @throws IOException 入力エラー
298      * @throws SAXException XML構文エラー
299      * @throws TogaXmlException 不正なXMLデータ
300      */
301     private PmdModel xmlRead(InputSource source)
302             throws IOException,
303                    SAXException,
304                    TogaXmlException {
305         DocumentBuilder builder = buildBuilder();
306         XmlLoader loader = new XmlLoader();
307         PmdModel model = loader.parse(builder, source);
308         return model;
309     }
310
311     /**
312      * モデルデータをPMDファイルに出力する。
313      * @param model モデルデータ
314      * @param ostream 出力ストリーム
315      * @throws IOException 出力エラー
316      * @throws IllegalPmdDataException 不正なモデルデータ
317      */
318     private void pmdOut(PmdModel model, OutputStream ostream)
319             throws IOException, IllegalPmdDataException{
320         PmdExporter exporter = new PmdExporter(ostream);
321         exporter.dumpPmdModel(model);
322         ostream.close();
323         return;
324     }
325
326     /**
327      * モデルデータをXMLファイルに出力する。
328      * @param model モデルデータ
329      * @param ostream 出力ストリーム
330      * @throws IOException 出力エラー
331      * @throws IllegalPmdDataException 不正なモデルデータ
332      */
333     private void xmlOut(PmdModel model, OutputStream ostream)
334             throws IOException, IllegalPmdDataException{
335         XmlExporter exporter = new XmlExporter(ostream);
336
337         XmlModelFileType xmlType = this.outTypes.toXmlType();
338         exporter.setXmlFileType(xmlType);
339         exporter.setNewLine(this.newLine);
340         exporter.setGenerator(this.generator);
341
342         exporter.putPmdModel(model);
343
344         exporter.close();
345
346         return;
347     }
348
349 }