1
6
7 package com.ontotext.gate.ontology;
8
9 import gate.creole.ontology.*;
10 import java.util.List;
11 import java.net.URL;
12 import gate.creole.ResourceInstantiationException;
13 import java.util.Set;
14 import java.util.Iterator;
15 import java.util.Comparator;
16 import gate.DataStore;
17 import gate.persist.PersistenceException;
18 import gate.security.SecurityException;
19 import gate.LanguageResource;
20 import gate.FeatureMap;
21 import gate.creole.ontology.Ontology;
22 import java.util.*;
23 import com.hp.hpl.jena.daml.*;
24 import com.hp.hpl.jena.daml.common.*;
25 import com.hp.hpl.mesa.rdf.jena.model.*;
26 import com.hp.hpl.mesa.rdf.jena.common.*;
27 import com.hp.hpl.jena.vocabulary.*;
28 import com.hp.hpl.mesa.rdf.jena.common.prettywriter.*;
29 import com.hp.hpl.mesa.rdf.jena.vocabulary.*;
30 import com.hp.hpl.jena.rdf.arp.*;
31
32 import java.util.*;
33 import java.io.*;
34 import java.net.*;
35
36 import gate.util.Files;
37 import gate.util.Out;
38
39 public class DAMLKnowledgeBaseImpl extends OntologyImpl {
40
41
42 private static final boolean DEBUG = false;
43 private DAMLModel model = null;
44
45 public void load() throws gate.creole.ResourceInstantiationException {
46 model = loadAndGetModel();
47 if (model == null || !model.getLoadSuccessful())
48 return;
49
50 DAMLInstance instance;
54 Iterator ri = model.listDAMLInstances();
55 while (ri.hasNext()) {
56 Object inst = ri.next();
57 if (! (inst instanceof DAMLInstance))
58 continue;
59 instance = (DAMLInstance) inst;
60
61 Iterator classTypes = instance.getRDFTypes(false);
62 TClass theClass = null;
63 while (classTypes.hasNext() && theClass == null) {
69 String localName =
70 ((com.hp.hpl.mesa.rdf.jena.model.Resource)classTypes.next()
71 ).getLocalName();
72 if (localName != null && this.containsClassByName(localName))
73 theClass = this.getClassByName(localName);
74 } if (theClass != null && instance.getLocalName() != null) {
76 addInstance(instance.getLocalName(), (OClass) theClass);
77 if (DEBUG)
78 System.out.println("Loaded instance: " + instance.getLocalName() +
79 "in class: " + theClass.getName());
80 }
81 }
83 }
85
88 protected DAMLModel loadAndGetModel() throws ResourceInstantiationException{
89
90 try {
91 model = new DAMLModelImpl();
92
93
94
95 URL curl = getURL();
96 if ( null == curl )
97 throw new ResourceInstantiationException(
98 "Unable to load ontology because url is not set. (null)");
99
100 if (-1 != curl.getProtocol().indexOf("gate")) {
101 curl = gate.util.protocols.gate.Handler.class.getResource(
102 Files.getResourcePath() + getURL().getPath()
103 );
104 }
106 model.read(curl.toString());
107 DAMLVocabulary voc = DAML_OIL.getInstance();
108
109 if (! model.getLoadSuccessful()) {
110
111 File f = new File(curl.getFile());
112 if (!f.exists()) {
113 this.store();
114 }
116 model.read(curl.toString());
118
119 if ( !model.getLoadSuccessful()) {
120 throw new ResourceInstantiationException(
121 "loading of ontology failed. url="+curl.toString());
122 }
123 }
125 if (model.getLoadSuccessful()) {
126
127
128 DAMLClass clas;
129 ResIterator ri = model.listSubjects();
130 Resource res;
131 while (ri.hasNext()) {
132 res = ri.next();
133 if ( (res instanceof DAMLClass) && ! (res instanceof DAMLRestriction) ) {
134 clas = (DAMLClass)res;
135 String comment = null;
136 if (null != clas.prop_comment().getValue()) {
137 comment = clas.prop_comment().getValue().getString();
138 }
139
140
141 if ( null!=clas.getLocalName()) {
142 TClass oClass = this.createClass(
143 clas.getLocalName(),
144 comment);
145
146
150 String localURI = clas.getURI();
151 oClass.setURI(localURI);
153 } } else {
160 if (res instanceof DAMLOntologyImpl) {
161
162 DAMLOntologyImpl onto = (DAMLOntologyImpl) res;
163
164
165 try {
166 Statement s = onto.getProperty(RDFS.label);
167 this.setLabel(s.getObject().toString());
168 } catch (RDFException rdfex) {
169 this.setLabel("");
172 }
173
174 if ( null != onto.prop_comment().getValue()) {
175 this.setComment(onto.prop_comment().getValue().toString());
176 }
177
178 if (null != onto.prop_versionInfo()) {
179 LiteralAccessor la = onto.prop_versionInfo();
180 NodeIterator niValues = la.getValues();
181 if (niValues.hasNext()) {
182 this.setVersion(niValues.next().toString());
183 }
184 }
186
187 {
188 String luri = onto.getURI();
189 if (null == luri) {
190 this.setSourceURI("");
191 } else {
192 int ix = luri.indexOf('#');
193 if (-1 != ix) {
194 this.setSourceURI(luri.substring(0,ix));
195 this.setId(luri.substring(ix+1));
196 } else {
197 this.setSourceURI(onto.getURI());
198 } } } } }
204 }
206
207
208 Iterator cli = this.getClasses().iterator();
209 while(cli.hasNext()) {
210 OClass ocl = (OClass)cli.next();
211 if ( -1 == ocl.getURI().indexOf('#')) {
212 ocl.setURI(this.getSourceURI()+'#'+ocl.getURI());
213 }
214 }
216
217 ri = model.listSubjects();
218 while (ri.hasNext()) {
219 res = ri.next();
220 if ( (res instanceof DAMLClass) && ! (res instanceof DAMLRestriction) ) {
221
222 clas = (DAMLClass) res;
223 if ( null == clas.getLocalName()) {
224 continue;
225 }
226 TClass oc = this.getClassByName(clas.getLocalName());
227 if ( null == oc ) {
228 throw new InvalidFormatException(
229 curl,"class not found by name = "+clas.getLocalName());
230 }
231
232 com.hp.hpl.mesa.rdf.jena.model.Property propSCO = RDFS.subClassOf;
233 StmtIterator subi = clas.listProperties(propSCO);
234 while(subi.hasNext()) {
235 Statement damlSub = (Statement)subi.next();
236 String obj = damlSub.getObject().toString();
237
238 if (obj.charAt(0) == '<' && obj.charAt(obj.length()-1) == '>') {
239 obj=obj.substring(1,obj.length()-1);
240 }
241 obj = obj.substring(obj.lastIndexOf("#")+1);
242 TClass sub = this.getClassByName(obj);
243
244 if ( null != sub )
245 oc.addSuperClass(sub);
246
247 } } }
251
254 Iterator classIter = model.listDAMLClasses();
256 while (classIter.hasNext()) {
257 DAMLClass theClass = (DAMLClass) classIter.next();
258 if ( null == theClass.getLocalName()) {
259 continue;
260 }
261
262 Iterator propIter =
263 theClass.getDefinedProperties(false);
264 TClass oc = this.getClassByName(theClass.getLocalName());
265 if (! (oc instanceof OClass) || oc == null)
268 continue;
269
270 OClass kbClass = (OClass) oc;
271
272 if (DEBUG) {
273 Out.println("==============================================");
274 Out.println("Class is: " + theClass.getLocalName());
275
276 Out.println("Properties: ");
277 Out.println("----------------");
278 }
279
280 HashMap propertiesMap = new HashMap();
281
282 while (propIter.hasNext()) {
283 Object prop = propIter.next();
284 if (! (prop instanceof DAMLProperty))
285 continue;
286 DAMLProperty property = (DAMLProperty) prop;
287 if (property.getLocalName() == null)
288 continue;
289 String propName = property.getLocalName();
290
291 if (DEBUG) {
292 Out.println("local name " + property.getLocalName());
293 Out.println("domains ");
294 }
295 boolean toAdd = true;
299 Iterator domainIter = property.getDomainClasses();
300 while (domainIter.hasNext()) {
301 DAMLClass theDomain = (DAMLClass) domainIter.next();
302 if (DEBUG)
303 Out.println(theDomain.getLocalName());
304 if (theDomain == null)
305 continue;
306 if (kbClass.getName().equals(theDomain.getLocalName()))
307 toAdd = true;
308 else
309 toAdd = false;
310 }
311 if (!toAdd)
312 continue;
313
314 if (DEBUG)
315 Out.println("range ");
316
317 addPropertyDefinition(property, propName, kbClass, propertiesMap);
318
319 if (DEBUG) Out.println("superproperties ");
320 Iterator superPropIter = property.getSuperProperties(true);
321 while (superPropIter.hasNext()) {
322 DAMLProperty superProp = (DAMLProperty) superPropIter.next();
323 if (superProp == null || superProp.getLocalName() == null)
324 continue;
325 if (DEBUG) Out.println(superProp.getLocalName());
326 ((gate.creole.ontology.Property) propertiesMap.get(propName)).
327 setSubPropertyOf(superProp.getLocalName());
328 }
329
330 }
332 addPropertyDefinitions(propertiesMap);
334
335 if (DEBUG) {
336 Out.println("Restrictions: ");
337 Out.println("----------------");
338 }
339
340 Iterator superIter = theClass.getSuperClasses();
341 while (superIter.hasNext()) {
342 Object supClass = superIter.next();
343 if (! (supClass instanceof DAMLClass) )
344 continue;
345 DAMLClass superClass = (DAMLClass) supClass;
346 if (superClass.isRestriction()) {
347 DAMLRestriction restriction = (DAMLRestriction) superClass;
348 if (DEBUG) {
349 Out.println("onProperty "
350 + restriction.prop_onProperty().getDAMLValue().getLocalName());
351 Out.println("toClass "
352 + restriction.prop_toClass().getDAMLValue());
353 Out.println("hasClass "
354 + restriction.prop_hasClass().getDAMLValue());
355 Out.println("hasClassQ "
356 + restriction.prop_hasClassQ().getDAMLValue());
357 Out.println("cardinality "
358 + restriction.prop_cardinality().getDAMLValue());
359 Out.println("cardinalityQ "
360 + restriction.prop_cardinalityQ().getDAMLValue());
361 }
362 String propName =
363 restriction.prop_onProperty().getDAMLValue().getLocalName();
364 if (propName == null)
365 continue;
366 String rangeName = null;
367 if (restriction.prop_toClass().getDAMLValue() != null) {
368 rangeName = restriction.prop_toClass().getDAMLValue().getLocalName();
369 } else if (restriction.prop_hasClass().getDAMLValue() != null) {
370 rangeName = restriction.prop_hasClass().getDAMLValue().getLocalName();
371 } else if (restriction.prop_hasClassQ().getDAMLValue() != null) {
372 rangeName = restriction.prop_hasClassQ().getDAMLValue().getLocalName();
373 }
374
375
376 gate.creole.ontology.Property theNewProperty = null;
377 gate.creole.ontology.Property thePropDefinition =
378 (gate.creole.ontology.Property) propertiesMap.get(propName);
379 if (thePropDefinition == null) {
380 thePropDefinition =
382 searchSuperClasses(propName, theClass, propertiesMap);
383 }
384 if (thePropDefinition == null) {
386 Out.println("Warning: Ignoring restriction on property " + propName +
387 " because cannot find such property defined for this class");
388 } else {
389 if (thePropDefinition instanceof ObjectProperty) {
391 TClass rangeClass = this.getClassByName(rangeName);
392
393 if (rangeClass == null || !(rangeClass instanceof OClass))
394 rangeClass = (OClass)((ObjectProperty) thePropDefinition).getRange();
395
396 theNewProperty = this.addObjectProperty(
397 thePropDefinition.getName(),
398 kbClass,
399 (OClass) rangeClass);
400 } else {
401 theNewProperty = this.addDatatypeProperty(
402 thePropDefinition.getName(),
403 kbClass,
404 rangeName);
405 }
406 }
408
409 } }
412 }
414 }
416
417 if (DEBUG) {
418 Out.println("Property definitions for the ontology");
419 Set propertyDefs = this.getPropertyDefinitions();
420 if (propertyDefs != null ) {
421 Iterator iter = propertyDefs.iterator();
422 while (iter.hasNext())
423 Out.println( iter.next().toString());
424 }
425
426 Out.println("Classes: ");
427 Iterator ic = this.getClasses().iterator();
428 while (ic.hasNext()) {
429 OClass cl = (OClass)ic.next();
430 Out.println(" ");
431 Out.println(" " +cl+ " [direct sub classes = "+
432 cl.getSubClasses(OClass.DIRECT_CLOSURE).size()+"] "+
433 "[transitive sub classes = "+
434 cl.getSubClasses(OClass.TRANSITIVE_CLOSURE).size()+"]" +
435 "[direct super classes = " +
436 cl.getSuperClasses(OClass.DIRECT_CLOSURE).size() + " ] " +
437 "[transitive super classes = " +
438 cl.getSuperClasses(OClass.TRANSITIVE_CLOSURE).size() + "]");
439
440 if (cl instanceof OClass) {
441 OClass kbCl = (OClass) cl;
442 if (kbCl.getProperties() == null)
443 continue;
444 Iterator ip = kbCl.getProperties().iterator();
445 while (ip.hasNext()) {
446 Out.println( ip.next().toString());
447 }
448 }
449 }
450 }
452
453 } catch (Exception e) {
454 throw new ResourceInstantiationException(e);
455 }
456
457 this.setModified(false);
458
459 return model;
460 }
462 private gate.creole.ontology.Property addPropertyDefinition(
463 DAMLProperty property, String propName, OClass kbClass,
464 Map propertiesMap) throws RDFException{
465 gate.creole.ontology.Property newProperty = null;
466 PropertyAccessor propAcc = property.prop_range();
467 if (property instanceof DAMLDatatypeProperty) {
468 newProperty =
471 new DatatypePropertyImpl(propName, kbClass, (String) null, this);
472 propertiesMap.put(propName, newProperty);
473 } else if (propAcc instanceof LiteralAccessor) {
474 if (DEBUG) Out.println("Literal accessor");
475 if (((LiteralAccessor)propAcc).getValue() != null) {
477 newProperty = new DatatypePropertyImpl(propName, kbClass,
478 ((LiteralAccessor)propAcc).getValue().getString(), this);
479 propertiesMap.put(propName, newProperty);
480 if (DEBUG)
481 Out.println(((LiteralAccessor)propAcc).getValue());
482 }
483 } else if (property instanceof DAMLObjectProperty) {
484 if (DEBUG)
485 Out.println(propAcc.getDAMLValue());
486 if (propAcc.getDAMLValue() == null) {
487 if (DEBUG)
488 Out.println("Found a null value, adding as null");
489 newProperty = new ObjectPropertyImpl(propName, kbClass, null, this);
490 propertiesMap.put(propName, newProperty);
491 } else {
492 if (DEBUG)
493 Out.println(propAcc.getDAMLValue().getLocalName());
494 TClass rangeClass =
495 this.getClassByName(propAcc.getDAMLValue().getLocalName());
496 if (rangeClass == null || !(rangeClass instanceof OClass)) {
497 newProperty = new ObjectPropertyImpl(propName, kbClass, null, this);
498 propertiesMap.put(propName, newProperty);
499 } else {
500 newProperty =
501 new ObjectPropertyImpl(propName, kbClass, (OClass) rangeClass, this);
502 propertiesMap.put(propName, newProperty);
503 }
504 }
505 }
506 return newProperty;
507 }
508
509 private gate.creole.ontology.Property searchSuperClasses(String propName, DAMLClass theClass,
510 Map propertiesMap)
511 throws RDFException{
512 if (DEBUG)
513 Out.println("searchSuperClasses called: propName" +
514 propName + "; className " + theClass.getLocalName());
515 if (theClass == null)
516 return null;
517 if (propName == null)
518 return null;
519
520 gate.creole.ontology.Property theProperty =
521 this.getPropertyDefinitionByName(propName);
522 String propDomainName = null;
523 if (theProperty == null) {
526 if (DEBUG) Out.println("Cannot find property definition" + propName);
527
528 Iterator iter = theClass.getDefinedProperties(true);
529 boolean propFound = false;
530 while (iter.hasNext() && !propFound) {
531 DAMLProperty property = (DAMLProperty) iter.next();
532 if (property.getLocalName().equals(propName)
533 && property.getDomainClasses().hasNext()) {
534 propDomainName =
535 ((DAMLClass) property.getDomainClasses().next()).getLocalName();
536 propFound = true;
537 if (DEBUG)
538 Out.println("Domain is: " + propDomainName);
539 TClass kbClass = this.getClassByName(propDomainName);
540 if (kbClass != null && kbClass instanceof OClass) {
541 theProperty =
542 this.addPropertyDefinition(
543 property, propName, (OClass) kbClass, propertiesMap);
544 } } } if (!propFound) {
548 Out.println("Warning: Found restriction on property " + propName +
549 " for class " +
550 theClass.getLocalName() +
551 "which has undefined domain or its domain does not" +
552 "match the given class");
553 Iterator propIter = model.listDAMLProperties();
554 while (propIter.hasNext()) {
555 DAMLProperty property = (DAMLProperty) propIter.next();
556 if (property.getLocalName().equals(propName))
557 theProperty =
558 this.addPropertyDefinition(
559 property, propName, null, propertiesMap);
560 }
561 }
562 } else {
563 propDomainName = theProperty.getDomain().getName();
564 boolean found = false;
565 Iterator cIter = theClass.getSuperClasses(true);
568 while (cIter.hasNext() && !found) {
569 if (propDomainName.equals( ((DAMLClass) cIter.next()).getLocalName()))
570 found = true;
571 }
572 if (!found)
573 theProperty = null;
574 }
575 return theProperty;
576
577 }
578
579 private boolean isRelationDefinedOnSuperClass(OClass kbClass, String domainName) {
580 boolean result = false;
581 Set superClasses = null;
582 try {
583 superClasses = kbClass.getSuperClasses(OClass.TRANSITIVE_CLOSURE);
584 } catch (gate.creole.ontology.NoSuchClosureTypeException ex) {}
585 if (superClasses == null || superClasses.isEmpty())
586 return false;
587 Iterator iter = superClasses.iterator();
588 while (iter.hasNext()) {
589 if (((OClass) iter.next()).getName().equals(domainName))
590 return true;
591 }
592 return result;
593 }
594 private void addPropertyDefinitions(HashMap propertiesMap) {
595 Iterator iter = propertiesMap.keySet().iterator();
596 while (iter.hasNext()) {
597 String propertyName = (String) iter.next();
598 if (this.getPropertyDefinitionByName(propertyName) != null)
600 continue;
601 this.addPropertyDefinition(
602 (gate.creole.ontology.Property) propertiesMap.get(propertyName));
603 }
604 }
605
606 private void addRemainingProperties(HashMap propertiesMap) {
607 if (propertiesMap == null || propertiesMap.isEmpty())
608 return;
609
610 Iterator iter = propertiesMap.keySet().iterator();
611 while (iter.hasNext()) {
612 String propertyName = (String) iter.next();
613 gate.creole.ontology.Property theProperty =
614 (gate.creole.ontology.Property) propertiesMap.get(propertyName);
615
616 if (theProperty instanceof ObjectProperty) {
618 this.addObjectProperty(theProperty.getName(),
619 theProperty.getDomain(),
620 (OClass)((ObjectProperty)theProperty).getRange());
621 } else {
622 this.addDatatypeProperty(theProperty.getName(),
623 theProperty.getDomain(),
624 (String)((DatatypeProperty)theProperty).getRange());
625 }
626 }
627
628 }
629
630 public void store() throws gate.creole.ResourceInstantiationException {
631 DAMLModel theModel = storeAndGetModel();
632 writeModel(theModel);
633 System.out.println("No storage of instances and properties implemented yet!");
634 }
635
636 protected void writeModel(DAMLModel model) throws ResourceInstantiationException {
637 try {
638
639 Writer writer = new FileWriter(this.getURL().getFile());
640 RDFWriter rdfWriter = model.getWriter("RDF/XML-ABBREV");
641 rdfWriter.write(model, writer, this.getSourceURI());
642 } catch (Exception e) {
643 throw new ResourceInstantiationException(e);
644 }
645 }
646
647
648 protected DAMLModel storeAndGetModel()throws ResourceInstantiationException {
649 DAMLModel model = new DAMLModelImpl();
650
651 try {
652
655 this.setModified(true);
656
657
658 DAMLVocabulary voc = DAML_OIL.getInstance();
659 com.hp.hpl.jena.daml.DAMLOntology onto =
660 new DAMLOntologyImpl(
661 this.getSourceURI(),
662 this.getLabel(),
663 model,
664 voc);
665
666
667
668 com.hp.hpl.mesa.rdf.jena.model.Property propVersion =
669 model.createProperty(voc.versionInfo().getURI());
670 onto.addProperty(propVersion,this.getVersion());
671
672 com.hp.hpl.mesa.rdf.jena.model.Property propLabel =
673 model.createProperty(RDFS.label.getURI());
674 onto.addProperty(propLabel,this.getLabel());
675
676 com.hp.hpl.mesa.rdf.jena.model.Property propComment =
677 model.createProperty(RDFS.comment.getURI());
678 onto.addProperty(propComment,this.getComment());
679
680
681 com.hp.hpl.mesa.rdf.jena.model.Property propSubClassOf =
682 model.createProperty(RDFS.subClassOf.getURI());
683
684
685
686 Iterator classes = this.getClasses().iterator();
687 OClass clas;
688 DAMLClass dclas;
689 while (classes.hasNext()) {
690 clas = (OClass) classes.next();
691
692 dclas = model.createDAMLClass(clas.getURI());
693 dclas.addProperty(propLabel,clas.getName());
694 if (null != clas.getComment()) {
695 dclas.addProperty(propComment,clas.getComment());
696 }
697
698
699 Iterator sups = clas.getSuperClasses(clas.DIRECT_CLOSURE).iterator();
700 OClass supClass;
701 while (sups.hasNext()) {
702 supClass = (OClass) sups.next();
703 dclas.addProperty(propSubClassOf,supClass.getURI());
704 }
706
707 }
709
710
711 } catch (Exception e) {
712 throw new ResourceInstantiationException(e);
713 }
714
715 this.setModified(false);
716 return model;
717 }
719
720 }