Package uk.ac.manchester.cs.owl.owlapi

Source Code of uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl

/*
* This file is part of the OWL API.
*
* The contents of this file are subject to the LGPL License, Version 3.0.
*
* Copyright (C) 2011, The University of Manchester
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see http://www.gnu.org/licenses/.
*
*
* Alternatively, the contents of this file may be used under the terms of the Apache License, Version 2.0
* in which case, the provisions of the Apache License Version 2.0 are applicable instead of those above.
*
* Copyright 2011, University of Manchester
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package uk.ac.manchester.cs.owl.owlapi;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import org.semanticweb.owlapi.io.FileDocumentSource;
import org.semanticweb.owlapi.io.IRIDocumentSource;
import org.semanticweb.owlapi.io.OWLOntologyDocumentSource;
import org.semanticweb.owlapi.io.OWLOntologyDocumentTarget;
import org.semanticweb.owlapi.io.OWLOntologyStorageIOException;
import org.semanticweb.owlapi.io.OntologyIRIMappingNotFoundException;
import org.semanticweb.owlapi.io.StreamDocumentSource;
import org.semanticweb.owlapi.io.StreamDocumentTarget;
import org.semanticweb.owlapi.model.AddAxiom;
import org.semanticweb.owlapi.model.AddImport;
import org.semanticweb.owlapi.model.DefaultChangeBroadcastStrategy;
import org.semanticweb.owlapi.model.DefaultImpendingChangeBroadcastStrategy;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.ImmutableOWLOntologyChangeException;
import org.semanticweb.owlapi.model.ImpendingOWLOntologyChangeBroadcastStrategy;
import org.semanticweb.owlapi.model.ImpendingOWLOntologyChangeListener;
import org.semanticweb.owlapi.model.MissingImportEvent;
import org.semanticweb.owlapi.model.MissingImportListener;
import org.semanticweb.owlapi.model.OWLAnnotationAxiom;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLImportsDeclaration;
import org.semanticweb.owlapi.model.OWLMutableOntology;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyAlreadyExistsException;
import org.semanticweb.owlapi.model.OWLOntologyChange;
import org.semanticweb.owlapi.model.OWLOntologyChangeBroadcastStrategy;
import org.semanticweb.owlapi.model.OWLOntologyChangeException;
import org.semanticweb.owlapi.model.OWLOntologyChangeListener;
import org.semanticweb.owlapi.model.OWLOntologyChangeProgressListener;
import org.semanticweb.owlapi.model.OWLOntologyChangeVetoException;
import org.semanticweb.owlapi.model.OWLOntologyChangesVetoedListener;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyDocumentAlreadyExistsException;
import org.semanticweb.owlapi.model.OWLOntologyFactory;
import org.semanticweb.owlapi.model.OWLOntologyFactoryNotFoundException;
import org.semanticweb.owlapi.model.OWLOntologyFormat;
import org.semanticweb.owlapi.model.OWLOntologyID;
import org.semanticweb.owlapi.model.OWLOntologyIRIMapper;
import org.semanticweb.owlapi.model.OWLOntologyIRIMappingNotFoundException;
import org.semanticweb.owlapi.model.OWLOntologyLoaderConfiguration;
import org.semanticweb.owlapi.model.OWLOntologyLoaderListener;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLOntologyManagerProperties;
import org.semanticweb.owlapi.model.OWLOntologyRenameException;
import org.semanticweb.owlapi.model.OWLOntologyStorageException;
import org.semanticweb.owlapi.model.OWLOntologyStorer;
import org.semanticweb.owlapi.model.OWLOntologyStorerNotFoundException;
import org.semanticweb.owlapi.model.RemoveAxiom;
import org.semanticweb.owlapi.model.RemoveImport;
import org.semanticweb.owlapi.model.SetOntologyID;
import org.semanticweb.owlapi.model.UnknownOWLOntologyException;
import org.semanticweb.owlapi.model.UnloadableImportException;
import org.semanticweb.owlapi.util.CollectionFactory;
import org.semanticweb.owlapi.util.NonMappingOntologyIRIMapper;


/**
* Author: Matthew Horridge<br>
* The University Of Manchester<br>
* Bio-Health Informatics Group<br>
* Date: 27-Oct-2006<br><br>
*/
public class OWLOntologyManagerImpl implements OWLOntologyManager, OWLOntologyFactory.OWLOntologyCreationHandler {

    private static final Logger logger = Logger.getLogger(OWLOntologyManagerImpl.class.getName());

    private Map<OWLOntologyID, OWLOntology> ontologiesByID;

    private Map<OWLOntologyID, IRI> documentIRIsByID;

    private Map<OWLOntologyID, OWLOntologyFormat> ontologyFormatsByOntology;

    private Map<OWLImportsDeclaration, OWLOntologyID> ontologyIDsByImportsDeclaration;

    private List<OWLOntologyIRIMapper> documentMappers;

    private List<OWLOntologyFactory> ontologyFactories;

    private List<OWLOntologyStorer> ontologyStorers;

    private boolean broadcastChanges;

    private int loadCount = 0;

    private int importsLoadCount = 0;

    @Deprecated
    private boolean silentMissingImportsHandling;

    private OWLDataFactory dataFactory;

    private Map<OWLOntologyID, Set<OWLOntology>> importsClosureCache;

    private OWLOntologyManagerProperties properties;

    private List<MissingImportListener> missingImportsListeners;

    private List<OWLOntologyLoaderListener> loaderListeners;

    private List<OWLOntologyChangeProgressListener> progressListeners;

    private int autoGeneratedURICounter;

    private OWLOntologyChangeBroadcastStrategy defaultChangeBroadcastStrategy;

    private ImpendingOWLOntologyChangeBroadcastStrategy defaultImpendingChangeBroadcastStrategy;


    public OWLOntologyManagerImpl(OWLDataFactory dataFactory) {
        this.dataFactory = dataFactory;
        properties = new OWLOntologyManagerProperties();
        ontologiesByID = new HashMap<OWLOntologyID, OWLOntology>();
        documentIRIsByID = new HashMap<OWLOntologyID, IRI>();
        ontologyFormatsByOntology = new HashMap<OWLOntologyID, OWLOntologyFormat>();
        documentMappers = new ArrayList<OWLOntologyIRIMapper>();
        ontologyFactories = new ArrayList<OWLOntologyFactory>();
        ontologyIDsByImportsDeclaration = new HashMap<OWLImportsDeclaration, OWLOntologyID>();
        installDefaultURIMappers();
        installDefaultOntologyFactories();
        broadcastChanges = true;
        ontologyStorers = new ArrayList<OWLOntologyStorer>();
        importsClosureCache = new HashMap<OWLOntologyID, Set<OWLOntology>>();
        missingImportsListeners = new ArrayList<MissingImportListener>();
        loaderListeners = new ArrayList<OWLOntologyLoaderListener>();
        progressListeners = new ArrayList<OWLOntologyChangeProgressListener>();
        autoGeneratedURICounter = 0;
        defaultChangeBroadcastStrategy = new DefaultChangeBroadcastStrategy();
        defaultImpendingChangeBroadcastStrategy = new DefaultImpendingChangeBroadcastStrategy();
    }


    public OWLOntologyManagerProperties getProperties() {
        return properties;
    }


    public OWLDataFactory getOWLDataFactory() {
        return dataFactory;
    }


    public Set<OWLOntology> getOntologies() {
        return new HashSet<OWLOntology>(ontologiesByID.values());
    }


    public Set<OWLOntology> getOntologies(OWLAxiom axiom) {
        Set<OWLOntology> result = new HashSet<OWLOntology>(ontologiesByID.size());
        for (OWLOntology ont : getOntologies()) {
            if (ont.containsAxiom(axiom)) {
                result.add(ont);
            }
        }
        return result;
    }

    public boolean contains(OWLOntology ontology) {
        return ontologiesByID.containsValue(ontology);
    }


    public boolean contains(IRI ontologyIRI) {
        return contains(new OWLOntologyID(ontologyIRI));
    }

    public boolean contains(OWLOntologyID id) {
        return ontologiesByID.containsKey(id);
    }

    /**
     * Gets a previously loaded/created ontology that has the specified ontology IRI and no version IRI.
     * @param ontologyIRI The IRI of the ontology to be retrieved.
     * @return The ontology that has the specified IRI and no version IRI, or <code>null</code> if this manager does
     *         not manage an ontology with the specified IRI and no version IRI.
     */
    public OWLOntology getOntology(IRI ontologyIRI) {
        OWLOntologyID ontologyID = new OWLOntologyID(ontologyIRI);
        return getOntology(ontologyID);
    }

    /**
     * Gets a previously loaded/created ontology that has the specified ontology ID
     * @param ontologyID The ID of the ontology to retrieve
     * @return The ontology that has the specified ID, or <code>null</code> if this manager does not manage an ontology
     *         with the specified ontology ID.
     */
    public OWLOntology getOntology(OWLOntologyID ontologyID) {
        return ontologiesByID.get(ontologyID);

    }

    public Set<OWLOntology> getVersions(IRI ontology) {
        Set<OWLOntology> onts = new HashSet<OWLOntology>();
        for (OWLOntology ont : getOntologies()) {
            if (ontology.equals(ont.getOntologyID().getOntologyIRI())) {
                onts.add(ont);
            }
        }
        return onts;
    }

    /**
     * Given an imports declaration, obtains the ontology that this import has been resolved to.
     * @param declaration The declaration that points to the imported ontology.
     * @return The ontology that the imports declaration resolves to, or <code>null</code> if the imports declaration
     *         could not be resolved to an ontology, because the ontology was not loaded or has been removed from this
     *         manager
     */
    public OWLOntology getImportedOntology(OWLImportsDeclaration declaration) {
        OWLOntologyID ontologyID = ontologyIDsByImportsDeclaration.get(declaration);
        if (ontologyID == null) {
            // No such ontology
            return null;
        }
        else {
            return getOntology(ontologyID);
        }
    }

    /**
     * Gets the set of <em>loaded</em> ontologies that the specified ontology is related to via the directlyImports relation as
     * defined in Section 3.4 of the OWL 2 Structural specification
     * @param ontology The ontology whose direct imports are to be retrieved.
     * @return The set of <em>loaded</em> ontologies that the specified ontology is related to via the directlyImports
     *         relation.
     * @throws org.semanticweb.owlapi.model.UnknownOWLOntologyException
     *          if there isn't an ontology in this manager which has the specified IRI.
     */
    public Set<OWLOntology> getDirectImports(OWLOntology ontology) throws UnknownOWLOntologyException {
        if (!contains(ontology)) {
            throw new UnknownOWLOntologyException(ontology.getOntologyID());
        }
        Set<OWLOntology> imports = new HashSet<OWLOntology>();
        for (OWLImportsDeclaration axiom : ontology.getImportsDeclarations()) {
            OWLOntology importedOntology = getImportedOntology(axiom);
            if (importedOntology != null) {
                imports.add(importedOntology);
            }
        }
        return imports;
    }

    /**
     * Gets the set of ontologies that are in the transitive closure of the directly imports relation.
     * @param ontology The ontology whose imports are to be retrieved.
     * @return A set of <code>OWLOntology</code>ies that are in the transitive closure of the directly imports relation
     *         of this ontology. If, for what ever reason, an imported ontology could not be loaded, then it will not be contained in the
     *         returned set of ontologies.
     * @throws org.semanticweb.owlapi.model.UnknownOWLOntologyException
     *          if there isn't an ontology in this manager which has the specified IRI.
     */
    public Set<OWLOntology> getImports(OWLOntology ontology) throws UnknownOWLOntologyException {
        if (!contains(ontology)) {
            throw new UnknownOWLOntologyException(ontology.getOntologyID());
        }
        Set<OWLOntology> result = new HashSet<OWLOntology>();
        getImports(ontology, result);
        return result;
    }

    /**
     * A method that gets the imports of a given ontology
     * @param ont The ontology whose (transitive) imports are to be retrieved.
     * @param result A place to store the result - the transitive closure of the imports will be stored in this
     * result set.
     */
    private void getImports(OWLOntology ont, Set<OWLOntology> result) {
        for (OWLOntology directImport : getDirectImports(ont)) {
            if (result.add(directImport)) {
                getImports(directImport, result);
            }
        }
    }

    public Set<OWLOntology> getImportsClosure(OWLOntology ontology) {
        Set<OWLOntology> ontologies = importsClosureCache.get(ontology.getOntologyID());
        if (ontologies == null) {
            ontologies = new HashSet<OWLOntology>();
            getImportsClosure(ontology, ontologies);
            // store the wrapped set
            importsClosureCache.put(ontology.getOntologyID(), ontologies);
        }
        // the returned set can be mutated, but changes will not be propagated back
        return CollectionFactory.getCopyOnRequestSet(ontologies);
    }


    /**
     * A recursive method that gets the reflexive transitive closure of the ontologies that are imported
     * by this ontology.
     * @param ontology The ontology whose reflexive transitive closure is to be retrieved
     * @param ontologies a place to store the result
     */
    private void getImportsClosure(OWLOntology ontology, Set<OWLOntology> ontologies) {
        ontologies.add(ontology);
        for (OWLOntology ont : getDirectImports(ontology)) {
            if (!ontologies.contains(ont)) {
                getImportsClosure(ont, ontologies);
            }
        }
    }


    public List<OWLOntology> getSortedImportsClosure(OWLOntology ontology) throws UnknownOWLOntologyException {
        List<OWLOntology> importsClosure = new ArrayList<OWLOntology>();
        getSortedImportsClosure(ontology, importsClosure, new HashSet<OWLOntology>());
        return importsClosure;
    }

    private void getSortedImportsClosure(OWLOntology ontology, List<OWLOntology> imports, Set<OWLOntology> marker) {
        if (!marker.contains(ontology)) {
            imports.add(ontology);
            marker.add(ontology);
            for (OWLOntology imported : getDirectImports(ontology)) {
                getSortedImportsClosure(imported, imports, marker);
            }
        }
    }


    /**
     * Determines if a change is applicable.  A change may not be applicable
     * for a number of reasons.
     * @param change The change to be tested.
     * @return <code>true</code> if the change is applicable,
     *         otherwise, <code>false</code>.
     */
    private boolean isChangeApplicable(OWLOntologyChange change) {
        if (!getProperties().isLoadAnnotationAxioms() && change instanceof AddAxiom) {
            if (change.getAxiom() instanceof OWLAnnotationAxiom) {
                return false;
            }
        }
        return true;
    }


    /**
     * Applies a change to an ontology and performs the necessary housekeeping
     * tasks.
     * @param change The change to be applied.
     * @return A list of changes that were actually applied.
     * @throws OWLOntologyChangeException
     */
    private List<OWLOntologyChange> enactChangeApplication(OWLOntologyChange change) {
        if (!isChangeApplicable(change)) {
            return Collections.emptyList();
        }
        OWLOntology ont = change.getOntology();
        if (!(ont instanceof OWLMutableOntology)) {
            throw new ImmutableOWLOntologyChangeException(change);
        }
        checkForOntologyIDChange(change);
        List<OWLOntologyChange> appliedChanges = ((OWLMutableOntology) ont).applyChange(change);

        checkForImportsChange(change);
        return appliedChanges;
    }


    public List<OWLOntologyChange> applyChanges(List<? extends OWLOntologyChange> changes) {
        try {
            broadcastImpendingChanges(changes);
        }
        catch (OWLOntologyChangeVetoException e) {
            // Some listener blocked the changes.
            broadcastOntologyChangesVetoed(changes, e);
            return Collections.emptyList();
        }
        List<OWLOntologyChange> appliedChanges = new ArrayList<OWLOntologyChange>(changes.size() + 2);
        fireBeginChanges(changes.size());
        for (OWLOntologyChange change : changes) {
            appliedChanges.addAll(enactChangeApplication(change));
            fireChangeApplied(change);
        }
        fireEndChanges();
        broadcastChanges(appliedChanges);
        return appliedChanges;
    }


    public List<OWLOntologyChange> addAxiom(OWLOntology ont, OWLAxiom axiom) {
        return addAxioms(ont, Collections.singleton(axiom));
    }


    public List<OWLOntologyChange> addAxioms(OWLOntology ont, Set<? extends OWLAxiom> axioms) {
        List<OWLOntologyChange> changes = new ArrayList<OWLOntologyChange>(axioms.size() + 2);
        for (OWLAxiom ax : axioms) {
            changes.add(new AddAxiom(ont, ax));
        }
        return applyChanges(changes);
    }

    public List<OWLOntologyChange> removeAxiom(OWLOntology ont, OWLAxiom axiom) {
        return removeAxioms(ont, Collections.singleton(axiom));
    }

    public List<OWLOntologyChange> removeAxioms(OWLOntology ont, Set<? extends OWLAxiom> axioms) {
        List<OWLOntologyChange> changes = new ArrayList<OWLOntologyChange>(axioms.size() + 2);
        for (OWLAxiom ax : axioms) {
            changes.add(new RemoveAxiom(ont, ax));
        }
        return applyChanges(changes);
    }

    public List<OWLOntologyChange> applyChange(OWLOntologyChange change) {
        return applyChanges(Arrays.asList(change));
    }


    private void checkForImportsChange(OWLOntologyChange change) {
        if (change.isImportChange()) {
            resetImportsClosureCache();
            if (change instanceof AddImport) {
              OWLImportsDeclaration addImportDeclaration = ((AddImport) change).getImportDeclaration();
              boolean found=false;
              IRI iri = addImportDeclaration.getIRI();
        for(OWLOntologyID id:ontologiesByID.keySet()) {
                if(iri.equals(id.getDefaultDocumentIRI())||iri.equals(id.getOntologyIRI())) {
                  found=true;
                  ontologyIDsByImportsDeclaration.put(addImportDeclaration, id);
                }
              }
              if(!found) {
                // then the import does not refer to a known IRI for ontologies; check for a document IRI
                for(Map.Entry<OWLOntologyID, IRI> e:documentIRIsByID.entrySet()) {
                  if(e.getValue().equals(iri)) {
                    // found the ontology id corresponding to the file location
                    ontologyIDsByImportsDeclaration.put(addImportDeclaration, e.getKey());
                  }
                 
                }
              }
//                // Do we contain the import already?
//                for (OWLOntologyID id : ontologiesByID.keySet()) {
//                     
//                    if ((id.getDefaultDocumentIRI() != null && id.getDefaultDocumentIRI().equals(iri))||(id.getOntologyIRI() != null && id.getOntologyIRI().equals(iri))) {
//                        // Yes we do
//                        ontologyIDsByImportsDeclaration.put(addImportDeclaration, id);
//                    }
//                }
            }
            else {
                // Remove the mapping from declaration to ontology
                ontologyIDsByImportsDeclaration.remove(((RemoveImport) change).getImportDeclaration());
            }
        }
    }


    private void checkForOntologyIDChange(OWLOntologyChange change) {
        if (change instanceof SetOntologyID) {
            SetOntologyID setID = (SetOntologyID) change;
            OWLOntology existingOntology = ontologiesByID.get(((SetOntologyID) change).getNewOntologyID());
            if (existingOntology != null && !change.getOntology().equals(existingOntology)) {
                throw new OWLOntologyRenameException(change, ((SetOntologyID) change).getNewOntologyID());
            }
            renameOntology(setID.getOriginalOntologyID(), setID.getNewOntologyID());
            resetImportsClosureCache();
        }
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Methods to create, load and reload ontologies
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////


    public void ontologyCreated(OWLOntology ontology) {
        // This method is called when a factory that we have asked to create or
        // load an ontology has created the ontology.  We add the ontology to the
        // set of loaded ontologies.
        addOntology(ontology);
    }


    /**
     * Sets the format of an ontology
     * @param ontology The ontology
     * @param format The format of the ontology
     */
    public void setOntologyFormat(OWLOntology ontology, OWLOntologyFormat format) {
        OWLOntologyID ontologyID = ontology.getOntologyID();
    ontologyFormatsByOntology.put(ontologyID, format);
    }


    public OWLOntologyFormat getOntologyFormat(OWLOntology ontology) {
        OWLOntologyID ontologyID = ontology.getOntologyID();
    return ontologyFormatsByOntology.get(ontologyID);
    }


    public OWLOntology createOntology() throws OWLOntologyCreationException {
        // Brand new ontology without a URI
        return createOntology(new OWLOntologyID());
    }

    public OWLOntology createOntology(IRI ontologyIRI) throws OWLOntologyCreationException {
        return createOntology(new OWLOntologyID(ontologyIRI));
    }

    public OWLOntology createOntology(IRI ontologyIRI, IRI versionIRI) throws OWLOntologyCreationException {
        return createOntology(new OWLOntologyID(ontologyIRI, versionIRI));
    }

    public OWLOntology createOntology(OWLOntologyID ontologyID) throws OWLOntologyCreationException {
        OWLOntology ontology = ontologiesByID.get(ontologyID);
        if (ontology != null) {
            throw new OWLOntologyAlreadyExistsException(ontologyID);
        }
        IRI documentIRI = getDocumentIRIFromMappers(ontologyID, true);
        if (documentIRI == null) {
            if(!ontologyID.isAnonymous()) {
                documentIRI = ontologyID.getDefaultDocumentIRI();
            }
            else {
                documentIRI = IRI.generateDocumentIRI();
            }
            Collection<IRI> existingDocumentIRIs = documentIRIsByID.values();
            while (existingDocumentIRIs.contains(documentIRI)) {
                documentIRI = IRI.generateDocumentIRI();
            }
        }
        if (documentIRIsByID.values().contains(documentIRI)) {
            throw new OWLOntologyDocumentAlreadyExistsException(documentIRI);
        }
        for (OWLOntologyFactory factory : ontologyFactories) {
            if (factory.canCreateFromDocumentIRI(documentIRI)) {
                documentIRIsByID.put(ontologyID, documentIRI);
                return factory.createOWLOntology(ontologyID, documentIRI, this);
            }
        }
        throw new OWLOntologyFactoryNotFoundException(documentIRI);
    }

    public OWLOntology createOntology(IRI ontologyIRI, Set<OWLOntology> ontologies) throws OWLOntologyCreationException {
        return createOntology(ontologyIRI, ontologies, false);
    }


    public OWLOntology createOntology(IRI ontologyIRI, Set<OWLOntology> ontologies, boolean copyLogicalAxiomsOnly) throws OWLOntologyCreationException {
        if (contains(ontologyIRI)) {
            throw new OWLOntologyAlreadyExistsException(new OWLOntologyID(ontologyIRI));
        }
        OWLOntology ont = createOntology(ontologyIRI);
        Set<OWLAxiom> axioms = new HashSet<OWLAxiom>();
        for (OWLOntology ontology : ontologies) {
            if (copyLogicalAxiomsOnly) {
                axioms.addAll(ontology.getLogicalAxioms());
            }
            else {
                axioms.addAll(ontology.getAxioms());
            }
        }
        addAxioms(ont, axioms);
        return ont;
    }


    public OWLOntology createOntology(Set<OWLAxiom> axioms, IRI iri) throws OWLOntologyCreationException {
        if (contains(iri)) {
            throw new OWLOntologyAlreadyExistsException(new OWLOntologyID(iri));
        }
        OWLOntology ont = createOntology(iri);
        addAxioms(ont, axioms);
        return ont;
    }


    public OWLOntology createOntology(Set<OWLAxiom> axioms) throws OWLOntologyCreationException {
        return createOntology(axioms, getNextAutoGeneratedIRI());
    }

    protected IRI getNextAutoGeneratedIRI() {
        autoGeneratedURICounter = autoGeneratedURICounter + 1;
        return IRI.create("owlapi:ontology:ont" + autoGeneratedURICounter);
    }

    public OWLOntology loadOntology(IRI ontologyIRI) throws OWLOntologyCreationException {
        return loadOntology(ontologyIRI, false, new OWLOntologyLoaderConfiguration());
    }

    private OWLOntology loadOntology(IRI ontologyIRI, boolean allowExists, OWLOntologyLoaderConfiguration configuration) throws OWLOntologyCreationException {
        OWLOntologyID id = new OWLOntologyID(ontologyIRI);
        OWLOntology ontByID = ontologiesByID.get(id);
        if (ontByID != null) {
            return ontByID;
        }
        IRI documentIRI = getDocumentIRIFromMappers(id, true);
        if (documentIRIsByID.values().contains(documentIRI) && !allowExists) {
            throw new OWLOntologyDocumentAlreadyExistsException(documentIRI);
        }
        // The ontology might be being loaded, but its IRI might
        // not have been set (as is probably the case with RDF/XML!)
        if (documentIRI != null) {
            OWLOntology ontByDocumentIRI = getOntologyByDocumentIRI(documentIRI);
            if (ontByDocumentIRI != null) {
                return ontByDocumentIRI;
            }
        }
        else {
            // Nothing we can do here.  We can't get a document IRI to load
            // the ontology from.
            throw new OntologyIRIMappingNotFoundException(ontologyIRI);
        }
        return loadOntology(ontologyIRI, new IRIDocumentSource(documentIRI), configuration);
    }

    private OWLOntology getOntologyByDocumentIRI(IRI documentIRI) {
        for (OWLOntologyID ontID : documentIRIsByID.keySet()) {
            IRI docIRI = documentIRIsByID.get(ontID);
            if (docIRI != null && docIRI.equals(documentIRI)) {
                return getOntology(ontID);
            }
        }
        return null;
    }


    public OWLOntology loadOntologyFromOntologyDocument(IRI documentIRI) throws OWLOntologyCreationException {
        // Ontology URI not known in advance
        return loadOntology(null, new IRIDocumentSource(documentIRI), new OWLOntologyLoaderConfiguration());
    }

    public OWLOntology loadOntologyFromOntologyDocument(OWLOntologyDocumentSource documentSource) throws OWLOntologyCreationException {
        // Ontology URI not known in advance
        return loadOntology(null, documentSource,new OWLOntologyLoaderConfiguration());
    }

    public OWLOntology loadOntologyFromOntologyDocument(OWLOntologyDocumentSource documentSource, OWLOntologyLoaderConfiguration config) throws OWLOntologyCreationException {
        return loadOntology(null, documentSource, config);
    }

    public OWLOntology loadOntologyFromOntologyDocument(File file) throws OWLOntologyCreationException {
        return loadOntologyFromOntologyDocument(new FileDocumentSource(file));
    }

    public OWLOntology loadOntologyFromOntologyDocument(InputStream inputStream) throws OWLOntologyCreationException {
        return loadOntologyFromOntologyDocument(new StreamDocumentSource(inputStream));
    }

    /**
     * This is the method that all the other load method delegate to.
     * @param ontologyIRI The URI of the ontology to be loaded.  This is only used to
     * report to listeners and may be <code>null</code>
     * @param documentSource The input source that specifies where the ontology should be loaded from.
     * @return The ontology that was loaded.
     * @throws OWLOntologyCreationException If the ontology could not be loaded.
     */
    protected OWLOntology loadOntology(IRI ontologyIRI, OWLOntologyDocumentSource documentSource, OWLOntologyLoaderConfiguration configuration) throws OWLOntologyCreationException {
        if (loadCount != importsLoadCount) {
            System.err.println("Runtime Warning: Parsers should load imported ontologies using the makeImportLoadRequest method.");
        }
        fireStartedLoadingEvent(new OWLOntologyID(ontologyIRI), documentSource.getDocumentIRI(), loadCount > 0);
        loadCount++;
        broadcastChanges = false;
        OWLOntologyCreationException ex = null;
        OWLOntologyID idOfLoadedOntology = new OWLOntologyID();
        try {
            for (OWLOntologyFactory factory : ontologyFactories) {
                if (factory.canLoad(documentSource)) {
                    try {
                        // Note - there is no need to add the ontology here, because it will be added
                        // when the ontology is created.
                        OWLOntology ontology = factory.loadOWLOntology(documentSource, this, configuration);
                        idOfLoadedOntology = ontology.getOntologyID();
                        // Store the ontology to the document IRI mapping
                        documentIRIsByID.put(ontology.getOntologyID(), documentSource.getDocumentIRI());
                        return ontology;
                    }
                    catch (OWLOntologyRenameException e) {
                        // We loaded an ontology from a document and the ontology turned out to have an IRI the same
                        // as a previously loaded ontology
                        throw new OWLOntologyAlreadyExistsException(e.getOntologyID());
                    }
                }
            }
        }
        catch (OWLOntologyCreationException e) {
            ex = e;
            throw e;
        }
        finally {
            loadCount--;
            if (loadCount == 0) {
                broadcastChanges = true;
//                 Completed loading ontology and imports
            }
            fireFinishedLoadingEvent(idOfLoadedOntology, documentSource.getDocumentIRI(), loadCount > 0, ex);
        }
        throw new OWLOntologyFactoryNotFoundException(documentSource.getDocumentIRI());
    }


    public void removeOntology(OWLOntology ontology) {
        ontologiesByID.remove(ontology.getOntologyID());
        ontologyFormatsByOntology.remove(ontology.getOntologyID());
        documentIRIsByID.remove(ontology.getOntologyID());
        resetImportsClosureCache();
    }

    private void addOntology(OWLOntology ont) {
        ontologiesByID.put(ont.getOntologyID(), ont);
        resetImportsClosureCache();
    }


    public IRI getOntologyDocumentIRI(OWLOntology ontology) throws UnknownOWLOntologyException {
        if (!contains(ontology)) {
            throw new UnknownOWLOntologyException(ontology.getOntologyID());
        }
        return documentIRIsByID.get(ontology.getOntologyID());
    }


    public void setOntologyDocumentIRI(OWLOntology ontology, IRI documentIRI) throws UnknownOWLOntologyException {
        if (!ontologiesByID.containsKey(ontology.getOntologyID())) {
            throw new UnknownOWLOntologyException(ontology.getOntologyID());
        }
        documentIRIsByID.put(ontology.getOntologyID(), documentIRI);
    }


    /**
     * Handles a rename of an ontology.  This method should only be called *after* the change has been applied
     * @param oldID The original ID of the ontology
     * @param newID The new ID of the ontology
     */
    private void renameOntology(OWLOntologyID oldID, OWLOntologyID newID) {
        OWLOntology ont = ontologiesByID.get(oldID);
        if (ont == null) {
            // Nothing to rename!
            return;
        }
        ontologiesByID.remove(oldID);
        ontologiesByID.put(newID, ont);
        ontologyFormatsByOntology.put(newID, ontologyFormatsByOntology.remove(oldID));
       
        IRI documentIRI = documentIRIsByID.remove(oldID);
        if (documentIRI != null) {
            documentIRIsByID.put(newID, documentIRI);
        }
        resetImportsClosureCache();
    }


    private void resetImportsClosureCache() {
        importsClosureCache.clear();
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Methods to save ontologies
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////


    public void saveOntology(OWLOntology ontology) throws OWLOntologyStorageException, UnknownOWLOntologyException {
        OWLOntologyFormat format = getOntologyFormat(ontology);
        saveOntology(ontology, format);
    }


    public void saveOntology(OWLOntology ontology, OWLOntologyFormat ontologyFormat) throws OWLOntologyStorageException, UnknownOWLOntologyException {
        IRI documentIRI = getOntologyDocumentIRI(ontology);
        saveOntology(ontology, ontologyFormat, documentIRI);
    }


    public void saveOntology(OWLOntology ontology, IRI documentIRI) throws OWLOntologyStorageException, UnknownOWLOntologyException {
        OWLOntologyFormat format = getOntologyFormat(ontology);
        saveOntology(ontology, format, documentIRI);
    }


    public void saveOntology(OWLOntology ontology, OWLOntologyFormat ontologyFormat, IRI documentIRI) throws OWLOntologyStorageException, UnknownOWLOntologyException {
        try {
            for (OWLOntologyStorer storer : ontologyStorers) {
                if (storer.canStoreOntology(ontologyFormat)) {
                    storer.storeOntology(this, ontology, documentIRI, ontologyFormat);
                    return;
                }
            }
            throw new OWLOntologyStorerNotFoundException(ontologyFormat);
        }
        catch (IOException e) {
            throw new OWLOntologyStorageIOException(e);
        }
    }

    public void saveOntology(OWLOntology ontology, OutputStream outputStream) throws OWLOntologyStorageException {
        saveOntology(ontology, new StreamDocumentTarget(outputStream));
    }

    public void saveOntology(OWLOntology ontology, OWLOntologyFormat ontologyFormat, OutputStream outputStream) throws OWLOntologyStorageException {
        saveOntology(ontology, ontologyFormat, new StreamDocumentTarget(outputStream));
    }

    public void saveOntology(OWLOntology ontology, OWLOntologyDocumentTarget documentTarget) throws OWLOntologyStorageException, UnknownOWLOntologyException {
        saveOntology(ontology, getOntologyFormat(ontology), documentTarget);
    }


    public void saveOntology(OWLOntology ontology, OWLOntologyFormat ontologyFormat, OWLOntologyDocumentTarget documentTarget) throws OWLOntologyStorageException, UnknownOWLOntologyException {
        try {
            for (OWLOntologyStorer storer : ontologyStorers) {
                if (storer.canStoreOntology(ontologyFormat)) {
                    storer.storeOntology(this, ontology, documentTarget, ontologyFormat);
                    return;
                }
            }
            throw new OWLOntologyStorerNotFoundException(ontologyFormat);
        }
        catch (IOException e) {
            throw new OWLOntologyStorageIOException(e);
        }
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Methods to add/remove ontology storers
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////


    public void addOntologyStorer(OWLOntologyStorer storer) {
        ontologyStorers.add(0, storer);
    }


    public void removeOntologyStorer(OWLOntologyStorer storer) {
        ontologyStorers.remove(storer);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Methods to add/remove mappers etc.
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////


    public void addIRIMapper(OWLOntologyIRIMapper mapper) {
        documentMappers.add(0, mapper);
    }


    public void clearIRIMappers() {
        documentMappers.clear();
    }


    public void removeIRIMapper(OWLOntologyIRIMapper mapper) {
        documentMappers.remove(mapper);
    }


    public void addOntologyFactory(OWLOntologyFactory factory) {
        ontologyFactories.add(0, factory);
        factory.setOWLOntologyManager(this);
    }


    public void removeOntologyFactory(OWLOntologyFactory factory) {
        ontologyFactories.remove(factory);
    }

    /**
     * Gets the ontology factories that are registered with this manager.
     * @return A collection of ontology factories.
     */
    public Collection<OWLOntologyFactory> getOntologyFactories() {
        return new ArrayList<OWLOntologyFactory>(ontologyFactories);
    }

    /**
     * Uses the mapper mechanism to obtain an ontology document IRI from an ontology IRI.
     * @param ontologyID The ontology ID for which a document IRI is to be retrieved
     * @param quiet If set to <code>true</code> and a mapping can't be found then a value of <code>null</code>
     * is returned.  If set to <code>false</code> and a mapping can't be found then an exception {@link org.semanticweb.owlapi.model.OWLOntologyIRIMappingNotFoundException}
     * is thrown.
     * @return The document IRI that corresponds to the ontology IRI, or
     *         <code>null</code> if no physical URI can be found.
     */
    private IRI getDocumentIRIFromMappers(OWLOntologyID ontologyID, boolean quiet) {
        IRI defIRI = ontologyID.getDefaultDocumentIRI();
        if (defIRI == null) {
            return null;
        }
        for (OWLOntologyIRIMapper mapper : documentMappers) {
            IRI documentIRI = mapper.getDocumentIRI(defIRI);
            if (documentIRI != null) {
                return documentIRI;
            }
        }
        if (!quiet) {
            throw new OWLOntologyIRIMappingNotFoundException(ontologyID.getDefaultDocumentIRI());
        }
        else {
            return null;
        }
    }


    private void installDefaultURIMappers() {
        // By defaut install the default mapper that simply maps
        // ontology URIs to themselves.
        addIRIMapper(new NonMappingOntologyIRIMapper());
    }


    private void installDefaultOntologyFactories() {
        // The default factories are the ones that can load
        // ontologies from http:// and file:// URIs
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Listener stuff - methods to add/remove listeners
    //
    ////////////////////////////////////////////////////////////////////////////////////////////////////

    private Map<OWLOntologyChangeListener, OWLOntologyChangeBroadcastStrategy> listenerMap = new IdentityHashMap<OWLOntologyChangeListener, OWLOntologyChangeBroadcastStrategy>();

    private Map<ImpendingOWLOntologyChangeListener, ImpendingOWLOntologyChangeBroadcastStrategy> impendingChangeListenerMap = new IdentityHashMap<ImpendingOWLOntologyChangeListener, ImpendingOWLOntologyChangeBroadcastStrategy>();

    private List<OWLOntologyChangesVetoedListener> vetoListeners = new ArrayList<OWLOntologyChangesVetoedListener>();

    public void addOntologyChangeListener(OWLOntologyChangeListener listener) {
        listenerMap.put(listener, defaultChangeBroadcastStrategy);
    }

    /**
     * Broadcasts to attached listeners, using the various broadcasting
     * strategies that were specified for each listener.
     * @param changes The ontology changes to broadcast
     */
    private void broadcastChanges(List<? extends OWLOntologyChange> changes) {
        if (!broadcastChanges) {
            return;
        }
        for (OWLOntologyChangeListener listener : new ArrayList<OWLOntologyChangeListener>(listenerMap.keySet())) {
            OWLOntologyChangeBroadcastStrategy strategy = listenerMap.get(listener);
            if (strategy == null) {
                // This listener may have been removed during the broadcast of the changes,
                // so when we attempt to retrieve it from the map it isn't there (because
                // we iterate over a copy).
                continue;
            }
            try {
                // Handle exceptions on a per listener basis.  If we have
                // badly behaving listeners, we don't want one listener
                // to prevent the other listeners from receiving events.
                strategy.broadcastChanges(listener, changes);
            }
            catch (Throwable e) {
                logger.warning("BADLY BEHAVING LISTENER: " + e);
                e.printStackTrace();
            }
        }
    }

    private void broadcastImpendingChanges(List<? extends OWLOntologyChange> changes) throws OWLOntologyChangeVetoException {
        if (!broadcastChanges) {
            return;
        }
        for (ImpendingOWLOntologyChangeListener listener : new ArrayList<ImpendingOWLOntologyChangeListener>(impendingChangeListenerMap.keySet())) {
            ImpendingOWLOntologyChangeBroadcastStrategy strategy = impendingChangeListenerMap.get(listener);
            if (strategy != null) {
                strategy.broadcastChanges(listener, changes);
            }
        }
    }

    public void setDefaultChangeBroadcastStrategy(OWLOntologyChangeBroadcastStrategy strategy) {
        if (strategy != null) {
            defaultChangeBroadcastStrategy = strategy;
        }
        else {
            defaultChangeBroadcastStrategy = new DefaultChangeBroadcastStrategy();
        }
    }

    public void addOntologyChangeListener(OWLOntologyChangeListener listener, OWLOntologyChangeBroadcastStrategy strategy) {
        listenerMap.put(listener, strategy);
    }

    public void addImpendingOntologyChangeListener(ImpendingOWLOntologyChangeListener listener) {
        impendingChangeListenerMap.put(listener, defaultImpendingChangeBroadcastStrategy);
    }

    public void removeImpendingOntologyChangeListener(ImpendingOWLOntologyChangeListener listener) {
        impendingChangeListenerMap.remove(listener);
    }

    public void removeOntologyChangeListener(OWLOntologyChangeListener listener) {
        listenerMap.remove(listener);
    }

    public void addOntologyChangesVetoedListener(OWLOntologyChangesVetoedListener listener) {
        vetoListeners.add(listener);
    }

    public void removeOntologyChangesVetoedListener(OWLOntologyChangesVetoedListener listener) {
        vetoListeners.remove(listener);
    }

    private void broadcastOntologyChangesVetoed(List<? extends OWLOntologyChange> changes, OWLOntologyChangeVetoException veto) {
        for (OWLOntologyChangesVetoedListener listener : new ArrayList<OWLOntologyChangesVetoedListener>(vetoListeners)) {
            listener.ontologyChangesVetoed(changes, veto);
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  Imports etc.
    //
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    private OWLOntology loadImports(OWLImportsDeclaration declaration, OWLOntologyLoaderConfiguration configuration) throws OWLOntologyCreationException {
        importsLoadCount++;
        OWLOntology ont = null;
        try {
            ont = loadOntology(declaration.getIRI(), true, configuration);
        }
        catch (OWLOntologyCreationException e) {
          //XXX note: uses both the configuration and this manager silent missing imports handling; should be removed when the manager mechanism is removed
            if (!configuration.isSilentMissingImportsHandling()&&!isSilentMissingImportsHandling()) {
                throw e;
            }
            else {
                // Silent
                MissingImportEvent evt = new MissingImportEvent(declaration.getURI(), e);
                fireMissingImportEvent(evt);
            }
        }
        finally {
            importsLoadCount--;
        }
        return ont;
    }

    @SuppressWarnings("deprecation")
    public void makeLoadImportRequest(OWLImportsDeclaration declaration) throws UnloadableImportException {
        makeLoadImportRequest(declaration, new OWLOntologyLoaderConfiguration());
    }

    @SuppressWarnings("deprecation")
    public void makeLoadImportRequest(OWLImportsDeclaration declaration, OWLOntologyLoaderConfiguration configuration) throws UnloadableImportException {
        if (!configuration.isIgnoredImport(declaration.getIRI())) {
            try {
                OWLOntology ont = loadImports(declaration, configuration);
                if (ont != null) {
                    ontologyIDsByImportsDeclaration.put(declaration, ont.getOntologyID());
                }
            }
            catch (OWLOntologyCreationException e) {
                // Wrap as UnloadableImportException and throw
                throw new UnloadableImportException(e, declaration);
            }
        }
    }


    public void setSilentMissingImportsHandling(boolean b) {
        silentMissingImportsHandling = b;
    }


    public boolean isSilentMissingImportsHandling() {
        return silentMissingImportsHandling;
    }


    public void addMissingImportListener(MissingImportListener listener) {
        missingImportsListeners.add(listener);
    }


    public void removeMissingImportListener(MissingImportListener listener) {
        missingImportsListeners.remove(listener);
    }

    protected void fireMissingImportEvent(MissingImportEvent evt) {
        for (MissingImportListener listener : new ArrayList<MissingImportListener>(missingImportsListeners)) {
            listener.importMissing(evt);
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  Other listeners etc.
    //
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////


    public void addOntologyLoaderListener(OWLOntologyLoaderListener listener) {
        loaderListeners.add(listener);
    }


    public void removeOntologyLoaderListener(OWLOntologyLoaderListener listener) {
        loaderListeners.remove(listener);
    }

    protected void fireStartedLoadingEvent(OWLOntologyID ontologyID, IRI documentIRI, boolean imported) {
        for (OWLOntologyLoaderListener listener : new ArrayList<OWLOntologyLoaderListener>(loaderListeners)) {
            listener.startedLoadingOntology(new OWLOntologyLoaderListener.LoadingStartedEvent(ontologyID, documentIRI, imported));
        }
    }

    protected void fireFinishedLoadingEvent(OWLOntologyID ontologyID, IRI documentIRI, boolean imported, OWLOntologyCreationException ex) {
        for (OWLOntologyLoaderListener listener : new ArrayList<OWLOntologyLoaderListener>(loaderListeners)) {
            listener.finishedLoadingOntology(new OWLOntologyLoaderListener.LoadingFinishedEvent(ontologyID, documentIRI, imported, ex));
        }
    }

    public void addOntologyChangeProgessListener(OWLOntologyChangeProgressListener listener) {
        progressListeners.add(listener);
    }

    public void removeOntologyChangeProgessListener(OWLOntologyChangeProgressListener listener) {
        progressListeners.remove(listener);
    }

    protected void fireBeginChanges(int size) {
        try {
            if (!broadcastChanges) {
                return;
            }
            for (OWLOntologyChangeProgressListener lsnr : progressListeners) {
                lsnr.begin(size);
            }
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }

    protected void fireEndChanges() {
        try {
            if (!broadcastChanges) {
                return;
            }
            for (OWLOntologyChangeProgressListener lsnr : progressListeners) {
                lsnr.end();
            }
        }
        catch (Throwable e) {
            // Listener threw an exception
            e.printStackTrace();
        }
    }

    protected void fireChangeApplied(OWLOntologyChange change) {
        try {
            if (!broadcastChanges) {
                return;
            }
            if (progressListeners.isEmpty()) {
                return;
            }
            for (OWLOntologyChangeProgressListener lsnr : progressListeners) {
                lsnr.appliedChange(change);
            }
        }
        catch (Throwable e) {
            // Listener threw an exception
            e.printStackTrace();
        }
    }

}
TOP

Related Classes of uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.