X-Git-Url: http://git.osdn.net/view?p=mikutoga%2FPmd2XML.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fjp%2Fsfjp%2Fmikutoga%2Fpmd2xml%2FXmlInputUtil.java;h=d17c40616947b1ad53ebd4f56c9fc34b5b74dac7;hp=91d04067c38e7216a1bf486b240e1721cb2251af;hb=91f6ac21aa8fad94b3336ba9d79ee38d9c3836de;hpb=9b83b2ab88046245489726207bf9fe2dd5db4453 diff --git a/src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java b/src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java index 91d0406..d17c406 100644 --- a/src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java +++ b/src/main/java/jp/sfjp/mikutoga/pmd2xml/XmlInputUtil.java @@ -7,6 +7,14 @@ package jp.sfjp.mikutoga.pmd2xml; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import javax.xml.XMLConstants; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -14,10 +22,12 @@ import javax.xml.validation.Schema; import jp.sfjp.mikutoga.pmd.model.xml.Schema101009; import jp.sfjp.mikutoga.pmd.model.xml.Schema130128; import jp.sfjp.mikutoga.xml.BotherHandler; -import jp.sfjp.mikutoga.xml.LocalXmlResource; +import jp.sfjp.mikutoga.xml.NoopEntityResolver; import jp.sfjp.mikutoga.xml.SchemaUtil; -import jp.sfjp.mikutoga.xml.XmlResourceResolver; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; /** @@ -25,6 +35,16 @@ import org.xml.sax.XMLReader; */ final class XmlInputUtil { + private static final String F_DISALLOW_DOCTYPE_DECL = + "http://apache.org/xml/features/disallow-doctype-decl"; + private static final String F_EXTERNAL_GENERAL_ENTITIES = + "http://xml.org/sax/features/external-general-entities"; + private static final String F_EXTERNAL_PARAMETER_ENTITIES = + "http://xml.org/sax/features/external-parameter-entities"; + private static final String F_LOAD_EXTERNAL_DTD = + "http://apache.org/xml/features/nonvalidating/load-external-dtd"; + + /** * 隠しコンストラクタ。 */ @@ -35,12 +55,71 @@ final class XmlInputUtil { /** + * 実在ファイルからXML入力ソースを得る。 + * + * @param file 実在ファイル + * @return XML入力ソース + */ + static InputSource fileToSource(File file){ + assert file.exists(); + + URI uri = file.toURI(); + + URL url; + try{ + url = uri.toURL(); + }catch(MalformedURLException e){ + // 実在File由来のURLでは起こりえない + assert false; + throw new AssertionError(e); + } + + String systemId = url.toString(); + + InputSource source = new InputSource(systemId); + + return source; + } + + /** + * InputSourceからInputStreamを得る。 + * + *

入力ソースには、少なくともバイトストリームか + * URL文字列(SystemId)のいずれかが設定されていなければならない。 + * + * @param source 入力ソース + * @return 入力バイトストリーム + * @throws IllegalArgumentException 入力ソースの設定が足りない。 + * @throws IOException 入力ソースにアクセス不能。 + */ + static InputStream openInputSource(InputSource source) + throws IllegalArgumentException, IOException{ + InputStream is; + + is = source.getByteStream(); + + if(is == null){ + String systemId = source.getSystemId(); + if(systemId == null) throw new IllegalArgumentException(); + + URL url = new URL(systemId); + is = url.openStream(); + } + + is = new BufferedInputStream(is); + + return is; + } + + /** * SAXパーサファクトリを生成する。 + * *

+ * * @param schema スキーマ * @return ファクトリ */ @@ -50,7 +129,19 @@ final class XmlInputUtil { factory.setNamespaceAware(true); factory.setValidating(false); factory.setXIncludeAware(false); -// factory.setFeature(name, value); + + try{ + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + factory.setFeature(F_DISALLOW_DOCTYPE_DECL, true); + factory.setFeature(F_EXTERNAL_GENERAL_ENTITIES, false); + factory.setFeature(F_EXTERNAL_PARAMETER_ENTITIES, false); + factory.setFeature(F_LOAD_EXTERNAL_DTD, false); + }catch( ParserConfigurationException + | SAXNotRecognizedException + | SAXNotSupportedException e ){ + assert false; + throw new AssertionError(e); + } factory.setSchema(schema); @@ -59,6 +150,7 @@ final class XmlInputUtil { /** * SAXパーサを生成する。 + * * @param schema スキーマ * @return SAXパーサ */ @@ -68,64 +160,72 @@ final class XmlInputUtil { SAXParser parser; try{ parser = factory.newSAXParser(); - }catch(ParserConfigurationException e){ + }catch(ParserConfigurationException | SAXException e){ assert false; throw new AssertionError(e); - }catch(SAXException e){ + } + + try{ + parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + }catch(SAXNotRecognizedException | SAXNotSupportedException e){ assert false; throw new AssertionError(e); } -// parser.setProperty(name, value); - return parser; } /** * スキーマを生成する。 - * @param resolver リゾルバ + * * @param xmlInType 入力XML種別 * @return スキーマ */ - private static Schema builsSchema(XmlResourceResolver resolver, - ModelFileType xmlInType ){ - LocalXmlResource[] schemaArray; + private static Schema buildSchema(ModelFileType xmlInType ){ + URI[] schemaUris; switch(xmlInType){ case XML_101009: - schemaArray = new LocalXmlResource[]{ - Schema101009.SINGLETON, + schemaUris = new URI[]{ + Schema101009.RES_SCHEMA_PMDXML, }; break; case XML_130128: - schemaArray = new LocalXmlResource[]{ - Schema130128.SINGLETON, + schemaUris = new URI[]{ + Schema130128.RES_SCHEMA_PMDXML, }; break; case XML_AUTO: - schemaArray = new LocalXmlResource[]{ - Schema101009.SINGLETON, - Schema130128.SINGLETON, + schemaUris = new URI[]{ + Schema101009.RES_SCHEMA_PMDXML, + Schema130128.RES_SCHEMA_PMDXML, }; break; default: throw new IllegalStateException(); } - Schema schema = SchemaUtil.newSchema(resolver, schemaArray); + Schema schema; + try{ + schema = SchemaUtil.newSchema(schemaUris); + }catch(IOException | SAXException e){ + assert false; + throw new AssertionError(e); + } return schema; } /** * XMLリーダを生成する。 + * *

エラーハンドラには{@link BotherHandler}が指定される。 + * * @param xmlInType 入力XML種別 * @return XMLリーダ */ static XMLReader buildReader(ModelFileType xmlInType){ - XmlResourceResolver resolver = new XmlResourceResolver(); - - Schema schema = builsSchema(resolver, xmlInType); + Schema schema = buildSchema(xmlInType); SAXParser parser = buildParser(schema); @@ -137,7 +237,7 @@ final class XmlInputUtil { throw new AssertionError(e); } - reader.setEntityResolver(resolver); + reader.setEntityResolver(NoopEntityResolver.NOOP_RESOLVER); reader.setErrorHandler(BotherHandler.HANDLER); return reader;