1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package complex.unoxml;
25 
26 import helper.StreamSimulator;
27 
28 import com.sun.star.uno.UnoRuntime;
29 import com.sun.star.uno.XComponentContext;
30 import com.sun.star.lang.XMultiServiceFactory;
31 import com.sun.star.lang.XServiceInfo;
32 import com.sun.star.lang.IllegalArgumentException;
33 import com.sun.star.lang.WrappedTargetException;
34 import com.sun.star.lang.WrappedTargetRuntimeException;
35 import com.sun.star.beans.XPropertySet;
36 import com.sun.star.beans.Pair;
37 import com.sun.star.beans.StringPair;
38 import com.sun.star.container.XEnumeration;
39 import com.sun.star.container.ElementExistException;
40 import com.sun.star.container.NoSuchElementException;
41 import com.sun.star.io.XInputStream;
42 import com.sun.star.io.XOutputStream;
43 import com.sun.star.text.XTextRange;
44 import com.sun.star.text.XText;
45 import com.sun.star.rdf.*;
46 import lib.TestParameters;
47 
48 import org.junit.After;
49 import org.junit.AfterClass;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 import org.junit.Test;
53 import org.openoffice.test.OfficeConnection;
54 import static org.junit.Assert.*;
55 
56 /**
57  * Test case for service com.sun.star.rdf.Repository
58  * Currently, this service is implemented in
59  * unoxml/source/rdf/librdf_repository.cxx
60  *
61  * @author mst
62  */
63 public class RDFRepositoryTest
64 {
65     XComponentContext xContext;
66     String tempDir;
67 
68     XDocumentRepository xRep;
69     XURI foo;
70     XURI bar;
71     XURI baz;
72     XURI uint;
73     XURI rdfslabel;
74     XURI manifest;
75     XURI uuid;
76     XURI base;
77     XBlankNode blank;
78     XLiteral lit;
79     XLiteral litlang;
80     XLiteral littype;
81     String rdfs = "http://www.w3.org/2000/01/rdf-schema#";
82 
83     /**
84      * The test parameters
85      */
86     private static TestParameters param = null;
87 
88 //    public String[] getTestMethodNames ()
89 //    {
90 //        return new String[] { "check", "checkSPARQL", "checkRDFa" };
91 //    }
92 
before()93     @Before public void before()
94     {
95         try {
96             XMultiServiceFactory xMSF = getMSF();
97             param = new TestParameters();
98             param.put("ServiceFactory", xMSF);
99 
100             assertNotNull("could not create MultiServiceFactory.", xMSF);
101             XPropertySet xPropertySet = UnoRuntime.queryInterface(XPropertySet.class, xMSF);
102             Object defaultCtx = xPropertySet.getPropertyValue("DefaultContext");
103             xContext = UnoRuntime.queryInterface(XComponentContext.class, defaultCtx);
104             assertNotNull("could not get component context.", xContext);
105 
106             tempDir = util.utils.getOfficeTemp/*Dir*/(xMSF);
107             System.out.println("tempdir: " + tempDir);
108 
109             foo = URI.create(xContext, "uri:foo");
110             assertNotNull("foo", foo);
111             bar = URI.create(xContext, "uri:bar");
112             assertNotNull("bar", bar);
113             baz = URI.create(xContext, "uri:baz");
114             assertNotNull("baz", baz);
115             uint = URI.create(xContext, "uri:int");
116             assertNotNull("uint", uint);
117             blank = BlankNode.create(xContext, "_:uno");
118             assertNotNull("blank", blank);
119             lit = Literal.create(xContext, "i am the literal");
120             assertNotNull("lit", lit);
121             litlang = Literal.createWithLanguage(xContext,
122                 "i am the literal", "en");
123             assertNotNull("litlang", litlang);
124             littype = Literal.createWithType(xContext, "42", uint);
125             assertNotNull("littype", littype);
126 
127             rdfslabel = URI.create(xContext, rdfs + "label");
128             assertNotNull("rdfslabel", rdfslabel);
129             manifest = URI.create(xContext, "manifest:manifest"); //FIXME
130             assertNotNull("manifest", manifest);
131             uuid = URI.create(xContext,
132                 "urn:uuid:224ab023-77b8-4396-a75a-8cecd85b81e3");
133             assertNotNull("uuid", uuid);
134             base = URI.create(xContext, "base-uri:"); //FIXME
135             assertNotNull("base", base);
136         } catch (Exception e) {
137             report(e);
138         }
139         //FIXME: ?
140 //            xRep = Repository.create(xContext);
141         System.out.println("Creating service Repository...");
142         xRep = UnoRuntime.queryInterface(XDocumentRepository.class, Repository.create(xContext));
143         assertNotNull("null", xRep);
144         System.out.println("...done");
145     }
146 
after()147     @After public void after()
148     {
149         xRep = null;
150     }
151 
check()152     @Test public void check()
153     {
154         try {
155             System.out.println("Checking that new repository is really empty...");
156             assertTrue("empty: graphs", 0 == xRep.getGraphNames().length);
157 
158             XEnumeration stmts;
159             stmts = xRep.getStatements(null, null, null);
160             assertTrue("empty: stmts", !stmts.hasMoreElements());
161 
162             System.out.println("...done");
163 
164             System.out.println("Checking graph creation...");
165 
166             XNamedGraph xFooGraph = xRep.createGraph(foo);
167             assertNotNull("foo graph", xFooGraph);
168 
169             try {
170                 xRep.createGraph(foo);
171                 fail("creating duplicate graph was allowed");
172             } catch (ElementExistException e) {
173                 // ignore
174             }
175 
176             try {
177                 xRep.createGraph(null);
178                 fail("invalid graph name was allowed");
179             } catch (IllegalArgumentException e) {
180                 // ignore
181             }
182 
183             XURI[] names = xRep.getGraphNames();
184             assertTrue("no foo graph in getGraphNames",
185                 1 == names.length && eq(names[0], foo));
186             assertNotNull("no foo graph", xRep.getGraph(foo));
187 
188             stmts = xFooGraph.getStatements(null, null, null);
189             assertTrue("stmts in foo graph", !stmts.hasMoreElements());
190 
191             XOutputStream xFooOut =
192                 new StreamSimulator(tempDir + "empty.rdf", false, param);
193             xRep.exportGraph(FileFormat.RDF_XML, xFooOut, foo, base);
194             xFooOut.closeOutput();
195 
196             XInputStream xFooIn =
197                 new StreamSimulator(tempDir + "empty.rdf", true, param);
198             xRep.importGraph(FileFormat.RDF_XML, xFooIn, bar, base);
199             assertNotNull("no bar graph", xRep.getGraph(bar));
200 
201             System.out.println("...done");
202 
203             System.out.println("Checking graph manipulation...");
204 
205             XEnumeration xFooEnum;
206 
207             Statement xFoo_FooBarBaz = new Statement(foo, bar, baz, foo);
208             xFooGraph.addStatement(foo, bar, baz);
209             xFooEnum = xFooGraph.getStatements(null, null, null);
210             assertTrue("addStatement(foo,bar,baz)",
211                 eq(xFooEnum, new Statement[] { xFoo_FooBarBaz }));
212 
213             Statement xFoo_FooBarBlank = new Statement(foo, bar, blank, foo);
214             xFooGraph.addStatement(foo, bar, blank);
215             xFooEnum = xFooGraph.getStatements(null, null, null);
216             assertTrue("addStatement(foo,bar,blank)",
217                 eq(xFooEnum,
218                     new Statement[] { xFoo_FooBarBaz, xFoo_FooBarBlank }));
219             xFooEnum = xRep.getStatements(null, null, null);
220             assertTrue("addStatement(foo,bar,blank) (global)",
221                 eq(xFooEnum,
222                     new Statement[] { xFoo_FooBarBaz, xFoo_FooBarBlank }));
223 
224             Statement xFoo_BazBarLit = new Statement(baz, bar, lit, foo);
225             xFooGraph.addStatement(baz, bar, lit);
226             xFooEnum = xFooGraph.getStatements(null, null, null);
227             assertTrue("addStatement(baz,bar,lit)",
228                 eq(xFooEnum, new Statement[] {
229                     xFoo_FooBarBaz, xFoo_FooBarBlank, xFoo_BazBarLit }));
230             xFooEnum = xFooGraph.getStatements(baz, bar, null);
231             assertTrue("addStatement(baz,bar,lit) (baz,bar)",
232                 eq(xFooEnum, new Statement[] { xFoo_BazBarLit }));
233 
234             Statement xFoo_BazBarLitlang =
235                 new Statement(baz, bar, litlang, foo);
236             xFooGraph.addStatement(baz, bar, litlang);
237             xFooEnum = xFooGraph.getStatements(null, null, null);
238             assertTrue("addStatement(baz,bar,litlang)",
239                 eq(xFooEnum, new Statement[] {
240                     xFoo_FooBarBaz, xFoo_FooBarBlank, xFoo_BazBarLit,
241                     xFoo_BazBarLitlang }));
242             xFooEnum = xFooGraph.getStatements(null, null, baz);
243             assertTrue("addStatement(baz,bar,litlang) (baz)",
244                 eq(xFooEnum, new Statement[] { xFoo_FooBarBaz }));
245 
246             Statement xFoo_BazBarLittype =
247                 new Statement(baz, bar, littype, foo);
248             xFooGraph.addStatement(baz, bar, littype);
249             xFooEnum = xFooGraph.getStatements(null, null, null);
250             assertTrue("addStatement(baz,bar,littype)",
251                 eq(xFooEnum, new Statement[] { xFoo_FooBarBaz, xFoo_FooBarBlank,
252                     xFoo_BazBarLit, xFoo_BazBarLitlang, xFoo_BazBarLittype }));
253 
254             xFooGraph.removeStatements(baz, bar, litlang);
255             xFooEnum = xFooGraph.getStatements(null, null, null);
256             assertTrue("removeStatement(baz,bar,litlang)",
257                 eq(xFooEnum, new Statement[] { xFoo_FooBarBaz, xFoo_FooBarBlank,
258                     xFoo_BazBarLit, xFoo_BazBarLittype }));
259 
260             xFooGraph.removeStatements(foo, bar, null);
261             xFooEnum = xFooGraph.getStatements(null, null, null);
262             assertTrue("removeStatement(foo,bar,null)",
263                 eq(xFooEnum, new Statement[] {
264                     xFoo_BazBarLit, xFoo_BazBarLittype }));
265 
266             xFooGraph.addStatement(foo, bar, baz);
267             xFooEnum = xFooGraph.getStatements(null, null, null);
268             assertTrue("addStatement(foo,bar,baz) (re-add)",
269                 eq(xFooEnum, new Statement[] { xFoo_FooBarBaz,
270                     xFoo_BazBarLit, xFoo_BazBarLittype }));
271 
272             xFooGraph.addStatement(foo, bar, baz);
273             xFooEnum = xFooGraph.getStatements(null, null, null);
274             assertTrue("addStatement(foo,bar,baz) (duplicate)",
275                 eq(xFooEnum, new Statement[] { xFoo_FooBarBaz,
276                     xFoo_BazBarLit, xFoo_BazBarLittype }));
277 
278             xFooGraph.addStatement(xFooGraph, bar, baz);
279             xFooEnum = xFooGraph.getStatements(null, null, null);
280             assertTrue("addStatement(foo,bar,baz) (triplicate, as graph)",
281                 eq(xFooEnum, new Statement[] { xFoo_FooBarBaz,
282                      xFoo_BazBarLit, xFoo_BazBarLittype }));
283 
284             System.out.println("...done");
285 
286             System.out.println("Checking graph import/export...");
287 
288             xFooOut = new StreamSimulator(tempDir + "foo.rdf", false, param);
289             xRep.exportGraph(FileFormat.RDF_XML, xFooOut, foo, base);
290             xFooOut.closeOutput();
291 
292             xFooIn = new StreamSimulator(tempDir + "foo.rdf", true, param);
293             try {
294                 xRep.importGraph(FileFormat.RDF_XML, xFooIn, bar, base);
295                 fail("importing existing graph did not fail");
296             } catch (ElementExistException e) {
297                 // ignore
298             }
299 
300             xFooIn = new StreamSimulator(tempDir + "foo.rdf", true, param);
301             xRep.importGraph(FileFormat.RDF_XML, xFooIn, baz, base);
302             XNamedGraph xBazGraph =  xRep.getGraph(baz);
303             assertNotNull("no baz graph", xBazGraph);
304 
305             Statement xBaz_FooBarBaz = new Statement(foo, bar, baz, baz);
306             Statement xBaz_BazBarLit = new Statement(baz, bar, lit, baz);
307             Statement xBaz_BazBarLittype =
308                 new Statement(baz, bar, littype, baz);
309             XEnumeration xBazEnum = xBazGraph.getStatements(null, null, null);
310             assertTrue("importing exported graph",
311                 eq(xBazEnum, new Statement[] {
312                      xBaz_FooBarBaz, xBaz_BazBarLit, xBaz_BazBarLittype }));
313 
314             System.out.println("...done");
315 
316             System.out.println("Checking graph deletion...");
317 
318             xFooGraph.clear();
319             xFooEnum = xFooGraph.getStatements(null, null, null);
320             assertTrue("clear", eq(xFooEnum, new Statement[] { }));
321 
322             xRep.destroyGraph(baz);
323             assertNull("baz graph zombie", xRep.getGraph(baz));
324 
325             try {
326                 xBazGraph.clear();
327                 fail("deleted graph not invalid (clear)");
328             } catch (NoSuchElementException e) {
329                 // ignore
330             }
331 
332             try {
333                 xBazGraph.addStatement(foo, foo, foo);
334                 fail("deleted graph not invalid (add)");
335             } catch (NoSuchElementException e) {
336                 // ignore
337             }
338 
339             try {
340                 xBazGraph.removeStatements(null, null, null);
341                 fail("deleted graph not invalid (remove)");
342             } catch (NoSuchElementException e) {
343                 // ignore
344             }
345 
346             try {
347                 xBazGraph.getStatements(null, null, null);
348                 fail("deleted graph not invalid (get)");
349             } catch (NoSuchElementException e) {
350                 // ignore
351             }
352 
353             System.out.println("...done");
354 
355         } catch (Exception e) {
356             report(e);
357         }
358     }
359 
checkSPARQL()360     @Test public void checkSPARQL()
361     {
362         try {
363 
364             System.out.println("Checking SPARQL queries...");
365 
366             XInputStream xIn = new StreamSimulator(TestDocument.getUrl("example.rdf"), true, param);
367                 // util.utils.getFullTestDocName("example.rdf"), true, param);
368             xRep.importGraph(FileFormat.RDF_XML, xIn, manifest, base);
369 
370             String query;
371             query = "SELECT ?p WHERE { ?p rdf:type pkg:Package . }";
372             XQuerySelectResult result = xRep.querySelect(mkNss() + query);
373             assertTrue("query: package-id\n" + query,
374                 eq(result, new String[] { "p" },
375                     new XNode[][] { { uuid } }));
376 
377             query = "SELECT ?part ?path FROM <" + manifest +
378                "> WHERE { ?pkg rdf:type pkg:Package . ?pkg pkg:hasPart ?part ."
379                + " ?part pkg:path ?path . ?part rdf:type odf:ContentFile. }";
380             result = xRep.querySelect(mkNss() + query);
381             assertTrue("query: contentfile",
382                 eq(result, new String[] { "part", "path" },
383                     new XNode[][] { { BlankNode.create(xContext, "whatever"),
384                             Literal.create(xContext, "content.xml") } }));
385 
386             query = "SELECT ?pkg ?path FROM <" + toS(manifest) +  "> WHERE { "
387                 + "?pkg rdf:type pkg:Package . ?pkg pkg:hasPart ?part . "
388                 + "?part pkg:path ?path . ?part rdf:type odf:ContentFile. }";
389             result = xRep.querySelect(mkNss() + query);
390             assertTrue("query: contentfile\n" + query,
391                 eq(result, new String[] { "pkg", "path" },
392                     new XNode[][] { { uuid ,
393                             Literal.create(xContext, "content.xml") } }));
394 
395             query = "SELECT ?part ?path FROM <" + toS(manifest) + "> WHERE { "
396                 + "?pkg rdf:type pkg:Package . ?pkg pkg:hasPart ?part . "
397                 + "?part pkg:path ?path . ?part rdf:type odf:StylesFile. }";
398             result = xRep.querySelect(mkNss() + query);
399             assertTrue("query: stylesfile\n" + query,
400                 eq(result, new String[] { "part", "path" },
401                     new XNode[][] { }));
402 
403             query = "SELECT ?part ?path FROM <" + toS(manifest) + "> WHERE { "
404                 + "?pkg rdf:type pkg:Package . ?pkg pkg:hasPart ?part . "
405                 + "?part pkg:path ?path . ?part rdf:type odf:MetadataFile. }";
406             result = xRep.querySelect(mkNss() + query);
407             assertTrue("query: metadatafile\n" + query,
408                 eq(result, new String[] { "part", "path" },
409                     new XNode[][] { {
410                         URI.create(xContext, "http://hospital-employee/doctor"),
411                         Literal.create(xContext,
412                             "meta/hospital/doctor.rdf") } }));
413 
414 //FIXME redland BUG
415             String uri = "uri:example-element-2";
416             query = "SELECT ?path ?idref FROM <" + toS(manifest) +  "> WHERE { "
417 //                + "<" + toS(uuid) + "> rdf:type pkg:Package ; "
418 //                                 + " pkg:hasPart ?part . "
419                 + "<" + toS(uuid) + "> pkg:hasPart ?part . "
420                 + "?part pkg:path ?path ; "
421                      + " rdf:type ?type ; "
422                      + " pkg:hasPart <" + uri + "> . "
423 //                + "<" + uri + "> rdf:type odf:Element ; "
424                 + "<" + uri + "> "
425                       + " pkg:idref ?idref . "
426                 + " FILTER (?type = odf:ContentFile || ?type = odf:StylesFile)"
427                 + " }";
428 //System.out.println(query);
429             result = xRep.querySelect(mkNss() + query);
430             assertTrue("query: example-element-2\n" + query,
431                 eq(result, new String[] { "path", "idref" },
432                     new XNode[][] { {
433                         Literal.create(xContext, "content.xml"),
434                         Literal.create(xContext, "ID_B") } }));
435 
436             // CONSTRUCT result triples have no graph!
437             Statement x_PkgFooLit = new Statement(uuid, foo, lit, null);
438             query = "CONSTRUCT { ?pkg <" + toS(foo) + "> \"" +
439                 lit.getStringValue() + "\" } FROM <" + toS(manifest) +
440                 "> WHERE { ?pkg rdf:type pkg:Package . } ";
441             XEnumeration xResultEnum = xRep.queryConstruct(mkNss() + query);
442             assertTrue("query: construct\n" + query,
443                 eq(xResultEnum, new Statement[] { x_PkgFooLit }));
444 
445             query = "ASK { ?pkg rdf:type pkg:Package . }";
446             boolean bResult = xRep.queryAsk(mkNss() + query);
447             assertTrue("query: ask\n" + query, bResult);
448 
449             System.out.println("...done");
450 
451         } catch (Exception e) {
452             report(e);
453         }
454     }
455 
checkRDFa()456     @Test public void checkRDFa()
457     {
458         try {
459             System.out.println("Checking RDFa gunk...");
460 
461             String content = "behold, for i am the content.";
462             XTextRange xTR = new TestRange(content);
463             XMetadatable xM = (XMetadatable) xTR;
464 
465             Pair<Statement[], Boolean> result =
466                 xRep.getStatementRDFa((XMetadatable)xTR);
467             assertTrue("RDFa: get: not empty (initial)",
468                 0 == result.First.length);
469 
470             try {
471                 xRep.setStatementRDFa(foo, new XURI[] {}, xM, "", null);
472                 fail("RDFa: set: no predicate");
473             } catch (IllegalArgumentException e) {
474                 // ignore
475             }
476 
477             try {
478                 xRep.setStatementRDFa(foo, new XURI[] {bar}, null, "", null);
479                 fail("RDFa: set: null");
480             } catch (IllegalArgumentException e) {
481                 // ignore
482             }
483 
484             XLiteral trlit = Literal.create(xContext, content);
485             Statement x_FooBarTRLit = new Statement(foo, bar, trlit, null);
486             xRep.setStatementRDFa(foo, new XURI[] { bar }, xM, "", null);
487 
488             result = xRep.getStatementRDFa((XMetadatable)xTR);
489             assertTrue("RDFa: get: without content",
490                 !result.Second && (1 == result.First.length)
491                 && eq(result.First[0], x_FooBarTRLit));
492 
493             //FIXME: do this?
494             xTR.setString(lit.getStringValue());
495 /*
496             Statement xFooBarLit = new Statement(foo, bar, lit, null);
497             result = xRep.getStatementRDFa((XMetadatable)xTR);
498             assertTrue("RDFa: get: change",
499                 eq((Statement)result.First, xFooBarLit) && null == result.Second);
500 */
501 
502             Statement x_FooBarLittype = new Statement(foo, bar, littype, null);
503             xRep.setStatementRDFa(foo, new XURI[] { bar }, xM, "42", uint);
504 
505             result = xRep.getStatementRDFa((XMetadatable)xTR);
506             assertTrue("RDFa: get: with content",
507                 result.Second &&
508                 (1 == result.First.length) &&
509                 eq(result.First[0], x_FooBarLittype));
510 
511             //FIXME: do this?
512             xTR.setString(content);
513 /*
514             Statement xFooLabelTRLit = new Statement(foo, rdfslabel, trlit, null);
515             result = xRep.getStatementRDFa((XMetadatable)xTR);
516             assertTrue("RDFa: get: change (label)",
517                 eq((Statement)result.First, xFooBarLittype) &&
518                 eq((Statement)result.Second, xFooLabelTRLit));
519 */
520 
521             xRep.removeStatementRDFa((XMetadatable)xTR);
522 
523             result = xRep.getStatementRDFa((XMetadatable)xTR);
524             assertTrue("RDFa: get: not empty (removed)",
525                 0 == result.First.length);
526 
527             xRep.setStatementRDFa(foo, new XURI[] { foo, bar, baz }, xM,
528                 "", null);
529 
530             Statement x_FooFooTRLit = new Statement(foo, foo, trlit, null);
531             Statement x_FooBazTRLit = new Statement(foo, baz, trlit, null);
532             result = xRep.getStatementRDFa((XMetadatable) xTR);
533             assertTrue("RDFa: get: without content (multiple predicates, reinsert)",
534                 !result.Second &&
535                 eq(result.First, new Statement[] {
536                      x_FooFooTRLit, x_FooBarTRLit, x_FooBazTRLit }));
537 
538             xRep.removeStatementRDFa((XMetadatable)xTR);
539 
540             result = xRep.getStatementRDFa((XMetadatable) xTR);
541             assertTrue("RDFa: get: not empty (re-removed)",
542                 0 == result.First.length);
543 
544             System.out.println("...done");
545 
546         } catch (Exception e) {
547             report(e);
548         }
549     }
550 
551 // utilities -------------------------------------------------------------
552 
report2(Exception e)553     public void report2(Exception e)
554     {
555         if (e instanceof WrappedTargetException)
556         {
557             System.out.println("Cause:");
558             Exception cause = (Exception)
559                 (((WrappedTargetException)e).TargetException);
560             System.out.println(cause.toString());
561             report2(cause);
562         } else if (e instanceof WrappedTargetRuntimeException) {
563             System.out.println("Cause:");
564             Exception cause = (Exception)
565                 (((WrappedTargetRuntimeException)e).TargetException);
566             System.out.println(cause.toString());
567             report2(cause);
568         }
569     }
570 
report(Exception e)571     public void report(Exception e) {
572         System.out.println("Exception occurred:");
573         e.printStackTrace();
574         report2(e);
575         fail();
576     }
577 
toS(XNode n)578     public static String toS(XNode n) {
579         if (null == n)
580         {
581             return "< null >";
582         }
583         return n.getStringValue();
584     }
585 
isBlank(XNode i_node)586     static boolean isBlank(XNode i_node)
587     {
588         XBlankNode blank = UnoRuntime.queryInterface(XBlankNode.class, i_node);
589         return blank != null;
590     }
591 
592 /*
593     static class Statement implements XStatement
594     {
595         XResource m_Subject;
596         XResource m_Predicate;
597         XNode m_Object;
598         XURI m_Graph;
599 
600         Statement(XResource i_Subject, XResource i_Predicate, XNode i_Object,
601             XURI i_Graph)
602         {
603             m_Subject = i_Subject;
604             m_Predicate = i_Predicate;
605             m_Object = i_Object;
606             m_Graph = i_Graph;
607         }
608 
609         public XResource getSubject() { return m_Subject; }
610         public XResource getPredicate() { return m_Predicate; }
611         public XNode getObject() { return m_Object; }
612         public XURI getGraph() { return m_Graph; }
613     }
614 */
615 
toSeq(XEnumeration i_Enum)616     static Statement[] toSeq(XEnumeration i_Enum) throws Exception
617     {
618         java.util.Collection c = new java.util.Vector();
619         while (i_Enum.hasMoreElements()) {
620             Statement s = (Statement) i_Enum.nextElement();
621 //System.out.println("toSeq: " + s.getSubject().getStringValue() + " " + s.getPredicate().getStringValue() + " " + s.getObject().getStringValue() + ".");
622             c.add(s);
623         }
624 //        return (Statement[]) c.toArray();
625         // java sucks
626         Object[] arr = c.toArray();
627         Statement[] ret = new Statement[arr.length];
628         for (int i = 0; i < arr.length; ++i) {
629             ret[i] = (Statement) arr[i];
630         }
631         return ret;
632     }
633 
toSeqs(XEnumeration i_Enum)634     static XNode[][] toSeqs(XEnumeration i_Enum) throws Exception
635     {
636         java.util.Collection c = new java.util.Vector();
637         while (i_Enum.hasMoreElements()) {
638             XNode[] s = (XNode[]) i_Enum.nextElement();
639             c.add(s);
640         }
641 //        return (XNode[][]) c.toArray();
642         Object[] arr = c.toArray();
643         XNode[][] ret = new XNode[arr.length][];
644         for (int i = 0; i < arr.length; ++i) {
645             ret[i] = (XNode[]) arr[i];
646         }
647         return ret;
648     }
649 
650     static class BindingComp implements java.util.Comparator
651     {
compare(Object i_Left, Object i_Right)652         public int compare(Object i_Left, Object i_Right)
653         {
654             XNode[] left = (XNode[]) i_Left;
655             XNode[] right = (XNode[]) i_Right;
656             if (left.length != right.length)
657             {
658                 throw new RuntimeException();
659             }
660             for (int i = 0; i < left.length; ++i) {
661                 int eq = (left[i].getStringValue().compareTo(
662                             right[i].getStringValue()));
663                 if (eq != 0) return eq;
664             }
665             return 0;
666         }
667     }
668 
669     static class StmtComp implements java.util.Comparator
670     {
compare(Object i_Left, Object i_Right)671         public int compare(Object i_Left, Object i_Right)
672         {
673             int eq;
674             Statement left = (Statement) i_Left;
675             Statement right = (Statement) i_Right;
676             if ((eq = cmp(left.Graph,     right.Graph    )) != 0)
677             {
678                 return eq;
679             }
680             if ((eq = cmp(left.Subject,   right.Subject  )) != 0)
681             {
682                 return eq;
683             }
684             if ((eq = cmp(left.Predicate, right.Predicate)) != 0)
685             {
686                 return eq;
687             }
688             if ((eq = cmp(left.Object,    right.Object   )) != 0)
689             {
690                 return eq;
691             }
692             return 0;
693         }
694 
cmp(XNode i_Left, XNode i_Right)695         public int cmp(XNode i_Left, XNode i_Right)
696         {
697             if (isBlank(i_Left)) {
698                 return isBlank(i_Right) ? 0 : 1;
699             } else {
700                 if (isBlank(i_Right)) {
701                     return -1;
702                 } else {
703                     return toS(i_Left).compareTo(toS(i_Right));
704                 }
705             }
706         }
707     }
708 
eq(Statement i_Left, Statement i_Right)709     static boolean eq(Statement i_Left, Statement i_Right)
710     {
711         XURI lG = i_Left.Graph;
712         XURI rG = i_Right.Graph;
713         if (!eq(lG, rG)) {
714             System.out.println("Graphs differ: " + toS(lG) + " != " + toS(rG));
715             return false;
716         }
717         if (!eq(i_Left.Subject, i_Right.Subject)) {
718             System.out.println("Subjects differ: " +
719                 i_Left.Subject.getStringValue() + " != " +
720                 i_Right.Subject.getStringValue());
721             return false;
722         }
723         if (!eq(i_Left.Predicate, i_Right.Predicate)) {
724             System.out.println("Predicates differ: " +
725                 i_Left.Predicate.getStringValue() + " != " +
726                 i_Right.Predicate.getStringValue());
727             return false;
728         }
729         if (!eq(i_Left.Object, i_Right.Object)) {
730             System.out.println("Objects differ: " +
731                 i_Left.Object.getStringValue() + " != " +
732                 i_Right.Object.getStringValue());
733             return false;
734         }
735         return true;
736     }
737 
eq(Statement[] i_Result, Statement[] i_Expected)738     static boolean eq(Statement[] i_Result, Statement[] i_Expected)
739     {
740         if (i_Result.length != i_Expected.length) {
741             System.out.println("eq: different lengths: " + i_Result.length + " " +
742                 i_Expected.length);
743             return false;
744         }
745         Statement[] expected = (Statement[])
746             java.util.Arrays.asList(i_Expected).toArray();
747         java.util.Arrays.sort(i_Result, new StmtComp());
748         java.util.Arrays.sort(expected, new StmtComp());
749         for (int i = 0; i < expected.length; ++i) {
750             if (!eq(i_Result[i], expected[i]))
751             {
752                 return false;
753             }
754         }
755         return true;
756     }
757 
eq(XEnumeration i_Enum, Statement[] i_Expected)758     static boolean eq(XEnumeration i_Enum, Statement[] i_Expected)
759         throws Exception
760     {
761         Statement[] current = toSeq(i_Enum);
762         return eq(current, i_Expected);
763     }
764 
eq(XNode i_Left, XNode i_Right)765     static boolean eq(XNode i_Left, XNode i_Right)
766     {
767         if (i_Left == null) {
768             return (i_Right == null);
769         } else {
770             return (i_Right != null) &&
771                 (i_Left.getStringValue().equals(i_Right.getStringValue())
772                 // FIXME: hack: blank nodes considered equal
773                 || (isBlank(i_Left) && isBlank(i_Right)));
774         }
775     }
776 
eq(XQuerySelectResult i_Result, String[] i_Vars, XNode[][] i_Bindings)777     static boolean eq(XQuerySelectResult i_Result,
778             String[] i_Vars, XNode[][] i_Bindings) throws Exception
779     {
780         String[] vars = (String[]) i_Result.getBindingNames();
781         XEnumeration iter = (XEnumeration) i_Result;
782         XNode[][] bindings = toSeqs(iter);
783         if (vars.length != i_Vars.length) {
784             System.out.println("var lengths differ");
785             return false;
786         }
787         if (bindings.length != i_Bindings.length) {
788             System.out.println("binding lengths differ: " + i_Bindings.length +
789                 " vs " + bindings.length );
790             return false;
791         }
792         java.util.Arrays.sort(bindings, new BindingComp());
793         java.util.Arrays.sort(i_Bindings, new BindingComp());
794         for (int i = 0; i < i_Bindings.length; ++i) {
795             if (i_Bindings[i].length != i_Vars.length) {
796                 System.out.println("TEST ERROR!");
797                 throw new Exception();
798             }
799             if (bindings[i].length != i_Vars.length) {
800                 System.out.println("binding length and var length differ");
801                 return false;
802             }
803             for (int j = 0; j < i_Vars.length; ++j) {
804                 if (!eq(bindings[i][j], i_Bindings[i][j])) {
805                     System.out.println("bindings differ: " +
806                         toS(bindings[i][j]) + " != " + toS(i_Bindings[i][j]));
807                     return false;
808                 }
809             }
810         }
811         for (int i = 0; i < i_Vars.length; ++i) {
812             if (!vars[i].equals(i_Vars[i])) {
813                 System.out.println("variable names differ: " +
814                     vars[i] + " != " + i_Vars[i]);
815                 return false;
816             }
817         }
818         return true;
819     }
820 
mkNamespace(String i_prefix, String i_namespace)821     static String mkNamespace(String i_prefix, String i_namespace)
822     {
823         return "PREFIX " + i_prefix + ": <" + i_namespace + ">\n";
824     }
825 
mkNss()826     static String mkNss()
827     {
828         String namespaces = mkNamespace("rdf",
829             "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
830         namespaces += mkNamespace("pkg",
831             "http://docs.oasis-open.org/opendocument/meta/package/common#");
832         namespaces += mkNamespace("odf",
833             "http://docs.oasis-open.org/opendocument/meta/package/odf#");
834         return namespaces;
835     }
836 
837     class TestRange implements XTextRange, XMetadatable, XServiceInfo
838     {
839         String m_Stream;
840         String m_XmlId;
841         String m_Text;
TestRange(String i_Str)842         TestRange(String i_Str) { m_Text = i_Str; }
843 
getStringValue()844         public String getStringValue() { return ""; }
getNamespace()845         public String getNamespace() { return ""; }
getLocalName()846         public String getLocalName() { return ""; }
847 
getMetadataReference()848         public StringPair getMetadataReference()
849             { return new StringPair(m_Stream, m_XmlId); }
setMetadataReference(StringPair i_Ref)850         public void setMetadataReference(StringPair i_Ref)
851             throws IllegalArgumentException
852             { m_Stream = i_Ref.First; m_XmlId = i_Ref.Second; }
ensureMetadataReference()853         public void ensureMetadataReference()
854             { m_Stream = "content.xml"; m_XmlId = "42"; }
855 
getImplementationName()856         public String getImplementationName() { return null; }
getSupportedServiceNames()857         public String[] getSupportedServiceNames() { return null; }
supportsService(String i_Svc)858         public boolean supportsService(String i_Svc)
859             { return i_Svc.equals("com.sun.star.text.Paragraph"); }
860 
getText()861         public XText getText() { return null; }
getStart()862         public XTextRange getStart() { return null; }
getEnd()863         public XTextRange getEnd() { return null; }
getString()864         public String getString() { return m_Text; }
setString(String i_Str)865         public void setString(String i_Str) { m_Text = i_Str; }
866     }
867 
getMSF()868         private XMultiServiceFactory getMSF()
869     {
870         final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager());
871         return xMSF1;
872     }
873 
874     // setup and close connections
setUpConnection()875     @BeforeClass public static void setUpConnection() throws Exception {
876         System.out.println("setUpConnection()");
877         connection.setUp();
878     }
879 
tearDownConnection()880     @AfterClass public static void tearDownConnection()
881         throws InterruptedException, com.sun.star.uno.Exception
882     {
883         System.out.println("tearDownConnection()");
884         connection.tearDown();
885     }
886 
887     private static final OfficeConnection connection = new OfficeConnection();
888 }
889 
890