KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > db > impl > DBQueryStageCompiler


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

5
6 package com.hp.hpl.jena.db.impl;
7
8 import java.util.List JavaDoc;
9
10 import com.hp.hpl.jena.graph.*;
11 import com.hp.hpl.jena.graph.query.*;
12 import com.hp.hpl.jena.shared.JenaException;
13 import com.hp.hpl.jena.vocabulary.RDF;
14
15 import java.util.*;
16
17 /**
18     @author kers
19 <br>
20     PatternStageCompiler serves two purposes: it contains the standard algorithm
21     for compiling patterns-as-triples to patterns-as-Pattern(s), and it has the
22     standard implementation of PatternCompiler in terms of ordinary Elements.
23 */

24 public final class DBQueryStageCompiler
25     {
26     
27     public DBQueryStageCompiler()
28         {}
29       
30     /**
31         to compile an array of triples, compile each triple and form the corresponding
32         array of Patterns. *preserve the order*.
33     */

34     public static DBQuery compile( DBQueryStageCompiler compiler, DBQueryHandler qh, SpecializedGraph sg,
35             List JavaDoc varList, List JavaDoc dbPat, ExpressionSet constraints )
36         {
37         DBQuery query = new DBQuery(sg,varList,qh.queryOnlyStmt,
38                 qh.queryOnlyReif,qh.queryFullReif);
39         int j;
40         if ( !query.isEmpty ) {
41             for (int i = 0; i < dbPat.size(); i += 1) {
42                 compilePattern (compiler, query, (DBPattern) dbPat.get(i));
43             }
44             compileConstraints (compiler, query, constraints);
45             compileQuery (compiler, query);
46         }
47         return query;
48     }
49        
50     
51     /**
52         compile a triple pattern.
53     */

54
55     private static void compilePattern( DBQueryStageCompiler compiler, DBQuery query,
56             DBPattern dbpat )
57         {
58             Element subj = dbpat.S;
59             Element obj = dbpat.O;
60             Element pred = dbpat.P;
61             String JavaDoc qual = null;
62             int alias = query.aliasCnt;
63
64             if ( query.isReifier ) {
65                 boolean newAlias = true;
66                 if ( !(pred instanceof Fixed) )
67                     throw new JenaException("Reifier predicate not bound");
68                 Node p = ((Fixed)pred).asNodeMatch((Domain)null);
69                 char reifProp;
70                 if ( p.equals(RDF.Nodes.subject) ) reifProp = 'S';
71                 else if ( p.equals(RDF.Nodes.predicate) ) reifProp = 'P';
72                 else if ( p.equals(RDF.Nodes.object) ) reifProp = 'O';
73                 else if ( p.equals(RDF.Nodes.type) ) {
74                     reifProp = 'T';
75                 }
76                 else throw new JenaException("Unexpected reifier predicate");
77                 if ( !subj.equals(Element.ANY) ) {
78                     // optionally do join optimization for reification.
79
// if the subject is joined with another pattern and
80
// that subject is already bound, skip the join.
81
if ( query.qryFullReif && (subj instanceof Free) &&
82                         query.getBinding(((Free)subj).getListing()).isBoundToCol() ) {
83                             alias = (query.getBinding(((Free)subj).getListing())).alias;
84                             newAlias = false;
85                         } else
86                             qual = query.sqlAnd.gen(getQual(query,alias,'N',subj));
87                 }
88                 qual += query.sqlAnd.gen(getQual(query,alias,reifProp,obj));
89                 qual += query.sqlAnd.gen(query.driver.genSQLQualGraphId(alias,query.graphId));
90                 if ( newAlias ) query.newAlias();
91                 
92             } else {
93                 // query over triple table
94
qual = query.sqlAnd.gen(getQual(query,alias,'S',subj));
95                 qual += query.sqlAnd.gen(getQual(query,alias,'P',pred));
96                 qual += query.sqlAnd.gen(getQual(query,alias,'O',obj));
97                 qual += query.sqlAnd.gen(query.driver.genSQLQualGraphId(alias,query.graphId));
98                 query.newAlias();
99             }
100         query.stmt += qual;
101         }
102         
103         private static String JavaDoc getQual(DBQuery query,int alias,char pred, Element spo) {
104             String JavaDoc qual = "";
105             if (spo instanceof Fixed) {
106                 Node obj = ((Fixed) spo).asNodeMatch((Domain) null);
107                 if ( query.isReifier )
108                     qual = query.driver.genSQLReifQualConst(alias,pred,obj);
109                 else
110                     qual = query.driver.genSQLQualConst(alias,pred,obj);
111             } else if (spo instanceof Free){
112                 Free v = (Free) spo;
113                 VarDesc bind = query.getBinding(v.getListing());
114                 // only bind to argument value for first use of variable.
115
// subsequent references should join to first binding.
116
if ( v.isArg() && !bind.isBoundToCol ) {
117                     query.argCnt++;
118                     query.argType += pred;
119                     query.argIndex.add(new Integer JavaDoc(v.getMapping()));
120                     qual = query.driver.genSQLQualParam(alias, pred);
121                     bind.bindToCol(alias, pred);
122                 } else {
123                     if (bind.isBoundToCol()) {
124                         qual =
125                             query.driver.genSQLJoin( bind.alias, bind.column,
126                                 alias, pred);
127                     } else {
128                         // nothing to compare. just binding the var to the column
129
bind.bindToCol(alias, pred);
130                         qual = "";
131                     }
132                 }
133             } else if ( spo != Element.ANY )
134                 throw new JenaException("Invalid Element in qualifier");
135             return qual;
136         }
137
138         /**
139             compile the constraints.
140         */

141         private static void compileConstraints( DBQueryStageCompiler compiler, DBQuery query,
142             ExpressionSet constraints ) {
143             Iterator it = constraints.iterator();
144             Expression e;
145             while (it.hasNext()) {
146                 e = (Expression) it.next();
147                 VarDesc bind = query.findBinding(e.getArg(0).getName());
148                 if ( bind == null )
149                     throw new JenaException("Unbound variable in constraint");
150                 String JavaDoc strMat = ((Expression.Fixed)e.getArg(1)).toString();
151                 query.stmt += query.sqlAnd.gen(query.driver.genSQLStringMatch(bind.alias,
152                     bind.column, e.getFun(), strMat));
153             }
154         }
155             
156
157     /**
158         compile the final form of the query statement.
159     */

160     private static void compileQuery( DBQueryStageCompiler compiler, DBQuery query )
161         {
162             // create result list
163
int resCnt = query.vars.length - query.argCnt;
164             query.resList = new int[resCnt];
165             query.stmt = query.driver.genSQLSelectStmt(
166                 query.driver.genSQLResList(query.resList,query.vars),
167                 query.driver.genSQLFromList(query.aliasCnt,query.table),
168                 query.stmt);
169         }
170         
171 }
172
173 /*
174  * (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
175  * All rights reserved.
176  *
177  * Redistribution and use in source and binary forms, with or without
178  * modification, are permitted provided that the following conditions
179  * are met:
180  * 1. Redistributions of source code must retain the above copyright
181  * notice, this list of conditions and the following disclaimer.
182  * 2. Redistributions in binary form must reproduce the above copyright
183  * notice, this list of conditions and the following disclaimer in the
184  * documentation and/or other materials provided with the distribution.
185  * 3. The name of the author may not be used to endorse or promote products
186  * derived from this software without specific prior written permission.
187  *
188  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
189  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
190  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
191  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
192  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
193  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
194  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
195  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
196  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
197  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
198  */

199
Popular Tags