nokogiri 1.11.0.rc3-java → 1.11.4-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/LICENSE-DEPENDENCIES.md +1015 -947
  4. data/LICENSE.md +1 -1
  5. data/README.md +168 -91
  6. data/dependencies.yml +12 -12
  7. data/ext/java/nokogiri/EncodingHandler.java +76 -89
  8. data/ext/java/nokogiri/HtmlDocument.java +135 -144
  9. data/ext/java/nokogiri/HtmlElementDescription.java +102 -117
  10. data/ext/java/nokogiri/HtmlEntityLookup.java +33 -60
  11. data/ext/java/nokogiri/HtmlSaxParserContext.java +218 -222
  12. data/ext/java/nokogiri/HtmlSaxPushParser.java +162 -169
  13. data/ext/java/nokogiri/NokogiriService.java +595 -556
  14. data/ext/java/nokogiri/XmlAttr.java +118 -126
  15. data/ext/java/nokogiri/XmlAttributeDecl.java +95 -106
  16. data/ext/java/nokogiri/XmlCdata.java +35 -58
  17. data/ext/java/nokogiri/XmlComment.java +46 -67
  18. data/ext/java/nokogiri/XmlDocument.java +645 -572
  19. data/ext/java/nokogiri/XmlDocumentFragment.java +125 -137
  20. data/ext/java/nokogiri/XmlDtd.java +448 -414
  21. data/ext/java/nokogiri/XmlElement.java +23 -48
  22. data/ext/java/nokogiri/XmlElementContent.java +343 -316
  23. data/ext/java/nokogiri/XmlElementDecl.java +124 -125
  24. data/ext/java/nokogiri/XmlEntityDecl.java +119 -127
  25. data/ext/java/nokogiri/XmlEntityReference.java +49 -72
  26. data/ext/java/nokogiri/XmlNamespace.java +175 -175
  27. data/ext/java/nokogiri/XmlNode.java +1843 -1622
  28. data/ext/java/nokogiri/XmlNodeSet.java +361 -331
  29. data/ext/java/nokogiri/XmlProcessingInstruction.java +47 -69
  30. data/ext/java/nokogiri/XmlReader.java +513 -450
  31. data/ext/java/nokogiri/XmlRelaxng.java +89 -101
  32. data/ext/java/nokogiri/XmlSaxParserContext.java +328 -310
  33. data/ext/java/nokogiri/XmlSaxPushParser.java +227 -220
  34. data/ext/java/nokogiri/XmlSchema.java +335 -242
  35. data/ext/java/nokogiri/XmlSyntaxError.java +113 -119
  36. data/ext/java/nokogiri/XmlText.java +55 -76
  37. data/ext/java/nokogiri/XmlXpathContext.java +242 -210
  38. data/ext/java/nokogiri/XsltStylesheet.java +280 -269
  39. data/ext/java/nokogiri/internals/ClosedStreamException.java +5 -2
  40. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +201 -190
  41. data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +17 -10
  42. data/ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java +43 -16
  43. data/ext/java/nokogiri/internals/NokogiriDomParser.java +63 -80
  44. data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +107 -88
  45. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +27 -52
  46. data/ext/java/nokogiri/internals/NokogiriHandler.java +316 -286
  47. data/ext/java/nokogiri/internals/NokogiriHelpers.java +736 -652
  48. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +184 -173
  49. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +79 -89
  50. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +64 -79
  51. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +84 -99
  52. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +48 -65
  53. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +119 -78
  54. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +34 -54
  55. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +23 -46
  56. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +55 -72
  57. data/ext/java/nokogiri/internals/ParserContext.java +206 -211
  58. data/ext/java/nokogiri/internals/ReaderNode.java +478 -403
  59. data/ext/java/nokogiri/internals/SaveContextVisitor.java +822 -739
  60. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +31 -54
  61. data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +129 -123
  62. data/ext/java/nokogiri/internals/XmlDeclHandler.java +3 -34
  63. data/ext/java/nokogiri/internals/XmlDomParserContext.java +206 -207
  64. data/ext/java/nokogiri/internals/XmlSaxParser.java +22 -47
  65. data/ext/java/nokogiri/internals/c14n/AttrCompare.java +71 -68
  66. data/ext/java/nokogiri/internals/c14n/C14nHelper.java +137 -118
  67. data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +27 -21
  68. data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +74 -61
  69. data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +230 -205
  70. data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +572 -547
  71. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +17 -10
  72. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +17 -10
  73. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +323 -302
  74. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +232 -219
  75. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +22 -15
  76. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +23 -16
  77. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +23 -16
  78. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +22 -15
  79. data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +575 -545
  80. data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +141 -120
  81. data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +39 -38
  82. data/ext/java/nokogiri/internals/c14n/Constants.java +13 -10
  83. data/ext/java/nokogiri/internals/c14n/ElementProxy.java +279 -247
  84. data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +66 -53
  85. data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +44 -37
  86. data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +135 -120
  87. data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +59 -48
  88. data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +384 -334
  89. data/ext/java/nokogiri/internals/c14n/NodeFilter.java +25 -24
  90. data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +151 -140
  91. data/ext/java/nokogiri/internals/c14n/XMLUtils.java +456 -423
  92. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +1466 -1500
  93. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java +626 -574
  94. data/ext/nokogiri/depend +37 -358
  95. data/ext/nokogiri/extconf.rb +581 -374
  96. data/ext/nokogiri/html_document.c +78 -82
  97. data/ext/nokogiri/html_element_description.c +84 -71
  98. data/ext/nokogiri/html_entity_lookup.c +21 -16
  99. data/ext/nokogiri/html_sax_parser_context.c +69 -66
  100. data/ext/nokogiri/html_sax_push_parser.c +42 -34
  101. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  102. data/ext/nokogiri/nokogiri.c +192 -93
  103. data/ext/nokogiri/test_global_handlers.c +40 -0
  104. data/ext/nokogiri/xml_attr.c +15 -15
  105. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  106. data/ext/nokogiri/xml_cdata.c +13 -18
  107. data/ext/nokogiri/xml_comment.c +19 -26
  108. data/ext/nokogiri/xml_document.c +246 -188
  109. data/ext/nokogiri/xml_document_fragment.c +13 -15
  110. data/ext/nokogiri/xml_dtd.c +54 -48
  111. data/ext/nokogiri/xml_element_content.c +30 -27
  112. data/ext/nokogiri/xml_element_decl.c +22 -22
  113. data/ext/nokogiri/xml_encoding_handler.c +17 -11
  114. data/ext/nokogiri/xml_entity_decl.c +32 -30
  115. data/ext/nokogiri/xml_entity_reference.c +16 -18
  116. data/ext/nokogiri/xml_namespace.c +56 -49
  117. data/ext/nokogiri/xml_node.c +371 -320
  118. data/ext/nokogiri/xml_node_set.c +168 -156
  119. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  120. data/ext/nokogiri/xml_reader.c +191 -157
  121. data/ext/nokogiri/xml_relax_ng.c +52 -28
  122. data/ext/nokogiri/xml_sax_parser.c +118 -118
  123. data/ext/nokogiri/xml_sax_parser_context.c +103 -86
  124. data/ext/nokogiri/xml_sax_push_parser.c +36 -27
  125. data/ext/nokogiri/xml_schema.c +95 -47
  126. data/ext/nokogiri/xml_syntax_error.c +42 -21
  127. data/ext/nokogiri/xml_text.c +13 -17
  128. data/ext/nokogiri/xml_xpath_context.c +206 -123
  129. data/ext/nokogiri/xslt_stylesheet.c +158 -161
  130. data/lib/nokogiri.rb +3 -7
  131. data/lib/nokogiri/css/parser.rb +3 -3
  132. data/lib/nokogiri/css/parser.y +2 -2
  133. data/lib/nokogiri/css/xpath_visitor.rb +70 -42
  134. data/lib/nokogiri/extension.rb +26 -0
  135. data/lib/nokogiri/html/document.rb +12 -26
  136. data/lib/nokogiri/html/document_fragment.rb +15 -15
  137. data/lib/nokogiri/nokogiri.jar +0 -0
  138. data/lib/nokogiri/version.rb +2 -149
  139. data/lib/nokogiri/version/constant.rb +5 -0
  140. data/lib/nokogiri/version/info.rb +205 -0
  141. data/lib/nokogiri/xml/document.rb +91 -35
  142. data/lib/nokogiri/xml/document_fragment.rb +4 -6
  143. data/lib/nokogiri/xml/node.rb +89 -69
  144. data/lib/nokogiri/xml/parse_options.rb +6 -0
  145. data/lib/nokogiri/xml/reader.rb +2 -9
  146. data/lib/nokogiri/xml/relax_ng.rb +6 -2
  147. data/lib/nokogiri/xml/schema.rb +12 -4
  148. data/lib/nokogiri/xml/searchable.rb +3 -1
  149. data/lib/nokogiri/xml/xpath.rb +1 -3
  150. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
  151. metadata +86 -177
  152. data/ext/nokogiri/html_document.h +0 -10
  153. data/ext/nokogiri/html_element_description.h +0 -10
  154. data/ext/nokogiri/html_entity_lookup.h +0 -8
  155. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  156. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  157. data/ext/nokogiri/nokogiri.h +0 -134
  158. data/ext/nokogiri/xml_attr.h +0 -9
  159. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  160. data/ext/nokogiri/xml_cdata.h +0 -9
  161. data/ext/nokogiri/xml_comment.h +0 -9
  162. data/ext/nokogiri/xml_document.h +0 -23
  163. data/ext/nokogiri/xml_document_fragment.h +0 -10
  164. data/ext/nokogiri/xml_dtd.h +0 -10
  165. data/ext/nokogiri/xml_element_content.h +0 -10
  166. data/ext/nokogiri/xml_element_decl.h +0 -9
  167. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  168. data/ext/nokogiri/xml_entity_decl.h +0 -10
  169. data/ext/nokogiri/xml_entity_reference.h +0 -9
  170. data/ext/nokogiri/xml_io.c +0 -63
  171. data/ext/nokogiri/xml_io.h +0 -11
  172. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  173. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  174. data/ext/nokogiri/xml_namespace.h +0 -14
  175. data/ext/nokogiri/xml_node.h +0 -13
  176. data/ext/nokogiri/xml_node_set.h +0 -12
  177. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  178. data/ext/nokogiri/xml_reader.h +0 -10
  179. data/ext/nokogiri/xml_relax_ng.h +0 -9
  180. data/ext/nokogiri/xml_sax_parser.h +0 -39
  181. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  182. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  183. data/ext/nokogiri/xml_schema.h +0 -9
  184. data/ext/nokogiri/xml_syntax_error.h +0 -13
  185. data/ext/nokogiri/xml_text.h +0 -9
  186. data/ext/nokogiri/xml_xpath_context.h +0 -10
  187. data/ext/nokogiri/xslt_stylesheet.h +0 -14
@@ -1,35 +1,3 @@
1
- /**
2
- * (The MIT License)
3
- *
4
- * Copyright (c) 2008 - 2012:
5
- *
6
- * * {Aaron Patterson}[http://tenderlovemaking.com]
7
- * * {Mike Dalessio}[http://mike.daless.io]
8
- * * {Charles Nutter}[http://blog.headius.com]
9
- * * {Sergio Arbeo}[http://www.serabe.com]
10
- * * {Patrick Mahoney}[http://polycrystal.org]
11
- * * {Yoko Harada}[http://yokolet.blogspot.com]
12
- *
13
- * Permission is hereby granted, free of charge, to any person obtaining
14
- * a copy of this software and associated documentation files (the
15
- * 'Software'), to deal in the Software without restriction, including
16
- * without limitation the rights to use, copy, modify, merge, publish,
17
- * distribute, sublicense, and/or sell copies of the Software, and to
18
- * permit persons to whom the Software is furnished to do so, subject to
19
- * the following conditions:
20
- *
21
- * The above copyright notice and this permission notice shall be
22
- * included in all copies or substantial portions of the Software.
23
- *
24
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
- */
32
-
33
1
  package nokogiri.internals;
34
2
 
35
3
  import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
@@ -58,202 +26,229 @@ import org.xml.sax.InputSource;
58
26
  * @author Patrick Mahoney <pat@polycrystal.org>
59
27
  * @author Yoko Harada <yokolet@gmail.com>
60
28
  */
61
- public abstract class ParserContext extends RubyObject {
62
- protected InputSource source = null;
63
- protected IRubyObject detected_encoding = null;
64
- protected int stringDataSize = -1;
65
- protected String java_encoding;
66
-
67
- public ParserContext(Ruby runtime) {
68
- // default to class 'Object' because this class isn't exposed to Ruby
69
- super(runtime, runtime.getObject());
29
+ public abstract class ParserContext extends RubyObject
30
+ {
31
+ protected InputSource source = null;
32
+ protected IRubyObject detected_encoding = null;
33
+ protected int stringDataSize = -1;
34
+ protected String java_encoding;
35
+
36
+ public
37
+ ParserContext(Ruby runtime)
38
+ {
39
+ // default to class 'Object' because this class isn't exposed to Ruby
40
+ super(runtime, runtime.getObject());
41
+ }
42
+
43
+ public
44
+ ParserContext(Ruby runtime, RubyClass klass)
45
+ {
46
+ super(runtime, klass);
47
+ }
48
+
49
+ protected InputSource
50
+ getInputSource()
51
+ {
52
+ return source;
53
+ }
54
+
55
+ public void
56
+ setIOInputSource(ThreadContext context, IRubyObject data, IRubyObject url)
57
+ {
58
+ source = new InputSource();
59
+ ParserContext.setUrl(context, source, url);
60
+
61
+ source.setByteStream(new IOInputStream(data));
62
+ if (java_encoding != null) {
63
+ source.setEncoding(java_encoding);
70
64
  }
65
+ }
71
66
 
72
- public ParserContext(Ruby runtime, RubyClass klass) {
73
- super(runtime, klass);
74
- }
67
+ public void
68
+ setStringInputSource(ThreadContext context, IRubyObject data, IRubyObject url)
69
+ {
70
+ source = new InputSource();
71
+ ParserContext.setUrl(context, source, url);
75
72
 
76
- protected InputSource getInputSource() {
77
- return source;
78
- }
79
-
80
- public void setIOInputSource(ThreadContext context, IRubyObject data, IRubyObject url) {
81
- source = new InputSource();
82
- ParserContext.setUrl(context, source, url);
73
+ Ruby ruby = context.getRuntime();
83
74
 
84
- source.setByteStream(new IOInputStream(data));
85
- if (java_encoding != null) {
86
- source.setEncoding(java_encoding);
87
- }
75
+ if (!(data instanceof RubyString)) {
76
+ throw ruby.newArgumentError("must be kind_of String");
88
77
  }
89
78
 
90
- public void setStringInputSource(ThreadContext context, IRubyObject data, IRubyObject url) {
91
- source = new InputSource();
92
- ParserContext.setUrl(context, source, url);
93
-
94
- Ruby ruby = context.getRuntime();
95
-
96
- if (!(data instanceof RubyString)) {
97
- throw ruby.newArgumentError("must be kind_of String");
98
- }
99
-
100
- RubyString stringData = (RubyString) data;
101
-
102
- if (stringData.encoding(context) != null) {
103
- RubyString stringEncoding = stringData.encoding(context).asString();
104
- String encName = NokogiriHelpers.getValidEncodingOrNull(stringEncoding);
105
- if (encName != null) {
106
- java_encoding = encName;
107
- }
108
- }
109
-
110
- ByteList bytes = stringData.getByteList();
79
+ RubyString stringData = (RubyString) data;
111
80
 
112
- stringDataSize = bytes.length() - bytes.begin();
113
- ByteArrayInputStream stream = new ByteArrayInputStream(bytes.unsafeBytes(), bytes.begin(), bytes.length());
114
- source.setByteStream(stream);
115
- source.setEncoding(java_encoding);
81
+ if (stringData.encoding(context) != null) {
82
+ RubyString stringEncoding = stringData.encoding(context).asString();
83
+ String encName = NokogiriHelpers.getValidEncodingOrNull(stringEncoding);
84
+ if (encName != null) {
85
+ java_encoding = encName;
86
+ }
116
87
  }
117
88
 
118
- public static void setUrl(ThreadContext context, InputSource source, IRubyObject url) {
119
- String path = rubyStringToString(url);
120
- // Dir.chdir might be called at some point before this.
121
- if (path != null) {
89
+ ByteList bytes = stringData.getByteList();
90
+
91
+ stringDataSize = bytes.length() - bytes.begin();
92
+ ByteArrayInputStream stream = new ByteArrayInputStream(bytes.unsafeBytes(), bytes.begin(), bytes.length());
93
+ source.setByteStream(stream);
94
+ source.setEncoding(java_encoding);
95
+ }
96
+
97
+ public static void
98
+ setUrl(ThreadContext context, InputSource source, IRubyObject url)
99
+ {
100
+ String path = rubyStringToString(url);
101
+ // Dir.chdir might be called at some point before this.
102
+ if (path != null) {
103
+ try {
104
+ URI uri = URI.create(path);
105
+ source.setSystemId(uri.toURL().toString());
106
+ } catch (Exception ex) {
107
+ // fallback to the old behavior
108
+ File file = new File(path);
109
+ if (file.isAbsolute()) {
110
+ source.setSystemId(path);
111
+ } else {
112
+ String pwd = context.getRuntime().getCurrentDirectory();
113
+ String absolutePath;
122
114
  try {
123
- URI uri = URI.create(path);
124
- source.setSystemId(uri.toURL().toString());
125
- } catch (Exception ex) {
126
- // fallback to the old behavior
127
- File file = new File(path);
128
- if (file.isAbsolute()) {
129
- source.setSystemId(path);
130
- } else {
131
- String pwd = context.getRuntime().getCurrentDirectory();
132
- String absolutePath;
133
- try {
134
- absolutePath = new File(pwd, path).getCanonicalPath();
135
- } catch (IOException e) {
136
- absolutePath = new File(pwd, path).getAbsolutePath();
137
- }
138
- source.setSystemId(absolutePath);
139
- }
115
+ absolutePath = new File(pwd, path).getCanonicalPath();
116
+ } catch (IOException e) {
117
+ absolutePath = new File(pwd, path).getAbsolutePath();
140
118
  }
119
+ source.setSystemId(absolutePath);
141
120
  }
121
+ }
142
122
  }
143
-
144
- protected void setEncoding(String encoding) {
145
- source.setEncoding(encoding);
123
+ }
124
+
125
+ protected void
126
+ setEncoding(String encoding)
127
+ {
128
+ source.setEncoding(encoding);
129
+ }
130
+
131
+ /**
132
+ * Set the InputSource to read from <code>file</code>, a String filename.
133
+ */
134
+ public void
135
+ setInputSourceFile(ThreadContext context, IRubyObject file)
136
+ {
137
+ source = new InputSource();
138
+ ParserContext.setUrl(context, source, file);
139
+ }
140
+
141
+ /**
142
+ * Set the InputSource from <code>stream</code>.
143
+ */
144
+ public void
145
+ setInputSource(InputStream stream)
146
+ {
147
+ source = new InputSource(stream);
148
+ }
149
+
150
+ /**
151
+ * Wrap Nokogiri parser options in a utility class. This is
152
+ * read-only.
153
+ */
154
+ public static class Options
155
+ {
156
+ protected static final long STRICT = 0;
157
+ protected static final long RECOVER = 1;
158
+ protected static final long NOENT = 2;
159
+ protected static final long DTDLOAD = 4;
160
+ protected static final long DTDATTR = 8;
161
+ protected static final long DTDVALID = 16;
162
+ protected static final long NOERROR = 32;
163
+ protected static final long NOWARNING = 64;
164
+ protected static final long PEDANTIC = 128;
165
+ protected static final long NOBLANKS = 256;
166
+ protected static final long SAX1 = 512;
167
+ protected static final long XINCLUDE = 1024;
168
+ protected static final long NONET = 2048;
169
+ protected static final long NODICT = 4096;
170
+ protected static final long NSCLEAN = 8192;
171
+ protected static final long NOCDATA = 16384;
172
+ protected static final long NOXINCNODE = 32768;
173
+
174
+ public final boolean strict;
175
+ public final boolean recover;
176
+ public final boolean noEnt;
177
+ public final boolean dtdLoad;
178
+ public final boolean dtdAttr;
179
+ public final boolean dtdValid;
180
+ public final boolean noError;
181
+ public final boolean noWarning;
182
+ public final boolean pedantic;
183
+ public final boolean noBlanks;
184
+ public final boolean sax1;
185
+ public final boolean xInclude;
186
+ public final boolean noNet;
187
+ public final boolean noDict;
188
+ public final boolean nsClean;
189
+ public final boolean noCdata;
190
+ public final boolean noXIncNode;
191
+
192
+ protected static boolean
193
+ test(long options, long mask)
194
+ {
195
+ return ((options & mask) == mask);
146
196
  }
147
197
 
148
- /**
149
- * Set the InputSource to read from <code>file</code>, a String filename.
150
- */
151
- public void setInputSourceFile(ThreadContext context, IRubyObject file) {
152
- source = new InputSource();
153
- ParserContext.setUrl(context, source, file);
198
+ public
199
+ Options(long options)
200
+ {
201
+ strict = ((options & RECOVER) == STRICT);
202
+ recover = test(options, RECOVER);
203
+ noEnt = test(options, NOENT);
204
+ dtdLoad = test(options, DTDLOAD);
205
+ dtdAttr = test(options, DTDATTR);
206
+ dtdValid = test(options, DTDVALID);
207
+ noError = test(options, NOERROR);
208
+ noWarning = test(options, NOWARNING);
209
+ pedantic = test(options, PEDANTIC);
210
+ noBlanks = test(options, NOBLANKS);
211
+ sax1 = test(options, SAX1);
212
+ xInclude = test(options, XINCLUDE);
213
+ noNet = test(options, NONET);
214
+ noDict = test(options, NODICT);
215
+ nsClean = test(options, NSCLEAN);
216
+ noCdata = test(options, NOCDATA);
217
+ noXIncNode = test(options, NOXINCNODE);
154
218
  }
155
-
156
- /**
157
- * Set the InputSource from <code>stream</code>.
158
- */
159
- public void setInputSource(InputStream stream) {
160
- source = new InputSource(stream);
161
- }
162
-
163
- /**
164
- * Wrap Nokogiri parser options in a utility class. This is
165
- * read-only.
166
- */
167
- public static class Options {
168
- protected static final long STRICT = 0;
169
- protected static final long RECOVER = 1;
170
- protected static final long NOENT = 2;
171
- protected static final long DTDLOAD = 4;
172
- protected static final long DTDATTR = 8;
173
- protected static final long DTDVALID = 16;
174
- protected static final long NOERROR = 32;
175
- protected static final long NOWARNING = 64;
176
- protected static final long PEDANTIC = 128;
177
- protected static final long NOBLANKS = 256;
178
- protected static final long SAX1 = 512;
179
- protected static final long XINCLUDE = 1024;
180
- protected static final long NONET = 2048;
181
- protected static final long NODICT = 4096;
182
- protected static final long NSCLEAN = 8192;
183
- protected static final long NOCDATA = 16384;
184
- protected static final long NOXINCNODE = 32768;
185
-
186
- public final boolean strict;
187
- public final boolean recover;
188
- public final boolean noEnt;
189
- public final boolean dtdLoad;
190
- public final boolean dtdAttr;
191
- public final boolean dtdValid;
192
- public final boolean noError;
193
- public final boolean noWarning;
194
- public final boolean pedantic;
195
- public final boolean noBlanks;
196
- public final boolean sax1;
197
- public final boolean xInclude;
198
- public final boolean noNet;
199
- public final boolean noDict;
200
- public final boolean nsClean;
201
- public final boolean noCdata;
202
- public final boolean noXIncNode;
203
-
204
- protected static boolean test(long options, long mask) {
205
- return ((options & mask) == mask);
206
- }
207
-
208
- public Options(long options) {
209
- strict = ((options & RECOVER) == STRICT);
210
- recover = test(options, RECOVER);
211
- noEnt = test(options, NOENT);
212
- dtdLoad = test(options, DTDLOAD);
213
- dtdAttr = test(options, DTDATTR);
214
- dtdValid = test(options, DTDVALID);
215
- noError = test(options, NOERROR);
216
- noWarning = test(options, NOWARNING);
217
- pedantic = test(options, PEDANTIC);
218
- noBlanks = test(options, NOBLANKS);
219
- sax1 = test(options, SAX1);
220
- xInclude = test(options, XINCLUDE);
221
- noNet = test(options, NONET);
222
- noDict = test(options, NODICT);
223
- nsClean = test(options, NSCLEAN);
224
- noCdata = test(options, NOCDATA);
225
- noXIncNode = test(options, NOXINCNODE);
226
- }
219
+ }
220
+
221
+ /*
222
+ public static class NokogiriXInlcudeEntityResolver implements org.xml.sax.EntityResolver {
223
+ InputSource source;
224
+ public NokogiriXInlcudeEntityResolver(InputSource source) {
225
+ this.source = source;
226
+ }
227
+
228
+ @Override
229
+ public InputSource resolveEntity(String publicId, String systemId)
230
+ throws SAXException, IOException {
231
+ if (systemId != null) source.setSystemId(systemId);
232
+ if (publicId != null) source.setPublicId(publicId);
233
+ return source;
234
+ }
235
+ } */
236
+
237
+ public static abstract class ParserTask<T extends ParserContext> implements Callable<T>
238
+ {
239
+
240
+ protected final ThreadContext context; // TODO does not seem like a good idea!?
241
+ protected final IRubyObject handler;
242
+ protected final T parser;
243
+
244
+ protected
245
+ ParserTask(ThreadContext context, IRubyObject handler, T parser)
246
+ {
247
+ this.context = context;
248
+ this.handler = handler;
249
+ this.parser = parser;
227
250
  }
228
251
 
229
- /*
230
- public static class NokogiriXInlcudeEntityResolver implements org.xml.sax.EntityResolver {
231
- InputSource source;
232
- public NokogiriXInlcudeEntityResolver(InputSource source) {
233
- this.source = source;
234
- }
235
-
236
- @Override
237
- public InputSource resolveEntity(String publicId, String systemId)
238
- throws SAXException, IOException {
239
- if (systemId != null) source.setSystemId(systemId);
240
- if (publicId != null) source.setPublicId(publicId);
241
- return source;
242
- }
243
- } */
244
-
245
- public static abstract class ParserTask<T extends ParserContext> implements Callable<T> {
246
-
247
- protected final ThreadContext context; // TODO does not seem like a good idea!?
248
- protected final IRubyObject handler;
249
- protected final T parser;
250
-
251
- protected ParserTask(ThreadContext context, IRubyObject handler, T parser) {
252
- this.context = context;
253
- this.handler = handler;
254
- this.parser = parser;
255
- }
256
-
257
- }
252
+ }
258
253
 
259
254
  }
@@ -1,35 +1,3 @@
1
- /**
2
- * (The MIT License)
3
- *
4
- * Copyright (c) 2008 - 2011:
5
- *
6
- * * {Aaron Patterson}[http://tenderlovemaking.com]
7
- * * {Mike Dalessio}[http://mike.daless.io]
8
- * * {Charles Nutter}[http://blog.headius.com]
9
- * * {Sergio Arbeo}[http://www.serabe.com]
10
- * * {Patrick Mahoney}[http://polycrystal.org]
11
- * * {Yoko Harada}[http://yokolet.blogspot.com]
12
- *
13
- * Permission is hereby granted, free of charge, to any person obtaining
14
- * a copy of this software and associated documentation files (the
15
- * 'Software'), to deal in the Software without restriction, including
16
- * without limitation the rights to use, copy, modify, merge, publish,
17
- * distribute, sublicense, and/or sell copies of the Software, and to
18
- * permit persons to whom the Software is furnished to do so, subject to
19
- * the following conditions:
20
- *
21
- * The above copyright notice and this permission notice shall be
22
- * included in all copies or substantial portions of the Software.
23
- *
24
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
- */
32
-
33
1
  package nokogiri.internals;
34
2
 
35
3
  import java.util.ArrayList;
@@ -62,427 +30,534 @@ import static nokogiri.internals.NokogiriHelpers.*;
62
30
  * @author Yoko Harada <yokolet@gmail.com>
63
31
  *
64
32
  */
65
- public abstract class ReaderNode {
66
-
67
- final Ruby ruby;
68
- public ReaderAttributeList attributeList;
69
- public Map<String, String> namespaces;
70
- public int depth, nodeType;
71
- public String lang, localName, xmlBase, prefix, name, uri, value, xmlVersion = "1.0";
72
- public int startOffset, endOffset;
73
- public boolean hasChildren = false;
74
- private Document document = null;
75
-
76
- protected ReaderNode(final Ruby runtime) {
77
- this.ruby = runtime;
33
+ public abstract class ReaderNode
34
+ {
35
+
36
+ final Ruby ruby;
37
+ public ReaderAttributeList attributeList;
38
+ public Map<String, String> namespaces;
39
+ public int depth, nodeType;
40
+ public String lang, localName, xmlBase, prefix, name, uri, value, xmlVersion = "1.0";
41
+ public int startOffset, endOffset;
42
+ public boolean hasChildren = false;
43
+ private Document document = null;
44
+
45
+ protected
46
+ ReaderNode(final Ruby runtime)
47
+ {
48
+ this.ruby = runtime;
49
+ }
50
+
51
+ public abstract String getString();
52
+
53
+ public IRubyObject
54
+ getAttributeByIndex(IRubyObject index)
55
+ {
56
+ if (index.isNil()) { return index; }
57
+
58
+ long i = index.convertToInteger().getLongValue();
59
+ if (i > Integer.MAX_VALUE) {
60
+ throw ruby.newArgumentError("value too long to be an array index");
78
61
  }
79
62
 
80
- public abstract String getString();
81
-
82
- public IRubyObject getAttributeByIndex(IRubyObject index){
83
- if(index.isNil()) return index;
84
-
85
- long i = index.convertToInteger().getLongValue();
86
- if(i > Integer.MAX_VALUE) {
87
- throw ruby.newArgumentError("value too long to be an array index");
63
+ if (attributeList == null) { return ruby.getNil(); }
64
+ if (i < 0 || attributeList.length <= i) { return ruby.getNil(); }
65
+ return stringOrBlank(ruby, attributeList.values.get(((Long)i).intValue()));
66
+ }
67
+
68
+ public IRubyObject
69
+ getAttributeByName(IRubyObject name)
70
+ {
71
+ if (attributeList == null) { return ruby.getNil(); }
72
+ String value = attributeList.getByName(rubyStringToString(name));
73
+ return stringOrNil(ruby, value);
74
+ }
75
+
76
+ public IRubyObject
77
+ getAttributeByName(String name)
78
+ {
79
+ if (attributeList == null) { return ruby.getNil(); }
80
+ String value = attributeList.getByName(name);
81
+ return stringOrNil(ruby, value);
82
+ }
83
+
84
+ public IRubyObject
85
+ getAttributeCount()
86
+ {
87
+ if (attributeList == null) { return ruby.newFixnum(0); }
88
+ return ruby.newFixnum(attributeList.length);
89
+ }
90
+
91
+ public IRubyObject
92
+ getAttributesNodes()
93
+ {
94
+ RubyArray array = RubyArray.newArray(ruby);
95
+ if (attributeList != null && attributeList.length > 0) {
96
+ if (document == null) {
97
+ document = XmlDocument.createNewDocument(ruby);
98
+ }
99
+ for (int i = 0; i < attributeList.length; i++) {
100
+ if (!isNamespace(attributeList.names.get(i))) {
101
+ Attr attr = document.createAttributeNS(attributeList.namespaces.get(i), attributeList.names.get(i));
102
+ attr.setValue(attributeList.values.get(i));
103
+ XmlAttr xmlAttr = new XmlAttr(ruby, attr);
104
+ array.append(xmlAttr);
88
105
  }
89
-
90
- if (attributeList == null) return ruby.getNil();
91
- if (i<0 || attributeList.length <= i) return ruby.getNil();
92
- return stringOrBlank(ruby, attributeList.values.get(((Long)i).intValue()));
106
+ }
93
107
  }
94
-
95
- public IRubyObject getAttributeByName(IRubyObject name){
96
- if(attributeList == null) return ruby.getNil();
97
- String value = attributeList.getByName(rubyStringToString(name));
98
- return stringOrNil(ruby, value);
108
+ return array;
109
+ }
110
+
111
+ public IRubyObject
112
+ getAttributes(ThreadContext context)
113
+ {
114
+ final Ruby runtime = context.runtime;
115
+ if (attributeList == null) { return runtime.getNil(); }
116
+ RubyHash hash = RubyHash.newHash(runtime);
117
+ for (int i = 0; i < attributeList.length; i++) {
118
+ IRubyObject k = stringOrBlank(runtime, attributeList.names.get(i));
119
+ IRubyObject v = stringOrBlank(runtime, attributeList.values.get(i));
120
+ hash.fastASetCheckString(runtime, k, v); // hash.op_aset(context, k, v)
99
121
  }
100
-
101
- public IRubyObject getAttributeByName(String name){
102
- if(attributeList == null) return ruby.getNil();
103
- String value = attributeList.getByName(name);
104
- return stringOrNil(ruby, value);
122
+ return hash;
123
+ }
124
+
125
+ public IRubyObject
126
+ getDepth()
127
+ {
128
+ return ruby.newFixnum(depth);
129
+ }
130
+
131
+ public IRubyObject
132
+ getLang()
133
+ {
134
+ return stringOrNil(ruby, lang);
135
+ }
136
+
137
+ public IRubyObject
138
+ getLocalName()
139
+ {
140
+ return stringOrNil(ruby, localName);
141
+ }
142
+
143
+ public IRubyObject
144
+ getName()
145
+ {
146
+ return stringOrNil(ruby, name);
147
+ }
148
+
149
+ public IRubyObject
150
+ getNamespaces(ThreadContext context)
151
+ {
152
+ final Ruby runtime = context.runtime;
153
+ if (namespaces == null) { return runtime.getNil(); }
154
+ RubyHash hash = RubyHash.newHash(runtime);
155
+ for (Map.Entry<String, String> entry : namespaces.entrySet()) {
156
+ IRubyObject k = stringOrBlank(runtime, entry.getKey());
157
+ IRubyObject v = stringOrBlank(runtime, entry.getValue());
158
+ hash.fastASetCheckString(runtime, k, v); // hash.op_aset(context, k, v)
105
159
  }
106
-
107
- public IRubyObject getAttributeCount(){
108
- if(attributeList == null) return ruby.newFixnum(0);
109
- return ruby.newFixnum(attributeList.length);
160
+ return hash;
161
+ }
162
+
163
+ public IRubyObject
164
+ getXmlBase()
165
+ {
166
+ return stringOrNil(ruby, xmlBase);
167
+ }
168
+
169
+ public IRubyObject
170
+ getPrefix()
171
+ {
172
+ return stringOrNil(ruby, prefix);
173
+ }
174
+
175
+ public IRubyObject
176
+ getUri()
177
+ {
178
+ return stringOrNil(ruby, uri);
179
+ }
180
+
181
+ public IRubyObject
182
+ getValue()
183
+ {
184
+ return stringOrNil(ruby, value);
185
+ }
186
+
187
+ public IRubyObject
188
+ getXmlVersion()
189
+ {
190
+ return ruby.newString(xmlVersion);
191
+ }
192
+
193
+ public RubyBoolean
194
+ hasAttributes()
195
+ {
196
+ if (attributeList == null || attributeList.length == 0) { return ruby.getFalse(); }
197
+ return ruby.getTrue();
198
+ }
199
+
200
+ public abstract RubyBoolean hasValue();
201
+
202
+ public RubyBoolean
203
+ isDefault()
204
+ {
205
+ // TODO Implement.
206
+ return ruby.getFalse();
207
+ }
208
+
209
+ public boolean
210
+ isError() { return false; }
211
+
212
+ protected void
213
+ parsePrefix(String qName)
214
+ {
215
+ int index = qName.indexOf(':');
216
+ if (index != -1) { prefix = qName.substring(0, index); }
217
+ }
218
+
219
+ public void
220
+ setLang(String lang)
221
+ {
222
+ this.lang = lang;
223
+ }
224
+
225
+ public IRubyObject
226
+ toSyntaxError() { return ruby.getNil(); }
227
+
228
+ public IRubyObject
229
+ getNodeType() { return ruby.newFixnum(nodeType); }
230
+
231
+ public static enum ReaderNodeType {
232
+ NODE(0),
233
+ ELEMENT(1),
234
+ ATTRIBUTE(2),
235
+ TEXT(3),
236
+ CDATA(4),
237
+ ENTITY_REFERENCE(5),
238
+ ENTITY(6),
239
+ PROCESSING_INSTRUCTION(7),
240
+ COMMENT(8),
241
+ DOCUMENT(9),
242
+ DOCUMENT_TYPE(10),
243
+ DOCUMENTFRAGMENT(11),
244
+ NOTATION(12),
245
+ WHITESPACE(13),
246
+ SIGNIFICANT_WHITESPACE(14),
247
+ END_ELEMENT(15),
248
+ END_ENTITY(16),
249
+ XML_DECLARATION(17);
250
+
251
+ private final int value;
252
+ ReaderNodeType(int value)
253
+ {
254
+ this.value = value;
110
255
  }
111
256
 
112
- public IRubyObject getAttributesNodes() {
113
- RubyArray array = RubyArray.newArray(ruby);
114
- if (attributeList != null && attributeList.length > 0) {
115
- if (document == null) {
116
- document = XmlDocument.createNewDocument(ruby);
117
- }
118
- for (int i=0; i<attributeList.length; i++) {
119
- if (!isNamespace(attributeList.names.get(i))) {
120
- Attr attr = document.createAttributeNS(attributeList.namespaces.get(i), attributeList.names.get(i));
121
- attr.setValue(attributeList.values.get(i));
122
- XmlAttr xmlAttr = new XmlAttr(ruby, attr);
123
- array.append(xmlAttr);
124
- }
125
- }
126
- }
127
- return array;
257
+ public int getValue()
258
+ {
259
+ return value;
128
260
  }
129
-
130
- public IRubyObject getAttributes(ThreadContext context) {
131
- final Ruby runtime = context.runtime;
132
- if (attributeList == null) return runtime.getNil();
133
- RubyHash hash = RubyHash.newHash(runtime);
134
- for (int i=0; i<attributeList.length; i++) {
135
- IRubyObject k = stringOrBlank(runtime, attributeList.names.get(i));
136
- IRubyObject v = stringOrBlank(runtime, attributeList.values.get(i));
137
- hash.fastASetCheckString(runtime, k, v); // hash.op_aset(context, k, v)
138
- }
139
- return hash;
261
+ }
262
+
263
+ public static ClosingNode
264
+ createClosingNode(Ruby ruby, String uri, String localName, String qName, int depth, Stack<String> langStack,
265
+ Stack<String> xmlBaseStack)
266
+ {
267
+ return new ClosingNode(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
268
+ }
269
+
270
+ public static class ClosingNode extends ReaderNode
271
+ {
272
+
273
+ // public ClosingNode() {}
274
+
275
+ ClosingNode(Ruby runtime, String uri, String localName, String qName, int depth, Stack<String> langStack,
276
+ Stack<String> xmlBaseStack)
277
+ {
278
+ super(runtime);
279
+ nodeType = ReaderNodeType.END_ELEMENT.getValue();
280
+ this.uri = "".equals(uri) ? null : uri;
281
+ this.localName = ! isBlank(localName) ? localName : qName;
282
+ this.name = qName;
283
+ parsePrefix(qName);
284
+ this.depth = depth;
285
+ if (!langStack.isEmpty()) { this.lang = langStack.peek(); }
286
+ if (!xmlBaseStack.isEmpty()) { this.xmlBase = xmlBaseStack.peek(); }
140
287
  }
141
288
 
142
- public IRubyObject getDepth() {
143
- return ruby.newFixnum(depth);
289
+ @Override
290
+ public IRubyObject
291
+ getAttributeCount()
292
+ {
293
+ return ruby.newFixnum(0);
144
294
  }
145
295
 
146
- public IRubyObject getLang() {
147
- return stringOrNil(ruby, lang);
296
+ @Override
297
+ public RubyBoolean
298
+ hasValue()
299
+ {
300
+ return ruby.getFalse();
148
301
  }
149
302
 
150
- public IRubyObject getLocalName() {
151
- return stringOrNil(ruby, localName);
303
+ @Override
304
+ public String
305
+ getString()
306
+ {
307
+ return "</" + name + '>';
308
+ }
309
+ }
310
+
311
+ public static ElementNode
312
+ createElementNode(Ruby ruby, String uri, String localName, String qName, XMLAttributes attrs, int depth,
313
+ Stack<String> langStack, Stack<String> xmlBaseStack)
314
+ {
315
+ return new ElementNode(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
316
+ }
317
+
318
+ public static class ElementNode extends ReaderNode
319
+ {
320
+
321
+ // public ElementNode() {}
322
+
323
+ ElementNode(Ruby runtime, String uri, String localName, String qName, XMLAttributes attrs, int depth,
324
+ Stack<String> langStack, Stack<String> xmlBaseStack)
325
+ {
326
+ super(runtime);
327
+ this.nodeType = ReaderNodeType.ELEMENT.getValue();
328
+ this.uri = "".equals(uri) ? null : uri;
329
+ this.localName = ! isBlank(localName) ? localName : qName;
330
+ this.name = qName;
331
+ parsePrefix(qName);
332
+ this.depth = depth;
333
+ parseAttributes(attrs, langStack, xmlBaseStack);
152
334
  }
153
335
 
154
- public IRubyObject getName() {
155
- return stringOrNil(ruby, name);
336
+ @Override
337
+ public RubyBoolean
338
+ hasValue()
339
+ {
340
+ return ruby.getFalse();
156
341
  }
157
342
 
158
- public IRubyObject getNamespaces(ThreadContext context) {
159
- final Ruby runtime = context.runtime;
160
- if (namespaces == null) return runtime.getNil();
161
- RubyHash hash = RubyHash.newHash(runtime);
162
- for (Map.Entry<String, String> entry : namespaces.entrySet()) {
163
- IRubyObject k = stringOrBlank(runtime, entry.getKey());
164
- IRubyObject v = stringOrBlank(runtime, entry.getValue());
165
- hash.fastASetCheckString(runtime, k, v); // hash.op_aset(context, k, v)
343
+ private void
344
+ parseAttributes(XMLAttributes attrs, Stack<String> langStack, Stack<String> xmlBaseStack)
345
+ {
346
+ if (attrs.getLength() > 0) { attributeList = new ReaderAttributeList(); }
347
+ String u, n, v;
348
+ for (int i = 0; i < attrs.getLength(); i++) {
349
+ u = attrs.getURI(i);
350
+ n = attrs.getQName(i);
351
+ v = attrs.getValue(i);
352
+ if (isNamespace(n)) {
353
+ if (namespaces == null) { namespaces = new HashMap<String, String>(); }
354
+ namespaces.put(n, v);
355
+ } else {
356
+ if (lang == null) { lang = resolveLang(n, v, langStack); }
357
+ if (xmlBase == null) { xmlBase = resolveXmlBase(n, v, xmlBaseStack); }
166
358
  }
167
- return hash;
359
+ attributeList.add(u, n, v);
360
+ }
168
361
  }
169
362
 
170
- public IRubyObject getXmlBase() {
171
- return stringOrNil(ruby, xmlBase);
363
+ private String
364
+ resolveLang(String n, String v, Stack<String> langStack)
365
+ {
366
+ if ("xml:lang".equals(n)) {
367
+ return v;
368
+ } else if (!langStack.isEmpty()) {
369
+ return langStack.peek();
370
+ } else {
371
+ return null;
372
+ }
172
373
  }
173
374
 
174
- public IRubyObject getPrefix() {
175
- return stringOrNil(ruby, prefix);
375
+ private String
376
+ resolveXmlBase(String n, String v, Stack<String> xmlBaseStack)
377
+ {
378
+ if (isXmlBase(n)) {
379
+ return getXmlBaseUri(n, v, xmlBaseStack);
380
+ } else if (!xmlBaseStack.isEmpty()) {
381
+ return xmlBaseStack.peek();
382
+ } else {
383
+ return null;
384
+ }
176
385
  }
177
386
 
178
- public IRubyObject getUri() {
179
- return stringOrNil(ruby, uri);
387
+ private String
388
+ getXmlBaseUri(String n, String v, Stack<String> xmlBaseStack)
389
+ {
390
+ if ("xml:base".equals(n)) {
391
+ if (v.startsWith("http://")) {
392
+ return v;
393
+ } else if (v.startsWith("/") && v.endsWith("/")) {
394
+ String sub = v.substring(1, v.length() - 2);
395
+ String base = xmlBaseStack.peek();
396
+ if (base.endsWith("/")) {
397
+ base = base.substring(0, base.length() - 1);
398
+ }
399
+ int pos = base.lastIndexOf("/");
400
+ return base.substring(0, pos).concat(sub);
401
+ } else {
402
+ String base = xmlBaseStack.peek();
403
+ if (base.endsWith("/")) { return base.concat(v); }
404
+ else { return base.concat("/").concat(v); }
405
+ }
406
+ } else if ("xlink:href".equals(n)) {
407
+ if (v.startsWith("http://")) {
408
+ return v;
409
+ } else if (!xmlBaseStack.isEmpty()) {
410
+ String base = xmlBaseStack.peek();
411
+ return base;
412
+ }
413
+ }
414
+ return null;
180
415
  }
181
416
 
182
- public IRubyObject getValue() {
183
- return stringOrNil(ruby, value);
417
+ @Override
418
+ public String
419
+ getString()
420
+ {
421
+ StringBuffer sb = new StringBuffer(24);
422
+ sb.append('<').append(name);
423
+ if (attributeList != null) {
424
+ for (int i = 0; i < attributeList.length; i++) {
425
+ String n = attributeList.names.get(i);
426
+ String v = attributeList.values.get(i);
427
+ sb.append(' ').append(n).append('=')
428
+ .append('"').append(v).append('"');
429
+ }
430
+ }
431
+ if (hasChildren) { sb.append('>'); }
432
+ else { sb.append("/>"); }
433
+ return sb.toString();
184
434
  }
185
-
186
- public IRubyObject getXmlVersion() {
187
- return ruby.newString(xmlVersion);
435
+ }
436
+
437
+ private static class ReaderAttributeList
438
+ {
439
+ final List<String> namespaces = new ArrayList<String>();
440
+ final List<String> names = new ArrayList<String>();
441
+ final List<String> values = new ArrayList<String>();
442
+ int length = 0;
443
+
444
+ void
445
+ add(String namespace, String name, String value)
446
+ {
447
+ namespaces.add(namespace != null ? namespace : "");
448
+ names.add(name != null ? name : "");
449
+ values.add(value != null ? value : "");
450
+ length++;
188
451
  }
189
452
 
190
- public RubyBoolean hasAttributes() {
191
- if (attributeList == null || attributeList.length == 0) return ruby.getFalse();
192
- return ruby.getTrue();
453
+ String
454
+ getByName(String name)
455
+ {
456
+ for (int i = 0; i < names.size(); i++) {
457
+ if (name.equals(names.get(i))) {
458
+ return values.get(i);
459
+ }
460
+ }
461
+ return null;
193
462
  }
463
+ }
194
464
 
195
- public abstract RubyBoolean hasValue();
465
+ public static class EmptyNode extends ReaderNode
466
+ {
196
467
 
197
- public RubyBoolean isDefault(){
198
- // TODO Implement.
199
- return ruby.getFalse();
468
+ public
469
+ EmptyNode(Ruby runtime)
470
+ {
471
+ super(runtime);
472
+ this.nodeType = ReaderNodeType.NODE.getValue();
200
473
  }
201
474
 
202
- public boolean isError() { return false; }
203
-
204
- protected void parsePrefix(String qName) {
205
- int index = qName.indexOf(':');
206
- if(index != -1) prefix = qName.substring(0, index);
475
+ @Override
476
+ public IRubyObject
477
+ getXmlVersion()
478
+ {
479
+ return this.ruby.getNil();
207
480
  }
208
481
 
209
- public void setLang(String lang) {
210
- this.lang = lang;
482
+ @Override
483
+ public RubyBoolean
484
+ hasValue()
485
+ {
486
+ return ruby.getFalse();
211
487
  }
212
488
 
213
- public IRubyObject toSyntaxError() { return ruby.getNil(); }
214
-
215
- public IRubyObject getNodeType() { return ruby.newFixnum(nodeType); }
216
-
217
- public static enum ReaderNodeType {
218
- NODE(0),
219
- ELEMENT(1),
220
- ATTRIBUTE(2),
221
- TEXT(3),
222
- CDATA(4),
223
- ENTITY_REFERENCE(5),
224
- ENTITY(6),
225
- PROCESSING_INSTRUCTION(7),
226
- COMMENT(8),
227
- DOCUMENT(9),
228
- DOCUMENT_TYPE(10),
229
- DOCUMENTFRAGMENT(11),
230
- NOTATION(12),
231
- WHITESPACE(13),
232
- SIGNIFICANT_WHITESPACE(14),
233
- END_ELEMENT(15),
234
- END_ENTITY(16),
235
- XML_DECLARATION(17);
236
-
237
- private final int value;
238
- ReaderNodeType(int value) {
239
- this.value = value;
240
- }
241
-
242
- public int getValue() {
243
- return value;
244
- }
489
+ @Override
490
+ public String
491
+ getString()
492
+ {
493
+ return null;
245
494
  }
246
-
247
- public static ClosingNode createClosingNode(Ruby ruby, String uri, String localName, String qName, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
248
- return new ClosingNode(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
495
+ }
496
+
497
+ public static class ExceptionNode extends EmptyNode
498
+ {
499
+ private final XmlSyntaxError exception;
500
+
501
+ public
502
+ ExceptionNode(Ruby runtime, Exception ex)
503
+ {
504
+ super(runtime);
505
+ exception = XmlSyntaxError.createXMLSyntaxError(runtime); // Nokogiri::XML::SyntaxError
506
+ exception.setException(ex);
249
507
  }
250
508
 
251
- public static class ClosingNode extends ReaderNode {
252
-
253
- // public ClosingNode() {}
254
-
255
- ClosingNode(Ruby runtime, String uri, String localName, String qName, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
256
- super(runtime);
257
- nodeType = ReaderNodeType.END_ELEMENT.getValue();
258
- this.uri = "".equals(uri) ? null : uri;
259
- this.localName = ! isBlank(localName) ? localName : qName;
260
- this.name = qName;
261
- parsePrefix(qName);
262
- this.depth = depth;
263
- if (!langStack.isEmpty()) this.lang = langStack.peek();
264
- if (!xmlBaseStack.isEmpty()) this.xmlBase = xmlBaseStack.peek();
265
- }
266
-
267
- @Override
268
- public IRubyObject getAttributeCount() {
269
- return ruby.newFixnum(0);
270
- }
271
-
272
- @Override
273
- public RubyBoolean hasValue() {
274
- return ruby.getFalse();
275
- }
276
-
277
- @Override
278
- public String getString() {
279
- return "</" + name + '>';
280
- }
509
+ @Override
510
+ public boolean
511
+ isError()
512
+ {
513
+ return true;
281
514
  }
282
515
 
283
- public static ElementNode createElementNode(Ruby ruby, String uri, String localName, String qName, XMLAttributes attrs, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
284
- return new ElementNode(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
516
+ @Override
517
+ public IRubyObject
518
+ toSyntaxError()
519
+ {
520
+ return this.exception;
285
521
  }
286
-
287
- public static class ElementNode extends ReaderNode {
288
-
289
- // public ElementNode() {}
290
-
291
- ElementNode(Ruby runtime, String uri, String localName, String qName, XMLAttributes attrs, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
292
- super(runtime);
293
- this.nodeType = ReaderNodeType.ELEMENT.getValue();
294
- this.uri = "".equals(uri) ? null : uri;
295
- this.localName = ! isBlank(localName) ? localName : qName;
296
- this.name = qName;
297
- parsePrefix(qName);
298
- this.depth = depth;
299
- parseAttributes(attrs, langStack, xmlBaseStack);
300
- }
301
-
302
- @Override
303
- public RubyBoolean hasValue() {
304
- return ruby.getFalse();
305
- }
306
-
307
- private void parseAttributes(XMLAttributes attrs, Stack<String> langStack, Stack<String> xmlBaseStack) {
308
- if (attrs.getLength() > 0) attributeList = new ReaderAttributeList();
309
- String u, n, v;
310
- for (int i = 0; i < attrs.getLength(); i++) {
311
- u = attrs.getURI(i);
312
- n = attrs.getQName(i);
313
- v = attrs.getValue(i);
314
- if (isNamespace(n)) {
315
- if (namespaces == null) namespaces = new HashMap<String, String>();
316
- namespaces.put(n, v);
317
- } else {
318
- if (lang == null) lang = resolveLang(n, v, langStack);
319
- if (xmlBase == null) xmlBase = resolveXmlBase(n, v, xmlBaseStack);
320
- }
321
- attributeList.add(u, n, v);
322
- }
323
- }
324
-
325
- private String resolveLang(String n, String v, Stack<String> langStack) {
326
- if ("xml:lang".equals(n)) {
327
- return v;
328
- } else if (!langStack.isEmpty()) {
329
- return langStack.peek();
330
- } else {
331
- return null;
332
- }
333
- }
334
-
335
- private String resolveXmlBase(String n, String v, Stack<String> xmlBaseStack) {
336
- if (isXmlBase(n)) {
337
- return getXmlBaseUri(n, v, xmlBaseStack);
338
- } else if (!xmlBaseStack.isEmpty()) {
339
- return xmlBaseStack.peek();
340
- } else {
341
- return null;
342
- }
343
- }
344
-
345
- private String getXmlBaseUri(String n, String v, Stack<String> xmlBaseStack) {
346
- if ("xml:base".equals(n)) {
347
- if (v.startsWith("http://")) {
348
- return v;
349
- } else if (v.startsWith("/") && v.endsWith("/")) {
350
- String sub = v.substring(1, v.length() - 2);
351
- String base = xmlBaseStack.peek();
352
- if (base.endsWith("/")) {
353
- base = base.substring(0, base.length() - 1);
354
- }
355
- int pos = base.lastIndexOf("/");
356
- return base.substring(0, pos).concat(sub);
357
- } else {
358
- String base = xmlBaseStack.peek();
359
- if (base.endsWith("/")) return base.concat(v);
360
- else return base.concat("/").concat(v);
361
- }
362
- } else if ("xlink:href".equals(n)) {
363
- if (v.startsWith("http://")) {
364
- return v;
365
- } else if (!xmlBaseStack.isEmpty()) {
366
- String base = xmlBaseStack.peek();
367
- return base;
368
- }
369
- }
370
- return null;
371
- }
372
-
373
- @Override
374
- public String getString() {
375
- StringBuffer sb = new StringBuffer(24);
376
- sb.append('<').append(name);
377
- if (attributeList != null) {
378
- for (int i=0; i<attributeList.length; i++) {
379
- String n = attributeList.names.get(i);
380
- String v = attributeList.values.get(i);
381
- sb.append(' ').append(n).append('=')
382
- .append('"').append(v).append('"');
383
- }
384
- }
385
- if (hasChildren) sb.append('>');
386
- else sb.append("/>");
387
- return sb.toString();
388
- }
522
+ }
523
+
524
+ public static TextNode
525
+ createTextNode(Ruby ruby, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack)
526
+ {
527
+ return new TextNode(ruby, content, depth, langStack, xmlBaseStack);
528
+ }
529
+
530
+ public static class TextNode extends ReaderNode
531
+ {
532
+
533
+ // public TextNode() {}
534
+
535
+ TextNode(Ruby runtime, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack)
536
+ {
537
+ super(runtime);
538
+ this.value = content;
539
+ this.localName = "#text";
540
+ this.name = "#text";
541
+ this.depth = depth;
542
+ if (!isBlank(content)) { nodeType = ReaderNodeType.TEXT.getValue(); }
543
+ else { nodeType = ReaderNodeType.SIGNIFICANT_WHITESPACE.getValue(); }
544
+ if (!langStack.isEmpty()) { this.lang = langStack.peek(); }
545
+ if (!xmlBaseStack.isEmpty()) { this.xmlBase = xmlBaseStack.peek(); }
389
546
  }
390
547
 
391
- private static class ReaderAttributeList {
392
- final List<String> namespaces = new ArrayList<String>();
393
- final List<String> names = new ArrayList<String>();
394
- final List<String> values = new ArrayList<String>();
395
- int length = 0;
396
-
397
- void add(String namespace, String name, String value) {
398
- namespaces.add(namespace != null ? namespace : "");
399
- names.add(name != null ? name : "");
400
- values.add(value != null ? value : "");
401
- length++;
402
- }
403
-
404
- String getByName(String name) {
405
- for (int i=0; i<names.size(); i++) {
406
- if (name.equals(names.get(i))) {
407
- return values.get(i);
408
- }
409
- }
410
- return null;
411
- }
548
+ @Override
549
+ public RubyBoolean
550
+ hasValue()
551
+ {
552
+ return ruby.getTrue();
412
553
  }
413
554
 
414
- public static class EmptyNode extends ReaderNode {
415
-
416
- public EmptyNode(Ruby runtime) {
417
- super(runtime);
418
- this.nodeType = ReaderNodeType.NODE.getValue();
419
- }
420
-
421
- @Override
422
- public IRubyObject getXmlVersion() {
423
- return this.ruby.getNil();
424
- }
425
-
426
- @Override
427
- public RubyBoolean hasValue() {
428
- return ruby.getFalse();
429
- }
430
-
431
- @Override
432
- public String getString() {
433
- return null;
434
- }
435
- }
436
-
437
- public static class ExceptionNode extends EmptyNode {
438
- private final XmlSyntaxError exception;
439
-
440
- public ExceptionNode(Ruby runtime, Exception ex) {
441
- super(runtime);
442
- exception = XmlSyntaxError.createXMLSyntaxError(runtime); // Nokogiri::XML::SyntaxError
443
- exception.setException(ex);
444
- }
445
-
446
- @Override
447
- public boolean isError() {
448
- return true;
449
- }
450
-
451
- @Override
452
- public IRubyObject toSyntaxError() {
453
- return this.exception;
454
- }
455
- }
456
-
457
- public static TextNode createTextNode(Ruby ruby, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
458
- return new TextNode(ruby, content, depth, langStack, xmlBaseStack);
459
- }
460
-
461
- public static class TextNode extends ReaderNode {
462
-
463
- // public TextNode() {}
464
-
465
- TextNode(Ruby runtime, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
466
- super(runtime);
467
- this.value = content;
468
- this.localName = "#text";
469
- this.name = "#text";
470
- this.depth = depth;
471
- if (!isBlank(content)) nodeType = ReaderNodeType.TEXT.getValue();
472
- else nodeType = ReaderNodeType.SIGNIFICANT_WHITESPACE.getValue();
473
- if (!langStack.isEmpty()) this.lang = langStack.peek();
474
- if (!xmlBaseStack.isEmpty()) this.xmlBase = xmlBaseStack.peek();
475
- }
476
-
477
- @Override
478
- public RubyBoolean hasValue() {
479
- return ruby.getTrue();
480
- }
481
-
482
- @Override
483
- public String getString() {
484
- return value;
485
- }
555
+ @Override
556
+ public String
557
+ getString()
558
+ {
559
+ return value;
486
560
  }
561
+ }
487
562
 
488
563
  }