nokogiri 1.10.8-java → 1.11.0.rc3-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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -22
  3. data/ext/java/nokogiri/HtmlDocument.java +34 -46
  4. data/ext/java/nokogiri/HtmlSaxParserContext.java +87 -57
  5. data/ext/java/nokogiri/NokogiriService.java +1 -1
  6. data/ext/java/nokogiri/XmlAttr.java +13 -20
  7. data/ext/java/nokogiri/XmlAttributeDecl.java +11 -12
  8. data/ext/java/nokogiri/XmlCdata.java +3 -4
  9. data/ext/java/nokogiri/XmlComment.java +1 -1
  10. data/ext/java/nokogiri/XmlDocument.java +148 -175
  11. data/ext/java/nokogiri/XmlDocumentFragment.java +13 -31
  12. data/ext/java/nokogiri/XmlDtd.java +5 -8
  13. data/ext/java/nokogiri/XmlElement.java +1 -20
  14. data/ext/java/nokogiri/XmlElementDecl.java +23 -28
  15. data/ext/java/nokogiri/XmlEntityDecl.java +23 -27
  16. data/ext/java/nokogiri/XmlEntityReference.java +2 -2
  17. data/ext/java/nokogiri/XmlNamespace.java +72 -89
  18. data/ext/java/nokogiri/XmlNode.java +300 -401
  19. data/ext/java/nokogiri/XmlNodeSet.java +72 -77
  20. data/ext/java/nokogiri/XmlReader.java +10 -11
  21. data/ext/java/nokogiri/XmlSaxParserContext.java +7 -7
  22. data/ext/java/nokogiri/XmlSchema.java +3 -3
  23. data/ext/java/nokogiri/XmlText.java +12 -9
  24. data/ext/java/nokogiri/XmlXpathContext.java +7 -7
  25. data/ext/java/nokogiri/XsltStylesheet.java +7 -15
  26. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +4 -10
  27. data/ext/java/nokogiri/internals/NokogiriHelpers.java +71 -135
  28. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +90 -58
  29. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +5 -4
  30. data/ext/java/nokogiri/internals/ParserContext.java +27 -73
  31. data/ext/java/nokogiri/internals/ReaderNode.java +2 -4
  32. data/ext/java/nokogiri/internals/XmlDomParserContext.java +17 -32
  33. data/ext/nokogiri/extconf.rb +50 -37
  34. data/ext/nokogiri/nokogiri.c +12 -6
  35. data/ext/nokogiri/nokogiri.h +13 -0
  36. data/ext/nokogiri/xml_document.c +16 -2
  37. data/ext/nokogiri/xml_io.c +8 -6
  38. data/ext/nokogiri/xml_node.c +20 -0
  39. data/ext/nokogiri/xml_reader.c +6 -17
  40. data/ext/nokogiri/xml_schema.c +29 -0
  41. data/ext/nokogiri/xslt_stylesheet.c +0 -4
  42. data/lib/nokogiri.rb +3 -20
  43. data/lib/nokogiri/css.rb +1 -0
  44. data/lib/nokogiri/css/node.rb +1 -0
  45. data/lib/nokogiri/css/parser.rb +61 -60
  46. data/lib/nokogiri/css/parser_extras.rb +39 -36
  47. data/lib/nokogiri/css/syntax_error.rb +1 -0
  48. data/lib/nokogiri/css/tokenizer.rb +1 -0
  49. data/lib/nokogiri/css/xpath_visitor.rb +3 -1
  50. data/lib/nokogiri/decorators/slop.rb +1 -0
  51. data/lib/nokogiri/html.rb +1 -0
  52. data/lib/nokogiri/html/builder.rb +1 -0
  53. data/lib/nokogiri/html/document.rb +1 -0
  54. data/lib/nokogiri/html/document_fragment.rb +1 -0
  55. data/lib/nokogiri/html/element_description.rb +1 -0
  56. data/lib/nokogiri/html/element_description_defaults.rb +1 -0
  57. data/lib/nokogiri/html/entity_lookup.rb +1 -0
  58. data/lib/nokogiri/html/sax/parser.rb +1 -0
  59. data/lib/nokogiri/html/sax/parser_context.rb +1 -0
  60. data/lib/nokogiri/html/sax/push_parser.rb +1 -0
  61. data/lib/nokogiri/jruby/dependencies.rb +20 -0
  62. data/lib/nokogiri/nokogiri.jar +0 -0
  63. data/lib/nokogiri/syntax_error.rb +1 -0
  64. data/lib/nokogiri/version.rb +86 -45
  65. data/lib/nokogiri/xml.rb +1 -0
  66. data/lib/nokogiri/xml/attr.rb +1 -0
  67. data/lib/nokogiri/xml/attribute_decl.rb +1 -0
  68. data/lib/nokogiri/xml/builder.rb +3 -2
  69. data/lib/nokogiri/xml/cdata.rb +1 -0
  70. data/lib/nokogiri/xml/character_data.rb +1 -0
  71. data/lib/nokogiri/xml/document.rb +3 -8
  72. data/lib/nokogiri/xml/document_fragment.rb +1 -0
  73. data/lib/nokogiri/xml/dtd.rb +1 -0
  74. data/lib/nokogiri/xml/element_content.rb +1 -0
  75. data/lib/nokogiri/xml/element_decl.rb +1 -0
  76. data/lib/nokogiri/xml/entity_decl.rb +1 -0
  77. data/lib/nokogiri/xml/entity_reference.rb +1 -0
  78. data/lib/nokogiri/xml/namespace.rb +1 -0
  79. data/lib/nokogiri/xml/node.rb +539 -224
  80. data/lib/nokogiri/xml/node/save_options.rb +1 -0
  81. data/lib/nokogiri/xml/node_set.rb +1 -0
  82. data/lib/nokogiri/xml/notation.rb +1 -0
  83. data/lib/nokogiri/xml/parse_options.rb +4 -3
  84. data/lib/nokogiri/xml/pp.rb +1 -0
  85. data/lib/nokogiri/xml/pp/character_data.rb +1 -0
  86. data/lib/nokogiri/xml/pp/node.rb +1 -0
  87. data/lib/nokogiri/xml/processing_instruction.rb +1 -0
  88. data/lib/nokogiri/xml/reader.rb +7 -3
  89. data/lib/nokogiri/xml/relax_ng.rb +1 -0
  90. data/lib/nokogiri/xml/sax.rb +1 -0
  91. data/lib/nokogiri/xml/sax/document.rb +1 -0
  92. data/lib/nokogiri/xml/sax/parser.rb +1 -0
  93. data/lib/nokogiri/xml/sax/parser_context.rb +1 -0
  94. data/lib/nokogiri/xml/sax/push_parser.rb +1 -0
  95. data/lib/nokogiri/xml/schema.rb +1 -0
  96. data/lib/nokogiri/xml/searchable.rb +22 -15
  97. data/lib/nokogiri/xml/syntax_error.rb +1 -0
  98. data/lib/nokogiri/xml/text.rb +1 -0
  99. data/lib/nokogiri/xml/xpath.rb +1 -0
  100. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -0
  101. data/lib/nokogiri/xml/xpath_context.rb +1 -0
  102. data/lib/nokogiri/xslt.rb +1 -0
  103. data/lib/nokogiri/xslt/stylesheet.rb +1 -0
  104. data/lib/xsd/xmlparser/nokogiri.rb +1 -0
  105. metadata +53 -34
  106. data/ext/java/nokogiri/internals/NokogiriEncodingReaderWrapper.java +0 -107
  107. data/ext/java/nokogiri/internals/UncloseableInputStream.java +0 -102
@@ -57,6 +57,8 @@ import nokogiri.internals.NokogiriNamespaceContext;
57
57
  import nokogiri.internals.NokogiriXPathFunctionResolver;
58
58
  import nokogiri.internals.NokogiriXPathVariableResolver;
59
59
 
60
+ import static nokogiri.internals.NokogiriHelpers.nodeListToRubyArray;
61
+
60
62
  /**
61
63
  * Class for Nokogiri::XML::XpathContext
62
64
  *
@@ -181,14 +183,12 @@ public class XmlXpathContext extends RubyObject {
181
183
  xobj = xpathInternal.execute(getXPathContext(fnResolver), contextNode, prefixResolver);
182
184
 
183
185
  switch (xobj.getType()) {
184
- case XObject.CLASS_BOOLEAN : return context.getRuntime().newBoolean(xobj.bool());
185
- case XObject.CLASS_NUMBER : return context.getRuntime().newFloat(xobj.num());
186
+ case XObject.CLASS_BOOLEAN : return context.runtime.newBoolean(xobj.bool());
187
+ case XObject.CLASS_NUMBER : return context.runtime.newFloat(xobj.num());
186
188
  case XObject.CLASS_NODESET :
187
- XmlNodeSet xmlNodeSet = XmlNodeSet.newEmptyNodeSet(context);
188
- xmlNodeSet.setNodeList(xobj.nodelist());
189
- xmlNodeSet.initialize(context.getRuntime(), this.context);
190
- return xmlNodeSet;
191
- default : return context.getRuntime().newString(xobj.str());
189
+ IRubyObject[] nodes = nodeListToRubyArray(context.runtime, xobj.nodelist());
190
+ return XmlNodeSet.newNodeSet(context.runtime, nodes, this.context);
191
+ default : return context.runtime.newString(xobj.str());
192
192
  }
193
193
  }
194
194
 
@@ -130,12 +130,11 @@ public class XsltStylesheet extends RubyObject {
130
130
  }
131
131
  }
132
132
 
133
- private Pattern p = Pattern.compile("'.{1,}'");
133
+ private static final Pattern QUOTED = Pattern.compile("'.{1,}'");
134
134
 
135
135
  private String unparseValue(String orig) {
136
- Matcher m = p.matcher(orig);
137
- if ((orig.startsWith("\"") && orig.endsWith("\"")) || m.matches()) {
138
- orig = orig.substring(1, orig.length()-1);
136
+ if ((orig.startsWith("\"") && orig.endsWith("\"")) || QUOTED.matcher(orig).matches()) {
137
+ orig = orig.substring(1, orig.length() - 1);
139
138
  }
140
139
 
141
140
  return orig;
@@ -174,11 +173,8 @@ public class XsltStylesheet extends RubyObject {
174
173
  }
175
174
 
176
175
  private static void ensureFirstArgIsDocument(Ruby runtime, IRubyObject arg) {
177
- if (arg instanceof XmlDocument) {
178
- return;
179
- } else {
180
- throw runtime.newArgumentError("doc must be a Nokogiri::XML::Document instance");
181
- }
176
+ if (arg instanceof XmlDocument) return;
177
+ throw runtime.newArgumentError("doc must be a Nokogiri::XML::Document instance");
182
178
  }
183
179
 
184
180
  private static void ensureDocumentHasNoError(ThreadContext context, XmlDocument xmlDoc) {
@@ -289,13 +285,9 @@ public class XsltStylesheet extends RubyObject {
289
285
 
290
286
  private IRubyObject createDocumentFromDomResult(ThreadContext context, Ruby runtime, DOMResult domResult) {
291
287
  if ("html".equals(domResult.getNode().getFirstChild().getNodeName())) {
292
- HtmlDocument htmlDocument = (HtmlDocument) getNokogiriClass(runtime, "Nokogiri::HTML::Document").allocate();
293
- htmlDocument.setDocumentNode(context, (Document) domResult.getNode());
294
- return htmlDocument;
288
+ return new HtmlDocument(context.runtime, (Document) domResult.getNode());
295
289
  } else {
296
- XmlDocument xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Document"));
297
- xmlDocument.setDocumentNode(context, (Document) domResult.getNode());
298
- return xmlDocument;
290
+ return new XmlDocument(context.runtime, (Document) domResult.getNode());
299
291
  }
300
292
  }
301
293
 
@@ -118,15 +118,9 @@ public class HtmlDomParserContext extends XmlDomParserContext {
118
118
  }
119
119
 
120
120
  @Override
121
- protected XmlDocument getNewEmptyDocument(ThreadContext context) {
122
- IRubyObject[] args = IRubyObject.NULL_ARRAY;
123
- return (XmlDocument) XmlDocument.rbNew(context, getNokogiriClass(context.getRuntime(), "Nokogiri::HTML::Document"), args);
124
- }
125
-
126
- @Override
127
- protected XmlDocument wrapDocument(ThreadContext context, RubyClass klazz, Document document) {
128
- HtmlDocument htmlDocument = (HtmlDocument) NokogiriService.HTML_DOCUMENT_ALLOCATOR.allocate(context.getRuntime(), klazz);
129
- htmlDocument.setDocumentNode(context, document);
121
+ protected XmlDocument wrapDocument(ThreadContext context, RubyClass klass, Document document) {
122
+ HtmlDocument htmlDocument = new HtmlDocument(context.runtime, klass, document);
123
+ htmlDocument.setDocumentNode(context.runtime, document);
130
124
  if (ruby_encoding.isNil()) {
131
125
  // ruby_encoding might have detected by HtmlDocument::EncodingReader
132
126
  if (detected_encoding != null && !detected_encoding.isNil()) {
@@ -134,7 +128,7 @@ public class HtmlDomParserContext extends XmlDomParserContext {
134
128
  } else {
135
129
  // no encoding given & no encoding detected, then try to get it
136
130
  String charset = tryGetCharsetFromHtml5MetaTag(document);
137
- ruby_encoding = stringOrNil(context.getRuntime(), charset);
131
+ ruby_encoding = stringOrNil(context.runtime, charset);
138
132
  }
139
133
  }
140
134
  htmlDocument.setEncoding(ruby_encoding);
@@ -39,6 +39,7 @@ import java.lang.reflect.Method;
39
39
  import java.nio.ByteBuffer;
40
40
  import java.nio.CharBuffer;
41
41
  import java.nio.charset.Charset;
42
+ import java.util.List;
42
43
  import java.util.Set;
43
44
  import java.util.regex.Matcher;
44
45
  import java.util.regex.Pattern;
@@ -53,7 +54,6 @@ import org.jruby.util.ByteList;
53
54
  import org.w3c.dom.Attr;
54
55
  import org.w3c.dom.DOMException;
55
56
  import org.w3c.dom.Document;
56
- import org.w3c.dom.NamedNodeMap;
57
57
  import org.w3c.dom.Node;
58
58
  import org.w3c.dom.NodeList;
59
59
 
@@ -81,7 +81,7 @@ import nokogiri.XmlXpathContext;
81
81
  */
82
82
  public class NokogiriHelpers {
83
83
  public static final String CACHED_NODE = "NOKOGIRI_CACHED_NODE";
84
- public static final String VALID_ROOT_NODE = "NOKOGIRI_VALIDE_ROOT_NODE";
84
+ public static final String ROOT_NODE_INVALID = "NOKOGIRI_ROOT_NODE_INVALID";
85
85
  public static final String ENCODED_STRING = "NOKOGIRI_ENCODED_STRING";
86
86
 
87
87
  public static XmlNode getCachedNode(Node node) {
@@ -108,22 +108,21 @@ public class NokogiriHelpers {
108
108
  * or XmlNamespace wrapping <code>node</code> if there is no cached
109
109
  * value.
110
110
  */
111
- public static IRubyObject getCachedNodeOrCreate(Ruby ruby, Node node) {
112
- if(node == null) return ruby.getNil();
111
+ public static IRubyObject getCachedNodeOrCreate(Ruby runtime, Node node) {
112
+ if (node == null) return runtime.getNil();
113
113
  if (node.getNodeType() == Node.ATTRIBUTE_NODE && isNamespace(node.getNodeName())) {
114
- XmlDocument xmlDocument = (XmlDocument)node.getOwnerDocument().getUserData(CACHED_NODE);
114
+ XmlDocument xmlDocument = (XmlDocument) node.getOwnerDocument().getUserData(CACHED_NODE);
115
115
  if (!(xmlDocument instanceof HtmlDocument)) {
116
- String prefix = getLocalNameForNamespace(((Attr)node).getName());
117
- prefix = prefix != null ? prefix : "";
118
- String href = ((Attr)node).getValue();
116
+ String prefix = getLocalNameForNamespace(((Attr) node).getName(), null);
117
+ String href = ((Attr) node).getValue();
119
118
  XmlNamespace xmlNamespace = xmlDocument.getNamespaceCache().get(prefix, href);
120
119
  if (xmlNamespace != null) return xmlNamespace;
121
- else return XmlNamespace.createFromAttr(ruby, (Attr)node);
120
+ return XmlNamespace.createFromAttr(runtime, (Attr) node);
122
121
  }
123
122
  }
124
123
  XmlNode xmlNode = getCachedNode(node);
125
- if(xmlNode == null) {
126
- xmlNode = (XmlNode)constructNode(ruby, node);
124
+ if (xmlNode == null) {
125
+ xmlNode = (XmlNode) constructNode(runtime, node);
127
126
  node.setUserData(CACHED_NODE, xmlNode, null);
128
127
  }
129
128
  return xmlNode;
@@ -140,37 +139,37 @@ public class NokogiriHelpers {
140
139
  switch (node.getNodeType()) {
141
140
  case Node.ELEMENT_NODE:
142
141
  XmlElement xmlElement = (XmlElement) NokogiriService.XML_ELEMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Element"));
143
- xmlElement.setNode(runtime.getCurrentContext(), node);
142
+ xmlElement.setNode(runtime, node);
144
143
  return xmlElement;
145
144
  case Node.ATTRIBUTE_NODE:
146
145
  XmlAttr xmlAttr = (XmlAttr) NokogiriService.XML_ATTR_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Attr"));
147
- xmlAttr.setNode(runtime.getCurrentContext(), node);
146
+ xmlAttr.setNode(runtime, node);
148
147
  return xmlAttr;
149
148
  case Node.TEXT_NODE:
150
149
  XmlText xmlText = (XmlText) NokogiriService.XML_TEXT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Text"));
151
- xmlText.setNode(runtime.getCurrentContext(), node);
150
+ xmlText.setNode(runtime, node);
152
151
  return xmlText;
153
152
  case Node.COMMENT_NODE:
154
153
  XmlComment xmlComment = (XmlComment) NokogiriService.XML_COMMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Comment"));
155
- xmlComment.setNode(runtime.getCurrentContext(), node);
154
+ xmlComment.setNode(runtime, node);
156
155
  return xmlComment;
157
156
  case Node.ENTITY_NODE:
158
157
  return new XmlNode(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityDecl"), node);
159
158
  case Node.ENTITY_REFERENCE_NODE:
160
159
  XmlEntityReference xmlEntityRef = (XmlEntityReference) NokogiriService.XML_ENTITY_REFERENCE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityReference"));
161
- xmlEntityRef.setNode(runtime.getCurrentContext(), node);
160
+ xmlEntityRef.setNode(runtime, node);
162
161
  return xmlEntityRef;
163
162
  case Node.PROCESSING_INSTRUCTION_NODE:
164
163
  XmlProcessingInstruction xmlProcessingInstruction = (XmlProcessingInstruction) NokogiriService.XML_PROCESSING_INSTRUCTION_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::ProcessingInstruction"));
165
- xmlProcessingInstruction.setNode(runtime.getCurrentContext(), node);
164
+ xmlProcessingInstruction.setNode(runtime, node);
166
165
  return xmlProcessingInstruction;
167
166
  case Node.CDATA_SECTION_NODE:
168
167
  XmlCdata xmlCdata = (XmlCdata) NokogiriService.XML_CDATA_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::CDATA"));
169
- xmlCdata.setNode(runtime.getCurrentContext(), node);
168
+ xmlCdata.setNode(runtime, node);
170
169
  return xmlCdata;
171
170
  case Node.DOCUMENT_NODE:
172
171
  XmlDocument xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Document"));
173
- xmlDocument.setDocumentNode(runtime.getCurrentContext(), node);
172
+ xmlDocument.setDocumentNode(runtime, (Document) node);
174
173
  return xmlDocument;
175
174
  case Node.DOCUMENT_TYPE_NODE:
176
175
  XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
@@ -178,7 +177,7 @@ public class NokogiriHelpers {
178
177
  return xmlDtd;
179
178
  default:
180
179
  XmlNode xmlNode = (XmlNode) NokogiriService.XML_NODE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Node"));
181
- xmlNode.setNode(runtime.getCurrentContext(), node);
180
+ xmlNode.setNode(runtime, node);
182
181
  return xmlNode;
183
182
  }
184
183
  }
@@ -242,47 +241,18 @@ public class NokogiriHelpers {
242
241
  return pos > 0 ? qName.substring(pos + 1) : qName;
243
242
  }
244
243
 
245
- public static String getLocalNameForNamespace(String name) {
244
+ public static String getLocalNameForNamespace(String name, String defValue) {
246
245
  String localName = getLocalPart(name);
247
- return ("xmlns".equals(localName)) ? null : localName;
246
+ return ("xmlns".equals(localName)) ? defValue : localName;
248
247
  }
249
248
 
250
- private static final Charset UTF8 = Charset.forName("UTF-8");
251
-
252
- /**
253
- * Converts a RubyString in to a Java String. Assumes the
254
- * RubyString is encoded as UTF-8. This is generally the case for
255
- * RubyStrings created with getRuntime().newString("java string").
256
- * It also seems to be the case for strings created within Ruby
257
- * where $KCODE has not been set.
258
- *
259
- * Note that RubyString#toString() decodes the string data as
260
- * ISO-8859-1 (See org.jruby.util.ByteList.java). This is not
261
- * what you want if you have any multibyte characters in your
262
- * UTF-8 string.
263
- *
264
- * FIXME: This really needs to be more robust in terms of
265
- * detecting the encoding and properly converting to a Java
266
- * String. It's unfortunate that RubyString#toString() doesn't do
267
- * this for us.
268
- */
269
249
  public static String rubyStringToString(IRubyObject str) {
270
250
  if (str.isNil()) return null;
271
- //return rubyStringToString(str.convertToString());
272
- return toJavaString(str.convertToString());
273
- }
274
-
275
- private static String toJavaString(RubyString str) {
276
- return str.decodeString(); // toString()
251
+ return str.convertToString().decodeString();
277
252
  }
278
253
 
279
254
  public static String rubyStringToString(RubyString str) {
280
- ByteList byteList = str.getByteList();
281
- byte[] data = byteList.unsafeBytes();
282
- int offset = byteList.begin();
283
- int len = byteList.length();
284
- ByteBuffer buf = ByteBuffer.wrap(data, offset, len);
285
- return UTF8.decode(buf).toString();
255
+ return str.decodeString(); // if encoding UTF-8 will decode UTF-8
286
256
  }
287
257
 
288
258
  public static ByteArrayInputStream stringBytesToStream(final IRubyObject str) {
@@ -297,7 +267,6 @@ public class NokogiriHelpers {
297
267
 
298
268
  Node cur, tmp, next;
299
269
 
300
- // TODO: Rename buffer to path.
301
270
  String buffer = "";
302
271
 
303
272
  cur = node;
@@ -494,33 +463,20 @@ public class NokogiriHelpers {
494
463
  return buffer;
495
464
  }
496
465
 
497
- protected static boolean compareTwoNodes(Node m, Node n) {
466
+ static boolean compareTwoNodes(Node m, Node n) {
498
467
  return nodesAreEqual(m.getLocalName(), n.getLocalName()) &&
499
468
  nodesAreEqual(m.getPrefix(), n.getPrefix());
500
469
  }
501
470
 
502
- protected static boolean fullNamesMatch(Node a, Node b) {
503
- return a.getNodeName().equals(b.getNodeName());
504
- }
505
-
506
- protected static String getFullName(Node n) {
507
- String lname = n.getLocalName();
508
- String prefix = n.getPrefix();
509
- if (lname != null) {
510
- if (prefix != null)
511
- return prefix + ":" + lname;
512
- else
513
- return lname;
514
- } else {
515
- return n.getNodeName();
516
- }
517
- }
518
-
519
471
  private static boolean nodesAreEqual(Object a, Object b) {
520
472
  return (((a == null) && (b == null)) ||
521
473
  ((a != null) && (b != null) && (b.equals(a))));
522
474
  }
523
475
 
476
+ private static boolean fullNamesMatch(Node a, Node b) {
477
+ return a.getNodeName().equals(b.getNodeName());
478
+ }
479
+
524
480
  private static final Pattern encoded_pattern = Pattern.compile("&amp;|&gt;|&lt;|&#13;");
525
481
  private static final String[] encoded = {"&amp;", "&gt;", "&lt;", "&#13;"};
526
482
  private static final Pattern decoded_pattern = Pattern.compile("&|>|<|\r");
@@ -554,20 +510,6 @@ public class NokogiriHelpers {
554
510
  return convert(encoded_pattern, str, encoded, decoded);
555
511
  }
556
512
 
557
- public static String getNodeName(Node node) {
558
- if(node == null) { System.out.println("node is null"); return ""; }
559
- String name = node.getNodeName();
560
- if(name == null) { System.out.println("name is null"); return ""; }
561
- if(name.equals("#document")) {
562
- return "document";
563
- } else if(name.equals("#text")) {
564
- return "text";
565
- } else {
566
- name = getLocalPart(name);
567
- return (name == null) ? "" : name;
568
- }
569
- }
570
-
571
513
  public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
572
514
  public static boolean isNamespace(Node node) {
573
515
  return (XMLNS_URI.equals(node.getNamespaceURI()) || isNamespace(node.getNodeName()));
@@ -602,6 +544,10 @@ public class NokogiriHelpers {
602
544
  return str.isEmpty() || isBlank((CharSequence) str);
603
545
  }
604
546
 
547
+ public static boolean isNullOrEmpty(String str) {
548
+ return str == null || str.isEmpty();
549
+ }
550
+
605
551
  public static CharSequence canonicalizeWhitespace(CharSequence str) {
606
552
  final int len = str.length();
607
553
  StringBuilder sb = new StringBuilder(len);
@@ -625,59 +571,44 @@ public class NokogiriHelpers {
625
571
  return newPrefix + ':' + tagName;
626
572
  }
627
573
 
628
- public static IRubyObject[] nodeListToRubyArray(Ruby ruby, NodeList nodes) {
574
+ public static IRubyObject[] nodeListToRubyArray(Ruby runtime, NodeList nodes) {
629
575
  IRubyObject[] array = new IRubyObject[nodes.getLength()];
630
576
  for (int i = 0; i < nodes.getLength(); i++) {
631
- array[i] = NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes.item(i));
577
+ array[i] = NokogiriHelpers.getCachedNodeOrCreate(runtime, nodes.item(i));
632
578
  }
633
579
  return array;
634
580
  }
635
581
 
636
- public static IRubyObject[] nodeArrayToArray(Ruby ruby, Node[] nodes) {
637
- IRubyObject[] result = new IRubyObject[nodes.length];
638
- for(int i = 0; i < nodes.length; i++) {
639
- result[i] = NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes[i]);
582
+ public static IRubyObject[] nodeListToArray(Ruby ruby, List<Node> nodes) {
583
+ IRubyObject[] result = new IRubyObject[nodes.size()];
584
+ for (int i = 0; i < result.length; i++) {
585
+ result[i] = NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes.get(i));
640
586
  }
641
587
  return result;
642
588
  }
643
589
 
644
590
  public static RubyArray nodeArrayToRubyArray(Ruby ruby, Node[] nodes) {
645
591
  RubyArray n = RubyArray.newArray(ruby, nodes.length);
646
- for(int i = 0; i < nodes.length; i++) {
592
+ for (int i = 0; i < nodes.length; i++) {
647
593
  n.append(NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes[i]));
648
594
  }
649
595
  return n;
650
596
  }
651
597
 
652
- public static RubyArray namedNodeMapToRubyArray(Ruby ruby, NamedNodeMap map) {
653
- RubyArray n = RubyArray.newArray(ruby, map.getLength());
654
- for(int i = 0; i < map.getLength(); i++) {
655
- n.append(NokogiriHelpers.getCachedNodeOrCreate(ruby, map.item(i)));
656
- }
657
- return n;
658
- }
659
-
660
- public static String getValidEncoding(Ruby runtime, IRubyObject encoding) {
661
- if (encoding.isNil()) {
662
- return guessEncoding();
663
- } else {
664
- return ignoreInvalidEncoding(runtime, encoding);
665
- }
598
+ public static String getValidEncodingOrNull(IRubyObject encoding) {
599
+ if (encoding.isNil()) return null; // charsetNames does not like contains(null)
600
+ String enc = rubyStringToString(encoding.convertToString());
601
+ if (CharsetNames.contains(enc)) return enc;
602
+ return null;
666
603
  }
667
604
 
668
- private static String guessEncoding() {
669
- String name = System.getProperty("file.encoding");
670
- if (name == null) name = "UTF-8";
671
- return name;
605
+ public static String getValidEncoding(IRubyObject encoding) {
606
+ String validEncoding = getValidEncodingOrNull(encoding);
607
+ if (validEncoding != null) return validEncoding;
608
+ return Charset.defaultCharset().name();
672
609
  }
673
610
 
674
- private static Set<String> charsetNames = Charset.availableCharsets().keySet();
675
-
676
- private static String ignoreInvalidEncoding(Ruby runtime, IRubyObject encoding) {
677
- String givenEncoding = rubyStringToString(encoding);
678
- if (charsetNames.contains(givenEncoding)) return givenEncoding;
679
- else return guessEncoding();
680
- }
611
+ private static final Set<String> CharsetNames = Charset.availableCharsets().keySet();
681
612
 
682
613
  public static String adjustSystemIdIfNecessary(String currentDir, String scriptFileName, String baseURI, String systemId) {
683
614
  if (systemId == null) return systemId;
@@ -704,9 +635,13 @@ public class NokogiriHelpers {
704
635
  return null;
705
636
  }
706
637
 
638
+ private static final Charset UTF8 = Charset.forName("UTF-8");
639
+
707
640
  public static boolean isUTF8(String encoding) {
708
641
  if (encoding == null) return true; // no need to convert encoding
709
- return Charset.forName(encoding).compareTo(UTF8) == 0;
642
+
643
+ if ("UTF-8".equals(encoding)) return true;
644
+ return UTF8.aliases().contains(encoding);
710
645
  }
711
646
 
712
647
  public static ByteBuffer convertEncoding(Charset output_charset, CharSequence input_string) {
@@ -738,15 +673,16 @@ public class NokogiriHelpers {
738
673
  private static CharSequence nkf(ThreadContext context, Charset encoding, CharSequence str) {
739
674
  final Ruby runtime = context.getRuntime();
740
675
  final ByteList opt;
741
- if (NokogiriHelpers.shift_jis.compareTo(encoding) == 0) opt = _Sw;
742
- else if (NokogiriHelpers.jis.compareTo(encoding) == 0) opt = _Jw;
743
- else if (NokogiriHelpers.euc_jp.compareTo(encoding) == 0) opt = _Ew;
676
+ if (NokogiriHelpers.Shift_JIS.compareTo(encoding) == 0) opt = _Sw;
677
+ else if (NokogiriHelpers.ISO_2022_JP.compareTo(encoding) == 0) opt = _Jw;
678
+ else if (NokogiriHelpers.EUC_JP.compareTo(encoding) == 0) opt = _Ew;
744
679
  else opt = _Ww; // should not come here. should be treated before this method.
745
680
 
746
681
  Class nkfClass;
747
682
  try {
748
- nkfClass = runtime.getClassLoader().loadClass("org.jruby.RubyNKF");
749
- } catch (ClassNotFoundException e2) {
683
+ // JRuby 1.7 and later
684
+ nkfClass = runtime.getClassLoader().loadClass("org.jruby.ext.nkf.RubyNKF");
685
+ } catch (ClassNotFoundException e1) {
750
686
  return str;
751
687
  }
752
688
  Method nkf_method;
@@ -768,9 +704,9 @@ public class NokogiriHelpers {
768
704
  }
769
705
  }
770
706
 
771
- private static final Charset shift_jis = Charset.forName("Shift_JIS");
772
- private static final Charset jis = Charset.forName("ISO-2022-JP");
773
- private static final Charset euc_jp = Charset.forName("EUC-JP");
707
+ private static final Charset Shift_JIS = Charset.forName("Shift_JIS");
708
+ private static final Charset ISO_2022_JP = Charset.forName("ISO-2022-JP"); // JIS
709
+ private static final Charset EUC_JP = Charset.forName("EUC-JP");
774
710
 
775
711
  public static boolean shouldEncode(Node text) {
776
712
  final Boolean encoded = (Boolean) text.getUserData(NokogiriHelpers.ENCODED_STRING);
@@ -781,17 +717,17 @@ public class NokogiriHelpers {
781
717
  return !shouldEncode(text);
782
718
  }
783
719
 
784
- public static NokogiriNamespaceCache getNamespaceCacheFormNode(Node n) {
785
- XmlDocument xmlDoc = (XmlDocument)getCachedNode(n.getOwnerDocument());
720
+ public static NokogiriNamespaceCache getNamespaceCache(Node node) {
721
+ XmlDocument xmlDoc = (XmlDocument) getCachedNode(node.getOwnerDocument());
786
722
  return xmlDoc.getNamespaceCache();
787
723
  }
788
724
 
789
- public static Node renameNode(Node n, String namespaceURI, String qualifiedName) throws DOMException {
790
- Document doc = n.getOwnerDocument();
791
- NokogiriNamespaceCache nsCache = getNamespaceCacheFormNode(n);
792
- Node result = doc.renameNode(n, namespaceURI, qualifiedName);
793
- if (result != n) {
794
- nsCache.replaceNode(n, result);
725
+ public static Node renameNode(Node node, String namespaceURI, String qualifiedName) throws DOMException {
726
+ Document doc = node.getOwnerDocument();
727
+ NokogiriNamespaceCache nsCache = getNamespaceCache(node);
728
+ Node result = doc.renameNode(node, namespaceURI, qualifiedName);
729
+ if (result != node) {
730
+ nsCache.replaceNode(node, result);
795
731
  }
796
732
  return result;
797
733
  }