OSDN Git Service

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