001/*
002 * Copyright (c) 2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: riddle $'
006 * '$Date: 2010-09-27 18:23:32 +0000 (Mon, 27 Sep 2010) $' 
007 * '$Revision: 25854 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.kepler.sms;
031
032import java.io.BufferedWriter;
033import java.io.File;
034import java.io.FileWriter;
035import java.io.IOException;
036import java.net.URI;
037import java.util.Collections;
038import java.util.HashSet;
039import java.util.Iterator;
040import java.util.Set;
041import java.util.Vector;
042
043import javax.swing.JFrame;
044import javax.swing.JOptionPane;
045
046import org.apache.commons.logging.Log;
047import org.apache.commons.logging.LogFactory;
048import org.kepler.build.modules.ModuleTree;
049import org.kepler.sms.util.OntologyConfiguration;
050import org.kepler.util.DotKeplerManager;
051import org.semanticweb.owl.apibinding.OWLManager;
052import org.semanticweb.owl.model.AddAxiom;
053import org.semanticweb.owl.model.OWLAnnotation;
054import org.semanticweb.owl.model.OWLAxiom;
055import org.semanticweb.owl.model.OWLClass;
056import org.semanticweb.owl.model.OWLDataFactory;
057import org.semanticweb.owl.model.OWLOntology;
058import org.semanticweb.owl.model.OWLOntologyChangeException;
059import org.semanticweb.owl.model.OWLOntologyCreationException;
060import org.semanticweb.owl.model.OWLOntologyManager;
061import org.semanticweb.owl.model.OWLOntologyStorageException;
062import org.semanticweb.owl.util.OWLEntityRemover;
063import org.semanticweb.owl.vocab.OWLRDFVocabulary;
064
065/**
066 * Created by IntelliJ IDEA. User: sean Date: May 20, 2009 Time: 4:55:34 PM
067 */
068
069public class OntologyCatalog {
070
071        static {
072                manager = OWLManager.createOWLOntologyManager();
073        }
074
075        private Vector<NamedOntModel> _namedOntModels = new Vector<NamedOntModel>();
076        private Vector<NamedOntModel> _libraryModels = new Vector<NamedOntModel>();
077        private Vector<NamedOntModel> _tagBarModels = new Vector<NamedOntModel>();
078
079        private static OntologyCatalog _catalog = null;
080        // singleton instance
081        // private String KEPLER = System.getProperty("KEPLER");
082        // private String LOCAL_PATH = KEPLER + "/configs/ptolemy/configs/kepler/";
083        // private String ONTO_FILE = LOCAL_PATH + "ontology2.owl";
084        private String DEFAULT_NSPREFIX = "http://seek.ecoinformatics.org/ontology#";
085        // this should be obtained from the onto
086
087        // list of OntModel objects
088        private Vector<NamedOntModel> _ontologyModels = new Vector<NamedOntModel>();
089
090        protected OntologyCatalog(boolean initialize) {
091                if (initialize) {
092                        initialize();
093                } else {
094                        initialize(false);
095                }
096        }
097
098        /**
099         * Constructor for the OntologyCatalog object
100         */
101        protected OntologyCatalog() {
102                initialize();
103        }
104
105        public static OntologyCatalog standaloneInstance() {
106                OntologyConfiguration oc = OntologyConfiguration.instance();
107                File indexFile = new File(System.getProperty("user.home")
108                                + "/.kepler/ontology_catalog.xml");
109                oc.setIndexFile(indexFile);
110                oc.initialize();
111                return instance();
112        }
113
114        /**
115         * @return The unique instance of this class This must be called to
116         *         create/obtain an instance of the catalog
117         */
118        public static OntologyCatalog instance() {
119                if (_catalog == null) {
120                        _catalog = new OntologyCatalog();
121                }
122                return _catalog;
123        }
124
125        public static OntologyCatalog instanceNoInitialize() {
126                if (_catalog == null) {
127                        _catalog = new OntologyCatalog(false);
128                }
129                return _catalog;
130        }
131
132        private static boolean TEST_MODE = false;
133
134        private OWLOntology createTestOntology()
135                        throws OWLOntologyCreationException, OWLOntologyChangeException {
136                OWLDataFactory factory = manager.getOWLDataFactory();
137                URI uri = URI.create("http://www.example.com/test.owl");
138                OWLOntology ontology = manager.createOntology(uri);
139                OWLClass human = factory.getOWLClass(URI.create(uri + "#human"));
140                OWLClass man = factory.getOWLClass(URI.create(uri + "#man"));
141                OWLClass woman = factory.getOWLClass(URI.create(uri + "#woman"));
142                OWLClass socrates = factory.getOWLClass(URI.create(uri + "#socrates"));
143                OWLClass plato = factory.getOWLClass(URI.create(uri + "#plato"));
144                OWLClass hildegard = factory
145                                .getOWLClass(URI.create(uri + "#hildegard"));
146                OWLAxiom a1 = factory.getOWLSubClassAxiom(man, human);
147                OWLAxiom a2 = factory.getOWLSubClassAxiom(woman, human);
148                OWLAxiom a3 = factory.getOWLSubClassAxiom(socrates, man);
149                OWLAxiom a4 = factory.getOWLSubClassAxiom(plato, man);
150                OWLAxiom a5 = factory.getOWLSubClassAxiom(hildegard, woman);
151                manager.applyChange(new AddAxiom(ontology, a1));
152                manager.applyChange(new AddAxiom(ontology, a2));
153                manager.applyChange(new AddAxiom(ontology, a3));
154                manager.applyChange(new AddAxiom(ontology, a4));
155                manager.applyChange(new AddAxiom(ontology, a5));
156                OWLAxiom b1 = factory.getOWLEntityAnnotationAxiom(human, factory
157                                .getOWLLabelAnnotation("Human"));
158                OWLAxiom b2 = factory.getOWLEntityAnnotationAxiom(man, factory
159                                .getOWLLabelAnnotation("Man"));
160                OWLAxiom b3 = factory.getOWLEntityAnnotationAxiom(woman, factory
161                                .getOWLLabelAnnotation("Woman"));
162                OWLAxiom b4 = factory.getOWLEntityAnnotationAxiom(socrates, factory
163                                .getOWLLabelAnnotation("Socrates"));
164                OWLAxiom b5 = factory.getOWLEntityAnnotationAxiom(plato, factory
165                                .getOWLLabelAnnotation("Plato"));
166                OWLAxiom b6 = factory.getOWLEntityAnnotationAxiom(hildegard, factory
167                                .getOWLLabelAnnotation("Hildegard"));
168                manager.applyChange(new AddAxiom(ontology, b1));
169                manager.applyChange(new AddAxiom(ontology, b2));
170                manager.applyChange(new AddAxiom(ontology, b3));
171                manager.applyChange(new AddAxiom(ontology, b4));
172                manager.applyChange(new AddAxiom(ontology, b5));
173                manager.applyChange(new AddAxiom(ontology, b6));
174                return ontology;
175        }
176
177        /**
178         * Returns the default ontology model for the actor library.
179         * 
180         * @return The defaultOntology value
181         */
182        public OWLOntology getDefaultOntology() {
183                if (TEST_MODE) {
184                        try {
185                                return createTestOntology();
186                        } catch (OWLOntologyCreationException ex) {
187                                log.error("Problem 1", ex);
188                        } catch (OWLOntologyChangeException ex) {
189                                log.error("Problem 2", ex);
190                        }
191                }
192                Iterator<NamedOntModel> models = getNamedOntModels();
193                while (models.hasNext()) {
194                        NamedOntModel model = models.next();
195                        if (Constants.defaultOntologyName.equals(model.getName())) {
196                                return model.getOntology();
197                        }
198                }
199                return this.createDefaultOntology();
200                // return (OWLOntology) getOntModels().elementAt(0);
201        }
202
203        public OWLOntology createDefaultOntology() {
204                OntologyCatalog catalog = OntologyCatalog.instance();
205                OWLOntology ontology = catalog.addModel(true,
206                                Constants.defaultOntologyName, true).getOntology();
207                catalog.saveCatalog();
208                try {
209                        // LibraryManager.getInstance().addOntology(OntologyCatalog.instance().getNamedOntModel(Constants.defaultOntologyName));
210                } catch (Exception ex) {
211                        log.error("Error adding default ontology", ex);
212                }
213                return ontology;
214
215        }
216
217        /**
218         * Gets the ontModels attribute of the OntologyCatalog object
219         * 
220         * @return The ontModels value
221         */
222        public Vector<NamedOntModel> getOntModels() {
223                return _ontologyModels;
224        }
225
226        /**
227         * Get the named ontology model with the given name
228         * 
229         * @param name
230         *            the ontology name
231         * @return the NamedOntModel if it exists
232         */
233        public NamedOntModel getNamedOntModel(String name) {
234                Iterator<NamedOntModel> models = getNamedOntModels();
235                while (models.hasNext()) {
236                        NamedOntModel model = models.next();
237                        if (model.getName().equals(name))
238                                return model;
239                }
240                return null;
241        }
242
243        /**
244         * Returns the first concept in the default onto with the given label
245         * 
246         * @param label
247         *            Description of the Parameter
248         * @return The conceptNameWithLabel value
249         */
250        public String getConceptNameWithLabel(String label) {
251                try {
252                        return getConceptWithLabel(label).toString();
253                } catch (NullPointerException ex) {
254                        return null;
255                }
256        }
257
258        public String getConceptName(OWLClass cls) {
259                return cls.toString();
260        }
261
262        public String getLabelNameWithConcept(String conceptName) {
263                OWLOntology defaultOnt = getDefaultOntology();
264                if (defaultOnt == null || conceptName == null) {
265                        return null;
266                }
267                Set<OWLClass> classes = defaultOnt.getReferencedClasses();
268                for (OWLClass c : classes) {
269                        if (conceptName.equals(c.toString())) {
270                                return getLabelNameWithConcept(c);
271                        }
272                }
273                return null;
274        }
275
276        public String getLabelNameWithConcept(NamedOntClass cls) {
277                OWLOntology ontology = cls.getOntology();
278                OWLClass owlClass = cls.ontClass();
279                String label = getLabelNameWithConcept(ontology, owlClass);
280                if (label != null) {
281                        // Not an orphan
282                        return label;
283                }
284
285                // Orphan!
286                String[] parts = cls.getManualUrl().split("#");
287                return parts[parts.length - 1];
288
289        }
290
291        public String getLabelNameWithConcept(OWLOntology ontology, OWLClass cls) {
292                if (ontology == null || cls == null) {
293                        return null;
294                }
295                Set<OWLAnnotation> annotations = cls.getAnnotations(ontology,
296                                OWLRDFVocabulary.RDFS_LABEL.getURI());
297                try {
298                        return Util.parseOWLSerializedString(annotations
299                                        .toArray(new OWLAnnotation[1])[0].getAnnotationValue()
300                                        .toString());
301                } catch (NullPointerException ex) {
302                        String[] parts = cls.getURI().toString().split("#");
303                        return parts[parts.length - 1];
304                }
305        }
306
307        public String getLabelNameWithConcept(OWLClass cls) {
308                return getLabelNameWithConcept(getDefaultOntology(), cls);
309        }
310
311        /**
312         * Add a class with the given name to the ontology
313         * 
314         * @param model
315         *            the NamedOntModel to create the class in
316         * @param name
317         *            the name of the class
318         * @return the NamedOntModel
319         */
320        public NamedOntClass createClass(NamedOntModel model, String name) {
321                String id = name.trim().replaceAll("\\s", "");
322                OWLDataFactory factory = manager.getOWLDataFactory();
323                String fullId = model.getNameSpace() + "#" + id;
324                OWLClass owlClass = factory.getOWLClass(URI.create(fullId));
325                OWLAxiom axiom1 = factory.getOWLDeclarationAxiom(owlClass);
326                OWLAnnotation annot = factory.getOWLLabelAnnotation(name);
327                OWLAxiom axiom2 = factory.getOWLEntityAnnotationAxiom(owlClass, annot);
328                try {
329                        manager.applyChange(new AddAxiom(model.getOntology(), axiom1));
330                        manager.applyChange(new AddAxiom(model.getOntology(), axiom2));
331                } catch (OWLOntologyChangeException ex) {
332                        log.error("Error adding class declaration axiom to ontology");
333                }
334                return new NamedOntClass(owlClass, model.getOntology());
335        }
336
337        public NamedOntClass createClass(NamedOntModel model, String className,
338                        NamedOntClass superClass) {
339                NamedOntClass ontClass = createClass(model, className);
340                OWLDataFactory factory = manager.getOWLDataFactory();
341                OWLAxiom axiom = factory.getOWLSubClassAxiom(ontClass.ontClass(),
342                                superClass.ontClass());
343                try {
344                        manager.applyChange(new AddAxiom(model.getOntology(), axiom));
345                } catch (OWLOntologyChangeException ex) {
346                        log.error("Error adding subclass axiom");
347                }
348                return ontClass;
349        }
350
351        /**
352         * Adds a concept to the default ontology
353         * 
354         * @param conceptName
355         *            The feature to be added to the Concept attribute
356         */
357        public void addConcept(String conceptName) {
358                addConcept(conceptName, conceptName);
359        }
360
361        /**
362         * Adds a concept to the default ontology
363         * 
364         * @param conceptName
365         *            The feature to be added to the Concept attribute
366         * @param conceptLabel
367         *            The feature to be added to the Concept attribute
368         */
369        public void addConcept(String conceptName, String conceptLabel) {
370                OWLOntology defaultOnt = getDefaultOntology();
371                if (defaultOnt == null) {
372                        return;
373                }
374                OWLDataFactory factory = manager.getOWLDataFactory();
375                OWLClass c = factory.getOWLClass(URI.create(DEFAULT_NSPREFIX
376                                + conceptName));
377
378                OWLAxiom axiom = factory.getOWLDeclarationAxiom(c);
379                OWLAxiom axiom2 = factory.getOWLEntityAnnotationAxiom(c, factory
380                                .getOWLLabelAnnotation(conceptLabel));
381                try {
382                        manager.applyChange(new AddAxiom(defaultOnt, axiom));
383                        manager.applyChange(new AddAxiom(defaultOnt, axiom2));
384                } catch (OWLOntologyChangeException ex) {
385                        log.error("Error adding class declaration axiom to ontology", ex);
386                }
387                writeDefaultModel();
388        }
389
390        public void removeConcept(NamedOntClass ontClass) {
391                OWLOntology ontology = ontClass.getOntology();
392                OWLEntityRemover remover = new OWLEntityRemover(manager, Collections
393                                .singleton(ontology));
394                ontClass.ontClass().accept(remover);
395                try {
396                        manager.applyChanges(remover.getChanges());
397                } catch (OWLOntologyChangeException ex) {
398                        log.error("Error removing concept", ex);
399                }
400        }
401
402        /**
403         * Assigns a concept as a subconcept to a superconcept
404         * 
405         * @param subConceptName
406         *            Description of the Parameter
407         * @param superConceptName
408         *            Description of the Parameter
409         */
410        public void assignSuperConcept(String subConceptName,
411                        String superConceptName) {
412                OWLOntology defaultOnt = getDefaultOntology();
413                if (defaultOnt == null) {
414                        return;
415                }
416                // check if sub and sup have been created already
417                OWLDataFactory factory = manager.getOWLDataFactory();
418                OWLClass sub = factory.getOWLClass(URI.create(DEFAULT_NSPREFIX
419                                + subConceptName));
420                OWLClass sup = factory.getOWLClass(URI.create(DEFAULT_NSPREFIX
421                                + superConceptName));
422                OWLAxiom axiom = factory.getOWLSubClassAxiom(sub, sup);
423                try {
424                        manager.applyChange(new AddAxiom(defaultOnt, axiom));
425                } catch (OWLOntologyChangeException ex) {
426                        log.error("Error adding subclass axiom to ontology", ex);
427                }
428                writeDefaultModel();
429        }
430
431        public void write() {
432                writeDefaultModel();
433        }
434
435        /**
436         * Description of the Method
437         */
438        protected void writeDefaultModel() {
439                OWLOntology defaultOnt = getDefaultOntology();
440                if (defaultOnt == null) {
441                        return;
442                }
443                try {
444                        manager.saveOntology(defaultOnt);
445                } catch (OWLOntologyStorageException ex) {
446                        log.error("Error saving default model", ex);
447                }
448        }
449
450        protected void initialize() {
451                initialize(true);
452        }
453
454        /**
455         * Description of the Method
456         */
457        protected void initialize(boolean init) {
458                _namedOntModels.clear();
459                _libraryModels.clear();
460                _tagBarModels.clear();
461                if (init) {
462                        OntologyConfiguration.instance().initialize();
463                }
464                // the default ontology is now "ontology.owl"
465                // manager = OWLManager.createOWLOntologyManager();
466                OntologyConfiguration config = OntologyConfiguration.instance();
467
468                // for each ontology create a NamedOntModel from the
469                for (Iterator iter = config.getFilePathNames(); iter.hasNext();) {
470                        String ontoFilePath = (String) iter.next();
471                        if (isDebugging)
472                                log.debug(ontoFilePath);
473                        NamedOntModel mdl;
474                        try {
475                                mdl = new NamedOntModel(ontoFilePath);
476                                boolean success = mdl.initialize();
477                                if (!success) {
478                                        System.out.println("Could not instantiate model: '" + ontoFilePath + "'");
479                                        return;
480                                }
481                                mdl.setColor(config.getLibraryColor(ontoFilePath));
482                                mdl.setLocal(config.isLibraryLocal(ontoFilePath));
483                                if (isDebugging)
484                                        log.debug(mdl.getNameSpace());
485
486                                _namedOntModels.add(mdl);
487                                if (isDebugging)
488                                        log.debug("_namedOntModels.add(" + mdl.getName() + ")");
489
490                                if (config.isLibraryOntology(ontoFilePath)) {
491                                        _libraryModels.add(mdl);
492                                        if (isDebugging)
493                                                log.debug("_libraryModels.add(" + mdl.getName() + ")");
494                                }
495                                // TODO: This can be made more efficient. We don't need to
496                                // double
497                                // parse it.
498                                if (config.isTagBarOntology(ontoFilePath)) {
499                                        _tagBarModels.add(mdl);
500                                        if (isDebugging)
501                                                log.debug("_tagBarModels.add(" + mdl.getName() + ")");
502                                }
503                        } catch (Exception e) {
504                                JFrame f = new JFrame();
505                                String errmsg = "Cannot locate ontology: " + ontoFilePath;
506                                JOptionPane.showMessageDialog(f, errmsg, "Configuration Error",
507                                                JOptionPane.WARNING_MESSAGE);
508                                f.dispose();
509                        }
510                }
511        }
512
513        /**
514         * The main program for the OntologyCatalog class
515         * 
516         * @param args
517         *            The command line arguments
518         */
519        public static void main(String[] args) {
520                OntologyCatalog catalog = OntologyCatalog.instance();
521                catalog.addConcept("MyClass", "My Class Label");
522                catalog.assignSuperConcept("MyClass", "WorkflowComponent");
523        }
524
525        public void setInLibrary(NamedOntModel model, boolean isInLibrary) {
526                if (isInLibrary && !_libraryModels.contains(model)) {
527                        _libraryModels.add(model);
528                } else if (!isInLibrary && _libraryModels.contains(model)) {
529                        _libraryModels.remove(model);
530                }
531        }
532
533        public void setInTagBar(NamedOntModel model, boolean isInTagBar) {
534                if (isInTagBar && !_tagBarModels.contains(model)) {
535                        _tagBarModels.add(model);
536                } else if (!isInTagBar && _tagBarModels.contains(model)) {
537                        _tagBarModels.remove(model);
538                }
539        }
540
541        /**
542         * Save out catalog to catalog filename
543         */
544        public void saveCatalog() {
545                Vector<OntologyRow> rows = new Vector<OntologyRow>();
546                OntologyConfiguration config = OntologyConfiguration.instance();
547                for (NamedOntModel model : _namedOntModels) {
548                        String path = model.getFile().getPath();
549                        if (isDebugging)
550                                log.debug("Processing ontology: '" + model.getName() + "'");
551                        boolean local = Constants.defaultOntologyName.equals(model
552                                        .getName())
553                                        || model.isLocal();
554                        if (isDebugging)
555                                log.debug("Looking for the color of: " + path);
556                        Color color = config.getLibraryColor(path);
557                        rows.add(new OntologyRow(model, _libraryModels.contains(model),
558                                        _tagBarModels.contains(model), color, local));
559                }
560                saveCatalog(rows);
561        }
562
563        public void saveCatalog(Vector<OntologyRow> rows) {
564                // check paths
565                for (OntologyRow row : rows) {
566                        File file = row.getModel().getFile();
567                        if (!file.exists()) {
568                                System.out.println("File path corruption detected. Aborting write.");
569                                return;
570                        }
571                }
572                OntologyConfiguration config = OntologyConfiguration.instance();
573                File indexFile = config.getIndexFile();
574                File directory = ModuleTree.instance().getModuleByStemName("common").getDir();
575                if (indexFile.getAbsolutePath().startsWith(directory.getAbsolutePath())) {
576                        System.out.println("Preparing to write common ontology_catalog.xml file. Aborting.");
577                        return;
578                }
579
580                try {
581                        BufferedWriter writer = new BufferedWriter(
582                                        new FileWriter(indexFile));
583                        writer.write("<?xml version=\"1.0\"?>\n<ontologies>\n");
584                        for (OntologyRow row : rows) {
585                                writer.write("<ontology filename=\""
586                                                + row.getModel().getFile().getAbsolutePath()
587                                                + "\" library=\"");
588                                if (row.isInLibrary()) {
589                                        writer.write("true");
590                                } else {
591                                        writer.write("false");
592                                }
593
594                                writer.write("\" tagbar=\"");
595                                if (row.isInTagBar()) {
596                                        writer.write("true");
597                                } else {
598                                        writer.write("false");
599                                }
600                                writer.write("\" color=\"" + row.getColor());
601
602                                writer.write("\" local=\"");
603                                if (row.isLocal()) {
604                                        writer.write("true");
605                                } else {
606                                        writer.write("false");
607                                }
608
609                                writer.write("\"/>\n");
610                        }
611                        writer.write("</ontologies>\n");
612                        writer.close();
613                } catch (IOException ex) {
614                        log.error("IO error", ex);
615                }
616                // OntologyConfiguration.instance().reset();
617                initialize();
618        }
619
620        private Set<String> getTopLevelLabels() {
621                Set<String> labels = new HashSet<String>();
622                for (NamedOntModel model : _namedOntModels) {
623                        labels.add(model.getTopLevelLabel());
624                }
625                return labels;
626        }
627
628        private String getNewOntologyName() {
629                Set<String> labels = getTopLevelLabels();
630                int i = 1;
631                while (true) {
632                        String label = "Untitled " + i;
633
634                        // Is it taken?
635                        if (!labels.contains(label)) {
636                                // Nope, grab it.
637                                return label;
638                        }
639                        // Yes
640                        ++i;
641                }
642        }
643
644        public NamedOntModel addModel(boolean isInLibrary, String label,
645                        boolean editable) {
646                File coreModuleDir = DotKeplerManager.getInstance()
647                                .getTransientModuleDirectory("core");
648                NamedOntModel model = null;
649                try {
650                        File temporaryFile = File.createTempFile("onto", ".owl",
651                                        coreModuleDir);
652                        try {
653                                model = new NamedOntModel(temporaryFile.getAbsolutePath());
654                                model.setLocal(editable);
655                                if (label == null) {
656                                        model.initializeNew(getNewOntologyName());
657                                } else {
658                                        model.initializeNew(label);
659                                }
660                                model.write();
661                                addModel(model, isInLibrary);
662                        } catch (Exception ex) {
663                                log.error("Error", ex);
664                        }
665                } catch (IOException ex) {
666                        log.error("Error", ex);
667                }
668                return model;
669        }
670
671        public void addModel(NamedOntModel model, boolean isInLibrary) {
672                _namedOntModels.add(model);
673                if (isInLibrary) {
674                        _libraryModels.add(model);
675                }
676        }
677
678        public Iterator<NamedOntModel> getNamedOntModels() {
679                return _namedOntModels.iterator();
680        }
681
682        /**
683         * Provides the set of named ontology models
684         * 
685         *@param libraryOnly
686         *            if true, return only the library models
687         *@return the set of named ontology models in the catalog
688         */
689        public Iterator<NamedOntModel> getNamedOntModels(boolean libraryOnly) {
690                if (libraryOnly) {
691                        return getLibraryNamedOntModels();
692                } else {
693                        return getNamedOntModels();
694                }
695        }
696
697        /**
698         * Provides the set of named ontology models used in the actor library
699         * 
700         *@return the unique instance of this class
701         */
702        public Iterator<NamedOntModel> getLibraryNamedOntModels() {
703                return _libraryModels.iterator();
704        }
705
706        public Iterator<NamedOntModel> getTagBarOntModels() {
707                return _tagBarModels.iterator();
708        }
709
710        /**
711         * The set of ontology names in the catalog
712         * 
713         *@return The set of names for ontologies
714         */
715        public Iterator<String> getOntologyNames() {
716                Vector<String> results = new Vector<String>();
717                for (Iterator<NamedOntModel> iter = getNamedOntModels(); iter.hasNext();) {
718                        NamedOntModel m = iter.next();
719                        results.add(m.getName());
720                }
721                return results.iterator();
722        }
723
724        /**
725         * The set of ontology names for use in the catalog
726         * 
727         *@return The libraryOntologyNames value
728         */
729        public Iterator<String> getLibraryOntologyNames() {
730                Vector<String> results = new Vector<String>();
731                for (Iterator<NamedOntModel> iter = getLibraryNamedOntModels(); iter
732                                .hasNext();) {
733                        NamedOntModel m = iter.next();
734                        results.add(m.getName());
735                }
736                return results.iterator();
737        }
738
739        /**
740         * Maps the namespace of an ontology to the given ontology name
741         * 
742         *@param namespace
743         *            the namespace of the desired ontology
744         *@return the name of the ontology for the given namespace. The namespace
745         *         can optionally end in #
746         */
747        public String getOntologyName(String namespace) {
748                for (Iterator<NamedOntModel> iter = getNamedOntModels(); iter.hasNext();) {
749                        NamedOntModel m = iter.next();
750                        String nspace = m.getNameSpace() + "#";
751                        if (m.getNameSpace().equals(namespace) || nspace.equals(namespace)) {
752                                return m.getName();
753                        }
754                }
755                return null;
756        }
757
758        /**
759         * Maps semantic types to their NamedOntClass objects. Tries to optimize the
760         * search assuming '#' is used to distinguish namespaces from local names.
761         * 
762         *@param st
763         *            the semantic type to search for
764         *@return the named ontology class for the given semantic type or null if
765         *         none exists.
766         */
767        public NamedOntClass getNamedOntClass(SemanticType st) {
768                String conceptId = st.getConceptId();
769                String[] parts = conceptId.split("#");
770                // make sure we have a valid semantic type
771                if (parts.length < 2) {
772                        return null;
773                }
774                // search for a matching model and class
775                for (Iterator iter = getNamedOntModels(); iter.hasNext();) {
776                        NamedOntModel m = (NamedOntModel) iter.next();
777                        if (m.getNameSpace().equals(parts[0])) {
778                                for (Iterator iter2 = m.getNamedClasses(); iter2.hasNext();) {
779                                        NamedOntClass c = (NamedOntClass) iter2.next();
780                                        if (c.getLocalName().equals(parts[1])) {
781                                                return c;
782                                        }
783                                }
784                        }
785                }
786                return null;
787        }
788
789        /**
790         * Maps namespaces and local names to NamedOntClass objects
791         * 
792         *@param namespace
793         *            the namespace of the class
794         *@param localName
795         *            the local name (id) of the class within the namespace
796         *@return the named ontology class for the given semantic type or null if
797         *         none exists.
798         */
799        public NamedOntClass getNamedOntClass(String namespace, String localName) {
800                if (namespace == null || localName == null) {
801                        return null;
802                }
803                // search for a matching model and class
804                for (Iterator iter = getNamedOntModels(); iter.hasNext();) {
805                        NamedOntModel m = (NamedOntModel) iter.next();
806                        String m_nspace = m.getNameSpace() + "#";
807                        if (m.getNameSpace().equals(namespace)
808                                        || m_nspace.equals(namespace)) {
809                                for (Iterator<NamedOntClass> iter2 = m.getNamedClasses(); iter2
810                                                .hasNext();) {
811                                        NamedOntClass c = iter2.next();
812                                        if (c.getLocalName().equals(localName)) {
813                                                return c;
814                                        }
815                                }
816                        }
817                }
818                return null;
819        }
820
821        /**
822         * Returns class name with the given concept id in the ontologies managed by
823         * the catalog.
824         * 
825         *@param conceptId
826         *            complete name of class (with namespace)
827         *@param libraryClassesOnly
828         *            if true, search only those classes in one of the library
829         *            ontologies
830         *@return The named ontology class for the given concept id (local name
831         *         plus namespace), or null if no such class exist
832         */
833        public NamedOntClass getNamedOntClass(String conceptId,
834                        boolean libraryClassesOnly) {
835                if (conceptId == null) {
836                        return null;
837                }
838                for (Iterator<NamedOntModel> ontos = getNamedOntModels(libraryClassesOnly); ontos
839                                .hasNext();) {
840                        NamedOntModel m = ontos.next();
841                        for (Iterator<NamedOntClass> classes = m.getNamedClasses(); classes
842                                        .hasNext();) {
843                                NamedOntClass c = classes.next();
844                                if (conceptId.equals(c.getConceptId())) {
845                                        return c;
846                                }
847                        }
848                }
849                return null;
850        }
851
852        /**
853         * Returns class name with the given concept id in the ontologies managed by
854         * the catalog.
855         * 
856         *@param conceptId
857         *            complete name of class (with namespace)
858         *@return The named ontology class for the given concept id (local name
859         *         plus namespace), or null if no such class exist
860         */
861        public NamedOntClass getNamedOntClass(String conceptId) {
862                return getNamedOntClass(conceptId, false);
863        }
864
865        private static OWLOntologyManager manager;
866
867        public static OWLOntologyManager getManager() {
868                return manager;
869        }
870
871        private static final Log log = LogFactory.getLog(OntologyCatalog.class);
872        private static final boolean isDebugging = log.isDebugEnabled();
873
874        public OWLClass getConceptWithLabel(String label) {
875                OWLOntology defaultOnt = getDefaultOntology();
876                if (defaultOnt == null || label == null) {
877                        return null;
878                }
879                Set<OWLClass> classes = defaultOnt.getReferencedClasses();
880                for (OWLClass c : classes) {
881                        String thisLabel = c.getAnnotations(defaultOnt,
882                                        OWLRDFVocabulary.RDFS_LABEL.getURI()).toArray(
883                                        new OWLAnnotation[1])[0].getAnnotationValue().toString();
884                        if (label.equals(thisLabel)) {
885                                return c;
886                        }
887                }
888                return null;
889        }
890}