/* * Copyright (c) 2007, 2010, James Leigh All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the openrdf.org nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ package net.enilink.komma.generator; import java.io.File; 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.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.enilink.commons.iterator.IExtendedIterator; import net.enilink.komma.core.IEntity; import net.enilink.komma.core.IEntityManager; import net.enilink.komma.core.ILiteral; import net.enilink.komma.core.INamespace; import net.enilink.komma.core.IQuery; import net.enilink.komma.core.IReference; import net.enilink.komma.core.IStatement; import net.enilink.komma.core.IValue; import net.enilink.komma.core.Statement; import net.enilink.komma.core.URI; import net.enilink.komma.core.URIs; import net.enilink.komma.em.concepts.IResource; import net.enilink.vocab.owl.Class; import net.enilink.vocab.owl.OWL; import net.enilink.vocab.owl.Ontology; import net.enilink.vocab.owl.Thing; import net.enilink.vocab.rdf.Property; import net.enilink.vocab.rdf.RDF; import net.enilink.vocab.rdfs.Datatype; import net.enilink.vocab.rdfs.RDFS; import net.enilink.vocab.xmlschema.XMLSCHEMA; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; /** * Applies a series of rules against the ontology, making it easier to convert * into Java classes. This includes applying some OWL reasoning on properties, * renaming anonymous and foreign classes. * */ public class OwlNormalizer { private final Logger log = LoggerFactory.getLogger(OwlNormalizer.class); private static final String PREFIX = "PREFIX rdf: <" + RDF.NAMESPACE + "> PREFIX rdfs: <" + RDFS.NAMESPACE + "> PREFIX owl: <" + OWL.NAMESPACE + "> "; private static final String FIND_PROPERTIES_WO_DOMAIN = PREFIX + "SELECT ?prop " + "WHERE { { ?prop a rdf:Property } " + "UNION { ?prop a owl:ObjectProperty } UNION { ?prop a owl:DatatypeProperty } " + "UNION { ?prop a owl:DeprecatedProperty } UNION { ?prop a owl:AnnotationProperty } " + "OPTIONAL { ?prop rdfs:domain ?domain } " + "OPTIONAL { ?restriction owl:onProperty ?prop }" + "FILTER (!(bound(?domain) || bound(?restriction))) }"; private static final String SELECT_DEFINED = PREFIX + "SELECT ?bean " + "WHERE { ?bean rdfs:isDefinedBy ?ont " + "FILTER ( ?bean != ?ont ) } "; private static final String FIND_ORPHANS_ONTOLOGY = PREFIX + "SELECT DISTINCT ?bean ?ontology" + " WHERE { GRAPH ?graph { ?bean a ?type. " + " ?ontology a owl:Ontology " + " OPTIONAL { ?bean rdfs:isDefinedBy ?ont }" + " FILTER ( isURI(?bean) && ! bound(?ont) ) }}"; private static final String SELECT_ORPHANS = PREFIX + "SELECT DISTINCT ?bean WHERE { ?bean rdf:type ?type" + " OPTIONAL { ?bean rdfs:isDefinedBy ?ont }" + " FILTER ( isURI(?bean) && ! bound(?ont) ) }"; private static final String BEAN_DEFINED_BY = PREFIX + "SELECT ?bean WHERE { ?bean rdfs:isDefinedBy ?ont }"; private static final String SELECT_C_INTERSECTION_OF = PREFIX + "SELECT ?c WHERE { ?c owl:intersectionOf ?l }"; private static final String SELECT_C_ONE_OF = PREFIX + "SELECT ?c WHERE { ?c owl:oneOf ?l }"; private IEntityManager manager; private Set<IReference> anonymousClasses = new HashSet<IReference>(); private Map<URI, URI> aliases = new HashMap<URI, URI>(); private Map<URI, Ontology> ontologies; private Set<String> commonNS = new HashSet<String>(Arrays.asList( RDF.NAMESPACE, RDFS.NAMESPACE, OWL.NAMESPACE)); private static final Pattern NS_PREFIX = Pattern .compile("^.*[/#](\\w+)[/#]?$"); private void addBaseClass(Class base, java.lang.Class<Class> type) { IQuery<?> query = manager.createQuery(BEAN_DEFINED_BY); for (Object ont : base.getRdfsIsDefinedBy()) { query.setParameter("ont", ont); for (Object o : query.getResultList()) { if (o instanceof Class && !o.equals(base)) { Class c = (Class) o; boolean isBase = true; for (net.enilink.vocab.rdfs.Class e : c .getRdfsSubClassOf()) { if (e.getRdfsIsDefinedBy().contains(ont)) { isBase = false; } } if (isBase) { log.debug("extending " + c + " " + base); c.getRdfsSubClassOf().add(base); } } } } } private void assignOrphansToNewOntology(Map<URI, Ontology> ontologies) { IExtendedIterator<IResource> results = manager.createQuery( SELECT_ORPHANS).evaluate(IResource.class); try { while (results.hasNext()) { IResource bean = results.next(); URI ns = bean.getURI().namespace(); Ontology ont = findOntology(ns, ontologies); log.debug("assigning " + bean + " " + ont); bean.getRdfsIsDefinedBy().add(ont); } } finally { results.close(); } } private void assignOrphansToTheirOntology(Map<URI, Ontology> ontologies) { IExtendedIterator<Object[]> results = manager.createQuery( FIND_ORPHANS_ONTOLOGY).evaluate(Object[].class); try { while (results.hasNext()) { Object[] result = results.next(); IResource bean = (IResource) result[0]; if (bean.getRdfsIsDefinedBy().isEmpty()) { IReference ontology = (IReference) result[1]; log.debug("assigning " + bean + " " + ontology); bean.getRdfsIsDefinedBy().add(ontology); } } } finally { results.close(); } } private void checkNamespacePrefixes() throws Exception { IExtendedIterator<IReference> results = manager.createQuery( SELECT_DEFINED).evaluate(IReference.class); try { while (results.hasNext()) { IReference bean = results.next(); if (bean.getURI() == null) continue; URI ns = bean.getURI().namespace(); String prefix = getPrefix(ns); if (prefix == null) { Matcher matcher = NS_PREFIX.matcher(ns.toString()); if (matcher.find()) { prefix = matcher.group(1); log.debug("creating prefix " + prefix + " " + ns); manager.setNamespace(prefix, ns); } } } } finally { results.close(); } } private void checkPropertyDomains() { IQuery<?> query = manager.createQuery(FIND_PROPERTIES_WO_DOMAIN); java.util.List<?> list = query.getResultList(); for (Object result : list) { Property p = (Property) result; boolean found = false; for (Property sup : p.getRdfsSubPropertyOf()) { if (!sup.getRdfsDomains().isEmpty()) { found = true; p.getRdfsDomains().addAll(sup.getRdfsDomains()); } } if (!found) { Class res = manager.createNamed( net.enilink.vocab.rdfs.RDFS.TYPE_RESOURCE, Class.class); p.getRdfsDomains().add(res); } } } private URI createLocalClass(URI obj, Ontology ont) { String localName = obj.localPart(); String prefix = findPrefix(ont); if (prefix != null) { localName = initcap(prefix) + initcap(localName); } URI nc = URIs.createURI(findNamespace(ont)).appendLocalPart( localName); aliases.put(nc, obj); if (obj.equals(RDFS.TYPE_RESOURCE)) { Class base = manager.createNamed(nc, Class.class); base.getRdfsIsDefinedBy().add(ont); addBaseClass(base, Class.class); } return nc; } private void distributeEquivalentClasses() { for (Class klass : manager.findAll(Class.class)) { for (Class equiv : klass.getOwlEquivalentClasses()) { klass.getOwlEquivalentClasses().addAll( equiv.getOwlEquivalentClasses()); } klass.getOwlEquivalentClasses().remove(klass); } for (Class c : manager.findAll(Class.class)) { for (Class e : c.getOwlEquivalentClasses()) { c.getOwlDisjointWith().addAll(e.getOwlDisjointWith()); List<Class> inter = e.getOwlIntersectionOf(); if (inter != null) { if (c.getOwlIntersectionOf() == null) { c.setOwlIntersectionOf(inter); } else if (!inter.equals(c.getOwlIntersectionOf())) { java.util.List<Class> list = new ArrayList<Class>(inter); list.removeAll(c.getOwlIntersectionOf()); c.getOwlIntersectionOf().addAll(list); } } if (e.getOwlOneOf() != null) { if (c.getOwlOneOf() == null) { c.setOwlOneOf(e.getOwlOneOf()); } else if (!e.getOwlOneOf().equals(c.getOwlOneOf())) { java.util.List<Object> list = new ArrayList<Object>( e.getOwlOneOf()); list.removeAll(c.getOwlOneOf()); c.getOwlOneOf().addAll(list); } } if (e.getOwlUnionOf() != null) { if (c.getOwlUnionOf() == null) { c.setOwlUnionOf(e.getOwlUnionOf()); } else if (!e.getOwlUnionOf().equals(c.getOwlUnionOf())) { java.util.List<Class> list = new ArrayList<Class>( e.getOwlUnionOf()); list.removeAll(c.getOwlUnionOf()); c.getOwlUnionOf().addAll(list); } } if (e.getOwlComplementOf() != null) { if (c.getOwlComplementOf() == null) { c.setOwlComplementOf(e.getOwlComplementOf()); } } if (!e.getOwlDisjointWith().isEmpty()) { c.getOwlDisjointWith().addAll(e.getOwlDisjointWith()); } } } } private Set<IReference> findClasses(Collection<IReference> classes) { Set<IReference> set = new HashSet<IReference>(classes); for (IReference c : classes) { IExtendedIterator<IStatement> stmts = manager.match(null, RDFS.PROPERTY_SUBCLASSOF, c); try { while (stmts.hasNext()) { IStatement stmt = stmts.next(); IReference subj = stmt.getSubject(); set.add(subj); } } finally { stmts.close(); } } if (set.size() > classes.size()) { return findClasses(set); } else { return set; } } private Class findCommon( Collection<? extends net.enilink.vocab.rdfs.Class> common, List<? extends IEntity> unionOf) { Class result = null; for (IEntity e : unionOf) { if (common.contains(e)) { result = (Class) e; } } return result; } private Collection<? extends net.enilink.vocab.rdfs.Class> findCommonSupers( java.util.List<?> unionOf) { Set<net.enilink.vocab.rdfs.Class> common = null; for (Object of : unionOf) { Set<net.enilink.vocab.rdfs.Class> supers = findSuperClasses((Class) of); if (common == null) { common = new HashSet<net.enilink.vocab.rdfs.Class>( supers); } else { common.retainAll(supers); } } if (common == null) return Collections.emptySet(); Iterator<? extends IEntity> iter = common.iterator(); while (iter.hasNext()) { if (iter.next().getURI() == null) { iter.remove(); } } return common; } private String findNamespace(Ontology ont) { String prefix = findPrefix(ont); if (prefix != null) { String ns = manager.getNamespace(prefix).toString(); if (ns.endsWith("#") || ns.endsWith("/") || ns.endsWith(":")) return ns; if (ns.contains("#")) return ns.substring(0, ns.indexOf('#') + 1); return ns + "#"; } String ns = ont.toString(); if (ns.contains("#")) return ns.substring(0, ns.indexOf('#') + 1); return ont.toString() + '#'; } private void findNamespacesOfOntologies(Map<URI, Ontology> ontologies) { IQuery<?> query = manager.createQuery(BEAN_DEFINED_BY); for (Ontology ont : manager.findAll(Ontology.class)) { log.debug("found ontology " + ont); ontologies.put(ont.getURI(), ont); ontologies.put(ont.getURI().trimFragment(), ont); ontologies.put(ont.getURI().appendFragment(""), ont); Set<URI> spaces = new HashSet<URI>(); query.setParameter("ont", ont); IExtendedIterator<IReference> result = query .evaluate(IReference.class); try { while (result.hasNext()) { IReference bean = result.next(); if (bean.getURI() != null) { spaces.add(bean.getURI().namespace()); } } } finally { result.close(); } if (spaces.size() > 0) { for (URI ns : spaces) { ontologies.put(ns, ont); } } else { ontologies.put(guessNamespace(ont), ont); } } } private Map<URI, Ontology> findOntologies() { Map<URI, Ontology> ontologies = new HashMap<URI, Ontology>(); assignOrphansToTheirOntology(ontologies); findNamespacesOfOntologies(ontologies); assignOrphansToNewOntology(ontologies); return ontologies; } private Ontology findOntology(URI ns, Map<URI, Ontology> ontologies) { if (ontologies.containsKey(ns)) { return ontologies.get(ns); } for (Map.Entry<URI, Ontology> e : ontologies.entrySet()) { String keyStr = e.getKey().toString(); if (keyStr.indexOf('#') > 0 && ns.toString().startsWith( keyStr.substring(0, keyStr.indexOf('#')))) return e.getValue(); } Ontology ont = manager.createNamed(ns.trimFragment(), Ontology.class); ontologies.put(ns, ont); return ont; } private String findPrefix(Ontology ont) { IExtendedIterator<INamespace> spaces = manager.getNamespaces(); try { while (spaces.hasNext()) { INamespace next = spaces.next(); if (next.getURI().equals(ont.getURI().namespace())) return next.getPrefix(); for (Map.Entry<URI, Ontology> e : ontologies.entrySet()) { if (e.getValue().equals(ont) && next.getURI().equals(e.getKey())) return next.getPrefix(); } } } finally { spaces.close(); } return null; } private Set<net.enilink.vocab.rdfs.Class> findSuperClasses(Class of) { HashSet<net.enilink.vocab.rdfs.Class> set = new HashSet<net.enilink.vocab.rdfs.Class>(); set.add(of); return findSuperClasses(of, set); } private Set<net.enilink.vocab.rdfs.Class> findSuperClasses( Class of, Set<net.enilink.vocab.rdfs.Class> supers) { if (supers.addAll(of.getRdfsSubClassOf())) { for (Object s : of.getRdfsSubClassOf()) { findSuperClasses((Class) s, supers); } } return supers; } public Map<URI, URI> getAliases() { return aliases; } public Set<IReference> getAnonymousClasses() { return anonymousClasses; } public URI getOriginal(URI alias) { if (anonymousClasses.contains(alias)) return null; if (aliases.containsKey(alias)) return aliases.get(alias); return alias; } private String getPrefix(URI namespace) { return manager.getPrefix(namespace); } private URI guessNamespace(IEntity bean) { if (bean instanceof Ontology) { return bean.getURI(); } return bean.getURI().namespace(); } private void infer() { log.debug("inferring"); propagateSubClassType(RDFS.TYPE_CLASS); symmetric(OWL.PROPERTY_INVERSEOF); symmetric(OWL.PROPERTY_EQUIVALENTCLASS); symmetric(OWL.PROPERTY_EQUIVALENTPROPERTY); symmetric(OWL.PROPERTY_DISJOINTWITH); setSubjectType(RDF.PROPERTY_FIRST, null, RDF.TYPE_LIST); setSubjectType(RDF.PROPERTY_REST, null, RDF.TYPE_LIST); setSubjectType(OWL.PROPERTY_UNIONOF, null, OWL.TYPE_CLASS); setSubjectType(OWL.PROPERTY_DISJOINTWITH, null, OWL.TYPE_CLASS); setSubjectType(OWL.PROPERTY_COMPLEMENTOF, null, OWL.TYPE_CLASS); setSubjectType(OWL.PROPERTY_EQUIVALENTCLASS, null, OWL.TYPE_CLASS); setSubjectType(OWL.PROPERTY_INTERSECTIONOF, null, OWL.TYPE_CLASS); setSubjectType(RDF.PROPERTY_TYPE, RDFS.TYPE_CLASS, OWL.TYPE_CLASS); setSubjectType(RDF.PROPERTY_TYPE, OWL.TYPE_DEPRECATEDCLASS, OWL.TYPE_CLASS); setObjectType(RDFS.PROPERTY_SUBCLASSOF, OWL.TYPE_CLASS); setObjectType(OWL.PROPERTY_UNIONOF, RDF.TYPE_LIST); setObjectType(RDFS.PROPERTY_ISDEFINEDBY, OWL.TYPE_ONTOLOGY); setSubjectType(OWL.PROPERTY_INVERSEOF, null, OWL.TYPE_OBJECTPROPERTY); setObjectType(OWL.PROPERTY_INVERSEOF, OWL.TYPE_OBJECTPROPERTY); setSubjectType(RDFS.PROPERTY_RANGE, null, RDF.TYPE_PROPERTY); setSubjectType(RDFS.PROPERTY_DOMAIN, null, RDF.TYPE_PROPERTY); setObjectType(RDFS.PROPERTY_SUBPROPERTYOF, RDF.TYPE_PROPERTY); setDatatype(OWL.PROPERTY_CARDINALITY, XMLSCHEMA.TYPE_NONNEGATIVEINTEGER); setDatatype(OWL.PROPERTY_MINCARDINALITY, XMLSCHEMA.TYPE_NONNEGATIVEINTEGER); setDatatype(OWL.PROPERTY_MAXCARDINALITY, XMLSCHEMA.TYPE_NONNEGATIVEINTEGER); } private String initcap(String str) { if (str.isEmpty()) { return str; } return str.substring(0, 1).toUpperCase() + str.substring(1); } private boolean isInOntology(URI subj, URI ns, Ontology ont) { if (subj.namespace().equals(ns)) return true; return manager.hasMatch(subj, RDFS.PROPERTY_ISDEFINEDBY, ont); } private boolean isInSameOntology(URI subj, URI obj) { if (subj.namespace().equals(obj.namespace())) return true; IExtendedIterator<IStatement> stmts = manager.match(subj, RDFS.PROPERTY_ISDEFINEDBY, null); try { while (stmts.hasNext()) { if (manager.hasMatch(obj, RDFS.PROPERTY_ISDEFINEDBY, stmts .next().getObject())) return true; } } finally { stmts.close(); } return false; } private boolean isLocal(IReference nc, IReference obj) { if (obj.getURI() == null) return true; if (nc.getURI() == null) return true; return isInSameOntology(nc.getURI(), obj.getURI()); } private void mergeUnionClasses() { Iterable<Class> classes = manager.findAll(Class.class); for (Class clazz : classes) { List<? extends IEntity> unionOf = clazz.getOwlUnionOf(); if (unionOf != null) { Collection<? extends net.enilink.vocab.rdfs.Class> common = findCommonSupers(unionOf); if (common.contains(clazz)) { unionOf.clear(); manager.remove(unionOf); continue; } else if (findCommon(common, unionOf) != null) { Class sup = findCommon(common, unionOf); unionOf.clear(); manager.remove(unionOf); if (sup.getURI() == null) { sup = nameAnonymous(sup); } rename(clazz, sup.getURI()); continue; } clazz.getRdfsSubClassOf().addAll(common); for (IEntity bean : unionOf) { Class of = manager.assignTypes(bean, Class.class); if (bean instanceof Datatype && bean.getURI() != null) { // don't use anonymous class for datatypes rename(clazz, bean.getURI()); } else if (isLocal(clazz, of)) { of.getRdfsSubClassOf().add(clazz); } else { Ontology ont = (Ontology) clazz.getRdfsIsDefinedBy() .toArray()[0]; URI nc = createLocalClass(of.getURI(), ont); manager.add(Arrays .asList( // new Statement(nc, RDF.PROPERTY_TYPE, OWL.TYPE_CLASS), // new Statement(nc, RDFS.PROPERTY_SUBCLASSOF, of), // new Statement(nc, RDFS.PROPERTY_SUBCLASSOF, clazz), // new Statement(nc, RDFS.PROPERTY_ISDEFINEDBY, ont))); renameClass(of.getURI(), nc); } } } } } private void moveForeignDomains() { IExtendedIterator<IStatement> stmts = manager.match(null, RDFS.PROPERTY_DOMAIN, null); try { while (stmts.hasNext()) { IStatement stmt = stmts.next(); if (stmt.getSubject().getURI() != null && stmt.getObject() instanceof IReference && ((IReference) stmt.getObject()).getURI() != null) { URI subj = stmt.getSubject().getURI(); URI obj = ((IReference) stmt.getObject()).getURI(); for (Map.Entry<URI, Ontology> e : ontologies.entrySet()) { URI ns = e.getKey(); Ontology ont = e.getValue(); if (isInOntology(subj, ns, ont) && !isInSameOntology(subj, obj)) { URI nc = createLocalClass(obj, ont); log.debug("moving " + subj + " " + nc); manager.remove(stmt); manager.add(Arrays.asList( // new Statement(subj, RDFS.PROPERTY_DOMAIN, nc), // new Statement(nc, RDF.PROPERTY_TYPE, OWL.TYPE_CLASS), // new Statement(nc, RDFS.PROPERTY_SUBCLASSOF, obj), // new Statement(nc, RDFS.PROPERTY_ISDEFINEDBY, ont))); } } } } } finally { stmts.close(); } } @SuppressWarnings("unchecked") private Class nameAnonymous(Class clazz) { List<Class> unionOf = clazz.getOwlUnionOf(); if (unionOf != null) { return renameClass(clazz, "Or", unionOf); } List<Class> intersectionOf = clazz.getOwlIntersectionOf(); if (intersectionOf != null) { return renameClass(clazz, "And", intersectionOf); } List<? extends IEntity> oneOf = (List<? extends IEntity>) clazz .getOwlOneOf(); if (oneOf != null) { boolean things = true; for (Object of : oneOf) { things &= of instanceof Thing; } if (things) return renameClass(clazz, "Or", oneOf); } Class complement = clazz.getOwlComplementOf(); if (complement != null) { net.enilink.komma.core.URI comp = complement.getURI(); if (comp == null) { Class nc = nameAnonymous(complement); if (nc == null) return null; comp = nc.getURI(); } String name = "Not" + comp.localPart(); return rename(clazz, comp.namespace().appendLocalPart(name)); } return null; } public void normalize() throws Exception { infer(); ontologies = findOntologies(); checkNamespacePrefixes(); checkPropertyDomains(); subClassIntersectionOf(); subClassOneOf(); distributeEquivalentClasses(); mergeUnionClasses(); moveForeignDomains(); if (log.isDebugEnabled()) { File file = File.createTempFile("normalized", ".rdf"); // manager.getConnection().export(new OrganizedRDFXMLWriter(file)); log.debug("Normalized RDF saved to " + file); } } private void propagateSubClassType(IReference classDef) { for (IReference c : findClasses(Collections.singleton(classDef))) { if (c.equals(RDFS.TYPE_DATATYPE)) continue; IExtendedIterator<IStatement> stmts = manager.match(null, RDF.PROPERTY_TYPE, c); try { while (stmts.hasNext()) { IStatement stmt = stmts.next(); IReference subj = stmt.getSubject(); manager.add(new Statement(subj, RDF.PROPERTY_TYPE, classDef)); } } finally { stmts.close(); } } } private Class rename(Class clazz, net.enilink.komma.core.URI name) { log.debug("renaming " + clazz + " " + name); Ontology ont = findOntology(name.namespace(), ontologies); Class renamed = manager.rename(clazz, name); renamed.getRdfsIsDefinedBy().add(ont); anonymousClasses.add(renamed); return renamed; } private Class renameClass(Class clazz, String and, List<? extends IEntity> list) { String namespace = null; Set<String> names = new TreeSet<String>(); for (IEntity of : list) { net.enilink.komma.core.URI uri = of.getURI(); if (uri == null) { if (!(of instanceof Class)) return null; Class nc = nameAnonymous((Class) of); if (nc == null) return null; uri = nc.getURI(); } if (namespace == null || commonNS.contains(namespace)) { namespace = uri.namespace().toString(); } names.add(uri.localPart()); } StringBuilder sb = new StringBuilder(); for (String localPart : names) { sb.append(initcap(localPart)); sb.append(and); } sb.setLength(sb.length() - and.length()); return rename(clazz, URIs.createURI(namespace).appendLocalPart(sb.toString())); } private void renameClass(URI obj, URI nc) { log.debug("renaming " + obj + " " + nc); aliases.put(nc, obj); IExtendedIterator<IStatement> stmts = manager.match(null, null, obj); try { while (stmts.hasNext()) { IStatement stmt = stmts.next(); if (isLocal(nc, stmt.getSubject())) { if (!stmt.getPredicate().equals(RDFS.PROPERTY_RANGE) || !stmt.getObject().equals(RDFS.TYPE_RESOURCE)) { if (!stmt.getPredicate().equals(RDF.PROPERTY_TYPE)) manager.remove(stmt); manager.add(new Statement(stmt.getSubject(), stmt .getPredicate(), nc)); } } } } finally { stmts.close(); } if (obj.equals(RDFS.TYPE_RESOURCE)) { Class base = manager.createNamed(URIs.createURI(nc.toString()), Class.class); addBaseClass(base, Class.class); } } private void setDatatype(URI pred, URI datatype) { IExtendedIterator<IStatement> stmts = manager.match(null, pred, null); try { while (stmts.hasNext()) { IStatement stmt = stmts.next(); if (stmt.getObject() instanceof IReference) { continue; } String label = ((ILiteral) stmt.getObject()).getLabel(); ILiteral literal = manager.createLiteral(label, datatype, null); manager.remove(stmt); manager.add(new Statement(stmt.getSubject(), stmt .getPredicate(), literal)); } } finally { stmts.close(); } } private void setObjectType(URI pred, URI type) { IExtendedIterator<IStatement> stmts = manager.match(null, pred, null); try { while (stmts.hasNext()) { IStatement st = stmts.next(); if (st.getObject() instanceof IReference) { IReference subj = (IReference) st.getObject(); manager.add(new Statement(subj, RDF.PROPERTY_TYPE, type)); } else { log.warn("Invalid statement " + st); } } } finally { stmts.close(); } } @Inject public void setEntityManager(IEntityManager manager) { this.manager = manager; } private void setSubjectType(URI pred, IValue obj, URI type) { IExtendedIterator<IStatement> stmts = manager.match(null, pred, obj); try { while (stmts.hasNext()) { manager.add(new Statement(stmts.next().getSubject(), RDF.PROPERTY_TYPE, type)); } } finally { stmts.close(); } } @SuppressWarnings("unchecked") private void subClassIntersectionOf() { IQuery<?> query = manager.createQuery(SELECT_C_INTERSECTION_OF); java.util.List<Class> classes = (java.util.List<Class>) query .getResultList(); for (Class c : classes) { List<Class> intersectionOf = c.getOwlIntersectionOf(); if (intersectionOf != null) { for (Class of : intersectionOf) { c.getRdfsSubClassOf().add(of); } } } } @SuppressWarnings("unchecked") private void subClassOneOf() { IQuery<?> query = manager.createQuery(SELECT_C_ONE_OF); java.util.List<Class> classes = (java.util.List<Class>) query .getResultList(); for (Class c : classes) { java.util.List<Object> list = new ArrayList<Object>(); for (Object of : c.getOwlOneOf()) { if (of instanceof Thing) { Set<?> types = ((Thing) of).getRdfTypes(); if (types.isEmpty()) { list.add(manager.find(OWL.TYPE_THING)); } else { list.addAll(types); } } } for (net.enilink.vocab.rdfs.Class s : findCommonSupers(list)) { c.getRdfsSubClassOf().add(s); } } } private void symmetric(URI pred) { IExtendedIterator<IStatement> stmts = manager.match(null, pred, null); try { while (stmts.hasNext()) { IStatement stmt = stmts.next(); if (stmt.getObject() instanceof IReference) { IReference subj = (IReference) stmt.getObject(); manager.add(new Statement(subj, pred, stmt.getSubject())); } else { log.warn("Invalid statement " + stmt); } } } finally { stmts.close(); } } }