smile-xml 1.0.3-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/lib/smile-xml.jar +0 -0
  2. data/lib/xml/libxml.rb +1 -0
  3. data/lib/xml.rb +5 -0
  4. data/src/main/java/smile/xml/AttrJ.java +165 -0
  5. data/src/main/java/smile/xml/AttributesJ.java +219 -0
  6. data/src/main/java/smile/xml/BaseJ.java +60 -0
  7. data/src/main/java/smile/xml/DocumentJ.java +435 -0
  8. data/src/main/java/smile/xml/EncodingJ.java +94 -0
  9. data/src/main/java/smile/xml/ErrorJ.java +155 -0
  10. data/src/main/java/smile/xml/NamespaceJ.java +132 -0
  11. data/src/main/java/smile/xml/NamespacesJ.java +158 -0
  12. data/src/main/java/smile/xml/NodeJ.java +1040 -0
  13. data/src/main/java/smile/xml/NodeSetJ.java +90 -0
  14. data/src/main/java/smile/xml/ParserContextJ.java +44 -0
  15. data/src/main/java/smile/xml/ParserJ.java +196 -0
  16. data/src/main/java/smile/xml/ParserOptionsJ.java +58 -0
  17. data/src/main/java/smile/xml/ReaderJ.java +34 -0
  18. data/src/main/java/smile/xml/SchemaJ.java +66 -0
  19. data/src/main/java/smile/xml/SmileXML.java +65 -0
  20. data/src/main/java/smile/xml/XmlJ.java +58 -0
  21. data/src/main/java/smile/xml/sax/CallbackHandler.java +113 -0
  22. data/src/main/java/smile/xml/sax/SaxParserCallbacksJ.java +71 -0
  23. data/src/main/java/smile/xml/sax/SaxParserJ.java +153 -0
  24. data/src/main/java/smile/xml/util/UtilJ.java +447 -0
  25. data/src/main/java/smile/xml/xpath/CustomNamespaceContext.java +59 -0
  26. data/src/main/java/smile/xml/xpath/XPathContextJ.java +154 -0
  27. data/src/main/java/smile/xml/xpath/XPathExpressionJ.java +62 -0
  28. data/src/main/java/smile/xml/xpath/XPathJ.java +36 -0
  29. data/src/main/java/smile/xml/xpath/XPathObjectJ.java +196 -0
  30. data/src/main/java/smile/xml/xpath/XPointerJ.java +32 -0
  31. data/src/main/ruby/xml/libxml.rb +1 -0
  32. data/src/main/ruby/xml.rb +5 -0
  33. data/src/test/ruby/etc_doc_to_s.rb +21 -0
  34. data/src/test/ruby/ets_doc_file.rb +17 -0
  35. data/src/test/ruby/ets_doc_to_s.rb +23 -0
  36. data/src/test/ruby/ets_gpx.rb +28 -0
  37. data/src/test/ruby/ets_node_gc.rb +23 -0
  38. data/src/test/ruby/ets_test.xml +2 -0
  39. data/src/test/ruby/ets_tsr.rb +11 -0
  40. data/src/test/ruby/model/atom.xml +13 -0
  41. data/src/test/ruby/model/bands.iso-8859-1.xml +5 -0
  42. data/src/test/ruby/model/bands.utf-8.xml +5 -0
  43. data/src/test/ruby/model/bands.xml +5 -0
  44. data/src/test/ruby/model/books.xml +146 -0
  45. data/src/test/ruby/model/merge_bug_data.xml +58 -0
  46. data/src/test/ruby/model/ruby-lang.html +238 -0
  47. data/src/test/ruby/model/rubynet.xml +79 -0
  48. data/src/test/ruby/model/shiporder.rnc +28 -0
  49. data/src/test/ruby/model/shiporder.rng +86 -0
  50. data/src/test/ruby/model/shiporder.xml +23 -0
  51. data/src/test/ruby/model/shiporder.xsd +31 -0
  52. data/src/test/ruby/model/soap.xml +27 -0
  53. data/src/test/ruby/model/xinclude.xml +5 -0
  54. data/src/test/ruby/smile_xml_test.rb +64 -0
  55. data/src/test/ruby/tc_attr.rb +191 -0
  56. data/src/test/ruby/tc_attr_decl.rb +133 -0
  57. data/src/test/ruby/tc_attributes.rb +135 -0
  58. data/src/test/ruby/tc_deprecated_require.rb +13 -0
  59. data/src/test/ruby/tc_document.rb +162 -0
  60. data/src/test/ruby/tc_document_write.rb +212 -0
  61. data/src/test/ruby/tc_dtd.rb +125 -0
  62. data/src/test/ruby/tc_error.rb +150 -0
  63. data/src/test/ruby/tc_html_parser.rb +140 -0
  64. data/src/test/ruby/tc_namespace.rb +62 -0
  65. data/src/test/ruby/tc_namespaces.rb +210 -0
  66. data/src/test/ruby/tc_node.rb +273 -0
  67. data/src/test/ruby/tc_node_cdata.rb +51 -0
  68. data/src/test/ruby/tc_node_comment.rb +33 -0
  69. data/src/test/ruby/tc_node_copy.rb +42 -0
  70. data/src/test/ruby/tc_node_edit.rb +178 -0
  71. data/src/test/ruby/tc_node_text.rb +73 -0
  72. data/src/test/ruby/tc_node_write.rb +108 -0
  73. data/src/test/ruby/tc_node_xlink.rb +29 -0
  74. data/src/test/ruby/tc_parser.rb +371 -0
  75. data/src/test/ruby/tc_parser_context.rb +189 -0
  76. data/src/test/ruby/tc_properties.rb +40 -0
  77. data/src/test/ruby/tc_reader.rb +306 -0
  78. data/src/test/ruby/tc_relaxng.rb +54 -0
  79. data/src/test/ruby/tc_sax_parser.rb +340 -0
  80. data/src/test/ruby/tc_schema.rb +59 -0
  81. data/src/test/ruby/tc_traversal.rb +222 -0
  82. data/src/test/ruby/tc_xinclude.rb +21 -0
  83. data/src/test/ruby/tc_xml.rb +226 -0
  84. data/src/test/ruby/tc_xpath.rb +210 -0
  85. data/src/test/ruby/tc_xpath_context.rb +80 -0
  86. data/src/test/ruby/tc_xpath_expression.rb +38 -0
  87. data/src/test/ruby/tc_xpointer.rb +74 -0
  88. data/src/test/ruby/test_helper.rb +23 -0
  89. data/src/test/ruby/test_suite.rb +41 -0
  90. metadata +142 -0
@@ -0,0 +1,447 @@
1
+ package smile.xml.util;
2
+
3
+ import java.io.StringWriter;
4
+ import java.io.Writer;
5
+ import java.util.ArrayList;
6
+ import java.util.Arrays;
7
+ import java.util.Iterator;
8
+ import java.util.List;
9
+ import java.util.ListIterator;
10
+
11
+ import javax.xml.parsers.DocumentBuilder;
12
+ import javax.xml.parsers.DocumentBuilderFactory;
13
+ import javax.xml.parsers.ParserConfigurationException;
14
+ import javax.xml.transform.OutputKeys;
15
+ import javax.xml.transform.Transformer;
16
+ import javax.xml.transform.TransformerConfigurationException;
17
+ import javax.xml.transform.TransformerFactory;
18
+ import javax.xml.transform.dom.DOMSource;
19
+ import javax.xml.transform.stream.StreamResult;
20
+ import javax.xml.validation.SchemaFactory;
21
+ import javax.xml.xpath.XPath;
22
+ import javax.xml.xpath.XPathFactory;
23
+
24
+ import jline.Terminal;
25
+
26
+ import org.jruby.Ruby;
27
+ import org.jruby.RubyBoolean;
28
+ import org.jruby.RubyClass;
29
+ import org.jruby.RubyModule;
30
+ import org.jruby.RubyNil;
31
+ import org.jruby.RubyObject;
32
+ import org.jruby.RubyString;
33
+ import org.jruby.RubySymbol;
34
+ import org.jruby.anno.JRubyClass;
35
+ import org.jruby.anno.JRubyModule;
36
+ import org.jruby.runtime.Block;
37
+ import org.jruby.runtime.ObjectAllocator;
38
+ import org.jruby.runtime.ThreadContext;
39
+ import org.jruby.runtime.builtin.IRubyObject;
40
+ import org.w3c.dom.NamedNodeMap;
41
+ import org.w3c.dom.Node;
42
+ import org.w3c.dom.NodeList;
43
+
44
+ import smile.xml.AttrJ;
45
+ import smile.xml.EncodingJ;
46
+
47
+ public class UtilJ {
48
+ private static final SchemaFactory schemaFactoryInstance = SchemaFactory
49
+ .newInstance( "http://www.w3.org/2001/XMLSchema");
50
+
51
+ private static final DocumentBuilderFactory factory = DocumentBuilderFactory
52
+ .newInstance();
53
+ private static final TransformerFactory transformerFactory;
54
+ private static final XPathFactory xpathFactory;
55
+ private static final ThreadLocal<DocumentBuilder> builderLocal;
56
+ private static final ThreadLocal<Transformer> transformerLocal;
57
+
58
+ public static TransformerFactory getTransformerFactory() {
59
+ return transformerFactory;
60
+ }
61
+
62
+ public static DocumentBuilderFactory getDocumentBuilderFactory() {
63
+ return factory;
64
+ }
65
+
66
+ public static DocumentBuilder getBuilder() {
67
+ return (DocumentBuilder) builderLocal.get();
68
+ }
69
+
70
+ public static Transformer getTransformer() {
71
+ return (Transformer) transformerLocal.get();
72
+ }
73
+
74
+ public static XPathFactory getXPathFactory() {
75
+ return xpathFactory;
76
+ }
77
+
78
+ public static XPath newXPath() {
79
+ return getXPathFactory().newXPath();
80
+ }
81
+
82
+ public static SchemaFactory getSchemaFactoryInstance() {
83
+ return schemaFactoryInstance;
84
+ }
85
+
86
+ private static List<String> split( String name ) {
87
+ List<String> list = new ArrayList<String>();
88
+ int i=0;
89
+ for( int j=name.indexOf("::"); j!=-1; j=name.indexOf("::", i ) ) {
90
+ list.add( name.substring(i,j) );
91
+ i = j+2;
92
+ }
93
+ list.add( name.substring(i) );
94
+ return list;
95
+ }
96
+
97
+ public static RubyClass defineClass( Ruby runtime, Class<? extends RubyObject> klass, ObjectAllocator allocator ) {
98
+
99
+ JRubyClass anno = klass.getAnnotation( JRubyClass.class );
100
+ List<String> path = split( anno.name()[0] );
101
+ String name = path.remove( path.size()-1 );
102
+ List<String> parent = split( anno.parent() );
103
+
104
+ RubyModule module = getModule( runtime, path );
105
+ RubyClass result = module.defineClassUnder( name, getClass(runtime, parent), allocator );
106
+
107
+ for( String i : anno.include() ) {
108
+ result.includeModule( getModule(runtime, split(i) ) );
109
+ }
110
+
111
+ result.defineAnnotatedMethods( klass );
112
+
113
+ result.defineAnnotatedConstants( klass );
114
+
115
+ return result;
116
+ }
117
+
118
+ public static RubyModule defineModule( Ruby runtime, Class<?> klass ) {
119
+
120
+ JRubyModule anno = klass.getAnnotation( JRubyModule.class );
121
+ List<String> path = split( anno.name()[0] );
122
+ String name = path.remove( path.size()-1 );
123
+
124
+ RubyModule module = getModule( runtime, path );
125
+ RubyModule result = module.defineModuleUnder( name );
126
+
127
+ for( String i : anno.include() ) {
128
+ result.includeModule( getModule(runtime, split(i) ) );
129
+ }
130
+
131
+ result.defineAnnotatedMethods( klass );
132
+ result.defineAnnotatedConstants( klass );
133
+
134
+ return result;
135
+ }
136
+
137
+ public static IRubyObject toRubyString( ThreadContext context, Object obj ) {
138
+
139
+ if( obj == null || obj instanceof RubyNil )
140
+ return context.getRuntime().getNil();
141
+
142
+ if( obj instanceof RubyString )
143
+ return (RubyString) obj;
144
+
145
+ if( obj instanceof String )
146
+ return context.getRuntime().newString( (String) obj );
147
+
148
+ throw context.getRuntime().newTypeError("");
149
+ }
150
+
151
+ public static String toJavaString( ThreadContext context, Object obj ) {
152
+ return toJavaString(context, obj, null );
153
+ }
154
+
155
+ public static <T> T nvl( T obj, T defaultValue ) {
156
+ return obj == null ? defaultValue : obj;
157
+ }
158
+
159
+ public static String toJavaString( ThreadContext context, Object obj, String defaultValue ) {
160
+
161
+ if( obj == null || obj instanceof RubyNil )
162
+ return defaultValue;
163
+
164
+ if( obj instanceof RubyString )
165
+ return ((RubyString) obj).asJavaString();
166
+
167
+ if( obj instanceof RubySymbol )
168
+ return ((RubySymbol) obj).asJavaString();
169
+
170
+ if( obj instanceof String )
171
+ return (String) obj;
172
+
173
+ throw context.getRuntime().newTypeError("");
174
+ }
175
+
176
+ public static RubyModule getModule(Ruby runtime, String...path) {
177
+ return getModule(runtime, Arrays.asList( path ) );
178
+ }
179
+
180
+ public static RubyModule getModule(Ruby runtime, List<String> path) {
181
+
182
+ if( path.isEmpty() )
183
+ return runtime.getObject();
184
+
185
+ RubyModule m = runtime.fastGetModule( path.get(0) ) ;
186
+
187
+ for (int i = 1; i < path.size(); i++) {
188
+ IRubyObject tmp = m.fastGetConstant( path.get(i) );
189
+ if (tmp == null) {
190
+ tmp = m.defineModuleUnder( path.get(i) );
191
+ }
192
+ m = (RubyModule) tmp;
193
+ }
194
+
195
+ return m;
196
+ }
197
+
198
+ public static RubyClass getClass(Ruby runtime, Class<? extends RubyObject> klass ) {
199
+
200
+ JRubyClass anno = klass.getAnnotation( JRubyClass.class );
201
+ List<String> path = split( anno.name()[0] );
202
+ return getClass( runtime, path );
203
+ }
204
+
205
+ public static RubyClass getClass(Ruby runtime, String...path) {
206
+ return getClass(runtime, Arrays.asList(path) );
207
+ }
208
+
209
+ public static RubyClass getClass(Ruby runtime, List<String> path ) {
210
+ if (path.size() == 1) {
211
+ return runtime.fastGetClass( path.get(0) );
212
+ }
213
+ RubyModule m = runtime.fastGetModule( path.get(0) );
214
+
215
+ for (int i = 1; i < path.size() - 1; i++) {
216
+ IRubyObject tmp = m.fastGetConstant( path.get(i) );
217
+ if (tmp == null) {
218
+ tmp = m.defineModuleUnder( path.get(i) );
219
+ }
220
+ m = (RubyModule) tmp;
221
+ }
222
+
223
+ return m.fastGetClass( path.get( path.size() - 1) );
224
+ }
225
+
226
+ public static void iterateOver(ThreadContext context, Block block, Iterable<?> it) {
227
+ for (Iterator i$ = it.iterator(); i$.hasNext();) {
228
+ Object o = i$.next();
229
+ block.yield(context, (IRubyObject) o);
230
+ if (block.isEscaped())
231
+ break;
232
+ }
233
+ }
234
+
235
+ public static void write( Writer writer, Node node, boolean indent, String encoding) {
236
+ try {
237
+ StreamResult result = new StreamResult(writer);
238
+ DOMSource source = new DOMSource(node);
239
+ Transformer transformer = getTransformer();
240
+
241
+ transformer.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
242
+
243
+ if( encoding != null ) {
244
+ transformer.setOutputProperty( OutputKeys.ENCODING, encoding );
245
+ }
246
+
247
+ transformer.transform( source, result);
248
+
249
+ } catch( RuntimeException e) {
250
+ throw e;
251
+ } catch( Exception e ) {
252
+ throw new RuntimeException(e);
253
+ }
254
+ }
255
+
256
+
257
+ public static String toString(Node node, boolean indent) {
258
+ return toString(node, indent, (String) null );
259
+ }
260
+
261
+ public static String toString(Node node, boolean indent, EncodingJ encoding) {
262
+ return toString(node, indent, encoding == null ? null : encoding.asJavaString() );
263
+ }
264
+
265
+ public static String toString(Node node, boolean indent, String encoding) {
266
+ StringWriter writer = new StringWriter();
267
+ try {
268
+ try {
269
+ StreamResult result = new StreamResult(writer);
270
+ DOMSource source = new DOMSource(node);
271
+ Transformer transformer = getTransformer();
272
+
273
+ transformer.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
274
+
275
+ //OMIT_XML_DECLARATION
276
+ if( encoding != null )
277
+ transformer.setOutputProperty( OutputKeys.ENCODING, encoding );
278
+
279
+ transformer.transform(source, result);
280
+
281
+ String str = writer.toString().replace(
282
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "");
283
+ return str;
284
+ } finally {
285
+ writer.close();
286
+ }
287
+ } catch( RuntimeException e) {
288
+ throw e;
289
+ } catch( Exception e ) {
290
+ throw new RuntimeException(e);
291
+ }
292
+ }
293
+
294
+ public static IRubyObject[] toStringArray(ThreadContext context,
295
+ Object array, int offset) {
296
+ List list;
297
+ if (array == null) {
298
+ list = new ArrayList(0);
299
+ } else {
300
+ if ((array instanceof List)) {
301
+ list = (List) array;
302
+ } else {
303
+ if (array.getClass().isArray())
304
+ list = Arrays.asList((Object[]) (Object[]) array);
305
+ else
306
+ throw context.getRuntime().newArgumentError(
307
+ array.getClass().getName() + " unsuported");
308
+ }
309
+ }
310
+ List result = new ArrayList();
311
+ for (int i = offset; i < list.size(); i++) {
312
+ if ((list.get(i) instanceof List))
313
+ result.addAll((List) list.get(i));
314
+ else if ((list.get(i) instanceof String))
315
+ result.add(context.getRuntime().newString((String) list.get(i)));
316
+ else {
317
+ result.add((IRubyObject) list.get(i));
318
+ }
319
+ }
320
+ ListIterator it = result.listIterator();
321
+ while (it.hasNext()) {
322
+ Object obj = it.next();
323
+ if ((obj instanceof RubyString))
324
+ continue;
325
+ it.set(context.getRuntime().newString(obj.toString()));
326
+ }
327
+ return (IRubyObject[]) result.toArray(new IRubyObject[result.size()]);
328
+ }
329
+
330
+ public static String toJavaString(Object object) {
331
+ if ((object instanceof RubyNil)) {
332
+ return null;
333
+ }
334
+ if ((object instanceof String)) {
335
+ return (String) object;
336
+ }
337
+ if ((object instanceof RubyString)) {
338
+ return ((RubyString) object).asJavaString();
339
+ }
340
+ if ((object instanceof RubySymbol)) {
341
+ return ((RubySymbol) object).asJavaString();
342
+ }
343
+ throw new IllegalArgumentException(object.getClass().getName()
344
+ + " can not be a String");
345
+ }
346
+
347
+ public static Boolean toJavaBoolean( ThreadContext context, Object object ) {
348
+ return toJavaBoolean(context, object, null );
349
+ }
350
+
351
+ public static Boolean toJavaBoolean( ThreadContext context, Object object, Boolean defaultValue ) {
352
+
353
+ if ( object == null || object instanceof RubyNil)
354
+ return defaultValue;
355
+
356
+ if (object instanceof Boolean)
357
+ return (Boolean) object;
358
+
359
+ if (object instanceof RubyBoolean ) {
360
+ return ((RubyBoolean) object).isTrue();
361
+ }
362
+
363
+ throw context.getRuntime().newArgumentError("");
364
+ }
365
+
366
+
367
+ public static RubyBoolean toBool(ThreadContext context, boolean value) {
368
+ return value ? context.getRuntime().getTrue() : context.getRuntime()
369
+ .getFalse();
370
+ }
371
+
372
+ static {
373
+ factory.setNamespaceAware(true);
374
+
375
+ transformerFactory = TransformerFactory.newInstance();
376
+
377
+ xpathFactory = XPathFactory.newInstance();
378
+
379
+ builderLocal = new ThreadLocal<DocumentBuilder>() {
380
+ protected DocumentBuilder initialValue() {
381
+ try {
382
+ return UtilJ.getDocumentBuilderFactory().newDocumentBuilder();
383
+ } catch (ParserConfigurationException e) {
384
+ throw new RuntimeException(e);
385
+ }
386
+ }
387
+
388
+ public DocumentBuilder get() {
389
+ DocumentBuilder builder = (DocumentBuilder) super.get();
390
+ builder.reset();
391
+ return builder;
392
+ }
393
+ };
394
+ transformerLocal = new ThreadLocal() {
395
+ protected Transformer initialValue() {
396
+ try {
397
+ return UtilJ.getTransformerFactory().newTransformer();
398
+ } catch (TransformerConfigurationException e) {
399
+ throw new RuntimeException(e);
400
+ }
401
+ }
402
+
403
+ public Transformer get() {
404
+ Transformer builder = (Transformer) super.get();
405
+ builder.reset();
406
+ return builder;
407
+ }
408
+ };
409
+ }
410
+
411
+ public static Node find( NamedNodeMap map, String name ) {
412
+
413
+ Node node = map.getNamedItem( name );
414
+
415
+ if( node != null )
416
+ return node;
417
+
418
+ for( int i=0;i<map.getLength(); i++ ) {
419
+ Node item = map.item(i);
420
+
421
+ if( item.getLocalName().equals( name ) ) {
422
+ return item;
423
+ }
424
+ }
425
+
426
+ return null;
427
+ }
428
+
429
+ public static String getRubyClassName(IRubyObject rObject) {
430
+ if (rObject.isNil()) {
431
+ return "nil";
432
+ }
433
+ return rObject.getMetaClass().asString().asJavaString();
434
+ }
435
+
436
+ public static boolean isNamespace(Node node) {
437
+ String name = node.getNodeName();
438
+ if (name.startsWith("xmlns:") || name.equals("xmlns")) {
439
+ return true;
440
+ }
441
+ return false;
442
+ }
443
+
444
+ public static boolean isAttr(Node node) {
445
+ return ! isNamespace(node);
446
+ }
447
+ }
@@ -0,0 +1,59 @@
1
+ package smile.xml.xpath;
2
+
3
+ import java.util.HashMap;
4
+ import java.util.Iterator;
5
+ import java.util.Map;
6
+
7
+ import javax.xml.namespace.NamespaceContext;
8
+
9
+ import org.w3c.dom.Node;
10
+
11
+ public class CustomNamespaceContext
12
+ implements NamespaceContext
13
+ {
14
+ private final Map<String, String> namespaceMapping = new HashMap<String, String>();
15
+ private final Class<?> cl;
16
+ private final Object resolver;
17
+
18
+ public CustomNamespaceContext(Node node, String[] namespaces)
19
+ {
20
+ try
21
+ {
22
+ this.cl = Class.forName("com.sun.org.apache.xml.internal.utils.PrefixResolverDefault", true, getClass().getClassLoader());
23
+ this.resolver = this.cl.getConstructor(new Class[] { Node.class }).newInstance(new Object[] { node });
24
+ } catch (RuntimeException e) {
25
+ throw e;
26
+ } catch (Exception e) {
27
+ throw new RuntimeException(e);
28
+ }
29
+ for (String ns : namespaces) {
30
+ int i = ns.indexOf(':');
31
+ this.namespaceMapping.put(ns.substring(0, i), ns.substring(i + 1));
32
+ }
33
+ }
34
+
35
+ public String getNamespaceURI(String prefix)
36
+ {
37
+ String uri = (String)this.namespaceMapping.get(prefix);
38
+ if (uri != null)
39
+ return uri;
40
+ try {
41
+ String r = (String)this.cl.getMethod("getNamespaceForPrefix", new Class[] { String.class }).invoke(this.resolver, new Object[] { prefix });
42
+ return r;
43
+ } catch (RuntimeException e) {
44
+ throw e; } catch (Exception e) {
45
+ throw new RuntimeException(e);
46
+ }
47
+
48
+ }
49
+
50
+ public String getPrefix(String namespaceURI)
51
+ {
52
+ return null;
53
+ }
54
+
55
+ public Iterator<?> getPrefixes(String namespaceURI)
56
+ {
57
+ return null;
58
+ }
59
+ }
@@ -0,0 +1,154 @@
1
+ package smile.xml.xpath;
2
+
3
+ import java.util.HashMap;
4
+ import java.util.Map;
5
+
6
+ import org.jruby.Ruby;
7
+ import org.jruby.RubyArray;
8
+ import org.jruby.RubyClass;
9
+ import org.jruby.RubyHash;
10
+ import org.jruby.RubyObject;
11
+ import org.jruby.RubyString;
12
+ import org.jruby.anno.JRubyClass;
13
+ import org.jruby.anno.JRubyMethod;
14
+ import org.jruby.runtime.ObjectAllocator;
15
+ import org.jruby.runtime.ThreadContext;
16
+ import org.jruby.runtime.builtin.IRubyObject;
17
+
18
+ import smile.xml.DocumentJ;
19
+ import smile.xml.NamespaceJ;
20
+ import smile.xml.NamespacesJ;
21
+ import smile.xml.NodeJ;
22
+ import smile.xml.util.UtilJ;
23
+
24
+ @JRubyClass(name="LibXML::XML::XPath::Context")
25
+ public class XPathContextJ extends RubyObject {
26
+
27
+ private static final long serialVersionUID = -5768331253256181175L;
28
+
29
+ private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
30
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
31
+ return new XPathContextJ(runtime, klass);
32
+ }
33
+ };
34
+
35
+ private final Map<String, String> namespaceMapping = new HashMap<String, String>();
36
+ private DocumentJ document;
37
+ private NodeJ node;
38
+
39
+ public static RubyClass define(Ruby runtime) {
40
+ return UtilJ.defineClass( runtime, XPathContextJ.class, ALLOCATOR );
41
+ }
42
+
43
+ private static RubyClass getRubyClass(Ruby runtime) {
44
+ return UtilJ.getClass(runtime, XPathContextJ.class);
45
+ }
46
+
47
+ public static XPathContextJ newInstance(ThreadContext context,
48
+ DocumentJ document) {
49
+ IRubyObject[] args = { document };
50
+ return (XPathContextJ) getRubyClass(context.getRuntime()).newInstance(
51
+ context, args, null);
52
+ }
53
+
54
+ private XPathContextJ(Ruby runtime, RubyClass metaClass) {
55
+ super(runtime, metaClass);
56
+ }
57
+
58
+ @JRubyMethod(name = { "initialize" }, optional = 1)
59
+ public void initialize(ThreadContext context, IRubyObject[] args) {
60
+ if (args.length > 0)
61
+ this.document = ((DocumentJ) args[0]);
62
+ }
63
+
64
+ @JRubyMethod(name = { "doc" })
65
+ public IRubyObject getDocument(ThreadContext context) {
66
+ return this.document;
67
+ }
68
+
69
+ @JRubyMethod(name = { "register_namespace" })
70
+ public IRubyObject registerNamespace(ThreadContext context,
71
+ IRubyObject pPrefix, IRubyObject pUri) {
72
+ String prefix = pPrefix.asJavaString();
73
+ String uri = pUri.asJavaString();
74
+ this.namespaceMapping.put(prefix, uri);
75
+
76
+ return context.getRuntime().getTrue();
77
+ }
78
+
79
+ @JRubyMethod(name = { "register_namespaces" }, rest = true)
80
+ public IRubyObject registerNamespaces(ThreadContext context,
81
+ IRubyObject[] args) {
82
+ for (int i = 0; i < args.length; i++) {
83
+ if ((args[i] instanceof RubyString)) {
84
+ String str = args[i].asJavaString();
85
+ int j = str.indexOf(':');
86
+ this.namespaceMapping.put(str.substring(0, j),
87
+ str.substring(j + 1));
88
+ } else {
89
+ if ((args[i] instanceof RubyHash)) {
90
+ RubyHash hash = (RubyHash) args[i];
91
+ for( Object obj : hash.entrySet() ) {
92
+ Map.Entry<?,?> entry = (Map.Entry<?,?>) obj;
93
+ String prefix = UtilJ.toJavaString(entry.getKey());
94
+ String uri = UtilJ.toJavaString(entry.getValue());
95
+ this.namespaceMapping.put(prefix, uri);
96
+ }
97
+ } else if ((args[i] instanceof RubyArray)) {
98
+ RubyArray array = (RubyArray) args[i];
99
+
100
+ for (IRubyObject obj : UtilJ.toStringArray(context, array,
101
+ 0)) {
102
+ String str = obj.asJavaString();
103
+ int x = str.indexOf(':');
104
+ this.namespaceMapping.put(str.substring(0, x),
105
+ str.substring(x + 1));
106
+ }
107
+ } else {
108
+ throw context.getRuntime().newArgumentError(
109
+ "unsupported argument type "
110
+ + args[i].getMetaClass().getName());
111
+ }
112
+ }
113
+ }
114
+ return this;
115
+ }
116
+
117
+ @JRubyMethod(name = { "register_namespaces_from_node" })
118
+ public IRubyObject registerNamespacesFromNode(ThreadContext context,
119
+ IRubyObject pNode) {
120
+ NodeJ node = (NodeJ) pNode;
121
+ NamespacesJ namespaces = node.getNamespaces(context);
122
+ IRubyObject ns = namespaces.getNamespace(context);
123
+ if ((ns instanceof NamespaceJ)) {
124
+ NamespaceJ nss = (NamespaceJ) ns;
125
+ IRubyObject prefix = nss.getPrefix(context);
126
+ IRubyObject uri = nss.getHref(context);
127
+ if ((!prefix.isNil()) && (!uri.isNil())) {
128
+ this.namespaceMapping.put(prefix.asJavaString(),
129
+ uri.asJavaString());
130
+ }
131
+ }
132
+ return this;
133
+ }
134
+
135
+ @JRubyMethod(name = "find")
136
+ public IRubyObject find(ThreadContext context, IRubyObject pXpath) {
137
+ IRubyObject[] array = new IRubyObject[this.namespaceMapping.size()];
138
+ int i = 0;
139
+ for (Map.Entry<String,String> e : this.namespaceMapping.entrySet()) {
140
+ array[i] = context.getRuntime().newString(
141
+ (String) e.getKey() + ":" + (String) e.getValue());
142
+ i++;
143
+ }
144
+ if ((this.node instanceof NodeJ)) {
145
+ return XPathObjectJ.newInstance(context, pXpath, this.node, array);
146
+ }
147
+ return XPathObjectJ.newInstance(context, pXpath, this.document, array);
148
+ }
149
+
150
+ @JRubyMethod(name = { "node=" })
151
+ public void setNode(ThreadContext context, IRubyObject pNode) {
152
+ this.node = ((NodeJ) pNode);
153
+ }
154
+ }
@@ -0,0 +1,62 @@
1
+ package smile.xml.xpath;
2
+
3
+ import org.jruby.Ruby;
4
+ import org.jruby.RubyClass;
5
+ import org.jruby.RubyObject;
6
+ import org.jruby.RubyString;
7
+ import org.jruby.anno.JRubyClass;
8
+ import org.jruby.anno.JRubyMethod;
9
+ import org.jruby.runtime.ObjectAllocator;
10
+ import org.jruby.runtime.ThreadContext;
11
+ import org.jruby.runtime.builtin.IRubyObject;
12
+
13
+ import smile.xml.util.UtilJ;
14
+
15
+ @JRubyClass( name="LibXML::XML::XPath::Expression" )
16
+ public class XPathExpressionJ extends RubyObject {
17
+
18
+ private static final long serialVersionUID = 9176572911090989553L;
19
+
20
+ private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
21
+
22
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
23
+ return new XPathExpressionJ(runtime, klass);
24
+ }
25
+ };
26
+
27
+ public static RubyClass define(Ruby runtime) {
28
+ return UtilJ.defineClass(runtime, XPathExpressionJ.class, ALLOCATOR);
29
+ }
30
+
31
+ private static RubyClass getRubyClass(Ruby runtime) {
32
+ return UtilJ.getClass(runtime, XPathExpressionJ.class);
33
+ }
34
+
35
+ @JRubyMethod( name="compile", module=true )
36
+ public static XPathExpressionJ compile(ThreadContext context, IRubyObject self, IRubyObject pString ) {
37
+ RubyString string = (RubyString) pString;
38
+ return newInstance(context, string );
39
+ }
40
+
41
+ public static XPathExpressionJ newInstance(ThreadContext context, RubyString string ) {
42
+ IRubyObject[] args = { string };
43
+ return (XPathExpressionJ) getRubyClass(context.getRuntime()).newInstance(
44
+ context, args, null);
45
+ }
46
+
47
+ private XPathExpressionJ(Ruby runtime, RubyClass metaClass) {
48
+ super(runtime, metaClass);
49
+ }
50
+
51
+ private RubyString string;
52
+
53
+ @JRubyMethod(name = "initialize" )
54
+ public void initialize(ThreadContext context, RubyString pString ) {
55
+ string = pString;
56
+ }
57
+
58
+ public RubyString getExpression() {
59
+ return string;
60
+ }
61
+
62
+ }