nokogiri 1.7.2-java → 1.8.0-java

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

Potentially problematic release.


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

Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.cross_rubies +4 -4
  3. data/.travis.yml +43 -24
  4. data/CHANGELOG.md +54 -6
  5. data/Gemfile +8 -7
  6. data/Gemfile-libxml-ruby +3 -0
  7. data/LICENSE-DEPENDENCIES.md +1612 -0
  8. data/{LICENSE.txt → LICENSE.md} +1 -1
  9. data/Manifest.txt +5 -8
  10. data/README.md +8 -5
  11. data/Rakefile +15 -31
  12. data/appveyor.yml +2 -0
  13. data/dependencies.yml +12 -7
  14. data/ext/java/nokogiri/HtmlDocument.java +2 -2
  15. data/ext/java/nokogiri/HtmlSaxParserContext.java +20 -21
  16. data/ext/java/nokogiri/HtmlSaxPushParser.java +6 -10
  17. data/ext/java/nokogiri/NokogiriService.java +10 -31
  18. data/ext/java/nokogiri/XmlAttr.java +1 -26
  19. data/ext/java/nokogiri/XmlCdata.java +0 -1
  20. data/ext/java/nokogiri/XmlComment.java +1 -1
  21. data/ext/java/nokogiri/XmlDocument.java +4 -5
  22. data/ext/java/nokogiri/XmlDocumentFragment.java +29 -21
  23. data/ext/java/nokogiri/XmlDtd.java +1 -1
  24. data/ext/java/nokogiri/XmlElement.java +9 -10
  25. data/ext/java/nokogiri/XmlEntityDecl.java +4 -5
  26. data/ext/java/nokogiri/XmlNode.java +105 -103
  27. data/ext/java/nokogiri/XmlNodeSet.java +64 -76
  28. data/ext/java/nokogiri/XmlReader.java +48 -48
  29. data/ext/java/nokogiri/XmlRelaxng.java +1 -1
  30. data/ext/java/nokogiri/XmlSaxPushParser.java +37 -17
  31. data/ext/java/nokogiri/XmlSchema.java +7 -5
  32. data/ext/java/nokogiri/XmlSyntaxError.java +47 -35
  33. data/ext/java/nokogiri/XmlXpathContext.java +160 -132
  34. data/ext/java/nokogiri/XsltStylesheet.java +15 -24
  35. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +19 -23
  36. data/ext/java/nokogiri/internals/NokogiriDomParser.java +1 -1
  37. data/ext/java/nokogiri/internals/NokogiriEncodingReaderWrapper.java +1 -1
  38. data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +11 -13
  39. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +5 -21
  40. data/ext/java/nokogiri/internals/NokogiriHandler.java +1 -1
  41. data/ext/java/nokogiri/internals/NokogiriHelpers.java +105 -142
  42. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +16 -26
  43. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +32 -50
  44. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +10 -13
  45. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +3 -10
  46. data/ext/java/nokogiri/internals/ParserContext.java +4 -8
  47. data/ext/java/nokogiri/internals/ReaderNode.java +53 -93
  48. data/ext/java/nokogiri/internals/SaveContextVisitor.java +77 -89
  49. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +6 -9
  50. data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +167 -0
  51. data/ext/java/nokogiri/internals/XmlDomParserContext.java +17 -6
  52. data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +1 -1
  53. data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +28 -28
  54. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +3 -4
  55. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +2 -2
  56. data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +10 -10
  57. data/ext/java/nokogiri/internals/c14n/ElementProxy.java +5 -5
  58. data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +2 -2
  59. data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +1 -1
  60. data/ext/java/nokogiri/internals/c14n/XMLUtils.java +2 -2
  61. data/ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java +1749 -0
  62. data/ext/nokogiri/extconf.rb +12 -17
  63. data/ext/nokogiri/nokogiri.h +0 -10
  64. data/ext/nokogiri/xml_attr.c +12 -8
  65. data/ext/nokogiri/xml_node.c +17 -14
  66. data/ext/nokogiri/xml_sax_push_parser.c +56 -12
  67. data/lib/nokogiri/html/sax/parser.rb +10 -0
  68. data/lib/nokogiri/nokogiri.jar +0 -0
  69. data/lib/nokogiri/version.rb +5 -4
  70. data/lib/nokogiri/xml/document.rb +9 -9
  71. data/lib/nokogiri/xml/node.rb +7 -7
  72. data/lib/nokogiri/xml/node_set.rb +12 -7
  73. data/lib/nokogiri/xml/sax/parser.rb +6 -7
  74. data/lib/nokogiri/xml/searchable.rb +34 -25
  75. data/lib/nokogiri/xml/syntax_error.rb +24 -1
  76. data/test/decorators/test_slop.rb +4 -1
  77. data/test/helper.rb +10 -0
  78. data/test/html/sax/test_parser.rb +27 -0
  79. data/test/html/test_document.rb +12 -1
  80. data/test/html/test_document_encoding.rb +1 -3
  81. data/test/html/test_document_fragment.rb +3 -0
  82. data/test/xml/sax/test_push_parser.rb +48 -0
  83. data/test/xml/test_attr.rb +7 -0
  84. data/test/xml/test_document.rb +1 -1
  85. data/test/xml/test_document_fragment.rb +27 -0
  86. data/test/xml/test_entity_reference.rb +2 -2
  87. data/test/xml/test_node.rb +12 -15
  88. data/test/xml/test_node_reparenting.rb +14 -0
  89. data/test/xml/test_node_set.rb +8 -6
  90. data/test/xml/test_reader.rb +19 -0
  91. data/test/xml/test_syntax_error.rb +21 -15
  92. data/test/xml/test_unparented_node.rb +54 -11
  93. data/test/xml/test_xpath.rb +23 -6
  94. metadata +32 -20
  95. data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +0 -73
  96. data/ext/java/nokogiri/internals/XsltExtensionFunction.java +0 -72
  97. data/suppressions/nokogiri_ree-1.8.7.358.supp +0 -61
  98. data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
  99. data/suppressions/nokogiri_ruby-1.9.2.320.supp +0 -28
  100. data/suppressions/nokogiri_ruby-1.9.3.327.supp +0 -28
  101. data/test_all +0 -105
@@ -33,11 +33,11 @@
33
33
  package nokogiri.internals;
34
34
 
35
35
  import java.util.ArrayList;
36
- import java.util.Hashtable;
36
+ import java.util.HashMap;
37
37
  import java.util.Iterator;
38
- import java.util.List;
39
- import java.util.Set;
38
+ import java.util.Map;
40
39
  import java.util.Map.Entry;
40
+ import java.util.Set;
41
41
 
42
42
  import javax.xml.XMLConstants;
43
43
  import javax.xml.namespace.NamespaceContext;
@@ -48,28 +48,20 @@ import javax.xml.namespace.NamespaceContext;
48
48
  * @author Yoko Harada <yokolet@gmail.com>
49
49
  *
50
50
  */
51
+ public final class NokogiriNamespaceContext implements NamespaceContext {
51
52
 
52
- public class NokogiriNamespaceContext implements NamespaceContext {
53
- private static NokogiriNamespaceContext namespaceContext;
54
53
  public static final String NOKOGIRI_PREFIX = "nokogiri";
55
54
  public static final String NOKOGIRI_URI = "http://www.nokogiri.org/default_ns/ruby/extensions_functions";
56
55
  public static final String NOKOGIRI_TEMPORARY_ROOT_TAG = "nokogiri-temporary-root-tag";
57
56
 
58
- private Hashtable<String,String> register;
57
+ private final Map<String,String> register;
59
58
 
60
59
  public static NokogiriNamespaceContext create() {
61
- if (namespaceContext == null) namespaceContext = new NokogiriNamespaceContext();
62
- try {
63
- NokogiriNamespaceContext clone = (NokogiriNamespaceContext) namespaceContext.clone();
64
- return clone;
65
- } catch (CloneNotSupportedException e) {
66
- NokogiriNamespaceContext freshContext = new NokogiriNamespaceContext();
67
- return freshContext;
68
- }
60
+ return new NokogiriNamespaceContext();
69
61
  }
70
62
 
71
63
  private NokogiriNamespaceContext() {
72
- this.register = new Hashtable<String,String>();
64
+ register = new HashMap<String, String>(6, 1);
73
65
  register.put(NOKOGIRI_PREFIX, NOKOGIRI_URI);
74
66
  register.put("xml", "http://www.w3.org/XML/1998/namespace");
75
67
  register.put("xhtml", "http://www.w3.org/1999/xhtml");
@@ -95,21 +87,19 @@ public class NokogiriNamespaceContext implements NamespaceContext {
95
87
  public String getPrefix(String uri) {
96
88
  if (uri == null) {
97
89
  throw new IllegalArgumentException("uri is null");
98
- } else {
99
- Set<Entry<String, String>> entries = register.entrySet();
100
- for (Entry<String, String> entry : entries) {
101
- if (uri.equals(entry.getValue())) {
102
- return entry.getKey();
103
- }
90
+ }
91
+ Set<Entry<String, String>> entries = register.entrySet();
92
+ for (Entry<String, String> entry : entries) {
93
+ if (uri.equals(entry.getValue())) {
94
+ return entry.getKey();
104
95
  }
105
96
  }
106
97
  return null;
107
98
  }
108
99
 
109
100
  public Iterator<String> getPrefixes(String uri) {
110
- if (register == null) return null;
111
101
  Set<Entry<String, String>> entries = register.entrySet();
112
- List<String> list = new ArrayList<String>();
102
+ ArrayList<String> list = new ArrayList<String>(entries.size());
113
103
  for (Entry<String, String> entry : entries) {
114
104
  if (uri.equals(entry.getValue())) {
115
105
  list.add(entry.getKey());
@@ -119,12 +109,12 @@ public class NokogiriNamespaceContext implements NamespaceContext {
119
109
  }
120
110
 
121
111
  public Set<String> getAllPrefixes() {
122
- if (register == null) return null;
123
112
  return register.keySet();
124
113
  }
125
114
 
126
115
  public void registerNamespace(String prefix, String uri) {
127
- if("xmlns".equals(prefix)) prefix = "";
128
- this.register.put(prefix, uri);
116
+ if ("xmlns".equals(prefix)) prefix = "";
117
+ register.put(prefix, uri);
129
118
  }
119
+
130
120
  }
@@ -32,21 +32,20 @@
32
32
 
33
33
  package nokogiri.internals;
34
34
 
35
- import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
36
-
37
35
  import java.util.List;
38
36
 
39
37
  import javax.xml.xpath.XPathFunction;
40
38
  import javax.xml.xpath.XPathFunctionException;
41
39
 
42
- import nokogiri.NokogiriService;
43
40
  import nokogiri.XmlNode;
44
41
  import nokogiri.XmlNodeSet;
45
42
 
46
43
  import org.jruby.Ruby;
47
44
  import org.jruby.RubyArray;
48
45
  import org.jruby.RubyBoolean;
46
+ import org.jruby.RubyFixnum;
49
47
  import org.jruby.RubyFloat;
48
+ import org.jruby.RubyInteger;
50
49
  import org.jruby.RubyString;
51
50
  import org.jruby.javasupport.JavaUtil;
52
51
  import org.jruby.javasupport.util.RuntimeHelpers;
@@ -61,81 +60,64 @@ import org.w3c.dom.NodeList;
61
60
  * @author Yoko Harada <yokolet@gmail.com>
62
61
  */
63
62
  public class NokogiriXPathFunction implements XPathFunction {
64
- private static NokogiriXPathFunction xpathFunction;
65
- private IRubyObject handler;
66
- private String name;
67
- private int arity;
63
+
64
+ private final IRubyObject handler;
65
+ private final String name;
66
+ private final int arity;
68
67
 
69
68
  public static NokogiriXPathFunction create(IRubyObject handler, String name, int arity) {
70
- if (xpathFunction == null) xpathFunction = new NokogiriXPathFunction();
71
- try {
72
- NokogiriXPathFunction clone = (NokogiriXPathFunction) xpathFunction.clone();
73
- clone.init(handler, name, arity);
74
- return clone;
75
- } catch (CloneNotSupportedException e) {
76
- NokogiriXPathFunction freshXpathFunction = new NokogiriXPathFunction();
77
- freshXpathFunction.init(handler, name, arity);
78
- return freshXpathFunction;
79
- }
69
+ return new NokogiriXPathFunction(handler, name, arity);
80
70
  }
81
71
 
82
- private void init(IRubyObject handler, String name, int arity) {
72
+ private NokogiriXPathFunction(IRubyObject handler, String name, int arity) {
83
73
  this.handler = handler;
84
74
  this.name = name;
85
75
  this.arity = arity;
86
76
  }
87
77
 
88
- private NokogiriXPathFunction() {}
89
-
90
78
  public Object evaluate(List args) throws XPathFunctionException {
91
- if(args.size() != this.arity) {
79
+ if (args.size() != this.arity) {
92
80
  throw new XPathFunctionException("arity does not match");
93
81
  }
94
82
 
95
- Ruby ruby = this.handler.getRuntime();
96
- ThreadContext context = ruby.getCurrentContext();
83
+ final Ruby runtime = this.handler.getRuntime();
84
+ ThreadContext context = runtime.getCurrentContext();
97
85
 
98
- IRubyObject result = RuntimeHelpers.invoke(context, this.handler,
99
- this.name, fromObjectToRubyArgs(args));
86
+ IRubyObject result = RuntimeHelpers.invoke(context, this.handler, this.name, fromObjectToRubyArgs(runtime, args));
100
87
 
101
- return fromRubyToObject(result);
88
+ return fromRubyToObject(runtime, result);
102
89
  }
103
90
 
104
- private IRubyObject[] fromObjectToRubyArgs(List args) {
91
+ private static IRubyObject[] fromObjectToRubyArgs(final Ruby runtime, List args) {
105
92
  IRubyObject[] newArgs = new IRubyObject[args.size()];
106
93
  for(int i = 0; i < args.size(); i++) {
107
- newArgs[i] = fromObjectToRuby(args.get(i));
94
+ newArgs[i] = fromObjectToRuby(runtime, args.get(i));
108
95
  }
109
96
  return newArgs;
110
97
  }
111
98
 
112
- private IRubyObject fromObjectToRuby(Object o) {
99
+ private static IRubyObject fromObjectToRuby(final Ruby runtime, Object obj) {
113
100
  // argument object type is one of NodeList, String, Boolean, or Double.
114
- Ruby runtime = this.handler.getRuntime();
115
- if (o instanceof NodeList) {
116
- XmlNodeSet xmlNodeSet = (XmlNodeSet)NokogiriService.XML_NODESET_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::NodeSet"));
117
- xmlNodeSet.setNodeList((NodeList) o);
101
+ if (obj instanceof NodeList) {
102
+ XmlNodeSet xmlNodeSet = XmlNodeSet.create(runtime);
103
+ xmlNodeSet.setNodeList((NodeList) obj);
118
104
  return xmlNodeSet;
119
- } else {
120
- return JavaUtil.convertJavaToUsableRubyObject(runtime, o);
121
105
  }
106
+ return JavaUtil.convertJavaToUsableRubyObject(runtime, obj);
122
107
  }
123
108
 
124
- private Object fromRubyToObject(IRubyObject o) {
125
- Ruby runtime = this.handler.getRuntime();
126
- if(o instanceof RubyString) {
127
- return o.toJava(String.class);
128
- } else if (o instanceof RubyFloat) {
129
- return o.toJava(Double.class);
130
- } else if (o instanceof RubyBoolean) {
131
- return o.toJava(Boolean.class);
132
- } else if (o instanceof XmlNodeSet) {
133
- return (NodeList)o;
134
- } else if (o instanceof RubyArray) {
135
- XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(runtime.getCurrentContext(), (RubyArray)o);
136
- return (NodeList)xmlNodeSet;
137
- } else /*if (o instanceof XmlNode)*/ {
138
- return ((XmlNode) o).getNode();
109
+ private static Object fromRubyToObject(final Ruby runtime, IRubyObject obj) {
110
+ if (obj instanceof RubyString) return obj.asJavaString();
111
+ if (obj instanceof RubyBoolean) return obj.toJava(Boolean.class);
112
+ if (obj instanceof RubyFloat) return obj.toJava(Double.class);
113
+ if (obj instanceof RubyInteger) {
114
+ if ( obj instanceof RubyFixnum ) return RubyFixnum.fix2long(obj);
115
+ return obj.toJava(java.math.BigInteger.class);
116
+ }
117
+ if (obj instanceof XmlNodeSet) return obj;
118
+ if (obj instanceof RubyArray) {
119
+ return XmlNodeSet.newXmlNodeSet(runtime, (RubyArray) obj);
139
120
  }
121
+ /*if (o instanceof XmlNode)*/ return ((XmlNode) obj).getNode();
140
122
  }
141
123
  }
@@ -44,25 +44,22 @@ import org.jruby.runtime.builtin.IRubyObject;
44
44
  * @author sergio
45
45
  * @author Yoko Harada <yokolet@gmail.com>
46
46
  */
47
- public class NokogiriXPathFunctionResolver implements XPathFunctionResolver {
48
- private static NokogiriXPathFunctionResolver resolver;
47
+ public final class NokogiriXPathFunctionResolver implements XPathFunctionResolver {
48
+
49
49
  private IRubyObject handler;
50
50
 
51
51
  public static NokogiriXPathFunctionResolver create(IRubyObject handler) {
52
- if (resolver == null) resolver = new NokogiriXPathFunctionResolver();
53
- try {
54
- NokogiriXPathFunctionResolver clone = (NokogiriXPathFunctionResolver) resolver.clone();
55
- clone.setHandler(handler);
56
- return clone;
57
- } catch (CloneNotSupportedException e) {
58
- NokogiriXPathFunctionResolver freshResolver = new NokogiriXPathFunctionResolver();
59
- freshResolver.setHandler(handler);
60
- return freshResolver;
61
- }
52
+ NokogiriXPathFunctionResolver freshResolver = new NokogiriXPathFunctionResolver();
53
+ freshResolver.setHandler(handler);
54
+ return freshResolver;
62
55
  }
63
56
 
64
57
  private NokogiriXPathFunctionResolver() {}
65
-
58
+
59
+ public final IRubyObject getHandler() {
60
+ return handler;
61
+ }
62
+
66
63
  public void setHandler(IRubyObject handler) {
67
64
  this.handler = handler;
68
65
  }
@@ -42,18 +42,11 @@ import javax.xml.xpath.XPathVariableResolver;
42
42
  * @author Yoko Harada <yokolet@gmail.com>
43
43
  */
44
44
  public class NokogiriXPathVariableResolver implements XPathVariableResolver {
45
- private static NokogiriXPathVariableResolver resolver;
46
- private HashMap<QName,String> variables = new HashMap<QName,String>();
45
+
46
+ private final HashMap<QName,String> variables = new HashMap<QName,String>();
47
47
 
48
48
  public static NokogiriXPathVariableResolver create() {
49
- if (resolver == null) resolver = new NokogiriXPathVariableResolver();
50
- try {
51
- NokogiriXPathVariableResolver clone = (NokogiriXPathVariableResolver) resolver.clone();
52
- return clone;
53
- } catch (CloneNotSupportedException e) {
54
- NokogiriXPathVariableResolver freshResolver = new NokogiriXPathVariableResolver();
55
- return freshResolver;
56
- }
49
+ return new NokogiriXPathVariableResolver();
57
50
  }
58
51
 
59
52
  private NokogiriXPathVariableResolver() {}
@@ -98,8 +98,7 @@ public class ParserContext extends RubyObject {
98
98
  return;
99
99
 
100
100
  RubyString stringData = null;
101
- if (invoke(context, data, "respond_to?",
102
- ruby.newSymbol("to_io").to_sym()).isTrue()) {
101
+ if (invoke(context, data, "respond_to?", ruby.newSymbol("to_io")).isTrue()) {
103
102
  RubyIO io =
104
103
  (RubyIO) TypeConverter.convertToType(data,
105
104
  ruby.getIO(),
@@ -107,20 +106,17 @@ public class ParserContext extends RubyObject {
107
106
  // use unclosedable input stream to fix #495
108
107
  source.setByteStream(new UncloseableInputStream(io.getInStream()));
109
108
 
110
- } else if (invoke(context, data, "respond_to?",
111
- ruby.newSymbol("read").to_sym()).isTrue()) {
109
+ } else if (invoke(context, data, "respond_to?", ruby.newSymbol("read")).isTrue()) {
112
110
  stringData = invoke(context, data, "read").convertToString();
113
111
 
114
- } else if (invoke(context, data, "respond_to?",
115
- ruby.newSymbol("string").to_sym()).isTrue()) {
112
+ } else if (invoke(context, data, "respond_to?", ruby.newSymbol("string")).isTrue()) {
116
113
  stringData = invoke(context, data, "string").convertToString();
117
114
 
118
115
  } else if (data instanceof RubyString) {
119
116
  stringData = (RubyString) data;
120
117
 
121
118
  } else {
122
- throw ruby.newArgumentError(
123
- "must be kind_of String or respond to :to_io, :read, or :string");
119
+ throw ruby.newArgumentError("must be kind_of String or respond to :to_io, :read, or :string");
124
120
  }
125
121
 
126
122
  if (stringData != null) {
@@ -69,19 +69,20 @@ import org.w3c.dom.Document;
69
69
  */
70
70
  public abstract class ReaderNode {
71
71
 
72
- Ruby ruby;
72
+ final Ruby ruby;
73
73
  public ReaderAttributeList attributeList;
74
74
  public Map<String, String> namespaces;
75
75
  public int depth, nodeType;
76
76
  public String lang, localName, xmlBase, prefix, name, uri, value, xmlVersion = "1.0";
77
77
  public int startOffset, endOffset;
78
78
  public boolean hasChildren = false;
79
- public abstract String getString();
80
79
  private Document document = null;
81
80
 
82
- private static ElementNode elementNode = null;
83
- private static ClosingNode closingNode = null;
84
- private static TextNode textNode = null;
81
+ protected ReaderNode(final Ruby runtime) {
82
+ this.ruby = runtime;
83
+ }
84
+
85
+ public abstract String getString();
85
86
 
86
87
  public IRubyObject getAttributeByIndex(IRubyObject index){
87
88
  if(index.isNil()) return index;
@@ -134,13 +135,13 @@ public abstract class ReaderNode {
134
135
  }
135
136
 
136
137
  public IRubyObject getAttributes(ThreadContext context) {
137
- if(attributeList == null) return context.getRuntime().getNil();
138
- RubyHash hash = RubyHash.newHash(context.getRuntime());
138
+ final Ruby runtime = context.runtime;
139
+ if (attributeList == null) return runtime.getNil();
140
+ RubyHash hash = RubyHash.newHash(runtime);
139
141
  for (int i=0; i<attributeList.length; i++) {
140
- IRubyObject k = stringOrBlank(context.getRuntime(), attributeList.names.get(i));
141
- IRubyObject v = stringOrBlank(context.getRuntime(), attributeList.values.get(i));
142
- if (context.getRuntime().is1_9()) hash.op_aset19(context, k, v);
143
- else hash.op_aset(context, k, v);
142
+ IRubyObject k = stringOrBlank(runtime, attributeList.names.get(i));
143
+ IRubyObject v = stringOrBlank(runtime, attributeList.values.get(i));
144
+ hash.fastASetCheckString(runtime, k, v); // hash.op_aset(context, k, v)
144
145
  }
145
146
  return hash;
146
147
  }
@@ -162,15 +163,13 @@ public abstract class ReaderNode {
162
163
  }
163
164
 
164
165
  public IRubyObject getNamespaces(ThreadContext context) {
165
- if(namespaces == null) return ruby.getNil();
166
- RubyHash hash = RubyHash.newHash(ruby);
167
- Set<String> keys = namespaces.keySet();
168
- for (String key : keys) {
169
- String stringValue = namespaces.get(key);
170
- IRubyObject k = stringOrBlank(context.getRuntime(), key);
171
- IRubyObject v = stringOrBlank(context.getRuntime(), stringValue);
172
- if (context.getRuntime().is1_9()) hash.op_aset19(context, k, v);
173
- else hash.op_aset(context, k, v);
166
+ final Ruby runtime = context.runtime;
167
+ if (namespaces == null) return runtime.getNil();
168
+ RubyHash hash = RubyHash.newHash(runtime);
169
+ for (Map.Entry<String, String> entry : namespaces.entrySet()) {
170
+ IRubyObject k = stringOrBlank(runtime, entry.getKey());
171
+ IRubyObject v = stringOrBlank(runtime, entry.getValue());
172
+ hash.fastASetCheckString(runtime, k, v); // hash.op_aset(context, k, v)
174
173
  }
175
174
  return hash;
176
175
  }
@@ -215,7 +214,7 @@ public abstract class ReaderNode {
215
214
  }
216
215
 
217
216
  public void setLang(String lang) {
218
- lang = (lang != null) ? lang : null;
217
+ this.lang = lang;
219
218
  }
220
219
 
221
220
  public IRubyObject toSyntaxError() { return ruby.getNil(); }
@@ -253,27 +252,15 @@ public abstract class ReaderNode {
253
252
  }
254
253
 
255
254
  public static ClosingNode createClosingNode(Ruby ruby, String uri, String localName, String qName, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
256
- if (closingNode == null) closingNode = new ClosingNode();
257
- ClosingNode clone;
258
- try {
259
- clone = (ClosingNode) closingNode.clone();
260
- } catch (CloneNotSupportedException e) {
261
- clone = new ClosingNode();
262
- }
263
- clone.init(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
264
- return clone;
255
+ return new ClosingNode(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
265
256
  }
266
257
 
267
258
  public static class ClosingNode extends ReaderNode {
268
259
 
269
- public ClosingNode() {}
270
-
271
- public ClosingNode(Ruby ruby, String uri, String localName, String qName, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
272
- init(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
273
- }
260
+ // public ClosingNode() {}
274
261
 
275
- public void init(Ruby ruby, String uri, String localName, String qName, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
276
- this.ruby = ruby;
262
+ ClosingNode(Ruby runtime, String uri, String localName, String qName, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
263
+ super(runtime);
277
264
  nodeType = ReaderNodeType.END_ELEMENT.getValue();
278
265
  this.uri = "".equals(uri) ? null : uri;
279
266
  this.localName = localName.trim().length() > 0 ? localName : qName;
@@ -296,35 +283,20 @@ public abstract class ReaderNode {
296
283
 
297
284
  @Override
298
285
  public String getString() {
299
- StringBuffer sb = new StringBuffer();
300
- sb.append("</").append(name).append(">");
301
- return new String(sb);
286
+ return "</" + name + '>';
302
287
  }
303
288
  }
304
289
 
305
290
  public static ElementNode createElementNode(Ruby ruby, String uri, String localName, String qName, XMLAttributes attrs, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
306
- if (elementNode == null) elementNode = new ElementNode();
307
- ElementNode clone;
308
- try {
309
- clone = (ElementNode) elementNode.clone();
310
- } catch (CloneNotSupportedException e) {
311
- clone = new ElementNode();
312
- }
313
- clone.init(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
314
- return clone;
291
+ return new ElementNode(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
315
292
  }
316
293
 
317
294
  public static class ElementNode extends ReaderNode {
318
- private final List<String> attributeStrings = new ArrayList<String>();
319
-
320
- public ElementNode() {}
321
295
 
322
- public ElementNode(Ruby ruby, String uri, String localName, String qName, XMLAttributes attrs, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
323
- init(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
324
- }
296
+ // public ElementNode() {}
325
297
 
326
- public void init(Ruby ruby, String uri, String localName, String qName, XMLAttributes attrs, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
327
- this.ruby = ruby;
298
+ ElementNode(Ruby runtime, String uri, String localName, String qName, XMLAttributes attrs, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
299
+ super(runtime);
328
300
  this.nodeType = ReaderNodeType.ELEMENT.getValue();
329
301
  this.uri = "".equals(uri) ? null : uri;
330
302
  this.localName = localName.trim().length() > 0 ? localName : qName;
@@ -354,7 +326,6 @@ public abstract class ReaderNode {
354
326
  if (xmlBase == null) xmlBase = resolveXmlBase(n, v, xmlBaseStack);
355
327
  }
356
328
  attributeList.add(u, n, v);
357
- attributeStrings.add(n + "=\"" + v + "\"");
358
329
  }
359
330
  }
360
331
 
@@ -408,32 +379,32 @@ public abstract class ReaderNode {
408
379
 
409
380
  @Override
410
381
  public String getString() {
411
- StringBuffer sb = new StringBuffer();
412
- sb.append("<").append(name);
382
+ StringBuffer sb = new StringBuffer(24);
383
+ sb.append('<').append(name);
413
384
  if (attributeList != null) {
414
385
  for (int i=0; i<attributeList.length; i++) {
415
- sb.append(" ").append(attributeStrings.get(i));
386
+ String n = attributeList.names.get(i);
387
+ String v = attributeList.values.get(i);
388
+ sb.append(' ').append(n).append('=')
389
+ .append('"').append(v).append('"');
416
390
  }
417
391
  }
418
- if (hasChildren) sb.append(">");
392
+ if (hasChildren) sb.append('>');
419
393
  else sb.append("/>");
420
- return new String(sb);
394
+ return sb.toString();
421
395
  }
422
396
  }
423
397
 
424
- public static class ReaderAttributeList {
425
- List<String> namespaces = new ArrayList<String>();
426
- List<String> names = new ArrayList<String>();
427
- List<String> values = new ArrayList<String>();
398
+ private static class ReaderAttributeList {
399
+ final List<String> namespaces = new ArrayList<String>();
400
+ final List<String> names = new ArrayList<String>();
401
+ final List<String> values = new ArrayList<String>();
428
402
  int length = 0;
429
403
 
430
404
  void add(String namespace, String name, String value) {
431
- namespace = namespace != null ? namespace : "";
432
- namespaces.add(namespace);
433
- name = name != null ? name : "";
434
- names.add(name);
435
- value = value != null ? value : "";
436
- values.add(value);
405
+ namespaces.add(namespace != null ? namespace : "");
406
+ names.add(name != null ? name : "");
407
+ values.add(value != null ? value : "");
437
408
  length++;
438
409
  }
439
410
 
@@ -449,8 +420,8 @@ public abstract class ReaderNode {
449
420
 
450
421
  public static class EmptyNode extends ReaderNode {
451
422
 
452
- public EmptyNode(Ruby ruby) {
453
- this.ruby = ruby;
423
+ public EmptyNode(Ruby runtime) {
424
+ super(runtime);
454
425
  this.nodeType = ReaderNodeType.NODE.getValue();
455
426
  }
456
427
 
@@ -473,10 +444,10 @@ public abstract class ReaderNode {
473
444
  public static class ExceptionNode extends EmptyNode {
474
445
  private final XmlSyntaxError exception;
475
446
 
476
- // Still don't know what to do with ex.
477
447
  public ExceptionNode(Ruby runtime, Exception ex) {
478
448
  super(runtime);
479
- exception = (XmlSyntaxError) NokogiriService.XML_SYNTAXERROR_ALLOCATOR.allocate(runtime, getNokogiriClass(ruby, "Nokogiri::XML::SyntaxError"));
449
+ exception = XmlSyntaxError.createXMLSyntaxError(runtime); // Nokogiri::XML::SyntaxError
450
+ exception.setException(ex);
480
451
  }
481
452
 
482
453
  @Override
@@ -491,26 +462,15 @@ public abstract class ReaderNode {
491
462
  }
492
463
 
493
464
  public static TextNode createTextNode(Ruby ruby, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
494
- if (textNode == null) textNode = new TextNode();
495
- TextNode clone;
496
- try {
497
- clone = (TextNode) textNode.clone();
498
- } catch (CloneNotSupportedException e) {
499
- clone = new TextNode();
500
- }
501
- clone.init(ruby, content, depth, langStack, xmlBaseStack);
502
- return clone;
465
+ return new TextNode(ruby, content, depth, langStack, xmlBaseStack);
503
466
  }
504
467
 
505
468
  public static class TextNode extends ReaderNode {
506
- public TextNode() {}
507
469
 
508
- public TextNode(Ruby ruby, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
509
- init(ruby, content, depth, langStack, xmlBaseStack);
510
- }
470
+ // public TextNode() {}
511
471
 
512
- public void init(Ruby ruby, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
513
- this.ruby = ruby;
472
+ TextNode(Ruby runtime, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
473
+ super(runtime);
514
474
  this.value = content;
515
475
  this.localName = "#text";
516
476
  this.name = "#text";
@@ -531,4 +491,4 @@ public abstract class ReaderNode {
531
491
  return value;
532
492
  }
533
493
  }
534
- }
494
+ }