nokogiri 1.11.1-java → 1.11.2-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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE-DEPENDENCIES.md +12 -12
  3. data/LICENSE.md +1 -1
  4. data/README.md +20 -15
  5. data/ext/java/nokogiri/EncodingHandler.java +78 -59
  6. data/ext/java/nokogiri/HtmlDocument.java +137 -114
  7. data/ext/java/nokogiri/HtmlElementDescription.java +104 -87
  8. data/ext/java/nokogiri/HtmlEntityLookup.java +31 -26
  9. data/ext/java/nokogiri/HtmlSaxParserContext.java +220 -192
  10. data/ext/java/nokogiri/HtmlSaxPushParser.java +164 -139
  11. data/ext/java/nokogiri/NokogiriService.java +597 -526
  12. data/ext/java/nokogiri/XmlAttr.java +120 -96
  13. data/ext/java/nokogiri/XmlAttributeDecl.java +97 -76
  14. data/ext/java/nokogiri/XmlCdata.java +35 -26
  15. data/ext/java/nokogiri/XmlComment.java +48 -37
  16. data/ext/java/nokogiri/XmlDocument.java +642 -540
  17. data/ext/java/nokogiri/XmlDocumentFragment.java +127 -107
  18. data/ext/java/nokogiri/XmlDtd.java +450 -384
  19. data/ext/java/nokogiri/XmlElement.java +25 -18
  20. data/ext/java/nokogiri/XmlElementContent.java +345 -286
  21. data/ext/java/nokogiri/XmlElementDecl.java +126 -95
  22. data/ext/java/nokogiri/XmlEntityDecl.java +121 -97
  23. data/ext/java/nokogiri/XmlEntityReference.java +51 -42
  24. data/ext/java/nokogiri/XmlNamespace.java +177 -145
  25. data/ext/java/nokogiri/XmlNode.java +1843 -1588
  26. data/ext/java/nokogiri/XmlNodeSet.java +361 -299
  27. data/ext/java/nokogiri/XmlProcessingInstruction.java +49 -39
  28. data/ext/java/nokogiri/XmlReader.java +513 -418
  29. data/ext/java/nokogiri/XmlRelaxng.java +91 -78
  30. data/ext/java/nokogiri/XmlSaxParserContext.java +330 -285
  31. data/ext/java/nokogiri/XmlSaxPushParser.java +229 -190
  32. data/ext/java/nokogiri/XmlSchema.java +328 -263
  33. data/ext/java/nokogiri/XmlSyntaxError.java +113 -83
  34. data/ext/java/nokogiri/XmlText.java +57 -46
  35. data/ext/java/nokogiri/XmlXpathContext.java +240 -206
  36. data/ext/java/nokogiri/XsltStylesheet.java +282 -239
  37. data/ext/java/nokogiri/internals/ClosedStreamException.java +5 -2
  38. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +199 -168
  39. data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +17 -10
  40. data/ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java +43 -16
  41. data/ext/java/nokogiri/internals/NokogiriDomParser.java +65 -50
  42. data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +107 -88
  43. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +25 -18
  44. data/ext/java/nokogiri/internals/NokogiriHandler.java +316 -254
  45. data/ext/java/nokogiri/internals/NokogiriHelpers.java +738 -622
  46. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +186 -143
  47. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +83 -68
  48. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +66 -49
  49. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +86 -69
  50. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +44 -29
  51. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +118 -101
  52. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +34 -24
  53. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +25 -17
  54. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +57 -42
  55. data/ext/java/nokogiri/internals/ParserContext.java +206 -179
  56. data/ext/java/nokogiri/internals/ReaderNode.java +478 -371
  57. data/ext/java/nokogiri/internals/SaveContextVisitor.java +822 -707
  58. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +28 -19
  59. data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +129 -123
  60. data/ext/java/nokogiri/internals/XmlDeclHandler.java +5 -4
  61. data/ext/java/nokogiri/internals/XmlDomParserContext.java +208 -177
  62. data/ext/java/nokogiri/internals/XmlSaxParser.java +24 -17
  63. data/ext/java/nokogiri/internals/c14n/AttrCompare.java +71 -68
  64. data/ext/java/nokogiri/internals/c14n/C14nHelper.java +137 -118
  65. data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +27 -21
  66. data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +74 -61
  67. data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +230 -205
  68. data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +572 -547
  69. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +17 -10
  70. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +17 -10
  71. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +323 -302
  72. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +232 -219
  73. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +22 -15
  74. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +23 -16
  75. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +23 -16
  76. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +22 -15
  77. data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +575 -545
  78. data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +141 -120
  79. data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +39 -38
  80. data/ext/java/nokogiri/internals/c14n/Constants.java +13 -10
  81. data/ext/java/nokogiri/internals/c14n/ElementProxy.java +279 -247
  82. data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +66 -53
  83. data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +44 -37
  84. data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +135 -120
  85. data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +59 -48
  86. data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +384 -334
  87. data/ext/java/nokogiri/internals/c14n/NodeFilter.java +25 -24
  88. data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +151 -140
  89. data/ext/java/nokogiri/internals/c14n/XMLUtils.java +456 -423
  90. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +1466 -1500
  91. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java +626 -570
  92. data/ext/nokogiri/depend +34 -474
  93. data/ext/nokogiri/extconf.rb +253 -183
  94. data/ext/nokogiri/html_document.c +10 -15
  95. data/ext/nokogiri/html_element_description.c +84 -71
  96. data/ext/nokogiri/html_entity_lookup.c +21 -16
  97. data/ext/nokogiri/html_sax_parser_context.c +66 -65
  98. data/ext/nokogiri/html_sax_push_parser.c +29 -27
  99. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  100. data/ext/nokogiri/nokogiri.c +171 -63
  101. data/ext/nokogiri/test_global_handlers.c +3 -4
  102. data/ext/nokogiri/xml_attr.c +15 -15
  103. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  104. data/ext/nokogiri/xml_cdata.c +13 -18
  105. data/ext/nokogiri/xml_comment.c +19 -26
  106. data/ext/nokogiri/xml_document.c +221 -164
  107. data/ext/nokogiri/xml_document_fragment.c +13 -15
  108. data/ext/nokogiri/xml_dtd.c +54 -48
  109. data/ext/nokogiri/xml_element_content.c +30 -27
  110. data/ext/nokogiri/xml_element_decl.c +22 -22
  111. data/ext/nokogiri/xml_encoding_handler.c +17 -11
  112. data/ext/nokogiri/xml_entity_decl.c +32 -30
  113. data/ext/nokogiri/xml_entity_reference.c +16 -18
  114. data/ext/nokogiri/xml_namespace.c +56 -49
  115. data/ext/nokogiri/xml_node.c +338 -286
  116. data/ext/nokogiri/xml_node_set.c +168 -156
  117. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  118. data/ext/nokogiri/xml_reader.c +191 -157
  119. data/ext/nokogiri/xml_relax_ng.c +29 -23
  120. data/ext/nokogiri/xml_sax_parser.c +117 -112
  121. data/ext/nokogiri/xml_sax_parser_context.c +100 -85
  122. data/ext/nokogiri/xml_sax_push_parser.c +34 -27
  123. data/ext/nokogiri/xml_schema.c +48 -42
  124. data/ext/nokogiri/xml_syntax_error.c +21 -23
  125. data/ext/nokogiri/xml_text.c +13 -17
  126. data/ext/nokogiri/xml_xpath_context.c +134 -127
  127. data/ext/nokogiri/xslt_stylesheet.c +157 -157
  128. data/lib/nokogiri.rb +1 -22
  129. data/lib/nokogiri/css/parser.rb +1 -1
  130. data/lib/nokogiri/extension.rb +26 -0
  131. data/lib/nokogiri/html/document_fragment.rb +15 -15
  132. data/lib/nokogiri/nokogiri.jar +0 -0
  133. data/lib/nokogiri/version/constant.rb +1 -1
  134. data/lib/nokogiri/version/info.rb +31 -8
  135. data/lib/nokogiri/xml/document.rb +31 -11
  136. data/lib/nokogiri/xml/node.rb +38 -42
  137. data/lib/nokogiri/xml/reader.rb +2 -9
  138. data/lib/nokogiri/xml/xpath.rb +1 -3
  139. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
  140. metadata +7 -8
  141. data/ext/nokogiri/xml_io.c +0 -63
  142. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
@@ -17,10 +17,10 @@
17
17
  * distribute, sublicense, and/or sell copies of the Software, and to
18
18
  * permit persons to whom the Software is furnished to do so, subject to
19
19
  * the following conditions:
20
- *
20
+ *
21
21
  * The above copyright notice and this permission notice shall be
22
22
  * included in all copies or substantial portions of the Software.
23
- *
23
+ *
24
24
  * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
25
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
26
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -49,52 +49,62 @@ import nokogiri.internals.SaveContextVisitor;
49
49
 
50
50
  /**
51
51
  * Class for Nokogiri::XML::ProcessingInstruction
52
- *
52
+ *
53
53
  * @author sergio
54
54
  * @author Yoko Harada <yokolet@gmail.com>
55
55
  */
56
- @JRubyClass(name="Nokogiri::XML::ProcessingInstruction", parent="Nokogiri::XML::Node")
57
- public class XmlProcessingInstruction extends XmlNode {
56
+ @JRubyClass(name = "Nokogiri::XML::ProcessingInstruction", parent = "Nokogiri::XML::Node")
57
+ public class XmlProcessingInstruction extends XmlNode
58
+ {
59
+
60
+ public
61
+ XmlProcessingInstruction(Ruby ruby, RubyClass klazz)
62
+ {
63
+ super(ruby, klazz);
64
+ }
65
+
66
+ public
67
+ XmlProcessingInstruction(Ruby ruby, RubyClass klazz, Node node)
68
+ {
69
+ super(ruby, klazz, node);
70
+ }
58
71
 
59
- public XmlProcessingInstruction(Ruby ruby, RubyClass klazz) {
60
- super(ruby, klazz);
61
- }
62
-
63
- public XmlProcessingInstruction(Ruby ruby, RubyClass klazz, Node node) {
64
- super(ruby, klazz, node);
65
- }
72
+ @JRubyMethod(name = "new", meta = true, rest = true, required = 3)
73
+ public static IRubyObject
74
+ rbNew(ThreadContext context,
75
+ IRubyObject klazz,
76
+ IRubyObject[] args)
77
+ {
66
78
 
67
- @JRubyMethod(name="new", meta=true, rest=true, required=3)
68
- public static IRubyObject rbNew(ThreadContext context,
69
- IRubyObject klazz,
70
- IRubyObject[] args) {
79
+ IRubyObject doc = args[0];
80
+ IRubyObject target = args[1];
81
+ IRubyObject data = args[2];
71
82
 
72
- IRubyObject doc = args[0];
73
- IRubyObject target = args[1];
74
- IRubyObject data = args[2];
83
+ Document document = ((XmlNode) doc).getOwnerDocument();
84
+ Node node =
85
+ document.createProcessingInstruction(rubyStringToString(target),
86
+ rubyStringToString(data));
87
+ XmlProcessingInstruction self =
88
+ new XmlProcessingInstruction(context.getRuntime(),
89
+ (RubyClass) klazz,
90
+ node);
75
91
 
76
- Document document = ((XmlNode) doc).getOwnerDocument();
77
- Node node =
78
- document.createProcessingInstruction(rubyStringToString(target),
79
- rubyStringToString(data));
80
- XmlProcessingInstruction self =
81
- new XmlProcessingInstruction(context.getRuntime(),
82
- (RubyClass) klazz,
83
- node);
92
+ Helpers.invoke(context, self, "initialize", args);
84
93
 
85
- Helpers.invoke(context, self, "initialize", args);
94
+ // TODO: if_block_given.
86
95
 
87
- // TODO: if_block_given.
96
+ return self;
97
+ }
88
98
 
89
- return self;
90
- }
99
+ @Override
100
+ public boolean
101
+ isProcessingInstruction() { return true; }
91
102
 
92
- @Override
93
- public boolean isProcessingInstruction() { return true; }
94
-
95
- @Override
96
- public void accept(ThreadContext context, SaveContextVisitor visitor) {
97
- visitor.enter((ProcessingInstruction)node);
98
- visitor.leave((ProcessingInstruction)node);
99
- }
103
+ @Override
104
+ public void
105
+ accept(ThreadContext context, SaveContextVisitor visitor)
106
+ {
107
+ visitor.enter((ProcessingInstruction)node);
108
+ visitor.leave((ProcessingInstruction)node);
109
+ }
100
110
  }
@@ -86,446 +86,541 @@ import nokogiri.internals.ReaderNode.TextNode;
86
86
  * @author sergio
87
87
  * @author Yoko Harada <yokolet@gmail.com>
88
88
  */
89
- @JRubyClass(name="Nokogiri::XML::Reader")
90
- public class XmlReader extends RubyObject {
91
-
92
- private static final int XML_TEXTREADER_MODE_INITIAL = 0;
93
- private static final int XML_TEXTREADER_MODE_INTERACTIVE = 1;
94
- private static final int XML_TEXTREADER_MODE_ERROR = 2;
95
- private static final int XML_TEXTREADER_MODE_EOF = 3;
96
- private static final int XML_TEXTREADER_MODE_CLOSED = 4;
97
- private static final int XML_TEXTREADER_MODE_READING = 5;
98
-
99
- List<ReaderNode> nodeQueue;
100
- private int state;
101
- private int position = 0;
102
- private XMLPullParserConfiguration config;
103
- private boolean continueParsing = true;
104
-
105
- public XmlReader(Ruby runtime, RubyClass klazz) {
106
- super(runtime, klazz);
89
+ @JRubyClass(name = "Nokogiri::XML::Reader")
90
+ public class XmlReader extends RubyObject
91
+ {
92
+
93
+ private static final int XML_TEXTREADER_MODE_INITIAL = 0;
94
+ private static final int XML_TEXTREADER_MODE_INTERACTIVE = 1;
95
+ private static final int XML_TEXTREADER_MODE_ERROR = 2;
96
+ private static final int XML_TEXTREADER_MODE_EOF = 3;
97
+ private static final int XML_TEXTREADER_MODE_CLOSED = 4;
98
+ private static final int XML_TEXTREADER_MODE_READING = 5;
99
+
100
+ List<ReaderNode> nodeQueue;
101
+ private int state;
102
+ private int position = 0;
103
+ private XMLPullParserConfiguration config;
104
+ private boolean continueParsing = true;
105
+
106
+ public
107
+ XmlReader(Ruby runtime, RubyClass klazz)
108
+ {
109
+ super(runtime, klazz);
110
+ }
111
+
112
+ /**
113
+ * Create and return a copy of this object.
114
+ *
115
+ * @return a clone of this object
116
+ */
117
+ @Override
118
+ public Object
119
+ clone() throws CloneNotSupportedException
120
+ {
121
+ return super.clone();
122
+ }
123
+
124
+ public void
125
+ init(Ruby runtime)
126
+ {
127
+ nodeQueue = new LinkedList<ReaderNode>();
128
+ nodeQueue.add(new ReaderNode.EmptyNode(runtime));
129
+ }
130
+
131
+ private void
132
+ setInput(ThreadContext context, InputStream in, IRubyObject url, Options options)
133
+ {
134
+ this.setState(XML_TEXTREADER_MODE_READING);
135
+ config = this.createReader(context.getRuntime(), options);
136
+ InputSource inputSource = new InputSource();
137
+ ParserContext.setUrl(context, inputSource, url);
138
+ XMLInputSource xmlInputSource = new XMLInputSource(inputSource.getPublicId(),
139
+ inputSource.getSystemId(), null, in, null);
140
+ try {
141
+ config.setInputSource(xmlInputSource);
142
+ } catch (IOException e) {
143
+ throw context.getRuntime().newRuntimeError(e.getMessage());
144
+ }
145
+ this.setState(XML_TEXTREADER_MODE_CLOSED);
146
+ }
147
+
148
+ private void
149
+ setState(int state) { this.state = state; }
150
+
151
+ @JRubyMethod
152
+ public IRubyObject
153
+ attribute(ThreadContext context, IRubyObject name)
154
+ {
155
+ return currentNode().getAttributeByName(name);
156
+ }
157
+
158
+ @JRubyMethod
159
+ public IRubyObject
160
+ attribute_at(ThreadContext context, IRubyObject index)
161
+ {
162
+ return currentNode().getAttributeByIndex(index);
163
+ }
164
+
165
+ @JRubyMethod
166
+ public IRubyObject
167
+ attribute_count(ThreadContext context)
168
+ {
169
+ return currentNode().getAttributeCount();
170
+ }
171
+
172
+ @JRubyMethod
173
+ public IRubyObject
174
+ attribute_nodes(ThreadContext context)
175
+ {
176
+ return currentNode().getAttributesNodes();
177
+ }
178
+
179
+ @JRubyMethod(name = "attributes?")
180
+ public IRubyObject
181
+ attributes_p(ThreadContext context)
182
+ {
183
+ return currentNode().hasAttributes();
184
+ }
185
+
186
+ @JRubyMethod
187
+ public IRubyObject
188
+ base_uri(ThreadContext context)
189
+ {
190
+ return currentNode().getXmlBase();
191
+ }
192
+
193
+ @JRubyMethod(name = "default?")
194
+ public IRubyObject
195
+ default_p(ThreadContext context)
196
+ {
197
+ return currentNode().isDefault();
198
+ }
199
+
200
+ @JRubyMethod
201
+ public IRubyObject
202
+ depth(ThreadContext context)
203
+ {
204
+ return currentNode().getDepth();
205
+ }
206
+
207
+ @JRubyMethod(name = {"empty_element?", "self_closing?"})
208
+ public IRubyObject
209
+ empty_element_p(ThreadContext context)
210
+ {
211
+ ReaderNode readerNode = currentNode();
212
+ ensureNodeClosed(context);
213
+
214
+ if (readerNode == null) { return context.getRuntime().getNil(); }
215
+ if (!(readerNode instanceof ElementNode)) { context.getRuntime().getFalse(); }
216
+ return RubyBoolean.newBoolean(context.getRuntime(), !readerNode.hasChildren);
217
+ }
218
+
219
+ @JRubyMethod(meta = true, rest = true)
220
+ public static IRubyObject
221
+ from_io(ThreadContext context, IRubyObject cls, IRubyObject args[])
222
+ {
223
+ // Only to pass the source test.
224
+ Ruby runtime = context.getRuntime();
225
+ // Not nil allowed!
226
+ if (args[0].isNil()) { throw runtime.newArgumentError("io cannot be nil"); }
227
+
228
+ XmlReader reader = (XmlReader) NokogiriService.XML_READER_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
229
+ "Nokogiri::XML::Reader"));
230
+ reader.init(runtime);
231
+ reader.setInstanceVariable("@source", args[0]);
232
+ reader.setInstanceVariable("@errors", runtime.newArray());
233
+ IRubyObject url = context.nil;
234
+ if (args.length > 1) { url = args[1]; }
235
+ if (args.length > 2) { reader.setInstanceVariable("@encoding", args[2]); }
236
+
237
+ Options options;
238
+ if (args.length > 3) {
239
+ options = new ParserContext.Options((Long)args[3].toJava(Long.class));
240
+ } else {
241
+ // use the default options RECOVER | NONET
242
+ options = new ParserContext.Options(2048 | 1);
243
+ }
244
+
245
+ InputStream in = new IOInputStream(args[0]);
246
+ reader.setInput(context, in, url, options);
247
+ return reader;
248
+ }
249
+
250
+ @JRubyMethod(meta = true, rest = true)
251
+ public static IRubyObject
252
+ from_memory(ThreadContext context, IRubyObject cls, IRubyObject args[])
253
+ {
254
+ // args[0]: string, args[1]: url, args[2]: encoding, args[3]: options
255
+ Ruby runtime = context.getRuntime();
256
+ // Not nil allowed!
257
+ if (args[0].isNil()) { throw runtime.newArgumentError("string cannot be nil"); }
258
+
259
+ XmlReader reader = (XmlReader) NokogiriService.XML_READER_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
260
+ "Nokogiri::XML::Reader"));
261
+ reader.init(runtime);
262
+ reader.setInstanceVariable("@source", args[0]);
263
+ reader.setInstanceVariable("@errors", runtime.newArray());
264
+ IRubyObject url = context.nil;
265
+ if (args.length > 1) { url = args[1]; }
266
+ if (args.length > 2) { reader.setInstanceVariable("@encoding", args[2]); }
267
+
268
+ Options options;
269
+ if (args.length > 3) {
270
+ options = new ParserContext.Options((Long)args[3].toJava(Long.class));
271
+ } else {
272
+ // use the default options RECOVER | NONET
273
+ options = new ParserContext.Options(2048 | 1);
274
+ }
275
+ IRubyObject stringIO = runtime.getClass("StringIO").newInstance(context, args[0], Block.NULL_BLOCK);
276
+ InputStream in = new IOInputStream(stringIO);
277
+ reader.setInput(context, in, url, options);
278
+ return reader;
279
+ }
280
+
281
+ @JRubyMethod
282
+ public IRubyObject
283
+ node_type(ThreadContext context)
284
+ {
285
+ IRubyObject node_type = currentNode().getNodeType();
286
+ return node_type == null ? RubyFixnum.zero(context.getRuntime()) : node_type;
287
+ }
288
+
289
+ @JRubyMethod
290
+ public IRubyObject
291
+ inner_xml(ThreadContext context)
292
+ {
293
+ ensureNodeClosed(context);
294
+ return stringOrBlank(context.getRuntime(), getInnerXml(currentNode()));
295
+ }
296
+
297
+ private String
298
+ getInnerXml(ReaderNode current)
299
+ {
300
+ if (current.depth < 0) { return null; }
301
+ if (!current.hasChildren) { return null; }
302
+ StringBuffer sb = new StringBuffer();
303
+ for (int i = current.startOffset + 1; i <= current.endOffset - 1; i++) {
304
+ sb.append(nodeQueue.get(i).getString());
305
+ }
306
+ return new String(sb);
307
+ }
308
+
309
+ @JRubyMethod
310
+ public IRubyObject
311
+ outer_xml(ThreadContext context)
312
+ {
313
+ ensureNodeClosed(context);
314
+ return stringOrBlank(context.getRuntime(), getOuterXml());
315
+ }
316
+
317
+ private String
318
+ getOuterXml()
319
+ {
320
+ ReaderNode current = currentNode();
321
+ if (current == null || current.depth < 0) { return null; }
322
+
323
+ if (current instanceof ClosingNode) {
324
+ return "<" + current.name + "/>";
325
+ }
326
+
327
+ StringBuilder sb = new StringBuilder();
328
+ for (int i = position; i <= current.endOffset; i++) {
329
+ sb.append(nodeQueue.get(i).getString());
330
+ }
331
+ return new String(sb);
332
+ }
333
+
334
+ @JRubyMethod
335
+ public IRubyObject
336
+ lang(ThreadContext context)
337
+ {
338
+ return currentNode().getLang();
339
+ }
340
+
341
+ @JRubyMethod
342
+ public IRubyObject
343
+ local_name(ThreadContext context)
344
+ {
345
+ return currentNode().getLocalName();
346
+ }
347
+
348
+ @JRubyMethod
349
+ public IRubyObject
350
+ name(ThreadContext context)
351
+ {
352
+ return currentNode().getName();
353
+ }
354
+
355
+ @JRubyMethod
356
+ public IRubyObject
357
+ namespace_uri(ThreadContext context)
358
+ {
359
+ return currentNode().getUri();
360
+ }
361
+
362
+ @JRubyMethod
363
+ public IRubyObject
364
+ namespaces(ThreadContext context)
365
+ {
366
+ return currentNode().getNamespaces(context);
367
+ }
368
+
369
+ @JRubyMethod
370
+ public IRubyObject
371
+ prefix(ThreadContext context)
372
+ {
373
+ return currentNode().getPrefix();
374
+ }
375
+
376
+ private void
377
+ readMoreData(ThreadContext context)
378
+ {
379
+ if (!continueParsing) { throw context.runtime.newRuntimeError("Cannot parse more data"); }
380
+ try {
381
+ continueParsing = config.parse(false);
382
+ } catch (XNIException e) {
383
+ throw XmlSyntaxError.createXMLSyntaxError(context.runtime, e).toThrowable(); // Nokogiri::XML::SyntaxError
384
+ } catch (IOException e) {
385
+ throw context.runtime.newRuntimeError(e.toString());
386
+ }
387
+ }
388
+
389
+ private void
390
+ ensureNodeClosed(ThreadContext context)
391
+ {
392
+ ReaderNode node = currentNode();
393
+ if (node instanceof TextNode) { return; }
394
+ while (node.endOffset < 1) { readMoreData(context); }
395
+ }
396
+
397
+ @JRubyMethod
398
+ public IRubyObject
399
+ read(ThreadContext context)
400
+ {
401
+ position++;
402
+ try {
403
+ while (nodeQueue.size() <= position && continueParsing) {
404
+ readMoreData(context);
405
+ }
406
+ return setAndRaiseErrorsIfAny(context.runtime, null);
407
+ } catch (RaiseException ex) {
408
+ return setAndRaiseErrorsIfAny(context.runtime, ex);
409
+ }
410
+ }
411
+
412
+ private IRubyObject
413
+ setAndRaiseErrorsIfAny(final Ruby runtime, final RaiseException ex) throws RaiseException
414
+ {
415
+ final ReaderNode currentNode = currentNode();
416
+ if (currentNode == null) { return runtime.getNil(); }
417
+ if (currentNode.isError()) {
418
+ RubyArray errors = (RubyArray) getInstanceVariable("@errors");
419
+ IRubyObject error = currentNode.toSyntaxError();
420
+ errors.append(error);
421
+ setInstanceVariable("@errors", errors);
422
+
423
+ throw ex != null ? ex : ((XmlSyntaxError) error).toThrowable();
424
+ }
425
+ if (ex != null) { throw ex; }
426
+ return this;
427
+ }
428
+
429
+ private ReaderNode
430
+ currentNode()
431
+ {
432
+ if (position >= nodeQueue.size()) { return null; }
433
+ return nodeQueue.get(position);
434
+ }
435
+
436
+ @JRubyMethod
437
+ public IRubyObject
438
+ state(ThreadContext context)
439
+ {
440
+ return context.getRuntime().newFixnum(this.state);
441
+ }
442
+
443
+ @JRubyMethod
444
+ public IRubyObject
445
+ value(ThreadContext context)
446
+ {
447
+ return currentNode().getValue();
448
+ }
449
+
450
+ @JRubyMethod(name = "value?")
451
+ public IRubyObject
452
+ value_p(ThreadContext context)
453
+ {
454
+ return currentNode().hasValue();
455
+ }
456
+
457
+ @JRubyMethod
458
+ public IRubyObject
459
+ xml_version(ThreadContext context)
460
+ {
461
+ return currentNode().getXmlVersion();
462
+ }
463
+
464
+ protected XMLPullParserConfiguration
465
+ createReader(Ruby ruby, Options options)
466
+ {
467
+ StandardParserConfiguration config = new StandardParserConfiguration();
468
+ DocumentHandler handler = new DocumentHandler(ruby);
469
+ // XMLReader reader = XMLReaderFactory.createXMLReader();
470
+ config.setDocumentHandler(handler);
471
+ config.setDTDHandler(handler);
472
+ config.setErrorHandler(handler);
473
+ config.setEntityResolver(new EntityResolver2Wrapper(new NokogiriEntityResolver(ruby, null, options)));
474
+ // config.setFeature("http://xml.org/sax/features/xmlns-uris", true);
475
+ // config.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
476
+ config.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", options.dtdLoad
477
+ || options.dtdValid);
478
+ return config;
479
+ }
480
+
481
+ private class DocumentHandler extends DefaultXMLDocumentHandler implements XMLErrorHandler
482
+ {
483
+
484
+ Stack<String> langStack;
485
+ int depth;
486
+ Stack<String> xmlBaseStack;
487
+ Stack<ReaderNode.ElementNode> elementStack;
488
+ private final Ruby ruby;
489
+
490
+ public
491
+ DocumentHandler(Ruby ruby)
492
+ {
493
+ this.ruby = ruby;
107
494
  }
108
495
 
109
- /**
110
- * Create and return a copy of this object.
111
- *
112
- * @return a clone of this object
113
- */
114
496
  @Override
115
- public Object clone() throws CloneNotSupportedException {
116
- return super.clone();
497
+ public void
498
+ startGeneralEntity(String name, XMLResourceIdentifier identifier,
499
+ String encoding, Augmentations augs) throws XNIException
500
+ {
501
+ Object entitySkipped;
502
+ if (augs != null && (entitySkipped = augs.getItem(Constants.ENTITY_SKIPPED)) != null && ((Boolean) entitySkipped)) {
503
+ nodeQueue.add(new ReaderNode.ExceptionNode(ruby, null));
504
+ }
117
505
  }
118
506
 
119
- public void init(Ruby runtime) {
120
- nodeQueue = new LinkedList<ReaderNode>();
121
- nodeQueue.add(new ReaderNode.EmptyNode(runtime));
122
- }
123
-
124
- private void setInput(ThreadContext context, InputStream in, IRubyObject url, Options options){
125
- this.setState(XML_TEXTREADER_MODE_READING);
126
- config = this.createReader(context.getRuntime(), options);
127
- InputSource inputSource = new InputSource();
128
- ParserContext.setUrl(context, inputSource, url);
129
- XMLInputSource xmlInputSource = new XMLInputSource(inputSource.getPublicId(),
130
- inputSource.getSystemId(), null, in, null);
131
- try {
132
- config.setInputSource(xmlInputSource);
133
- } catch (IOException e) {
134
- throw context.getRuntime().newRuntimeError(e.getMessage());
135
- }
136
- this.setState(XML_TEXTREADER_MODE_CLOSED);
137
- }
138
507
 
139
- private void setState(int state) { this.state = state; }
140
-
141
- @JRubyMethod
142
- public IRubyObject attribute(ThreadContext context, IRubyObject name) {
143
- return currentNode().getAttributeByName(name);
144
- }
145
-
146
- @JRubyMethod
147
- public IRubyObject attribute_at(ThreadContext context, IRubyObject index) {
148
- return currentNode().getAttributeByIndex(index);
149
- }
150
-
151
- @JRubyMethod
152
- public IRubyObject attribute_count(ThreadContext context) {
153
- return currentNode().getAttributeCount();
154
- }
155
-
156
- @JRubyMethod
157
- public IRubyObject attribute_nodes(ThreadContext context) {
158
- return currentNode().getAttributesNodes();
159
- }
160
-
161
- @JRubyMethod
162
- public IRubyObject attr_nodes(ThreadContext context) {
163
- return currentNode().getAttributesNodes();
164
- }
165
-
166
- @JRubyMethod(name = "attributes?")
167
- public IRubyObject attributes_p(ThreadContext context) {
168
- return currentNode().hasAttributes();
169
- }
170
-
171
- @JRubyMethod
172
- public IRubyObject base_uri(ThreadContext context) {
173
- return currentNode().getXmlBase();
174
- }
175
508
 
176
- @JRubyMethod(name="default?")
177
- public IRubyObject default_p(ThreadContext context){
178
- return currentNode().isDefault();
179
- }
180
-
181
- @JRubyMethod
182
- public IRubyObject depth(ThreadContext context) {
183
- return currentNode().getDepth();
184
- }
185
-
186
- @JRubyMethod(name = {"empty_element?", "self_closing?"})
187
- public IRubyObject empty_element_p(ThreadContext context) {
188
- ReaderNode readerNode = currentNode();
189
- ensureNodeClosed(context);
190
-
191
- if (readerNode == null) return context.getRuntime().getNil();
192
- if (!(readerNode instanceof ElementNode)) context.getRuntime().getFalse();
193
- return RubyBoolean.newBoolean(context.getRuntime(), !readerNode.hasChildren);
194
- }
195
-
196
- @JRubyMethod(meta = true, rest = true)
197
- public static IRubyObject from_io(ThreadContext context, IRubyObject cls, IRubyObject args[]) {
198
- // Only to pass the source test.
199
- Ruby runtime = context.getRuntime();
200
- // Not nil allowed!
201
- if(args[0].isNil()) throw runtime.newArgumentError("io cannot be nil");
202
-
203
- XmlReader reader = (XmlReader) NokogiriService.XML_READER_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Reader"));
204
- reader.init(runtime);
205
- reader.setInstanceVariable("@source", args[0]);
206
- reader.setInstanceVariable("@errors", runtime.newArray());
207
- IRubyObject url = context.nil;
208
- if (args.length > 1) url = args[1];
209
- if (args.length > 2) reader.setInstanceVariable("@encoding", args[2]);
210
-
211
- Options options;
212
- if (args.length > 3) {
213
- options = new ParserContext.Options((Long)args[3].toJava(Long.class));
214
- } else {
215
- // use the default options RECOVER | NONET
216
- options = new ParserContext.Options(2048 | 1);
217
- }
218
-
219
- InputStream in = new IOInputStream(args[0]);
220
- reader.setInput(context, in, url, options);
221
- return reader;
222
- }
223
-
224
- @JRubyMethod(meta = true, rest = true)
225
- public static IRubyObject from_memory(ThreadContext context, IRubyObject cls, IRubyObject args[]) {
226
- // args[0]: string, args[1]: url, args[2]: encoding, args[3]: options
227
- Ruby runtime = context.getRuntime();
228
- // Not nil allowed!
229
- if(args[0].isNil()) throw runtime.newArgumentError("string cannot be nil");
230
-
231
- XmlReader reader = (XmlReader) NokogiriService.XML_READER_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Reader"));
232
- reader.init(runtime);
233
- reader.setInstanceVariable("@source", args[0]);
234
- reader.setInstanceVariable("@errors", runtime.newArray());
235
- IRubyObject url = context.nil;
236
- if (args.length > 1) url = args[1];
237
- if (args.length > 2) reader.setInstanceVariable("@encoding", args[2]);
238
-
239
- Options options;
240
- if (args.length > 3) {
241
- options = new ParserContext.Options((Long)args[3].toJava(Long.class));
242
- } else {
243
- // use the default options RECOVER | NONET
244
- options = new ParserContext.Options(2048 | 1);
245
- }
246
- IRubyObject stringIO = runtime.getClass("StringIO").newInstance(context, args[0], Block.NULL_BLOCK);
247
- InputStream in = new IOInputStream(stringIO);
248
- reader.setInput(context, in, url, options);
249
- return reader;
250
- }
251
-
252
- @JRubyMethod
253
- public IRubyObject node_type(ThreadContext context) {
254
- IRubyObject node_type = currentNode().getNodeType();
255
- return node_type == null ? RubyFixnum.zero(context.getRuntime()) : node_type;
256
- }
257
-
258
- @JRubyMethod
259
- public IRubyObject inner_xml(ThreadContext context) {
260
- ensureNodeClosed(context);
261
- return stringOrBlank(context.getRuntime(), getInnerXml(currentNode()));
262
- }
263
-
264
- private String getInnerXml(ReaderNode current) {
265
- if (current.depth < 0) return null;
266
- if (!current.hasChildren) return null;
267
- StringBuffer sb = new StringBuffer();
268
- for (int i = current.startOffset + 1; i <= current.endOffset - 1; i++) {
269
- sb.append(nodeQueue.get(i).getString());
270
- }
271
- return new String(sb);
272
- }
273
-
274
- @JRubyMethod
275
- public IRubyObject outer_xml(ThreadContext context) {
276
- ensureNodeClosed(context);
277
- return stringOrBlank(context.getRuntime(), getOuterXml());
278
- }
279
-
280
- private String getOuterXml() {
281
- ReaderNode current = currentNode();
282
- if (current == null || current.depth < 0) return null;
283
-
284
- if (current instanceof ClosingNode) {
285
- return "<" + current.name + "/>";
286
- }
287
-
288
- StringBuilder sb = new StringBuilder();
289
- for (int i = position; i <= current.endOffset; i++) {
290
- sb.append(nodeQueue.get(i).getString());
291
- }
292
- return new String(sb);
293
- }
294
-
295
- @JRubyMethod
296
- public IRubyObject lang(ThreadContext context) {
297
- return currentNode().getLang();
298
- }
299
-
300
- @JRubyMethod
301
- public IRubyObject local_name(ThreadContext context) {
302
- return currentNode().getLocalName();
303
- }
304
-
305
- @JRubyMethod
306
- public IRubyObject name(ThreadContext context) {
307
- return currentNode().getName();
308
- }
309
-
310
- @JRubyMethod
311
- public IRubyObject namespace_uri(ThreadContext context) {
312
- return currentNode().getUri();
313
- }
314
-
315
- @JRubyMethod
316
- public IRubyObject namespaces(ThreadContext context) {
317
- return currentNode().getNamespaces(context);
318
- }
319
-
320
- @JRubyMethod
321
- public IRubyObject prefix(ThreadContext context) {
322
- return currentNode().getPrefix();
323
- }
324
-
325
- private void readMoreData(ThreadContext context) {
326
- if (!continueParsing) throw context.runtime.newRuntimeError("Cannot parse more data");
327
- try {
328
- continueParsing = config.parse(false);
329
- }
330
- catch (XNIException e) {
331
- throw XmlSyntaxError.createXMLSyntaxError(context.runtime, e).toThrowable(); // Nokogiri::XML::SyntaxError
332
- }
333
- catch (IOException e) {
334
- throw context.runtime.newRuntimeError(e.toString());
335
- }
336
- }
337
-
338
- private void ensureNodeClosed(ThreadContext context) {
339
- ReaderNode node = currentNode();
340
- if (node instanceof TextNode) return;
341
- while (node.endOffset < 1) readMoreData(context);
342
- }
343
-
344
- @JRubyMethod
345
- public IRubyObject read(ThreadContext context) {
346
- position++;
347
- try {
348
- while (nodeQueue.size() <= position && continueParsing) {
349
- readMoreData(context);
350
- }
351
- return setAndRaiseErrorsIfAny(context.runtime, null);
352
- }
353
- catch (RaiseException ex) {
354
- return setAndRaiseErrorsIfAny(context.runtime, ex);
355
- }
509
+ @Override
510
+ public void
511
+ startDocument(XMLLocator locator, String encoding, NamespaceContext context, Augmentations augs)
512
+ {
513
+ depth = 0;
514
+ langStack = new Stack<String>();
515
+ xmlBaseStack = new Stack<String>();
516
+ elementStack = new Stack<ReaderNode.ElementNode>();
356
517
  }
357
518
 
358
- private IRubyObject setAndRaiseErrorsIfAny(final Ruby runtime, final RaiseException ex) throws RaiseException {
359
- final ReaderNode currentNode = currentNode();
360
- if (currentNode == null) return runtime.getNil();
361
- if (currentNode.isError()) {
362
- RubyArray errors = (RubyArray) getInstanceVariable("@errors");
363
- IRubyObject error = currentNode.toSyntaxError();
364
- errors.append(error);
365
- setInstanceVariable("@errors", errors);
366
-
367
- throw ex != null ? ex : ((XmlSyntaxError) error).toThrowable();
368
- }
369
- if ( ex != null ) throw ex;
370
- return this;
519
+ @Override
520
+ public void
521
+ endDocument(Augmentations augs)
522
+ {
523
+ langStack = null;
524
+ xmlBaseStack = null;
525
+ elementStack = null;
371
526
  }
372
527
 
373
- private ReaderNode currentNode() {
374
- if (position >= nodeQueue.size()) return null;
375
- return nodeQueue.get(position);
528
+ @Override
529
+ public void
530
+ startElement(QName element, XMLAttributes attrs, Augmentations augs)
531
+ {
532
+ commonElement(element, attrs, false);
376
533
  }
377
534
 
378
- @JRubyMethod
379
- public IRubyObject state(ThreadContext context) {
380
- return context.getRuntime().newFixnum(this.state);
535
+ @Override
536
+ public void
537
+ endElement(QName element, Augmentations augs)
538
+ {
539
+ String uri = element.uri;
540
+ String localName = element.localpart;
541
+ String qName = element.rawname;
542
+ depth--;
543
+ ElementNode startElementNode = elementStack.pop();
544
+ ReaderNode node = ReaderNode.createClosingNode(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
545
+
546
+ startElementNode.endOffset = nodeQueue.size() - 1;
547
+
548
+ if (startElementNode.endOffset != startElementNode.startOffset) {
549
+ // this node isn't empty
550
+ node.attributeList = startElementNode.attributeList;
551
+ node.namespaces = startElementNode.namespaces;
552
+ node.startOffset = startElementNode.startOffset;
553
+ node.endOffset = ++startElementNode.endOffset;
554
+ node.hasChildren = startElementNode.hasChildren = true;
555
+ nodeQueue.add(node);
556
+ }
557
+ if (!langStack.isEmpty()) { langStack.pop(); }
558
+ if (!xmlBaseStack.isEmpty()) { xmlBaseStack.pop(); }
381
559
  }
382
560
 
383
- @JRubyMethod
384
- public IRubyObject value(ThreadContext context) {
385
- return currentNode().getValue();
561
+ @Override
562
+ public void
563
+ emptyElement(QName element, XMLAttributes attrs, Augmentations augs)
564
+ {
565
+ commonElement(element, attrs, true);
566
+ }
567
+
568
+ private void
569
+ commonElement(QName element, XMLAttributes attrs, boolean isEmpty)
570
+ {
571
+ String qName = element.rawname;
572
+ String uri = element.uri;
573
+ String localName = element.localpart;
574
+ ReaderNode readerNode = ReaderNode.createElementNode(ruby, uri, localName, qName, attrs, depth, langStack,
575
+ xmlBaseStack);
576
+ if (!elementStack.isEmpty()) {
577
+ ElementNode parent = elementStack.peek();
578
+ parent.hasChildren = true;
579
+ }
580
+ nodeQueue.add(readerNode);
581
+ readerNode.startOffset = nodeQueue.size() - 1;
582
+ if (!isEmpty) {
583
+ depth++;
584
+ if (readerNode.lang != null) { langStack.push(readerNode.lang); }
585
+ if (readerNode.xmlBase != null) { xmlBaseStack.push(readerNode.xmlBase); }
586
+ elementStack.push((ReaderNode.ElementNode)readerNode);
587
+ } else {
588
+ readerNode.endOffset = readerNode.startOffset;
589
+ readerNode.hasChildren = false;
590
+ }
386
591
  }
387
592
 
388
- @JRubyMethod(name = "value?")
389
- public IRubyObject value_p(ThreadContext context) {
390
- return currentNode().hasValue();
593
+ @Override
594
+ public void
595
+ characters(XMLString string, Augmentations augs)
596
+ {
597
+ ReaderNode.TextNode node = ReaderNode.createTextNode(ruby, string.toString(), depth, langStack, xmlBaseStack);
598
+ nodeQueue.add(node);
599
+ node.startOffset = node.endOffset = nodeQueue.size() - 1;
391
600
  }
392
601
 
393
- @JRubyMethod
394
- public IRubyObject xml_version(ThreadContext context) {
395
- return currentNode().getXmlVersion();
602
+ @Override
603
+ public void
604
+ error(String domain, String key, XMLParseException ex)
605
+ {
606
+ nodeQueue.add(new ReaderNode.ExceptionNode(ruby, ex));
607
+ throw ex;
396
608
  }
397
609
 
398
- protected XMLPullParserConfiguration createReader(Ruby ruby, Options options) {
399
- StandardParserConfiguration config = new StandardParserConfiguration();
400
- DocumentHandler handler = new DocumentHandler(ruby);
401
- // XMLReader reader = XMLReaderFactory.createXMLReader();
402
- config.setDocumentHandler(handler);
403
- config.setDTDHandler(handler);
404
- config.setErrorHandler(handler);
405
- config.setEntityResolver(new EntityResolver2Wrapper(new NokogiriEntityResolver(ruby, null, options)));
406
- // config.setFeature("http://xml.org/sax/features/xmlns-uris", true);
407
- // config.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
408
- config.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", options.dtdLoad || options.dtdValid);
409
- return config;
610
+ @Override
611
+ public void
612
+ fatalError(String domain, String key, XMLParseException ex)
613
+ {
614
+ nodeQueue.add(new ReaderNode.ExceptionNode(ruby, ex));
615
+ throw ex;
410
616
  }
411
617
 
412
- private class DocumentHandler extends DefaultXMLDocumentHandler implements XMLErrorHandler {
413
-
414
- Stack<String> langStack;
415
- int depth;
416
- Stack<String> xmlBaseStack;
417
- Stack<ReaderNode.ElementNode> elementStack;
418
- private final Ruby ruby;
419
-
420
- public DocumentHandler(Ruby ruby) {
421
- this.ruby = ruby;
422
- }
423
-
424
- @Override
425
- public void startGeneralEntity(String name, XMLResourceIdentifier identifier,
426
- String encoding, Augmentations augs) throws XNIException {
427
- Object entitySkipped;
428
- if (augs != null && (entitySkipped = augs.getItem(Constants.ENTITY_SKIPPED)) != null && ((Boolean) entitySkipped)) {
429
- nodeQueue.add(new ReaderNode.ExceptionNode(ruby, null));
430
- }
431
- }
432
-
433
-
434
-
435
- @Override
436
- public void startDocument(XMLLocator locator, String encoding, NamespaceContext context, Augmentations augs) {
437
- depth = 0;
438
- langStack = new Stack<String>();
439
- xmlBaseStack = new Stack<String>();
440
- elementStack = new Stack<ReaderNode.ElementNode>();
441
- }
442
-
443
- @Override
444
- public void endDocument(Augmentations augs) {
445
- langStack = null;
446
- xmlBaseStack = null;
447
- elementStack = null;
448
- }
449
-
450
- @Override
451
- public void startElement(QName element, XMLAttributes attrs, Augmentations augs) {
452
- commonElement(element, attrs, false);
453
- }
454
-
455
- @Override
456
- public void endElement(QName element, Augmentations augs) {
457
- String uri = element.uri;
458
- String localName = element.localpart;
459
- String qName = element.rawname;
460
- depth--;
461
- ElementNode startElementNode = elementStack.pop();
462
- ReaderNode node = ReaderNode.createClosingNode(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
463
-
464
- startElementNode.endOffset = nodeQueue.size() - 1;
465
-
466
- if (startElementNode.endOffset != startElementNode.startOffset) {
467
- // this node isn't empty
468
- node.attributeList = startElementNode.attributeList;
469
- node.namespaces = startElementNode.namespaces;
470
- node.startOffset = startElementNode.startOffset;
471
- node.endOffset = ++startElementNode.endOffset;
472
- node.hasChildren = startElementNode.hasChildren = true;
473
- nodeQueue.add(node);
474
- }
475
- if (!langStack.isEmpty()) langStack.pop();
476
- if (!xmlBaseStack.isEmpty()) xmlBaseStack.pop();
477
- }
478
-
479
- @Override
480
- public void emptyElement(QName element, XMLAttributes attrs, Augmentations augs) {
481
- commonElement(element, attrs, true);
482
- }
483
-
484
- private void commonElement(QName element, XMLAttributes attrs, boolean isEmpty) {
485
- String qName = element.rawname;
486
- String uri = element.uri;
487
- String localName = element.localpart;
488
- ReaderNode readerNode = ReaderNode.createElementNode(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
489
- if (!elementStack.isEmpty()) {
490
- ElementNode parent = elementStack.peek();
491
- parent.hasChildren = true;
492
- }
493
- nodeQueue.add(readerNode);
494
- readerNode.startOffset = nodeQueue.size() - 1;
495
- if (!isEmpty) {
496
- depth++;
497
- if (readerNode.lang != null) langStack.push(readerNode.lang);
498
- if (readerNode.xmlBase != null) xmlBaseStack.push(readerNode.xmlBase);
499
- elementStack.push((ReaderNode.ElementNode)readerNode);
500
- } else {
501
- readerNode.endOffset = readerNode.startOffset;
502
- readerNode.hasChildren = false;
503
- }
504
- }
505
-
506
- @Override
507
- public void characters(XMLString string, Augmentations augs) {
508
- ReaderNode.TextNode node = ReaderNode.createTextNode(ruby, string.toString(), depth, langStack, xmlBaseStack);
509
- nodeQueue.add(node);
510
- node.startOffset = node.endOffset = nodeQueue.size() - 1;
511
- }
512
-
513
- @Override
514
- public void error(String domain, String key, XMLParseException ex) {
515
- nodeQueue.add(new ReaderNode.ExceptionNode(ruby, ex));
516
- throw ex;
517
- }
518
-
519
- @Override
520
- public void fatalError(String domain, String key, XMLParseException ex) {
521
- nodeQueue.add(new ReaderNode.ExceptionNode(ruby, ex));
522
- throw ex;
523
- }
524
-
525
- @Override
526
- public void warning(String domain, String key, XMLParseException ex) {
527
- nodeQueue.add(new ReaderNode.ExceptionNode(ruby, ex));
528
- throw ex;
529
- }
618
+ @Override
619
+ public void
620
+ warning(String domain, String key, XMLParseException ex)
621
+ {
622
+ nodeQueue.add(new ReaderNode.ExceptionNode(ruby, ex));
623
+ throw ex;
530
624
  }
625
+ }
531
626
  }