nokogiri 1.7.2-java → 1.8.0-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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/.cross_rubies +4 -4
  3. data/.travis.yml +43 -24
  4. data/CHANGELOG.md +54 -6
  5. data/Gemfile +8 -7
  6. data/Gemfile-libxml-ruby +3 -0
  7. data/LICENSE-DEPENDENCIES.md +1612 -0
  8. data/{LICENSE.txt → LICENSE.md} +1 -1
  9. data/Manifest.txt +5 -8
  10. data/README.md +8 -5
  11. data/Rakefile +15 -31
  12. data/appveyor.yml +2 -0
  13. data/dependencies.yml +12 -7
  14. data/ext/java/nokogiri/HtmlDocument.java +2 -2
  15. data/ext/java/nokogiri/HtmlSaxParserContext.java +20 -21
  16. data/ext/java/nokogiri/HtmlSaxPushParser.java +6 -10
  17. data/ext/java/nokogiri/NokogiriService.java +10 -31
  18. data/ext/java/nokogiri/XmlAttr.java +1 -26
  19. data/ext/java/nokogiri/XmlCdata.java +0 -1
  20. data/ext/java/nokogiri/XmlComment.java +1 -1
  21. data/ext/java/nokogiri/XmlDocument.java +4 -5
  22. data/ext/java/nokogiri/XmlDocumentFragment.java +29 -21
  23. data/ext/java/nokogiri/XmlDtd.java +1 -1
  24. data/ext/java/nokogiri/XmlElement.java +9 -10
  25. data/ext/java/nokogiri/XmlEntityDecl.java +4 -5
  26. data/ext/java/nokogiri/XmlNode.java +105 -103
  27. data/ext/java/nokogiri/XmlNodeSet.java +64 -76
  28. data/ext/java/nokogiri/XmlReader.java +48 -48
  29. data/ext/java/nokogiri/XmlRelaxng.java +1 -1
  30. data/ext/java/nokogiri/XmlSaxPushParser.java +37 -17
  31. data/ext/java/nokogiri/XmlSchema.java +7 -5
  32. data/ext/java/nokogiri/XmlSyntaxError.java +47 -35
  33. data/ext/java/nokogiri/XmlXpathContext.java +160 -132
  34. data/ext/java/nokogiri/XsltStylesheet.java +15 -24
  35. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +19 -23
  36. data/ext/java/nokogiri/internals/NokogiriDomParser.java +1 -1
  37. data/ext/java/nokogiri/internals/NokogiriEncodingReaderWrapper.java +1 -1
  38. data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +11 -13
  39. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +5 -21
  40. data/ext/java/nokogiri/internals/NokogiriHandler.java +1 -1
  41. data/ext/java/nokogiri/internals/NokogiriHelpers.java +105 -142
  42. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +16 -26
  43. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +32 -50
  44. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +10 -13
  45. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +3 -10
  46. data/ext/java/nokogiri/internals/ParserContext.java +4 -8
  47. data/ext/java/nokogiri/internals/ReaderNode.java +53 -93
  48. data/ext/java/nokogiri/internals/SaveContextVisitor.java +77 -89
  49. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +6 -9
  50. data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +167 -0
  51. data/ext/java/nokogiri/internals/XmlDomParserContext.java +17 -6
  52. data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +1 -1
  53. data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +28 -28
  54. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +3 -4
  55. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +2 -2
  56. data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +10 -10
  57. data/ext/java/nokogiri/internals/c14n/ElementProxy.java +5 -5
  58. data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +2 -2
  59. data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +1 -1
  60. data/ext/java/nokogiri/internals/c14n/XMLUtils.java +2 -2
  61. data/ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java +1749 -0
  62. data/ext/nokogiri/extconf.rb +12 -17
  63. data/ext/nokogiri/nokogiri.h +0 -10
  64. data/ext/nokogiri/xml_attr.c +12 -8
  65. data/ext/nokogiri/xml_node.c +17 -14
  66. data/ext/nokogiri/xml_sax_push_parser.c +56 -12
  67. data/lib/nokogiri/html/sax/parser.rb +10 -0
  68. data/lib/nokogiri/nokogiri.jar +0 -0
  69. data/lib/nokogiri/version.rb +5 -4
  70. data/lib/nokogiri/xml/document.rb +9 -9
  71. data/lib/nokogiri/xml/node.rb +7 -7
  72. data/lib/nokogiri/xml/node_set.rb +12 -7
  73. data/lib/nokogiri/xml/sax/parser.rb +6 -7
  74. data/lib/nokogiri/xml/searchable.rb +34 -25
  75. data/lib/nokogiri/xml/syntax_error.rb +24 -1
  76. data/test/decorators/test_slop.rb +4 -1
  77. data/test/helper.rb +10 -0
  78. data/test/html/sax/test_parser.rb +27 -0
  79. data/test/html/test_document.rb +12 -1
  80. data/test/html/test_document_encoding.rb +1 -3
  81. data/test/html/test_document_fragment.rb +3 -0
  82. data/test/xml/sax/test_push_parser.rb +48 -0
  83. data/test/xml/test_attr.rb +7 -0
  84. data/test/xml/test_document.rb +1 -1
  85. data/test/xml/test_document_fragment.rb +27 -0
  86. data/test/xml/test_entity_reference.rb +2 -2
  87. data/test/xml/test_node.rb +12 -15
  88. data/test/xml/test_node_reparenting.rb +14 -0
  89. data/test/xml/test_node_set.rb +8 -6
  90. data/test/xml/test_reader.rb +19 -0
  91. data/test/xml/test_syntax_error.rb +21 -15
  92. data/test/xml/test_unparented_node.rb +54 -11
  93. data/test/xml/test_xpath.rb +23 -6
  94. metadata +32 -20
  95. data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +0 -73
  96. data/ext/java/nokogiri/internals/XsltExtensionFunction.java +0 -72
  97. data/suppressions/nokogiri_ree-1.8.7.358.supp +0 -61
  98. data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
  99. data/suppressions/nokogiri_ruby-1.9.2.320.supp +0 -28
  100. data/suppressions/nokogiri_ruby-1.9.3.327.supp +0 -28
  101. data/test_all +0 -105
@@ -32,6 +32,7 @@
32
32
 
33
33
  package nokogiri;
34
34
 
35
+ import static nokogiri.XmlNode.setDocumentAndDecorate;
35
36
  import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
36
37
  import static nokogiri.internals.NokogiriHelpers.nodeListToRubyArray;
37
38
 
@@ -43,7 +44,6 @@ import org.jruby.RubyClass;
43
44
  import org.jruby.RubyObject;
44
45
  import org.jruby.anno.JRubyClass;
45
46
  import org.jruby.anno.JRubyMethod;
46
- import org.jruby.javasupport.util.RuntimeHelpers;
47
47
  import org.jruby.runtime.Block;
48
48
  import org.jruby.runtime.ThreadContext;
49
49
  import org.jruby.runtime.builtin.IRubyObject;
@@ -58,14 +58,31 @@ import org.w3c.dom.NodeList;
58
58
  */
59
59
  @JRubyClass(name="Nokogiri::XML::NodeSet")
60
60
  public class XmlNodeSet extends RubyObject implements NodeList {
61
- private List<?> list;
62
- private RubyArray nodes;
63
- private IRubyObject doc;
61
+
62
+ RubyArray nodes;
64
63
 
65
64
  public XmlNodeSet(Ruby ruby, RubyClass klazz) {
66
65
  super(ruby, klazz);
67
66
  }
68
67
 
68
+ public static XmlNodeSet create(final Ruby runtime) {
69
+ return (XmlNodeSet) NokogiriService.XML_NODESET_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::NodeSet"));
70
+ }
71
+
72
+ public static XmlNodeSet newEmptyNodeSet(ThreadContext context) {
73
+ return create(context.getRuntime());
74
+ }
75
+
76
+ public static XmlNodeSet newXmlNodeSet(final Ruby runtime, RubyArray nodes) {
77
+ XmlNodeSet xmlNodeSet = create(runtime);
78
+ xmlNodeSet.setNodes(nodes);
79
+ return xmlNodeSet;
80
+ }
81
+
82
+ static XmlNodeSet newXmlNodeSet(ThreadContext context, RubyArray nodes) {
83
+ return newXmlNodeSet(context.getRuntime(), nodes);
84
+ }
85
+
69
86
  /**
70
87
  * Create and return a copy of this object.
71
88
  *
@@ -92,25 +109,17 @@ public class XmlNodeSet extends RubyObject implements NodeList {
92
109
  public void setNodeList(NodeList nodeList) {
93
110
  setNodes(nodeListToRubyArray(getRuntime(), nodeList));
94
111
  }
95
-
96
- public void initialize(Ruby ruby, IRubyObject refNode) {
112
+
113
+ final void initialize(Ruby runtime, IRubyObject refNode) {
97
114
  if (refNode instanceof XmlNode) {
98
- XmlNode n = (XmlNode)refNode;
99
- doc = n.document(ruby.getCurrentContext());
100
- setInstanceVariable("@document", doc);
101
- if (doc != null) {
102
- RuntimeHelpers.invoke(ruby.getCurrentContext(), doc, "decorate", this);
103
- }
115
+ IRubyObject doc = ((XmlNode) refNode).document(runtime);
116
+ setDocumentAndDecorate(runtime.getCurrentContext(), this, doc);
104
117
  }
105
118
  }
106
119
 
107
- public static IRubyObject newEmptyNodeSet(ThreadContext context) {
108
- return (XmlNodeSet)NokogiriService.XML_NODESET_ALLOCATOR.allocate(context.getRuntime(), getNokogiriClass(context.getRuntime(), "Nokogiri::XML::NodeSet"));
109
- }
110
-
111
- public long length() {
112
- if (nodes == null) return 0L;
113
- return nodes.length().getLongValue();
120
+ public int length() {
121
+ if (nodes == null) return 0;
122
+ return nodes.size();
114
123
  }
115
124
 
116
125
  public void relink_namespace(ThreadContext context) {
@@ -124,86 +133,77 @@ public class XmlNodeSet extends RubyObject implements NodeList {
124
133
  }
125
134
 
126
135
  @JRubyMethod(name="&")
127
- public IRubyObject and(ThreadContext context, IRubyObject nodeSet){
136
+ public IRubyObject and(ThreadContext context, IRubyObject nodeSet) {
128
137
  if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime()));
129
- return newXmlNodeSet(context, (RubyArray) nodes.op_and(asXmlNodeSet(context, nodeSet).nodes));
138
+ return newXmlNodeSet(context, (RubyArray) nodes.op_and(getNodes(context, nodeSet)));
130
139
  }
131
140
 
132
141
  @JRubyMethod
133
- public IRubyObject delete(ThreadContext context, IRubyObject node_or_namespace){
142
+ public IRubyObject delete(ThreadContext context, IRubyObject node_or_namespace) {
134
143
  if (nodes == null) return context.getRuntime().getNil();
135
144
  if (node_or_namespace instanceof XmlNamespace) {
136
- ((XmlNamespace)node_or_namespace).deleteHref();
145
+ ((XmlNamespace) node_or_namespace).deleteHref();
137
146
  }
138
147
  return nodes.delete(context, asXmlNodeOrNamespace(context, node_or_namespace), Block.NULL_BLOCK);
139
148
  }
140
149
 
141
150
  @JRubyMethod
142
151
  public IRubyObject dup(ThreadContext context){
143
- if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime()));
152
+ if (nodes == null) return newEmptyNodeSet(context);
144
153
  return newXmlNodeSet(context, nodes.aryDup());
145
154
  }
146
155
 
147
156
  @JRubyMethod(name = "include?")
148
- public IRubyObject include_p(ThreadContext context, IRubyObject node_or_namespace){
149
- if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime()));
150
- return nodes.include_p(context, asXmlNodeOrNamespace(context, node_or_namespace));
157
+ public IRubyObject include_p(ThreadContext context, IRubyObject node_or_namespace) {
158
+ node_or_namespace = asXmlNodeOrNamespace(context, node_or_namespace);
159
+ if (nodes == null) return context.getRuntime().getFalse();
160
+ return nodes.include_p(context, node_or_namespace);
151
161
  }
152
162
 
153
163
  @JRubyMethod(name = {"length", "size"})
154
164
  public IRubyObject length(ThreadContext context) {
155
- if (nodes != null) return nodes.length();
156
- else return context.getRuntime().newFixnum(0);
165
+ return nodes != null ? nodes.length() : context.getRuntime().newFixnum(0);
157
166
  }
158
167
 
159
168
  @JRubyMethod(name="-")
160
- public IRubyObject op_diff(ThreadContext context, IRubyObject nodeSet){
169
+ public IRubyObject op_diff(ThreadContext context, IRubyObject nodeSet) {
161
170
  XmlNodeSet xmlNodeSet = newXmlNodeSet(context, this);
162
171
  if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime()));
163
- xmlNodeSet.setNodes((RubyArray) nodes.op_diff(asXmlNodeSet(context, nodeSet).nodes));
172
+ xmlNodeSet.setNodes((RubyArray) nodes.op_diff(getNodes(context, nodeSet)));
164
173
  return xmlNodeSet;
165
174
  }
166
175
 
167
176
  @JRubyMethod(name={"|", "+"})
168
- public IRubyObject op_or(ThreadContext context, IRubyObject nodeSet){
177
+ public IRubyObject op_or(ThreadContext context, IRubyObject nodeSet) {
169
178
  if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime()));
170
- return newXmlNodeSet(context, (RubyArray) nodes.op_or(asXmlNodeSet(context, nodeSet).nodes));
179
+ return newXmlNodeSet(context, (RubyArray) nodes.op_or(getNodes(context, nodeSet)));
171
180
  }
172
181
 
173
182
  @JRubyMethod(name = {"push", "<<"})
174
183
  public IRubyObject push(ThreadContext context, IRubyObject node_or_namespace) {
175
- if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime()));
184
+ if (nodes == null) setNodes(RubyArray.newArray(context.getRuntime()));
176
185
  nodes.append(asXmlNodeOrNamespace(context, node_or_namespace));
177
186
  return this;
178
187
  }
179
188
 
180
189
  @JRubyMethod(name={"[]", "slice"})
181
190
  public IRubyObject slice(ThreadContext context, IRubyObject indexOrRange){
182
- IRubyObject result;
183
191
  if (nodes == null) return context.getRuntime().getNil();
184
- if (context.getRuntime().is1_9()) {
185
- result = nodes.aref19(indexOrRange);
186
- } else {
187
- result = nodes.aref(indexOrRange);
188
- }
192
+ IRubyObject result = nodes.aref19(indexOrRange);
189
193
  if (result instanceof RubyArray) {
190
- return newXmlNodeSet(context, (RubyArray)result);
191
- } else {
192
- return result;
194
+ return newXmlNodeSet(context, (RubyArray) result);
193
195
  }
196
+ return result;
194
197
  }
195
198
 
196
199
  @JRubyMethod(name={"[]", "slice"})
197
200
  public IRubyObject slice(ThreadContext context, IRubyObject start, IRubyObject length){
198
- IRubyObject result;
199
201
  if (nodes == null) return context.getRuntime().getNil();
200
- if (context.getRuntime().is1_9()) {
201
- result = nodes.aref19(start, length);
202
- } else {
203
- result = nodes.aref(start, length);
202
+ IRubyObject result = nodes.aref19(start, length);
203
+ if (result instanceof RubyArray) {
204
+ return newXmlNodeSet(context, (RubyArray) result);
204
205
  }
205
- if (result instanceof RubyArray) return newXmlNodeSet(context, (RubyArray)result);
206
- else return context.getRuntime().getNil();
206
+ return context.getRuntime().getNil();
207
207
  }
208
208
 
209
209
  @JRubyMethod(name = {"to_a", "to_ary"})
@@ -213,10 +213,9 @@ public class XmlNodeSet extends RubyObject implements NodeList {
213
213
 
214
214
  @JRubyMethod(name = {"unlink", "remove"})
215
215
  public IRubyObject unlink(ThreadContext context){
216
- if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime()));
217
- IRubyObject[] arr = this.nodes.toJavaArrayUnsafe();
218
- long length = arr.length;
219
- for (int i = 0; i < length; i++) {
216
+ if (nodes == null) return this;
217
+ IRubyObject[] arr = nodes.toJavaArrayUnsafe();
218
+ for (int i = 0; i < arr.length; i++) {
220
219
  if (arr[i] instanceof XmlNode) {
221
220
  ((XmlNode) arr[i] ).unlink(context);
222
221
  }
@@ -224,44 +223,33 @@ public class XmlNodeSet extends RubyObject implements NodeList {
224
223
  return this;
225
224
  }
226
225
 
227
- public static XmlNodeSet newXmlNodeSet(ThreadContext context, RubyArray array) {
228
- XmlNodeSet xmlNodeSet = (XmlNodeSet)NokogiriService.XML_NODESET_ALLOCATOR.allocate(context.getRuntime(), getNokogiriClass(context.getRuntime(), "Nokogiri::XML::NodeSet"));
229
- xmlNodeSet.setNodes(array);
230
- return xmlNodeSet;
231
- }
232
-
233
- private XmlNodeSet newXmlNodeSet(ThreadContext context, XmlNodeSet reference) {
234
- XmlNodeSet xmlNodeSet = (XmlNodeSet)NokogiriService.XML_NODESET_ALLOCATOR.allocate(context.getRuntime(), getNokogiriClass(context.getRuntime(), "Nokogiri::XML::NodeSet"));
226
+ private static XmlNodeSet newXmlNodeSet(ThreadContext context, XmlNodeSet reference) {
227
+ XmlNodeSet xmlNodeSet = create(context.getRuntime());
235
228
  xmlNodeSet.setReference(reference);
236
229
  return xmlNodeSet;
237
230
  }
238
231
 
239
- private IRubyObject asXmlNodeOrNamespace(ThreadContext context, IRubyObject possibleNode) {
232
+ private static IRubyObject asXmlNodeOrNamespace(ThreadContext context, IRubyObject possibleNode) {
240
233
  if (possibleNode instanceof XmlNode || possibleNode instanceof XmlNamespace) {
241
234
  return possibleNode;
242
- } else {
243
- throw context.getRuntime().newArgumentError("node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");
244
235
  }
236
+ throw context.getRuntime().newArgumentError("node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");
245
237
  }
246
238
 
247
- private XmlNodeSet asXmlNodeSet(ThreadContext context, IRubyObject possibleNodeSet) {
248
- // if(!(possibleNodeSet instanceof XmlNodeSet)) {
249
- if(!RuntimeHelpers.invoke(context, possibleNodeSet, "is_a?",
250
- getNokogiriClass(context.getRuntime(), "Nokogiri::XML::NodeSet")).isTrue()) {
251
- throw context.getRuntime().newArgumentError("node must be a Nokogiri::XML::NodeSet");
239
+ private static RubyArray getNodes(ThreadContext context, IRubyObject possibleNodeSet) {
240
+ if (possibleNodeSet instanceof XmlNodeSet) {
241
+ RubyArray nodes = ((XmlNodeSet) possibleNodeSet).nodes;
242
+ return nodes == null ? RubyArray.newEmptyArray(context.getRuntime()) : nodes;
252
243
  }
253
- XmlNodeSet xmlNodeSet = (XmlNodeSet)possibleNodeSet;
254
- if (xmlNodeSet.nodes == null) xmlNodeSet.setNodes(RubyArray.newEmptyArray(context.getRuntime()));
255
- return xmlNodeSet;
244
+ throw context.getRuntime().newArgumentError("node must be a Nokogiri::XML::NodeSet");
256
245
  }
257
246
 
258
247
  public int getLength() {
259
- if (nodes == null) return 0 ;
260
- return nodes.size();
248
+ return nodes == null ? 0 : nodes.size();
261
249
  }
262
250
 
263
251
  public Node item(int index) {
264
- if (nodes == null) return null ;
252
+ if (nodes == null) return null;
265
253
  Object n = nodes.get(index);
266
254
  if (n instanceof XmlNode) return ((XmlNode)n).node;
267
255
  if (n instanceof XmlNamespace) return ((XmlNamespace)n).getNode();
@@ -244,7 +244,7 @@ public class XmlReader extends RubyObject {
244
244
  // use the default options RECOVER | NONET
245
245
  options = new ParserContext.Options(2048 | 1);
246
246
  }
247
- IRubyObject stringIO = NokogiriService.getNokogiriClassCache(context.getRuntime()).get("StringIO").newInstance(context, args[0], Block.NULL_BLOCK);
247
+ IRubyObject stringIO = runtime.getClass("StringIO").newInstance(context, args[0], Block.NULL_BLOCK);
248
248
  InputStream in = new UncloseableInputStream(new IOInputStream(stringIO));
249
249
  reader.setInput(context, in, url, options);
250
250
  return reader;
@@ -280,15 +280,15 @@ public class XmlReader extends RubyObject {
280
280
 
281
281
  private String getOuterXml() {
282
282
  ReaderNode current = currentNode();
283
- if (current.depth < 0) return null;
283
+ if (current == null || current.depth < 0) return null;
284
284
 
285
285
  if (current instanceof ClosingNode) {
286
- return "<" + current.name + "/>";
286
+ return "<" + current.name + "/>";
287
287
  }
288
288
 
289
- StringBuffer sb = new StringBuffer();
289
+ StringBuilder sb = new StringBuilder();
290
290
  for (int i = position; i <= current.endOffset; i++) {
291
- sb.append(nodeQueue.get(i).getString());
291
+ sb.append(nodeQueue.get(i).getString());
292
292
  }
293
293
  return new String(sb);
294
294
  }
@@ -324,54 +324,56 @@ public class XmlReader extends RubyObject {
324
324
  }
325
325
 
326
326
  private void readMoreData(ThreadContext context) {
327
- if (!continueParsing) {
328
- throw context.runtime.newRuntimeError("Cannot parse more data");
329
- }
330
- try {
331
- continueParsing = config.parse(false);
332
- } catch (XNIException e) {
333
- Ruby ruby = context.runtime;
334
- XmlSyntaxError exception = (XmlSyntaxError) NokogiriService.XML_SYNTAXERROR_ALLOCATOR.allocate(ruby, getNokogiriClass(ruby, "Nokogiri::XML::SyntaxError"));
335
- throw new RaiseException(exception);
336
- } catch (IOException e) {
337
- throw context.getRuntime().newRuntimeError("Received IOException: " + e.getMessage());
338
- }
327
+ if (!continueParsing) throw context.runtime.newRuntimeError("Cannot parse more data");
328
+ try {
329
+ continueParsing = config.parse(false);
330
+ }
331
+ catch (XNIException e) {
332
+ throw new RaiseException(XmlSyntaxError.createXMLSyntaxError(context.runtime, e)); // Nokogiri::XML::SyntaxError
333
+ }
334
+ catch (IOException e) {
335
+ throw context.runtime.newRuntimeError(e.toString());
336
+ }
339
337
  }
340
338
 
341
339
  private void ensureNodeClosed(ThreadContext context) {
342
- ReaderNode node = currentNode();
343
- if (node instanceof TextNode) {
344
- return;
345
- }
346
- while (node.endOffset < 1) {
347
- readMoreData(context);
348
- }
340
+ ReaderNode node = currentNode();
341
+ if (node instanceof TextNode) return;
342
+ while (node.endOffset < 1) readMoreData(context);
349
343
  }
350
344
 
351
345
  @JRubyMethod
352
346
  public IRubyObject read(ThreadContext context) {
353
347
  position++;
354
- while (nodeQueue.size() <= position && continueParsing) {
355
- readMoreData(context);
348
+ try {
349
+ while (nodeQueue.size() <= position && continueParsing) {
350
+ readMoreData(context);
351
+ }
352
+ return setAndRaiseErrorsIfAny(context.runtime, null);
353
+ }
354
+ catch (RaiseException ex) {
355
+ return setAndRaiseErrorsIfAny(context.runtime, ex);
356
356
  }
357
- if(currentNode() == null) {
358
- return context.nil;
359
- } else if(currentNode().isError()) {
360
- RubyArray errors = (RubyArray) this.getInstanceVariable("@errors");
361
- errors.append(currentNode().toSyntaxError());
357
+ }
362
358
 
363
- this.setInstanceVariable("@errors", errors);
359
+ private IRubyObject setAndRaiseErrorsIfAny(final Ruby runtime, final RaiseException ex) throws RaiseException {
360
+ final ReaderNode currentNode = currentNode();
361
+ if (currentNode == null) return runtime.getNil();
362
+ if (currentNode.isError()) {
363
+ RubyArray errors = (RubyArray) getInstanceVariable("@errors");
364
+ IRubyObject error = currentNode.toSyntaxError();
365
+ errors.append(error);
366
+ setInstanceVariable("@errors", errors);
364
367
 
365
- throw new RaiseException((XmlSyntaxError) currentNode().toSyntaxError());
366
- } else {
367
- return this;
368
+ throw ex != null ? ex : new RaiseException((XmlSyntaxError) error);
368
369
  }
370
+ if ( ex != null ) throw ex;
371
+ return this;
369
372
  }
370
373
 
371
374
  private ReaderNode currentNode() {
372
- if (position >= nodeQueue.size())
373
- return null;
374
- return nodeQueue.get(position);
375
+ if (position >= nodeQueue.size()) return null;
376
+ return nodeQueue.get(position);
375
377
  }
376
378
 
377
379
  @JRubyMethod
@@ -420,15 +422,13 @@ public class XmlReader extends RubyObject {
420
422
  this.ruby = ruby;
421
423
  }
422
424
 
423
-
424
-
425
425
  @Override
426
- public void startGeneralEntity(String name, XMLResourceIdentifier identifier, String encoding,
427
- Augmentations augs) throws XNIException {
428
- Object entitySkipped;
429
- if (augs != null && (entitySkipped = augs.getItem(Constants.ENTITY_SKIPPED)) != null && ((Boolean) entitySkipped) == true) {
430
- nodeQueue.add(new ReaderNode.ExceptionNode(ruby, null));
431
- }
426
+ public void startGeneralEntity(String name, XMLResourceIdentifier identifier,
427
+ String encoding, Augmentations augs) throws XNIException {
428
+ Object entitySkipped;
429
+ if (augs != null && (entitySkipped = augs.getItem(Constants.ENTITY_SKIPPED)) != null && ((Boolean) entitySkipped)) {
430
+ nodeQueue.add(new ReaderNode.ExceptionNode(ruby, null));
431
+ }
432
432
  }
433
433
 
434
434
 
@@ -479,7 +479,7 @@ public class XmlReader extends RubyObject {
479
479
 
480
480
  @Override
481
481
  public void emptyElement(QName element, XMLAttributes attrs, Augmentations augs) {
482
- commonElement(element, attrs, true);
482
+ commonElement(element, attrs, true);
483
483
  }
484
484
 
485
485
  private void commonElement(QName element, XMLAttributes attrs, boolean isEmpty) {
@@ -528,5 +528,5 @@ public class XmlReader extends RubyObject {
528
528
  nodeQueue.add(new ReaderNode.ExceptionNode(ruby, ex));
529
529
  throw ex;
530
530
  }
531
- };
531
+ }
532
532
  }
@@ -93,7 +93,7 @@ public class XmlRelaxng extends XmlSchema {
93
93
  }
94
94
 
95
95
  private Schema getSchema(Source source, ThreadContext context) {
96
- InputStream is = null;
96
+ InputStream is;
97
97
  VerifierFactory factory = new com.thaiopensource.relaxng.jarv.VerifierFactoryImpl();
98
98
  if (source instanceof StreamSource) {
99
99
  StreamSource ss = (StreamSource)source;
@@ -46,6 +46,7 @@ import java.util.concurrent.ThreadFactory;
46
46
 
47
47
  import nokogiri.internals.ClosedStreamException;
48
48
  import nokogiri.internals.NokogiriBlockingQueueInputStream;
49
+ import nokogiri.internals.NokogiriHelpers;
49
50
  import nokogiri.internals.ParserContext;
50
51
 
51
52
  import org.jruby.Ruby;
@@ -58,6 +59,7 @@ import org.jruby.anno.JRubyMethod;
58
59
  import org.jruby.exceptions.RaiseException;
59
60
  import org.jruby.runtime.ThreadContext;
60
61
  import org.jruby.runtime.builtin.IRubyObject;
62
+ import org.jruby.util.ByteList;
61
63
  import org.xml.sax.SAXException;
62
64
 
63
65
  /**
@@ -115,42 +117,60 @@ public class XmlSaxPushParser extends RubyObject {
115
117
  return getOptions(context);
116
118
  }
117
119
 
120
+ /**
121
+ * Can take a boolean assignment.
122
+ *
123
+ * @param context
124
+ * @param value
125
+ * @return
126
+ */
127
+ @JRubyMethod(name = "replace_entities=")
128
+ public IRubyObject setReplaceEntities(ThreadContext context, IRubyObject value) {
129
+ // Ignore the value.
130
+ return this;
131
+ }
132
+
133
+ @JRubyMethod(name="replace_entities")
134
+ public IRubyObject getReplaceEntities(ThreadContext context) {
135
+ // The java parser always replaces entities.
136
+ return context.getRuntime().getTrue();
137
+ }
138
+
118
139
  @JRubyMethod
119
140
  public IRubyObject native_write(ThreadContext context, IRubyObject chunk,
120
141
  IRubyObject isLast) {
121
142
  try {
122
143
  initialize_task(context);
123
144
  } catch (IOException e) {
124
- throw context.getRuntime().newRuntimeError(e.getMessage());
145
+ throw context.runtime.newRuntimeError(e.getMessage());
125
146
  }
126
- byte[] data = null;
127
- if (chunk instanceof RubyString || chunk.respondsTo("to_str")) {
128
- data = chunk.convertToString().getBytes();
129
- } else {
147
+ final ByteArrayInputStream data = NokogiriHelpers.stringBytesToStream(chunk);
148
+ if (data == null) {
130
149
  terminateTask(context);
131
- XmlSyntaxError xmlSyntaxError =
132
- (XmlSyntaxError) NokogiriService.XML_SYNTAXERROR_ALLOCATOR.allocate(context.getRuntime(), getNokogiriClass(context.getRuntime(), "Nokogiri::XML::SyntaxError"));
133
- throw new RaiseException(xmlSyntaxError);
150
+ throw new RaiseException(XmlSyntaxError.createXMLSyntaxError(context.runtime)); // Nokogiri::XML::SyntaxError
134
151
  }
135
152
 
136
- int errorCount0 = parserTask.getErrorCount();;
153
+ int errorCount0 = parserTask.getErrorCount();
137
154
 
138
155
 
139
156
  if (isLast.isTrue()) {
140
157
  try {
141
158
  parserTask.parser.getNokogiriHandler().endDocument();
142
- } catch (SAXException e) {
143
- throw context.getRuntime().newRuntimeError(e.getMessage());
159
+ }
160
+ catch (SAXException e) {
161
+ throw context.runtime.newRuntimeError(e.getMessage());
144
162
  }
145
163
  terminateTask(context);
146
164
  } else {
147
165
  try {
148
- Future<Void> task = stream.addChunk(new ByteArrayInputStream(data));
149
- task.get();
150
- } catch (ClosedStreamException ex) {
151
- // this means the stream is closed, ignore this exception
152
- } catch (Exception e) {
153
- throw context.getRuntime().newRuntimeError(e.getMessage());
166
+ Future<Void> task = stream.addChunk(data);
167
+ task.get();
168
+ }
169
+ catch (ClosedStreamException ex) {
170
+ // this means the stream is closed, ignore this exception
171
+ }
172
+ catch (Exception e) {
173
+ throw context.runtime.newRuntimeError(e.toString());
154
174
  }
155
175
 
156
176
  }