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