@@ -14,32 +14,36 @@ package scala
14
14
package xml
15
15
package factory
16
16
17
- import org .xml .sax .{SAXNotRecognizedException , XMLReader }
17
+ import org .xml .sax .{SAXNotRecognizedException , SAXNotSupportedException , XMLReader }
18
18
import javax .xml .parsers .SAXParserFactory
19
19
import parsing .{FactoryAdapter , NoBindingFactoryAdapter }
20
20
import java .io .{File , FileDescriptor , InputStream , Reader }
21
21
import java .net .URL
22
22
23
23
/**
24
24
* 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" .
26
26
*/
27
27
trait XMLLoader [T <: Node ] {
28
28
import scala .xml .Source ._
29
29
def adapter : FactoryAdapter = new NoBindingFactoryAdapter ()
30
30
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
+
31
42
private lazy val parserInstance : ThreadLocal [SAXParser ] = new ThreadLocal [SAXParser ] {
32
43
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
43
47
}
44
48
}
45
49
@@ -51,72 +55,68 @@ trait XMLLoader[T <: Node] {
51
55
52
56
/**
53
57
* 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).
55
60
*/
56
- def loadXML (source : InputSource , parser : SAXParser ): T = loadXML(source , parser.getXMLReader)
61
+ def loadXML (inputSource : InputSource , parser : SAXParser ): T = loadXML(inputSource , parser.getXMLReader)
57
62
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)
59
64
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)
62
67
result.rootElem.asInstanceOf [T ]
63
68
}
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)
67
72
result.prolog ++ (result.rootElem :: result.epilogue)
68
73
}
69
74
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" )
72
77
73
78
val result : FactoryAdapter = adapter
74
79
75
- reader .setContentHandler(result)
76
- reader .setDTDHandler(result)
80
+ xmlReader .setContentHandler(result)
81
+ xmlReader .setDTDHandler(result)
77
82
/* Do not overwrite pre-configured EntityResolver. */
78
- if (reader .getEntityResolver == null ) reader .setEntityResolver(result)
83
+ if (xmlReader .getEntityResolver == null ) xmlReader .setEntityResolver(result)
79
84
/* Do not overwrite pre-configured ErrorHandler. */
80
- if (reader .getErrorHandler == null ) reader .setErrorHandler(result)
85
+ if (xmlReader .getErrorHandler == null ) xmlReader .setErrorHandler(result)
81
86
82
87
try {
83
- reader .setProperty(" http://xml.org/sax/properties/lexical-handler" , result)
88
+ xmlReader .setProperty(" http://xml.org/sax/properties/lexical-handler" , result)
84
89
} catch {
85
90
case _ : SAXNotRecognizedException =>
91
+ case _ : SAXNotSupportedException =>
86
92
}
87
93
88
94
result.scopeStack = TopScope :: result.scopeStack
89
- reader .parse(source )
95
+ xmlReader .parse(inputSource )
90
96
result.scopeStack = result.scopeStack.tail
91
97
92
98
result
93
99
}
94
100
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))
99
104
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))
105
109
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. */
110
110
def loadString (string : String ): T = load(fromString(string))
111
111
112
112
/** 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))
114
115
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))
118
120
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()))
121
121
def loadStringNodes (string : String ): Seq [Node ] = loadNodes(fromString(string))
122
122
}
0 commit comments