4 * License : The MIT License
5 * Copyright(c) 2013 MikuToga Partners
8 package jp.sfjp.mikutoga.pmd2xml;
10 import java.io.BufferedInputStream;
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.net.MalformedURLException;
17 import javax.xml.XMLConstants;
18 import javax.xml.parsers.ParserConfigurationException;
19 import javax.xml.parsers.SAXParser;
20 import javax.xml.parsers.SAXParserFactory;
21 import javax.xml.validation.Schema;
22 import jp.sfjp.mikutoga.pmd.model.xml.Schema101009;
23 import jp.sfjp.mikutoga.pmd.model.xml.Schema130128;
24 import jp.sfjp.mikutoga.xml.BotherHandler;
25 import jp.sfjp.mikutoga.xml.NoopEntityResolver;
26 import jp.sfjp.mikutoga.xml.SchemaUtil;
27 import org.xml.sax.InputSource;
28 import org.xml.sax.SAXException;
29 import org.xml.sax.SAXNotRecognizedException;
30 import org.xml.sax.SAXNotSupportedException;
31 import org.xml.sax.XMLReader;
36 final class XmlInputUtil {
38 private static final String F_DISALLOW_DOCTYPE_DECL =
39 "http://apache.org/xml/features/disallow-doctype-decl";
40 private static final String F_EXTERNAL_GENERAL_ENTITIES =
41 "http://xml.org/sax/features/external-general-entities";
42 private static final String F_EXTERNAL_PARAMETER_ENTITIES =
43 "http://xml.org/sax/features/external-parameter-entities";
44 private static final String F_LOAD_EXTERNAL_DTD =
45 "http://apache.org/xml/features/nonvalidating/load-external-dtd";
51 private XmlInputUtil(){
53 throw new AssertionError();
58 * 実在ファイルからXML入力ソースを得る。
63 static InputSource fileToSource(File file){
66 URI uri = file.toURI();
71 }catch(MalformedURLException e){
72 // 実在File由来のURLでは起こりえない
74 throw new AssertionError(e);
77 String systemId = url.toString();
79 InputSource source = new InputSource(systemId);
85 * InputSourceからInputStreamを得る。
87 * <p>入力ソースには、少なくともバイトストリームか
88 * URL文字列(SystemId)のいずれかが設定されていなければならない。
92 * @throws IllegalArgumentException 入力ソースの設定が足りない。
93 * @throws IOException 入力ソースにアクセス不能。
95 static InputStream openInputSource(InputSource source)
96 throws IllegalArgumentException, IOException{
99 is = source.getByteStream();
102 String systemId = source.getSystemId();
103 if(systemId == null) throw new IllegalArgumentException();
105 URL url = new URL(systemId);
106 is = url.openStream();
109 is = new BufferedInputStream(is);
118 * <li>XML名前空間機能は有効になる。
119 * <li>DTDによる形式検証は無効となる。
120 * <li>XIncludeによる差し込み機能は無効となる。
126 private static SAXParserFactory buildFactory(Schema schema){
127 SAXParserFactory factory = SAXParserFactory.newInstance();
129 factory.setNamespaceAware(true);
130 factory.setValidating(false);
131 factory.setXIncludeAware(false);
134 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
135 factory.setFeature(F_DISALLOW_DOCTYPE_DECL, true);
136 factory.setFeature(F_EXTERNAL_GENERAL_ENTITIES, false);
137 factory.setFeature(F_EXTERNAL_PARAMETER_ENTITIES, false);
138 factory.setFeature(F_LOAD_EXTERNAL_DTD, false);
139 }catch( ParserConfigurationException
140 | SAXNotRecognizedException
141 | SAXNotSupportedException e ){
143 throw new AssertionError(e);
146 factory.setSchema(schema);
157 private static SAXParser buildParser(Schema schema){
158 SAXParserFactory factory = buildFactory(schema);
162 parser = factory.newSAXParser();
163 }catch(ParserConfigurationException | SAXException e){
165 throw new AssertionError(e);
169 parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
170 parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
171 }catch(SAXNotRecognizedException | SAXNotSupportedException e){
173 throw new AssertionError(e);
182 * @param xmlInType 入力XML種別
185 private static Schema buildSchema(ModelFileType xmlInType ){
189 schemaUris = new URI[]{
190 Schema101009.RES_SCHEMA_PMDXML,
194 schemaUris = new URI[]{
195 Schema130128.RES_SCHEMA_PMDXML,
199 schemaUris = new URI[]{
200 Schema101009.RES_SCHEMA_PMDXML,
201 Schema130128.RES_SCHEMA_PMDXML,
205 throw new IllegalStateException();
210 schema = SchemaUtil.newSchema(schemaUris);
211 }catch(IOException | SAXException e){
213 throw new AssertionError(e);
222 * <p>エラーハンドラには{@link BotherHandler}が指定される。
224 * @param xmlInType 入力XML種別
227 static XMLReader buildReader(ModelFileType xmlInType){
228 Schema schema = buildSchema(xmlInType);
230 SAXParser parser = buildParser(schema);
234 reader = parser.getXMLReader();
235 }catch(SAXException e){
237 throw new AssertionError(e);
240 reader.setEntityResolver(NoopEntityResolver.NOOP_RESOLVER);
241 reader.setErrorHandler(BotherHandler.HANDLER);