/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory
This file is part of HermiT.
HermiT is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
HermiT 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with HermiT. If not, see <http://www.gnu.org/licenses/>.
*/
package org.semanticweb.HermiT.hierarchy;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.semanticweb.HermiT.Prefixes;
import org.semanticweb.HermiT.model.AtomicConcept;
import org.semanticweb.HermiT.model.AtomicRole;
import org.semanticweb.HermiT.model.InverseRole;
import org.semanticweb.HermiT.model.Role;
public class HierarchyPrinterFSS {
protected final PrintWriter m_out;
protected final String m_defaultPrefixIRI;
protected final Set<String> m_prefixIRIs;
protected Prefixes m_prefixes;
public HierarchyPrinterFSS(PrintWriter out,String defaultPrefixIRI) {
m_out=out;
m_defaultPrefixIRI=defaultPrefixIRI;
m_prefixIRIs=new TreeSet<String>();
m_prefixIRIs.add(defaultPrefixIRI);
m_prefixIRIs.add(Prefixes.s_semanticWebPrefixes.get("owl:"));
}
public void loadAtomicConceptPrefixIRIs(Collection<AtomicConcept> atomicConcepts) {
for (AtomicConcept atomicConcept : atomicConcepts) {
String uri=atomicConcept.getIRI();
int hashIndex=uri.indexOf('#');
if (hashIndex!=-1) {
String prefixIRI=uri.substring(0,hashIndex+1);
String localName=uri.substring(hashIndex+1);
if (Prefixes.isValidLocalName(localName))
m_prefixIRIs.add(prefixIRI);
}
}
}
public void loadAtomicRolePrefixIRIs(Collection<AtomicRole> atomicRoles) {
for (AtomicRole atomicRole : atomicRoles) {
String uri=atomicRole.getIRI();
int hashIndex=uri.indexOf('#');
if (hashIndex!=-1) {
String prefixIRI=uri.substring(0,hashIndex+1);
String localName=uri.substring(hashIndex+1);
if (Prefixes.isValidLocalName(localName))
m_prefixIRIs.add(prefixIRI);
}
}
}
public void startPrinting() {
String owlPrefixIRI=Prefixes.s_semanticWebPrefixes.get("owl:");
m_prefixes=new Prefixes();
m_prefixes.declareDefaultPrefix(m_defaultPrefixIRI);
m_prefixes.declarePrefix("owl:",owlPrefixIRI);
int index=1;
for (String prefixIRI : m_prefixIRIs)
if (!m_defaultPrefixIRI.equals(prefixIRI) && !owlPrefixIRI.equals(prefixIRI)) {
String prefixName="a"+(index++)+":";
m_prefixes.declarePrefix(prefixName,prefixIRI);
}
for (Map.Entry<String,String> entry : m_prefixes.getPrefixIRIsByPrefixName().entrySet())
if (!"owl:".equals(entry.getKey()))
m_out.println("Prefix("+entry.getKey()+"=<"+entry.getValue()+">)");
m_out.println();
m_out.println("Ontology(<"+m_prefixes.getPrefixIRIsByPrefixName().get(":")+">");
m_out.println();
}
public void printAtomicConceptHierarchy(Hierarchy<AtomicConcept> atomicConceptHierarchy) {
Hierarchy<AtomicConcept> sortedAtomicConceptHierarchy=atomicConceptHierarchy.transform(new IdentityTransformer<AtomicConcept>(),AtomicConceptComparator.INSTANCE);
AtomicConceptPrinter atomicConceptPrinter=new AtomicConceptPrinter(sortedAtomicConceptHierarchy.getBottomNode());
sortedAtomicConceptHierarchy.traverseDepthFirst(atomicConceptPrinter);
atomicConceptPrinter.printNode(0,sortedAtomicConceptHierarchy.getBottomNode(),null,true);
}
public void printRoleHierarchy(Hierarchy<? extends Role> roleHierarchy,boolean objectProperties) {
Hierarchy<Role> sortedRoleHierarchy=roleHierarchy.transform(new IdentityTransformer<Role>(),RoleComparator.INSTANCE);
RolePrinter rolePrinter=new RolePrinter(sortedRoleHierarchy,objectProperties);
sortedRoleHierarchy.traverseDepthFirst(rolePrinter);
rolePrinter.printNode(0,sortedRoleHierarchy.getBottomNode(),null,true);
}
public void endPrinting() {
m_out.println();
m_out.println(")");
m_out.flush();
}
protected class AtomicConceptPrinter implements Hierarchy.HierarchyNodeVisitor<AtomicConcept> {
protected final HierarchyNode<AtomicConcept> m_bottomNode;
public AtomicConceptPrinter(HierarchyNode<AtomicConcept> bottomNode) {
m_bottomNode=bottomNode;
}
public boolean redirect(HierarchyNode<AtomicConcept>[] nodes) {
return true;
}
public void visit(int level,HierarchyNode<AtomicConcept> node,HierarchyNode<AtomicConcept> parentNode,boolean firstVisit) {
if (!node.equals(m_bottomNode))
printNode(level,node,parentNode,firstVisit);
}
public void printNode(int level,HierarchyNode<AtomicConcept> node,HierarchyNode<AtomicConcept> parentNode,boolean firstVisit) {
Set<AtomicConcept> equivalences=node.getEquivalentElements();
boolean printSubClasOf=(parentNode!=null);
boolean printEquivalences=firstVisit && equivalences.size()>1;
boolean printDeclarations=false;
if (firstVisit)
for (AtomicConcept atomicConcept : equivalences)
if (needsDeclaration(atomicConcept)) {
printDeclarations=true;
break;
}
if (printSubClasOf || printEquivalences || printDeclarations) {
for (int i=2*level;i>0;--i)
m_out.print(' ');
boolean afterWS=true;
if (printSubClasOf) {
m_out.print("SubClassOf( ");
print(node.getRepresentative());
m_out.print(' ');
print(parentNode.getRepresentative());
m_out.print(" )");
afterWS=false;
}
if (printEquivalences) {
if (!afterWS)
m_out.print(' ');
m_out.print("EquivalentClasses(");
for (AtomicConcept atomicConcept : equivalences) {
m_out.print(' ');
print(atomicConcept);
}
m_out.print(" )");
afterWS=false;
}
if (printDeclarations)
for (AtomicConcept atomicConcept : equivalences)
if (needsDeclaration(atomicConcept)) {
if (!afterWS)
m_out.print(' ');
m_out.print("Declaration( Class( ");
print(atomicConcept);
m_out.print(" ) )");
afterWS=false;
}
m_out.println();
}
}
protected void print(AtomicConcept atomicConcept) {
m_out.print(m_prefixes.abbreviateIRI(atomicConcept.getIRI()));
}
protected boolean needsDeclaration(AtomicConcept atomicConcept) {
return !AtomicConcept.NOTHING.equals(atomicConcept) && !AtomicConcept.THING.equals(atomicConcept);
}
}
protected class RolePrinter implements Hierarchy.HierarchyNodeVisitor<Role> {
protected final Hierarchy<Role> m_hierarchy;
protected final boolean m_objectProperties;
public RolePrinter(Hierarchy<Role> hierarchy,boolean objectProperties) {
m_hierarchy=hierarchy;
m_objectProperties=objectProperties;
}
public boolean redirect(HierarchyNode<Role>[] nodes) {
return true;
}
public void visit(int level,HierarchyNode<Role> node,HierarchyNode<Role> parentNode,boolean firstVisit) {
if (!node.equals(m_hierarchy.getBottomNode()))
printNode(level,node,parentNode,firstVisit);
}
public void printNode(int level,HierarchyNode<Role> node,HierarchyNode<Role> parentNode,boolean firstVisit) {
Set<Role> equivalences=node.getEquivalentElements();
boolean printSubPropertyOf=(parentNode!=null);
boolean printEquivalences=firstVisit && equivalences.size()>1;
boolean printDeclarations=false;
if (firstVisit)
for (Role role : equivalences)
if (needsDeclaration(role)) {
printDeclarations=true;
break;
}
if (printSubPropertyOf || printEquivalences || printDeclarations) {
for (int i=2*level;i>0;--i)
m_out.print(' ');
boolean afterWS=true;
if (printSubPropertyOf) {
if (m_objectProperties)
m_out.print("SubObjectPropertyOf( ");
else
m_out.print("SubDataPropertyOf( ");
print(node.getRepresentative());
m_out.print(' ');
print(parentNode.getRepresentative());
m_out.print(" )");
afterWS=false;
}
if (printEquivalences) {
if (!afterWS)
m_out.print(' ');
if (m_objectProperties)
m_out.print("EquivalentObjectProperties(");
else
m_out.print("EquivalentDataProperties(");
for (Role role : equivalences) {
m_out.print(' ');
print(role);
}
m_out.print(" )");
afterWS=false;
}
if (printDeclarations)
for (Role role : equivalences)
if (needsDeclaration(role)) {
if (!afterWS)
m_out.print(' ');
m_out.print("Declaration( ");
if (m_objectProperties)
m_out.print("ObjectProperty( ");
else
m_out.print("DataProperty( ");
print(role);
m_out.print(" ) )");
afterWS=false;
}
m_out.println();
}
}
protected void print(Role role) {
if (role instanceof AtomicRole)
m_out.print(m_prefixes.abbreviateIRI(((AtomicRole)role).getIRI()));
else {
m_out.print("ObjectInverseOf( ");
print(((InverseRole)role).getInverseOf());
m_out.print(" )");
}
}
protected void print(AtomicRole atomicRole) {
m_out.print(m_prefixes.abbreviateIRI(atomicRole.getIRI()));
}
protected boolean needsDeclaration(Role role) {
return !AtomicRole.BOTTOM_OBJECT_ROLE.equals(role) && !AtomicRole.TOP_OBJECT_ROLE.equals(role) && !AtomicRole.BOTTOM_DATA_ROLE.equals(role) && !AtomicRole.TOP_DATA_ROLE.equals(role) && role instanceof AtomicRole;
}
}
protected static class RoleComparator implements Comparator<Role> {
public static final RoleComparator INSTANCE=new RoleComparator();
public int compare(Role role1,Role role2) {
int comparison=getRoleClass(role1)-getRoleClass(role2);
if (comparison!=0)
return comparison;
comparison=getRoleDirection(role1)-getRoleDirection(role2);
if (comparison!=0)
return comparison;
return getInnerAtomicRole(role1).getIRI().compareTo(getInnerAtomicRole(role2).getIRI());
}
protected int getRoleClass(Role role) {
if (AtomicRole.BOTTOM_OBJECT_ROLE.equals(role))
return 0;
else if (AtomicRole.TOP_OBJECT_ROLE.equals(role))
return 1;
else if (AtomicRole.BOTTOM_DATA_ROLE.equals(role))
return 2;
else if (AtomicRole.TOP_DATA_ROLE.equals(role))
return 3;
else
return 4;
}
protected AtomicRole getInnerAtomicRole(Role role) {
if (role instanceof AtomicRole)
return (AtomicRole)role;
else
return ((InverseRole)role).getInverseOf();
}
protected int getRoleDirection(Role role) {
return role instanceof AtomicRole ? 0 : 1;
}
}
protected static class AtomicConceptComparator implements Comparator<AtomicConcept> {
public static final AtomicConceptComparator INSTANCE=new AtomicConceptComparator();
public int compare(AtomicConcept atomicConcept1,AtomicConcept atomicConcept2) {
int comparison=getAtomicConceptClass(atomicConcept1)-getAtomicConceptClass(atomicConcept2);
if (comparison!=0)
return comparison;
return atomicConcept1.getIRI().compareTo(atomicConcept2.getIRI());
}
protected int getAtomicConceptClass(AtomicConcept atomicConcept) {
if (AtomicConcept.NOTHING.equals(atomicConcept))
return 0;
else if (AtomicConcept.THING.equals(atomicConcept))
return 1;
else
return 2;
}
}
protected class IdentityTransformer<E> implements Hierarchy.Transformer<E,E> {
public E transform(E object) {
return object;
}
public E determineRepresentative(E oldRepresentative,Set<E> newEquivalentElements) {
return ((SortedSet<E>)newEquivalentElements).first();
}
}
}