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    }