@@ -14,32 +14,36 @@ package scala
1414package xml
1515package factory
1616
17- import org .xml .sax .{SAXNotRecognizedException , XMLReader }
17+ import org .xml .sax .{SAXNotRecognizedException , SAXNotSupportedException , XMLReader }
1818import javax .xml .parsers .SAXParserFactory
1919import parsing .{FactoryAdapter , NoBindingFactoryAdapter }
2020import java .io .{File , FileDescriptor , InputStream , Reader }
2121import java .net .URL
2222
2323/**
2424 * Presents collection of XML loading methods which use the parser
25- * created by "def parser".
25+ * created by "def parser" or the reader created by "def reader" .
2626 */
2727trait XMLLoader [T <: Node ] {
2828 import scala .xml .Source ._
2929 def adapter : FactoryAdapter = new NoBindingFactoryAdapter ()
3030
31+ private def setSafeDefaults (parserFactory : SAXParserFactory ): Unit = {
32+ parserFactory.setFeature(" http://javax.xml.XMLConstants/feature/secure-processing" , true )
33+ parserFactory.setFeature(" http://apache.org/xml/features/nonvalidating/load-external-dtd" , false )
34+ parserFactory.setFeature(" http://apache.org/xml/features/disallow-doctype-decl" , true )
35+ parserFactory.setFeature(" http://xml.org/sax/features/external-parameter-entities" , false )
36+ parserFactory.setFeature(" http://xml.org/sax/features/external-general-entities" , false )
37+ parserFactory.setFeature(" http://xml.org/sax/features/resolve-dtd-uris" , false )
38+ parserFactory.setXIncludeAware(false )
39+ parserFactory.setNamespaceAware(false )
40+ }
41+
3142 private lazy val parserInstance : ThreadLocal [SAXParser ] = new ThreadLocal [SAXParser ] {
3243 override def initialValue : SAXParser = {
33- val parser : SAXParserFactory = SAXParserFactory .newInstance
34- parser.setFeature(" http://javax.xml.XMLConstants/feature/secure-processing" , true )
35- parser.setFeature(" http://apache.org/xml/features/nonvalidating/load-external-dtd" , false )
36- parser.setFeature(" http://apache.org/xml/features/disallow-doctype-decl" , true )
37- parser.setFeature(" http://xml.org/sax/features/external-parameter-entities" , false )
38- parser.setFeature(" http://xml.org/sax/features/external-general-entities" , false )
39- parser.setFeature(" http://xml.org/sax/features/resolve-dtd-uris" , false )
40- parser.setXIncludeAware(false )
41- parser.setNamespaceAware(false )
42- parser.newSAXParser
44+ val parserFactory : SAXParserFactory = SAXParserFactory .newInstance
45+ setSafeDefaults(parserFactory)
46+ parserFactory.newSAXParser
4347 }
4448 }
4549
@@ -51,72 +55,68 @@ trait XMLLoader[T <: Node] {
5155
5256 /**
5357 * Loads XML from the given InputSource, using the supplied parser.
54- * The methods available in scala.xml.XML use the XML parser in the JDK.
58+ * The methods available in scala.xml.XML use the XML parser in the JDK
59+ * (unless another parser is present on the classpath).
5560 */
56- def loadXML (source : InputSource , parser : SAXParser ): T = loadXML(source , parser.getXMLReader)
61+ def loadXML (inputSource : InputSource , parser : SAXParser ): T = loadXML(inputSource , parser.getXMLReader)
5762
58- def loadXMLNodes (source : InputSource , parser : SAXParser ): Seq [Node ] = loadXMLNodes(source , parser.getXMLReader)
63+ def loadXMLNodes (inputSource : InputSource , parser : SAXParser ): Seq [Node ] = loadXMLNodes(inputSource , parser.getXMLReader)
5964
60- private def loadXML (source : InputSource , reader : XMLReader ): T = {
61- val result : FactoryAdapter = parse(source , reader)
65+ private def loadXML (inputSource : InputSource , reader : XMLReader ): T = {
66+ val result : FactoryAdapter = parse(inputSource , reader)
6267 result.rootElem.asInstanceOf [T ]
6368 }
64-
65- private def loadXMLNodes (source : InputSource , reader : XMLReader ): Seq [Node ] = {
66- val result : FactoryAdapter = parse(source , reader)
69+
70+ private def loadXMLNodes (inputSource : InputSource , reader : XMLReader ): Seq [Node ] = {
71+ val result : FactoryAdapter = parse(inputSource , reader)
6772 result.prolog ++ (result.rootElem :: result.epilogue)
6873 }
6974
70- private def parse (source : InputSource , reader : XMLReader ): FactoryAdapter = {
71- if (source == null ) throw new IllegalArgumentException (" InputSource cannot be null" )
75+ private def parse (inputSource : InputSource , xmlReader : XMLReader ): FactoryAdapter = {
76+ if (inputSource == null ) throw new IllegalArgumentException (" InputSource cannot be null" )
7277
7378 val result : FactoryAdapter = adapter
7479
75- reader .setContentHandler(result)
76- reader .setDTDHandler(result)
80+ xmlReader .setContentHandler(result)
81+ xmlReader .setDTDHandler(result)
7782 /* Do not overwrite pre-configured EntityResolver. */
78- if (reader .getEntityResolver == null ) reader .setEntityResolver(result)
83+ if (xmlReader .getEntityResolver == null ) xmlReader .setEntityResolver(result)
7984 /* Do not overwrite pre-configured ErrorHandler. */
80- if (reader .getErrorHandler == null ) reader .setErrorHandler(result)
85+ if (xmlReader .getErrorHandler == null ) xmlReader .setErrorHandler(result)
8186
8287 try {
83- reader .setProperty(" http://xml.org/sax/properties/lexical-handler" , result)
88+ xmlReader .setProperty(" http://xml.org/sax/properties/lexical-handler" , result)
8489 } catch {
8590 case _ : SAXNotRecognizedException =>
91+ case _ : SAXNotSupportedException =>
8692 }
8793
8894 result.scopeStack = TopScope :: result.scopeStack
89- reader .parse(source )
95+ xmlReader .parse(inputSource )
9096 result.scopeStack = result.scopeStack.tail
9197
9298 result
9399 }
94100
95- /** loads XML from given InputSource. */
96- def load (source : InputSource ): T = loadXML(source, reader)
97-
98- /** Loads XML from the given file, file descriptor, or filename. */
101+ /** Loads XML. */
102+ def load (inputSource : InputSource ): T = loadXML(inputSource, reader)
103+ def loadFile (fileName : String ): T = load(fromFile(fileName))
99104 def loadFile (file : File ): T = load(fromFile(file))
100- def loadFile (fd : FileDescriptor ): T = load(fromFile(fd))
101- def loadFile (name : String ): T = load(fromFile(name))
102-
103- /** loads XML from given InputStream, Reader, sysID, or URL. */
104- def load (is : InputStream ): T = load(fromInputStream(is))
105+ def load (url : URL ): T = load(fromUrl(url))
106+ def load (sysId : String ): T = load(fromSysId(sysId))
107+ def loadFile (fileDescriptor : FileDescriptor ): T = load(fromFile(fileDescriptor))
108+ def load (inputStream : InputStream ): T = load(fromInputStream(inputStream))
105109 def load (reader : Reader ): T = load(fromReader(reader))
106- def load (sysID : String ): T = load(fromSysId(sysID))
107- def load (url : URL ): T = load(fromInputStream(url.openStream()))
108-
109- /** Loads XML from the given String. */
110110 def loadString (string : String ): T = load(fromString(string))
111111
112112 /** Load XML nodes, including comments and processing instructions that precede and follow the root element. */
113- def loadNodes (source : InputSource ): Seq [Node ] = loadXMLNodes(source, reader)
113+ def loadNodes (inputSource : InputSource ): Seq [Node ] = loadXMLNodes(inputSource, reader)
114+ def loadFileNodes (fileName : String ): Seq [Node ] = loadNodes(fromFile(fileName))
114115 def loadFileNodes (file : File ): Seq [Node ] = loadNodes(fromFile(file))
115- def loadFileNodes (fd : FileDescriptor ): Seq [Node ] = loadNodes(fromFile(fd))
116- def loadFileNodes (name : String ): Seq [Node ] = loadNodes(fromFile(name))
117- def loadNodes (is : InputStream ): Seq [Node ] = loadNodes(fromInputStream(is))
116+ def loadNodes (url : URL ): Seq [Node ] = loadNodes(fromUrl(url))
117+ def loadNodes (sysId : String ): Seq [Node ] = loadNodes(fromSysId(sysId))
118+ def loadFileNodes (fileDescriptor : FileDescriptor ): Seq [Node ] = loadNodes(fromFile(fileDescriptor))
119+ def loadNodes (inputStream : InputStream ): Seq [Node ] = loadNodes(fromInputStream(inputStream))
118120 def loadNodes (reader : Reader ): Seq [Node ] = loadNodes(fromReader(reader))
119- def loadNodes (sysID : String ): Seq [Node ] = loadNodes(fromSysId(sysID))
120- def loadNodes (url : URL ): Seq [Node ] = loadNodes(fromInputStream(url.openStream()))
121121 def loadStringNodes (string : String ): Seq [Node ] = loadNodes(fromString(string))
122122}
0 commit comments