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

org.coode.owlapi.rdf.renderer.RDFRendererBase Maven / Gradle / Ivy

There is a newer version: 3.4.9.2-ansell
Show newest version
/*
 * 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 org.coode.owlapi.rdf.renderer;

import static org.semanticweb.owlapi.vocab.OWLRDFVocabulary.*;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.coode.owlapi.rdf.model.RDFGraph;
import org.coode.owlapi.rdf.model.RDFTranslator;
import org.semanticweb.owlapi.io.RDFLiteral;
import org.semanticweb.owlapi.io.RDFNode;
import org.semanticweb.owlapi.io.RDFOntologyFormat;
import org.semanticweb.owlapi.io.RDFResource;
import org.semanticweb.owlapi.io.RDFResourceBlankNode;
import org.semanticweb.owlapi.io.RDFResourceIRI;
import org.semanticweb.owlapi.io.RDFTriple;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnnotation;
import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
import org.semanticweb.owlapi.model.OWLAnnotationSubject;
import org.semanticweb.owlapi.model.OWLAnnotationValueVisitorEx;
import org.semanticweb.owlapi.model.OWLAnonymousIndividual;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLDatatype;
import org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom;
import org.semanticweb.owlapi.model.OWLDisjointClassesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointObjectPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLEntityVisitor;
import org.semanticweb.owlapi.model.OWLHasKeyAxiom;
import org.semanticweb.owlapi.model.OWLImportsDeclaration;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyFormat;
import org.semanticweb.owlapi.model.OWLOntologyID;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom;
import org.semanticweb.owlapi.model.SWRLRule;
import org.semanticweb.owlapi.model.SWRLVariable;
import org.semanticweb.owlapi.util.AxiomSubjectProvider;
import org.semanticweb.owlapi.util.SWRLVariableExtractor;


/**
 * Author: Matthew Horridge
* The University Of Manchester
* Bio-Health Informatics Group
* Date: 26-Jan-2008

*/ @SuppressWarnings("javadoc") public abstract class RDFRendererBase { private static final String ANNOTATION_PROPERTIES_BANNER_TEXT = "Annotation properties"; private static final String DATATYPES_BANNER_TEXT = "Datatypes"; private static final String OBJECT_PROPERTIES_BANNER_TEXT = "Object Properties"; private static final String DATA_PROPERTIES_BANNER_TEXT = "Data properties"; private static final String CLASSES_BANNER_TEXT = "Classes"; private static final String INDIVIDUALS_BANNER_TEXT = "Individuals"; private static final String ANNOTATED_IRIS_BANNER_TEXT = "Annotations"; public static final String GENERAL_AXIOMS_BANNER_TEXT = "General axioms"; public static final String RULES_BANNER_TEXT = "Rules"; protected OWLOntology ontology; private RDFGraph graph; protected Set prettyPrintedTypes; private OWLOntologyFormat format; public RDFRendererBase(OWLOntology ontology) { this(ontology, ontology.getOWLOntologyManager().getOntologyFormat(ontology)); } @Deprecated public RDFRendererBase(OWLOntology ontology, OWLOntologyManager manager) { this(ontology, ontology.getOWLOntologyManager().getOntologyFormat(ontology)); } @Deprecated protected RDFRendererBase(OWLOntology ontology, OWLOntologyManager manager, OWLOntologyFormat format) { this(ontology, format); } protected RDFRendererBase(OWLOntology ontology, OWLOntologyFormat format) { this.ontology = ontology; this.format = format; } public RDFGraph getGraph() { return graph; } public OWLOntology getOntology() { return ontology; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////// /////// Hooks for subclasses /////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Called before the ontology document is rendered. * @throws IOException if there was a problem writing to the output stream */ protected abstract void beginDocument() throws IOException; /** * Called after the ontology document has been rendered. * @throws IOException if there was a problem writing to the output stream */ protected abstract void endDocument() throws IOException; /** * Called before an OWLObject such as an entity, anonymous individual, rule etc. is rendered. * @throws IOException if there was a problem writing to the output stream */ protected void beginObject() throws IOException { } /** * Called after an OWLObject such as an entity, anonymous individual, rule etc. has been rendered. * @throws IOException if there was a problem writing to the output stream */ protected void endObject() throws IOException { } /** * Called before an annotation property is rendered to give subclasses the chance to prefix the rendering with * comments etc. * @param prop The property being rendered * @throws IOException if there was a problem writing to the output stream */ protected abstract void writeAnnotationPropertyComment(OWLAnnotationProperty prop) throws IOException; /** * Called before a data property is rendered to give subclasses the chance to prefix the rendering with comments etc. * @param prop The property being rendered * @throws IOException if there was a problem writing to the output stream */ protected abstract void writeDataPropertyComment(OWLDataProperty prop) throws IOException; /** * Called before an object property is rendered. * @param prop The property being rendered * @throws IOException if there was a problem writing to the output stream */ protected abstract void writeObjectPropertyComment(OWLObjectProperty prop) throws IOException; /** * Called before a class is rendered to give subclasses the chance to prefix the rendering with comments etc. * @param cls The class being rendered * @throws IOException if there was a problem writing to the output stream */ protected abstract void writeClassComment(OWLClass cls) throws IOException; /** * Called before a datatype is rendered to give subclasses the chance to prefix the rendering with comments etc. * @param datatype The datatype being rendered * @throws IOException if there was a problem writing to the output stream */ protected abstract void writeDatatypeComment(OWLDatatype datatype) throws IOException; /** * Called before an individual is rendered to give subclasses the chance to prefix the rendering with comments etc. * @param ind The individual being rendered * @throws IOException if there was a problem writing to the output stream */ protected abstract void writeIndividualComments(OWLNamedIndividual ind) throws IOException; public void render() throws IOException { beginDocument(); renderOntologyHeader(); renderOntologyComponents(); endDocument(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////// /////// Rendering implementation /////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void renderOntologyComponents() throws IOException { renderInOntologySignatureEntities(); renderAnonymousIndividuals(); renderUntypedIRIAnnotationAssertions(); renderGeneralAxioms(); renderSWRLRules(); } private void renderInOntologySignatureEntities() throws IOException { renderAnnotationProperties(); renderDatatypes(); renderObjectProperties(); renderDataProperties(); renderClasses(); renderNamedIndividuals(); } private void renderAnnotationProperties() throws IOException { Set annotationProperties = ontology.getAnnotationPropertiesInSignature(); renderEntities(annotationProperties, ANNOTATION_PROPERTIES_BANNER_TEXT); } private void renderNamedIndividuals() throws IOException { Set individuals = ontology.getIndividualsInSignature(); renderEntities(individuals, INDIVIDUALS_BANNER_TEXT); } private void renderClasses() throws IOException { Set clses = ontology.getClassesInSignature(); renderEntities(clses, CLASSES_BANNER_TEXT); } private void renderDataProperties() throws IOException { Set dataProperties = ontology.getDataPropertiesInSignature(); renderEntities(dataProperties, DATA_PROPERTIES_BANNER_TEXT); } private void renderObjectProperties() throws IOException { Set objectProperties = ontology.getObjectPropertiesInSignature(); renderEntities(objectProperties, OBJECT_PROPERTIES_BANNER_TEXT); } private void renderDatatypes() throws IOException { Set datatypes = ontology.getDatatypesInSignature(); renderEntities(datatypes, DATATYPES_BANNER_TEXT); } /** * Renders a set of entities. * @param entities The entities. Not null. * @param bannerText The banner text that will prefix the rendering of the entities if anything is rendered. * Not null. May be empty, in which case no banner will be written. * @throws IOException If there was a problem writing the rendering */ private void renderEntities(Set entities, String bannerText) throws IOException { boolean firstRendering = true; for(OWLEntity entity : toSortedSet(entities)) { if(createGraph(entity)) { if(firstRendering) { firstRendering = false; if (!bannerText.isEmpty()) { writeBanner(bannerText); } } renderEntity(entity); } } } private void renderEntity(OWLEntity entity) throws IOException { beginObject(); writeEntityComment(entity); render(new RDFResourceIRI(entity.getIRI())); renderAnonRoots(); endObject(); } /** * Calls the appropriate hook method to write the comments for an entity. * @param entity The entity for which comments should be written. * @throws IOException if there was a problem writing the comment */ private void writeEntityComment(OWLEntity entity) throws IOException { if(entity.isOWLClass()) { writeClassComment(entity.asOWLClass()); } else if(entity.isOWLDatatype()) { writeDatatypeComment(entity.asOWLDatatype()); } else if(entity.isOWLObjectProperty()) { writeObjectPropertyComment(entity.asOWLObjectProperty()); } else if(entity.isOWLDataProperty()) { writeDataPropertyComment(entity.asOWLDataProperty()); } else if(entity.isOWLAnnotationProperty()) { writeAnnotationPropertyComment(entity.asOWLAnnotationProperty()); } else if(entity.isOWLNamedIndividual()) { writeIndividualComments(entity.asOWLNamedIndividual()); } } private void renderUntypedIRIAnnotationAssertions() throws IOException { Set annotatedIRIs = new HashSet(); for (OWLAnnotationAssertionAxiom ax : ontology.getAxioms(AxiomType.ANNOTATION_ASSERTION)) { OWLAnnotationSubject subject = ax.getSubject(); if (subject instanceof IRI) { IRI iri = (IRI) subject; if (!ontology.containsEntityInSignature(iri)) { annotatedIRIs.add(iri); } } } if (!annotatedIRIs.isEmpty()) { writeBanner(ANNOTATED_IRIS_BANNER_TEXT); for (IRI iri : annotatedIRIs) { beginObject(); createGraph(ontology.getAnnotationAssertionAxioms(iri)); render(new RDFResourceIRI(iri)); renderAnonRoots(); endObject(); } } } private void renderAnonymousIndividuals() throws IOException { for (OWLAnonymousIndividual anonInd : ontology.getReferencedAnonymousIndividuals()) { boolean anonRoot = true; Set axioms = new HashSet(); for (OWLAxiom ax : ontology.getReferencingAxioms(anonInd)) { if (!(ax instanceof OWLDifferentIndividualsAxiom)) { AxiomSubjectProvider subjectProvider = new AxiomSubjectProvider(); OWLObject obj = subjectProvider.getSubject(ax); if (!obj.equals(anonInd)) { anonRoot = false; break; } else { axioms.add(ax); } } } if (anonRoot) { //TODO check this: in some cases it seems to cause a StackOverflow error. createGraph(axioms); renderAnonRoots(); } } } private void renderSWRLRules() throws IOException { Set ruleAxioms = ontology.getAxioms(AxiomType.SWRL_RULE); createGraph(ruleAxioms); if (!ruleAxioms.isEmpty()) { writeBanner(RULES_BANNER_TEXT); SWRLVariableExtractor variableExtractor = new SWRLVariableExtractor(); for (SWRLRule rule : ruleAxioms) { rule.accept(variableExtractor); } for (SWRLVariable var : variableExtractor.getVariables()) { render(new RDFResourceIRI(var.getIRI())); } renderAnonRoots(); } } private void renderGeneralAxioms() throws IOException { Set generalAxioms = getGeneralAxioms(); createGraph(generalAxioms); Set rootNodes = graph.getRootAnonymousNodes(); if (!rootNodes.isEmpty()) { writeBanner(GENERAL_AXIOMS_BANNER_TEXT); beginObject(); renderAnonRoots(); endObject(); } } /** * Gets the general axioms in the ontology. These are axioms such as DifferentIndividuals, General Class axioms * which do not describe or define a named class and so can't be written out as a frame, nary disjoint classes, * disjoint object properties, disjoint data properties and HasKey axioms where the class expression is anonymous. * @return A set of axioms that are general axioms (and can't be written out in a frame-based style). */ private Set getGeneralAxioms() { Set generalAxioms = new HashSet(); generalAxioms.addAll(ontology.getGeneralClassAxioms()); generalAxioms.addAll(ontology.getAxioms(AxiomType.DIFFERENT_INDIVIDUALS)); for (OWLDisjointClassesAxiom ax : ontology.getAxioms(AxiomType.DISJOINT_CLASSES)) { if (ax.getClassExpressions().size() > 2) { generalAxioms.add(ax); } } for (OWLDisjointObjectPropertiesAxiom ax : ontology.getAxioms(AxiomType.DISJOINT_OBJECT_PROPERTIES)) { if (ax.getProperties().size() > 2) { generalAxioms.add(ax); } } for (OWLDisjointDataPropertiesAxiom ax : ontology.getAxioms(AxiomType.DISJOINT_DATA_PROPERTIES)) { if (ax.getProperties().size() > 2) { generalAxioms.add(ax); } } for (OWLHasKeyAxiom ax : ontology.getAxioms(AxiomType.HAS_KEY)) { if (ax.getClassExpression().isAnonymous()) { generalAxioms.add(ax); } } return generalAxioms; } private void renderOntologyHeader() throws IOException { graph = new RDFGraph(); OWLOntologyID ontID = ontology.getOntologyID(); RDFResource ontologyHeaderNode = createOntologyHeaderNode(); addVersionIRIToOntologyHeader(ontologyHeaderNode); addImportsDeclarationsToOntologyHeader(ontologyHeaderNode); addAnnotationsToOntologyHeader(ontologyHeaderNode); if(!ontID.isAnonymous() || !graph.isEmpty()) { graph.addTriple(new RDFTriple(ontologyHeaderNode, new RDFResourceIRI(RDF_TYPE.getIRI()), new RDFResourceIRI(OWL_ONTOLOGY.getIRI()))); } if (!graph.isEmpty()) { render(ontologyHeaderNode); } } private RDFResource createOntologyHeaderNode() { OWLOntologyID ontID = ontology.getOntologyID(); if(ontID.isAnonymous()) { return new RDFResourceBlankNode(System.identityHashCode(ontology)); } else { return new RDFResourceIRI(ontID.getOntologyIRI()); } } private void addVersionIRIToOntologyHeader(RDFResource ontologyHeaderNode) { OWLOntologyID ontID = ontology.getOntologyID(); if (ontID.getVersionIRI() != null) { graph.addTriple(new RDFTriple(ontologyHeaderNode, new RDFResourceIRI(OWL_VERSION_IRI.getIRI()), new RDFResourceIRI(ontID.getVersionIRI()))); } } private void addImportsDeclarationsToOntologyHeader(RDFResource ontologyHeaderNode) { for (OWLImportsDeclaration decl : ontology.getImportsDeclarations()) { graph.addTriple(new RDFTriple(ontologyHeaderNode, new RDFResourceIRI(OWL_IMPORTS.getIRI()), new RDFResourceIRI(decl.getIRI()))); } } private void addAnnotationsToOntologyHeader(RDFResource ontologyHeaderNode) { for (OWLAnnotation anno : ontology.getAnnotations()) { OWLAnnotationValueVisitorEx valVisitor = new OWLAnnotationValueVisitorEx() { @Override public RDFNode visit(IRI iri) { return new RDFResourceIRI(iri); } @Override public RDFNode visit(OWLAnonymousIndividual individual) { return new RDFResourceBlankNode(System.identityHashCode(individual)); } @Override public RDFNode visit(OWLLiteral literal) { return RDFTranslator.translateLiteralNode(literal); } }; RDFNode node = anno.getValue().accept(valVisitor); graph.addTriple(new RDFTriple(ontologyHeaderNode, new RDFResourceIRI(anno.getProperty().getIRI()), node)); } } private boolean createGraph(OWLEntity entity) { final Set axioms = new HashSet(); // Don't write out duplicates for punned annotations! if (!isIndividualAndClass(entity)) { axioms.addAll(entity.getAnnotationAssertionAxioms(ontology)); } axioms.addAll(ontology.getDeclarationAxioms(entity)); entity.accept(new OWLEntityVisitor() { @Override public void visit(OWLClass cls) { for (OWLAxiom ax : ontology.getAxioms(cls)) { if (ax instanceof OWLDisjointClassesAxiom) { OWLDisjointClassesAxiom disjAx = (OWLDisjointClassesAxiom) ax; if (disjAx.getClassExpressions().size() > 2) { continue; } } axioms.add(ax); } for (OWLHasKeyAxiom ax : ontology.getAxioms(AxiomType.HAS_KEY)) { if (ax.getClassExpression().equals(cls)) { axioms.add(ax); } } } @Override public void visit(OWLDatatype datatype) { axioms.addAll(ontology.getDatatypeDefinitions(datatype)); createGraph(axioms); } @Override public void visit(OWLNamedIndividual individual) { for (OWLAxiom ax : ontology.getAxioms(individual)) { if (ax instanceof OWLDifferentIndividualsAxiom) { continue; } axioms.add(ax); } } @Override public void visit(OWLDataProperty property) { for (OWLAxiom ax : ontology.getAxioms(property)) { if (ax instanceof OWLDisjointDataPropertiesAxiom) { if (((OWLDisjointDataPropertiesAxiom) ax).getProperties().size() > 2) { continue; } } axioms.add(ax); } } @Override public void visit(OWLObjectProperty property) { for (OWLAxiom ax : ontology.getAxioms(property)) { if (ax instanceof OWLDisjointObjectPropertiesAxiom) { if (((OWLDisjointObjectPropertiesAxiom) ax).getProperties().size() > 2) { continue; } } axioms.add(ax); } for (OWLSubPropertyChainOfAxiom ax : ontology.getAxioms(AxiomType.SUB_PROPERTY_CHAIN_OF)) { if (ax.getSuperProperty().equals(property)) { axioms.add(ax); } } axioms.addAll(ontology.getAxioms(ontology.getOWLOntologyManager() .getOWLDataFactory().getOWLObjectInverseOf(property))); } @Override public void visit(OWLAnnotationProperty property) { axioms.addAll(ontology.getAxioms(property)); } }); if (axioms.isEmpty() && shouldInsertDeclarations()) { if (RDFOntologyFormat.isMissingType(entity, ontology)) { axioms.add(ontology.getOWLOntologyManager().getOWLDataFactory().getOWLDeclarationAxiom(entity)); } } createGraph(axioms); return !axioms.isEmpty(); } private boolean isIndividualAndClass(OWLEntity entity) { return entity.isOWLNamedIndividual() && ontology.containsClassInSignature(entity.getIRI()); } protected boolean shouldInsertDeclarations() { return !(format instanceof RDFOntologyFormat) || ((RDFOntologyFormat) format).isAddMissingTypes(); } protected void createGraph(Set objects) { RDFTranslator translator = new RDFTranslator(ontology.getOWLOntologyManager(), ontology, shouldInsertDeclarations()); for (OWLObject obj : objects) { obj.accept(translator); } graph = translator.getGraph(); } protected abstract void writeBanner(String name) throws IOException; private static Set toSortedSet(Set entities) { Set results = new TreeSet(new OWLEntityIRIComparator()); results.addAll(entities); return results; } public void renderAnonRoots() throws IOException { for (RDFResourceBlankNode node : graph.getRootAnonymousNodes()) { render(node); } } /** * Renders the triples in the current graph into a concrete format. Subclasses of this class decide upon * how the triples get rendered. * @param node The main node to be rendered * @throws IOException If there was a problem rendering the triples. */ public abstract void render(RDFResource node) throws IOException; protected boolean isObjectList(RDFResource node) { for (RDFTriple triple : graph.getSortedTriplesForSubject(node, false)) { if (triple.getProperty().getIRI().equals(RDF_TYPE.getIRI())) { if (!triple.getObject().isAnonymous()) { if (triple.getObject().getIRI().equals(RDF_LIST.getIRI())) { List items = new ArrayList(); toJavaList(node, items); for (RDFNode n : items) { if (n.isLiteral()) { return false; } } return true; } } } } return false; } protected void toJavaList(RDFNode n, List list) { RDFNode currentNode = n; while (currentNode != null) { for (RDFTriple triple : graph.getSortedTriplesForSubject(currentNode, false)) { if (triple.getProperty().getIRI().equals(RDF_FIRST.getIRI())) { list.add(triple.getObject()); } } for (RDFTriple triple : graph.getSortedTriplesForSubject(currentNode, false)) { if (triple.getProperty().getIRI().equals(RDF_REST.getIRI())) { if (!triple.getObject().isAnonymous()) { if (triple.getObject().getIRI().equals(RDF_NIL.getIRI())) { // End of list currentNode = null; } } else { if(triple.getObject() instanceof RDFResource) { // Should be another list currentNode = (RDFResource)triple.getObject(); // toJavaList(triple.getObject(), list); } } } } } } /** * Comparator that uses IRI ordering to order entities. * XXX stateless, might be used through a singleton */ private static final class OWLEntityIRIComparator implements Comparator, Serializable { private static final long serialVersionUID = 30402L; public OWLEntityIRIComparator() {} @Override public int compare(OWLEntity o1, OWLEntity o2) { return o1.getIRI().compareTo(o2.getIRI()); } } public static class TripleComparator implements Comparator, Serializable { private static final long serialVersionUID = 30402L; private static final List orderedURIs = Arrays.asList(RDF_TYPE.getIRI(), RDFS_LABEL.getIRI(), OWL_EQUIVALENT_CLASS.getIRI(), RDFS_SUBCLASS_OF.getIRI(), OWL_DISJOINT_WITH.getIRI(), OWL_ON_PROPERTY.getIRI(), OWL_DATA_RANGE.getIRI(), OWL_ON_CLASS.getIRI()); public TripleComparator() { } private int getIndex(IRI iri) { int index = orderedURIs.indexOf(iri); if (index == -1) { index = orderedURIs.size(); } return index; } @Override public int compare(RDFTriple o1, RDFTriple o2) { int diff = getIndex(o1.getProperty().getIRI()) - getIndex(o2.getProperty().getIRI()); if (diff == 0) { // Compare by subject, then predicate, then object if (!o1.getSubject().isAnonymous()) { if (!o2.getSubject().isAnonymous()) { diff = o1.getSubject().getIRI().compareTo(o2.getSubject().getIRI()); } else { diff = -1; } } else { if (!o2.getSubject().isAnonymous()) { diff = 1; } else { diff = 0; } } if (diff == 0) { diff = o2.getProperty().getIRI().compareTo(o2.getProperty().getIRI()); if (diff == 0) { if (!o1.getObject().isLiteral()) { // Resource if (!o2.getObject().isLiteral()) { // Resource if (!o1.getObject().isAnonymous()) { if (!o2.getObject().isAnonymous()) { diff = o1.getObject().getIRI().compareTo(o2.getObject().getIRI()); } else { diff = -1; } } else { if (!o2.getObject().isAnonymous()) { diff = 1; } else { diff = -1; } } } else { // Literal // Literals first? diff = 1; } } else { // Literal if (!o2.getObject().isLiteral()) { // Resource diff = -1; } else { // Literal RDFLiteral lit1 = (RDFLiteral) o1.getObject(); RDFLiteral lit2 = (RDFLiteral) o2.getObject(); if (lit1.isTyped()) { if (lit2.isTyped()) { diff = lit1.getLiteral().compareTo(lit2.getLiteral()); if (diff == 0) { diff = lit1.getDatatype().compareTo(lit2.getDatatype()); } } else { diff = -1; } } else { if (lit2.isTyped()) { diff = 1; } else { if (lit1.getLang() != null) { if (lit2.getLang() != null) { diff = lit1.getLang().compareTo(lit2.getLang()); } } else { diff = -1; } if (diff == 0) { diff = lit1.getLiteral().compareTo(lit2.getLiteral()); } } } } } } } } if (diff == 0) { diff = 1; } return diff; } } public static final TripleComparator tripleComparator = new TripleComparator(); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy