001 package nl.tudelft.tbm.eeni.owlstructure.utils;
002
003 import com.hp.hpl.jena.ontology.OntClass;
004 import com.hp.hpl.jena.ontology.OntModel;
005 import com.hp.hpl.jena.ontology.OntModelSpec;
006 import com.hp.hpl.jena.rdf.model.ModelFactory;
007 import com.hp.hpl.jena.rdf.model.RDFWriter;
008 import com.hp.hpl.jena.util.FileManager;
009 import com.hp.hpl.jena.util.iterator.ClosableIterator;
010
011 import java.io.FileOutputStream;
012 import java.util.ArrayList;
013 import java.util.Collection;
014 import java.util.Iterator;
015 import java.util.Map;
016
017 public final class OntologyUtils {
018 /**
019 * Closes an iterator if it has interface ClosableIterator. This is useful
020 * to avoid open iterator warnings when we're not interested in all results
021 * of a sparql query.
022 */
023 public static void closeIterator(Iterator<?> iterator) {
024 while (iterator.hasNext()) {
025 iterator.next();
026 }
027 }
028
029 /**
030 * Check whether a list of candidate classes contains a partial superset of
031 * a given class In inheritance chains where each class extends at most one
032 * other class, this basically checks whether there is an (indirect)
033 * ancestor of the class in the candidates list. When multiple inheritance
034 * is allowed, this is recursively checked for any of the inheritance
035 * branches. Also returns false if a class has no superclass at all.
036 */
037 public static boolean containsClassSuperset(OntClass ontClass, Collection<OntClass> candidates) {
038 ClosableIterator<OntClass> superClassIterator = ontClass.listSuperClasses();
039 while (superClassIterator.hasNext()) {
040 OntClass superClass = superClassIterator.next();
041 if (candidates.contains(superClass) || containsClassSuperset(superClass, candidates)) {
042 // We've found an ancestor
043 superClassIterator.close();
044 return true;
045 }
046 }
047 // We've found no ancestors
048 return false;
049 }
050
051 /**
052 * Check whether a list of candidate classes contains a defining superset of
053 * a given class In inheritance chains where each class extends at most one
054 * other class, this basically checks whether there is an (indirect)
055 * ancestor of the class in the candidates list. When multiple inheritance
056 * is allowed, this is recursively checked for all inheritance branches.
057 * Also returns false if a class has no superclass at all.
058 */
059 public static boolean containsCompleteClassSuperset(OntClass ontClass, Collection<OntClass> candidates) {
060 ClosableIterator<OntClass> superClassIterator = ontClass.listSuperClasses();
061 if (!superClassIterator.hasNext()) {
062 // There are no ancestors
063 return false;
064 }
065 while (superClassIterator.hasNext()) {
066 OntClass superClass = superClassIterator.next();
067 if (!candidates.contains(superClass) && !containsCompleteClassSuperset(superClass, candidates)) {
068 // We've found an unlisted ancestor
069 superClassIterator.close();
070 return false;
071 }
072 }
073 // We've found no unlisted ancestors
074 return true;
075 }
076
077 /**
078 * This convenience function fetches all namespaces that are currently part
079 * of the ontology model and known to Jena and dumps them as a sparql prefix
080 * list
081 */
082 public static String getSparqlPrefixes(OntModel ontModel) {
083 String sparqlPrefixes = "";
084
085 Map<String, String> prefixMap = ontModel.getNsPrefixMap();
086 Iterator<Map.Entry<String, String>> prefixIterator = prefixMap.entrySet().iterator();
087 while (prefixIterator.hasNext()) {
088 Map.Entry<String, String> prefixPair = prefixIterator.next();
089 sparqlPrefixes += "PREFIX " + prefixPair.getKey() + ": <" + prefixPair.getValue() + ">\n";
090 }
091
092 return sparqlPrefixes;
093 }
094
095 /**
096 * Returns the OntClass instance of owl:Thing
097 */
098 public static OntClass getOwlThing(OntModel ontModel) {
099 return ontModel.createClass("http://www.w3.org/2002/07/owl#Thing");
100 }
101
102 /**
103 * List all (indirect) parents of an ontology class That is, list its
104 * parent, its parent's parent, etc.
105 */
106 public static Collection<OntClass> listClassAncestors(OntClass ontClass) {
107 Collection<OntClass> ancestors = new ArrayList<OntClass>();
108 Iterator<OntClass> superClassIterator = ontClass.listSuperClasses();
109 while (superClassIterator.hasNext()) {
110 OntClass superClass = superClassIterator.next();
111 ancestors.add(superClass);
112 ancestors.addAll(listClassAncestors(superClass));
113 }
114 return ancestors;
115 }
116
117 /**
118 * List all (indirect) descendants of an ontology class That is, list its
119 * children, its children's children, etc.
120 */
121 public static Collection<OntClass> listClassDescendants(OntClass ontClass) {
122 Collection<OntClass> descendants = new ArrayList<OntClass>();
123 Iterator<OntClass> subClassIterator = ontClass.listSubClasses();
124 while (subClassIterator.hasNext()) {
125 OntClass subClass = subClassIterator.next();
126 descendants.add(subClass);
127 descendants.addAll(listClassDescendants(subClass));
128 }
129 return descendants;
130 }
131
132 public static OntModel createOntology() {
133 try {
134 return ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM);
135 } catch (Exception e) {
136 throw new RuntimeException(e);
137 }
138 }
139
140 public static OntModel loadOntology(String path) {
141 try {
142 OntModel ontModel = OntologyUtils.createOntology();
143
144 // use the FileManager to find the input file and read it in
145 FileManager fm = FileManager.get();
146 fm.addLocatorURL();
147 fm.readModel(ontModel, path);
148
149 return ontModel;
150 } catch (Exception e) {
151 throw new RuntimeException(e);
152 }
153 }
154
155 public static void saveOntologyRdf(OntModel ontModel, String path) {
156 // Open output stream
157 try {
158 // Create a rdf writer
159 RDFWriter writer = ontModel.getWriter("RDF/XML-ABBREV");
160 writer.setProperty("showXmlDeclaration", "true");
161 writer.setProperty("showDoctypeDeclaration", "true");
162
163 // Create an output stream
164 FileOutputStream stream = new FileOutputStream(path);
165
166 // Write to the file
167 writer.write(ontModel, stream, ontModel.getNsPrefixURI(""));
168
169 // Close the out stream
170 stream.close();
171 } catch (Exception e) {
172 throw new RuntimeException(e);
173 }
174 }
175 }