OSDN Git Service

JRE version-checking modified.
[mikutoga/Pmd2XML.git] / src / main / java / jp / sfjp / mikutoga / pmd2xml / XmlInputUtil.java
1 /*
2  * xml input utility
3  *
4  * License : The MIT License
5  * Copyright(c) 2013 MikuToga Partners
6  */
7
8 package jp.sfjp.mikutoga.pmd2xml;
9
10 import java.io.BufferedInputStream;
11 import java.io.File;
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.net.MalformedURLException;
15 import java.net.URI;
16 import java.net.URL;
17 import javax.xml.parsers.ParserConfigurationException;
18 import javax.xml.parsers.SAXParser;
19 import javax.xml.parsers.SAXParserFactory;
20 import javax.xml.validation.Schema;
21 import jp.sfjp.mikutoga.pmd.model.xml.Schema101009;
22 import jp.sfjp.mikutoga.pmd.model.xml.Schema130128;
23 import jp.sfjp.mikutoga.xml.BotherHandler;
24 import jp.sfjp.mikutoga.xml.LocalXmlResource;
25 import jp.sfjp.mikutoga.xml.SchemaUtil;
26 import jp.sfjp.mikutoga.xml.XmlResourceResolver;
27 import org.xml.sax.InputSource;
28 import org.xml.sax.SAXException;
29 import org.xml.sax.XMLReader;
30
31 /**
32  * XML入力に関する各種ユーティリティ。
33  */
34 final class XmlInputUtil {
35
36     /**
37      * 隠しコンストラクタ。
38      */
39     private XmlInputUtil(){
40         assert false;
41         throw new AssertionError();
42     }
43
44
45     /**
46      * 実在ファイルからXML入力ソースを得る。
47      * @param file 実在ファイル
48      * @return XML入力ソース
49      */
50     static InputSource fileToSource(File file){
51         assert file.exists();
52
53         URI uri = file.toURI();
54
55         URL url;
56         try{
57             url = uri.toURL();
58         }catch(MalformedURLException e){
59             // 実在File由来のURLでは起こりえない
60             assert false;
61             throw new AssertionError(e);
62         }
63
64         String systemId = url.toString();
65
66         InputSource source = new InputSource(systemId);
67
68         return source;
69     }
70
71     /**
72      * InputSourceからInputStreamを得る。
73      * <p>入力ソースには、少なくともバイトストリームか
74      * URL文字列(SystemId)のいずれかが設定されていなければならない。
75      * @param source 入力ソース
76      * @return 入力バイトストリーム
77      * @throws IllegalArgumentException 入力ソースの設定が足りない。
78      * @throws IOException 入力ソースにアクセス不能。
79      */
80     static InputStream openInputSource(InputSource source)
81             throws IllegalArgumentException, IOException{
82         InputStream is;
83
84         is = source.getByteStream();
85
86         if(is == null){
87             String systemId = source.getSystemId();
88             if(systemId == null) throw new IllegalArgumentException();
89
90             URL url = new URL(systemId);
91             is = url.openStream();
92         }
93
94         is = new BufferedInputStream(is);
95
96         return is;
97     }
98
99     /**
100      * SAXパーサファクトリを生成する。
101      * <ul>
102      * <li>XML名前空間機能は有効になる。
103      * <li>DTDによる形式検証は無効となる。
104      * <li>XIncludeによる差し込み機能は無効となる。
105      * </ul>
106      * @param schema スキーマ
107      * @return ファクトリ
108      */
109     private static SAXParserFactory buildFactory(Schema schema){
110         SAXParserFactory factory = SAXParserFactory.newInstance();
111
112         factory.setNamespaceAware(true);
113         factory.setValidating(false);
114         factory.setXIncludeAware(false);
115 //      factory.setFeature(name, value);
116
117         factory.setSchema(schema);
118
119         return factory;
120     }
121
122     /**
123      * SAXパーサを生成する。
124      * @param schema スキーマ
125      * @return SAXパーサ
126      */
127     private static SAXParser buildParser(Schema schema){
128         SAXParserFactory factory = buildFactory(schema);
129
130         SAXParser parser;
131         try{
132             parser = factory.newSAXParser();
133         }catch(ParserConfigurationException e){
134             assert false;
135             throw new AssertionError(e);
136         }catch(SAXException e){
137             assert false;
138             throw new AssertionError(e);
139         }
140
141 //      parser.setProperty(name, value);
142
143         return parser;
144     }
145
146     /**
147      * スキーマを生成する。
148      * @param resolver リゾルバ
149      * @param xmlInType 入力XML種別
150      * @return スキーマ
151      */
152     private static Schema builsSchema(XmlResourceResolver resolver,
153                                         ModelFileType xmlInType ){
154         LocalXmlResource[] schemaArray;
155         switch(xmlInType){
156         case XML_101009:
157             schemaArray = new LocalXmlResource[]{
158                 Schema101009.SINGLETON,
159             };
160             break;
161         case XML_130128:
162             schemaArray = new LocalXmlResource[]{
163                 Schema130128.SINGLETON,
164             };
165             break;
166         case XML_AUTO:
167             schemaArray = new LocalXmlResource[]{
168                 Schema101009.SINGLETON,
169                 Schema130128.SINGLETON,
170             };
171             break;
172         default:
173             throw new IllegalStateException();
174         }
175
176         Schema schema = SchemaUtil.newSchema(resolver, schemaArray);
177
178         return schema;
179     }
180
181     /**
182      * XMLリーダを生成する。
183      * <p>エラーハンドラには{@link BotherHandler}が指定される。
184      * @param xmlInType 入力XML種別
185      * @return XMLリーダ
186      */
187     static XMLReader buildReader(ModelFileType xmlInType){
188         XmlResourceResolver resolver = new XmlResourceResolver();
189
190         Schema schema = builsSchema(resolver, xmlInType);
191
192         SAXParser parser = buildParser(schema);
193
194         XMLReader reader;
195         try{
196             reader = parser.getXMLReader();
197         }catch(SAXException e){
198             assert false;
199             throw new AssertionError(e);
200         }
201
202         reader.setEntityResolver(resolver);
203         reader.setErrorHandler(BotherHandler.HANDLER);
204
205         return reader;
206     }
207
208 }