nokogiri-backupify 1.5.0.beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. data/.autotest +26 -0
  2. data/CHANGELOG.ja.rdoc +509 -0
  3. data/CHANGELOG.rdoc +490 -0
  4. data/Manifest.txt +274 -0
  5. data/README.ja.rdoc +106 -0
  6. data/README.rdoc +150 -0
  7. data/Rakefile +217 -0
  8. data/bin/nokogiri +54 -0
  9. data/deps.rip +5 -0
  10. data/ext/java/nokogiri/EncodingHandler.java +124 -0
  11. data/ext/java/nokogiri/HtmlDocument.java +146 -0
  12. data/ext/java/nokogiri/HtmlElementDescription.java +145 -0
  13. data/ext/java/nokogiri/HtmlEntityLookup.java +79 -0
  14. data/ext/java/nokogiri/HtmlSaxParserContext.java +256 -0
  15. data/ext/java/nokogiri/NokogiriService.java +466 -0
  16. data/ext/java/nokogiri/XmlAttr.java +183 -0
  17. data/ext/java/nokogiri/XmlAttributeDecl.java +130 -0
  18. data/ext/java/nokogiri/XmlCdata.java +89 -0
  19. data/ext/java/nokogiri/XmlComment.java +84 -0
  20. data/ext/java/nokogiri/XmlDocument.java +514 -0
  21. data/ext/java/nokogiri/XmlDocumentFragment.java +216 -0
  22. data/ext/java/nokogiri/XmlDtd.java +464 -0
  23. data/ext/java/nokogiri/XmlElement.java +221 -0
  24. data/ext/java/nokogiri/XmlElementContent.java +382 -0
  25. data/ext/java/nokogiri/XmlElementDecl.java +147 -0
  26. data/ext/java/nokogiri/XmlEntityDecl.java +161 -0
  27. data/ext/java/nokogiri/XmlEntityReference.java +75 -0
  28. data/ext/java/nokogiri/XmlNamespace.java +127 -0
  29. data/ext/java/nokogiri/XmlNode.java +1392 -0
  30. data/ext/java/nokogiri/XmlNodeSet.java +284 -0
  31. data/ext/java/nokogiri/XmlProcessingInstruction.java +103 -0
  32. data/ext/java/nokogiri/XmlReader.java +409 -0
  33. data/ext/java/nokogiri/XmlRelaxng.java +199 -0
  34. data/ext/java/nokogiri/XmlSaxParserContext.java +353 -0
  35. data/ext/java/nokogiri/XmlSaxPushParser.java +182 -0
  36. data/ext/java/nokogiri/XmlSchema.java +175 -0
  37. data/ext/java/nokogiri/XmlSyntaxError.java +114 -0
  38. data/ext/java/nokogiri/XmlText.java +135 -0
  39. data/ext/java/nokogiri/XmlXpathContext.java +175 -0
  40. data/ext/java/nokogiri/XsltStylesheet.java +181 -0
  41. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +205 -0
  42. data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +73 -0
  43. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +80 -0
  44. data/ext/java/nokogiri/internals/NokogiriHandler.java +326 -0
  45. data/ext/java/nokogiri/internals/NokogiriHelpers.java +583 -0
  46. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +170 -0
  47. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +118 -0
  48. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +73 -0
  49. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +121 -0
  50. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +78 -0
  51. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +120 -0
  52. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +56 -0
  53. data/ext/java/nokogiri/internals/ParserContext.java +278 -0
  54. data/ext/java/nokogiri/internals/PushInputStream.java +411 -0
  55. data/ext/java/nokogiri/internals/ReaderNode.java +473 -0
  56. data/ext/java/nokogiri/internals/SaveContext.java +282 -0
  57. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +68 -0
  58. data/ext/java/nokogiri/internals/XmlDeclHandler.java +42 -0
  59. data/ext/java/nokogiri/internals/XmlDomParser.java +77 -0
  60. data/ext/java/nokogiri/internals/XmlDomParserContext.java +233 -0
  61. data/ext/java/nokogiri/internals/XmlSaxParser.java +65 -0
  62. data/ext/java/nokogiri/internals/XsltExtensionFunction.java +72 -0
  63. data/ext/nokogiri/depend +358 -0
  64. data/ext/nokogiri/extconf.rb +124 -0
  65. data/ext/nokogiri/html_document.c +154 -0
  66. data/ext/nokogiri/html_document.h +10 -0
  67. data/ext/nokogiri/html_element_description.c +276 -0
  68. data/ext/nokogiri/html_element_description.h +10 -0
  69. data/ext/nokogiri/html_entity_lookup.c +32 -0
  70. data/ext/nokogiri/html_entity_lookup.h +8 -0
  71. data/ext/nokogiri/html_sax_parser_context.c +94 -0
  72. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  73. data/ext/nokogiri/nokogiri.c +92 -0
  74. data/ext/nokogiri/nokogiri.h +160 -0
  75. data/ext/nokogiri/xml_attr.c +94 -0
  76. data/ext/nokogiri/xml_attr.h +9 -0
  77. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  78. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  79. data/ext/nokogiri/xml_cdata.c +56 -0
  80. data/ext/nokogiri/xml_cdata.h +9 -0
  81. data/ext/nokogiri/xml_comment.c +54 -0
  82. data/ext/nokogiri/xml_comment.h +9 -0
  83. data/ext/nokogiri/xml_document.c +478 -0
  84. data/ext/nokogiri/xml_document.h +23 -0
  85. data/ext/nokogiri/xml_document_fragment.c +48 -0
  86. data/ext/nokogiri/xml_document_fragment.h +10 -0
  87. data/ext/nokogiri/xml_dtd.c +202 -0
  88. data/ext/nokogiri/xml_dtd.h +10 -0
  89. data/ext/nokogiri/xml_element_content.c +123 -0
  90. data/ext/nokogiri/xml_element_content.h +10 -0
  91. data/ext/nokogiri/xml_element_decl.c +69 -0
  92. data/ext/nokogiri/xml_element_decl.h +9 -0
  93. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  94. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  95. data/ext/nokogiri/xml_entity_decl.c +110 -0
  96. data/ext/nokogiri/xml_entity_decl.h +10 -0
  97. data/ext/nokogiri/xml_entity_reference.c +52 -0
  98. data/ext/nokogiri/xml_entity_reference.h +9 -0
  99. data/ext/nokogiri/xml_io.c +31 -0
  100. data/ext/nokogiri/xml_io.h +11 -0
  101. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  102. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  103. data/ext/nokogiri/xml_namespace.c +84 -0
  104. data/ext/nokogiri/xml_namespace.h +13 -0
  105. data/ext/nokogiri/xml_node.c +1384 -0
  106. data/ext/nokogiri/xml_node.h +13 -0
  107. data/ext/nokogiri/xml_node_set.c +418 -0
  108. data/ext/nokogiri/xml_node_set.h +9 -0
  109. data/ext/nokogiri/xml_processing_instruction.c +56 -0
  110. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  111. data/ext/nokogiri/xml_reader.c +684 -0
  112. data/ext/nokogiri/xml_reader.h +10 -0
  113. data/ext/nokogiri/xml_relax_ng.c +161 -0
  114. data/ext/nokogiri/xml_relax_ng.h +9 -0
  115. data/ext/nokogiri/xml_sax_parser.c +288 -0
  116. data/ext/nokogiri/xml_sax_parser.h +39 -0
  117. data/ext/nokogiri/xml_sax_parser_context.c +199 -0
  118. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  119. data/ext/nokogiri/xml_sax_push_parser.c +115 -0
  120. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  121. data/ext/nokogiri/xml_schema.c +205 -0
  122. data/ext/nokogiri/xml_schema.h +9 -0
  123. data/ext/nokogiri/xml_syntax_error.c +58 -0
  124. data/ext/nokogiri/xml_syntax_error.h +13 -0
  125. data/ext/nokogiri/xml_text.c +50 -0
  126. data/ext/nokogiri/xml_text.h +9 -0
  127. data/ext/nokogiri/xml_xpath_context.c +309 -0
  128. data/ext/nokogiri/xml_xpath_context.h +9 -0
  129. data/ext/nokogiri/xslt_stylesheet.c +258 -0
  130. data/ext/nokogiri/xslt_stylesheet.h +9 -0
  131. data/lib/isorelax.jar +0 -0
  132. data/lib/jing.jar +0 -0
  133. data/lib/nekodtd.jar +0 -0
  134. data/lib/nekohtml.jar +0 -0
  135. data/lib/nokogiri.rb +143 -0
  136. data/lib/nokogiri/css.rb +23 -0
  137. data/lib/nokogiri/css/node.rb +99 -0
  138. data/lib/nokogiri/css/parser.rb +677 -0
  139. data/lib/nokogiri/css/parser.y +237 -0
  140. data/lib/nokogiri/css/parser_extras.rb +91 -0
  141. data/lib/nokogiri/css/syntax_error.rb +7 -0
  142. data/lib/nokogiri/css/tokenizer.rb +152 -0
  143. data/lib/nokogiri/css/tokenizer.rex +55 -0
  144. data/lib/nokogiri/css/xpath_visitor.rb +171 -0
  145. data/lib/nokogiri/decorators/slop.rb +35 -0
  146. data/lib/nokogiri/html.rb +36 -0
  147. data/lib/nokogiri/html/builder.rb +35 -0
  148. data/lib/nokogiri/html/document.rb +221 -0
  149. data/lib/nokogiri/html/document_fragment.rb +41 -0
  150. data/lib/nokogiri/html/element_description.rb +23 -0
  151. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  152. data/lib/nokogiri/html/entity_lookup.rb +13 -0
  153. data/lib/nokogiri/html/sax/parser.rb +52 -0
  154. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  155. data/lib/nokogiri/syntax_error.rb +4 -0
  156. data/lib/nokogiri/version.rb +35 -0
  157. data/lib/nokogiri/xml.rb +67 -0
  158. data/lib/nokogiri/xml/attr.rb +14 -0
  159. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  160. data/lib/nokogiri/xml/builder.rb +418 -0
  161. data/lib/nokogiri/xml/cdata.rb +11 -0
  162. data/lib/nokogiri/xml/character_data.rb +7 -0
  163. data/lib/nokogiri/xml/document.rb +218 -0
  164. data/lib/nokogiri/xml/document_fragment.rb +84 -0
  165. data/lib/nokogiri/xml/dtd.rb +22 -0
  166. data/lib/nokogiri/xml/element_content.rb +36 -0
  167. data/lib/nokogiri/xml/element_decl.rb +13 -0
  168. data/lib/nokogiri/xml/entity_decl.rb +19 -0
  169. data/lib/nokogiri/xml/namespace.rb +13 -0
  170. data/lib/nokogiri/xml/node.rb +907 -0
  171. data/lib/nokogiri/xml/node/save_options.rb +45 -0
  172. data/lib/nokogiri/xml/node_set.rb +350 -0
  173. data/lib/nokogiri/xml/notation.rb +6 -0
  174. data/lib/nokogiri/xml/parse_options.rb +85 -0
  175. data/lib/nokogiri/xml/pp.rb +2 -0
  176. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  177. data/lib/nokogiri/xml/pp/node.rb +56 -0
  178. data/lib/nokogiri/xml/processing_instruction.rb +8 -0
  179. data/lib/nokogiri/xml/reader.rb +112 -0
  180. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  181. data/lib/nokogiri/xml/sax.rb +4 -0
  182. data/lib/nokogiri/xml/sax/document.rb +164 -0
  183. data/lib/nokogiri/xml/sax/parser.rb +115 -0
  184. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  185. data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
  186. data/lib/nokogiri/xml/schema.rb +57 -0
  187. data/lib/nokogiri/xml/syntax_error.rb +47 -0
  188. data/lib/nokogiri/xml/text.rb +9 -0
  189. data/lib/nokogiri/xml/xpath.rb +10 -0
  190. data/lib/nokogiri/xml/xpath/syntax_error.rb +11 -0
  191. data/lib/nokogiri/xml/xpath_context.rb +16 -0
  192. data/lib/nokogiri/xslt.rb +52 -0
  193. data/lib/nokogiri/xslt/stylesheet.rb +25 -0
  194. data/lib/xercesImpl.jar +0 -0
  195. data/lib/xsd/xmlparser/nokogiri.rb +90 -0
  196. data/tasks/cross_compile.rb +177 -0
  197. data/tasks/test.rb +94 -0
  198. data/test/css/test_nthiness.rb +159 -0
  199. data/test/css/test_parser.rb +303 -0
  200. data/test/css/test_tokenizer.rb +198 -0
  201. data/test/css/test_xpath_visitor.rb +85 -0
  202. data/test/decorators/test_slop.rb +16 -0
  203. data/test/files/2ch.html +108 -0
  204. data/test/files/address_book.rlx +12 -0
  205. data/test/files/address_book.xml +10 -0
  206. data/test/files/bar/bar.xsd +4 -0
  207. data/test/files/dont_hurt_em_why.xml +422 -0
  208. data/test/files/exslt.xml +8 -0
  209. data/test/files/exslt.xslt +35 -0
  210. data/test/files/foo/foo.xsd +4 -0
  211. data/test/files/po.xml +32 -0
  212. data/test/files/po.xsd +66 -0
  213. data/test/files/shift_jis.html +10 -0
  214. data/test/files/shift_jis.xml +5 -0
  215. data/test/files/snuggles.xml +3 -0
  216. data/test/files/staff.dtd +10 -0
  217. data/test/files/staff.xml +59 -0
  218. data/test/files/staff.xslt +32 -0
  219. data/test/files/tlm.html +850 -0
  220. data/test/files/valid_bar.xml +2 -0
  221. data/test/helper.rb +171 -0
  222. data/test/html/sax/test_parser.rb +136 -0
  223. data/test/html/sax/test_parser_context.rb +48 -0
  224. data/test/html/test_builder.rb +164 -0
  225. data/test/html/test_document.rb +457 -0
  226. data/test/html/test_document_encoding.rb +123 -0
  227. data/test/html/test_document_fragment.rb +255 -0
  228. data/test/html/test_element_description.rb +100 -0
  229. data/test/html/test_named_characters.rb +14 -0
  230. data/test/html/test_node.rb +190 -0
  231. data/test/html/test_node_encoding.rb +27 -0
  232. data/test/test_convert_xpath.rb +135 -0
  233. data/test/test_css_cache.rb +45 -0
  234. data/test/test_encoding_handler.rb +46 -0
  235. data/test/test_memory_leak.rb +52 -0
  236. data/test/test_nokogiri.rb +132 -0
  237. data/test/test_reader.rb +403 -0
  238. data/test/test_soap4r_sax.rb +52 -0
  239. data/test/test_xslt_transforms.rb +189 -0
  240. data/test/xml/node/test_save_options.rb +20 -0
  241. data/test/xml/node/test_subclass.rb +44 -0
  242. data/test/xml/sax/test_parser.rb +338 -0
  243. data/test/xml/sax/test_parser_context.rb +113 -0
  244. data/test/xml/sax/test_push_parser.rb +156 -0
  245. data/test/xml/test_attr.rb +65 -0
  246. data/test/xml/test_attribute_decl.rb +86 -0
  247. data/test/xml/test_builder.rb +210 -0
  248. data/test/xml/test_cdata.rb +50 -0
  249. data/test/xml/test_comment.rb +29 -0
  250. data/test/xml/test_document.rb +675 -0
  251. data/test/xml/test_document_encoding.rb +26 -0
  252. data/test/xml/test_document_fragment.rb +192 -0
  253. data/test/xml/test_dtd.rb +107 -0
  254. data/test/xml/test_dtd_encoding.rb +33 -0
  255. data/test/xml/test_element_content.rb +56 -0
  256. data/test/xml/test_element_decl.rb +73 -0
  257. data/test/xml/test_entity_decl.rb +122 -0
  258. data/test/xml/test_entity_reference.rb +21 -0
  259. data/test/xml/test_namespace.rb +70 -0
  260. data/test/xml/test_node.rb +899 -0
  261. data/test/xml/test_node_attributes.rb +34 -0
  262. data/test/xml/test_node_encoding.rb +107 -0
  263. data/test/xml/test_node_reparenting.rb +321 -0
  264. data/test/xml/test_node_set.rb +708 -0
  265. data/test/xml/test_parse_options.rb +52 -0
  266. data/test/xml/test_processing_instruction.rb +30 -0
  267. data/test/xml/test_reader_encoding.rb +126 -0
  268. data/test/xml/test_relax_ng.rb +60 -0
  269. data/test/xml/test_schema.rb +89 -0
  270. data/test/xml/test_syntax_error.rb +12 -0
  271. data/test/xml/test_text.rb +47 -0
  272. data/test/xml/test_unparented_node.rb +381 -0
  273. data/test/xml/test_xpath.rb +237 -0
  274. data/test/xslt/test_custom_functions.rb +94 -0
  275. metadata +525 -0
@@ -0,0 +1,514 @@
1
+ /**
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008 - 2010:
5
+ *
6
+ * * {Aaron Patterson}[http://tenderlovemaking.com]
7
+ * * {Mike Dalessio}[http://mike.daless.io]
8
+ * * {Charles Nutter}[http://blog.headius.com]
9
+ * * {Sergio Arbeo}[http://www.serabe.com]
10
+ * * {Patrick Mahoney}[http://polycrystal.org]
11
+ * * {Yoko Harada}[http://yokolet.blogspot.com]
12
+ *
13
+ * Permission is hereby granted, free of charge, to any person obtaining
14
+ * a copy of this software and associated documentation files (the
15
+ * 'Software'), to deal in the Software without restriction, including
16
+ * without limitation the rights to use, copy, modify, merge, publish,
17
+ * distribute, sublicense, and/or sell copies of the Software, and to
18
+ * permit persons to whom the Software is furnished to do so, subject to
19
+ * the following conditions:
20
+ *
21
+ * The above copyright notice and this permission notice shall be
22
+ * included in all copies or substantial portions of the Software.
23
+ *
24
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ */
32
+
33
+ package nokogiri;
34
+
35
+ import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
36
+ import static nokogiri.internals.NokogiriHelpers.getLocalNameForNamespace;
37
+ import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
38
+ import static nokogiri.internals.NokogiriHelpers.isNamespace;
39
+ import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
40
+ import static nokogiri.internals.NokogiriHelpers.stringOrNil;
41
+
42
+ import javax.xml.parsers.DocumentBuilderFactory;
43
+ import javax.xml.parsers.ParserConfigurationException;
44
+
45
+ import nokogiri.internals.NokogiriHelpers;
46
+ import nokogiri.internals.NokogiriNamespaceCache;
47
+ import nokogiri.internals.SaveContext;
48
+ import nokogiri.internals.XmlDomParserContext;
49
+
50
+ import org.jruby.Ruby;
51
+ import org.jruby.RubyClass;
52
+ import org.jruby.RubyFixnum;
53
+ import org.jruby.RubyNil;
54
+ import org.jruby.anno.JRubyClass;
55
+ import org.jruby.anno.JRubyMethod;
56
+ import org.jruby.javasupport.util.RuntimeHelpers;
57
+ import org.jruby.runtime.Arity;
58
+ import org.jruby.runtime.ThreadContext;
59
+ import org.jruby.runtime.builtin.IRubyObject;
60
+ import org.w3c.dom.Attr;
61
+ import org.w3c.dom.Document;
62
+ import org.w3c.dom.NamedNodeMap;
63
+ import org.w3c.dom.Node;
64
+ import org.w3c.dom.NodeList;
65
+
66
+ /**
67
+ * Class for Nokogiri::XML::Document
68
+ *
69
+ */
70
+
71
+ @JRubyClass(name="Nokogiri::XML::Document", parent="Nokogiri::XML::Node")
72
+ public class XmlDocument extends XmlNode {
73
+ private NokogiriNamespaceCache nsCache;
74
+
75
+ /* UserData keys for storing extra info in the document node. */
76
+ public final static String DTD_RAW_DOCUMENT = "DTD_RAW_DOCUMENT";
77
+ protected final static String DTD_INTERNAL_SUBSET = "DTD_INTERNAL_SUBSET";
78
+ protected final static String DTD_EXTERNAL_SUBSET = "DTD_EXTERNAL_SUBSET";
79
+
80
+ private static boolean substituteEntities = false;
81
+ private static boolean loadExternalSubset = false; // TODO: Verify this.
82
+
83
+ /** cache variables */
84
+ protected IRubyObject encoding = null;
85
+ protected IRubyObject url = null;
86
+
87
+ public XmlDocument(Ruby ruby, RubyClass klazz) {
88
+ super(ruby, klazz, createNewDocument());
89
+ nsCache = new NokogiriNamespaceCache();
90
+ }
91
+
92
+ public XmlDocument(Ruby ruby, Document document) {
93
+ this(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Document"), document);
94
+ }
95
+
96
+ public XmlDocument(Ruby ruby, RubyClass klass, Document document) {
97
+ super(ruby, klass, document);
98
+ nsCache = new NokogiriNamespaceCache();
99
+ createAndCacheNamespaces(ruby, document.getDocumentElement());
100
+ stabilizeTextContent(document);
101
+ setInstanceVariable("@decorators", ruby.getNil());
102
+ }
103
+
104
+ @Override
105
+ public void setNode(ThreadContext context, Node node) {
106
+ super.setNode(context, node);
107
+ Ruby runtime = context.getRuntime();
108
+ if (node != null) {
109
+ Document document = (Document)node;
110
+ stabilizeTextContent(document);
111
+ createAndCacheNamespaces(runtime, document.getDocumentElement());
112
+ }
113
+ setInstanceVariable("@decorators", runtime.getNil());
114
+ }
115
+
116
+ public void setEncoding(IRubyObject encoding) {
117
+ this.encoding = encoding;
118
+ }
119
+
120
+ // not sure, but like attribute values, text value will be lost
121
+ // unless it is referred once before this document is used.
122
+ // this seems to happen only when the fragment is parsed from Node#in_context.
123
+ private void stabilizeTextContent(Document document) {
124
+ if (document.getDocumentElement() != null) document.getDocumentElement().getTextContent();
125
+ }
126
+
127
+ private void createAndCacheNamespaces(Ruby ruby, Node node) {
128
+ if (node == null) return;
129
+ if (node.hasAttributes()) {
130
+ NamedNodeMap nodeMap = node.getAttributes();
131
+ for (int i=0; i<nodeMap.getLength(); i++) {
132
+ Node n = nodeMap.item(i);
133
+ if (n instanceof Attr) {
134
+ Attr attr = (Attr)n;
135
+ String attrName = attr.getName();
136
+ // not sure, but need to get value always before document is referred.
137
+ // or lose attribute value
138
+ String attrValue = attr.getValue();
139
+ if (isNamespace(attrName)) {
140
+ String prefix = getLocalNameForNamespace(attrName);
141
+ prefix = prefix != null ? prefix : "";
142
+ nsCache.put(ruby, prefix, attrValue, node, this);
143
+ }
144
+ }
145
+ }
146
+ }
147
+ NodeList children = node.getChildNodes();
148
+ for (int i=0; i<children.getLength(); i++) {
149
+ createAndCacheNamespaces(ruby, children.item(i));
150
+ }
151
+ }
152
+
153
+ // When a document is created from fragment with a context (reference) document,
154
+ // namespace should be resolved based on the context document.
155
+ public XmlDocument(Ruby ruby, RubyClass klass, Document document, XmlDocument contextDoc) {
156
+ super(ruby, klass, document);
157
+ nsCache = contextDoc.getNamespaceCache();
158
+ XmlNamespace default_ns = nsCache.getDefault();
159
+ String default_href = rubyStringToString(default_ns.href(ruby.getCurrentContext()));
160
+ resolveNamespaceIfNecessary(ruby.getCurrentContext(), document.getDocumentElement(), default_href);
161
+ }
162
+
163
+ private void resolveNamespaceIfNecessary(ThreadContext context, Node node, String default_href) {
164
+ if (node == null) return;
165
+ String nodePrefix = node.getPrefix();
166
+ if (nodePrefix == null) { // default namespace
167
+ node.getOwnerDocument().renameNode(node, default_href, node.getNodeName());
168
+ } else {
169
+ XmlNamespace xmlNamespace = nsCache.get(nodePrefix);
170
+ String href = rubyStringToString(xmlNamespace.href(context));
171
+ node.getOwnerDocument().renameNode(node, href, node.getNodeName());
172
+ }
173
+ resolveNamespaceIfNecessary(context, node.getNextSibling(), default_href);
174
+ NodeList children = node.getChildNodes();
175
+ for (int i=0; i<children.getLength(); i++) {
176
+ resolveNamespaceIfNecessary(context, children.item(i), default_href);
177
+ }
178
+ }
179
+
180
+ public NokogiriNamespaceCache getNamespaceCache() {
181
+ return nsCache;
182
+ }
183
+
184
+ public void setNamespaceCache(NokogiriNamespaceCache nsCache) {
185
+ this.nsCache = nsCache;
186
+ }
187
+
188
+ public Document getDocument() {
189
+ return (Document) node;
190
+ }
191
+
192
+ @Override
193
+ protected IRubyObject getNodeName(ThreadContext context) {
194
+ if (name == null) name = context.getRuntime().newString("document");
195
+ return name;
196
+ }
197
+
198
+ public void setUrl(IRubyObject url) {
199
+ this.url = url;
200
+ }
201
+
202
+ protected IRubyObject getUrl() {
203
+ return this.url;
204
+ }
205
+
206
+ @JRubyMethod
207
+ public IRubyObject url(ThreadContext context) {
208
+ return getUrl();
209
+ }
210
+
211
+ protected static Document createNewDocument() {
212
+ try {
213
+ return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
214
+ } catch (ParserConfigurationException e) {
215
+ return null; // this will end is disaster...
216
+ }
217
+ }
218
+
219
+ /*
220
+ * call-seq:
221
+ * new(version = default)
222
+ *
223
+ * Create a new document with +version+ (defaults to "1.0")
224
+ */
225
+ @JRubyMethod(name="new", meta = true, rest = true, required=0)
226
+ public static IRubyObject rbNew(ThreadContext context, IRubyObject cls, IRubyObject[] args) {
227
+ XmlDocument doc = null;
228
+ try {
229
+ Document docNode = createNewDocument();
230
+ doc = new XmlDocument(context.getRuntime(), (RubyClass) cls, docNode);
231
+ } catch (Exception ex) {
232
+ throw context.getRuntime().newRuntimeError("couldn't create document: "+ex.toString());
233
+ }
234
+
235
+ RuntimeHelpers.invoke(context, doc, "initialize", args);
236
+
237
+ return doc;
238
+ }
239
+
240
+ @JRubyMethod(required=1, optional=4)
241
+ public IRubyObject create_entity(ThreadContext context, IRubyObject[] argv) {
242
+ // FIXME: Entity node should be create by some right way.
243
+ // this impl passes tests, but entity doesn't exists in DTD, which
244
+ // would cause validation failure.
245
+ if (argv.length == 0) throw context.getRuntime().newRuntimeError("Could not create entity");
246
+ String tagName = rubyStringToString(argv[0]);
247
+ Node n = this.getOwnerDocument().createElement(tagName);
248
+ return XmlEntityDecl.create(context, n, argv);
249
+ }
250
+
251
+ @Override
252
+ @JRubyMethod
253
+ public IRubyObject document(ThreadContext context) {
254
+ return this;
255
+ }
256
+
257
+ @JRubyMethod(name="encoding=")
258
+ public IRubyObject encoding_set(ThreadContext context, IRubyObject encoding) {
259
+ this.encoding = encoding;
260
+ return this;
261
+ }
262
+
263
+ @JRubyMethod
264
+ public IRubyObject encoding(ThreadContext context) {
265
+ if (this.encoding == null) {
266
+ if (getDocument().getXmlEncoding() == null) {
267
+ this.encoding = context.getRuntime().getNil();
268
+ } else {
269
+ this.encoding = context.getRuntime().newString(getDocument().getXmlEncoding());
270
+ }
271
+ }
272
+
273
+ return this.encoding;
274
+ }
275
+
276
+ @JRubyMethod(meta = true)
277
+ public static IRubyObject load_external_subsets_set(ThreadContext context, IRubyObject cls, IRubyObject value) {
278
+ XmlDocument.loadExternalSubset = value.isTrue();
279
+ return context.getRuntime().getNil();
280
+ }
281
+
282
+ /**
283
+ * TODO: handle encoding?
284
+ *
285
+ * @param args[0] a Ruby IO or StringIO
286
+ * @param args[1] url or nil
287
+ * @param args[2] encoding
288
+ * @param args[3] bitset of parser options
289
+ */
290
+ public static IRubyObject newFromData(ThreadContext context,
291
+ IRubyObject klass,
292
+ IRubyObject[] args) {
293
+ Ruby ruby = context.getRuntime();
294
+ Arity.checkArgumentCount(ruby, args, 4, 4);
295
+ XmlDomParserContext ctx =
296
+ new XmlDomParserContext(ruby, args[2], args[3]);
297
+ ctx.setInputSource(context, args[0]);
298
+ return ctx.parse(context, klass, args[1]);
299
+ }
300
+
301
+ @JRubyMethod(meta = true, rest = true)
302
+ public static IRubyObject read_io(ThreadContext context,
303
+ IRubyObject klass,
304
+ IRubyObject[] args) {
305
+ return newFromData(context, klass, args);
306
+ }
307
+
308
+ @JRubyMethod(meta = true, rest = true)
309
+ public static IRubyObject read_memory(ThreadContext context,
310
+ IRubyObject klass,
311
+ IRubyObject[] args) {
312
+ return newFromData(context, klass, args);
313
+ }
314
+
315
+ /** not a JRubyMethod */
316
+ public static IRubyObject read_memory(ThreadContext context,
317
+ IRubyObject[] args) {
318
+ return read_memory(context,
319
+ getNokogiriClass(context.getRuntime(), "Nokogiri::XML::Document"),
320
+ args);
321
+ }
322
+
323
+ @JRubyMethod(name="remove_namespaces!")
324
+ public IRubyObject remove_namespaces(ThreadContext context) {
325
+ removeNamespceRecursively(context, this);
326
+ nsCache.clear();
327
+ return this;
328
+ }
329
+
330
+ private void removeNamespceRecursively(ThreadContext context, XmlNode xmlNode) {
331
+ Node node = xmlNode.node;
332
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
333
+ node.setPrefix(null);
334
+ node.getOwnerDocument().renameNode(node, null, node.getLocalName());
335
+ NamedNodeMap attrs = node.getAttributes();
336
+ for (int i=0; i<attrs.getLength(); i++) {
337
+ Node attr = attrs.item(i);
338
+ attr.setPrefix(null);
339
+ attr.getOwnerDocument().renameNode(attr, null, attr.getLocalName());
340
+ }
341
+ }
342
+ XmlNodeSet nodeSet = (XmlNodeSet) xmlNode.children(context);
343
+ for (long i=0; i < nodeSet.length(); i++) {
344
+ XmlNode childNode = (XmlNode)nodeSet.slice(context, RubyFixnum.newFixnum(context.getRuntime(), i));
345
+ removeNamespceRecursively(context, childNode);
346
+ }
347
+ }
348
+
349
+ @JRubyMethod
350
+ public IRubyObject root(ThreadContext context) {
351
+ Node rootNode = getDocument().getDocumentElement();
352
+ try {
353
+ Boolean isValid = (Boolean)rootNode.getUserData(NokogiriHelpers.VALID_ROOT_NODE);
354
+ if (!isValid) return context.getRuntime().getNil();
355
+ } catch (NullPointerException e) {
356
+ // does nothing since nil wasn't set to the root node before.
357
+ }
358
+ if (rootNode == null)
359
+ return context.getRuntime().getNil();
360
+ else
361
+ return getCachedNodeOrCreate(context.getRuntime(), rootNode);
362
+ }
363
+
364
+ @JRubyMethod(name="root=")
365
+ public IRubyObject root_set(ThreadContext context, IRubyObject newRoot_) {
366
+ // in case of document fragment, temporary root node should be deleted.
367
+
368
+ // Java can't have a root whose value is null. Instead of setting null,
369
+ // the method sets user data so that other methods are able to know the root
370
+ // should be nil.
371
+ if (newRoot_ instanceof RubyNil) {
372
+ getDocument().getDocumentElement().setUserData(NokogiriHelpers.VALID_ROOT_NODE, false, null);
373
+ return newRoot_;
374
+ }
375
+ XmlNode newRoot = asXmlNode(context, newRoot_);
376
+
377
+ IRubyObject root = root(context);
378
+ if (root.isNil()) {
379
+ Node newRootNode;
380
+ if (getDocument() == newRoot.getOwnerDocument()) {
381
+ newRootNode = newRoot.node;
382
+ } else {
383
+ // must copy otherwise newRoot may exist in two places
384
+ // with different owner document.
385
+ newRootNode = getDocument().importNode(newRoot.node, true);
386
+ }
387
+ add_child_node(context, getCachedNodeOrCreate(context.getRuntime(), newRootNode));
388
+ } else {
389
+ Node rootNode = asXmlNode(context, root).node;
390
+ ((XmlNode)getCachedNodeOrCreate(context.getRuntime(), rootNode)).replace_node(context, newRoot);
391
+ }
392
+
393
+ return newRoot;
394
+ }
395
+
396
+ @JRubyMethod
397
+ public IRubyObject version(ThreadContext context) {
398
+ return stringOrNil(context.getRuntime(), getDocument().getXmlVersion());
399
+ }
400
+
401
+ @JRubyMethod(meta = true)
402
+ public static IRubyObject substitute_entities_set(ThreadContext context, IRubyObject cls, IRubyObject value) {
403
+ XmlDocument.substituteEntities = value.isTrue();
404
+ return context.getRuntime().getNil();
405
+ }
406
+
407
+ public IRubyObject getInternalSubset(ThreadContext context) {
408
+ IRubyObject dtd =
409
+ (IRubyObject) node.getUserData(DTD_INTERNAL_SUBSET);
410
+
411
+ if (dtd == null) {
412
+ if (getDocument().getDoctype() == null)
413
+ dtd = context.getRuntime().getNil();
414
+ else
415
+ dtd = XmlDtd.newFromInternalSubset(context.getRuntime(),
416
+ getDocument());
417
+
418
+ setInternalSubset(dtd);
419
+ }
420
+
421
+ return dtd;
422
+ }
423
+
424
+ /**
425
+ * Assumes XmlNode#internal_subset() has returned nil. (i.e. there
426
+ * is not already an internal subset).
427
+ */
428
+ public IRubyObject createInternalSubset(ThreadContext context,
429
+ IRubyObject name,
430
+ IRubyObject external_id,
431
+ IRubyObject system_id) {
432
+ XmlDtd dtd = XmlDtd.newEmpty(context.getRuntime(),
433
+ this.getDocument(),
434
+ name, external_id, system_id);
435
+ setInternalSubset(dtd);
436
+ return dtd;
437
+ }
438
+
439
+ protected void setInternalSubset(IRubyObject data) {
440
+ node.setUserData(DTD_INTERNAL_SUBSET, data, null);
441
+ }
442
+
443
+ public IRubyObject getExternalSubset(ThreadContext context) {
444
+ IRubyObject dtd = (IRubyObject)
445
+ node.getUserData(DTD_EXTERNAL_SUBSET);
446
+
447
+ if (dtd == null) {
448
+ dtd = XmlDtd.newFromExternalSubset(context.getRuntime(),
449
+ getDocument());
450
+ setExternalSubset(dtd);
451
+ }
452
+
453
+ return dtd;
454
+ }
455
+
456
+ /**
457
+ * Assumes XmlNode#external_subset() has returned nil. (i.e. there
458
+ * is not already an external subset).
459
+ */
460
+ public IRubyObject createExternalSubset(ThreadContext context,
461
+ IRubyObject name,
462
+ IRubyObject external_id,
463
+ IRubyObject system_id) {
464
+ XmlDtd dtd = XmlDtd.newEmpty(context.getRuntime(),
465
+ this.getDocument(),
466
+ name, external_id, system_id);
467
+ setExternalSubset(dtd);
468
+ return dtd;
469
+ }
470
+
471
+ protected void setExternalSubset(IRubyObject data) {
472
+ node.setUserData(DTD_EXTERNAL_SUBSET, data, null);
473
+ }
474
+
475
+ //public IRubyObject createE
476
+
477
+ @Override
478
+ public void saveContent(ThreadContext context, SaveContext ctx) {
479
+ if(!ctx.noDecl()) {
480
+ ctx.append("<?xml version=\"");
481
+ ctx.append(getDocument().getXmlVersion());
482
+ ctx.append("\"");
483
+ // if(!cur.encoding(context).isNil()) {
484
+ // ctx.append(" encoding=");
485
+ // ctx.append(cur.encoding(context).asJavaString());
486
+ // }
487
+
488
+ String encoding = ctx.getEncoding();
489
+
490
+ if(encoding == null &&
491
+ !encoding(context).isNil()) {
492
+ encoding = encoding(context).convertToString().asJavaString();
493
+ }
494
+
495
+ if(encoding != null) {
496
+ ctx.append(" encoding=\"");
497
+ ctx.append(encoding);
498
+ ctx.append("\"");
499
+ }
500
+
501
+ //ctx.append(" standalone=\"");
502
+ //ctx.append(getDocument().getXmlStandalone() ? "yes" : "no");
503
+ ctx.append("?>\n");
504
+ }
505
+
506
+ IRubyObject maybeRoot = root(context);
507
+ if (maybeRoot.isNil())
508
+ throw context.getRuntime().newRuntimeError("no root document");
509
+
510
+ XmlNode root = (XmlNode) maybeRoot;
511
+ root.saveContent(context, ctx);
512
+ ctx.append("\n");
513
+ }
514
+ }