OSDN Git Service

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