/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source: /cvsroot/slrp/boca/com.ibm.adtech.boca.owl/src/com/ibm/adtech/boca/utils/Attic/OntologyUtils.java,v $ * Created by: Matthew Roy ( <a href="mailto:mroy@us.ibm.com">mroy@us.ibm.com </a>) * Created on: Apr 5, 2007 * Revision: $Id: OntologyUtils.java 165 2007-07-31 14:11:11Z mroy $ * * Contributors: * IBM Corporation - initial API and implementation * Cambridge Semantics Incorporated - Fork to Anzo *******************************************************************************/ package org.openanzo.rdf.owl.utils; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import org.openanzo.exceptions.AnzoException; import org.openanzo.glitter.Engine; import org.openanzo.glitter.query.PatternSolution; import org.openanzo.glitter.query.QueryResults; import org.openanzo.rdf.BlankNode; import org.openanzo.rdf.INamedGraph; import org.openanzo.rdf.MemQuadStore; import org.openanzo.rdf.Resource; import org.openanzo.rdf.Statement; import org.openanzo.rdf.URI; import org.openanzo.rdf.Value; import org.openanzo.rdf.jastor.JastorException; import org.openanzo.rdf.jastor.Thing; import org.openanzo.rdf.owl.DatatypeProperty; import org.openanzo.rdf.owl.Individual; import org.openanzo.rdf.owl.OWL11Factory; import org.openanzo.rdf.owl.ObjectProperty; import org.openanzo.rdf.owl._Thing; import org.openanzo.rdf.query.QuadStoreEngineConfig; import org.openanzo.rdf.query.QueryEncoder; import org.openanzo.rdf.rdfs.RDFSFactory; import org.openanzo.rdf.rdfs._Property; import org.openanzo.rdf.utils.StatementUtils; import org.openanzo.rdf.vocabulary.OWL; import org.openanzo.rdf.vocabulary.RDF; import org.openanzo.rdf.vocabulary.RDFS; /** * Utilities for operating on ontology data within a INamedGraph * * @author Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>) * */ public class OntologyUtils { /** * Within an INamedGraph, retrieve all the individuals of the given class type * * @param graph * graph containing data * @param clazz * class for which whose type must match * @param directlyAssertedOnly * only include individuals that directly assert the classes type * @return set of Resources for the individuals that match */ public static Collection<Resource> getAllImplementors(INamedGraph graph, org.openanzo.rdf.rdfs.Class clazz, boolean directlyAssertedOnly) { HashSet<Resource> impls = new HashSet<Resource>(); Iterable<Statement> stmts = graph.find(null, RDF.TYPE, clazz.resource()); for (Statement stmt : stmts) { impls.add(stmt.getSubject()); } if (!directlyAssertedOnly) { List<org.openanzo.rdf.rdfs.Class> subclasses = getSubClasses(clazz, directlyAssertedOnly); for (org.openanzo.rdf.rdfs.Class clazzz : subclasses) { Iterable<Statement> stmtss = graph.find(null, RDF.TYPE, clazzz.resource()); for (Statement stmt : stmtss) { impls.add(stmt.getSubject()); } } } return impls; } /** * Get the set of all defined Classes within the INamedGraph * * @param graph * graph containing data * @param directlyAssertedOnly * only include classes that directly assert RDFS.CLASS TYPE or OWL.CLASS TYPE * @return the set of Resources for all defined Classes within the INamedGraph */ public static Collection<Resource> getAllClasses(INamedGraph graph, boolean directlyAssertedOnly) { HashSet<Resource> impls = new HashSet<Resource>(); Iterable<Statement> stmts = graph.find(null, RDF.TYPE, RDFS.Class); for (Statement stmt : stmts) { impls.add(stmt.getSubject()); } stmts = graph.find(null, RDF.TYPE, OWL.CLASS); for (Statement stmt : stmts) { impls.add(stmt.getSubject()); } if (!directlyAssertedOnly) { List<Resource> subclasses = getSubClasses(graph, RDFS.Class, directlyAssertedOnly); for (Resource clazzz : subclasses) { Iterable<Statement> stmtss = graph.find(null, RDF.TYPE, clazzz); for (Statement stmt : stmtss) { impls.add(stmt.getSubject()); } } subclasses = getSubClasses(graph, OWL.CLASS, directlyAssertedOnly); for (Resource clazzz : subclasses) { Iterable<Statement> stmtss = graph.find(null, RDF.TYPE, clazzz); for (Statement stmt : stmtss) { impls.add(stmt.getSubject()); } } } return impls; } /** * Get subclasses for a given Class * * @param graph * graph containing data * @param clazz * type of class of which to find subclasses * @param directlyAssertedOnly * only include classes that are directlyAssertedOnly subclasses * @return set of Resources for subclasses for a given Class */ public static List<Resource> getSubClasses(INamedGraph graph, Resource clazz, boolean directlyAssertedOnly) { ArrayList<Resource> subClasses = new ArrayList<Resource>(); Iterable<Statement> subClazzes = graph.find(null, RDFS.subClassOf, clazz); for (Statement next : subClazzes) { Resource subClazz = next.getSubject(); if (!subClasses.contains(subClazz)) { subClasses.add(subClazz); if (!directlyAssertedOnly) { List<Resource> scs = getSubClasses(graph, subClazz, directlyAssertedOnly); for (Resource scc : scs) { if (!subClasses.contains(scc)) { subClasses.add(scc); } } } } } return subClasses; } /** * Get subclasses for a given Class * * @param clazz * class of which to find subclasses * @param directlyAssertedOnly * only include classes that directly asserted subclasses * @return set of subclasses for the Class */ public static List<org.openanzo.rdf.rdfs.Class> getSubClasses(org.openanzo.rdf.rdfs.Class clazz, boolean directlyAssertedOnly) { ArrayList<org.openanzo.rdf.rdfs.Class> subClasses = new ArrayList<org.openanzo.rdf.rdfs.Class>(); Iterable<Statement> subClazzes = clazz.graph().find(null, RDFS.subClassOf, clazz.resource()); for (Statement next : subClazzes) { org.openanzo.rdf.rdfs.Class subClazz = OWL11Factory.getClass(next.getSubject(), clazz.graph()); if (subClazz.isRDFType(org.openanzo.rdf.rdfs.Class.TYPE) || subClazz.isRDFType(org.openanzo.rdf.owl.Class.TYPE)) { if (!subClasses.contains(subClazz)) { subClasses.add(subClazz); if (!directlyAssertedOnly) { List<org.openanzo.rdf.rdfs.Class> scs = getSubClasses(subClazz, directlyAssertedOnly); for (org.openanzo.rdf.rdfs.Class scc : scs) { if (!subClasses.contains(scc)) { subClasses.add(scc); } } } } } } return subClasses; } /** * Get super classes for a given Class * * @param clazz * class of which to find super classes * @param directlyAssertedOnly * only include classes that directly asserted super classes * @return set of super classes for the Class */ public static List<org.openanzo.rdf.rdfs.Class> getSuperClasses(org.openanzo.rdf.rdfs.Class clazz, boolean directlyAssertedOnly) { ArrayList<org.openanzo.rdf.rdfs.Class> subClasses = new ArrayList<org.openanzo.rdf.rdfs.Class>(); Iterable<Statement> subClazzes = clazz.graph().find(clazz.resource(), RDFS.subClassOf, null); for (Statement next : subClazzes) { if (next.getObject() instanceof Resource) { org.openanzo.rdf.owl.Class subClazz = OWL11Factory.getClass((Resource) next.getObject(), clazz.graph()); if (subClazz.isRDFType(org.openanzo.rdf.rdfs.Class.TYPE)) { if (!subClasses.contains(subClazz)) { subClasses.add(subClazz); if (!directlyAssertedOnly) { List<org.openanzo.rdf.rdfs.Class> scs = getSuperClasses(subClazz, directlyAssertedOnly); for (org.openanzo.rdf.rdfs.Class scc : scs) { if (!subClasses.contains(scc)) { subClasses.add(scc); } } } } } } } subClasses.add(OWL11Factory.getClass(_Thing.TYPE, clazz.graph())); return subClasses; } /** * Get set of sub properties for the property * * @param property * property of which to find sub properties * @param directlyAssertedOnly * only include directly asserted sub properties * @return set of sub properties for the property */ public static List<_Property> getSubProperties(_Property property, boolean directlyAssertedOnly) { ArrayList<_Property> subProperties = new ArrayList<_Property>(); Iterable<Statement> subProperteizes = property.graph().find(null, RDFS.subPropertyOf, property.resource()); for (Statement next : subProperteizes) { _Property subProperty = RDFSFactory.get_Property(next.getSubject(), property.graph()); if (subProperty.isRDFType(_Property.TYPE)) { if (!subProperties.contains(subProperty)) { subProperties.add(subProperty); if (!directlyAssertedOnly) { List<_Property> scs = getSubProperties(subProperty, directlyAssertedOnly); for (_Property spp : scs) { if (!subProperties.contains(spp)) { subProperties.add(spp); } } } } } } return subProperties; } /** * Get set of super properties for the property * * @param property * property of which to find super properties * @param directlyAssertedOnly * only include directly asserted super properties * @return set of super properties for the property */ public static List<_Property> getSuperProperties(_Property property, boolean directlyAssertedOnly) { ArrayList<_Property> subProperties = new ArrayList<_Property>(); Iterable<Statement> subProperteizes = property.graph().find(property.resource(), RDFS.subPropertyOf, null); for (Statement next : subProperteizes) { if (next.getObject() instanceof Resource) { _Property subProperty = RDFSFactory.get_Property((Resource) next.getObject(), property.graph()); if (subProperty.isRDFType(_Property.TYPE) || subProperty.isRDFType(DatatypeProperty.TYPE) || subProperty.isRDFType(ObjectProperty.TYPE)) { if (!subProperties.contains(subProperty)) { subProperties.add(subProperty); if (!directlyAssertedOnly) { List<_Property> scs = getSuperProperties(subProperty, directlyAssertedOnly); for (_Property spp : scs) { if (!subProperties.contains(spp)) { subProperties.add(spp); } } } } } } } return subProperties; } /** * Get all individuals for the given class type. Includes non direct implementors of the class type. * * @param graph * graph containing data * @param clazz * class of which to find individuals * @return set of Individuals of a given class type */ public static Collection<Individual> getAllIndividuals(INamedGraph graph, org.openanzo.rdf.rdfs.Class clazz) { HashSet<Individual> individuals = new HashSet<Individual>(); Collection<Resource> implementors = getAllImplementors(graph, clazz, false); for (Resource resource : implementors) { Individual indv = OWL11Factory.getIndividual(resource, graph); individuals.add(indv); } return individuals; } /** * Get the set of Classes that make up the Range of a property * * @param property * property of which to find the Range classes * @return set of Classes that make up the Range of a property * @throws AnzoException */ public static List<org.openanzo.rdf.rdfs.Class> getRange(_Property property) throws AnzoException { ArrayList<org.openanzo.rdf.rdfs.Class> ranges = new ArrayList<org.openanzo.rdf.rdfs.Class>(); org.openanzo.rdf.rdfs.Class range = property.getRange(); if (range != null && range.resource() instanceof BlankNode) { org.openanzo.rdf.owl.Class clazz = OWL11Factory.getClass(range.resource(), property.graph()); Thing union = clazz.getUnionOf(); if (union != null) { for (Value value : StatementUtils.getContainerMembers(union.resource(), property.graph())) { if (value instanceof Resource) { // org.openanzo.rdf.rdfs.Class rangeClazz = OWL11Factory.getClass((Resource) value, ontGraph); ranges.add(OWL11Factory.createClass((Resource) value, property.graph())); } } } else { if (!clazz.isRDFType(org.openanzo.rdf.rdfs.Class.TYPE)) { ranges.add(OWL11Factory.createClass(clazz.resource(), property.graph())); } else { ranges.add(clazz); } } } else if (range != null) { if (!range.isRDFType(org.openanzo.rdf.rdfs.Class.TYPE)) { range = OWL11Factory.createClass(range.resource(), property.graph()); } ranges.add(range); } return ranges; } /** * Get the set of Classes that make up the Domain of a property * * @param property * property of which to find the Domain classes * @return set of Classes that make up the Domain of a property * @throws AnzoException */ public static List<org.openanzo.rdf.rdfs.Class> getDomain(_Property property) throws AnzoException { ArrayList<org.openanzo.rdf.rdfs.Class> domains = new ArrayList<org.openanzo.rdf.rdfs.Class>(); org.openanzo.rdf.rdfs.Class domain = property.getDomain(); if (domain != null && domain.resource() instanceof BlankNode) { org.openanzo.rdf.owl.Class clazz = OWL11Factory.getClass(domain.resource(), property.graph()); Thing union = clazz.getUnionOf(); if (union != null) { for (Value value : StatementUtils.getContainerMembers(union.resource(), property.graph())) { if (value instanceof Resource) { // org.openanzo.rdf.rdfs.Class rangeClazz = OWL11Factory.getClass((Resource) value, ontGraph); domains.add(OWL11Factory.createClass((Resource) value, property.graph())); } } } else { if (!clazz.isRDFType(org.openanzo.rdf.rdfs.Class.TYPE)) { domains.add(OWL11Factory.createClass(clazz.resource(), property.graph())); } else { domains.add(clazz); } } } else if (domain != null) { if (!domain.isRDFType(org.openanzo.rdf.rdfs.Class.TYPE)) { domain = OWL11Factory.createClass(domain.resource(), property.graph()); } domains.add(domain); } return domains; } /** * Get the set of properties whose domain matches the class * * @param clazz * class for which to find properties * @return the set of properties whose domain matches the class * @throws JastorException */ public static List<_Property> findDeclaredProperties(org.openanzo.rdf.rdfs.Class clazz) throws JastorException { List<_Property> properties = new ArrayList<_Property>(); String query = "SELECT ?res WHERE {?res " + QueryEncoder.encodeForQuery(RDF.TYPE) + " " + QueryEncoder.encodeForQuery(DatatypeProperty.TYPE) + " . ?res " + QueryEncoder.encodeForQuery(RDFS.domain) + " " + QueryEncoder.encodeForQuery(clazz.resource()) + "}"; MemQuadStore ds = new MemQuadStore(); ds.add(clazz.graph().getStatements()); QuadStoreEngineConfig config = new QuadStoreEngineConfig(ds); Engine glitter = new Engine(config); try { QueryResults results = glitter.executeQuery(null, query, Collections.singleton(clazz.graph().getNamedGraphUri()), Collections.<URI> emptySet()); Iterator<PatternSolution> iter = results.getSelectResults().iterator(); while (iter.hasNext()) { iter.next(); Resource propRes = (Resource) iter.next().getBinding("res"); if (propRes != null) { DatatypeProperty dp = OWL11Factory.getDatatypeProperty(propRes, clazz.graph()); if (dp.isRDFType(DatatypeProperty.TYPE)) { properties.add(dp); } } } } catch (Exception e) { throw new JastorException(e, "Error querying for properties"); } query = "SELECT ?res WHERE {?res " + QueryEncoder.encodeForQuery(RDF.TYPE) + " " + QueryEncoder.encodeForQuery(ObjectProperty.TYPE) + " . ?res " + QueryEncoder.encodeForQuery(RDFS.domain) + " " + QueryEncoder.encodeForQuery(clazz.resource()) + "}"; try { QueryResults results = glitter.executeQuery(null, query, Collections.singleton(clazz.graph().getNamedGraphUri()), Collections.<URI> emptySet()); Iterator<PatternSolution> iter = results.getSelectResults().iterator(); while (iter.hasNext()) { iter.next(); Resource propRes = (Resource) iter.next().getBinding("res"); if (propRes != null) { ObjectProperty dp = OWL11Factory.getObjectProperty(propRes, clazz.graph()); if (dp.isRDFType(ObjectProperty.TYPE)) { properties.add(dp); } } } } catch (Exception e) { throw new JastorException(e, "Error querying for properties"); } return properties; } }