Source code: com/hp/hpl/jena/ontology/daml/impl/test/DAMLTest.java
1 /*****************************************************************************
2 * Source code information
3 * -----------------------
4 * Original author Ian Dickinson, HP Labs Bristol
5 * Author email Ian.Dickinson@hp.com
6 * Package Jena
7 * Created 10 Nov 2000
8 * Filename $RCSfile: DAMLTest.java,v $
9 * Revision $Revision: 1.28 $
10 * Release status Preview-release $State: Exp $
11 *
12 * Last modified on $Date: 2005/04/08 17:37:12 $
13 * by $Author: ian_dickinson $
14 *
15 * (c) Copyright 2001, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
16 * (see footer for full conditions)
17 *****************************************************************************/
18
19 // Package
20 ///////////////
21 package com.hp.hpl.jena.ontology.daml.impl.test;
22
23
24 // Imports
25 ///////////////
26 import junit.framework.*;
27
28 import com.hp.hpl.jena.rdf.model.*;
29 import com.hp.hpl.jena.datatypes.TypeMapper;
30 import com.hp.hpl.jena.ontology.OntDocumentManager;
31 import com.hp.hpl.jena.ontology.daml.*;
32 import com.hp.hpl.jena.vocabulary.*;
33
34 import java.util.*;
35
36 import java.io.*;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41
42 /**
43 * Legacy JUnit regression tests for the Jena DAML model.
44 *
45 * @author Ian Dickinson, HP Labs (<a href="mailto:Ian.Dickinson@hp.com">email</a>)
46 * @version CVS info: $Id: DAMLTest.java,v 1.28 2005/04/08 17:37:12 ian_dickinson Exp $,
47 */
48 public class DAMLTest
49 extends TestCase
50 {
51 // Constants
52 //////////////////////////////////
53
54
55 // Static variables
56 //////////////////////////////////
57
58 private static Log log = LogFactory.getLog( DAMLTest.class );
59
60
61 // Instance variables
62 //////////////////////////////////
63
64 // Constructors
65 //////////////////////////////////
66
67 /**
68 * Constructor requires that all tests be named
69 *
70 * @param name The name of this test
71 */
72 public DAMLTest( String name ) {
73 super( name );
74 }
75
76
77
78 // External signature methods
79 //////////////////////////////////
80
81
82
83 // Internal implementation methods
84 //////////////////////////////////
85
86 /**
87 * Set up the test conditions
88 */
89 public void setUp() {
90 // reset default condition
91 OntDocumentManager.getInstance().reset( true );
92 }
93
94
95 /**
96 * Release objects no longer needede when we're done
97 */
98 public void tearDown() {
99 }
100
101
102 // Test cases
103 /////////////
104
105 /**
106 * Test the various pathways through loading the ontology from a source document.
107 */
108 public void testLoadOntology()
109
110 {
111 DAMLModel m = getCleanModel();
112
113 // first do the model read with all options turned on
114 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
115 assertTrue( "Load success status should be true", m.getLoadSuccessful() );
116 assertEquals( "Count of number of classes in daml store (2001/03, import)", 31, countClasses( m ) );
117 // Replaced by der after reasoner update, uncertain whether the "new" results are correct yet!
118 // assertEquals( "Property count ", 66, countProperties( m ) );
119 assertEquals( "Property count ", 68, countProperties( m ) );
120 //dumpModel( m );
121
122 // now turn off importing - should only get the classes and properties in the source doc
123 m = getCleanModel();
124 m.getLoader().setLoadImportedOntologies( false );
125 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
126 assertTrue( "Load success status should be true", m.getLoadSuccessful() );
127 assertEquals( "Count of number of classes in daml store (2001/03, no import)", 16, countClasses( m ) );
128
129 // test case for bug reported by Charlie Abela: must be able to load instance files that import
130 // their own class declarations
131 m = getCleanModel();
132 m.read( "file:testing/ontology/daml/test-instance-load.daml" );
133 assertTrue( "Load status should be true", m.getLoadSuccessful() );
134 Resource pugh = m.getResource( "http://dickinson-i-4/daml/tests/test-instance-load.daml#pugh" );
135 assertNotNull( "Resource for officer Pugh should not be null", pugh );
136 DAMLInstance pughInst = (DAMLInstance) pugh.as( DAMLInstance.class );
137 assertNotNull( pughInst );
138
139 // test case for bug report by Michael Sintek
140 // try to ascertain the most specific class we can at load time -
141 // case in point is shoesize in standard example ontology
142 m = getCleanModel();
143 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
144 assertTrue( "Load success status should be true", m.getLoadSuccessful() );
145 DAMLProperty shoesize = (DAMLProperty) m.getProperty( "http://www.daml.org/2001/03/daml+oil-ex#shoesize" ).as( DAMLProperty.class );
146 assertNotNull( "Failed to find shoesize property in example ontology", shoesize );
147 assertEquals( "shoesize should be a unique property", true, shoesize.isUnique() );
148 }
149
150
151 /**
152 * Test case for testing rdf:type traversal
153 */
154 public void testRDFType()
155
156 {
157 String ns = "http://dickinson-i-4/daml/tests/test-cases.daml#";
158
159 DAMLModel m = getCleanModel();
160 m.read( "file:testing/ontology/daml/test-cases.daml" );
161
162 //dumpModel( m );
163
164 // first find fido
165 DAMLInstance fido = m.getDAMLInstance( ns + "fido" );
166 assertNotNull( "fido instance should not be null", fido );
167
168 // lookup some classes for convenience
169 DAMLClass cDog = m.getDAMLClass( ns + "Dog" );
170 assertNotNull( "Dog class should not be null", cDog );
171
172 DAMLClass cVertebrate = m.getDAMLClass( ns + "Vertebrate" );
173 assertNotNull( "Vertebrate class should not be null", cVertebrate );
174
175 DAMLClass cPet = m.getDAMLClass( ns + "Pet" );
176 assertNotNull( "Pet class should not be null", cPet );
177
178 // fido is a Dog, a vertebrate and a pet
179 assertTrue( "fido should be member of class Dog", fido.hasRDFType( cDog ) );
180 assertTrue( "fido should be member of class Vertebrate", fido.hasRDFType( cVertebrate ) );
181 assertTrue( "fido should be member of class Vertebrate (by URL)", fido.hasRDFType( ns + "Vertebrate" ) );
182 assertTrue( "fido should be member of class Pet", fido.hasRDFType( cPet ) );
183
184 // fido is not a class
185 assertTrue( "fido should not be a class", !fido.hasRDFType( DAML_OIL.Class ) );
186
187 // fido is a companion, even though this class is not defined in the current ontology
188 assertTrue( "fido should be a companion", fido.hasRDFType( ns + "Companion" ) );
189
190 // fido is a Thing (all things DAML are Things)
191 // disabled pending adding DAML semantic rules assertTrue( "fido should be a thing", fido.hasRDFType( DAML_OIL.Thing ) );
192
193 // get some more classes
194 DAMLClass cA = m.getDAMLClass( ns + "A" );
195 assertNotNull( "Class A should not be null", cA );
196
197 DAMLClass cB = m.getDAMLClass( ns + "B" );
198 assertNotNull( "Class B should not be null", cB );
199
200 DAMLInstance ab = m.getDAMLInstance( ns + "ab" );
201 assertNotNull( "Instance ab should not be null", ab );
202
203 // note that cA --subclass--> cB --subclass--> cA is a loop
204 assertTrue( "ab should be an A", ab.hasRDFType( cA ) );
205 assertTrue( "ab should be a B", ab.hasRDFType( cB ) );
206
207 // how many ways do I know thee? let me count the ways ...
208 assertEquals( "Number of classes fido belongs to (closure) should be 8",
209 8, countIteration( fido.getRDFTypes( true ), true, "fido member of class " ) );
210 assertEquals( "Number of classes fido belongs to (non-closure) should be 3",
211 3, countIteration( fido.getRDFTypes( false ), true, "fido member of non-closed class " ) );
212
213 // some tests on the built-in classes
214 DAMLProperty queenOf = m.getDAMLProperty( ns + "queen-of" );
215 assertNotNull( "queen-of property should be defined", queenOf );
216 assertTrue( "an UnabmbiguousProperty should be an ObjectProperty", queenOf.hasRDFType( DAML_OIL.UnambiguousProperty ) );
217 assertTrue( "an UnabmbiguousProperty should be an ObjectProperty", queenOf.hasRDFType( DAML_OIL.ObjectProperty ) );
218 assertTrue( "an UnabmbiguousProperty should be an rdf:Property", queenOf.hasRDFType( RDF.Property ) );
219 }
220
221
222 /**
223 * Test some of the properties of DAML classes
224 */
225 public void testClass() {
226 DAMLModel m = getCleanModel();
227
228 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
229 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
230 String ns = "http://www.daml.org/2001/03/daml+oil-ex#";
231
232 // get a reference to the Person class
233 DAMLClass person = m.getDAMLClass( ns + "Person" );
234 assertNotNull( "Person class should not be null", person );
235 assertTrue( "Person should be a named class", person.isNamedClass() );
236
237 // count the super-classes of a Person
238 int sCount0 = countIteration( person.prop_subClassOf().getAll( ), true, "super-class of Person (prop_subClassOf) " );
239 int sCount1 = countIteration( person.getSuperClasses(), true, "super-class of Person (getSuperClasses) " );
240 assertEquals( "person should have 10 super-classes (by prop_subClassOf)", 10, sCount0 );
241 assertEquals( "person should have 9 super-classes (by getSuperClasses)", 9, sCount1 );
242
243 // count the number of sub-classes of a Person
244 assertEquals( "person should have 3 sub-classes", 3,
245 countIteration( person.getSubClasses(), true, "Person super-class of: " ) );
246
247 // person is a disjoint union of Man and Woman
248 assertTrue( "Person should be a disjoint union", person.isDisjointUnion() );
249 DAMLList mw = person.prop_disjointUnionOf().getList();
250 assertNotNull( "Value of disjoint union should not be null", mw );
251 assertEquals( "Person should be a disjoint union of size 2", 2, mw.getCount() );
252
253 // Female is disjoint with Male
254 DAMLClass female = m.getDAMLClass( ns + "Female" );
255 assertNotNull( "Class Female should not be null", female );
256 DAMLClass male = m.getDAMLClass( ns + "Male" );
257 assertNotNull( "Class Male should not be null", male );
258 assertTrue( "Female should be disjoint with male", female.prop_disjointWith().hasValue( male ) );
259
260 // HumanBeing is the same class as Person
261 DAMLClass humanBeing = m.getDAMLClass( ns + "HumanBeing" );
262 assertNotNull( "Class humanBeing should not be null", humanBeing );
263 assertTrue( "Person should be same class as HumanBeing", humanBeing.prop_sameClassAs().hasValue( person ) );
264
265 // TallMan is an intersection of Man and TallThing
266 DAMLClass tallMan = m.getDAMLClass( ns + "TallMan" );
267 assertNotNull( "Class TallMan should not be null", tallMan );
268 DAMLList tm = tallMan.prop_intersectionOf().getList();
269 assertNotNull( "Value of intersection should not be null", tm );
270 assertEquals( "Tall man should be an intersection of size 2", 2, tm.getCount() );
271
272 // Car is a complement of Person
273 DAMLClass car = m.getDAMLClass( ns + "Car" );
274 assertNotNull( "Class Car should not be null", car );
275 DAMLClass carSuper = (DAMLClass) car.getSuperClasses(false).next();
276 assertNotNull( "Car should have a super-class", carSuper );
277 assertTrue( "Car super-class should be a complement", carSuper.isComplement() );
278 assertTrue( "Car super-class should be a complement of Person", carSuper.prop_complementOf().hasValue( person ) );
279
280 // Height is an enumeration of three values
281 DAMLClass height = m.getDAMLClass( ns + "Height" );
282 assertNotNull( "Class Height should not be null", height );
283 assertTrue( "Height should be an enumeration", height.isEnumeration() );
284 assertEquals( "Height should be an enumeration of 3 elements", 3, height.prop_oneOf().getList().getCount() );
285
286 // daml:subClassOf is processed as rdfs:subClassOf
287 DAMLModel m0 = getCleanModel();
288 m0.getLoader().setLoadImportedOntologies( true );
289 m0.read( "file:testing/ontology/daml/test-cases.daml", "http://dickinson-i-4/daml/tests/test-cases.daml", null );
290 String tcNs = "http://dickinson-i-4/daml/tests/test-cases.daml#";
291 DAMLClass subClassBug0 = m0.getDAMLClass( tcNs + "SubClassBug0" );
292 DAMLClass subClassBug1 = m0.getDAMLClass( tcNs + "SubClassBug1" );
293 assertNotNull( "Class SubClassBug0 should not be null", subClassBug0 );
294 assertNotNull( "Class SubClassBug1 should not be null", subClassBug1 );
295 assertTrue( "SubClassBug1 should have SubClassBug0 as a super-class", subClassBug1.hasSuperClass( subClassBug0 ) );
296 assertTrue( "SubClassBug0 should have SubClassBug1 as a sub-class", subClassBug0.hasSubClass( subClassBug1 ) );
297
298 // defined properties are those that mention this class as domain
299 DAMLClass defProp0 = m0.getDAMLClass( tcNs + "DefProp0" );
300 DAMLClass defProp1 = m0.getDAMLClass( tcNs + "DefProp1" );
301 DAMLClass defProp2 = m0.getDAMLClass( tcNs + "DefProp2" );
302 assertNotNull( "Class DefProp0 should not be null", defProp0 );
303 assertNotNull( "Class DefProp1 should not be null", defProp1 );
304 assertNotNull( "Class DefProp2 should not be null", defProp2 );
305
306 int nP0 = countIteration( defProp0.getDefinedProperties(), true, "Defined property of DefProp0, closed" );
307 int nP0nc = countIteration( defProp0.getDefinedProperties( false ), true, "Defined property of DefProp0, not closed" );
308 int nP1 = countIteration( defProp1.getDefinedProperties(), true, "Defined property of DefProp1, closed" );
309 int nP1nc = countIteration( defProp1.getDefinedProperties( false ), true, "Defined property of DefProp1, not closed" );
310 int nP2 = countIteration( defProp2.getDefinedProperties(), true, "Defined property of DefProp2, closed" );
311 int nP2nc = countIteration( defProp2.getDefinedProperties( false ), true, "Defined property of DefProp2, not closed" );
312 assertEquals( "Defined properties of DefProp0 should number 11", 11, nP0 );
313 assertEquals( "Defined properties of DefProp0 (non-closed) should number 11", 11, nP0nc );
314 assertEquals( "Defined properties of DefProp1 should number 11", 11, nP1 );
315 assertEquals( "Defined properties of DefProp1 (non-closed) should number 0", 0, nP1nc );
316
317 assertEquals( "Defined properties of DefProp2 should number 12", 12, nP2 );
318 assertEquals( "Defined properties of DefProp2 (non-closed) should number 1", 1, nP2nc );
319 assertEquals( "Defined properties of DefProp2 should number 12", 12, nP2 );
320 assertEquals( "Defined properties of DefProp2 (non-closed) should number 1", 1, nP2nc );
321
322 // Bug report by Thorsten Liebig
323 DAMLClass tl_one = m0.getDAMLClass( tcNs + "tl_one" );
324 assertNotNull( "Class tl_one should not be null", tl_one );
325 int tl_one_supers0 = countIteration( tl_one.prop_subClassOf().getAll( ), true, "prop_subClassOf " );
326 int tl_one_supers1 = countIteration( tl_one.getSuperClasses( false ), true, "getSuperClasses ");
327 assertEquals( "Should be four super-classes of tl_one by prop_subClassOf", 4, tl_one_supers0 );
328 assertEquals( "Should be two super-classes of tl_one by getSuperClasses", 2, tl_one_supers1 );
329
330 // Bug report by Andrei S. Lopatenko
331 DAMLClass researcher = m0.getDAMLClass( tcNs + "Researcher" );
332 assertNotNull( "Class Researcher should not be null", researcher );
333 int researcherSupers = countIteration( researcher.getSuperClasses( false ), true, "Super-class of researcher" );
334 assertEquals( "Should be 2 super-classes of researcher", 2, researcherSupers );
335 }
336
337
338 /**
339 * Test equivalance classes
340 */
341 public void testEquivalence() {
342 String ns = "http://dickinson-i-4/daml/tests/test-cases.daml#";
343
344 DAMLModel m = getCleanModel();
345
346 // don't allow any additional info to load
347 m.read( "file:testing/ontology/daml/test-cases.daml", "http://dickinson-i-4/daml/tests/test-cases.daml", null );
348
349 // get the root object
350 DAMLInstance root = m.getDAMLInstance( ns + "x0" );
351 assertNotNull( "Instance x0 should not be null", root );
352 // should really be 4 under daml rules, but only 1 under rdfs with no support for daml entailments
353 assertEquals( "Number of elements in equivalence class should be 1", 1,
354 countIteration( root.getEquivalentValues(), true, "Member of equivalence class to x0: " ) );
355
356 // now it's the classes' turn ...
357 DAMLClass cRoot = m.getDAMLClass( ns + "C0" );
358 assertNotNull( "Class C0 should not be null", cRoot );
359 // should be 4 under daml semantic rules, but only 1 under rdfs
360 assertEquals( "Number of elements in equivalence class should be 1", 1,
361 countIteration( cRoot.getSameClasses(), true, "sameClass as C0: " ) );
362
363 // and now the properties ...
364 DAMLProperty pRoot = m.getDAMLProperty( ns + "p0" );
365 assertNotNull( "Property p0 should not be null", pRoot );
366 // should be 4 under daml semantics rules, but only 1 under rdfs
367 assertEquals( "Number of elements in equivalence class should be 1", 1,
368 countIteration( pRoot.getSameProperties(), true, "sameProperty as p0: " ) );
369
370 // check that daml:type is recognised as equivalent to rdf:type
371 Resource dClass = m.getResource( ns + "CDaml" );
372 assertNotNull( "Resource dClass should not be null", dClass );
373 assertTrue( "Resource dClass should be a daml class", dClass.canAs( DAMLClass.class ) );
374
375 // check that class equivalence is considered during type testing
376 DAMLClass cD0 = m.getDAMLClass( ns + "D0" );
377 DAMLClass cD1 = m.getDAMLClass( ns + "D1" );
378 DAMLInstance d1 = m.getDAMLInstance( ns + "d1" );
379 assertNotNull( "Class D0 should not be null", cD0 );
380 assertNotNull( "Class D1 should not be null", cD1 );
381 assertNotNull( "Instance d1 should not be null", d1 );
382
383 assertTrue( "Instance d1 should have class D1", d1.hasRDFType( cD1 ) );
384 // RDFS reasoner can't do class equivalence assertTrue( "Instance d1 should have class D0", d1.hasRDFType( cD0 ) );
385
386 // check equivalence on properties, pd0 and pd1 are the same
387 DAMLProperty pd0 = m.getDAMLProperty( ns + "pd0" );
388 DAMLProperty pd1 = m.getDAMLProperty( ns + "pd1" );
389 assertNotNull( "Property pd0 should not be null", pd0 );
390 assertNotNull( "Property pd1 should not be null", pd1 );
391
392 DAMLInstance d2 = m.getDAMLInstance( ns + "d2" );
393 assertNotNull( "Instance d2 should not be null", d2 );
394
395 // check that d2 has d1 as a property value under pd0, and pd1 (it's equivalent)
396 assertTrue( "d2 should have d1 as a value for pd0", d2.accessProperty( pd0 ).hasValue( d1 ) );
397 // RDFS reasoner can't do property equivalence assertTrue( "d2 should have d1 as a value for pd1", d2.accessProperty( pd1 ).hasValue( d1 ) );
398
399 DAMLProperty pd2 = m.getDAMLProperty( ns + "pd2" );
400 DAMLProperty pd3 = m.getDAMLProperty( ns + "pd3" );
401 assertNotNull( "Property pd2 should not be null", pd2 );
402 assertNotNull( "Property pd3 should not be null", pd3 );
403
404 // we know that 'd1 pd3 d2', which implies 'd1 pd2 d2' since pd2 is a super-prop of pd3
405 assertTrue( "d2 should have d1 as a value for pd3", d2.accessProperty( pd3 ).hasValue( d1 ) );
406 assertTrue( "d2 should have d1 as a value for pd2", d2.accessProperty( pd2 ).hasValue( d1 ) );
407 }
408
409
410 /**
411 * Unit tests on DAMLProperty and its subclasses
412 */
413 public void testProperty() {
414 DAMLModel m = getCleanModel();
415
416 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
417 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
418 String ns = "http://www.daml.org/2001/03/daml+oil-ex#";
419
420 // Tests on property objects themselves
421 DAMLProperty hasMother = m.getDAMLProperty( ns + "hasMother" );
422 assertNotNull( "hasMother property should not be null", hasMother );
423 assertTrue( "hasMother property should be a unique property", hasMother.isUnique() );
424
425 DAMLProperty hasParent = m.getDAMLProperty( ns + "hasParent" );
426 assertNotNull( "hasParent property should not be null", hasParent );
427
428 DAMLClass female = m.getDAMLClass( ns + "Female" );
429 assertNotNull( "Class Female should not be null", female );
430 DAMLClass animal = m.getDAMLClass( ns + "Animal" );
431 assertNotNull( "Class Animal should not be null", animal );
432 DAMLClass person = m.getDAMLClass( ns + "Person" );
433 assertNotNull( "Class Person should not be null", person );
434
435 // range of hasMother includes female
436 assertTrue( "Mother should have Female as range", hasMother.prop_range().hasValue( female ) );
437 assertTrue( "Mother should not have Animal as local domain (prop_domain)", !hasMother.prop_domain().hasValue( animal ) );
438
439 /* test removed - depends on reasoner configuration
440 boolean found = false;
441 for (Iterator i = hasMother.getDomainClasses(); !found && i.hasNext(); ) {
442 Object cls = i.next();
443 found = found || cls.equals( animal );
444 }
445 assertTrue( "Mother should have Animal as domain (getDomainClasses)", found );
446 */
447
448 // ancestor is transitive
449 DAMLObjectProperty hasAncestor = (DAMLObjectProperty) m.getDAMLProperty( ns + "hasAncestor" ).as( DAMLObjectProperty.class );
450 assertNotNull( "hasAncestor should not be null", hasAncestor );
451 assertTrue( "hasAncestor should be transitive", hasAncestor.isTransitive() );
452
453 // bug report by Michael Sintek: getNext() does not terminate on getAll(false)
454 DAMLInstance peter = m.getDAMLInstance( ns + "Peter" );
455 assertNotNull( "Instance Peter should not be null", peter );
456 DAMLProperty shoesize = m.getDAMLProperty( ns + "shoesize" );
457 assertNotNull( "Property shoesize should not be null", shoesize );
458 PropertyAccessor paShoesize = peter.accessProperty( shoesize );
459 Iterator iShoes = paShoesize.getAll( );
460 assertEquals( "iShoes iterator should have at least one value", true, iShoes.hasNext() );
461 Object size = iShoes.next();
462 assertNotNull( "size returned from property accessor iterator should not be null", size );
463 assertTrue( "size object should be a literal", size instanceof Literal );
464 boolean nse = false;
465 try {
466 iShoes.next();
467 }
468 catch (NoSuchElementException ignore) {
469 nse = true;
470 }
471 assertEquals( "Accessing past end of property iterator should throw no such element exception", true, nse );
472
473 // try the same bug test with a multi-valued property
474 Iterator iSubClassOf = person.prop_subClassOf().getAll( );
475 assertNotNull( "Iterator over subClassOf values should not be null", iSubClassOf );
476 assertTrue( "Iteration of subClassOf should have at least one value", iSubClassOf.hasNext() );
477 int nSupers = countIteration( iSubClassOf, true, "direct super-class of Person = " );
478 assertEquals( "Should be 10 super-classes of Person", 10, nSupers );
479
480 // another bug report from Michael Sintek - get() on single-valued property does not terminate
481 DAMLClass male = m.getDAMLClass( ns + "Male" );
482 assertNotNull( "Class Male should not be null", male );
483 DAMLCommon femaleDisjoint = (DAMLCommon) female.prop_disjointWith().get();
484 assertNotNull( "Value for female.disjointWith should not be null", femaleDisjoint );
485 assertTrue( "female.disjointWith should be male", male.equals( femaleDisjoint ) );
486
487 // another property accessor check
488 m.getLoader().setLoadImportedOntologies( false );
489 m.read( "file:testing/ontology/daml/test-cases.daml", "http://dickinson-i-4/daml/tests/test-cases.daml", null );
490 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
491 ns = "http://dickinson-i-4/daml/tests/test-cases.daml#";
492
493 DAMLClass subClassCheck3 = (DAMLClass) m.getDAMLValue( ns + "subClassCheck3" ).as( DAMLClass.class );
494 assertNotNull( "Class subClassCheck3 should not be null", subClassCheck3 );
495
496 Iterator iSubClassOf3 = subClassCheck3.getSuperClasses( false ); // not closed
497 assertNotNull( "Iterator over subClassOf values should not be null", iSubClassOf );
498 assertTrue( "Iteration of subClassOf should have at least one value", iSubClassOf3.hasNext() );
499 nSupers = countIteration( iSubClassOf3, true, "property access on subClassCheck3" );
500 assertEquals( "Should be 1 non-closed super-classes of subClassCheck3", 1, nSupers );
501
502 iSubClassOf3 = subClassCheck3.getSuperClasses( true ); // closed
503 assertNotNull( "Iterator over subClassOf values should not be null", iSubClassOf );
504 assertTrue( "Iteration of subClassOf should have at least one value", iSubClassOf3.hasNext() );
505 nSupers = countIteration( iSubClassOf3, true, "property access on subClassCheck3 with closed = true " );
506 assertEquals( "Should be 3 closed super-classes of subClassCheck3", 3, nSupers );
507
508 // bug submitted by Michael Sintek: setUseEquivalence(false) does not work with property accessors
509 DAMLProperty q = m.getDAMLProperty( ns + "q" );
510 assertNotNull( "Property q should not be null", q );
511 DAMLInstance qX = m.getDAMLInstance( ns + "qX" );
512 assertNotNull( "Instance qX should not be null", qX );
513
514 // with equivalence turned on, there should be four values for q of qX
515 int nQ = qX.accessProperty( q ).count();
516 // daml equivalance not currently implemented assertEquals( "There should be 4 values for q of qX (equivalence on)", 4, nQ );
517
518 // turn off equivalence, should only be one value
519 assertEquals( "There should be 1 values for q of qX (equivalence off)", 1, nQ );
520
521 // Bug report by Thorsten Liebig
522 DAMLProperty tlPropTest = (DAMLObjectProperty) m.getDAMLProperty( ns + "TL_PropertyTest" ).as( DAMLObjectProperty.class );
523 assertNotNull( "Property should not be null", tlPropTest );
524
525 Iterator tl_domains = tlPropTest.prop_domain().getAll();
526 assertEquals( "Property TL_PropertyTest should have a domain of two classes", 2, countIteration( tl_domains, false, null ) );
527 Iterator tl_ranges = tlPropTest.prop_range().getAll();
528 assertEquals( "Property TL_PropertyTest should have a range of two classes", 2, countIteration( tl_ranges, false, null ) );
529
530 // bug reported by Wesley Bille
531 DAMLClass humanBody = (DAMLClass) m.getDAMLValue( ns + "HumanBody" ).as( DAMLClass.class );
532 assertNotNull( "Class humanBody should not be null", humanBody );
533 PropertyAccessor propUnion = humanBody.prop_unionOf();
534 assertNotNull( "Property accessor should not be null", propUnion );
535 assertEquals( "Should be two value in union", 1, propUnion.count() );
536 DAMLCommon union = propUnion.getDAMLValue();
537 assertNotNull( "Union should not be null", union );
538 assertTrue( "Union value should be a list", union.canAs( DAMLList.class ) );
539 assertEquals( "Should be two values in list", 2, ((DAMLList) union.as( DAMLList.class )).getCount() );
540 }
541
542
543 /**
544 * Tests on lists
545 */
546 public void testList() {
547 DAMLModel m = getCleanModel();
548
549 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
550 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
551 String ns = "http://www.daml.org/2001/03/daml+oil-ex#";
552
553 // get the Person class
554 DAMLClass person = m.getDAMLClass( ns + "Person" );
555 assertNotNull( "Person class should not be null", person );
556 DAMLClass man = m.getDAMLClass( ns + "Man" );
557 assertNotNull( "Man class should not be null", man );
558 DAMLClass woman = m.getDAMLClass( ns + "Woman" );
559 assertNotNull( "Woman class should not be null", woman );
560
561 // check some basic characteristics of the list
562 DAMLList union = (DAMLList) person.prop_disjointUnionOf().get().as( DAMLList.class );
563 assertNotNull( "union should not be null", union );
564 assertEquals( "union should have two values", 2, union.getCount() );
565
566 // man should be the first element in the list
567 RDFNode val1 = union.getFirst();
568 assertEquals( "Man should be the first element in the list", man, val1 );
569
570 // woman should be the other element in the list
571 DAMLList tail = union.getRest();
572 assertNotNull( "Tail of list should not be null", tail );
573
574 RDFNode val2 = tail.getFirst();
575 assertNotNull( "head of tail should not be null", val2 );
576 assertEquals( "Woman should be the first element in the tail of the list", woman, val2 );
577
578 DAMLList tail2 = tail.getRest();
579 assertNotNull( "Tail of tail should not be null", tail2 );
580 assertTrue( "Remainder of list should be empty", tail2.isEmpty() );
581
582 // ontologically nonsensical ... just want to test list manipulations
583 DAMLClass car = m.getDAMLClass( ns + "Car" );
584 assertNotNull( "Class Car should not be null", car );
585 union.add( car );
586 // DEBUG dumpModel( m.getModel() );
587 assertEquals( "Union should contain three elements", 3, union.getCount() );
588 }
589
590
591 /**
592 * Tests on instances
593 */
594 public void testInstance() {
595 DAMLModel m = getCleanModel();
596
597 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
598 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
599 String ns = "http://www.daml.org/2001/03/daml+oil-ex#";
600
601 // count the number of instances loaded from the standard example
602 assertEquals( "Number of instances should be 7", 7,
603 countIteration( m.listDAMLInstances(), false, " instance = " ) );
604
605 // test listing the instances of a class
606 DAMLClass person = m.getDAMLClass( ns + "Person" );
607 assertNotNull( "Person DAML class should not be null", person );
608 int nPerson = countIteration( person.getInstances(), true, "instance of person" );
609 assertEquals( "There should be 4 instances of Person in the model", 4, nPerson );
610 }
611
612
613 /**
614 * Tests on DAML datatypes
615 */
616 public void testDatatype() {
617 DAMLModel m = getCleanModel();
618
619 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
620 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
621 String ns = "http://www.daml.org/2001/03/daml+oil-ex#";
622
623 // get the Person class
624 DAMLInstance ian = m.getDAMLInstance( ns + "Ian" );
625 assertNotNull( "Instance Ian should not be null", ian );
626 DAMLProperty shirtsize = m.getDAMLProperty( ns + "shirtsize" );
627 assertNotNull( "Property shirtsize should not be null", shirtsize );
628 DAMLProperty shoesize = m.getDAMLProperty( ns + "shoesize" );
629 assertNotNull( "Property shoesize should not be null", shoesize );
630
631 DAMLDataInstance sSize = (DAMLDataInstance) ian.getRequiredProperty( shirtsize ).getObject().as( DAMLDataInstance.class );
632 assertNotNull( "Object ian should have a shirtsize", sSize );
633 Object x = sSize.getValue();
634 assertNotNull( "Value of shirtsize should not be null", x );
635 assertEquals( "Shirt size should be a string", String.class, x.getClass() );
636 assertEquals( "Shirt size should be \"12\"", "12", x );
637 }
638
639
640 public void testDataInstance() {
641 DAMLModel m = getCleanModel();
642 DAMLDataInstance di = m.createDAMLDataInstance( new Integer( 9 ) );
643 assertNotNull( "Failed to create data instance ", di );
644 assertEquals( "data instance URI not correct ", TypeMapper.getInstance().getTypeByName( XSD.xint.getURI() ), di.getDatatype() );
645
646 String NS="http://example.org/eg#";
647 DAMLClass person = m.createDAMLClass( NS+"Person");
648 DAMLInstance peter = m.createDAMLInstance( person, NS+"peter");
649 DAMLDatatypeProperty p = m.createDAMLDatatypeProperty( NS+"shirtsize");
650 peter.addProperty( p, di );
651
652 // just to confirm we are getting reasonable output m.write( System.out, "RDF/XML-ABBREV" );
653 }
654
655
656 /**
657 * Test the removal of DAML objects. We'll load a model, then
658 * delete everything in it one step at a time.
659 */
660 public void testRemove() {
661 DAMLModel m = ModelFactory.createDAMLModel();
662 m.getDocumentManager().setProcessImports( false );
663 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
664 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
665
666 List cache = new ArrayList();
667 checkValidLists( m, "baseline" );
668
669 // remove classes, properties and instances
670 for (Iterator i = m.listDAMLClasses(); i.hasNext(); ) {
671 cache.add( i.next() );
672 }
673 while (!cache.isEmpty()) {
674 DAMLClass c = (DAMLClass) cache.remove( 0 );
675 log.debug( "Removing class " + c );
676 c.remove();
677 checkValidLists( m, "remove class" );
678 }
679
680 for (Iterator i = m.listDAMLInstances(); i.hasNext(); ) {
681 cache.add( i.next() );
682 }
683 while (!cache.isEmpty()) {
684 DAMLInstance c = (DAMLInstance) cache.remove( 0 );
685 log.debug( "Removing instance " + c );
686 c.remove();
687 checkValidLists( m, "remove instance" );
688 }
689
690 for (Iterator i = m.listDAMLProperties(); i.hasNext(); ) {
691 cache.add( i.next() );
692 }
693 while (!cache.isEmpty()) {
694 DAMLProperty c = (DAMLProperty) cache.remove( 0 );
695 log.debug( "Removing property " + c );
696 c.remove();
697 checkValidLists( m, "remove property" );
698 }
699
700 boolean notBuiltin = false;
701 for (Iterator i = m.listDAMLClasses(); i.hasNext(); ) {
702 Resource x = (Resource) i.next();
703 if (x.equals( DAML_OIL.Thing ) ||
704 x.equals( DAML_OIL.Nothing ) ||
705 x.hasProperty( DAML_OIL.complementOf, DAML_OIL.Nothing )) {
706 // is a builtin
707 }
708 else {
709 log.debug( "Unexpected class remains: " + x );
710 for (StmtIterator j = ((Resource) x).listProperties(); j.hasNext(); ) {
711 log.debug( " ... has prop " + j.next() );
712 }
713 notBuiltin = true;
714 }
715 }
716 assertFalse( "Should be no more classes", notBuiltin );
717 assertFalse( "Should be no more properties", m.listDAMLProperties().hasNext() );
718 assertFalse( "Should be no more instances", m.listDAMLInstances().hasNext() );
719 }
720
721
722 /**
723 * Test the creation of new DAML values
724 */
725 public void testCreate()
726
727 {
728 DAMLModel m = getCleanModel();
729
730 String cURI = "http://dickinson-i-4/daml/tests/gen#A";
731 DAMLClass c = m.createDAMLClass( cURI );
732 assertNotNull( "Failed to create new DAML Class " + cURI, c );
733
734 // check that we can find this class again
735 boolean found = false;
736 for (Iterator i = m.listDAMLClasses(); i.hasNext(); ) {
737 if (((DAMLClass) i.next()).equals( c )) {
738 found = true;
739 }
740 }
741 assertTrue( "Could not see class after it was created", found );
742
743 // now create a new instance
744 DAMLInstance x = (DAMLInstance) m.createDAMLValue( "http://dickinson-i-4/daml/tests/gen#x", c );
745 assertNotNull( "Failed to create new DAML instance", x );
746
747 found = false;
748 for (Iterator i = m.listDAMLInstances(); i.hasNext(); ) {
749 if (((DAMLInstance) i.next()).equals( x )) {
750 found = true;
751 }
752 }
753 assertTrue( "Could not see instance after it was created", found );
754 }
755
756
757
758 /**
759 * Testing restrictions
760 */
761 public void testRestriction() {
762 DAMLModel m = getCleanModel();
763
764 m.read( "file:testing/ontology/daml/daml_oil_2001_03/daml+oil-ex.daml", "http://www.daml.org/2001/03/daml+oil-ex", null );
765 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
766 String ns = "http://www.daml.org/2001/03/daml+oil-ex#";
767
768 // bug report by Michael Sintek: class cast exception from getting the value of the property iterator
769 // get a reference to the Person class
770 DAMLClass person = m.getDAMLClass( ns + "Person" );
771
772 // now get a restriction, which we can find as one of the super-classes of Person
773 for (Iterator i = person.getSuperClasses(); i.hasNext(); ) {
774 Resource r = (Resource) i.next();
775
776 if (r instanceof DAMLRestriction) {
777 DAMLRestriction restriction = (DAMLRestriction) r;
778 PropertyAccessor onPropertyAccessor = restriction.prop_onProperty();
779
780 // now get the value from the restriction
781 int count = onPropertyAccessor.count();
782
783 if (count >= 1) {
784 Object x = onPropertyAccessor.get();
785 Object y = onPropertyAccessor.getAll( ).next();
786
787 assertNotNull( "Failed to access value of property accessor on restriction", x );
788 assertNotNull( "Failed to access value of property accessor on restriction", y );
789 }
790 }
791 }
792 }
793
794
795 /**
796 * Test adding a model to an existing model
797 */
798 public void testModelAdd() {
799 DAMLModel m = getCleanModel();
800
801 // create a daml model
802 m.read( "file:testing/ontology/daml/test-add-0.daml" );
803 assertTrue( "loadStatus should be true for successful load", m.getLoadSuccessful() );
804
805 // create a normal rdf model
806 Model m0 = ModelFactory.createDefaultModel();
807 m0.read( "file:testing/ontology/daml/test-add-1.daml" );
808
809 // should be 0 instances in the daml model so far
810 assertEquals( "Instance count in DAML model should be 0", 0, countIteration( m.listDAMLInstances(), true, "instance in test add" ) );
811
812 // now add the RDF data
813 m.add( m0 );
814
815 // now should be 1 instances in the daml model
816 assertEquals( "Instance count in DAML model should be 1", 1, countIteration( m.listDAMLInstances(), true, "instance in test add" ) );
817 }
818
819
820 /**
821 * Testing equality: case DatatypeProperty
822 */
823 public void testDatatypeProperty()
824
825 {
826 eqTest(new EqualityTest("DatatypeProperty") {
827 String xml() {
828 return "<daml:DatatypeProperty/>";
829 }
830 void java(DAMLModel m) {
831 m.createDAMLDatatypeProperty(null);
832 }
833 });
834 }
835 /**
836 * Testing equality: case ObjectProperty
837 */
838 public void testObjectProperty()
839
840 {
841 eqTest(new EqualityTest("ObjectProperty") {
842 String xml() {
843 return "<daml:ObjectProperty/>";
844 }
845 void java(DAMLModel m) {
846 m.createDAMLObjectProperty(null);
847 }
848 });
849 }
850 /**
851 * Testing equality: case Property
852 */
853 public void testPropertyEq()
854
855 {
856 eqTest(new EqualityTest("Property") {
857 String xml() {
858 return "<daml:Property/>";
859 }
860 void java(DAMLModel m) {
861 m.createDAMLProperty(null);
862 }
863 });
864 }
865
866
867 /**
868 * Testing equality: case Datatype
869 */
870 public void testDatatypeEq2()
871
872 {
873 eqTest(new EqualityTest("Datatype") {
874 String xml() {
875 return "<daml:Datatype rdf:about='http://www.w3.org/2000/10/XMLSchema#string'/>";
876 }
877 void java(DAMLModel m) {
878 m.createDAMLDatatype("http://www.w3.org/2000/10/XMLSchema#string");
879 }
880 });
881 }
882
883 public void testDatatypeRange()
884
885 {
886 eqTest(new EqualityTest("Datatype Range") {
887 String xml() {
888 // Example taken from the DAML+OIL walk-thru
889 return
890 "<daml:DatatypeProperty rdf:ID='shoesize'>"+
891 " <rdf:type rdf:resource='http://www.daml.org/2001/03/daml+oil#UniqueProperty'/>" +
892 " <daml:range rdf:resource='http://www.w3.org/2000/10/XMLSchema#decimal'/>" +
893 "</daml:DatatypeProperty>" +
894 "<daml:Datatype rdf:about='http://www.w3.org/2000/10/XMLSchema#decimal'/>";
895 }
896 void java(DAMLModel m) {
897 DAMLDatatypeProperty shoeSize=m.createDAMLDatatypeProperty("http://example.org/#shoesize");
898 shoeSize.setIsUnique(true);
899 shoeSize.prop_range().add(
900 m.createDAMLDatatype("http://www.w3.org/2000/10/XMLSchema#decimal") );
901 }
902 });
903 }
904
905
906 /**
907 * Concept: the EqualityTest object embodies some java code that adds
908 * stuff to a DAMLModel, and some xml that is the body of an RDF/XML doc.
909 * This test checks that these two different ways of describing a DAML
910 * model are the same.
911 *
912 */
913 private void eqTest(EqualityTest test) {
914 DAMLModel m1 = getCleanModel();
915 test.java(m1);
916
917 Model m2 = ModelFactory.createDefaultModel();
918 Reader rdr = new StringReader(
919 "<rdf:RDF " +
920 "xmlns:daml='http://www.daml.org/2001/03/daml+oil#' " +
921 "xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
922 + test.xml()
923 + "</rdf:RDF>");
924 m2.read(rdr,"http://example.org/");
925
926 if (! m1.getBaseModel().isIsomorphicWith(m2) ) {
927 System.out.println("Java:");
928 m1.write(System.out,"RDF/XML-ABBREV");
929 System.out.println("XML:");
930 m2.write(System.out,"RDF/XML-ABBREV");
931 }
932
933 assertTrue("java code and xml should be equivalent",m1.getBaseModel().isIsomorphicWith(m2));
934
935 }
936
937 static abstract private class EqualityTest {
938 String name;
939 EqualityTest(String nm) {
940 name = nm;
941 }
942 public String toString() {
943 return name;
944 }
945 abstract void java(DAMLModel m);
946 abstract String xml();
947 }
948
949
950 /**
951 * Dump the model out to a file for debugging
952 */
953 public void dumpModel( Model m ) {
954 dumpModel( m, "model-out.rdf" );
955 }
956 public void dumpModel( Model m, String fileName ) {
957 try {
958 OutputStream f = new FileOutputStream(fileName);
959 m.write( f, "RDF/XML-ABBREV" );
960 f.close();
961 }
962 catch (Exception e) {
963 LogFactory.getLog( getClass() ).debug( "Exception while dumping model: " + e, e );
964 }
965
966 }
967
968
969 /**
970 * Count the number of things in an iterator, optionally logging them
971 */
972 private int countIteration( Iterator i, boolean doLog, String message ) {
973 int count = 0;
974 for (; i.hasNext(); count++) {
975 Object x = i.next();
976
977 if (doLog) {
978 LogFactory.getLog( getClass() ).debug( "counting iteration, " + message + x );
979 }
980 }
981
982 return count;
983 }
984
985 private int countClasses( DAMLModel m ) {
986 return countIteration( m.listDAMLClasses(), true, "class = " );
987 }
988
989 private int countProperties( DAMLModel m ) {
990 return countIteration( m.listDAMLProperties(), true, "property = " );
991 }
992
993 private DAMLModel getCleanModel() {
994 DAMLModel m = ModelFactory.createDAMLModel();
995 m.getDocumentManager().setProcessImports(true);
996 m.getDocumentManager().clearCache();
997 m.getDocumentManager().setMetadataSearchPath( "file:etc/ont-policy-test.rdf", true );
998 List ll = new ArrayList();
999 for (Iterator i = m.getImportModelMaker().listModels(); i.hasNext(); ll.add( i.next() ) );
1000 for (Iterator i = ll.iterator(); i.hasNext(); ) {
1001 String mName = (String) i.next();
1002 m.getImportModelMaker().removeModel(mName);
1003 log.debug( "Removing " + mName );
1004 }
1005 return m;
1006 }
1007
1008 private void checkValidLists( Model m, String label ) {
1009 log.debug( "Checking lists in DAMLTest - " + label );
1010 for (StmtIterator i = m.listStatements(); i.hasNext(); ) {
1011 Statement s = i.nextStatement();
1012 RDFNode n = s.getObject();
1013 if (n instanceof Resource && ((Resource) n).canAs( RDFList.class )) {
1014 if (!((RDFList) n.as(RDFList.class)).isValid()) {
1015 log.debug( "!!Found invalid list in " + label + " - " + n );
1016 assertTrue( "DAML list not valid ", false );
1017 }
1018 }
1019 }
1020 }
1021
1022 //==============================================================================
1023 // Inner class definitions
1024 //==============================================================================
1025
1026
1027}
1028
1029
1030/*
1031 (c) Copyright 2001, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
1032 All rights reserved.
1033
1034 Redistribution and use in source and binary forms, with or without
1035 modification, are permitted provided that the following conditions
1036 are met:
1037
1038 1. Redistributions of source code must retain the above copyright
1039 notice, this list of conditions and the following disclaimer.
1040
1041 2. Redistributions in binary form must reproduce the above copyright
1042 notice, this list of conditions and the following disclaimer in the
1043 documentation and/or other materials provided with the distribution.
1044
1045 3. The name of the author may not be used to endorse or promote products
1046 derived from this software without specific prior written permission.
1047
1048 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1049 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1050 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1051 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1052 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1053 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1054 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1055 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1056 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1057 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1058*/
1059