1   /*
2    * JenaOntologyImpl.java
3    *
4    * Copyright (c) 2005, The University of Sheffield.
5    *
6    * This file is part of GATE (see http://gate.ac.uk/), and is free
7    * software, licenced under the GNU Library General Public License,
8    * Version 2, June1991.
9    *
10   * A copy of this licence is included in the distribution in the file
11   * licence.html, and is also available at http://gate.ac.uk/gate/licence.html.
12   *
13   * Valentin Tablan 09/2005
14   *
15   *
16   *  $Id$
17   */
18  package gate.creole.ontology.jena;
19  
20  import gate.Resource;
21  import gate.creole.ResourceInstantiationException;
22  import gate.creole.ontology.*;
23  import gate.creole.ontology.Property;
24  import gate.creole.ontology.ObjectProperty;
25  import gate.creole.ontology.DatatypeProperty;
26  import gate.gui.ActionsPublisher;
27  import gate.gui.MainFrame;
28  import gate.util.Err;
29  import gate.util.GateRuntimeException;
30  import gate.util.Out;
31  import java.awt.event.ActionEvent;
32  import java.io.*;
33  import java.net.URL;
34  import java.util.*;
35  import javax.swing.*;
36  import com.hp.hpl.jena.ontology.*;
37  import com.hp.hpl.jena.rdf.model.*;
38  import com.hp.hpl.jena.util.iterator.ExtendedIterator;
39  import com.ontotext.gate.ontology.OntologyImpl;
40  
41  /**
42   * An implementation for GATE Ontologies based on Jena2
43   * 
44   * @author Valentin Tablan
45   * 
46   */
47  public class JenaOntologyImpl extends OntologyImpl implements ActionsPublisher {
48    public JenaOntologyImpl() {
49      actionsList = new ArrayList();
50      actionsList.add(new LoadOntologyDataAction("Load OWL-Lite data",
51              "Reads OWL-Lite data from a file and populates the ontology.",
52              OWL_LITE));
53      actionsList
54              .add(new LoadOntologyDataAction(
55                      "Load OWL-DL data",
56                      "Reads OWL-DL data from a file and populates the ontology.",
57                      OWL_DL));
58      actionsList.add(new LoadOntologyDataAction("Load OWL-Full data",
59              "Reads OWL-Full data from a file and populates the ontology.",
60              OWL_FULL));
61      actionsList.add(new LoadOntologyDataAction("Load RDF(S) data",
62              "Reads RDF(S) data from a file and populates the ontology.", RDFS));
63  //    actionsList.add(new LoadOntologyDataAction("Load DAML data",
64  //            "Reads DAML data from a file and populates the ontology.", DAML));
65      actionsList.add(null);
66      actionsList.add(new CleanUpAction());
67      actionsList.add(null);
68      actionsList.add(new SaveOntologyAction("Save to file",
69              "Saves the ontology to a file", OWL_LITE));
70    }
71  
72    public Resource init() throws ResourceInstantiationException {
73      load();
74      return this;
75    }
76  
77    /*
78     * (non-Javadoc)
79     * 
80     * @see gate.gui.ActionsPublisher#getActions()
81     */
82    public List getActions() {
83      return actionsList;
84    }
85  
86    /**
87     * Loads the ontology from an external file.
88     */
89    public void load() throws ResourceInstantiationException {
90      // find what type of ontolgoy are we loading
91      URL inputURL = null;
92      int ontologyType = -1;
93      if(owlLiteFileURL != null) {
94        inputURL = owlLiteFileURL;
95        ontologyType = OWL_LITE;
96      } else if(owlDlFileURL != null) {
97        inputURL = owlDlFileURL;
98        ontologyType = OWL_DL;
99      } else if(owlFullFileURL != null) {
100       inputURL = owlFullFileURL;
101       ontologyType = OWL_FULL;
102     } else if(rdfsFileURL != null) {
103       inputURL = rdfsFileURL;
104       ontologyType = RDFS;
105     } else if(damlFileURL != null) {
106       inputURL = damlFileURL;
107       ontologyType = DAML;
108     } else {
109       // no input file provided - create an empty OWL Lite ontology
110       inputURL = null;
111       ontologyType = OWL_LITE;
112     }
113     super.setURL(inputURL);
114     load(inputURL, ontologyType);
115   }
116 
117   /**
118    * Loads ontological data of a given type from a URL.
119    * 
120    * @param inputURL
121    *          the URL for the file to be read.
122    * @param ontologyType
123    *          the type of ontology (one of {@link #OWL_LITE}, {@link #OWL_DL},
124    *          {@link #OWL_FULL}, {@link #RDFS} or {@link #DAML}).
125    */
126   public void load(URL inputURL, int ontologyType)
127           throws ResourceInstantiationException {
128     // build the Jena model
129     // we need some type of inference here in order to get all triples (i.e.
130     // including the inferred ones)
131     OntModel jenaModel = null;
132     switch(ontologyType){
133       case OWL_LITE:
134         jenaModel = ModelFactory
135                 .createOntologyModel(OntModelSpec.OWL_LITE_MEM_RDFS_INF);
136         break;
137       case OWL_DL:
138         jenaModel = ModelFactory
139                 .createOntologyModel(OntModelSpec.OWL_DL_MEM_RDFS_INF);
140         break;
141       case OWL_FULL:
142         jenaModel = ModelFactory
143                 .createOntologyModel(OntModelSpec.OWL_MEM_RDFS_INF);
144         break;
145       case RDFS:
146         jenaModel = ModelFactory
147                 .createOntologyModel(OntModelSpec.RDFS_MEM_RDFS_INF);
148         break;
149       case DAML:
150         jenaModel = ModelFactory
151                 .createOntologyModel(OntModelSpec.DAML_MEM_RDFS_INF);
152         break;
153       default:
154         throw new ResourceInstantiationException("Ontology type not specified!");
155     }
156     if(inputURL != null) {
157       try {
158         jenaModel.read(new BufferedInputStream(inputURL.openStream()), "");
159         // get the default name space
160         String defaultURIPrefix = jenaModel.getNsPrefixURI("");
161         if(defaultURIPrefix != null) setDefaultNameSpace(defaultURIPrefix);
162       } catch(IOException ioe) {
163         throw new ResourceInstantiationException(ioe);
164       }
165     }
166     if(this.getPropertyDefinitionByName("label") == null) {
167       // add labels as properties of everything
168       Set range = new HashSet();
169       range.add(String.class);
170       addProperty("label", "label property", new HashSet(), range);
171     }
172     // convert the Jena model into a GATE ontology
173     // create the class hierarchy
174     ExtendedIterator topClassIter = jenaModel.listHierarchyRootClasses();
175     while(topClassIter.hasNext()) {
176       OntClass aTopClass = (OntClass)topClassIter.next();
177       toGateClassRec(aTopClass, null);
178     }
179     // create the properties
180     Iterator propIter = jenaModel.listOntProperties();
181     while(propIter.hasNext()) {
182       OntProperty aJenaProperty = (OntProperty)propIter.next();
183       if(aJenaProperty.isOntLanguageTerm()) continue;
184       String propertyName = aJenaProperty.getLocalName();
185       String propertyComment = aJenaProperty.getComment(language);
186       Set gateDomain = convertoToGateClasses(aJenaProperty.listDomain());
187       reduceToMostSpecificClasses(gateDomain);
188       Property theProp = null;
189       if(ontologyType != RDFS && aJenaProperty.isObjectProperty()) {
190         Set gateRange = convertoToGateClasses(aJenaProperty.listRange());
191         reduceToMostSpecificClasses(gateRange);
192         theProp = addObjectProperty(propertyName, propertyComment, gateDomain,
193                 gateRange);
194       } else if(ontologyType != RDFS && aJenaProperty.isTransitiveProperty()) {
195         Set gateRange = convertoToGateClasses(aJenaProperty.listRange());
196         reduceToMostSpecificClasses(gateRange);
197         theProp = addTransitiveProperty(propertyName, propertyComment,
198                 gateDomain, gateRange);
199       } else if(ontologyType != RDFS && ontologyType != DAML
200               && aJenaProperty.isSymmetricProperty()) {
201         Set gateRange = convertoToGateClasses(aJenaProperty.listRange());
202         reduceToMostSpecificClasses(gateRange);
203         theProp = addSymmetricProperty(propertyName, propertyComment,
204                 gateDomain, gateRange);
205       } else if(ontologyType != RDFS && aJenaProperty.isDatatypeProperty()) {
206         Iterator rangeIter = aJenaProperty.listRange();
207         Set range = new HashSet();
208         while(rangeIter.hasNext())
209           range.add(rangeIter.next());
210         if(!range.isEmpty()) {
211           Out.prln("WARNING: Support for datatype properties ranges is not "
212                   + "implemented!\nRange " + range.toString()
213                   + " for property " + aJenaProperty.getLocalName()
214                   + " has been ignored!");
215         }
216         theProp = addDatatypeProperty(propertyName, propertyComment,
217                 gateDomain, Object.class);
218       } else {
219         // generic type of property
220         if(ontologyType == OWL_LITE || ontologyType == OWL_DL
221                 || ontologyType == OWL_FULL) {
222           Err.prln("WARNING: Property: \"" + aJenaProperty.toString() + "\""
223                   + " is neither an object or a datatype property!");
224         }
225         Set gateRange = convertoToGateClasses(aJenaProperty.listRange());
226         theProp = addProperty(propertyName, propertyComment, gateDomain,
227                 gateRange);
228       }
229       theProp.setURI(aJenaProperty.getURI());
230       if(ontologyType != RDFS) {
231         theProp.setFunctional(aJenaProperty.isFunctionalProperty());
232         theProp.setInverseFunctional(aJenaProperty
233                 .isInverseFunctionalProperty());
234       }
235     }
236     // create the properties hierarchy
237     propIter = jenaModel.listOntProperties();
238     while(propIter.hasNext()) {
239       OntProperty aJenaProp = (OntProperty)propIter.next();
240       Property aGateProp = getPropertyDefinitionByName(aJenaProp.getLocalName());
241       for(Iterator superIter = aJenaProp.listSuperProperties(); superIter
242               .hasNext();) {
243         OntProperty aJenaSuperProp = (OntProperty)superIter.next();
244         if(aJenaSuperProp.isOntLanguageTerm()) continue;
245         Property aGateSuperProp = getPropertyDefinitionByName(aJenaSuperProp
246                 .getLocalName());
247         if(aGateSuperProp == null) {
248           Err.prln("WARNING: Unknown super property \""
249                   + aJenaSuperProp.getLocalName() + "\" for property \""
250                   + aJenaProp.getLocalName() + "\"!");
251         } else {
252           aGateProp.addSuperProperty(aGateSuperProp);
253           aGateSuperProp.addSubProperty(aGateProp);
254         }
255       }
256     }
257     // read the instances
258     Iterator instanceIter = jenaModel.listIndividuals();
259     while(instanceIter.hasNext()) {
260       Individual aJenaInstance = (Individual)instanceIter.next();
261       Set jenaClasses = new HashSet();
262       Iterator classIter = aJenaInstance.listRDFTypes(true);
263       while(classIter.hasNext()) {
264         OntClass aClass = (OntClass)((com.hp.hpl.jena.rdf.model.Resource)classIter
265                 .next()).as(OntClass.class);
266         jenaClasses.add(aClass);
267       }
268       Set gateClasses = convertoToGateClasses(jenaClasses.iterator());
269       OInstance gateInstance = new OInstanceImpl(aJenaInstance.getLocalName(),
270               aJenaInstance.getComment(language), gateClasses, this);
271       addInstance(gateInstance);
272       String label = aJenaInstance.getLabel(language);
273       // if(label!=null)
274       // gateInstance.addPropertyValue("label", label);
275     }
276     // add the property values
277     instanceIter = jenaModel.listIndividuals();
278     while(instanceIter.hasNext()) {
279       Individual aJenaInstance = (Individual)instanceIter.next();
280       OInstance aGateInstance = getInstanceByName(aJenaInstance.getLocalName());
281       propIter = aJenaInstance.listProperties();
282       while(propIter.hasNext()) {
283         Statement propStatement = (Statement)propIter.next();
284         com.hp.hpl.jena.rdf.model.Property aProperty = (com.hp.hpl.jena.rdf.model.Property)(propStatement)
285                 .getPredicate();
286         RDFNode objectNode = propStatement.getObject();
287         Property aGateProperty = getPropertyDefinitionByName(aProperty
288                 .getLocalName());
289         if(aGateProperty == null) {
290           // Err.prln("Property not found " + aProperty.getURI() + " type: " +
291           // aProperty.getClass().getName());
292           continue;
293         }
294         if(aGateProperty instanceof ObjectProperty) {
295           if(objectNode.canAs(Individual.class)) {
296             Individual aJenaValue = (Individual)objectNode.as(Individual.class);
297             OInstance gateValue = getInstanceByName(aJenaValue.getLocalName());
298             boolean success = aGateInstance.addPropertyValue(aProperty
299                     .getLocalName(), gateValue);
300             if(!success)
301               Err.prln("Could not set value \"" + gateValue
302                       + "\" for property \"" + aProperty + "\" on instance "
303                       + aGateInstance.getName());
304           } else {
305             Err.prln("WARNING: object property " + aGateProperty.getName()
306                     + " has a value which is not an object "
307                     + objectNode.toString());
308           }
309         } else {
310           // datatype property
311           if(objectNode.canAs(Literal.class)) {
312             Literal aJenaValue = (Literal)objectNode.as(Literal.class);
313             Object aGateValue = aJenaValue.getDatatype() == null ? aJenaValue
314                     .getLexicalForm() : aJenaValue.getDatatype().parse(
315                     aJenaValue.getLexicalForm());
316             boolean success = aGateInstance.addPropertyValue(aGateProperty
317                     .getName(), aGateValue);
318             if(!success)
319               Err.prln("Could not set value \"" + aGateValue.toString()
320                       + "\" for property \"" + aProperty + "\" on instance "
321                       + aGateInstance.getName());
322           } else {
323             Err.prln("WARNING: datatype property " + aGateProperty.getName()
324                     + " has a value which is not an RDF literal "
325                     + objectNode.toString());
326           }
327         }
328       }
329     }
330   }
331 
332   /**
333    * Saves the ontology to a file.
334    * 
335    * @param outputFile
336    *          the file to write to.
337    * @param ontologyType
338    *          the output format to write.
339    */
340   public void save(File outputFile, int ontologyType) {
341     OntModel jenaModel = null;
342     switch(ontologyType){
343       case OWL_LITE:
344         jenaModel = ModelFactory
345                 .createOntologyModel(OntModelSpec.OWL_LITE_MEM);
346         break;
347       default:
348         throw new IllegalArgumentException("Ontology type " + ontologyType
349                 + " is not supported!");
350     }
351     // set the default URI
352     jenaModel.setNsPrefix("", getDefaultNameSpace());
353     // create the class hierarchy
354     Iterator topClassIter = getTopClasses().iterator();
355     while(topClassIter.hasNext()) {
356       OClass aGateClass = (OClass)topClassIter.next();
357       toJenaClassRec(aGateClass, jenaModel, null);
358     }
359     // create the properties
360     Iterator propIter = getPropertyDefinitions().iterator();
361     while(propIter.hasNext()) {
362       Property aGateProp = (Property)propIter.next();
363       OntProperty aJenaProp = null;
364       if(aGateProp instanceof ObjectProperty) {
365         aJenaProp = jenaModel.createObjectProperty(aGateProp.getURI());
366         Iterator rangIter = ((ObjectProperty)aGateProp).getRange().iterator();
367         while(rangIter.hasNext()) {
368           OClass aGateRangeClass = (OClass)rangIter.next();
369           OntClass aJenaRangeClass = jenaModel.getOntClass(aGateRangeClass
370                   .getURI());
371           aJenaProp.addRange(aJenaRangeClass);
372         }
373       } else if(aGateProp instanceof DatatypeProperty) {
374         aJenaProp = jenaModel.createDatatypeProperty(aGateProp.getURI());
375       }
376       aJenaProp.setLabel(aGateProp.getName(), language);
377       String comment = aGateProp.getComment();
378       if(comment != null) aJenaProp.setComment(comment, language);
379       // set the domain
380       Iterator domainIter = aGateProp.getDomain().iterator();
381       while(domainIter.hasNext()) {
382         OClass aGateDomainClass = (OClass)domainIter.next();
383         OntClass aJenaDomainClass = jenaModel.getOntClass(aGateDomainClass
384                 .getURI());
385         aJenaProp.addDomain(aJenaDomainClass);
386       }
387     }
388     // create the properties hierarchy
389     propIter = jenaModel.listObjectProperties();
390     while(propIter.hasNext()) {
391       com.hp.hpl.jena.ontology.ObjectProperty aJenaProp = (com.hp.hpl.jena.ontology.ObjectProperty)propIter
392               .next();
393       Property aGateProp = getPropertyDefinitionByName(aJenaProp.getLocalName());
394       Iterator superPropIter = aGateProp.getSuperProperties(DIRECT_CLOSURE)
395               .iterator();
396       while(superPropIter.hasNext()) {
397         Property aGateSuperProp = (Property)superPropIter.next();
398         OntProperty aJenaSuperProp = jenaModel.getOntProperty(aGateSuperProp
399                 .getURI());
400         aJenaProp.addSuperProperty(aJenaSuperProp);
401       }
402     }
403     // create the instances
404     // we need to keep track of anonymous nodes - use two synchronised lists
405     List gateInstances = new ArrayList(getInstances());
406     List jenaInstances = new ArrayList(gateInstances.size());
407     for(int i = 0; i < gateInstances.size(); i++) {
408       OInstance aGateInstace = (OInstance)gateInstances.get(i);
409       String instanceURI = aGateInstace.getURI();
410       Set types = aGateInstace.getOClasses();
411       Iterator typeIter = types.iterator();
412       // get the first type and use for creation
413       OClass aGateType = (OClass)typeIter.next();
414       OntClass aJenaType = jenaModel.getOntClass(aGateType.getURI());
415       Individual aJenaIndiv = instanceURI == null ? jenaModel
416               .createIndividual(aJenaType) : jenaModel.createIndividual(
417               instanceURI, aJenaType);
418       jenaInstances.add(aJenaIndiv);
419       // add all the remaining types, if any
420       while(typeIter.hasNext()) {
421         aGateType = (OClass)typeIter.next();
422         aJenaType = jenaModel.getOntClass(aGateType.getURI());
423         aJenaIndiv.addRDFType(aJenaType);
424       }
425     }
426     // add the property values for all instances
427     for(int i = 0; i < gateInstances.size(); i++) {
428       OInstance aGateInstace = (OInstance)gateInstances.get(i);
429       Individual aJenaIndiv = (Individual)jenaInstances.get(i);
430       Iterator propNameIter = aGateInstace.getSetPropertiesNames().iterator();
431       while(propNameIter.hasNext()) {
432         String propertyName = (String)propNameIter.next();
433         Property aProperty = getPropertyDefinitionByName(propertyName);
434         OntProperty aJenaProp = jenaModel.getOntProperty(aProperty.getURI());
435         Iterator valuesIter = aGateInstace.getPropertyValues(propertyName)
436                 .iterator();
437         while(valuesIter.hasNext()) {
438           Object value = valuesIter.next();
439           if(value instanceof OInstance) {
440             // object value
441             OInstance instanceValue = (OInstance)value;
442             String instURI = instanceValue.getURI();
443             Individual jenaInstValue = null;
444             if(instURI != null) {
445               jenaInstValue = jenaModel.getIndividual(instURI);
446             } else {
447               jenaInstValue = (Individual)jenaInstances.get(gateInstances
448                       .indexOf(instanceValue));
449             }
450             aJenaIndiv.addProperty(aJenaProp, jenaInstValue);
451           } else {
452             // datatype value
453             aJenaIndiv.addProperty(aJenaProp, value);
454           }
455         }
456       }
457     }
458     // save to the file
459     try {
460       jenaModel.write(new FileOutputStream(outputFile), "RDF/XML-ABBREV");
461     } catch(IOException ioe) {
462       throw new GateRuntimeException(ioe);
463     }
464   }
465 
466   /**
467    * Converts a GATE class and all its subclasses (recursively) to Jena classes
468    * and adds them to the Jena model provided.
469    * 
470    * @param aClass
471    *          the GATE class to be converted.
472    * @param jenaModel
473    *          the Jena model to be populated.
474    * @param parentClass
475    *          the parent of the GATE class in the Jena model. If <tt>null</tt>
476    *          then the created Jena class will be marked as a top class.
477    */
478   protected void toJenaClassRec(OClass aGateClass, OntModel jenaModel,
479           OntClass parentClass) {
480     OntClass jenaClass = jenaModel.createClass(aGateClass.getURI());
481     jenaClass.setLabel(aGateClass.getName(), language);
482     if(parentClass != null) jenaClass.addSuperClass(parentClass);
483     String comment = aGateClass.getComment();
484     if(comment != null) jenaClass.setComment(comment, language);
485     // make the recursive calls
486     Iterator subClassIter = aGateClass.getSubClasses(DIRECT_CLOSURE).iterator();
487     while(subClassIter.hasNext()) {
488       toJenaClassRec((OClass)subClassIter.next(), jenaModel, jenaClass);
489     }
490   }
491 
492   protected Set convertoToGateClasses(Iterator jenaIterator) {
493     Set result = new HashSet();
494     while(jenaIterator.hasNext()) {
495       com.hp.hpl.jena.rdf.model.Resource aResource = (com.hp.hpl.jena.rdf.model.Resource)jenaIterator
496               .next();
497       if(aResource.canAs(OntClass.class)) {
498         OntClass aJenaClass = (OntClass)aResource.as(OntClass.class);
499         OClass aGateClass = (OClass)getClassByName(aJenaClass.getLocalName());
500         if(aGateClass == null) {
501           Err.prln("WARNING: class \"" + aJenaClass.getLocalName()
502                   + "\" not found!");
503         } else {
504           result.add(aGateClass);
505         }
506       }
507     }
508     return result;
509   }
510 
511   /**
512    * Converts a Jena class and all its subclasses to GATE classes and adds them
513    * to this ontology.
514    * 
515    * @param aClass
516    *          the Class in Jena model
517    * @param parent
518    *          the parent class for the class to be added in this ontology.
519    */
520   protected void toGateClassRec(OntClass jenaClass, OClass parent) {
521     // create the class
522     String uri = jenaClass.getURI();
523     String name = jenaClass.getLocalName();
524     String comment = jenaClass.getComment(language);
525     String classLabel = jenaClass.getLabel(language);
526     // check whether the class exists already
527     OClass aClass = (OClass)getClassByName(name);
528     if(aClass == null) {
529       // if class not found, create a new one
530       aClass = new OClassImpl(uri, name, comment, this);
531       if(uri != null) aClass.setURI(uri);
532       addClass(aClass);
533       if(classLabel != null) aClass.addPropertyValue("label", classLabel);
534     }
535     // create the hierachy
536     if(parent != null) {
537       aClass.addSuperClass(parent);
538       parent.addSubClass(aClass);
539     }
540     // make the recursive calls
541     ExtendedIterator subClassIter = jenaClass.listSubClasses(true);
542     while(subClassIter.hasNext()) {
543       OntClass subJenaClass = (OntClass)subClassIter.next();
544       toGateClassRec(subJenaClass, aClass);
545     }
546   }
547 
548   /*
549    * (non-Javadoc)
550    * 
551    * @see gate.creole.AbstractLanguageResource#cleanup()
552    */
553   public void cleanup() {
554     super.cleanup();
555     Iterator instIter = new ArrayList(getInstances()).iterator();
556     while(instIter.hasNext()) {
557       removeInstance((OInstance)instIter.next());
558     }
559     Iterator classIter = new ArrayList(getClasses()).iterator();
560     while(classIter.hasNext()) {
561       removeClass((TClass)classIter.next());
562     }
563     propertyDefinitionSet.clear();
564   }
565 
566   /**
567    * @return Returns the language.
568    */
569   public String getLanguage() {
570     return language;
571   }
572 
573   /**
574    * @param language
575    *          The language to set.
576    */
577   public void setLanguage(String language) {
578     this.language = language;
579   }
580 
581   /**
582    * @return Returns the damlFileURL.
583    */
584   public URL getDamlFileURL() {
585     return damlFileURL;
586   }
587 
588   /**
589    * @param damlFileURL
590    *          The damlFileURL to set.
591    */
592   public void setDamlFileURL(URL damlFileURL) {
593     this.damlFileURL = damlFileURL;
594   }
595 
596   /**
597    * @return Returns the owlDlFileURL.
598    */
599   public URL getOwlDlFileURL() {
600     return owlDlFileURL;
601   }
602 
603   /**
604    * @param owlDlFileURL
605    *          The owlDlFileURL to set.
606    */
607   public void setOwlDlFileURL(URL owlDlFileURL) {
608     this.owlDlFileURL = owlDlFileURL;
609   }
610 
611   /**
612    * @return Returns the owlFullFileURL.
613    */
614   public URL getOwlFullFileURL() {
615     return owlFullFileURL;
616   }
617 
618   /**
619    * @param owlFullFileURL
620    *          The owlFullFileURL to set.
621    */
622   public void setOwlFullFileURL(URL owlFullFileURL) {
623     this.owlFullFileURL = owlFullFileURL;
624   }
625 
626   /**
627    * @return Returns the owlLiteFileURL.
628    */
629   public URL getOwlLiteFileURL() {
630     return owlLiteFileURL;
631   }
632 
633   /**
634    * @param owlLiteFileURL
635    *          The owlLiteFileURL to set.
636    */
637   public void setOwlLiteFileURL(URL owlLiteFileURL) {
638     this.owlLiteFileURL = owlLiteFileURL;
639   }
640 
641   /**
642    * @return Returns the rdfsFileURL.
643    */
644   public URL getRdfsFileURL() {
645     return rdfsFileURL;
646   }
647 
648   /**
649    * @param rdfsFileURL
650    *          The rdfsFileURL to set.
651    */
652   public void setRdfsFileURL(URL rdfsFileURL) {
653     this.rdfsFileURL = rdfsFileURL;
654   }
655 
656   protected class LoadOntologyDataAction extends AbstractAction {
657     public LoadOntologyDataAction(String name, String description,
658             int ontologyType) {
659       super(name);
660       putValue(SHORT_DESCRIPTION, description);
661       this.ontologyType = ontologyType;
662     }
663 
664     public void actionPerformed(ActionEvent e) {
665       Runnable runnable = new Runnable() {
666         public void run() {
667           JFileChooser fileChooser = MainFrame.getFileChooser();
668           fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
669           fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
670           fileChooser.setMultiSelectionEnabled(false);
671           if(fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
672             File file = fileChooser.getSelectedFile();
673             try {
674               MainFrame.lockGUI("Loading model...");
675               load(file.toURL(), ontologyType);
676             } catch(Exception e) {
677               JOptionPane.showMessageDialog(null, "Error!\n" + e.toString(),
678                       "GATE", JOptionPane.ERROR_MESSAGE);
679               e.printStackTrace(Err.getPrintWriter());
680             } finally {
681               MainFrame.unlockGUI();
682             }
683           }
684         }
685       };
686       Thread thread = new Thread(runnable, "Ontology Loader");
687       thread.setPriority(Thread.MIN_PRIORITY);
688       thread.start();
689     }
690 
691     protected int ontologyType;
692   }
693   protected class SaveOntologyAction extends AbstractAction {
694     public SaveOntologyAction(String name, String description, int ontologyType) {
695       super(name);
696       putValue(SHORT_DESCRIPTION, description);
697       this.ontologyType = ontologyType;
698     }
699 
700     public void actionPerformed(ActionEvent e) {
701       Runnable runnable = new Runnable() {
702         public void run() {
703           JFileChooser fileChooser = MainFrame.getFileChooser();
704           fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
705           fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
706           fileChooser.setMultiSelectionEnabled(false);
707           if(fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
708             File file = fileChooser.getSelectedFile();
709             try {
710               MainFrame.lockGUI("Saving model...");
711               save(file, ontologyType);
712             } catch(Exception e) {
713               JOptionPane.showMessageDialog(null, "Error!\n" + e.toString(),
714                       "GATE", JOptionPane.ERROR_MESSAGE);
715               e.printStackTrace(Err.getPrintWriter());
716             } finally {
717               MainFrame.unlockGUI();
718             }
719           }
720         }
721       };
722       Thread thread = new Thread(runnable, "Ontology Loader");
723       thread.setPriority(Thread.MIN_PRIORITY);
724       thread.start();
725     }
726 
727     protected int ontologyType;
728   }
729   protected class CleanUpAction extends AbstractAction {
730     public CleanUpAction() {
731       super("Clean ontology");
732       putValue(SHORT_DESCRIPTION, "Deletes all data rom this ontology");
733     }
734 
735     public void actionPerformed(ActionEvent e) {
736       Runnable runnable = new Runnable() {
737         public void run() {
738           try {
739             MainFrame.lockGUI("Cleaning up...");
740             cleanup();
741           } catch(Exception e) {
742             JOptionPane.showMessageDialog(null, "Error!\n" + e.toString(),
743                     "GATE", JOptionPane.ERROR_MESSAGE);
744             e.printStackTrace(Err.getPrintWriter());
745           } finally {
746             MainFrame.unlockGUI();
747           }
748         }
749       };
750       Thread thread = new Thread(runnable, "Ontology Cleaner");
751       thread.setPriority(Thread.MIN_PRIORITY);
752       thread.start();
753     }
754   }
755 
756   protected URL owlLiteFileURL;
757   protected URL owlDlFileURL;
758   protected URL owlFullFileURL;
759   protected URL rdfsFileURL;
760   protected URL damlFileURL;
761   protected String language;
762   protected List actionsList;
763   /**
764    * Constant for Owl-Lite ontology type.
765    */
766   public static final int OWL_LITE = 0;
767   /**
768    * Constant for Owl-DL ontology type.
769    */
770   public static final int OWL_DL = 1;
771   /**
772    * Constant for Owl-Full ontology type.
773    */
774   public static final int OWL_FULL = 2;
775   /**
776    * Constant for RDF-S ontology type.
777    */
778   public static final int RDFS = 3;
779   /**
780    * Constant for DAML ontology type.
781    */
782   public static final int DAML = 13;
783 
784 }
785