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入力ソースを得る。
62 static InputSource fileToSource(File file){
65 URI uri = file.toURI();
70 }catch(MalformedURLException e){
71 // 実在File由来のURLでは起こりえない
73 throw new AssertionError(e);
76 String systemId = url.toString();
78 InputSource source = new InputSource(systemId);
84 * InputSourceからInputStreamを得る。
85 * <p>入力ソースには、少なくともバイトストリームか
86 * URL文字列(SystemId)のいずれかが設定されていなければならない。
89 * @throws IllegalArgumentException 入力ソースの設定が足りない。
90 * @throws IOException 入力ソースにアクセス不能。
92 static InputStream openInputSource(InputSource source)
93 throws IllegalArgumentException, IOException{
96 is = source.getByteStream();
99 String systemId = source.getSystemId();
100 if(systemId == null) throw new IllegalArgumentException();
102 URL url = new URL(systemId);
103 is = url.openStream();
106 is = new BufferedInputStream(is);
114 * <li>XML名前空間機能は有効になる。
115 * <li>DTDによる形式検証は無効となる。
116 * <li>XIncludeによる差し込み機能は無効となる。
121 private static SAXParserFactory buildFactory(Schema schema){
122 SAXParserFactory factory = SAXParserFactory.newInstance();
124 factory.setNamespaceAware(true);
125 factory.setValidating(false);
126 factory.setXIncludeAware(false);
129 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
130 factory.setFeature(F_DISALLOW_DOCTYPE_DECL, true);
131 factory.setFeature(F_EXTERNAL_GENERAL_ENTITIES, false);
132 factory.setFeature(F_EXTERNAL_PARAMETER_ENTITIES, false);
133 factory.setFeature(F_LOAD_EXTERNAL_DTD, false);
134 }catch( ParserConfigurationException
135 | SAXNotRecognizedException
136 | SAXNotSupportedException e
139 throw new AssertionError(e);
142 factory.setSchema(schema);
152 private static SAXParser buildParser(Schema schema){
153 SAXParserFactory factory = buildFactory(schema);
157 parser = factory.newSAXParser();
158 }catch(ParserConfigurationException | SAXException e){
160 throw new AssertionError(e);
164 parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
165 parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
166 }catch(SAXNotRecognizedException | SAXNotSupportedException e){
168 throw new AssertionError(e);
176 * @param resolver リゾルバ
177 * @param xmlInType 入力XML種別
180 private static Schema buildSchema(ModelFileType xmlInType ){
184 schemaUris = new URI[]{
185 Schema101009.RES_SCHEMA_PMDXML,
189 schemaUris = new URI[]{
190 Schema130128.RES_SCHEMA_PMDXML,
194 schemaUris = new URI[]{
195 Schema101009.RES_SCHEMA_PMDXML,
196 Schema130128.RES_SCHEMA_PMDXML,
200 throw new IllegalStateException();
205 schema = SchemaUtil.newSchema(schemaUris);
206 }catch(IOException | SAXException e){
208 throw new AssertionError(e);
216 * <p>エラーハンドラには{@link BotherHandler}が指定される。
217 * @param xmlInType 入力XML種別
220 static XMLReader buildReader(ModelFileType xmlInType){
221 Schema schema = buildSchema(xmlInType);
223 SAXParser parser = buildParser(schema);
227 reader = parser.getXMLReader();
228 }catch(SAXException e){
230 throw new AssertionError(e);
233 reader.setEntityResolver(NoopEntityResolver.NOOP_RESOLVER);
234 reader.setErrorHandler(BotherHandler.HANDLER);