smile-xml 1.0.0-jruby → 1.0.2-jruby
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.
- 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
|
+
}
|