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.HashMap;
023 import java.util.List;
024 import java.util.Map;
025 import java.util.SortedSet;
026 import java.util.TreeSet;
027
028 import com.hp.hpl.jena.query.QuerySolution;
029 import org.apache.log4j.Logger;
030 import org.dllearner.kb.sparql.SPARQLTasks;
031 import org.dllearner.kb.sparql.SparqlQueryMaker;
032 import org.dllearner.utilities.datastructures.RDFNodeTuple;
033
034 import com.hp.hpl.jena.query.ResultSetFormatter;
035 import com.hp.hpl.jena.rdf.model.RDFNode;
036 import com.hp.hpl.jena.sparql.core.ResultBinding;
037 import com.hp.hpl.jena.sparql.resultset.ResultSetRewindable;
038
039 /**
040 * Can execute different queries.
041 *
042 * @author Sebastian Hellmann
043 *
044 */
045 public class SparqlTupleAquisitorImproved extends SparqlTupleAquisitor {
046
047 private static Logger logger = Logger.getLogger(SparqlTupleAquisitorImproved.class);
048 private Map<String,SortedSet<RDFNodeTuple>> resources = new HashMap<String, SortedSet<RDFNodeTuple>>();
049 int recursionDepth;
050
051
052 public SparqlTupleAquisitorImproved(SparqlQueryMaker sparqlQueryMaker, SPARQLTasks sparqlTasks, int recursionDepth) {
053 super(sparqlQueryMaker, sparqlTasks);
054 this.recursionDepth = recursionDepth;
055
056 }
057
058 @Override
059 public SortedSet<RDFNodeTuple> retrieveTupel(String uri){
060
061 SortedSet<RDFNodeTuple> cachedSet = resources.get(uri);
062 if(cachedSet!=null) {
063 return cachedSet;
064 }
065
066 //SortedSet<RDFNodeTuple> tmp = new TreeSet<RDFNodeTuple>();
067 String sparqlQueryString = sparqlQueryMaker.makeSubjectQueryLevel(uri, recursionDepth);
068 //System.out.println(sparqlQueryString);
069 ResultSetRewindable rsw=null;
070 try{
071 rsw = sparqlTasks.queryAsResultSet(sparqlQueryString);
072 }catch (Exception e) {
073 return super.retrieveTupel(uri);
074 }
075 @SuppressWarnings("unchecked")
076 List<QuerySolution> l = ResultSetFormatter.toList(rsw);
077 rsw.reset();
078
079
080
081 int resultsetcount = 0;
082 int i = 0;
083 for (QuerySolution binding : l) {
084 i = 0;
085 RDFNode nextOBJ = binding.get(OBJECT+i);
086 RDFNode nextPRED = binding.get(PREDICATE+i);
087 RDFNodeTuple tmptuple = new RDFNodeTuple(nextPRED, nextOBJ );
088 addToLocalCache(uri,tmptuple);
089
090 boolean cont = !nextOBJ.isLiteral();
091 for (i=1; (i < recursionDepth) && cont; i++) {
092 RDFNode tmpPREDURI = binding.get(PREDICATE+i);
093 RDFNode tmpOBJURI = binding.get(OBJECT+i);
094 if(tmpOBJURI==null) {
095 cont=false;
096 }else if (tmpOBJURI.isLiteral()) {
097 tmptuple = new RDFNodeTuple(tmpPREDURI, tmpOBJURI );
098 addToLocalCache(nextOBJ.toString(), tmptuple);
099 //logger.trace(tmptuple);
100 //logger.trace("For: "+nextOBJ.toString()+ " added :"+resources.get(nextOBJ.toString()));
101 cont=false;
102 }else {
103 tmptuple = new RDFNodeTuple(tmpPREDURI, tmpOBJURI );
104 addToLocalCache(nextOBJ.toString(), tmptuple);
105 //logger.trace(tmptuple);
106 //logger.trace("For: "+nextOBJ.toString()+ " added :"+resources.get(nextOBJ.toString()));
107 nextOBJ = tmpOBJURI;
108 cont = true;
109 }
110 }//end for
111
112 resultsetcount++;
113 }
114
115 //System.out.println("original count "+count);
116 //logger.warn("SparqlTupelAquisitor retrieved : "+resultsetcount);
117 if(resultsetcount>999) {
118 logger.warn("SparqlTupelAquisitor retrieved more than 1000 results, there might some be missing");
119 }
120 return ((cachedSet=resources.get(uri))==null)?new TreeSet<RDFNodeTuple>():cachedSet;
121 }
122
123 @Override
124 public SortedSet<RDFNodeTuple> retrieveTuplesForClassesOnly(String uri){
125 int tmp = recursionDepth;
126 recursionDepth=4;
127
128 SortedSet<RDFNodeTuple> tmpSet = retrieveTupel(uri);
129 recursionDepth = tmp;
130 return tmpSet;
131 //getQuery
132 //String sparqlQueryString = sparqlQueryMaker.makeSubjectQueryUsingFilters(uri);
133 //return sparqlTasks.queryAsRDFNodeTuple(sparqlQueryString, PREDICATE, OBJECT);
134 }
135
136
137
138
139 @Override
140 public SortedSet<RDFNodeTuple> retrieveClassesForInstances(String uri){
141 // getQuery
142 return super.retrieveClassesForInstances(uri);
143
144 }
145
146 private void addToLocalCache(String uri, RDFNodeTuple tuple){
147 SortedSet<RDFNodeTuple> set = resources.get(uri);
148
149
150 if(set==null){
151 set = new TreeSet<RDFNodeTuple>();
152 set.add(tuple);
153 resources.put(uri, set );
154
155 }else {
156 set.add(tuple);
157 }
158 }
159
160 public void removeFromCache(String uri){
161 resources.remove(uri);
162 }
163
164
165
166 }