001 /**
002 * Copyright (C) 2007-2011, 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 package org.dllearner.kb.aquisitors;
021
022 import java.util.ArrayList;
023 import java.util.HashMap;
024 import java.util.List;
025 import java.util.Map;
026 import java.util.SortedSet;
027
028 import org.apache.log4j.Logger;
029 import org.dllearner.kb.sparql.SPARQLTasks;
030 import org.dllearner.kb.sparql.SparqlQueryMaker;
031 import org.dllearner.utilities.JamonMonitorLogger;
032 import org.dllearner.utilities.datastructures.RDFNodeTuple;
033 import org.dllearner.utilities.owl.OWLVocabulary;
034
035 import com.hp.hpl.jena.query.QuerySolution;
036 import com.hp.hpl.jena.query.ResultSetRewindable;
037 import com.hp.hpl.jena.rdf.model.RDFNode;
038 import com.jamonapi.Monitor;
039
040 /**
041 * Can execute different queries.
042 *
043 * @author Sebastian Hellmann
044 *
045 */
046 public class SparqlTupleAquisitor extends TupleAquisitor {
047
048
049 private static Logger logger = Logger.getLogger(SparqlTupleAquisitor.class);
050 protected static final String PREDICATE = "predicate";
051 protected static final String OBJECT = "object";
052
053 protected SparqlQueryMaker sparqlQueryMaker;
054 protected SPARQLTasks sparqlTasks;
055
056
057
058
059
060 public SparqlTupleAquisitor(SparqlQueryMaker sparqlQueryMaker, SPARQLTasks sparqlTasks) {
061
062 this.sparqlQueryMaker = sparqlQueryMaker;
063 this.sparqlTasks = sparqlTasks;
064 }
065
066 @Override
067 public SortedSet<RDFNodeTuple> retrieveTupel(String uri){
068 // getQuery
069 String sparqlQueryString = sparqlQueryMaker.makeSubjectQueryUsingFilters(uri);
070 SortedSet<RDFNodeTuple> ret = sparqlTasks.queryAsRDFNodeTuple(sparqlQueryString, PREDICATE, OBJECT);
071 disambiguateBlankNodes(uri, ret);
072
073 return ret;
074 }
075 @Override
076 public SortedSet<RDFNodeTuple> retrieveClassesForInstances(String uri){
077 // getQuery
078 String sparqlQueryString = sparqlQueryMaker.makeClassQueryUsingFilters(uri);
079 SortedSet<RDFNodeTuple> ret = sparqlTasks.queryAsRDFNodeTuple(sparqlQueryString, PREDICATE, OBJECT);
080 disambiguateBlankNodes(uri, ret);
081 return ret;
082
083 }
084 @Override
085 public SortedSet<RDFNodeTuple> retrieveTuplesForClassesOnly(String uri){
086 SortedSet<RDFNodeTuple> ret = retrieveTupel(uri);
087 //the next line is not necessary
088 //disambiguateBlankNodes(uri, ret);
089 return ret;
090 }
091
092 @Override
093 public SortedSet<RDFNodeTuple> getBlankNode(int id){
094 return BlankNodeCollector.getBlankNode(id);
095 }
096
097 public void printHM(){
098
099 for (int j = 0; j < BlankNodeCollector.getBlankNodeMap().size(); j++) {
100 System.out.println(j);
101 for(RDFNodeTuple t :BlankNodeCollector.getBlankNodeMap().get(j)){
102 System.out.println(t);
103 }
104 }
105
106 }
107
108 // main function for resolving blanknodes
109 @Override
110 protected void disambiguateBlankNodes(String uri, SortedSet<RDFNodeTuple> resultSet){
111 if(!isDissolveBlankNodes()){
112 return;
113 }
114 Monitor bnodeMonitor = JamonMonitorLogger.getTimeMonitor(SparqlTupleAquisitor.class, "blanknode time").start();
115 try{
116 for (RDFNodeTuple tuple : resultSet) {
117
118 if(tuple.b.isAnon()){
119 int currentId = BlankNodeCollector.getNextGlobalBNodeId();
120 // replace the blanknode
121 tuple.b = new RDFBlankNode(currentId, tuple.b);
122 //System.out.println(uri+" replaced blanknode "+tuple.b);
123 dissolveBlankNodes(currentId, uri, tuple);
124 //System.out.println(BlankNodeCollector.getBlankNodeMap());
125
126 }
127 }
128 }catch (Exception e) {
129 e.printStackTrace();
130 System.exit(0);
131 }finally{
132 bnodeMonitor.stop();
133 }
134
135 }
136
137 // extends a sparql query as long as there are undissolved blanknodes
138 private void dissolveBlankNodes(int currentId, String uri, RDFNodeTuple tuple){
139 try{
140 int currentDepth = 1;
141 int lastDepth = 1;
142 ResultSetRewindable rsw=null;
143 do{
144 String p = tuple.a.toString();
145 if(p.equals(OWLVocabulary.RDFS_COMMENT) || p.equals(OWLVocabulary.RDFS_LABEL) ){
146 return ;
147 }
148 String q = BlankNodeCollector.makeQuery(uri, p, currentDepth);
149 // System.out.println(q);
150 rsw = sparqlTasks.queryAsResultSet(q);
151 rsw.reset();
152 lastDepth = currentDepth;
153 }while (!BlankNodeCollector.testResultSet(rsw, currentDepth++));
154
155 assignIds( currentId, rsw, lastDepth);
156 }catch (Exception e) {
157 logger.info("An error occurred while dissolving blanknodes");
158 }
159 }
160
161 //takes the resultset and assigns internal ids
162 private void assignIds(int currentId, ResultSetRewindable rsw, int lastDepth){
163 //prepare variables according to last depth
164 List<String> vars = new ArrayList<String>();
165 vars.add("o0");
166 for (int i = 1; i <= lastDepth; i++) {
167 vars.add("p"+i);
168 vars.add("o"+i);
169 }
170
171 final List<String> tmpVars = new ArrayList<String>();
172
173 Map<String, Integer> lastNodes = new HashMap<String, Integer>();
174 // the resultset first variable is o0
175 // iteration over each tuple of the set
176 while (rsw.hasNext()){
177 tmpVars.clear();
178 tmpVars.addAll(vars);
179 QuerySolution q = rsw.nextSolution();
180
181 //skip all that do not start with a blanknode
182 // could be two different blank nodes here, but unlikely
183 if(!q.get("o0").isAnon()){
184 lastNodes.put(q.get("o0").toString(), currentId);
185 continue;
186 }else{
187
188 // remove the first node
189 tmpVars.remove(0);
190 assignIdRec(currentId, q, tmpVars,lastNodes);
191 }
192
193
194 }
195 rsw.reset();
196
197 }
198
199 private void assignIdRec(int currentId, QuerySolution q, List<String> vars, Map<String, Integer> lastNodes ){
200 if(vars.isEmpty()){return;}
201 String pvar = vars.remove(0);
202 String ovar = vars.remove(0);
203
204 // the next node
205 RDFNode n = q.get(ovar);
206 if(n.isAnon()){
207 int nextId;
208 if(lastNodes.get(n.toString())==null){
209 nextId = BlankNodeCollector.getNextGlobalBNodeId();
210 lastNodes.put(n.toString(), nextId);
211 //System.out.println(n.toString());
212 }else{
213 nextId = lastNodes.get(n.toString());
214 }
215 RDFNodeTuple tuple = new RDFNodeTuple(q.get(pvar), new RDFBlankNode(nextId,n));
216 BlankNodeCollector.addBlankNode(currentId, tuple);
217 assignIdRec(nextId, q, vars, lastNodes);
218 }else{
219 BlankNodeCollector.addBlankNode(currentId, new RDFNodeTuple(q.get(pvar), n));
220 }
221
222
223 }
224
225
226
227
228
229
230
231
232
233
234
235
236
237 }