nokogiri 1.10.9-java → 1.11.0.rc4-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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE-DEPENDENCIES.md +1015 -947
  3. data/README.md +24 -22
  4. data/ext/java/nokogiri/HtmlDocument.java +34 -46
  5. data/ext/java/nokogiri/HtmlSaxParserContext.java +88 -58
  6. data/ext/java/nokogiri/HtmlSaxPushParser.java +1 -1
  7. data/ext/java/nokogiri/NokogiriService.java +1 -1
  8. data/ext/java/nokogiri/XmlAttr.java +13 -20
  9. data/ext/java/nokogiri/XmlAttributeDecl.java +11 -12
  10. data/ext/java/nokogiri/XmlCdata.java +3 -4
  11. data/ext/java/nokogiri/XmlComment.java +1 -1
  12. data/ext/java/nokogiri/XmlDocument.java +148 -175
  13. data/ext/java/nokogiri/XmlDocumentFragment.java +13 -31
  14. data/ext/java/nokogiri/XmlDtd.java +5 -8
  15. data/ext/java/nokogiri/XmlElement.java +1 -20
  16. data/ext/java/nokogiri/XmlElementDecl.java +23 -28
  17. data/ext/java/nokogiri/XmlEntityDecl.java +23 -27
  18. data/ext/java/nokogiri/XmlEntityReference.java +2 -2
  19. data/ext/java/nokogiri/XmlNamespace.java +72 -89
  20. data/ext/java/nokogiri/XmlNode.java +303 -406
  21. data/ext/java/nokogiri/XmlNodeSet.java +70 -76
  22. data/ext/java/nokogiri/XmlReader.java +12 -13
  23. data/ext/java/nokogiri/XmlRelaxng.java +10 -3
  24. data/ext/java/nokogiri/XmlSaxParserContext.java +15 -10
  25. data/ext/java/nokogiri/XmlSchema.java +87 -27
  26. data/ext/java/nokogiri/XmlSyntaxError.java +2 -6
  27. data/ext/java/nokogiri/XmlText.java +12 -9
  28. data/ext/java/nokogiri/XmlXpathContext.java +55 -25
  29. data/ext/java/nokogiri/XsltStylesheet.java +7 -15
  30. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +52 -46
  31. data/ext/java/nokogiri/internals/NokogiriHandler.java +1 -1
  32. data/ext/java/nokogiri/internals/NokogiriHelpers.java +71 -135
  33. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +90 -58
  34. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +9 -2
  35. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +67 -10
  36. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +4 -2
  37. data/ext/java/nokogiri/internals/ParserContext.java +27 -73
  38. data/ext/java/nokogiri/internals/ReaderNode.java +2 -4
  39. data/ext/java/nokogiri/internals/XmlDomParserContext.java +18 -33
  40. data/ext/nokogiri/depend +476 -357
  41. data/ext/nokogiri/extconf.rb +485 -352
  42. data/ext/nokogiri/html_document.c +79 -78
  43. data/ext/nokogiri/html_sax_parser_context.c +2 -2
  44. data/ext/nokogiri/nokogiri.c +34 -40
  45. data/ext/nokogiri/xml_document.c +18 -4
  46. data/ext/nokogiri/xml_io.c +8 -6
  47. data/ext/nokogiri/xml_node.c +21 -1
  48. data/ext/nokogiri/xml_node_set.c +1 -1
  49. data/ext/nokogiri/xml_reader.c +6 -17
  50. data/ext/nokogiri/xml_relax_ng.c +29 -11
  51. data/ext/nokogiri/xml_sax_parser.c +2 -7
  52. data/ext/nokogiri/xml_sax_parser_context.c +2 -2
  53. data/ext/nokogiri/xml_schema.c +55 -13
  54. data/ext/nokogiri/xml_xpath_context.c +80 -4
  55. data/ext/nokogiri/xslt_stylesheet.c +1 -8
  56. data/lib/nokogiri.rb +4 -21
  57. data/lib/nokogiri/css.rb +1 -0
  58. data/lib/nokogiri/css/node.rb +1 -0
  59. data/lib/nokogiri/css/parser.rb +63 -62
  60. data/lib/nokogiri/css/parser.y +2 -2
  61. data/lib/nokogiri/css/parser_extras.rb +39 -36
  62. data/lib/nokogiri/css/syntax_error.rb +1 -0
  63. data/lib/nokogiri/css/tokenizer.rb +1 -0
  64. data/lib/nokogiri/css/xpath_visitor.rb +73 -43
  65. data/lib/nokogiri/decorators/slop.rb +1 -0
  66. data/lib/nokogiri/html.rb +1 -0
  67. data/lib/nokogiri/html/builder.rb +1 -0
  68. data/lib/nokogiri/html/document.rb +13 -26
  69. data/lib/nokogiri/html/document_fragment.rb +1 -0
  70. data/lib/nokogiri/html/element_description.rb +1 -0
  71. data/lib/nokogiri/html/element_description_defaults.rb +1 -0
  72. data/lib/nokogiri/html/entity_lookup.rb +1 -0
  73. data/lib/nokogiri/html/sax/parser.rb +1 -0
  74. data/lib/nokogiri/html/sax/parser_context.rb +1 -0
  75. data/lib/nokogiri/html/sax/push_parser.rb +1 -0
  76. data/lib/nokogiri/jruby/dependencies.rb +20 -0
  77. data/lib/nokogiri/nokogiri.jar +0 -0
  78. data/lib/nokogiri/syntax_error.rb +1 -0
  79. data/lib/nokogiri/version.rb +3 -109
  80. data/lib/nokogiri/version/constant.rb +5 -0
  81. data/lib/nokogiri/version/info.rb +182 -0
  82. data/lib/nokogiri/xml.rb +1 -0
  83. data/lib/nokogiri/xml/attr.rb +1 -0
  84. data/lib/nokogiri/xml/attribute_decl.rb +1 -0
  85. data/lib/nokogiri/xml/builder.rb +3 -2
  86. data/lib/nokogiri/xml/cdata.rb +1 -0
  87. data/lib/nokogiri/xml/character_data.rb +1 -0
  88. data/lib/nokogiri/xml/document.rb +20 -15
  89. data/lib/nokogiri/xml/document_fragment.rb +5 -6
  90. data/lib/nokogiri/xml/dtd.rb +1 -0
  91. data/lib/nokogiri/xml/element_content.rb +1 -0
  92. data/lib/nokogiri/xml/element_decl.rb +1 -0
  93. data/lib/nokogiri/xml/entity_decl.rb +1 -0
  94. data/lib/nokogiri/xml/entity_reference.rb +1 -0
  95. data/lib/nokogiri/xml/namespace.rb +1 -0
  96. data/lib/nokogiri/xml/node.rb +587 -249
  97. data/lib/nokogiri/xml/node/save_options.rb +1 -0
  98. data/lib/nokogiri/xml/node_set.rb +1 -0
  99. data/lib/nokogiri/xml/notation.rb +1 -0
  100. data/lib/nokogiri/xml/parse_options.rb +10 -3
  101. data/lib/nokogiri/xml/pp.rb +1 -0
  102. data/lib/nokogiri/xml/pp/character_data.rb +1 -0
  103. data/lib/nokogiri/xml/pp/node.rb +1 -0
  104. data/lib/nokogiri/xml/processing_instruction.rb +1 -0
  105. data/lib/nokogiri/xml/reader.rb +7 -3
  106. data/lib/nokogiri/xml/relax_ng.rb +7 -2
  107. data/lib/nokogiri/xml/sax.rb +1 -0
  108. data/lib/nokogiri/xml/sax/document.rb +1 -0
  109. data/lib/nokogiri/xml/sax/parser.rb +1 -0
  110. data/lib/nokogiri/xml/sax/parser_context.rb +1 -0
  111. data/lib/nokogiri/xml/sax/push_parser.rb +1 -0
  112. data/lib/nokogiri/xml/schema.rb +13 -4
  113. data/lib/nokogiri/xml/searchable.rb +25 -16
  114. data/lib/nokogiri/xml/syntax_error.rb +1 -0
  115. data/lib/nokogiri/xml/text.rb +1 -0
  116. data/lib/nokogiri/xml/xpath.rb +1 -0
  117. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -0
  118. data/lib/nokogiri/xml/xpath_context.rb +1 -0
  119. data/lib/nokogiri/xslt.rb +1 -0
  120. data/lib/nokogiri/xslt/stylesheet.rb +1 -0
  121. data/lib/xsd/xmlparser/nokogiri.rb +1 -0
  122. metadata +89 -96
  123. data/ext/java/nokogiri/internals/NokogiriEncodingReaderWrapper.java +0 -107
  124. data/ext/java/nokogiri/internals/UncloseableInputStream.java +0 -102
  125. data/ext/nokogiri/html_document.h +0 -10
  126. data/ext/nokogiri/html_element_description.h +0 -10
  127. data/ext/nokogiri/html_entity_lookup.h +0 -8
  128. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  129. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  130. data/ext/nokogiri/nokogiri.h +0 -121
  131. data/ext/nokogiri/xml_attr.h +0 -9
  132. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  133. data/ext/nokogiri/xml_cdata.h +0 -9
  134. data/ext/nokogiri/xml_comment.h +0 -9
  135. data/ext/nokogiri/xml_document.h +0 -23
  136. data/ext/nokogiri/xml_document_fragment.h +0 -10
  137. data/ext/nokogiri/xml_dtd.h +0 -10
  138. data/ext/nokogiri/xml_element_content.h +0 -10
  139. data/ext/nokogiri/xml_element_decl.h +0 -9
  140. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  141. data/ext/nokogiri/xml_entity_decl.h +0 -10
  142. data/ext/nokogiri/xml_entity_reference.h +0 -9
  143. data/ext/nokogiri/xml_io.h +0 -11
  144. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  145. data/ext/nokogiri/xml_namespace.h +0 -14
  146. data/ext/nokogiri/xml_node.h +0 -13
  147. data/ext/nokogiri/xml_node_set.h +0 -12
  148. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  149. data/ext/nokogiri/xml_reader.h +0 -10
  150. data/ext/nokogiri/xml_relax_ng.h +0 -9
  151. data/ext/nokogiri/xml_sax_parser.h +0 -39
  152. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  153. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  154. data/ext/nokogiri/xml_schema.h +0 -9
  155. data/ext/nokogiri/xml_syntax_error.h +0 -13
  156. data/ext/nokogiri/xml_text.h +0 -9
  157. data/ext/nokogiri/xml_xpath_context.h +0 -10
  158. data/ext/nokogiri/xslt_stylesheet.h +0 -14
@@ -33,24 +33,13 @@
33
33
  package nokogiri;
34
34
 
35
35
  import static java.lang.Math.max;
36
- import static nokogiri.internals.NokogiriHelpers.clearXpathContext;
37
- import static nokogiri.internals.NokogiriHelpers.convertEncoding;
38
- import static nokogiri.internals.NokogiriHelpers.convertString;
39
- import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
40
- import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
41
- import static nokogiri.internals.NokogiriHelpers.isBlank;
42
- import static nokogiri.internals.NokogiriHelpers.nodeArrayToRubyArray;
43
- import static nokogiri.internals.NokogiriHelpers.nonEmptyStringOrNil;
44
- import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
45
- import static nokogiri.internals.NokogiriHelpers.stringOrNil;
36
+ import static nokogiri.internals.NokogiriHelpers.*;
46
37
 
47
38
  import java.io.ByteArrayInputStream;
48
39
  import java.io.InputStream;
49
40
  import java.nio.ByteBuffer;
50
41
  import java.nio.charset.Charset;
51
- import java.util.ArrayList;
52
- import java.util.Iterator;
53
- import java.util.List;
42
+ import java.util.*;
54
43
 
55
44
  import org.apache.xerces.dom.CoreDocumentImpl;
56
45
  import org.jruby.Ruby;
@@ -64,8 +53,8 @@ import org.jruby.RubyString;
64
53
  import org.jruby.anno.JRubyClass;
65
54
  import org.jruby.anno.JRubyMethod;
66
55
  import org.jruby.exceptions.RaiseException;
67
- import org.jruby.runtime.Helpers;
68
56
  import org.jruby.runtime.Block;
57
+ import org.jruby.runtime.Helpers;
69
58
  import org.jruby.runtime.ThreadContext;
70
59
  import org.jruby.runtime.Visibility;
71
60
  import org.jruby.runtime.builtin.IRubyObject;
@@ -102,8 +91,8 @@ public class XmlNode extends RubyObject {
102
91
 
103
92
  /* Cached objects */
104
93
  protected IRubyObject content = null;
105
- protected IRubyObject doc = null;
106
- protected IRubyObject name = null;
94
+ private transient XmlDocument doc;
95
+ protected transient RubyString name;
107
96
 
108
97
  /*
109
98
  * Taken from http://ejohn.org/blog/comparing-document-position/
@@ -124,7 +113,7 @@ public class XmlNode extends RubyObject {
124
113
  */
125
114
  protected static XmlNode asXmlNode(ThreadContext context, IRubyObject node) {
126
115
  if ( !(node instanceof XmlNode) ) {
127
- final Ruby runtime = context.getRuntime();
116
+ final Ruby runtime = context.runtime;
128
117
  throw runtime.newTypeError(node == null ? runtime.getNil() : node, getNokogiriClass(runtime, "Nokogiri::XML::Node"));
129
118
  }
130
119
  return (XmlNode) node;
@@ -206,29 +195,25 @@ public class XmlNode extends RubyObject {
206
195
  * This is the allocator for XmlNode class. It should only be
207
196
  * called from Ruby code.
208
197
  */
209
- public XmlNode(Ruby ruby, RubyClass cls) {
210
- super(ruby, cls);
198
+ public XmlNode(Ruby runtime, RubyClass klass) {
199
+ super(runtime, klass);
211
200
  }
212
201
 
213
202
  /**
214
203
  * This is a constructor to create an XmlNode from an already
215
204
  * existing node. It may be called by Java code.
216
205
  */
217
- public XmlNode(Ruby ruby, RubyClass cls, Node node) {
218
- super(ruby, cls);
219
- setNode(ruby.getCurrentContext(), node);
206
+ public XmlNode(Ruby runtime, RubyClass klass, Node node) {
207
+ super(runtime, klass);
208
+ setNode(runtime, node);
220
209
  }
221
210
 
222
- protected void decorate(final ThreadContext context) {
211
+ protected void decorate(final Ruby runtime) {
223
212
  if (node != null) {
224
213
  resetCache();
225
214
 
226
215
  if (node.getNodeType() != Node.DOCUMENT_NODE) {
227
- doc = document(context.runtime);
228
-
229
- if (doc != null && ! doc.isNil()) {
230
- Helpers.invoke(context, doc, "decorate", this);
231
- }
216
+ setDocumentAndDecorate(runtime.getCurrentContext(), this, document(runtime));
232
217
  }
233
218
  }
234
219
  }
@@ -287,7 +272,7 @@ public class XmlNode extends RubyObject {
287
272
  @JRubyMethod(name = "new", meta = true, rest = true)
288
273
  public static IRubyObject rbNew(ThreadContext context, IRubyObject cls,
289
274
  IRubyObject[] args, Block block) {
290
- Ruby ruby = context.getRuntime();
275
+ Ruby ruby = context.runtime;
291
276
  RubyClass klazz = (RubyClass) cls;
292
277
 
293
278
  if ("Nokogiri::XML::Node".equals(klazz.getName())) {
@@ -320,14 +305,14 @@ public class XmlNode extends RubyObject {
320
305
  */
321
306
  protected void init(ThreadContext context, IRubyObject[] args) {
322
307
  if (args.length < 2)
323
- throw context.getRuntime().newArgumentError(args.length, 2);
308
+ throw context.runtime.newArgumentError(args.length, 2);
324
309
 
325
310
  IRubyObject name = args[0];
326
311
  IRubyObject doc = args[1];
327
312
 
328
313
  Document document = asXmlNode(context, doc).getOwnerDocument();
329
314
  if (document == null) {
330
- throw getRuntime().newArgumentError("node must have owner document");
315
+ throw context.runtime.newArgumentError("node must have owner document");
331
316
  }
332
317
 
333
318
  Element element;
@@ -338,7 +323,7 @@ public class XmlNode extends RubyObject {
338
323
  namespace_uri = document.getDocumentElement().lookupNamespaceURI(prefix);
339
324
  }
340
325
  element = document.createElementNS(namespace_uri, node_name);
341
- setNode(context, element);
326
+ setNode(context.runtime, element);
342
327
  }
343
328
 
344
329
  /**
@@ -365,53 +350,6 @@ public class XmlNode extends RubyObject {
365
350
  return node;
366
351
  }
367
352
 
368
- public static Node getNodeFromXmlNode(ThreadContext context, IRubyObject xmlNode) {
369
- return asXmlNode(context, xmlNode).node;
370
- }
371
-
372
- protected String indentString(IRubyObject indentStringObject, String xml) {
373
- String[] lines = xml.split("\n");
374
-
375
- if(lines.length <= 1) return xml;
376
-
377
- String[] resultLines = new String[lines.length];
378
-
379
- String curLine;
380
- boolean closingTag = false;
381
- String indentString = rubyStringToString(indentStringObject);
382
- int lengthInd = indentString.length();
383
- StringBuilder curInd = new StringBuilder();
384
-
385
- resultLines[0] = lines[0];
386
-
387
- for(int i = 1; i < lines.length; i++) {
388
-
389
- curLine = lines[i].trim();
390
-
391
- if(curLine.length() == 0) continue;
392
-
393
- if(curLine.startsWith("</")) {
394
- closingTag = true;
395
- curInd.setLength(max(0,curInd.length() - lengthInd));
396
- }
397
-
398
- resultLines[i] = curInd.toString() + curLine;
399
-
400
- if(!curLine.endsWith("/>") && !closingTag) {
401
- curInd.append(indentString);
402
- }
403
-
404
- closingTag = false;
405
- }
406
-
407
- StringBuilder result = new StringBuilder();
408
- for(int i = 0; i < resultLines.length; i++) {
409
- result.append(resultLines[i]).append('\n');
410
- }
411
-
412
- return result.toString();
413
- }
414
-
415
353
  public boolean isComment() { return false; }
416
354
 
417
355
  public boolean isElement() {
@@ -431,7 +369,7 @@ public class XmlNode extends RubyObject {
431
369
  * declarations like XmlElementDecl.
432
370
  */
433
371
  protected IRubyObject getAttribute(ThreadContext context, String key) {
434
- return getAttribute(context.getRuntime(), key);
372
+ return getAttribute(context.runtime, key);
435
373
  }
436
374
 
437
375
  protected IRubyObject getAttribute(Ruby runtime, String key) {
@@ -472,9 +410,7 @@ public class XmlNode extends RubyObject {
472
410
  String nsURI = e.lookupNamespaceURI(prefix);
473
411
  this.node = NokogiriHelpers.renameNode(e, nsURI, e.getNodeName());
474
412
 
475
- if (nsURI == null || nsURI == "") {
476
- return;
477
- }
413
+ if (nsURI == null || nsURI.isEmpty()) return;
478
414
 
479
415
  String currentPrefix = e.getParentNode().lookupPrefix(nsURI);
480
416
  String currentURI = e.getParentNode().lookupNamespaceURI(prefix);
@@ -483,18 +419,15 @@ public class XmlNode extends RubyObject {
483
419
  // add xmlns attribute if this is a new root node or if the node's
484
420
  // namespace isn't a default namespace in the new document
485
421
  if (e.getParentNode().getNodeType() == Node.DOCUMENT_NODE) {
486
- // this is the root node, so we must set the namespaces attributes
487
- // anyway
488
- e.setAttribute(prefix == null ? "xmlns":"xmlns:"+prefix, nsURI);
422
+ // this is the root node, so we must set the namespaces attributes anyway
423
+ e.setAttribute(prefix == null ? "xmlns" : "xmlns:" + prefix, nsURI);
489
424
  } else if (prefix == null) {
490
- if (!isDefault)
491
- // this is a default namespace but isn't the default where this
492
- // node is being added
493
- e.setAttribute("xmlns", nsURI);
494
- } else if (currentPrefix != prefix || currentURI != nsURI) {
495
- // this is a prefixed namespace but doens't have the same prefix or
496
- // the prefix is set to a diffent URI
497
- e.setAttribute("xmlns:"+prefix, nsURI);
425
+ // this is a default namespace but isn't the default where this node is being added
426
+ if (!isDefault) e.setAttribute("xmlns", nsURI);
427
+ } else if (!prefix.equals(currentPrefix) || nsURI.equals(currentURI)) {
428
+ // this is a prefixed namespace
429
+ // but doesn't have the same prefix or the prefix is set to a different URI
430
+ e.setAttribute("xmlns:" + prefix, nsURI);
498
431
  }
499
432
 
500
433
  if (e.hasAttributes()) {
@@ -516,87 +449,76 @@ public class XmlNode extends RubyObject {
516
449
  nsUri = attr.lookupNamespaceURI(attrPrefix);
517
450
  }
518
451
 
519
- if (nsUri == e.getNamespaceURI()) {
452
+ if (nsUri != null && nsUri.equals(e.getNamespaceURI())) {
520
453
  nsUri = null;
521
454
  }
522
455
 
523
456
  if (!(nsUri == null || "".equals(nsUri) || "http://www.w3.org/XML/1998/namespace".equals(nsUri))) {
524
- // Create a new namespace object and add it to the document
525
- // namespace cache.
457
+ // Create a new namespace object and add it to the document namespace cache.
526
458
  // TODO: why do we need the namespace cache ?
527
- XmlNamespace.createFromAttr(context.getRuntime(), attr);
459
+ XmlNamespace.createFromAttr(context.runtime, attr);
528
460
  }
529
461
  NokogiriHelpers.renameNode(attr, nsUri, nodeName);
530
462
  }
531
463
  }
532
464
 
533
465
  if (this.node.hasChildNodes()) {
534
- XmlNodeSet nodeSet = (XmlNodeSet)(children(context));
535
- nodeSet.relink_namespace(context);
466
+ relink_namespace(context, getChildren());
467
+ }
468
+ }
469
+
470
+ static void relink_namespace(ThreadContext context, IRubyObject[] nodes) {
471
+ for (int i = 0; i < nodes.length; i++) {
472
+ if (nodes[i] instanceof XmlNode) {
473
+ ((XmlNode) nodes[i]).relink_namespace(context);
474
+ }
536
475
  }
537
476
  }
538
477
 
539
478
  // Users might extend XmlNode. This method works for such a case.
540
479
  public void accept(ThreadContext context, SaveContextVisitor visitor) {
541
480
  visitor.enter(node);
542
- XmlNodeSet xmlNodeSet = (XmlNodeSet) children(context);
543
- if (xmlNodeSet.length() > 0) {
544
- RubyArray array = (RubyArray) xmlNodeSet.to_a(context);
545
- for(int i = 0; i < array.getLength(); i++) {
546
- Object item = array.get(i);
481
+ acceptChildren(context, getChildren(), visitor);
482
+ visitor.leave(node);
483
+ }
484
+
485
+ void acceptChildren(ThreadContext context, IRubyObject[] nodes, SaveContextVisitor visitor) {
486
+ if (nodes.length > 0) {
487
+ for (int i = 0; i < nodes.length; i++) {
488
+ Object item = nodes[i];
547
489
  if (item instanceof XmlNode) {
548
- XmlNode cur = (XmlNode) item;
549
- cur.accept(context, visitor);
490
+ ((XmlNode) item).accept(context, visitor);
550
491
  } else if (item instanceof XmlNamespace) {
551
- XmlNamespace cur = (XmlNamespace)item;
552
- cur.accept(context, visitor);
492
+ ((XmlNamespace) item).accept(context, visitor);
553
493
  }
554
494
  }
555
495
  }
556
- visitor.leave(node);
557
496
  }
558
497
 
559
- public void setName(IRubyObject name) {
560
- this.name = name;
498
+ RubyString doSetName(IRubyObject name) {
499
+ if (name.isNil()) return this.name = null;
500
+ return this.name = name.convertToString();
561
501
  }
562
502
 
563
- public void setDocument(ThreadContext context, IRubyObject doc) {
503
+ public void setDocument(ThreadContext context, XmlDocument doc) {
564
504
  this.doc = doc;
565
505
 
566
506
  setDocumentAndDecorate(context, this, doc);
567
507
  }
568
508
 
569
509
  // shared logic with XmlNodeSet
570
- static void setDocumentAndDecorate(ThreadContext context, RubyObject self, IRubyObject doc) {
571
- self.setInstanceVariable("@document", doc);
572
- if (doc != null) {
573
- Helpers.invoke(context, doc, "decorate", self);
574
- }
510
+ static void setDocumentAndDecorate(ThreadContext context, RubyObject self, XmlDocument doc) {
511
+ self.setInstanceVariable("@document", doc == null ? context.nil : doc);
512
+ if (doc != null) Helpers.invoke(context, doc, "decorate", self);
575
513
  }
576
514
 
577
- public void setNode(ThreadContext context, Node node) {
515
+ public void setNode(Ruby runtime, Node node) {
578
516
  this.node = node;
579
517
 
580
- decorate(context);
518
+ decorate(runtime);
581
519
 
582
520
  if (this instanceof XmlAttr) {
583
- ((XmlAttr)this).setNamespaceIfNecessary(context.getRuntime());
584
- }
585
- }
586
-
587
- public void updateNodeNamespaceIfNecessary(ThreadContext context, XmlNamespace ns) {
588
- String oldPrefix = this.node.getPrefix();
589
- String uri = rubyStringToString(ns.href(context));
590
-
591
- /*
592
- * Update if both prefixes are null or equal
593
- */
594
- boolean update = (oldPrefix == null && ns.prefix(context).isNil()) ||
595
- (oldPrefix != null && !ns.prefix(context).isNil()
596
- && oldPrefix.equals(rubyStringToString(ns.prefix(context))));
597
-
598
- if(update) {
599
- this.node = NokogiriHelpers.renameNode(this.node, uri, this.node.getNodeName());
521
+ ((XmlAttr) this).setNamespaceIfNecessary(runtime);
600
522
  }
601
523
  }
602
524
 
@@ -605,12 +527,11 @@ public class XmlNode extends RubyObject {
605
527
 
606
528
  String str = null;
607
529
  if (node != null) {
608
- str = node.getNodeName();
609
- str = NokogiriHelpers.getLocalPart(str);
530
+ str = NokogiriHelpers.getLocalPart(node.getNodeName());
610
531
  }
611
532
  if (str == null) str = "";
612
- if (str.startsWith("#")) str = str.substring(1); // eliminates '#'
613
- return name = NokogiriHelpers.stringOrBlank(context.getRuntime(), str);
533
+ if (str.startsWith("#")) str = str.substring(1); // eliminates '#'
534
+ return name = context.runtime.newString(str);
614
535
  }
615
536
 
616
537
  /**
@@ -619,26 +540,20 @@ public class XmlNode extends RubyObject {
619
540
  * <code>xmlns:prefix="uri"</code>.
620
541
  */
621
542
  @JRubyMethod(name = {"add_namespace_definition", "add_namespace"})
622
- public IRubyObject add_namespace_definition(ThreadContext context,
623
- IRubyObject prefix,
624
- IRubyObject href) {
625
- String prefixString = rubyStringToString(prefix);
626
- String hrefString ;
543
+ public IRubyObject add_namespace_definition(ThreadContext context, IRubyObject prefix, IRubyObject href) {
544
+ String hrefStr, prefixStr = prefix.isNil() ? null : prefix.convertToString().decodeString();
627
545
 
628
546
  // try to search the namespace first
629
547
  if (href.isNil()) {
630
- hrefString = this.findNamespaceHref(context, rubyStringToString(prefix));
631
- if (hrefString == null) {
632
- return context.nil;
633
- }
634
- href = context.getRuntime().newString(hrefString);
548
+ hrefStr = findNamespaceHref(context, prefixStr);
549
+ if (hrefStr == null) return context.nil;
550
+ href = context.runtime.newString(hrefStr);
635
551
  } else {
636
- hrefString = rubyStringToString(href);
552
+ hrefStr = rubyStringToString(href.convertToString());
637
553
  }
638
554
 
639
- NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(node);
640
- XmlNamespace cachedNamespace = nsCache.get(prefixString, hrefString);
641
-
555
+ NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCache(node);
556
+ XmlNamespace cachedNamespace = nsCache.get(prefixStr, hrefStr);
642
557
  if (cachedNamespace != null) return cachedNamespace;
643
558
 
644
559
  Node namespaceOwner;
@@ -646,48 +561,58 @@ public class XmlNode extends RubyObject {
646
561
  namespaceOwner = node;
647
562
  Element element = (Element) node;
648
563
  // adds namespace as node's attribute
649
- final String uri = "http://www.w3.org/2000/xmlns/";
650
- String qName =
651
- prefix.isNil() ? "xmlns" : "xmlns:" + prefixString;
652
-
653
- element.setAttributeNS(uri, qName, hrefString);
564
+ String qName = prefix.isNil() ? "xmlns" : "xmlns:" + prefixStr;
565
+ element.setAttributeNS("http://www.w3.org/2000/xmlns/", qName, hrefStr);
654
566
  }
655
- else if (node.getNodeType() == Node.ATTRIBUTE_NODE) namespaceOwner = ((Attr)node).getOwnerElement();
567
+ else if (node.getNodeType() == Node.ATTRIBUTE_NODE) namespaceOwner = ((Attr) node).getOwnerElement();
656
568
  else namespaceOwner = node.getParentNode();
657
- XmlNamespace ns = XmlNamespace.createFromPrefixAndHref(namespaceOwner, prefix, href);
658
- if (node != namespaceOwner) {
659
569
 
660
- this.node = NokogiriHelpers.renameNode(node, ns.getHref(), ns.getPrefix() + ":" + node.getLocalName());
570
+ XmlNamespace ns = XmlNamespace.createImpl(namespaceOwner, prefix, prefixStr, href, hrefStr);
571
+
572
+ if (node != namespaceOwner) {
573
+ node = NokogiriHelpers.renameNode(node, ns.getHref(), ns.getPrefix() + ':' + node.getLocalName());
661
574
  }
662
- updateNodeNamespaceIfNecessary(context, ns);
575
+ updateNodeNamespaceIfNecessary(ns);
663
576
 
664
577
  return ns;
665
578
  }
666
579
 
580
+ private void updateNodeNamespaceIfNecessary(XmlNamespace ns) {
581
+ String oldPrefix = this.node.getPrefix();
582
+
583
+ /*
584
+ * Update if both prefixes are null or equal
585
+ */
586
+ boolean update =
587
+ (oldPrefix == null && ns.getPrefix() == null) ||
588
+ (oldPrefix != null && oldPrefix.equals(ns.getPrefix()));
589
+
590
+ if (update) {
591
+ this.node = NokogiriHelpers.renameNode(this.node, ns.getHref(), this.node.getNodeName());
592
+ }
593
+ }
594
+
667
595
  @JRubyMethod(name = {"attribute", "attr"})
668
596
  public IRubyObject attribute(ThreadContext context, IRubyObject name){
669
597
  NamedNodeMap attrs = this.node.getAttributes();
670
598
  Node attr = attrs.getNamedItem(rubyStringToString(name));
671
- if(attr == null) {
672
- return context.getRuntime().getNil();
673
- }
674
- return getCachedNodeOrCreate(context.getRuntime(), attr);
599
+ if (attr == null) return context.nil;
600
+ return getCachedNodeOrCreate(context.runtime, attr);
675
601
  }
676
602
 
677
603
  @JRubyMethod
678
604
  public IRubyObject attribute_nodes(ThreadContext context) {
679
- NamedNodeMap nodeMap = this.node.getAttributes();
605
+ final Ruby runtime = context.runtime;
680
606
 
681
- Ruby ruby = context.getRuntime();
682
- if(nodeMap == null){
683
- return ruby.newEmptyArray();
684
- }
607
+ NamedNodeMap nodeMap = this.node.getAttributes();
685
608
 
686
- RubyArray attr = ruby.newArray();
609
+ if (nodeMap == null) return runtime.newEmptyArray();
610
+ RubyArray attr = runtime.newArray(nodeMap.getLength());
687
611
 
688
- for(int i = 0; i < nodeMap.getLength(); i++) {
612
+ final XmlDocument doc = document(context.runtime);
613
+ for (int i = 0; i < nodeMap.getLength(); i++) {
689
614
  if ((doc instanceof HtmlDocument) || !NokogiriHelpers.isNamespace(nodeMap.item(i))) {
690
- attr.append(getCachedNodeOrCreate(context.getRuntime(), nodeMap.item(i)));
615
+ attr.append(getCachedNodeOrCreate(runtime, nodeMap.item(i)));
691
616
  }
692
617
  }
693
618
 
@@ -701,10 +626,9 @@ public class XmlNode extends RubyObject {
701
626
 
702
627
  Node el = this.node.getAttributes().getNamedItemNS(nsj, namej);
703
628
 
704
- if(el == null) {
705
- return context.getRuntime().getNil();
706
- }
707
- return NokogiriHelpers.getCachedNodeOrCreate(context.getRuntime(), el);
629
+ if (el == null) return context.nil;
630
+
631
+ return NokogiriHelpers.getCachedNodeOrCreate(context.runtime, el);
708
632
  }
709
633
 
710
634
  @JRubyMethod(name = "blank?")
@@ -725,55 +649,58 @@ public class XmlNode extends RubyObject {
725
649
 
726
650
  @JRubyMethod
727
651
  public IRubyObject children(ThreadContext context) {
728
- XmlNodeSet xmlNodeSet = XmlNodeSet.newEmptyNodeSet(context);
652
+ final IRubyObject[] nodes = getChildren();
653
+ if (nodes.length == 0) {
654
+ return XmlNodeSet.newEmptyNodeSet(context, this);
655
+ }
656
+ return XmlNodeSet.newNodeSet(context.runtime, nodes);
657
+ }
729
658
 
659
+ IRubyObject[] getChildren() {
730
660
  NodeList nodeList = node.getChildNodes();
731
661
  if (nodeList.getLength() > 0) {
732
- xmlNodeSet.setNodeList(nodeList); // initializes @document from first node
733
- }
734
- else { // TODO this is very ripe for refactoring
735
- setDocumentAndDecorate(context, xmlNodeSet, doc);
662
+ return nodeListToRubyArray(getRuntime(), nodeList);
736
663
  }
737
-
738
- return xmlNodeSet;
664
+ return IRubyObject.NULL_ARRAY;
739
665
  }
740
666
 
741
667
  @JRubyMethod
742
668
  public IRubyObject first_element_child(ThreadContext context) {
743
- List<Node> elementNodes = new ArrayList<Node>();
744
- addElements(node, elementNodes, true);
745
- if (elementNodes.size() == 0) return context.getRuntime().getNil();
746
- return getCachedNodeOrCreate(context.getRuntime(), elementNodes.get(0));
669
+ List<Node> elementNodes = getElements(node, true);
670
+ if (elementNodes.size() == 0) return context.nil;
671
+ return getCachedNodeOrCreate(context.runtime, elementNodes.get(0));
747
672
  }
748
673
 
749
674
  @JRubyMethod
750
675
  public IRubyObject last_element_child(ThreadContext context) {
751
- List<Node> elementNodes = new ArrayList<Node>();
752
- addElements(node, elementNodes, false);
753
- if (elementNodes.size() == 0) return context.getRuntime().getNil();
754
- return getCachedNodeOrCreate(context.getRuntime(), elementNodes.get(elementNodes.size()-1));
676
+ List<Node> elementNodes = getElements(node, false);
677
+ if (elementNodes.size() == 0) return context.nil;
678
+ return getCachedNodeOrCreate(context.runtime, elementNodes.get(elementNodes.size() - 1));
755
679
  }
756
680
 
757
681
  @JRubyMethod(name = {"element_children", "elements"})
758
682
  public IRubyObject element_children(ThreadContext context) {
759
- List<Node> elementNodes = new ArrayList<Node>();
760
- addElements(node, elementNodes, false);
761
- IRubyObject[] array = NokogiriHelpers.nodeArrayToArray(context.runtime,
762
- elementNodes.toArray(new Node[0]));
763
- XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, array);
764
- return xmlNodeSet;
683
+ List<Node> elementNodes = getElements(node, false);
684
+ IRubyObject[] array = NokogiriHelpers.nodeListToArray(context.runtime, elementNodes);
685
+ return XmlNodeSet.newNodeSet(context.runtime, array, this);
765
686
  }
766
687
 
767
- private void addElements(Node n, List<Node> nodes, boolean isFirstOnly) {
768
- NodeList children = n.getChildNodes();
769
- if (children.getLength() == 0) return;
688
+ private static List<Node> getElements(Node node, final boolean firstOnly) {
689
+ NodeList children = node.getChildNodes();
690
+ if (children.getLength() == 0) {
691
+ return Collections.emptyList();
692
+ }
693
+ ArrayList<Node> elements = firstOnly ? null : new ArrayList<Node>(children.getLength());
770
694
  for (int i=0; i< children.getLength(); i++) {
771
695
  Node child = children.item(i);
772
696
  if (child.getNodeType() == Node.ELEMENT_NODE) {
773
- nodes.add(child);
774
- if (isFirstOnly) return;
697
+ if (firstOnly) {
698
+ return Collections.singletonList(child);
699
+ }
700
+ elements.add(child);
775
701
  }
776
702
  }
703
+ return elements;
777
704
  }
778
705
 
779
706
  /**
@@ -785,7 +712,7 @@ public class XmlNode extends RubyObject {
785
712
  @JRubyMethod(visibility=Visibility.PRIVATE)
786
713
  public IRubyObject compare(ThreadContext context, IRubyObject other) {
787
714
  if (!(other instanceof XmlNode)) {
788
- return context.getRuntime().newFixnum(-2);
715
+ return context.runtime.newFixnum(-2);
789
716
  }
790
717
 
791
718
  Node otherNode = asXmlNode(context, other).node;
@@ -793,22 +720,22 @@ public class XmlNode extends RubyObject {
793
720
  // Do not touch this if, if it's not for a good reason.
794
721
  if (node.getNodeType() == Node.DOCUMENT_NODE ||
795
722
  otherNode.getNodeType() == Node.DOCUMENT_NODE) {
796
- return context.getRuntime().newFixnum(-1);
723
+ return context.runtime.newFixnum(1);
797
724
  }
798
725
 
799
726
  try{
800
727
  int res = node.compareDocumentPosition(otherNode);
801
728
  if ((res & FIRST_PRECEDES_SECOND) == FIRST_PRECEDES_SECOND) {
802
- return context.getRuntime().newFixnum(-1);
729
+ return context.runtime.newFixnum(-1);
803
730
  } else if ((res & SECOND_PRECEDES_FIRST) == SECOND_PRECEDES_FIRST) {
804
- return context.getRuntime().newFixnum(1);
731
+ return context.runtime.newFixnum(1);
805
732
  } else if (res == IDENTICAL_ELEMENTS) {
806
- return context.getRuntime().newFixnum(0);
733
+ return context.runtime.newFixnum(0);
807
734
  }
808
735
 
809
- return context.getRuntime().newFixnum(-2);
736
+ return context.runtime.newFixnum(-2);
810
737
  } catch (Exception ex) {
811
- return context.getRuntime().newFixnum(-2);
738
+ return context.runtime.newFixnum(-2);
812
739
  }
813
740
  }
814
741
 
@@ -818,35 +745,27 @@ public class XmlNode extends RubyObject {
818
745
  * <code>options</code> into account.
819
746
  */
820
747
  @JRubyMethod(required = 2, visibility = Visibility.PRIVATE)
821
- public IRubyObject in_context(ThreadContext context,
822
- IRubyObject str,
823
- IRubyObject options) {
824
- RubyModule klass;
748
+ public IRubyObject in_context(ThreadContext context, IRubyObject str, IRubyObject options) {
749
+ RubyClass klass;
825
750
  XmlDomParserContext ctx;
826
751
  InputStream istream;
827
- XmlDocument document;
828
752
 
829
- IRubyObject d = document(context);
830
- Ruby runtime = context.getRuntime();
831
- if (d != null && d instanceof XmlDocument) {
832
- document = (XmlDocument)d;
833
- } else {
834
- return runtime.getNil();
835
- }
753
+ final Ruby runtime = context.runtime;
754
+
755
+ XmlDocument document = document(runtime);
756
+ if (document == null) return context.nil;
836
757
 
837
758
  if (document instanceof HtmlDocument) {
838
759
  klass = getNokogiriClass(runtime, "Nokogiri::HTML::Document");
839
760
  ctx = new HtmlDomParserContext(runtime, options);
840
- ((HtmlDomParserContext)ctx).enableDocumentFragment();
841
- istream = new ByteArrayInputStream((rubyStringToString(str)).getBytes());
761
+ ((HtmlDomParserContext) ctx).enableDocumentFragment();
762
+ ctx.setStringInputSource(context, str, context.nil);
842
763
  } else {
843
764
  klass = getNokogiriClass(runtime, "Nokogiri::XML::Document");
844
765
  ctx = new XmlDomParserContext(runtime, options);
845
- String input = rubyStringToString(str);
846
- istream = new ByteArrayInputStream(input.getBytes());
766
+ ctx.setStringInputSource(context, str, context.nil);
847
767
  }
848
768
 
849
- ctx.setInputSource(istream);
850
769
  // TODO: for some reason, document.getEncoding() can be null or nil (don't know why)
851
770
  // run `test_parse_with_unparented_html_text_context_node' few times to see this happen
852
771
  if (document instanceof HtmlDocument && !(document.getEncoding() == null || document.getEncoding().isNil())) {
@@ -854,17 +773,16 @@ public class XmlNode extends RubyObject {
854
773
  htmlCtx.setEncoding(document.getEncoding().asJavaString());
855
774
  }
856
775
 
857
- XmlDocument doc = ctx.parse(context, klass, runtime.getNil());
776
+ XmlDocument doc = ctx.parse(context, klass, context.nil);
858
777
 
859
- RubyArray documentErrors = getErrorArray(document);
860
- RubyArray docErrors = getErrorArray(doc);
861
- if (isErrorIncreased(documentErrors, docErrors)) {
778
+ RubyArray documentErrors = getErrors(document);
779
+ RubyArray docErrors = getErrors(doc);
780
+ if (checkNewErrors(documentErrors, docErrors)) {
862
781
  for (int i = 0; i < docErrors.getLength(); i++) {
863
- documentErrors.add(docErrors.entry(i));
782
+ documentErrors.append(docErrors.entry(i));
864
783
  }
865
784
  document.setInstanceVariable("@errors", documentErrors);
866
- XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, new IRubyObject[0]);
867
- return xmlNodeSet;
785
+ return XmlNodeSet.newNodeSet(context.runtime, IRubyObject.NULL_ARRAY, this);
868
786
  }
869
787
 
870
788
  // The first child might be document type node (dtd declaration).
@@ -876,27 +794,24 @@ public class XmlNode extends RubyObject {
876
794
  first = doc.node.getFirstChild();
877
795
  }
878
796
 
879
- IRubyObject[] nodes = new IRubyObject[]{NokogiriHelpers.getCachedNodeOrCreate(runtime, first)};
880
- XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, nodes);
881
- return xmlNodeSet;
797
+ IRubyObject[] nodes = new IRubyObject[] { NokogiriHelpers.getCachedNodeOrCreate(runtime, first) };
798
+ return XmlNodeSet.newNodeSet(context.runtime, nodes, this);
882
799
  }
883
800
 
884
- private RubyArray getErrorArray(XmlDocument document) {
801
+ private static RubyArray getErrors(XmlDocument document) {
885
802
  IRubyObject obj = document.getInstanceVariable("@errors");
886
- if (obj != null && obj instanceof RubyArray) {
887
- return (RubyArray)obj;
888
- }
889
- return RubyArray.newArray(document.getRuntime());
803
+ if (obj instanceof RubyArray) return (RubyArray) obj;
804
+ return RubyArray.newEmptyArray(document.getRuntime());
890
805
  }
891
806
 
892
- private boolean isErrorIncreased(RubyArray baseErrors, RubyArray createdErrors) {
893
- int length = ((RubyArray) createdErrors.op_diff(baseErrors)).size();
807
+ private static boolean checkNewErrors(RubyArray baseErrors, RubyArray newErrors) {
808
+ int length = ((RubyArray) newErrors.op_diff(baseErrors)).size();
894
809
  return length > 0;
895
810
  }
896
811
 
897
812
  @JRubyMethod(name = {"content", "text", "inner_text"})
898
813
  public IRubyObject content(ThreadContext context) {
899
- return stringOrNil(context.getRuntime(), getContentImpl());
814
+ return stringOrNil(context.runtime, getContentImpl());
900
815
  }
901
816
 
902
817
  public CharSequence getContentImpl() {
@@ -906,7 +821,7 @@ public class XmlNode extends RubyObject {
906
821
  }
907
822
  CharSequence textContent;
908
823
  if (this instanceof XmlDocument) {
909
- Node node = ((Document)this.node).getDocumentElement();
824
+ Node node = ((Document) this.node).getDocumentElement();
910
825
  if (node == null) {
911
826
  textContent = "";
912
827
  } else {
@@ -920,7 +835,7 @@ public class XmlNode extends RubyObject {
920
835
  return textContent;
921
836
  }
922
837
 
923
- private StringBuilder getTextContentRecursively(StringBuilder buffer, Node currentNode) {
838
+ private static StringBuilder getTextContentRecursively(StringBuilder buffer, Node currentNode) {
924
839
  CharSequence textContent = currentNode.getNodeValue();
925
840
  if (textContent != null && NokogiriHelpers.shouldDecode(currentNode)) {
926
841
  textContent = NokogiriHelpers.decodeJavaString(textContent);
@@ -934,7 +849,7 @@ public class XmlNode extends RubyObject {
934
849
  return buffer;
935
850
  }
936
851
 
937
- private boolean hasTextContent(Node child) {
852
+ private static boolean hasTextContent(Node child) {
938
853
  return child.getNodeType() != Node.COMMENT_NODE && child.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE;
939
854
  }
940
855
 
@@ -943,13 +858,17 @@ public class XmlNode extends RubyObject {
943
858
  return document(context.runtime);
944
859
  }
945
860
 
946
- IRubyObject document(final Ruby runtime) {
861
+ XmlDocument document(final Ruby runtime) {
862
+ return document(runtime, true);
863
+ }
864
+
865
+ XmlDocument document(final Ruby runtime, boolean create) {
947
866
  if (doc == null) {
948
867
  doc = (XmlDocument) node.getOwnerDocument().getUserData(NokogiriHelpers.CACHED_NODE);
949
- }
950
- if (doc == null) {
951
- doc = getCachedNodeOrCreate(runtime, node.getOwnerDocument());
952
- node.getOwnerDocument().setUserData(NokogiriHelpers.CACHED_NODE, doc, null);
868
+ if (doc == null && create) {
869
+ doc = (XmlDocument) getCachedNodeOrCreate(runtime, node.getOwnerDocument());
870
+ node.getOwnerDocument().setUserData(NokogiriHelpers.CACHED_NODE, doc, null);
871
+ }
953
872
  }
954
873
  return doc;
955
874
  }
@@ -970,7 +889,7 @@ public class XmlNode extends RubyObject {
970
889
  }
971
890
 
972
891
  protected final IRubyObject dup_implementation(ThreadContext context, boolean deep) {
973
- return dup_implementation(context.getRuntime(), deep);
892
+ return dup_implementation(context.runtime, deep);
974
893
  }
975
894
 
976
895
  protected IRubyObject dup_implementation(Ruby runtime, boolean deep) {
@@ -987,15 +906,14 @@ public class XmlNode extends RubyObject {
987
906
 
988
907
  public static RubyString encode_special_chars(ThreadContext context, IRubyObject string) {
989
908
  CharSequence str = NokogiriHelpers.encodeJavaString( rubyStringToString(string) );
990
- return RubyString.newString(context.getRuntime(), str);
909
+ return RubyString.newString(context.runtime, str);
991
910
  }
992
911
 
993
912
  /**
994
913
  * Instance method version of the above static method.
995
914
  */
996
915
  @JRubyMethod(name="encode_special_chars")
997
- public IRubyObject i_encode_special_chars(ThreadContext context,
998
- IRubyObject string) {
916
+ public IRubyObject i_encode_special_chars(ThreadContext context, IRubyObject string) {
999
917
  return encode_special_chars(context, string);
1000
918
  }
1001
919
 
@@ -1007,14 +925,14 @@ public class XmlNode extends RubyObject {
1007
925
  @JRubyMethod(visibility = Visibility.PRIVATE)
1008
926
  public IRubyObject get(ThreadContext context, IRubyObject rbkey) {
1009
927
  if (node instanceof Element) {
1010
- if (rbkey == null || rbkey.isNil()) context.getRuntime().getNil();
928
+ if (rbkey == null || rbkey.isNil()) return context.nil;
1011
929
  String key = rubyStringToString(rbkey);
1012
930
  Element element = (Element) node;
1013
- if (!element.hasAttribute(key)) return context.getRuntime().getNil();
931
+ if (!element.hasAttribute(key)) return context.nil;
1014
932
  String value = element.getAttribute(key);
1015
- return stringOrNil(context.getRuntime(), value);
933
+ return stringOrNil(context.runtime, value);
1016
934
  }
1017
- return context.getRuntime().getNil();
935
+ return context.nil;
1018
936
  }
1019
937
 
1020
938
  /**
@@ -1050,8 +968,7 @@ public class XmlNode extends RubyObject {
1050
968
  IRubyObject system_id) {
1051
969
  IRubyObject subset = internal_subset(context);
1052
970
  if (!subset.isNil()) {
1053
- throw context.getRuntime()
1054
- .newRuntimeError("Document already has internal subset");
971
+ throw context.runtime.newRuntimeError("Document already has internal subset");
1055
972
  }
1056
973
 
1057
974
  Document document = getOwnerDocument();
@@ -1087,8 +1004,7 @@ public class XmlNode extends RubyObject {
1087
1004
  IRubyObject system_id) {
1088
1005
  IRubyObject subset = external_subset(context);
1089
1006
  if (!subset.isNil()) {
1090
- throw context.getRuntime()
1091
- .newRuntimeError("Document already has external subset");
1007
+ throw context.runtime.newRuntimeError("Document already has external subset");
1092
1008
  }
1093
1009
 
1094
1010
  Document document = getOwnerDocument();
@@ -1110,42 +1026,40 @@ public class XmlNode extends RubyObject {
1110
1026
  String key = rubyStringToString(rbkey);
1111
1027
  Element element = (Element) node;
1112
1028
  if (element.hasAttribute(key)) {
1113
- return context.getRuntime().getTrue();
1029
+ return context.runtime.getTrue();
1114
1030
  } else {
1115
1031
  NamedNodeMap namedNodeMap = element.getAttributes();
1116
1032
  for (int i=0; i<namedNodeMap.getLength(); i++) {
1117
1033
  Node n = namedNodeMap.item(i);
1118
1034
  if (key.equals(n.getLocalName())) {
1119
- return context.getRuntime().getTrue();
1035
+ return context.runtime.getTrue();
1120
1036
  }
1121
1037
  }
1122
1038
  }
1123
- return context.getRuntime().getFalse();
1124
- } else {
1125
- return context.getRuntime().getNil();
1039
+ return context.runtime.getFalse();
1126
1040
  }
1041
+ return context.nil;
1127
1042
  }
1128
1043
 
1129
1044
  @JRubyMethod
1130
1045
  public IRubyObject namespace(ThreadContext context) {
1131
- Ruby runtime = context.getRuntime();
1132
- if (doc instanceof HtmlDocument) return runtime.getNil();
1133
- NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(node);
1046
+ final XmlDocument doc = document(context.runtime);
1047
+ if (doc instanceof HtmlDocument) return context.nil;
1048
+
1134
1049
  String namespaceURI = node.getNamespaceURI();
1135
- if (namespaceURI == null || namespaceURI == "") {
1136
- return runtime.getNil();
1050
+ if (namespaceURI == null || namespaceURI.isEmpty()) {
1051
+ return context.nil;
1137
1052
  }
1138
1053
 
1139
1054
  String prefix = node.getPrefix();
1140
- XmlNamespace namespace = nsCache.get(prefix == null ? "" : prefix, namespaceURI);
1055
+ NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCache(node);
1056
+ XmlNamespace namespace = nsCache.get(prefix, namespaceURI);
1057
+
1141
1058
  if (namespace == null || namespace.isEmpty()) {
1142
- // if it's not in the cache, create an unowned, uncached namespace and
1143
- // return that. XmlReader can't insert namespaces into the cache, so
1144
- // this is necessary for XmlReader to work correctly.
1145
- namespace = new XmlNamespace(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Namespace"));
1146
- IRubyObject rubyPrefix = NokogiriHelpers.stringOrNil(runtime, prefix);
1147
- IRubyObject rubyUri = NokogiriHelpers.stringOrNil(runtime, namespaceURI);
1148
- namespace.init(null, rubyPrefix, rubyUri, doc);
1059
+ // if it's not in the cache, create an unowned, uncached namespace and
1060
+ // return that. XmlReader can't insert namespaces into the cache, so
1061
+ // this is necessary for XmlReader to work correctly.
1062
+ namespace = new XmlNamespace(context.runtime, null, prefix, namespaceURI, doc);
1149
1063
  }
1150
1064
 
1151
1065
  return namespace;
@@ -1159,18 +1073,14 @@ public class XmlNode extends RubyObject {
1159
1073
  public IRubyObject namespace_definitions(ThreadContext context) {
1160
1074
  // don't use namespace_definitions cache anymore since
1161
1075
  // namespaces might be deleted. Reflecting the result of
1162
- // namesapce removals is complicated, so the cache might not be
1076
+ // namespace removals is complicated, so the cache might not be
1163
1077
  // updated.
1164
- Ruby ruby = context.getRuntime();
1165
- RubyArray namespace_definitions = ruby.newArray();
1166
- if (doc == null) return namespace_definitions;
1167
- if (doc instanceof HtmlDocument) return namespace_definitions;
1168
- List<XmlNamespace> namespaces = ((XmlDocument)doc).getNamespaceCache().get(node);
1169
- for (XmlNamespace namespace : namespaces) {
1170
- namespace_definitions.append(namespace);
1171
- }
1078
+ final XmlDocument doc = document(context.runtime);
1079
+ if (doc == null) return context.runtime.newEmptyArray();
1080
+ if (doc instanceof HtmlDocument) return context.runtime.newEmptyArray();
1172
1081
 
1173
- return namespace_definitions;
1082
+ List<XmlNamespace> namespaces = doc.getNamespaceCache().get(node);
1083
+ return context.runtime.newArray((List) namespaces);
1174
1084
  }
1175
1085
 
1176
1086
  /**
@@ -1178,10 +1088,10 @@ public class XmlNode extends RubyObject {
1178
1088
  * on any ancestor node.
1179
1089
  */
1180
1090
  @JRubyMethod
1181
- public IRubyObject namespace_scopes(ThreadContext context) {
1182
- RubyArray scoped_namespaces = context.getRuntime().newArray();
1183
- if (doc == null) return scoped_namespaces;
1184
- if (doc instanceof HtmlDocument) return scoped_namespaces;
1091
+ public RubyArray namespace_scopes(ThreadContext context) {
1092
+ final XmlDocument doc = document(context.runtime);
1093
+ if (doc == null) return context.runtime.newEmptyArray();
1094
+ if (doc instanceof HtmlDocument) return context.runtime.newEmptyArray();
1185
1095
 
1186
1096
  Node previousNode;
1187
1097
  if (node.getNodeType() == Node.ELEMENT_NODE) {
@@ -1191,11 +1101,12 @@ public class XmlNode extends RubyObject {
1191
1101
  } else {
1192
1102
  previousNode = findPreviousElement(node);
1193
1103
  }
1194
- if (previousNode == null) return scoped_namespaces;
1104
+ if (previousNode == null) return context.runtime.newEmptyArray();
1195
1105
 
1196
- List<String> prefixes_in_scope = new ArrayList<String>();
1197
- NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(previousNode);
1198
- for (Node previous=previousNode; previous != null; ) {
1106
+ final RubyArray scoped_namespaces = context.runtime.newArray();
1107
+ final HashSet<String> prefixes_in_scope = new HashSet<String>(8);
1108
+ NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCache(previousNode);
1109
+ for (Node previous = previousNode; previous != null; ) {
1199
1110
  List<XmlNamespace> namespaces = nsCache.get(previous);
1200
1111
  for (XmlNamespace namespace : namespaces) {
1201
1112
  if (prefixes_in_scope.contains(namespace.getPrefix())) continue;
@@ -1220,7 +1131,7 @@ public class XmlNode extends RubyObject {
1220
1131
  @JRubyMethod(name="namespaced_key?")
1221
1132
  public IRubyObject namespaced_key_p(ThreadContext context, IRubyObject elementLName, IRubyObject namespaceUri) {
1222
1133
  return this.attribute_with_ns(context, elementLName, namespaceUri).isNil() ?
1223
- context.getRuntime().getFalse() : context.getRuntime().getTrue();
1134
+ context.runtime.getFalse() : context.runtime.getTrue();
1224
1135
  }
1225
1136
 
1226
1137
  protected void setContent(IRubyObject content) {
@@ -1249,12 +1160,12 @@ public class XmlNode extends RubyObject {
1249
1160
  IRubyObject currentObj = this ;
1250
1161
  while (!currentObj.isNil()) {
1251
1162
  XmlNode currentNode = asXmlNode(context, currentObj);
1252
- IRubyObject lang = currentNode.getAttribute(context.getRuntime(), "xml:lang");
1163
+ IRubyObject lang = currentNode.getAttribute(context.runtime, "xml:lang");
1253
1164
  if (!lang.isNil()) { return lang ; }
1254
1165
 
1255
1166
  currentObj = currentNode.parent(context);
1256
1167
  }
1257
- return context.nil ;
1168
+ return context.nil;
1258
1169
  }
1259
1170
 
1260
1171
  @JRubyMethod(name = "lang=")
@@ -1277,7 +1188,7 @@ public class XmlNode extends RubyObject {
1277
1188
  IRubyObject indentString = args[2];
1278
1189
  IRubyObject options = args[3];
1279
1190
 
1280
- String encString = encoding.isNil() ? null : rubyStringToString(encoding);
1191
+ String encString = rubyStringToString(encoding);
1281
1192
 
1282
1193
  SaveContextVisitor visitor =
1283
1194
  new SaveContextVisitor(RubyFixnum.fix2int(options), rubyStringToString(indentString), encString, isHtmlDoc(context), isFragment(), 0);
@@ -1285,11 +1196,11 @@ public class XmlNode extends RubyObject {
1285
1196
 
1286
1197
  final IRubyObject rubyString;
1287
1198
  if (NokogiriHelpers.isUTF8(encString)) {
1288
- rubyString = convertString(context.getRuntime(), visitor.getInternalBuffer());
1199
+ rubyString = convertString(context.runtime, visitor.getInternalBuffer());
1289
1200
  } else {
1290
1201
  ByteBuffer bytes = convertEncoding(Charset.forName(encString), visitor.getInternalBuffer());
1291
1202
  ByteList str = new ByteList(bytes.array(), bytes.arrayOffset(), bytes.remaining());
1292
- rubyString = RubyString.newString(context.getRuntime(), str);
1203
+ rubyString = RubyString.newString(context.runtime, str);
1293
1204
  }
1294
1205
  Helpers.invoke(context, io, "write", rubyString);
1295
1206
 
@@ -1297,7 +1208,7 @@ public class XmlNode extends RubyObject {
1297
1208
  }
1298
1209
 
1299
1210
  private boolean isHtmlDoc(ThreadContext context) {
1300
- return document(context).getMetaClass().isKindOfModule(getNokogiriClass(context.getRuntime(), "Nokogiri::HTML::Document"));
1211
+ return document(context).getMetaClass().isKindOfModule(getNokogiriClass(context.runtime, "Nokogiri::HTML::Document"));
1301
1212
  }
1302
1213
 
1303
1214
  private boolean isFragment() {
@@ -1316,14 +1227,6 @@ public class XmlNode extends RubyObject {
1316
1227
  return getCachedNodeOrCreate(context.getRuntime(), node.getPreviousSibling());
1317
1228
  }
1318
1229
 
1319
- @JRubyMethod(meta = true, rest = true)
1320
- public static IRubyObject new_from_str(ThreadContext context,
1321
- IRubyObject cls,
1322
- IRubyObject[] args) {
1323
- XmlDocument doc = (XmlDocument) XmlDocument.read_memory(context, args);
1324
- return doc.root(context);
1325
- }
1326
-
1327
1230
  @JRubyMethod(name = {"node_name", "name"})
1328
1231
  public IRubyObject node_name(ThreadContext context) {
1329
1232
  return getNodeName(context);
@@ -1331,9 +1234,9 @@ public class XmlNode extends RubyObject {
1331
1234
 
1332
1235
  @JRubyMethod(name = {"node_name=", "name="})
1333
1236
  public IRubyObject node_name_set(ThreadContext context, IRubyObject nodeName) {
1334
- String newName = rubyStringToString(nodeName);
1237
+ nodeName = doSetName(nodeName);
1238
+ String newName = nodeName == null ? null : rubyStringToString((RubyString) nodeName);
1335
1239
  this.node = NokogiriHelpers.renameNode(node, null, newName);
1336
- setName(nodeName);
1337
1240
  return this;
1338
1241
  }
1339
1242
 
@@ -1372,23 +1275,19 @@ public class XmlNode extends RubyObject {
1372
1275
  }
1373
1276
 
1374
1277
  private String findNamespaceHref(ThreadContext context, String prefix) {
1375
- XmlNode currentNode = this;
1376
- while(currentNode != document(context)) {
1377
- RubyArray namespaces = (RubyArray) currentNode.namespace_scopes(context);
1378
- Iterator iterator = namespaces.iterator();
1379
- while(iterator.hasNext()) {
1380
- XmlNamespace namespace = (XmlNamespace) iterator.next();
1381
- if (namespace.getPrefix().equals(prefix)) {
1382
- return namespace.getHref();
1383
- }
1384
- }
1385
- if (currentNode.parent(context).isNil()) {
1386
- break;
1387
- } else {
1388
- currentNode = (XmlNode) currentNode.parent(context);
1278
+ XmlNode currentNode = this;
1279
+ final XmlDocument doc = document(context.runtime);
1280
+ while (currentNode != doc) {
1281
+ RubyArray namespaces = currentNode.namespace_scopes(context);
1282
+ for (int i = 0; i<namespaces.size(); i++) {
1283
+ XmlNamespace namespace = (XmlNamespace) namespaces.eltInternal(i);
1284
+ if (namespace.hasPrefix(prefix)) return namespace.getHref();
1285
+ }
1286
+ IRubyObject parent = currentNode.parent(context);
1287
+ if (parent == context.nil) break;
1288
+ currentNode = (XmlNode) parent;
1389
1289
  }
1390
- }
1391
- return null;
1290
+ return null;
1392
1291
  }
1393
1292
 
1394
1293
  @JRubyMethod
@@ -1400,35 +1299,31 @@ public class XmlNode extends RubyObject {
1400
1299
  if (node.getOwnerDocument() != null &&
1401
1300
  node.getOwnerDocument().getDocumentElement() == node) {
1402
1301
  return document(context);
1403
- } else {
1404
- return getCachedNodeOrCreate(context.getRuntime(), node.getParentNode());
1405
1302
  }
1303
+ return getCachedNodeOrCreate(context.runtime, node.getParentNode());
1406
1304
  }
1407
1305
 
1408
1306
  @JRubyMethod
1409
1307
  public IRubyObject path(ThreadContext context) {
1410
- return RubyString.newString(context.getRuntime(), NokogiriHelpers.getNodeCompletePath(this.node));
1308
+ return RubyString.newString(context.runtime, NokogiriHelpers.getNodeCompletePath(this.node));
1411
1309
  }
1412
1310
 
1413
1311
  @JRubyMethod
1414
1312
  public IRubyObject pointer_id(ThreadContext context) {
1415
- return RubyFixnum.newFixnum(context.getRuntime(), this.node.hashCode());
1313
+ return RubyFixnum.newFixnum(context.runtime, this.node.hashCode());
1416
1314
  }
1417
1315
 
1418
1316
  @JRubyMethod(visibility=Visibility.PRIVATE)
1419
1317
  public IRubyObject set_namespace(ThreadContext context, IRubyObject namespace) {
1420
1318
  if (namespace.isNil()) {
1319
+ XmlDocument doc = document(context.runtime);
1421
1320
  if (doc != null) {
1422
- Node n = node;
1423
- String prefix = n.getPrefix();
1424
- String href = n.getNamespaceURI();
1425
- ((XmlDocument)doc).getNamespaceCache().remove(prefix == null ? "" : prefix, href);
1426
- this.node = NokogiriHelpers.renameNode(n, null, NokogiriHelpers.getLocalPart(n.getNodeName()));
1321
+ Node node = this.node;
1322
+ doc.getNamespaceCache().remove(node);
1323
+ this.node = NokogiriHelpers.renameNode(node, null, NokogiriHelpers.getLocalPart(node.getNodeName()));
1427
1324
  }
1428
1325
  } else {
1429
1326
  XmlNamespace ns = (XmlNamespace) namespace;
1430
- String prefix = rubyStringToString(ns.prefix(context));
1431
- String href = rubyStringToString(ns.href(context));
1432
1327
 
1433
1328
  // Assigning node = ...renameNode() or not seems to make no
1434
1329
  // difference. Why not? -pmahoney
@@ -1438,8 +1333,8 @@ public class XmlNode extends RubyObject {
1438
1333
  // The node you passed in *might* come back as you expect, but
1439
1334
  // it might not. It's much safer to throw away the original
1440
1335
  // and keep the return value. -mbklein
1441
- String new_name = NokogiriHelpers.newQName(prefix, node);
1442
- this.node = NokogiriHelpers.renameNode(node, href, new_name);
1336
+ String new_name = NokogiriHelpers.newQName(ns.getPrefix(), node);
1337
+ this.node = NokogiriHelpers.renameNode(node, ns.getHref(), new_name);
1443
1338
  }
1444
1339
 
1445
1340
  clearXpathContext(getNode());
@@ -1493,10 +1388,10 @@ public class XmlNode extends RubyObject {
1493
1388
  case Node.DOCUMENT_FRAGMENT_NODE: type = "DOCUMENT_FRAG_NODE"; break;
1494
1389
  case Node.NOTATION_NODE: type = "NOTATION_NODE"; break;
1495
1390
  default:
1496
- return context.getRuntime().newFixnum(0);
1391
+ return context.runtime.newFixnum(0);
1497
1392
  }
1498
1393
 
1499
- return getNokogiriClass(context.getRuntime(), "Nokogiri::XML::Node").getConstant(type);
1394
+ return getNokogiriClass(context.runtime, "Nokogiri::XML::Node").getConstant(type);
1500
1395
  }
1501
1396
 
1502
1397
  @JRubyMethod
@@ -1504,7 +1399,7 @@ public class XmlNode extends RubyObject {
1504
1399
  Node root = getOwnerDocument();
1505
1400
  int[] counter = new int[1];
1506
1401
  count(root, counter);
1507
- return RubyFixnum.newFixnum(context.getRuntime(), counter[0]+1);
1402
+ return RubyFixnum.newFixnum(context.runtime, counter[0]+1);
1508
1403
  }
1509
1404
 
1510
1405
  private boolean count(Node node, int[] counter) {
@@ -1526,27 +1421,25 @@ public class XmlNode extends RubyObject {
1526
1421
  @JRubyMethod
1527
1422
  public IRubyObject next_element(ThreadContext context) {
1528
1423
  Node nextNode = node.getNextSibling();
1529
- Ruby ruby = context.getRuntime();
1530
- if (nextNode == null) return ruby.getNil();
1424
+ if (nextNode == null) return context.nil;
1531
1425
  if (nextNode instanceof Element) {
1532
- return getCachedNodeOrCreate(context.getRuntime(), nextNode);
1426
+ return getCachedNodeOrCreate(context.runtime, nextNode);
1533
1427
  }
1534
1428
  Node deeper = nextNode.getNextSibling();
1535
- if (deeper == null) return ruby.getNil();
1536
- return getCachedNodeOrCreate(context.getRuntime(), deeper);
1429
+ if (deeper == null) return context.nil;
1430
+ return getCachedNodeOrCreate(context.runtime, deeper);
1537
1431
  }
1538
1432
 
1539
1433
  @JRubyMethod
1540
1434
  public IRubyObject previous_element(ThreadContext context) {
1541
1435
  Node prevNode = node.getPreviousSibling();
1542
- Ruby ruby = context.getRuntime();
1543
- if (prevNode == null) return ruby.getNil();
1436
+ if (prevNode == null) return context.nil;
1544
1437
  if (prevNode instanceof Element) {
1545
- return getCachedNodeOrCreate(context.getRuntime(), prevNode);
1438
+ return getCachedNodeOrCreate(context.runtime, prevNode);
1546
1439
  }
1547
1440
  Node shallower = prevNode.getPreviousSibling();
1548
- if (shallower == null) return ruby.getNil();
1549
- return getCachedNodeOrCreate(context.getRuntime(), shallower);
1441
+ if (shallower == null) return context.nil;
1442
+ return getCachedNodeOrCreate(context.runtime, shallower);
1550
1443
  }
1551
1444
 
1552
1445
  protected enum AdoptScheme {
@@ -1557,13 +1450,11 @@ public class XmlNode extends RubyObject {
1557
1450
  * Adopt XmlNode <code>other</code> into the document of
1558
1451
  * <code>this</code> using the specified scheme.
1559
1452
  */
1560
- protected IRubyObject adoptAs(ThreadContext context, AdoptScheme scheme,
1561
- IRubyObject other_) {
1562
- XmlNode other = asXmlNode(context, other_);
1453
+ protected IRubyObject adoptAs(ThreadContext context, AdoptScheme scheme, IRubyObject other_) {
1454
+ final XmlNode other = asXmlNode(context, other_);
1563
1455
  // this.doc might be null since this node can be empty node.
1564
- if (this.doc != null) {
1565
- other.setDocument(context, this.doc);
1566
- }
1456
+ if (doc != null) other.setDocument(context, doc);
1457
+
1567
1458
  IRubyObject nodeOrTags = other;
1568
1459
  Node thisNode = node;
1569
1460
  Node otherNode = other.node;
@@ -1572,18 +1463,18 @@ public class XmlNode extends RubyObject {
1572
1463
  Document prev = otherNode.getOwnerDocument();
1573
1464
  Document doc = thisNode.getOwnerDocument();
1574
1465
  if (doc == null && thisNode instanceof Document) {
1575
- // we are adding the new node to a new empty document
1576
- doc = (Document) thisNode;
1466
+ // we are adding the new node to a new empty document
1467
+ doc = (Document) thisNode;
1577
1468
  }
1578
1469
  clearXpathContext(prev);
1579
1470
  clearXpathContext(doc);
1580
1471
  if (doc != null && doc != otherNode.getOwnerDocument()) {
1581
1472
  Node ret = doc.adoptNode(otherNode);
1582
- // FIXME: this is really a hack, see documentation of fixUserData() for more details.
1583
- fixUserData(prev, ret);
1584
1473
  if (ret == null) {
1585
- throw context.getRuntime().newRuntimeError("Failed to take ownership of node");
1474
+ throw context.runtime.newRuntimeError("Failed to take ownership of node");
1586
1475
  }
1476
+ // FIXME: this is really a hack, see documentation of fixUserData() for more details.
1477
+ fixUserData(prev, ret);
1587
1478
  otherNode = ret;
1588
1479
  }
1589
1480
 
@@ -1591,11 +1482,11 @@ public class XmlNode extends RubyObject {
1591
1482
 
1592
1483
  switch (scheme) {
1593
1484
  case CHILD:
1594
- Node[] children = adoptAsChild(context, thisNode, otherNode);
1485
+ Node[] children = adoptAsChild(thisNode, otherNode);
1595
1486
  if (children.length == 1 && otherNode == children[0]) {
1596
1487
  break;
1597
1488
  } else {
1598
- nodeOrTags = nodeArrayToRubyArray(context.getRuntime(), children);
1489
+ nodeOrTags = nodeArrayToRubyArray(context.runtime, children);
1599
1490
  }
1600
1491
  break;
1601
1492
  case PREV_SIBLING:
@@ -1609,7 +1500,7 @@ public class XmlNode extends RubyObject {
1609
1500
  break;
1610
1501
  }
1611
1502
  } catch (Exception e) {
1612
- throw context.getRuntime().newRuntimeError(e.toString());
1503
+ throw context.runtime.newRuntimeError(e.toString());
1613
1504
  }
1614
1505
 
1615
1506
  if (otherNode.getNodeType() == Node.TEXT_NODE) {
@@ -1630,42 +1521,38 @@ public class XmlNode extends RubyObject {
1630
1521
  * It looks like CoreDocumentImpl.adoptNode() doesn't copy
1631
1522
  * the user data associated with child nodes (recursively).
1632
1523
  */
1633
- private void fixUserData(Document previous, Node ret) {
1634
- String key = NokogiriHelpers.ENCODED_STRING;
1635
- for (Node child = ret.getFirstChild(); child != null; child = child.getNextSibling()) {
1636
- CoreDocumentImpl previousDocument = (CoreDocumentImpl) previous;
1637
- child.setUserData(key, previousDocument.getUserData(child, key), null);
1638
- fixUserData(previous, child);
1639
- }
1524
+ private static void fixUserData(Document previous, Node ret) {
1525
+ final String key = NokogiriHelpers.ENCODED_STRING;
1526
+ for (Node child = ret.getFirstChild(); child != null; child = child.getNextSibling()) {
1527
+ CoreDocumentImpl previousDocument = (CoreDocumentImpl) previous;
1528
+ child.setUserData(key, previousDocument.getUserData(child, key), null);
1529
+ fixUserData(previous, child);
1530
+ }
1640
1531
  }
1641
1532
 
1642
- protected Node[] adoptAsChild(ThreadContext context, Node parent,
1643
- Node otherNode) {
1533
+ private Node[] adoptAsChild(final Node parent, Node otherNode) {
1644
1534
  /*
1645
- * This is a bit of a hack. C-Nokogiri allows adding a bare
1646
- * text node as the root element. Java (and XML spec?) does
1647
- * not. So we wrap the text node in an element.
1535
+ * This is a bit of a hack. C-Nokogiri allows adding a bare text node as the root element.
1536
+ * Java (and XML spec?) does not. So we wrap the text node in an element.
1648
1537
  */
1649
1538
  if (parent.getNodeType() == Node.DOCUMENT_NODE && otherNode.getNodeType() == Node.TEXT_NODE) {
1650
- Element e = (Element) parent.getFirstChild();
1651
- if (e == null || !e.getNodeName().equals(TEXT_WRAPPER_NAME)) {
1652
- e = ((Document)parent).createElement(TEXT_WRAPPER_NAME);
1653
- adoptAsChild(context, parent, e);
1654
- }
1655
- e.appendChild(otherNode);
1656
- otherNode = e;
1539
+ Element e = (Element) parent.getFirstChild();
1540
+ if (e == null || !e.getNodeName().equals(TEXT_WRAPPER_NAME)) {
1541
+ e = ((Document) parent).createElement(TEXT_WRAPPER_NAME);
1542
+ adoptAsChild(parent, e);
1543
+ }
1544
+ e.appendChild(otherNode);
1545
+ otherNode = e;
1657
1546
  } else {
1658
- addNamespaceURIIfNeeded(otherNode);
1659
- parent.appendChild(otherNode);
1547
+ addNamespaceURIIfNeeded(otherNode);
1548
+ parent.appendChild(otherNode);
1660
1549
  }
1661
- Node[] nodes = new Node[1];
1662
- nodes[0] = otherNode;
1663
- return nodes;
1550
+ return new Node[] { otherNode };
1664
1551
  }
1665
1552
 
1666
1553
  private void addNamespaceURIIfNeeded(Node child) {
1667
- if (this instanceof XmlDocumentFragment && ((XmlDocumentFragment)this).getFragmentContext() != null) {
1668
- XmlElement fragmentContext = ((XmlDocumentFragment)this).getFragmentContext();
1554
+ if (this instanceof XmlDocumentFragment && ((XmlDocumentFragment) this).getFragmentContext() != null) {
1555
+ XmlElement fragmentContext = ((XmlDocumentFragment) this).getFragmentContext();
1669
1556
  String namespace_uri = fragmentContext.node.getNamespaceURI();
1670
1557
  if (namespace_uri != null && namespace_uri.length() > 0) {
1671
1558
  NokogiriHelpers.renameNode(child, namespace_uri, child.getNodeName());
@@ -1722,7 +1609,7 @@ public class XmlNode extends RubyObject {
1722
1609
  parentNode.replaceChild(otherNode, thisNode);
1723
1610
  } catch (Exception e) {
1724
1611
  String prefix = "could not replace child: ";
1725
- throw context.getRuntime().newRuntimeError(prefix + e.toString());
1612
+ throw context.runtime.newRuntimeError(prefix + e.toString());
1726
1613
  }
1727
1614
  }
1728
1615
 
@@ -1773,7 +1660,7 @@ public class XmlNode extends RubyObject {
1773
1660
  while(errors.getLength() > 0) {
1774
1661
  XmlSyntaxError error = (XmlSyntaxError)errors.shift(context);
1775
1662
  if (error.toString().contains("Include operation failed")) {
1776
- throw new RaiseException(error);
1663
+ throw error.toThrowable();
1777
1664
  }
1778
1665
  }
1779
1666
  return this;
@@ -1784,4 +1671,14 @@ public class XmlNode extends RubyObject {
1784
1671
  clearXpathContext(getNode());
1785
1672
  return context.nil ;
1786
1673
  }
1674
+
1675
+ @SuppressWarnings("unchecked")
1676
+ @Override
1677
+ public Object toJava(final Class target) {
1678
+ if (target == Object.class || Node.class.isAssignableFrom(target)) {
1679
+ return getNode();
1680
+ }
1681
+ return super.toJava(target);
1682
+ }
1683
+
1787
1684
  }