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    }