KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > rdql > QueryEngine


1 /*
2  * (c) Copyright 2001, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
3  * [See end of file]
4  */

5
6 package com.hp.hpl.jena.rdql;
7 import java.util.* ;
8
9 import com.hp.hpl.jena.graph.*;
10 import com.hp.hpl.jena.graph.query.*;
11 import com.hp.hpl.jena.rdf.model.*;
12 import com.hp.hpl.jena.rdf.model.impl.*;
13 import com.hp.hpl.jena.util.FileManager;
14 import com.hp.hpl.jena.util.iterator.*;
15
16 /**
17  * @author Andy Seaborne
18  * @version $Id: QueryEngine.java,v 1.15 2005/02/21 12:15:23 andy_seaborne Exp $
19  */

20  
21 public class QueryEngine implements QueryExecution
22 {
23     Query query ;
24
25     static int queryCount = 0 ;
26     boolean queryInitialised = false ;
27     int idQueryExecution ;
28     
29     ResultsIterator resultsIter ;
30     // Statistics
31
long queryStartTime = -1 ;
32
33     public QueryEngine(Query q)
34     {
35         query = q ;
36         idQueryExecution = (++queryCount) ;
37     }
38
39     /** Initialise a query execution. May be called before exec.
40      * If it has not be called, the query engine will initialise
41      * itself during the exec() method.
42      */

43
44     public void init()
45     {
46         if (queryInitialised)
47             return;
48
49         if (query.getSource() == null)
50         {
51             if (query.sourceURL == null)
52             {
53                 //Query.logger.warn("No data for query (no URL, no model)");
54
throw new QueryException("No model for query");
55             }
56             long startTime = System.currentTimeMillis();
57             Model src = FileManager.get().loadModel(query.sourceURL, null) ;
58             if ( src == null )
59                 throw new QueryException("Failed to load data source") ;
60             query.setSource(src);
61             query.loadTime = System.currentTimeMillis() - startTime;
62         }
63         queryInitialised = true;
64     }
65     
66     /** Execute a query and get back the results.
67      * @return QueryResults
68      */

69     
70     public QueryResults exec() { return exec(null) ; }
71
72     /** Execute a query, passing in an initial binding of some of the variables in the query.
73      * @param startBinding Initial values of variables.
74      * @return QueryResults
75      */

76     
77     public QueryResults exec(ResultBindingImpl startBinding)
78     {
79         resultsIter = null ;
80         try {
81             init() ;
82             resultsIter = new ResultsIterator(query, startBinding) ;
83             return new QueryResultsStream(query, this, resultsIter) ;
84         } catch (RuntimeException JavaDoc ex) {
85             if ( resultsIter != null )
86                 resultsIter.close();
87             throw ex ;
88         }
89     }
90
91     public void abort()
92     {
93         resultsIter.close() ;
94     }
95
96     /** Normal end of use of this execution */
97     public void close()
98     {
99         resultsIter.close() ;
100     }
101
102
103     static class ResultsIterator implements ClosableIterator
104     {
105         Node[] projectionVars ;
106         Query query ;
107
108         ResultBindingImpl nextBinding = null ;
109         boolean finished = false ;
110         ClosableIterator planIter ;
111         ResultBindingImpl initialBindings ;
112          
113         ResultsIterator(Query q, ResultBindingImpl presets)
114         {
115             query = q ;
116             initialBindings = presets ;
117             // Build the graph query plan etc.
118
Graph graph = query.getSource().getGraph();
119
120             QueryHandler queryHandler = graph.queryHandler();
121             com.hp.hpl.jena.graph.query.Query graphQuery = new com.hp.hpl.jena.graph.query.Query();
122
123             for (Iterator iter = query.getTriplePatterns().listIterator(); iter.hasNext();)
124             {
125                 Triple t = (Triple) iter.next();
126                 t = substituteIntoTriple(t, presets) ;
127                 graphQuery.addMatch(t);
128             }
129
130             projectionVars = new Node[query.getBoundVars().size()];
131
132             for (int i = 0; i < projectionVars.length; i++)
133             {
134                 projectionVars[i] = Node.createVariable((String JavaDoc) query.getBoundVars().get(i));
135             }
136
137             // Constraints
138

139             for (Iterator cIter = query.constraints.iterator(); cIter.hasNext();)
140             {
141                 Constraint constraint = (Constraint)cIter.next();
142                 if ( constraint instanceof Expression )
143                 {
144                     Expression e = (Expression)constraint ;
145                     graphQuery.addConstraint(e) ;
146                 }
147                 else
148                     System.err.println("Query constraint '"+constraint+"' is not an expression") ;
149             }
150             
151             BindingQueryPlan plan = queryHandler.prepareBindings(graphQuery, projectionVars);
152             planIter = plan.executeBindings() ;
153         }
154           
155         public boolean hasNext()
156         {
157             if ( finished )
158                 return false ;
159             // Loop until we get a binding that is satifactory
160
// or we run out of candidates.
161
while ( nextBinding == null )
162             {
163                 if ( ! planIter.hasNext() )
164                     break ;
165                 // Convert from graph form to model form
166
Domain d = (Domain)planIter.next() ;
167                 nextBinding = new ResultBindingImpl(initialBindings) ;
168                 nextBinding.setQuery(query) ;
169                 for ( int i = 0 ; i < projectionVars.length ; i++ )
170                 {
171                     String JavaDoc name = projectionVars[i].toString().substring(1) ;
172                     Node n = (Node)d.get(i) ;
173                     if ( n == null )
174                     {
175                         // There was no variable of this name
176
// May have been prebound.
177
// (Later) may have optionally bound variables.
178
// Otherwise, should not occur but this is safe.
179
continue ;
180                     }
181     
182                     // Convert graph node to model RDFNode
183
RDFNode rdfNode = convertGraphNodeToRDFNode(n, query.getSource()) ;
184                     nextBinding.add(name, rdfNode) ;
185                 }
186                 
187 // // Verify constraints
188
// boolean passesTests = true;
189
// for (Iterator cIter = query.constraints.iterator(); cIter.hasNext();)
190
// {
191
// Constraint constraint = (Constraint)cIter.next();
192
// // Debugging
193
// printExpression((Expression)constraint) ;
194
// if (!constraint.isSatisfied(query, nextBinding))
195
// {
196
// passesTests = false;
197
// break;
198
// }
199
// }
200
// if (!passesTests)
201
// {
202
// nextBinding = null ;
203
// continue ;
204
// }
205
}
206
207             if ( nextBinding == null )
208             {
209                 close() ;
210                 return false ;
211             }
212             return true ;
213         }
214
215         public Object JavaDoc next()
216         {
217             if ( nextBinding == null )
218                 throw new NoSuchElementException("QueryEngine.ResultsIterator") ;
219             ResultBinding x = nextBinding ;
220             nextBinding = null ;
221             return x ;
222         }
223
224         public void remove()
225         {
226             throw new UnsupportedOperationException JavaDoc("QueryEngine.ResultsIterator.remove") ;
227         }
228         
229         public void close()
230         {
231             if ( ! finished )
232             {
233                 planIter.close() ;
234                 finished = true ;
235             }
236         }
237     }
238
239 // static Node convertValueToNode(Value value)
240
// {
241
// if ( value.isRDFLiteral())
242
// return Node.createLiteral(
243
// value.getRDFLiteral().getLexicalForm(),
244
// value.getRDFLiteral().getLanguage(),
245
// value.getRDFLiteral().getDatatype()) ;
246
//
247
// if ( value.isRDFResource())
248
// {
249
// if ( value.getRDFResource().isAnon())
250
// return Node.createAnon(value.getRDFResource().getId()) ;
251
// return Node.createURI(value.getRDFResource().getURI()) ;
252
// }
253
//
254
// if ( value.isURI())
255
// return Node.createURI(value.getURI()) ;
256
//
257
// return Node.createLiteral(value.asUnquotedString(),null ,null) ;
258
// }
259

260     /** Internal utility */
261     
262     static RDFNode convertGraphNodeToRDFNode(Node n, Model model)
263     {
264         if ( n.isLiteral() )
265             return new LiteralImpl(n, (ModelCom) model) ;
266                 
267         if ( n.isURI() || n.isBlank() )
268             return new ResourceImpl(n, (ModelCom) model) ;
269                 
270         if ( n.isVariable() )
271         {
272             // Hack
273
System.err.println("Variable unbound: "+n) ;
274             //binding.add(name, n) ;
275
return null ;
276         }
277                 
278         System.err.println("Unknown node type for node: "+n) ;
279         return null ;
280
281     }
282
283     static Triple substituteIntoTriple(Triple t, ResultBinding binding)
284     {
285         if ( binding == null )
286            return t ;
287         
288         boolean keep = true ;
289         Node subject = substituteNode(t.getSubject(), binding) ;
290         Node predicate = substituteNode(t.getPredicate(), binding) ;
291         Node object = substituteNode(t.getObject(), binding) ;
292         
293         if ( subject == t.getSubject() &&
294              predicate == t.getPredicate() &&
295              object == t.getObject() )
296              return t ;
297              
298         return new Triple(subject, predicate, object) ;
299     }
300     
301     static Node substituteNode(Node n, ResultBinding binding)
302     {
303         if ( ! n.isVariable() )
304             return n ;
305             
306         String JavaDoc name = ((Node_Variable)n).getName() ;
307         Object JavaDoc obj = binding.get(name) ;
308         if ( obj == null )
309             return n ;
310             
311         if ( obj instanceof RDFNode )
312             return ((RDFNode)obj).asNode() ;
313             
314         if ( obj instanceof Node )
315             return (Node)obj ;
316
317         System.err.println("Unknown object in binding: ignored: "+obj.getClass().getName()) ;
318         return n ;
319     }
320     
321     static private void printExpression(Expression e)
322     {
323         System.out.println("Expression: "+e+" ["+e.getClass().getName()+"]") ;
324         if ( e.isApply() )
325         {
326             System.out.println(" Apply - "+e.getFun()) ;
327             for ( int i = 0 ; i < e.argCount() ; i++ )
328             {
329                 printExpression(e.getArg(i)) ;
330             }
331         }
332         else if ( e.isVariable() )
333             System.out.println(" Variable - "+e.getName()) ;
334         else if ( e.isConstant() )
335             System.out.println(" Constant - "+e.getValue()) ;
336         else
337             System.out.println(" Unknown") ;
338     }
339 }
340
341 /*
342  * (c) Copyright 2001, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
343  * All rights reserved.
344  *
345  * Redistribution and use in source and binary forms, with or without
346  * modification, are permitted provided that the following conditions
347  * are met:
348  * 1. Redistributions of source code must retain the above copyright
349  * notice, this list of conditions and the following disclaimer.
350  * 2. Redistributions in binary form must reproduce the above copyright
351  * notice, this list of conditions and the following disclaimer in the
352  * documentation and/or other materials provided with the distribution.
353  * 3. The name of the author may not be used to endorse or promote products
354  * derived from this software without specific prior written permission.
355  *
356  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
357  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
358  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
359  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
360  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
361  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
363  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
364  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
365  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
366  */

367
Popular Tags