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