001/**
002 * Copyright (C) 2007 - 2016, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019/***************************************************************************/
020/*  Copyright (C) 2010-2011, Sebastian Hellmann                            */
021/*  Note: If you need parts of NLP2RDF in another licence due to licence   */
022/*  incompatibility, please mail hellmann@informatik.uni-leipzig.de        */
023/*                                                                         */
024/*  This file is part of NLP2RDF.                                          */
025/*                                                                         */
026/*  NLP2RDF is free software; you can redistribute it and/or modify        */
027/*  it under the terms of the GNU General Public License as published by   */
028/*  the Free Software Foundation; either version 3 of the License, or      */
029/*  (at your option) any later version.                                    */
030/*                                                                         */
031/*  NLP2RDF is distributed in the hope that it will be useful,             */
032/*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
033/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the           */
034/*  GNU General Public License for more details.                           */
035/*                                                                         */
036/*  You should have received a copy of the GNU General Public License      */
037/*  along with this program. If not, see <http://www.gnu.org/licenses/>.   */
038/***************************************************************************/
039
040package org.dllearner.kb.sparql.simple;
041
042import java.util.ArrayList;
043import java.util.HashMap;
044import java.util.HashSet;
045import java.util.List;
046import java.util.Map;
047import java.util.Set;
048
049import org.slf4j.Logger;
050import org.slf4j.LoggerFactory;
051
052import org.apache.jena.ontology.OntClass;
053import org.apache.jena.ontology.OntModel;
054import org.apache.jena.ontology.OntModelSpec;
055import org.apache.jena.rdf.model.ModelFactory;
056import org.apache.jena.util.iterator.ExtendedIterator;
057import com.jamonapi.Monitor;
058import com.jamonapi.MonitorFactory;
059
060/**
061 * Indexes an Ontology
062 * skips complex classes per default, this does not affect the hierarchy outcome
063 */
064public class ClassIndexer {
065    private static Logger log = LoggerFactory.getLogger(ClassIndexer.class);
066
067    //Options
068    private boolean copyLabels = true;
069    private boolean copyComments = true;
070    private String language = null;
071
072    //Not implemented
073    private Map<String, String> transform = new HashMap<>();
074    //Not implemented
075    private Set<String> remove = new HashSet<>();
076
077    //internal variables
078    private Map<String, OntModel> classUriToClassHierarchy = new HashMap<>();
079
080    public ClassIndexer() {
081    }
082
083    public void index(OntModel from) {
084
085       // Set<OntClass> classes = from.listClasses();
086        int i = 0;
087        OntClass cl;
088        for (ExtendedIterator<OntClass> it = from.listClasses(); it.hasNext(); ) {
089            Monitor m0 = MonitorFactory.start("Indexer listClasses");
090            cl = it.next();
091            m0.stop();
092            //for (OntClass cl : classes) {
093            Monitor m1 = MonitorFactory.start("Indexer generating tree");
094            Tree t = new Tree(cl);
095            m1.stop();
096            Monitor m2 = MonitorFactory.start("Indexer generating model");
097            OntModel m = t.toModel();
098            m2.stop();
099            Monitor m3 = MonitorFactory.start("Indexer generating hashmap");
100            classUriToClassHierarchy.put(cl.getURI(), m);
101            m3.stop();
102        }
103
104    }
105
106    /**
107     * @param classUri
108     * @return a filled OntModel with all superclasses of classUri or null, if no class is found
109     */
110    public OntModel getHierarchyForClassURI(String classUri) {
111        return classUriToClassHierarchy.get(classUri);
112    }
113
114    /**
115     * transforms namespaces
116     *
117     * @param in
118     * @return
119     */
120    private String transformNamespace(String in) {
121        String ret = in;
122        for (String s : transform.keySet()) {
123            if (in.startsWith(s)) {
124                return in.replace(s, transform.get(s));
125
126            }
127        }
128        return ret;
129    }
130
131    /**
132     * filters out certain namespaces
133     *
134     * @param s
135     * @return
136     */
137    private boolean filterNamespace(String s) {
138        for (String prefix : remove) {
139            if (s.startsWith(prefix)) {
140                return true;
141            }
142        }
143        return false;
144    }
145
146    public boolean isCopyLabels() {
147        return copyLabels;
148    }
149
150    public void setCopyLabels(boolean copyLabels) {
151        this.copyLabels = copyLabels;
152    }
153
154    public boolean isCopyComments() {
155        return copyComments;
156    }
157
158    public void setCopyComments(boolean copyComments) {
159        this.copyComments = copyComments;
160    }
161
162    public String getLanguage() {
163        return language;
164    }
165
166    public void setLanguage(String language) {
167        this.language = language;
168    }
169
170    /**
171     * A simple Helper Class to convert the hierarchy
172     */
173    private class Tree {
174        final String uri;
175        List<Tree> parents;
176        final String label;
177        final String comment;
178
179        public Tree(OntClass me) {
180            this.uri = me.getURI();
181            label = me.getLabel(language);
182            comment = me.getComment(language);
183            parents = new ArrayList<>();
184
185            Set<OntClass> superClasses = me.listSuperClasses(true).toSet();
186            for (OntClass s : superClasses) {
187                //this is were complex classes are skipped
188                if (s.isAnon()) {
189                    continue;
190                }
191                log.trace(s.toString());
192                parents.add(new Tree(s));
193            }
194        }
195
196        public OntModel toModel() {
197            OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM, ModelFactory.createDefaultModel());
198            OntClass me = model.createClass(uri);
199            //TODO test this for <&>
200            if (copyLabels && label != null) {
201                me.addLabel(label, language);
202            }
203            if (copyComments && comment != null) {
204                me.addComment(comment, language);
205            }
206            for (Tree p : parents) {
207                OntClass superClass = model.createClass(p.uri);
208                me.addSuperClass(superClass);
209                model.add(p.toModel());
210            }
211            return model;
212        }
213    }
214
215}
216
217/**
218 public void expandSuperAndCopy(String originalClassUri) {
219
220 String newClassUri = transform(originalClassUri);
221 if (isRemove(originalClassUri) || isRemove(newClassUri)) {
222 return;
223 }
224
225 // create initial classes
226 OntClass toClass = toModel.createClass(newClassUri);
227 OntClass fromClass = fromModel.getOntClass(originalClassUri);
228
229 if(toClass==null || fromClass == null){
230 logger.error("null occured in fromClass "+originalClassUri+" but retrieving yielded: "+fromClass );
231 return;
232 }
233
234 //System.out.println("begin");
235 //for(OntClass cltest: fromModel.listClasses().toSet()){
236 //  System.out.println(cltest.getURI());
237 // System.out.println(cltest.getClass().getSimpleName());
238 //}
239 //System.out.println("end");
240
241 if (copyLabelsAndComments ) {
242 String tmp = null;
243
244 if((tmp=fromClass.getLabel(null))!=null) {toClass.setLabel(tmp, null);}
245 //                     System.out.println(fromClass.getURI()+"has label "+tmp);
246
247 if((tmp=fromClass.getComment(null))!=null) {toClass.setComment(tmp, null);}
248 //                     System.out.println(fromClass.getURI()+"has comment "+tmp);
249 }
250
251 // get the superclasses
252 Set<OntClass> fromSuperclasses = fromClass.listSuperClasses(true).toSet();
253
254 for (OntClass fromSuperclass : fromSuperclasses) {
255 String newFromSuperclassUri = transform(fromSuperclass.getURI());
256 if (isRemove(fromSuperclass.getURI()) || isRemove(newFromSuperclassUri)) {
257 continue;
258 }
259 if(fromSuperclass.isAnon()){
260 continue;
261 }
262
263 OntClass toSuperclass = toModel.createClass(newFromSuperclassUri);
264 toClass.addSuperClass(toSuperclass);
265
266 if (copyLabelsAndComments) {
267 String tmp = null;
268 if((tmp=fromSuperclass.getLabel(null))!=null) {toSuperclass.setLabel(tmp, null);}
269 //                             System.out.println(fromSuperclass.getURI()+"has label "+tmp);
270
271 if((tmp=fromSuperclass.getComment(null))!=null) {toSuperclass.setComment(tmp, null);}
272 //                             System.out.println(fromSuperclass.getURI()+"has comment "+tmp);
273 }
274 // System.out.println(fromSuperclass);
275 expandSuperAndCopy(fromSuperclass.getURI());
276 }
277
278 }     **/