nokogiri 1.5.0.beta.4-java → 1.5.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 (87) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGELOG.ja.rdoc +34 -0
  3. data/CHANGELOG.rdoc +40 -1
  4. data/Manifest.txt +11 -2
  5. data/README.rdoc +1 -1
  6. data/Rakefile +96 -105
  7. data/bin/nokogiri +1 -2
  8. data/ext/java/nokogiri/HtmlDocument.java +1 -31
  9. data/ext/java/nokogiri/HtmlSaxParserContext.java +1 -1
  10. data/ext/java/nokogiri/NokogiriService.java +77 -22
  11. data/ext/java/nokogiri/XmlAttr.java +5 -16
  12. data/ext/java/nokogiri/XmlCdata.java +4 -11
  13. data/ext/java/nokogiri/XmlComment.java +5 -5
  14. data/ext/java/nokogiri/XmlDocument.java +49 -59
  15. data/ext/java/nokogiri/XmlDocumentFragment.java +14 -8
  16. data/ext/java/nokogiri/XmlDtd.java +45 -43
  17. data/ext/java/nokogiri/XmlElement.java +19 -46
  18. data/ext/java/nokogiri/XmlElementDecl.java +9 -5
  19. data/ext/java/nokogiri/XmlEntityReference.java +24 -2
  20. data/ext/java/nokogiri/XmlNamespace.java +89 -34
  21. data/ext/java/nokogiri/XmlNode.java +31 -52
  22. data/ext/java/nokogiri/XmlNodeSet.java +42 -86
  23. data/ext/java/nokogiri/XmlProcessingInstruction.java +15 -19
  24. data/ext/java/nokogiri/XmlReader.java +40 -43
  25. data/ext/java/nokogiri/XmlSaxParserContext.java +2 -2
  26. data/ext/java/nokogiri/XmlSchema.java +14 -9
  27. data/ext/java/nokogiri/XmlText.java +18 -35
  28. data/ext/java/nokogiri/XmlXpathContext.java +43 -23
  29. data/ext/java/nokogiri/XsltStylesheet.java +17 -3
  30. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +2 -4
  31. data/ext/java/nokogiri/internals/NokogiriHelpers.java +77 -20
  32. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +13 -17
  33. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +13 -1
  34. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +23 -8
  35. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +20 -3
  36. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +67 -0
  37. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +86 -0
  38. data/ext/java/nokogiri/internals/ParserContext.java +25 -27
  39. data/ext/java/nokogiri/internals/ReaderNode.java +58 -1
  40. data/ext/java/nokogiri/internals/SaveContextVisitor.java +567 -0
  41. data/ext/java/nokogiri/internals/XmlDomParser.java +1 -2
  42. data/ext/java/nokogiri/internals/XmlDomParserContext.java +6 -0
  43. data/ext/nokogiri/nokogiri.c +24 -1
  44. data/ext/nokogiri/xml_io.c +32 -7
  45. data/ext/nokogiri/xml_node.c +14 -13
  46. data/ext/nokogiri/xml_sax_parser.c +9 -4
  47. data/ext/nokogiri/xslt_stylesheet.c +7 -1
  48. data/lib/nokogiri.rb +3 -22
  49. data/lib/nokogiri/css.rb +4 -0
  50. data/lib/nokogiri/html/document.rb +10 -14
  51. data/lib/nokogiri/nokogiri.jar +0 -0
  52. data/lib/nokogiri/version.rb +76 -23
  53. data/lib/nokogiri/xml/builder.rb +7 -0
  54. data/lib/nokogiri/xml/document.rb +17 -1
  55. data/lib/nokogiri/xml/document_fragment.rb +14 -0
  56. data/lib/nokogiri/xml/node.rb +36 -28
  57. data/lib/nokogiri/xml/node/save_options.rb +17 -1
  58. data/lib/nokogiri/xml/node_set.rb +7 -0
  59. data/lib/nokogiri/xml/parse_options.rb +8 -0
  60. data/lib/nokogiri/xml/reader.rb +6 -6
  61. data/lib/nokogiri/xml/schema.rb +7 -1
  62. data/lib/xercesImpl.jar +0 -0
  63. data/nokogiri_help_responses.md +40 -0
  64. data/tasks/cross_compile.rb +134 -159
  65. data/tasks/nokogiri.org.rb +18 -0
  66. data/tasks/test.rb +1 -1
  67. data/test/files/encoding.html +82 -0
  68. data/test/files/encoding.xhtml +84 -0
  69. data/test/files/metacharset.html +10 -0
  70. data/test/files/noencoding.html +47 -0
  71. data/test/helper.rb +2 -0
  72. data/test/html/test_document.rb +15 -0
  73. data/test/html/test_document_encoding.rb +13 -0
  74. data/test/test_memory_leak.rb +20 -0
  75. data/test/test_reader.rb +22 -0
  76. data/test/test_xslt_transforms.rb +6 -2
  77. data/test/xml/node/test_save_options.rb +10 -2
  78. data/test/xml/test_builder.rb +17 -0
  79. data/test/xml/test_document.rb +22 -0
  80. data/test/xml/test_node.rb +19 -1
  81. data/test/xml/test_node_reparenting.rb +16 -3
  82. data/test/xml/test_node_set.rb +34 -0
  83. data/test/xml/test_schema.rb +5 -0
  84. data/test/xslt/test_exception_handling.rb +37 -0
  85. metadata +141 -107
  86. data/deps.rip +0 -5
  87. data/ext/java/nokogiri/internals/SaveContext.java +0 -288
@@ -57,6 +57,7 @@ import org.w3c.dom.Document;
57
57
  * Parser for HtmlDocument. This class actually parses HtmlDocument using NekoHtml.
58
58
  *
59
59
  * @author sergio
60
+ * @author Patrick Mahoney <pat@polycrystal.org>
60
61
  * @author Yoko Harada <yokolet@gmail.com>
61
62
  */
62
63
  public class HtmlDomParserContext extends XmlDomParserContext {
@@ -92,9 +93,9 @@ public class HtmlDomParserContext extends XmlDomParserContext {
92
93
  setProperty("http://cyberneko.org/html/properties/default-encoding", java_encoding);
93
94
  setProperty("http://cyberneko.org/html/properties/names/elems", "lower");
94
95
  setProperty("http://cyberneko.org/html/properties/names/attrs", "lower");
96
+ setProperty("http://cyberneko.org/html/properties/filters", filters);
95
97
  setFeature("http://cyberneko.org/html/features/report-errors", true);
96
98
  setFeature("http://xml.org/sax/features/namespaces", false);
97
- setProperty("http://cyberneko.org/html/properties/filters", filters);
98
99
  setFeature("http://cyberneko.org/html/features/insert-doctype", true);
99
100
  }
100
101
 
@@ -125,9 +126,6 @@ public class HtmlDomParserContext extends XmlDomParserContext {
125
126
 
126
127
  /**
127
128
  * Filter to strip out attributes that pertain to XML namespaces.
128
- *
129
- * @author sergio
130
- * @author Patrick Mahoney <pat@polycrystal.org>
131
129
  */
132
130
  public static class RemoveNSAttrsFilter extends DefaultFilter {
133
131
  @Override
@@ -32,18 +32,24 @@
32
32
 
33
33
  package nokogiri.internals;
34
34
 
35
+ import java.io.File;
35
36
  import java.io.UnsupportedEncodingException;
36
37
  import java.nio.ByteBuffer;
37
38
  import java.nio.charset.Charset;
39
+ import java.util.regex.Matcher;
40
+ import java.util.regex.Pattern;
38
41
 
39
42
  import nokogiri.NokogiriService;
40
43
  import nokogiri.XmlAttr;
41
44
  import nokogiri.XmlCdata;
42
45
  import nokogiri.XmlComment;
43
46
  import nokogiri.XmlDocument;
47
+ import nokogiri.XmlDtd;
44
48
  import nokogiri.XmlElement;
49
+ import nokogiri.XmlEntityReference;
45
50
  import nokogiri.XmlNamespace;
46
51
  import nokogiri.XmlNode;
52
+ import nokogiri.XmlProcessingInstruction;
47
53
  import nokogiri.XmlText;
48
54
 
49
55
  import org.jruby.Ruby;
@@ -87,9 +93,8 @@ public class NokogiriHelpers {
87
93
  prefix = prefix != null ? prefix : "";
88
94
  String href = ((Attr)node).getValue();
89
95
  XmlNamespace xmlNamespace = xmlDocument.getNamespaceCache().get(prefix, href);
90
- if (xmlNamespace == null) {
91
- return xmlDocument.getNamespaceCache().put(ruby, prefix, ((Attr)node).getValue(), node, xmlDocument);
92
- }
96
+ if (xmlNamespace != null) return xmlNamespace;
97
+ else return XmlNamespace.createFromAttr(ruby, (Attr)node);
93
98
  }
94
99
  XmlNode xmlNode = getCachedNode(node);
95
100
  if(xmlNode == null) {
@@ -126,6 +131,14 @@ public class NokogiriHelpers {
126
131
  return xmlComment;
127
132
  case Node.ENTITY_NODE:
128
133
  return new XmlNode(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityDecl"), node);
134
+ case Node.ENTITY_REFERENCE_NODE:
135
+ XmlEntityReference xmlEntityRef = (XmlEntityReference) NokogiriService.XML_ENTITY_REFERENCE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityReference"));
136
+ xmlEntityRef.setNode(runtime.getCurrentContext(), node);
137
+ return xmlEntityRef;
138
+ case Node.PROCESSING_INSTRUCTION_NODE:
139
+ XmlProcessingInstruction xmlProcessingInstruction = (XmlProcessingInstruction) NokogiriService.XML_PROCESSING_INSTRUCTION_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::ProcessingInstruction"));
140
+ xmlProcessingInstruction.setNode(runtime.getCurrentContext(), node);
141
+ return xmlProcessingInstruction;
129
142
  case Node.CDATA_SECTION_NODE:
130
143
  XmlCdata xmlCdata = (XmlCdata) NokogiriService.XML_CDATA_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::CDATA"));
131
144
  xmlCdata.setNode(runtime.getCurrentContext(), node);
@@ -134,6 +147,10 @@ public class NokogiriHelpers {
134
147
  XmlDocument xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Document"));
135
148
  xmlDocument.setNode(runtime.getCurrentContext(), node);
136
149
  return xmlDocument;
150
+ case Node.DOCUMENT_TYPE_NODE:
151
+ XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
152
+ xmlDtd.setNode(runtime, node);
153
+ return xmlDtd;
137
154
  default:
138
155
  XmlNode xmlNode = (XmlNode) NokogiriService.XML_NODE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Node"));
139
156
  xmlNode.setNode(runtime.getCurrentContext(), node);
@@ -481,28 +498,44 @@ public class NokogiriHelpers {
481
498
  (b.equals(a)));
482
499
  }
483
500
 
501
+ private static Pattern encoded_pattern = Pattern.compile("&amp;|&gt;|&lt;|&#13;");
502
+ private static Pattern decoded_pattern = Pattern.compile("&|>|<|\r");
503
+ private static String[] encoded = {"&amp;", "&gt;", "&lt;", "&#13;"};
504
+ private static String[] decoded = {"&", ">", "<", "\r"};
505
+
506
+ private static String convert(Pattern ptn, String input, String[] oldChars, String[] newChars) {
507
+ Matcher matcher = ptn.matcher(input);
508
+ boolean result = matcher.find();
509
+ StringBuffer sb = new StringBuffer();
510
+ while(result) {
511
+ String matched = matcher.group();
512
+ String replacement = "";
513
+ for (int i=0; i<oldChars.length; i++) {
514
+ if (matched.contains(oldChars[i])) {
515
+ replacement = matched.replace(oldChars[i], newChars[i]);
516
+ break;
517
+ }
518
+ }
519
+ matcher.appendReplacement(sb, replacement);
520
+ result = matcher.find();
521
+ }
522
+ matcher.appendTail(sb);
523
+ return sb.toString();
524
+ }
525
+
484
526
  public static String encodeJavaString(String s) {
485
-
486
- // From entities.c
487
- s = s.replaceAll("&", "&amp;");
488
- s = s.replaceAll("<", "&lt;");
489
- s = s.replaceAll(">", "&gt;");
490
- // s = s.replaceAll("\"", "&quot;");
491
- return s.replaceAll("\r", "&#13;");
527
+ return convert(decoded_pattern, s, decoded, encoded);
492
528
  }
493
529
 
494
530
  public static String decodeJavaString(String s) {
495
- s = s.replaceAll("&amp;", "&");
496
- s = s.replaceAll("&lt;", "<");
497
- s = s.replaceAll("&gt;", ">");
498
- return s.replaceAll("&#13;", "\r");
531
+ return convert(encoded_pattern, s, encoded, decoded);
499
532
  }
500
-
501
- public static boolean isXmlEscaped(String s) {
502
- if (s == null) return true;
503
- if (s.contains("<") || s.contains(">") || s.contains("\r")) return false;
504
- if (s.contains("&") && !s.contains("&amp;")) return false;
505
- return true;
533
+
534
+ private static Pattern not_escaped_pattern = Pattern.compile("\\&(?!(amp;|gt;|lt;))|<|>");
535
+ public static boolean isNotXmlEscaped(String s) {
536
+ if (s == null) return false;
537
+ Matcher matcher = not_escaped_pattern.matcher(s);
538
+ return (matcher.find());
506
539
  }
507
540
 
508
541
  public static String getNodeName(Node node) {
@@ -579,4 +612,28 @@ public class NokogiriHelpers {
579
612
  if (name == null) name = "UTF-8";
580
613
  return name;
581
614
  }
615
+
616
+ public static String adjustSystemIdIfNecessary(String currentDir, String scriptFileName, String baseURI, String systemId) {
617
+ if (systemId == null) return systemId;
618
+ File file = new File(systemId);
619
+ if (file.isAbsolute()) return systemId;
620
+ String path = resolveSystemId(baseURI, systemId);
621
+ if (path != null) return path;
622
+ path = resolveSystemId(currentDir, systemId);
623
+ if (path != null) return path;
624
+ return resolveSystemId(scriptFileName, systemId);
625
+ }
626
+
627
+ private static String resolveSystemId(String baseName, String systemId) {
628
+ if (baseName == null || baseName.length() < 1) return null;
629
+ String parentName = null;
630
+ baseName = baseName.replaceAll("%20", " ");
631
+ File base = new File(baseName);
632
+ if (base.isDirectory()) parentName = baseName;
633
+ else parentName = base.getParent();
634
+ if (parentName.toLowerCase().startsWith("file:")) parentName = parentName.substring("file:".length());
635
+ File dtdFile = new File(parentName + "/" + systemId);
636
+ if (dtdFile.exists()) return dtdFile.getPath();
637
+ return null;
638
+ }
582
639
  }
@@ -103,32 +103,28 @@ public class NokogiriNamespaceCache {
103
103
  List<XmlNamespace> namespaces = new ArrayList<XmlNamespace>();
104
104
  for (int i=0; i < keys.size(); i++) {
105
105
  CacheEntry entry = cache.get(i);
106
- if (entry.node == node) {
106
+ if (entry.ownerNode == node) {
107
107
  namespaces.add(entry.namespace);
108
108
  }
109
109
  }
110
110
  return namespaces;
111
111
  }
112
-
113
- public XmlNamespace put(Ruby ruby, String prefix, String href, Node node, XmlDocument document) {
112
+
113
+ public void put(XmlNamespace namespace, Node ownerNode) {
114
114
  // prefix should not be null.
115
115
  // In case of a default namespace, an empty string should be given to prefix argument.
116
- if (prefix == null || href == null) return null;
117
- Long hash = hashCode(prefix, href);
116
+ String prefixString = namespace.getPrefix();
117
+ String hrefString = namespace.getHref();
118
+ Long hash = hashCode(prefixString, hrefString);
118
119
  Integer index;
119
120
  if ((index = keys.indexOf(hash)) != -1) {
120
- return cache.get(index).namespace;
121
+ return;
121
122
  } else {
122
123
  keys.add(hash);
123
124
  index = keys.size() - 1;
124
- String actualPrefix = (prefix.equals("")) ? null : prefix;
125
- XmlNamespace namespace = (XmlNamespace) NokogiriService.XML_NAMESPACE_ALLOCATOR.allocate(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Namespace"));
126
- namespace.setDefinition(ruby, actualPrefix, href);
127
- namespace.setDocument(document);
128
- CacheEntry entry = new CacheEntry(namespace, node);
125
+ CacheEntry entry = new CacheEntry(namespace, ownerNode);
129
126
  cache.put(index, entry);
130
- if ("".equals(prefix)) defaultNamespace = namespace;
131
- return namespace;
127
+ if ("".equals(prefixString)) defaultNamespace = namespace;
132
128
  }
133
129
  }
134
130
 
@@ -146,7 +142,7 @@ public class NokogiriNamespaceCache {
146
142
  // removes namespace declarations from node
147
143
  for (int i=0; i < keys.size(); i++) {
148
144
  CacheEntry entry = cache.get(i);
149
- NamedNodeMap attributes = entry.node.getAttributes();
145
+ NamedNodeMap attributes = entry.ownerNode.getAttributes();
150
146
  for (int j=0; j<attributes.getLength(); j++) {
151
147
  String name = ((Attr)attributes.item(j)).getName();
152
148
  if (isNamespace(name)) {
@@ -161,11 +157,11 @@ public class NokogiriNamespaceCache {
161
157
 
162
158
  private class CacheEntry {
163
159
  private XmlNamespace namespace;
164
- private Node node;
160
+ private Node ownerNode;
165
161
 
166
- CacheEntry(XmlNamespace namespace, Node node) {
162
+ CacheEntry(XmlNamespace namespace, Node ownerNode) {
167
163
  this.namespace = namespace;
168
- this.node = node;
164
+ this.ownerNode = ownerNode;
169
165
  }
170
166
  }
171
167
  }
@@ -50,13 +50,25 @@ import javax.xml.namespace.NamespaceContext;
50
50
  */
51
51
 
52
52
  public class NokogiriNamespaceContext implements NamespaceContext {
53
+ private static NokogiriNamespaceContext namespaceContext;
53
54
  public static final String NOKOGIRI_PREFIX = "nokogiri";
54
55
  public static final String NOKOGIRI_URI = "http://www.nokogiri.org/default_ns/ruby/extensions_functions";
55
56
  public static final String NOKOGIRI_TEMPORARY_ROOT_TAG = "nokogiri-temporary-root-tag";
56
57
 
57
58
  private Hashtable<String,String> register;
58
59
 
59
- public NokogiriNamespaceContext() {
60
+ 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
+ }
69
+ }
70
+
71
+ private NokogiriNamespaceContext() {
60
72
  this.register = new Hashtable<String,String>();
61
73
  register.put(NOKOGIRI_PREFIX, NOKOGIRI_URI);
62
74
  register.put("xml", "http://www.w3.org/XML/1998/namespace");
@@ -61,16 +61,32 @@ import org.w3c.dom.NodeList;
61
61
  * @author Yoko Harada <yokolet@gmail.com>
62
62
  */
63
63
  public class NokogiriXPathFunction implements XPathFunction {
64
- private final IRubyObject handler;
65
- private final String name;
66
- private final int arity;
64
+ private static NokogiriXPathFunction xpathFunction;
65
+ private IRubyObject handler;
66
+ private String name;
67
+ private int arity;
68
+
69
+ 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
+ }
80
+ }
67
81
 
68
- public NokogiriXPathFunction(IRubyObject handler, String name, int arity) {
82
+ private void init(IRubyObject handler, String name, int arity) {
69
83
  this.handler = handler;
70
84
  this.name = name;
71
85
  this.arity = arity;
72
86
  }
73
87
 
88
+ private NokogiriXPathFunction() {}
89
+
74
90
  public Object evaluate(List args) throws XPathFunctionException {
75
91
  if(args.size() != this.arity) {
76
92
  throw new XPathFunctionException("arity does not match");
@@ -114,11 +130,10 @@ public class NokogiriXPathFunction implements XPathFunction {
114
130
  } else if (o instanceof RubyBoolean) {
115
131
  return o.toJava(Boolean.class);
116
132
  } else if (o instanceof XmlNodeSet) {
117
- return ((XmlNodeSet) o).toNodeList(runtime);
133
+ return (NodeList)o;
118
134
  } else if (o instanceof RubyArray) {
119
- XmlNodeSet xmlNodeSet = (XmlNodeSet)NokogiriService.XML_NODESET_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::NodeSet"));
120
- xmlNodeSet.setInitialNodes((RubyArray)o);
121
- return xmlNodeSet.toNodeList(runtime);
135
+ XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(runtime.getCurrentContext(), (RubyArray)o);
136
+ return (NodeList)xmlNodeSet;
122
137
  } else /*if (o instanceof XmlNode)*/ {
123
138
  return ((XmlNode) o).getNode();
124
139
  }
@@ -35,22 +35,39 @@ package nokogiri.internals;
35
35
  import javax.xml.namespace.QName;
36
36
  import javax.xml.xpath.XPathFunction;
37
37
  import javax.xml.xpath.XPathFunctionResolver;
38
+
38
39
  import org.jruby.runtime.builtin.IRubyObject;
39
40
 
40
41
  /**
41
42
  * Xpath function resolver class, which is used in XmlXpathContext.
42
43
  *
43
44
  * @author sergio
45
+ * @author Yoko Harada <yokolet@gmail.com>
44
46
  */
45
47
  public class NokogiriXPathFunctionResolver implements XPathFunctionResolver {
46
-
48
+ private static NokogiriXPathFunctionResolver resolver;
47
49
  private IRubyObject handler;
48
50
 
49
- public NokogiriXPathFunctionResolver(IRubyObject handler) {
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
+ }
62
+ }
63
+
64
+ private NokogiriXPathFunctionResolver() {}
65
+
66
+ private void setHandler(IRubyObject handler) {
50
67
  this.handler = handler;
51
68
  }
52
69
 
53
70
  public XPathFunction resolveFunction(QName name, int arity) {
54
- return new NokogiriXPathFunction(this.handler, name.getLocalPart(), arity);
71
+ return NokogiriXPathFunction.create(handler, name.getLocalPart(), arity);
55
72
  }
56
73
  }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008 - 2011:
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
+ package nokogiri.internals;
33
+
34
+ import java.util.HashMap;
35
+ import javax.xml.namespace.QName;
36
+ import javax.xml.xpath.XPathVariableResolver;
37
+
38
+ /**
39
+ * XPath variable support
40
+ *
41
+ * @author Ken Bloom <kbloom@gmail.com>
42
+ * @author Yoko Harada <yokolet@gmail.com>
43
+ */
44
+ public class NokogiriXPathVariableResolver implements XPathVariableResolver {
45
+ private static NokogiriXPathVariableResolver resolver;
46
+ private HashMap<QName,String> variables = new HashMap<QName,String>();
47
+
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
+ }
57
+ }
58
+
59
+ private NokogiriXPathVariableResolver() {}
60
+
61
+ public Object resolveVariable(QName variableName){
62
+ return variables.get(variableName);
63
+ }
64
+ public void registerVariable(String name,String value){
65
+ variables.put(new QName(name),value);
66
+ }
67
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008 - 2011:
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.internals;
34
+
35
+ import javax.xml.transform.ErrorListener;
36
+ import javax.xml.transform.TransformerException;
37
+
38
+ /**
39
+ * Error Listener for XSLT transformer
40
+ *
41
+ * @author Yoko Harada <yokolet@gmail.com>
42
+ */
43
+ public class NokogiriXsltErrorListener implements ErrorListener {
44
+ public enum ErrorType {
45
+ WARNING,
46
+ ERROR,
47
+ FATAL
48
+ }
49
+
50
+ private ErrorType type;
51
+ private String errorMessage;
52
+ private Exception exception;
53
+
54
+ public void warning(TransformerException ex) throws TransformerException {
55
+ type = ErrorType.WARNING;
56
+ setError(ex);
57
+ }
58
+
59
+ public void error(TransformerException ex) throws TransformerException {
60
+ type = ErrorType.ERROR;
61
+ setError(ex);
62
+ }
63
+
64
+ public void fatalError(TransformerException ex) throws TransformerException {
65
+ type = ErrorType.FATAL;
66
+ setError(ex);
67
+ }
68
+
69
+ private void setError(TransformerException ex) {
70
+ errorMessage = ex.getMessage();
71
+ exception = ex;
72
+ }
73
+
74
+ public String getErrorMessage() {
75
+ return errorMessage;
76
+ }
77
+
78
+ public ErrorType getErrorType() {
79
+ return type;
80
+ }
81
+
82
+ public Exception getException() {
83
+ return exception;
84
+ }
85
+
86
+ }