KickJava   Java API By Example, From Geeks To Geeks.

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


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
8 import java.io.* ;
9 import java.util.* ;
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12
13 import com.hp.hpl.jena.graph.*;
14 import com.hp.hpl.jena.graph.impl.*;
15
16 import com.hp.hpl.jena.rdf.model.* ;
17 import com.hp.hpl.jena.rdql.parser.Q_Query;
18 import com.hp.hpl.jena.rdql.parser.RDQLParser;
19
20 // Don't import the package! Conflict with graph.Node
21

22 /** The data structure for a query.
23  * There are two ways of creating a query - use the parser to turn
24  * a string description of the query into the executable form, and
25  * the programmatic way (the parser is calling the programmatic
26  * operations driven by the quyery string). The declarative approach
27  * of passing in a string is preferred.
28  *
29  * Once a query is built, it can be passed to a query engine.
30  * @see QueryEngine
31  * @see QueryResults
32  *
33  * @author Andy Seaborne
34  * @version $Id: Query.java,v 1.19 2005/02/21 12:15:23 andy_seaborne Exp $
35  */

36
37 public class Query
38 {
39     static Log logger = LogFactory.getLog(Query.class) ;
40     
41     // The names of variables wanted by the caller.
42
protected List resultVars = new ArrayList() ; // Type in list: String name
43
// List of all variabes used in the triple patterns
44
protected List patternVars = new ArrayList() ; // Type in list: String name
45
protected List triplePatterns = new ArrayList() ; // Type in list: TriplePatterns
46
protected List constraints = new ArrayList() ; // Type in list: Constraints
47

48     protected Map prefixMap = new HashMap() ;
49     protected static Map defaultPrefixMap = new HashMap() ;
50     static
51     {
52         defaultPrefixMap.put("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") ;
53         defaultPrefixMap.put("rdfs", "http://www.w3.org/2000/01/rdf-schema#") ;
54         defaultPrefixMap.put("xsd" , "http://www.w3.org/2001/XMLSchema#") ;
55         defaultPrefixMap.put("owl" , "http://www.w3.org/2002/07/owl#") ;
56     }
57
58     // If no model is provided explicitly, the query engine will load
59
// a model from the URL.
60
String JavaDoc sourceURL = null ;
61     Model source = null ;
62
63     // Statistics
64
public long parseTime = -1 ;
65     public long buildTime = -1 ;
66     public long loadTime = -1 ;
67     public long executeTime = -1 ;
68
69     /** Create a query from the given string by calling the parser.
70      * After it has been created, an application should set the data source, then
71      * call the QueryEngine.
72      *
73      * @param s The query string
74      * @throws QueryException Thrown when a parse error occurs
75      */

76
77     public Query(String JavaDoc s)
78     {
79         this() ;
80         Q_Query query = null ;
81         try {
82             //long initTime = 0;
83
parseTime = 0;
84             long startTime = 0;
85             //long stopTime = 0;
86

87             //ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes()) ;
88
Reader in = new StringReader(s) ;
89             
90             startTime = System.currentTimeMillis();
91             RDQLParser parser = new RDQLParser(in) ;
92             parser.CompilationUnit();
93             parseTime = System.currentTimeMillis() - startTime;
94
95             logger.debug("Query parse time: "+parseTime) ;
96
97             query = (Q_Query)parser.top() ;
98             // Post-parsing work on the query tree
99
query.phase2(this) ;
100
101             buildTime = System.currentTimeMillis() - parseTime - startTime ;
102             logger.debug("Query parse and build time: "+buildTime) ;
103         }
104         catch (QueryException qEx) { throw qEx ; }
105         catch (Exception JavaDoc e)
106         {
107             //e.printStackTrace(System.err) ;
108
throw new QueryException("Parse error: "+e) ;
109         }
110     }
111
112     /** Create a blank query. The application is expected to complete the query parts needed
113      * by calling the various "add" operations later,
114      */

115
116     public Query()
117     {
118     }
119
120     /** Convenience function to parse and execute a query.
121      *
122      * @param queryString The query: should include FROM clause to provide the data
123      * @throws QueryException Runtime exception
124      */

125     public static QueryResults exec(String JavaDoc queryString)
126     {
127         Query q = new Query(queryString) ;
128         QueryExecution qe = new QueryEngine(q) ;
129         qe.init() ;
130         return qe.exec() ;
131     }
132
133     /** Convenience function to parse and execute a query against an existing model.
134      *
135      * @param queryString The query: the FROM clause will be overridden
136      * @param model The data
137      * @throws QueryException Runtime exception
138      */

139     public static QueryResults exec(String JavaDoc queryString, Model model)
140     {
141         Query q = new Query(queryString) ;
142         if ( model != null )
143             q.setSource(model);
144         QueryExecution qe = new QueryEngine(q) ;
145         qe.init() ;
146         return qe.exec() ;
147     }
148
149
150     /** Convenience function to parse and execute a query against a remote model.
151      * The remote data is loaded into the local application.
152      *
153      * @param queryString The query: the FROM clause will be overridden
154      * @param dataURL The remote data source
155      * @throws QueryException Runtime exception
156      */

157     public static QueryResults exec(String JavaDoc queryString, String JavaDoc dataURL)
158     {
159         Query q = new Query(queryString) ;
160         q.setSourceURL(dataURL) ;
161         QueryExecution qe = new QueryEngine(q) ;
162         qe.init() ;
163         return qe.exec() ;
164     }
165
166
167     /** The data target for the query as a Jena model.
168      * Applications must call this whther using the parser or not.
169      */

170
171     public void setSource(Model m) { source = m ; }
172     /** Return the model that this query executes against. */
173     public Model getSource() { return source ; }
174
175     /** Location of the source for the data. If the model is not set, then the QueryEngine
176      * will attempt to load the data from this URL.
177      */

178     public void setSourceURL(String JavaDoc s) { sourceURL = s ; }
179     public String JavaDoc getSourceURL() { return sourceURL ; }
180
181     /** Programmatic API operation: return the SELECT variables. */
182     public List getResultVars() { return resultVars ; }
183     
184     /** Programmatic API operation: add a SELECT variable */
185     public void addResultVar(String JavaDoc varName)
186     {
187         if ( !resultVars.contains(varName) )
188             resultVars.add(varName);
189     }
190
191     /** Programmatic API operation: get all the variabes used by this query */
192     public List getBoundVars() { return patternVars ; }
193     
194     /** Programmatic API operation: declare a variable used by the query */
195     public void addBoundVar(String JavaDoc varName)
196     {
197         if ( !patternVars.contains(varName) )
198             patternVars.add(varName);
199     }
200
201     /** Programmatic API operation: add a constraint */
202     public void addConstraint(Constraint c) { constraints.add(c) ; }
203     /** Programmatic API operation: get all the constraints */
204     public List getConstraints() { return constraints ; }
205
206     /** Programmatic API operation */
207     public void addTriplePattern(Triple t) { triplePatterns.add(t) ; }
208     public void addTriplePattern(Node s, Node p, Node o)
209     {
210         Triple t = new Triple(s, p, o) ;
211         triplePatterns.add(t) ;
212     }
213
214     /** Programmatic API operation: get the query graph pattern */
215     public List getTriplePatterns() { return triplePatterns ; }
216
217     /** Set a prefix for this query */
218     public void setPrefix(String JavaDoc prefix, String JavaDoc expansion)
219     {
220         prefixMap.put(prefix, expansion) ;
221     }
222
223     /** Lookup a prefix for this query, including the default prefixes */
224     public String JavaDoc getPrefix(String JavaDoc prefix)
225     {
226         String JavaDoc s = null ;
227         
228         if ( prefixMap != null )
229             s = (String JavaDoc)prefixMap.get(prefix) ;
230             
231         if ( s == null )
232             s = (String JavaDoc)defaultPrefixMap.get(prefix) ;
233             
234         return s ;
235     }
236     
237     /** Return the prefix map fro the parsed query */
238     public Map getPrefixMap() { return prefixMap ; }
239
240     /** Return the default prefix map */
241     public Map getDefaultPrefixMap() { return defaultPrefixMap ; }
242
243
244
245     // Reverse of parsing : should produce a string that parses to the same query
246
public String JavaDoc toString()
247     {
248         StringBuffer JavaDoc sb = new StringBuffer JavaDoc() ;
249
250         sb.append("SELECT ") ;
251         if ( resultVars.size() == 0 )
252             sb.append("*") ;
253         else
254         {
255             boolean first = true ;
256             for ( Iterator iter = resultVars.iterator() ; iter.hasNext() ; )
257             {
258                 String JavaDoc var = (String JavaDoc)iter.next() ;
259                 if ( ! first )
260                     sb.append(", ") ;
261                 sb.append("?") ;
262                 sb.append(var) ;
263                 first = false ;
264             }
265         }
266         sb.append("\n") ;
267
268         // Source
269

270         // Triple patterns
271
if ( triplePatterns.size() > 0 )
272         {
273             sb.append("WHERE ") ;
274             boolean first = true ;
275             for ( Iterator iter = triplePatterns.iterator() ; iter.hasNext() ; )
276             {
277                 Triple tp = (Triple)iter.next() ;
278                 if ( ! first )
279                 {
280                     sb.append(", \n") ;
281                     sb.append(" ") ;
282                    
283                 }
284                 sb.append(triplePatternToString(tp)) ;
285                 first = false ;
286             }
287             sb.append("\n") ;
288         }
289
290         // Constraints
291
if ( constraints.size() > 0 )
292         {
293             for ( Iterator iter = constraints.iterator() ; iter.hasNext() ; )
294             {
295                 Constraint c = (Constraint)iter.next() ;
296                 sb.append("AND ") ;
297                 sb.append(c.toString()) ;
298                 sb.append("\n") ;
299             }
300         }
301
302         if ( prefixMap.size() > 0 )
303         {
304             sb.append("USING\n") ;
305             boolean first = true ;
306             for ( Iterator iter = prefixMap.keySet().iterator() ; iter.hasNext() ; )
307             {
308                 if ( ! first )
309                     sb.append(" ,\n") ;
310                 String JavaDoc k = (String JavaDoc)iter.next() ;
311                 String JavaDoc v = (String JavaDoc)prefixMap.get(k) ;
312                 sb.append(" "+k+" FOR <"+v+">") ;
313                 first = false ;
314             }
315             sb.append("\n") ;
316         }
317         
318         return sb.toString() ;
319     }
320     
321     private String JavaDoc triplePatternToString(Triple tp)
322     {
323         StringBuffer JavaDoc sb = new StringBuffer JavaDoc() ;
324         sb.append("( ") ;
325         sb.append(slotToString(tp.getSubject())) ;
326         sb.append(", ") ;
327         sb.append(slotToString(tp.getPredicate())) ;
328         sb.append(", ") ;
329         sb.append(slotToString(tp.getObject())) ;
330         sb.append(" )") ;
331         return sb.toString() ;
332     }
333     
334     private String JavaDoc slotToString(Node n)
335     {
336         if ( n instanceof Node_Variable)
337             return n.toString() ;
338         if ( n instanceof Node_URI)
339         {
340             String JavaDoc s = applyPrefix(n.getURI()) ;
341             if ( s == null )
342                 return "<"+n.getURI()+">" ;
343             return s ;
344         }
345             
346             
347         if ( n instanceof Node_Literal)
348         {
349             LiteralLabel lit = ((Node_Literal)n).getLiteral() ;
350             StringBuffer JavaDoc sb = new StringBuffer JavaDoc() ;
351             sb.append('"') ;
352             sb.append(lit.getLexicalForm()) ;
353             sb.append('"') ;
354             if ( lit.language() != null && lit.language().length() > 0 )
355             {
356                 sb.append("@") ;
357                 sb.append(lit.language()) ;
358             }
359             if ( lit.getDatatypeURI() != null )
360             {
361                 sb.append("^^<") ;
362                 sb.append(lit.getDatatypeURI()) ;
363                 sb.append(">") ;
364             }
365                             
366             return sb.toString() ;
367         }
368         //if ( n instanceof Node_Blank)
369
// return "_:"+n.toString() ;
370
if ( n instanceof Node_ANY )
371             // Shouldn't happen!
372
return "any:"+n ;
373         return "unknown:"+n ;
374     }
375     
376     private String JavaDoc applyPrefix(String JavaDoc uri)
377     {
378         String JavaDoc s = applyPrefix(uri, prefixMap, null) ;
379         if ( s == null )
380             s = applyPrefix(uri, defaultPrefixMap, prefixMap) ;
381         return s ;
382     }
383     
384     private String JavaDoc applyPrefix(String JavaDoc uri, Map pm, Map exclude)
385     {
386         Iterator it = pm.entrySet().iterator();
387         for ( ; it.hasNext() ; )
388         {
389             Map.Entry e = (Map.Entry) it.next();
390             String JavaDoc ss = (String JavaDoc) e.getValue();
391             if ( uri.startsWith( ss ) )
392             {
393                 if ( exclude != null )
394                 {
395                     // Check it is not in the exclusions as a different mapping.
396
if ( exclude.containsKey(e.getKey()) &&
397                          ! exclude.get(e.getKey()).equals(e.getValue()) )
398                         continue ;
399                 }
400                 return e.getKey()+":"+uri.substring(ss.length() );
401             }
402         }
403         return null ;
404     }
405 }
406
407 /*
408  * (c) Copyright 2001, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
409  * All rights reserved.
410  *
411  * Redistribution and use in source and binary forms, with or without
412  * modification, are permitted provided that the following conditions
413  * are met:
414  * 1. Redistributions of source code must retain the above copyright
415  * notice, this list of conditions and the following disclaimer.
416  * 2. Redistributions in binary form must reproduce the above copyright
417  * notice, this list of conditions and the following disclaimer in the
418  * documentation and/or other materials provided with the distribution.
419  * 3. The name of the author may not be used to endorse or promote products
420  * derived from this software without specific prior written permission.
421  *
422  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
423  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
424  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
425  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
426  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
427  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
428  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
429  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
430  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
431  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
432  */

433
Popular Tags