All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.clarkparsia.modularity.io.TaxonomyPersistence Maven / Gradle / Ivy

There is a newer version: 2.3.6-ansell
Show newest version
// Copyright (c) 2006 - 2009, Clark & Parsia, LLC. 
// This source code is available under the terms of the Affero General Public
// License v3.
//
// Please see LICENSE.txt for full license terms, including the availability of
// proprietary exceptions.
// Questions, comments, or requests for clarification: [email protected]

package com.clarkparsia.modularity.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.mindswap.pellet.taxonomy.Taxonomy;
import org.mindswap.pellet.taxonomy.TaxonomyNode;
import org.mindswap.pellet.utils.TaxonomyUtils;
import org.semanticweb.owlapi.formats.OWLXMLOntologyFormat;
import org.semanticweb.owlapi.io.StreamDocumentTarget;
import org.semanticweb.owlapi.model.AddAxiom;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owlapi.model.OWLException;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyChange;
import org.semanticweb.owlapi.model.OWLOntologyChangeException;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;

import com.clarkparsia.owlapiv3.OWL;

/**
 * 

* Title: Stores and restores a taxonomy to a stream. *

*

* Description: Enables storing and reading back a taxonomy from a stream. The taxonomy is first converted into an ontology, and then saved using * the standard OWLRenderers. *

*

* Copyright: Copyright (c) 2009 *

*

* Company: Clark & Parsia, LLC. *

* * @author Blazej Bulka */ public class TaxonomyPersistence { public static final Logger log = Logger.getLogger( TaxonomyPersistence.class.getName() ); /** * The URI of the ontology created to represent the Taxonomy */ private static IRI TAXONOMY_ONTOLOGY_IRI = IRI.create( "http://clarkparsia.com/pellet/modularity/taxonomy" ); /** * Saves a taxonomy into a stream. * * @param ontologyManager the ontology manager * @param taxonomy the taxonomy to be saved * @param outputStream the output stream where the ontology should be saved * @throws IOException if an I/O error should occur */ public static void save( Taxonomy taxonomy, OutputStream outputStream ) throws IOException { try { OWLOntology ontology = createTaxonomyOntology( taxonomy ); OWL.manager.saveOntology( ontology, new OWLXMLOntologyFormat(), new StreamDocumentTarget( outputStream) ); outputStream.flush(); OWL.manager.removeOntology( ontology ); } catch( OWLException e ) { log.log( Level.SEVERE, "An error occured while creating an ontology for taxonomy", e ); throw new IOException( "An error occured while creating an ontology for taxonomy" ); } } /** * Converts a taxonomy into an ontology. * * @param ontologyManager the ontology manager * @param taxonomy the taxonomy to be converted * @return the ontology based on the taxonomy * @throws OWLOntologyCreationException if OWLAPI reports an exception during the creation of the ontology * @throws OWLOntologyChangeException if OWLAPI report an exception during the population of the ontology */ private static OWLOntology createTaxonomyOntology( Taxonomy taxonomy ) throws OWLOntologyCreationException, OWLOntologyChangeException { OWLOntology ontology = OWL.Ontology( Collections.emptyList(), TAXONOMY_ONTOLOGY_IRI ); // populate the ontology LinkedList changes = new LinkedList(); HashSet processedEquivalentClasses = new HashSet(); for( TaxonomyNode taxonomyNode : taxonomy.getNodes() ) { if ( processedEquivalentClasses.contains( taxonomyNode.getName() ) ) { continue; } processedEquivalentClasses.addAll( taxonomyNode.getEquivalents() ); for( OWLClass owlClass : taxonomyNode.getEquivalents() ) { // add the class axiom AddAxiom classAxiom = new AddAxiom( ontology, OWL.declaration( owlClass ) ); changes.add( classAxiom ); // add the super/subclass axiom between the classes for( TaxonomyNode superNode : taxonomyNode.getSupers() ) { //if( superNode == taxonomy.getTop() ) // continue; AddAxiom subClassOfAxiom = new AddAxiom( ontology, OWL.subClassOf( owlClass, superNode.getName() ) ); changes.add( subClassOfAxiom ); } } // add the equivalent classes axiom if( taxonomyNode.getEquivalents().size() > 1 ) { AddAxiom equivalentAxiom = new AddAxiom( ontology, OWL.equivalentClasses( taxonomyNode.getEquivalents() ) ); changes.add( equivalentAxiom ); } // save the individuals Collection individuals = (Collection) taxonomyNode.getDatum( TaxonomyUtils.INSTANCES_KEY ); if( ( individuals != null ) && ( !individuals.isEmpty() ) ) { for( OWLNamedIndividual ind : individuals ) { AddAxiom classAssertionAxiom = new AddAxiom( ontology, OWL.classAssertion( ind, taxonomyNode.getName() ) ); changes.add( classAssertionAxiom ); } } } OWL.manager.applyChanges( changes ); return ontology; } /** * Gets all the super classes of the given class in the ontology * @param ontology ontology to be queried * @param owlClass the class whose super classes are to be retrieved * @return a set of super classes */ private static Set getSuperClasses( OWLOntology ontology, OWLClass owlClass ) { HashSet superClasses = new HashSet(); for( OWLSubClassOfAxiom superClassAxiom : ontology.getSubClassAxiomsForSubClass( owlClass ) ) { OWLClassExpression owlSuperDescription = superClassAxiom.getSuperClass(); if (owlSuperDescription instanceof OWLClass) { superClasses.add( (OWLClass) owlSuperDescription ); } } return superClasses; } /** * Creates a taxonomy from the ontology. * @param ontology the ontology containing the data which is the source for the taxonomy * @return the created taxonomy */ private static Taxonomy createTaxonomy( OWLOntology ontology ) { Taxonomy taxonomy = new Taxonomy(null, OWL.Thing, OWL.Nothing); HashSet processedEquivalentClasses = new HashSet(); processedEquivalentClasses.add( OWL.Thing ); processedEquivalentClasses.add( OWL.Nothing ); // first create all the nodes in the taxonomy based on classes in the ontology and the equivalence relationships among them // (only one node in taxonomy for all the equivalent classes in the group) for( OWLClass owlClass : ontology.getClassesInSignature() ) { if (processedEquivalentClasses.contains( owlClass )) { continue; } HashSet equivalentClasses = new HashSet(); boolean equivalentToThing = false; boolean equivalentToNothing = false; for ( OWLEquivalentClassesAxiom equivalentAxiom : ontology.getEquivalentClassesAxioms( owlClass ) ) { equivalentClasses.addAll( equivalentAxiom.getNamedClasses() ); if ( equivalentAxiom.containsOWLNothing() ) { equivalentToNothing = true; } if ( equivalentAxiom.containsOWLThing() ) { equivalentToThing = true; } } equivalentClasses.removeAll( processedEquivalentClasses ); if ( equivalentToThing ) { taxonomy.addEquivalents( OWL.Thing, equivalentClasses ); } else if ( equivalentToNothing ) { taxonomy.addEquivalents( OWL.Nothing, equivalentClasses ); } else { if ( equivalentClasses.contains( owlClass ) ) { equivalentClasses.remove( owlClass ); } taxonomy.addNode( owlClass, false ); taxonomy.addEquivalents( owlClass, equivalentClasses ); } processedEquivalentClasses.add( owlClass ); processedEquivalentClasses.addAll( equivalentClasses ); } // post process the top and bottom nodes for( TaxonomyNode taxonomyNode : taxonomy.getNodes() ) { if ( OWL.Nothing.equals(taxonomyNode.getName() ) && ( taxonomyNode.getSupers().size() > 1 ) && ( taxonomyNode.getSupers().contains( taxonomy.getTop() ) ) ) { taxonomy.getTop().removeSub( taxonomyNode ); } } // after all the nodes are in the taxonomy, create subclass and superclass relationships among them for ( TaxonomyNode taxonomyNode : taxonomy.getNodes() ) { OWLClass owlClass = taxonomyNode.getName(); if( owlClass == null || owlClass.equals( OWL.Nothing ) ) continue; taxonomy.addSupers( owlClass, getSuperClasses( ontology, owlClass ) ); } // read the instance data (if available) for( TaxonomyNode taxonomyNode : taxonomy.getNodes() ) { Set individuals = null; for( OWLClassAssertionAxiom classAssertionAxiom : ontology.getClassAssertionAxioms( taxonomyNode.getName() ) ) { OWLIndividual individual = classAssertionAxiom.getIndividual(); if( individual.isNamed() && ( individual instanceof OWLNamedIndividual ) ) { if( individuals == null ) { individuals = new HashSet(); } individuals.add( (OWLNamedIndividual) individual ); } } if( individuals != null ) { taxonomyNode.putDatum( TaxonomyUtils.INSTANCES_KEY, individuals ); } } return taxonomy; } /** * Loads the taxonomy from a stream * @param ontologyManager the ontology manager * @param is the stream containing the taxonomy in the form of an ontology * @return the read taxonomy * @throws IOException if an I/O error should occur while reading the taxonomy */ public static Taxonomy load( InputStream is ) throws IOException { try { OWLOntology ontology = OWL.manager.loadOntologyFromOntologyDocument( is ); Taxonomy result = createTaxonomy( ontology ); OWL.manager.removeOntology( ontology ); return result; } catch( OWLOntologyCreationException e ) { log.log( Level.SEVERE, "Unable to create the ontology", e ); throw new IOException( "Unable to create the ontology" ); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy