nokogiri 1.11.1-java → 1.11.2-java

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

Potentially problematic release.


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

Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE-DEPENDENCIES.md +12 -12
  3. data/LICENSE.md +1 -1
  4. data/README.md +20 -15
  5. data/ext/java/nokogiri/EncodingHandler.java +78 -59
  6. data/ext/java/nokogiri/HtmlDocument.java +137 -114
  7. data/ext/java/nokogiri/HtmlElementDescription.java +104 -87
  8. data/ext/java/nokogiri/HtmlEntityLookup.java +31 -26
  9. data/ext/java/nokogiri/HtmlSaxParserContext.java +220 -192
  10. data/ext/java/nokogiri/HtmlSaxPushParser.java +164 -139
  11. data/ext/java/nokogiri/NokogiriService.java +597 -526
  12. data/ext/java/nokogiri/XmlAttr.java +120 -96
  13. data/ext/java/nokogiri/XmlAttributeDecl.java +97 -76
  14. data/ext/java/nokogiri/XmlCdata.java +35 -26
  15. data/ext/java/nokogiri/XmlComment.java +48 -37
  16. data/ext/java/nokogiri/XmlDocument.java +642 -540
  17. data/ext/java/nokogiri/XmlDocumentFragment.java +127 -107
  18. data/ext/java/nokogiri/XmlDtd.java +450 -384
  19. data/ext/java/nokogiri/XmlElement.java +25 -18
  20. data/ext/java/nokogiri/XmlElementContent.java +345 -286
  21. data/ext/java/nokogiri/XmlElementDecl.java +126 -95
  22. data/ext/java/nokogiri/XmlEntityDecl.java +121 -97
  23. data/ext/java/nokogiri/XmlEntityReference.java +51 -42
  24. data/ext/java/nokogiri/XmlNamespace.java +177 -145
  25. data/ext/java/nokogiri/XmlNode.java +1843 -1588
  26. data/ext/java/nokogiri/XmlNodeSet.java +361 -299
  27. data/ext/java/nokogiri/XmlProcessingInstruction.java +49 -39
  28. data/ext/java/nokogiri/XmlReader.java +513 -418
  29. data/ext/java/nokogiri/XmlRelaxng.java +91 -78
  30. data/ext/java/nokogiri/XmlSaxParserContext.java +330 -285
  31. data/ext/java/nokogiri/XmlSaxPushParser.java +229 -190
  32. data/ext/java/nokogiri/XmlSchema.java +328 -263
  33. data/ext/java/nokogiri/XmlSyntaxError.java +113 -83
  34. data/ext/java/nokogiri/XmlText.java +57 -46
  35. data/ext/java/nokogiri/XmlXpathContext.java +240 -206
  36. data/ext/java/nokogiri/XsltStylesheet.java +282 -239
  37. data/ext/java/nokogiri/internals/ClosedStreamException.java +5 -2
  38. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +199 -168
  39. data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +17 -10
  40. data/ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java +43 -16
  41. data/ext/java/nokogiri/internals/NokogiriDomParser.java +65 -50
  42. data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +107 -88
  43. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +25 -18
  44. data/ext/java/nokogiri/internals/NokogiriHandler.java +316 -254
  45. data/ext/java/nokogiri/internals/NokogiriHelpers.java +738 -622
  46. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +186 -143
  47. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +83 -68
  48. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +66 -49
  49. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +86 -69
  50. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +44 -29
  51. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +118 -101
  52. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +34 -24
  53. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +25 -17
  54. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +57 -42
  55. data/ext/java/nokogiri/internals/ParserContext.java +206 -179
  56. data/ext/java/nokogiri/internals/ReaderNode.java +478 -371
  57. data/ext/java/nokogiri/internals/SaveContextVisitor.java +822 -707
  58. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +28 -19
  59. data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +129 -123
  60. data/ext/java/nokogiri/internals/XmlDeclHandler.java +5 -4
  61. data/ext/java/nokogiri/internals/XmlDomParserContext.java +208 -177
  62. data/ext/java/nokogiri/internals/XmlSaxParser.java +24 -17
  63. data/ext/java/nokogiri/internals/c14n/AttrCompare.java +71 -68
  64. data/ext/java/nokogiri/internals/c14n/C14nHelper.java +137 -118
  65. data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +27 -21
  66. data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +74 -61
  67. data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +230 -205
  68. data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +572 -547
  69. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +17 -10
  70. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +17 -10
  71. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +323 -302
  72. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +232 -219
  73. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +22 -15
  74. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +23 -16
  75. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +23 -16
  76. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +22 -15
  77. data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +575 -545
  78. data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +141 -120
  79. data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +39 -38
  80. data/ext/java/nokogiri/internals/c14n/Constants.java +13 -10
  81. data/ext/java/nokogiri/internals/c14n/ElementProxy.java +279 -247
  82. data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +66 -53
  83. data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +44 -37
  84. data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +135 -120
  85. data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +59 -48
  86. data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +384 -334
  87. data/ext/java/nokogiri/internals/c14n/NodeFilter.java +25 -24
  88. data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +151 -140
  89. data/ext/java/nokogiri/internals/c14n/XMLUtils.java +456 -423
  90. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +1466 -1500
  91. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java +626 -570
  92. data/ext/nokogiri/depend +34 -474
  93. data/ext/nokogiri/extconf.rb +253 -183
  94. data/ext/nokogiri/html_document.c +10 -15
  95. data/ext/nokogiri/html_element_description.c +84 -71
  96. data/ext/nokogiri/html_entity_lookup.c +21 -16
  97. data/ext/nokogiri/html_sax_parser_context.c +66 -65
  98. data/ext/nokogiri/html_sax_push_parser.c +29 -27
  99. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  100. data/ext/nokogiri/nokogiri.c +171 -63
  101. data/ext/nokogiri/test_global_handlers.c +3 -4
  102. data/ext/nokogiri/xml_attr.c +15 -15
  103. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  104. data/ext/nokogiri/xml_cdata.c +13 -18
  105. data/ext/nokogiri/xml_comment.c +19 -26
  106. data/ext/nokogiri/xml_document.c +221 -164
  107. data/ext/nokogiri/xml_document_fragment.c +13 -15
  108. data/ext/nokogiri/xml_dtd.c +54 -48
  109. data/ext/nokogiri/xml_element_content.c +30 -27
  110. data/ext/nokogiri/xml_element_decl.c +22 -22
  111. data/ext/nokogiri/xml_encoding_handler.c +17 -11
  112. data/ext/nokogiri/xml_entity_decl.c +32 -30
  113. data/ext/nokogiri/xml_entity_reference.c +16 -18
  114. data/ext/nokogiri/xml_namespace.c +56 -49
  115. data/ext/nokogiri/xml_node.c +338 -286
  116. data/ext/nokogiri/xml_node_set.c +168 -156
  117. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  118. data/ext/nokogiri/xml_reader.c +191 -157
  119. data/ext/nokogiri/xml_relax_ng.c +29 -23
  120. data/ext/nokogiri/xml_sax_parser.c +117 -112
  121. data/ext/nokogiri/xml_sax_parser_context.c +100 -85
  122. data/ext/nokogiri/xml_sax_push_parser.c +34 -27
  123. data/ext/nokogiri/xml_schema.c +48 -42
  124. data/ext/nokogiri/xml_syntax_error.c +21 -23
  125. data/ext/nokogiri/xml_text.c +13 -17
  126. data/ext/nokogiri/xml_xpath_context.c +134 -127
  127. data/ext/nokogiri/xslt_stylesheet.c +157 -157
  128. data/lib/nokogiri.rb +1 -22
  129. data/lib/nokogiri/css/parser.rb +1 -1
  130. data/lib/nokogiri/extension.rb +26 -0
  131. data/lib/nokogiri/html/document_fragment.rb +15 -15
  132. data/lib/nokogiri/nokogiri.jar +0 -0
  133. data/lib/nokogiri/version/constant.rb +1 -1
  134. data/lib/nokogiri/version/info.rb +31 -8
  135. data/lib/nokogiri/xml/document.rb +31 -11
  136. data/lib/nokogiri/xml/node.rb +38 -42
  137. data/lib/nokogiri/xml/reader.rb +2 -9
  138. data/lib/nokogiri/xml/xpath.rb +1 -3
  139. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
  140. metadata +7 -8
  141. data/ext/nokogiri/xml_io.c +0 -63
  142. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
@@ -50,89 +50,119 @@ import org.xml.sax.SAXParseException;
50
50
  * @author sergio
51
51
  * @author Yoko Harada <yokolet@gmail.com>
52
52
  */
53
- @JRubyClass(name="Nokogiri::XML::SyntaxError", parent="Nokogiri::SyntaxError")
54
- public class XmlSyntaxError extends RubyException {
55
-
56
- private Exception exception;
57
- private boolean messageSet; // whether a custom error message was set
58
-
59
- public XmlSyntaxError(Ruby runtime, RubyClass klazz) {
60
- super(runtime, klazz);
61
- }
62
-
63
- public XmlSyntaxError(Ruby runtime, RubyClass rubyClass, Exception ex) {
64
- super(runtime, rubyClass, ex.getMessage());
65
- this.exception = ex;
66
- }
67
-
68
- public XmlSyntaxError(Ruby runtime, RubyClass rubyClass, String message, Exception ex) {
69
- super(runtime, rubyClass, message);
70
- this.exception = ex; this.messageSet = true;
71
- }
72
-
73
- public static XmlSyntaxError createXMLSyntaxError(final Ruby runtime) {
74
- RubyClass klazz = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::SyntaxError");
75
- return new XmlSyntaxError(runtime, klazz);
76
- }
77
-
78
- public static XmlSyntaxError createXMLSyntaxError(final Ruby runtime, final Exception ex) {
79
- RubyClass klazz = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::SyntaxError");
80
- return new XmlSyntaxError(runtime, klazz, ex);
81
- }
82
-
83
- public static XmlSyntaxError createHTMLSyntaxError(final Ruby runtime) {
84
- RubyClass klazz = (RubyClass) runtime.getClassFromPath("Nokogiri::HTML::SyntaxError");
85
- return new XmlSyntaxError(runtime, klazz);
86
- }
87
-
88
- public static RubyException createXMLXPathSyntaxError(final Ruby runtime, final String msg, final Exception ex) {
89
- RubyClass klazz = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::XPath::SyntaxError");
90
- return new XmlSyntaxError(runtime, klazz, msg, ex);
91
- }
92
-
93
- public static XmlSyntaxError createWarning(Ruby runtime, SAXParseException e) {
94
- XmlSyntaxError xmlSyntaxError = createXMLSyntaxError(runtime);
95
- xmlSyntaxError.setException(runtime, e, 1);
96
- return xmlSyntaxError;
97
- }
98
-
99
- public static XmlSyntaxError createError(Ruby runtime, SAXParseException e) {
100
- XmlSyntaxError xmlSyntaxError = createXMLSyntaxError(runtime);
101
- xmlSyntaxError.setException(runtime, e, 2);
102
- return xmlSyntaxError;
103
- }
104
-
105
- public static XmlSyntaxError createFatalError(Ruby runtime, SAXParseException e) {
106
- XmlSyntaxError xmlSyntaxError = createXMLSyntaxError(runtime);
107
- xmlSyntaxError.setException(runtime, e, 3);
108
- return xmlSyntaxError;
109
- }
110
-
111
- public void setException(Exception exception) {
112
- this.exception = exception;
113
- }
114
-
115
- public void setException(Ruby runtime, SAXParseException exception, int level) {
116
- this.exception = exception;
117
- setInstanceVariable("@level", runtime.newFixnum(level));
118
- setInstanceVariable("@line", runtime.newFixnum(exception.getLineNumber()));
119
- setInstanceVariable("@column", runtime.newFixnum(exception.getColumnNumber()));
120
- setInstanceVariable("@file", stringOrNil(runtime, exception.getSystemId()));
121
- }
122
-
123
- @JRubyMethod(name = "to_s")
124
- @Override
125
- public IRubyObject to_s(ThreadContext context) {
126
- RubyString msg = msg(context.runtime);
127
- return msg != null ? msg : super.to_s(context).asString();
128
- }
129
-
130
- private RubyString msg(final Ruby runtime) {
131
- if (exception != null && exception.getMessage() != null) {
132
- if (messageSet) return null;
133
- return runtime.newString( exception.getMessage() );
134
- }
135
- return null;
53
+ @JRubyClass(name = "Nokogiri::XML::SyntaxError", parent = "Nokogiri::SyntaxError")
54
+ public class XmlSyntaxError extends RubyException
55
+ {
56
+
57
+ private Exception exception;
58
+ private boolean messageSet; // whether a custom error message was set
59
+
60
+ public
61
+ XmlSyntaxError(Ruby runtime, RubyClass klazz)
62
+ {
63
+ super(runtime, klazz);
64
+ }
65
+
66
+ public
67
+ XmlSyntaxError(Ruby runtime, RubyClass rubyClass, Exception ex)
68
+ {
69
+ super(runtime, rubyClass, ex.getMessage());
70
+ this.exception = ex;
71
+ }
72
+
73
+ public
74
+ XmlSyntaxError(Ruby runtime, RubyClass rubyClass, String message, Exception ex)
75
+ {
76
+ super(runtime, rubyClass, message);
77
+ this.exception = ex;
78
+ this.messageSet = true;
79
+ }
80
+
81
+ public static XmlSyntaxError
82
+ createXMLSyntaxError(final Ruby runtime)
83
+ {
84
+ RubyClass klazz = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::SyntaxError");
85
+ return new XmlSyntaxError(runtime, klazz);
86
+ }
87
+
88
+ public static XmlSyntaxError
89
+ createXMLSyntaxError(final Ruby runtime, final Exception ex)
90
+ {
91
+ RubyClass klazz = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::SyntaxError");
92
+ return new XmlSyntaxError(runtime, klazz, ex);
93
+ }
94
+
95
+ public static XmlSyntaxError
96
+ createHTMLSyntaxError(final Ruby runtime)
97
+ {
98
+ RubyClass klazz = (RubyClass) runtime.getClassFromPath("Nokogiri::HTML::SyntaxError");
99
+ return new XmlSyntaxError(runtime, klazz);
100
+ }
101
+
102
+ public static RubyException
103
+ createXMLXPathSyntaxError(final Ruby runtime, final String msg, final Exception ex)
104
+ {
105
+ RubyClass klazz = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::XPath::SyntaxError");
106
+ return new XmlSyntaxError(runtime, klazz, msg, ex);
107
+ }
108
+
109
+ public static XmlSyntaxError
110
+ createWarning(Ruby runtime, SAXParseException e)
111
+ {
112
+ XmlSyntaxError xmlSyntaxError = createXMLSyntaxError(runtime);
113
+ xmlSyntaxError.setException(runtime, e, 1);
114
+ return xmlSyntaxError;
115
+ }
116
+
117
+ public static XmlSyntaxError
118
+ createError(Ruby runtime, SAXParseException e)
119
+ {
120
+ XmlSyntaxError xmlSyntaxError = createXMLSyntaxError(runtime);
121
+ xmlSyntaxError.setException(runtime, e, 2);
122
+ return xmlSyntaxError;
123
+ }
124
+
125
+ public static XmlSyntaxError
126
+ createFatalError(Ruby runtime, SAXParseException e)
127
+ {
128
+ XmlSyntaxError xmlSyntaxError = createXMLSyntaxError(runtime);
129
+ xmlSyntaxError.setException(runtime, e, 3);
130
+ return xmlSyntaxError;
131
+ }
132
+
133
+ public void
134
+ setException(Exception exception)
135
+ {
136
+ this.exception = exception;
137
+ }
138
+
139
+ public void
140
+ setException(Ruby runtime, SAXParseException exception, int level)
141
+ {
142
+ this.exception = exception;
143
+ setInstanceVariable("@level", runtime.newFixnum(level));
144
+ setInstanceVariable("@line", runtime.newFixnum(exception.getLineNumber()));
145
+ setInstanceVariable("@column", runtime.newFixnum(exception.getColumnNumber()));
146
+ setInstanceVariable("@file", stringOrNil(runtime, exception.getSystemId()));
147
+ }
148
+
149
+ @JRubyMethod(name = "to_s")
150
+ @Override
151
+ public IRubyObject
152
+ to_s(ThreadContext context)
153
+ {
154
+ RubyString msg = msg(context.runtime);
155
+ return msg != null ? msg : super.to_s(context).asString();
156
+ }
157
+
158
+ private RubyString
159
+ msg(final Ruby runtime)
160
+ {
161
+ if (exception != null && exception.getMessage() != null) {
162
+ if (messageSet) { return null; }
163
+ return runtime.newString(exception.getMessage());
136
164
  }
165
+ return null;
166
+ }
137
167
 
138
168
  }
@@ -17,10 +17,10 @@
17
17
  * distribute, sublicense, and/or sell copies of the Software, and to
18
18
  * permit persons to whom the Software is furnished to do so, subject to
19
19
  * the following conditions:
20
- *
20
+ *
21
21
  * The above copyright notice and this permission notice shall be
22
22
  * included in all copies or substantial portions of the Software.
23
- *
23
+ *
24
24
  * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
25
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
26
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -54,57 +54,68 @@ import org.w3c.dom.Text;
54
54
  * @author sergio
55
55
  * @author Yoko Harada <yokolet@gmail.com>
56
56
  */
57
- @JRubyClass(name="Nokogiri::XML::Text", parent="Nokogiri::XML::CharacterData")
58
- public class XmlText extends XmlNode {
57
+ @JRubyClass(name = "Nokogiri::XML::Text", parent = "Nokogiri::XML::CharacterData")
58
+ public class XmlText extends XmlNode
59
+ {
59
60
 
60
- private static final ByteList TEXT = ByteList.create("text");
61
- static { TEXT.setEncoding(USASCIIEncoding.INSTANCE); }
61
+ private static final ByteList TEXT = ByteList.create("text");
62
+ static { TEXT.setEncoding(USASCIIEncoding.INSTANCE); }
62
63
 
63
- public XmlText(Ruby runtime, RubyClass rubyClass, Node node) {
64
- super(runtime, rubyClass, node);
65
- }
64
+ public
65
+ XmlText(Ruby runtime, RubyClass rubyClass, Node node)
66
+ {
67
+ super(runtime, rubyClass, node);
68
+ }
66
69
 
67
- public XmlText(Ruby runtime, RubyClass klass) {
68
- super(runtime, klass);
70
+ public
71
+ XmlText(Ruby runtime, RubyClass klass)
72
+ {
73
+ super(runtime, klass);
74
+ }
75
+
76
+ @Override
77
+ protected void
78
+ init(ThreadContext context, IRubyObject[] args)
79
+ {
80
+ if (args.length < 2) {
81
+ throw context.runtime.newArgumentError(args.length, 2);
69
82
  }
70
83
 
71
- @Override
72
- protected void init(ThreadContext context, IRubyObject[] args) {
73
- if (args.length < 2) {
74
- throw context.runtime.newArgumentError(args.length, 2);
75
- }
84
+ content = args[0];
85
+ IRubyObject xNode = args[1];
76
86
 
77
- content = args[0];
78
- IRubyObject xNode = args[1];
87
+ Document document = asXmlNode(context, xNode).getOwnerDocument();
88
+ // text node content should not be encoded when it is created by Text node.
89
+ // while content should be encoded when it is created by Element node.
90
+ Node node = document.createTextNode(rubyStringToString(content));
91
+ setNode(context.runtime, node);
92
+ }
79
93
 
80
- Document document = asXmlNode(context, xNode).getOwnerDocument();
81
- // text node content should not be encoded when it is created by Text node.
82
- // while content should be encoded when it is created by Element node.
83
- Node node = document.createTextNode(rubyStringToString(content));
84
- setNode(context.runtime, node);
85
- }
86
-
87
- @Override
88
- protected IRubyObject getNodeName(ThreadContext context) {
89
- if (name == null) name = RubyString.newStringShared(context.runtime, TEXT);
90
- return name;
91
- }
94
+ @Override
95
+ protected IRubyObject
96
+ getNodeName(ThreadContext context)
97
+ {
98
+ if (name == null) { name = RubyString.newStringShared(context.runtime, TEXT); }
99
+ return name;
100
+ }
92
101
 
93
- @Override
94
- public void accept(ThreadContext context, SaveContextVisitor visitor) {
95
- visitor.enter((Text) node);
96
- Node child = node.getFirstChild();
97
- while (child != null) {
98
- IRubyObject nokoNode = getCachedNodeOrCreate(context.runtime, child);
99
- if (nokoNode instanceof XmlNode) {
100
- XmlNode cur = (XmlNode) nokoNode;
101
- cur.accept(context, visitor);
102
- } else if (nokoNode instanceof XmlNamespace) {
103
- XmlNamespace cur = (XmlNamespace) nokoNode;
104
- cur.accept(context, visitor);
105
- }
106
- child = child.getNextSibling();
107
- }
108
- visitor.leave(node);
102
+ @Override
103
+ public void
104
+ accept(ThreadContext context, SaveContextVisitor visitor)
105
+ {
106
+ visitor.enter((Text) node);
107
+ Node child = node.getFirstChild();
108
+ while (child != null) {
109
+ IRubyObject nokoNode = getCachedNodeOrCreate(context.runtime, child);
110
+ if (nokoNode instanceof XmlNode) {
111
+ XmlNode cur = (XmlNode) nokoNode;
112
+ cur.accept(context, visitor);
113
+ } else if (nokoNode instanceof XmlNamespace) {
114
+ XmlNamespace cur = (XmlNamespace) nokoNode;
115
+ cur.accept(context, visitor);
116
+ }
117
+ child = child.getNextSibling();
109
118
  }
119
+ visitor.leave(node);
120
+ }
110
121
  }
@@ -68,234 +68,268 @@ import static nokogiri.internals.NokogiriHelpers.nodeListToRubyArray;
68
68
  * @author Yoko Harada <yokolet@gmail.com>
69
69
  * @author John Shahid <jvshahid@gmail.com>
70
70
  */
71
- @JRubyClass(name="Nokogiri::XML::XPathContext")
72
- public class XmlXpathContext extends RubyObject {
73
- static {
74
- final String DTMManager = "org.apache.xml.dtm.DTMManager";
75
- if (SafePropertyAccessor.getProperty(DTMManager) == null) {
76
- try { // use patched "org.apache.xml.dtm.ref.DTMManagerDefault"
77
- System.setProperty(DTMManager, nokogiri.internals.XalanDTMManagerPatch.class.getName());
78
- }
79
- catch (SecurityException ex) { /* no-op - will work although might be slower */ }
80
- }
71
+ @JRubyClass(name = "Nokogiri::XML::XPathContext")
72
+ public class XmlXpathContext extends RubyObject
73
+ {
74
+ static
75
+ {
76
+ final String DTMManager = "org.apache.xml.dtm.DTMManager";
77
+ if (SafePropertyAccessor.getProperty(DTMManager) == null) {
78
+ try { // use patched "org.apache.xml.dtm.ref.DTMManagerDefault"
79
+ System.setProperty(DTMManager, nokogiri.internals.XalanDTMManagerPatch.class.getName());
80
+ } catch (SecurityException ex) { /* no-op - will work although might be slower */ }
81
81
  }
82
-
83
- /**
84
- * user-data key for (cached) {@link XPathContext}
85
- */
86
- public static final String XPATH_CONTEXT = "CACHED_XPATH_CONTEXT";
87
-
88
- private XmlNode context;
89
-
90
- public XmlXpathContext(Ruby runtime, RubyClass klass) {
91
- super(runtime, klass);
82
+ }
83
+
84
+ /**
85
+ * user-data key for (cached) {@link XPathContext}
86
+ */
87
+ public static final String XPATH_CONTEXT = "CACHED_XPATH_CONTEXT";
88
+
89
+ private XmlNode context;
90
+
91
+ public
92
+ XmlXpathContext(Ruby runtime, RubyClass klass)
93
+ {
94
+ super(runtime, klass);
95
+ }
96
+
97
+ public
98
+ XmlXpathContext(Ruby runtime, RubyClass klass, XmlNode node)
99
+ {
100
+ this(runtime, klass);
101
+ initNode(node);
102
+ }
103
+
104
+ private void
105
+ initNode(XmlNode node)
106
+ {
107
+ context = node;
108
+ }
109
+
110
+ @JRubyMethod(name = "new", meta = true)
111
+ public static IRubyObject
112
+ rbNew(ThreadContext context, IRubyObject klazz, IRubyObject node)
113
+ {
114
+ try {
115
+ return new XmlXpathContext(context.runtime, (RubyClass) klazz, (XmlNode) node);
116
+ } catch (IllegalArgumentException e) {
117
+ throw context.getRuntime().newRuntimeError(e.getMessage());
92
118
  }
119
+ }
120
+
121
+
122
+ // see https://en.wikipedia.org/wiki/QName
123
+ private static final String NameStartCharStr =
124
+ "[_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]"
125
+ ;
126
+ private static final String NameCharStr = "[-\\.0-9\u00B7\u0300-\u036F\u203F-\u2040]|" + NameStartCharStr ;
127
+ private static final String NCNameStr = "(?:" + NameStartCharStr + ")(?:" + NameCharStr + ")*";
128
+ private static final String XPathFunctionCaptureStr = "(" + NCNameStr + "(?=\\())";
129
+ private static final Pattern XPathFunctionCaptureRE = Pattern.compile(XPathFunctionCaptureStr);
130
+
131
+ @JRubyMethod
132
+ public IRubyObject
133
+ evaluate(ThreadContext context, IRubyObject rbQuery, IRubyObject handler)
134
+ {
135
+ String query = rbQuery.convertToString().asJavaString();
136
+
137
+ if (!handler.isNil() && !isContainsPrefix(query)) {
138
+ //
139
+ // The user has passed in a handler, but isn't using the `nokogiri:` prefix as
140
+ // instructed in JRuby land, so let's try to be clever and rewrite the query, inserting
141
+ // the nokogiri namespace where appropriate.
142
+ //
143
+ StringBuilder namespacedQuery = new StringBuilder();
144
+ int jchar = 0;
145
+
146
+ // Find the methods on the handler object
147
+ Set<String> methodNames = handler.getMetaClass().getMethods().keySet();
148
+
149
+ // Find the function calls in the xpath query
150
+ Matcher xpathFunctionCalls = XPathFunctionCaptureRE.matcher(query);
151
+
152
+ while (xpathFunctionCalls.find()) {
153
+ namespacedQuery.append(query.subSequence(jchar, xpathFunctionCalls.start()));
154
+ jchar = xpathFunctionCalls.start();
155
+
156
+ if (methodNames.contains(xpathFunctionCalls.group())) {
157
+ namespacedQuery.append(NokogiriNamespaceContext.NOKOGIRI_PREFIX);
158
+ namespacedQuery.append(":");
159
+ }
93
160
 
94
- public XmlXpathContext(Ruby runtime, RubyClass klass, XmlNode node) {
95
- this(runtime, klass);
96
- initNode(node);
97
- }
161
+ namespacedQuery.append(query.subSequence(xpathFunctionCalls.start(), xpathFunctionCalls.end()));
162
+ jchar = xpathFunctionCalls.end();
163
+ }
98
164
 
99
- private void initNode(XmlNode node) {
100
- context = node;
165
+ if (jchar < query.length() - 1) {
166
+ namespacedQuery.append(query.subSequence(jchar, query.length()));
167
+ }
168
+ query = namespacedQuery.toString();
101
169
  }
102
170
 
103
- @JRubyMethod(name = "new", meta = true)
104
- public static IRubyObject rbNew(ThreadContext context, IRubyObject klazz, IRubyObject node) {
105
- try {
106
- return new XmlXpathContext(context.runtime, (RubyClass) klazz, (XmlNode) node);
107
- }
108
- catch (IllegalArgumentException e) {
109
- throw context.getRuntime().newRuntimeError(e.getMessage());
110
- }
171
+ return node_set(context, query, handler);
172
+ }
173
+
174
+ @JRubyMethod
175
+ public IRubyObject
176
+ evaluate(ThreadContext context, IRubyObject expr)
177
+ {
178
+ return this.evaluate(context, expr, context.getRuntime().getNil());
179
+ }
180
+
181
+ private final NokogiriNamespaceContext nsContext = NokogiriNamespaceContext.create();
182
+
183
+ @JRubyMethod
184
+ public IRubyObject
185
+ register_ns(IRubyObject prefix, IRubyObject uri)
186
+ {
187
+ nsContext.registerNamespace(prefix.asJavaString(), uri.asJavaString());
188
+ return this;
189
+ }
190
+
191
+ private NokogiriXPathVariableResolver variableResolver; // binds (if any)
192
+
193
+ @JRubyMethod
194
+ public IRubyObject
195
+ register_variable(IRubyObject name, IRubyObject value)
196
+ {
197
+ NokogiriXPathVariableResolver variableResolver = this.variableResolver;
198
+ if (variableResolver == null) {
199
+ variableResolver = NokogiriXPathVariableResolver.create();
200
+ this.variableResolver = variableResolver;
111
201
  }
112
-
113
-
114
- // see https://en.wikipedia.org/wiki/QName
115
- private static final String NameStartCharStr = "[_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]" ;
116
- private static final String NameCharStr = "[-\\.0-9\u00B7\u0300-\u036F\u203F-\u2040]|" + NameStartCharStr ;
117
- private static final String NCNameStr = "(?:" + NameStartCharStr + ")(?:" + NameCharStr + ")*";
118
- private static final String XPathFunctionCaptureStr = "(" + NCNameStr + "(?=\\())";
119
- private static final Pattern XPathFunctionCaptureRE = Pattern.compile(XPathFunctionCaptureStr);
120
-
121
- @JRubyMethod
122
- public IRubyObject evaluate(ThreadContext context, IRubyObject rbQuery, IRubyObject handler) {
123
- String query = rbQuery.convertToString().asJavaString();
124
-
125
- if (!handler.isNil() && !isContainsPrefix(query)) {
126
- //
127
- // The user has passed in a handler, but isn't using the `nokogiri:` prefix as
128
- // instructed in JRuby land, so let's try to be clever and rewrite the query, inserting
129
- // the nokogiri namespace where appropriate.
130
- //
131
- StringBuilder namespacedQuery = new StringBuilder();
132
- int jchar = 0;
133
-
134
- // Find the methods on the handler object
135
- Set<String> methodNames = handler.getMetaClass().getMethods().keySet();
136
-
137
- // Find the function calls in the xpath query
138
- Matcher xpathFunctionCalls = XPathFunctionCaptureRE.matcher(query);
139
-
140
- while (xpathFunctionCalls.find()) {
141
- namespacedQuery.append(query.subSequence(jchar, xpathFunctionCalls.start()));
142
- jchar = xpathFunctionCalls.start();
143
-
144
- if (methodNames.contains(xpathFunctionCalls.group())) {
145
- namespacedQuery.append(NokogiriNamespaceContext.NOKOGIRI_PREFIX);
146
- namespacedQuery.append(":");
147
- }
148
-
149
- namespacedQuery.append(query.subSequence(xpathFunctionCalls.start(), xpathFunctionCalls.end()));
150
- jchar = xpathFunctionCalls.end();
151
- }
152
-
153
- if (jchar < query.length()-1) {
154
- namespacedQuery.append(query.subSequence(jchar, query.length()));
155
- }
156
- query = namespacedQuery.toString();
157
- }
158
-
159
- return node_set(context, query, handler);
202
+ variableResolver.registerVariable(name.asJavaString(), value.asJavaString());
203
+ return this;
204
+ }
205
+
206
+ private IRubyObject
207
+ node_set(ThreadContext context, String expr, IRubyObject handler)
208
+ {
209
+ final NokogiriXPathFunctionResolver fnResolver = NokogiriXPathFunctionResolver.create(handler);
210
+ try {
211
+ return tryGetNodeSet(context, expr, fnResolver);
212
+ } catch (TransformerException ex) {
213
+ throw XmlSyntaxError.createXMLXPathSyntaxError(context.runtime,
214
+ (expr + ": " + ex.toString()),
215
+ ex).toThrowable();
160
216
  }
161
-
162
- @JRubyMethod
163
- public IRubyObject evaluate(ThreadContext context, IRubyObject expr) {
164
- return this.evaluate(context, expr, context.getRuntime().getNil());
217
+ }
218
+
219
+ private IRubyObject
220
+ tryGetNodeSet(ThreadContext context, String expr, NokogiriXPathFunctionResolver fnResolver) throws TransformerException
221
+ {
222
+ final Node contextNode = this.context.node;
223
+
224
+ final JAXPPrefixResolver prefixResolver = new JAXPPrefixResolver(nsContext);
225
+ XPath xpathInternal = new XPath(expr, null, prefixResolver, XPath.SELECT);
226
+
227
+ // We always need to have a ContextNode with Xalan XPath implementation
228
+ // To allow simple expression evaluation like 1+1 we are setting
229
+ // dummy Document as Context Node
230
+ final XObject xobj;
231
+ if (contextNode == null) {
232
+ xobj = xpathInternal.execute(getXPathContext(fnResolver), DTM.NULL, prefixResolver);
233
+ } else {
234
+ xobj = xpathInternal.execute(getXPathContext(fnResolver), contextNode, prefixResolver);
165
235
  }
166
236
 
167
- private final NokogiriNamespaceContext nsContext = NokogiriNamespaceContext.create();
168
-
169
- @JRubyMethod
170
- public IRubyObject register_ns(IRubyObject prefix, IRubyObject uri) {
171
- nsContext.registerNamespace(prefix.asJavaString(), uri.asJavaString());
172
- return this;
237
+ switch (xobj.getType()) {
238
+ case XObject.CLASS_BOOLEAN :
239
+ return context.runtime.newBoolean(xobj.bool());
240
+ case XObject.CLASS_NUMBER :
241
+ return context.runtime.newFloat(xobj.num());
242
+ case XObject.CLASS_NODESET :
243
+ IRubyObject[] nodes = nodeListToRubyArray(context.runtime, xobj.nodelist());
244
+ return XmlNodeSet.newNodeSet(context.runtime, nodes, this.context);
245
+ default :
246
+ return context.runtime.newString(xobj.str());
173
247
  }
174
-
175
- private NokogiriXPathVariableResolver variableResolver; // binds (if any)
176
-
177
- @JRubyMethod
178
- public IRubyObject register_variable(IRubyObject name, IRubyObject value) {
179
- NokogiriXPathVariableResolver variableResolver = this.variableResolver;
180
- if (variableResolver == null) {
181
- variableResolver = NokogiriXPathVariableResolver.create();
182
- this.variableResolver = variableResolver;
183
- }
184
- variableResolver.registerVariable(name.asJavaString(), value.asJavaString());
185
- return this;
248
+ }
249
+
250
+ private XPathContext
251
+ getXPathContext(final NokogiriXPathFunctionResolver fnResolver)
252
+ {
253
+ Node doc = context.getNode().getOwnerDocument();
254
+ if (doc == null) { doc = context.getNode(); }
255
+
256
+ XPathContext xpathContext = (XPathContext) doc.getUserData(XPATH_CONTEXT);
257
+
258
+ if (xpathContext == null) {
259
+ xpathContext = newXPathContext(fnResolver);
260
+ if (variableResolver == null) {
261
+ // NOTE: only caching without variables - could be improved by more sophisticated caching
262
+ doc.setUserData(XPATH_CONTEXT, xpathContext, null);
263
+ }
264
+ } else {
265
+ Object owner = xpathContext.getOwnerObject();
266
+ if ((owner == null && fnResolver == null) ||
267
+ (owner instanceof JAXPExtensionsProvider && ((JAXPExtensionsProvider) owner).hasSameResolver(fnResolver))) {
268
+ // can be re-used assuming it has the same variable-stack (for now only cached if no variables)
269
+ if (variableResolver == null) { return xpathContext; }
270
+ }
271
+ xpathContext = newXPathContext(fnResolver); // otherwise we can not use the cached xpath-context
186
272
  }
187
273
 
188
- private IRubyObject node_set(ThreadContext context, String expr, IRubyObject handler) {
189
- final NokogiriXPathFunctionResolver fnResolver = NokogiriXPathFunctionResolver.create(handler);
190
- try {
191
- return tryGetNodeSet(context, expr, fnResolver);
192
- }
193
- catch (TransformerException ex) {
194
- throw XmlSyntaxError.createXMLXPathSyntaxError(context.runtime,
195
- (expr + ": " + ex.toString()),
196
- ex).toThrowable();
197
- }
274
+ if (variableResolver != null) {
275
+ xpathContext.setVarStack(new JAXPVariableStack(variableResolver));
198
276
  }
199
277
 
200
- private IRubyObject tryGetNodeSet(ThreadContext context, String expr, NokogiriXPathFunctionResolver fnResolver) throws TransformerException {
201
- final Node contextNode = this.context.node;
202
-
203
- final JAXPPrefixResolver prefixResolver = new JAXPPrefixResolver(nsContext);
204
- XPath xpathInternal = new XPath(expr, null, prefixResolver, XPath.SELECT);
205
-
206
- // We always need to have a ContextNode with Xalan XPath implementation
207
- // To allow simple expression evaluation like 1+1 we are setting
208
- // dummy Document as Context Node
209
- final XObject xobj;
210
- if ( contextNode == null )
211
- xobj = xpathInternal.execute(getXPathContext(fnResolver), DTM.NULL, prefixResolver);
212
- else
213
- xobj = xpathInternal.execute(getXPathContext(fnResolver), contextNode, prefixResolver);
214
-
215
- switch (xobj.getType()) {
216
- case XObject.CLASS_BOOLEAN : return context.runtime.newBoolean(xobj.bool());
217
- case XObject.CLASS_NUMBER : return context.runtime.newFloat(xobj.num());
218
- case XObject.CLASS_NODESET :
219
- IRubyObject[] nodes = nodeListToRubyArray(context.runtime, xobj.nodelist());
220
- return XmlNodeSet.newNodeSet(context.runtime, nodes, this.context);
221
- default : return context.runtime.newString(xobj.str());
222
- }
278
+ return xpathContext;
279
+ }
280
+
281
+ private static XPathContext
282
+ newXPathContext(final NokogiriXPathFunctionResolver functionResolver)
283
+ {
284
+ if (functionResolver == null) { return new XPathContext(false); }
285
+ return new XPathContext(new JAXPExtensionsProvider(functionResolver), false);
286
+ }
287
+
288
+ private boolean
289
+ isContainsPrefix(final String str)
290
+ {
291
+ final StringBuilder prefix_ = new StringBuilder();
292
+ for (String prefix : nsContext.getAllPrefixes()) {
293
+ prefix_.setLength(0);
294
+ prefix_.ensureCapacity(prefix.length() + 1);
295
+ prefix_.append(prefix).append(':');
296
+ if (str.contains(prefix_)) { // prefix + ':'
297
+ return true;
298
+ }
223
299
  }
300
+ return false;
301
+ }
224
302
 
225
- private XPathContext getXPathContext(final NokogiriXPathFunctionResolver fnResolver) {
226
- Node doc = context.getNode().getOwnerDocument();
227
- if (doc == null) doc = context.getNode();
228
-
229
- XPathContext xpathContext = (XPathContext) doc.getUserData(XPATH_CONTEXT);
303
+ private static final class JAXPExtensionsProvider extends org.apache.xpath.jaxp.JAXPExtensionsProvider
304
+ {
230
305
 
231
- if ( xpathContext == null ) {
232
- xpathContext = newXPathContext(fnResolver);
233
- if ( variableResolver == null ) {
234
- // NOTE: only caching without variables - could be improved by more sophisticated caching
235
- doc.setUserData(XPATH_CONTEXT, xpathContext, null);
236
- }
237
- }
238
- else {
239
- Object owner = xpathContext.getOwnerObject();
240
- if ( ( owner == null && fnResolver == null ) ||
241
- ( owner instanceof JAXPExtensionsProvider && ((JAXPExtensionsProvider) owner).hasSameResolver(fnResolver) ) ) {
242
- // can be re-used assuming it has the same variable-stack (for now only cached if no variables)
243
- if ( variableResolver == null ) return xpathContext;
244
- }
245
- xpathContext = newXPathContext(fnResolver); // otherwise we can not use the cached xpath-context
246
- }
306
+ final NokogiriXPathFunctionResolver resolver;
247
307
 
248
- if ( variableResolver != null ) {
249
- xpathContext.setVarStack(new JAXPVariableStack(variableResolver));
250
- }
251
-
252
- return xpathContext;
308
+ JAXPExtensionsProvider(NokogiriXPathFunctionResolver resolver)
309
+ {
310
+ super(resolver, false);
311
+ this.resolver = resolver;
253
312
  }
254
313
 
255
- private static XPathContext newXPathContext(final NokogiriXPathFunctionResolver functionResolver) {
256
- if ( functionResolver == null ) return new XPathContext(false);
257
- return new XPathContext(new JAXPExtensionsProvider(functionResolver), false);
314
+ //@Override
315
+ //public boolean equals(Object obj) {
316
+ // if (obj instanceof JAXPExtensionsProvider) {
317
+ // return hasSameResolver(((JAXPExtensionsProvider) obj).resolver);
318
+ // }
319
+ // return false;
320
+ //}
321
+
322
+ final boolean
323
+ hasSameResolver(final NokogiriXPathFunctionResolver resolver)
324
+ {
325
+ return resolver == this.resolver || resolver != null && (
326
+ resolver.getHandler() == null ? this.resolver.getHandler() == null : (
327
+ resolver.getHandler() == this.resolver.getHandler()
328
+ // resolver.getHandler().eql( this.resolver.getHandler() )
329
+ )
330
+ );
258
331
  }
259
332
 
260
- private boolean isContainsPrefix(final String str) {
261
- final StringBuilder prefix_ = new StringBuilder();
262
- for ( String prefix : nsContext.getAllPrefixes() ) {
263
- prefix_.setLength(0);
264
- prefix_.ensureCapacity(prefix.length() + 1);
265
- prefix_.append(prefix).append(':');
266
- if ( str.contains(prefix_) ) { // prefix + ':'
267
- return true;
268
- }
269
- }
270
- return false;
271
- }
272
-
273
- private static final class JAXPExtensionsProvider extends org.apache.xpath.jaxp.JAXPExtensionsProvider {
274
-
275
- final NokogiriXPathFunctionResolver resolver;
276
-
277
- JAXPExtensionsProvider(NokogiriXPathFunctionResolver resolver) {
278
- super(resolver, false);
279
- this.resolver = resolver;
280
- }
281
-
282
- //@Override
283
- //public boolean equals(Object obj) {
284
- // if (obj instanceof JAXPExtensionsProvider) {
285
- // return hasSameResolver(((JAXPExtensionsProvider) obj).resolver);
286
- // }
287
- // return false;
288
- //}
289
-
290
- final boolean hasSameResolver(final NokogiriXPathFunctionResolver resolver) {
291
- return resolver == this.resolver || resolver != null && (
292
- resolver.getHandler() == null ? this.resolver.getHandler() == null : (
293
- resolver.getHandler() == this.resolver.getHandler()
294
- // resolver.getHandler().eql( this.resolver.getHandler() )
295
- )
296
- );
297
- }
298
-
299
- }
333
+ }
300
334
 
301
335
  }