KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > query > model > Query


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.query.model;
17
18 import org.outerj.daisy.repository.query.QueryException;
19 import org.outerj.daisy.repository.query.EvaluationContext;
20 import org.outerj.daisy.repository.query.SortOrder;
21 import org.outerj.daisy.query.QueryContext;
22 import org.outerj.daisy.jdbcutil.JdbcHelper;
23
24 import java.sql.PreparedStatement JavaDoc;
25 import java.sql.SQLException JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Iterator JavaDoc;
29
30 /**
31  * Describes a query. Obtained from the {@link org.outerj.daisy.query.QueryFactory QueryFactory}.
32  *
33  * <p>A query contains the following parts:
34  * <ul>
35  * <li>a select part (a list of identifiers). Always present.
36  * <li>a where clause: a query on 'structured' data (metadata etc.). This part is optional
37  * if a fulltext query (see below) is specified, otherwise it is always present.
38  * <li>a fulltext query. Optional. If both a fulltext query and a 'where clause' are specified,
39  * the results of both should be AND'ed together. In other words, the where clause' purpose
40  * is to further limit the results from the fulltext query.
41  * <li>order by clause. Optional.
42  * </ul>
43  *
44  * Once a query has been obtained from the QueryFactory, it should be prepared by calling
45  * {@link #prepare(org.outerj.daisy.query.QueryContext)}.
46  *
47  * <p>This class also has methods to generate SQL for performing the 'where clause'.
48  */

49 public class Query {
50     private ValueExprList selectClause;
51     private PredicateExpr whereClause;
52     private ValueExprList orderByClause;
53     private List JavaDoc sortOrders;
54     private int limit;
55     private FullTextQuery fullTextQuery;
56     private boolean includeRetired = false;
57     private boolean searchLastVersion = false;
58     private boolean annotateLinkFields = true;
59     private String JavaDoc styleHint;
60     private SqlGenerationContext sqlGenerationContext;
61
62     public Query(ValueExprList selectClause, PredicateExpr whereClause, FullTextQuery fullTextQuery, ValueExprList orderByClause, List JavaDoc sortOrders, int limit) {
63         this.selectClause = selectClause;
64         this.whereClause = whereClause;
65         this.orderByClause = orderByClause;
66         this.sortOrders = sortOrders;
67         this.limit = limit;
68         this.fullTextQuery = fullTextQuery;
69
70         if (selectClause == null)
71             throw new NullPointerException JavaDoc("select clause is a required part of Query.");
72         if (whereClause == null && fullTextQuery == null)
73             throw new NullPointerException JavaDoc("where clause is a required part of Query.");
74     }
75
76     public void prepare(QueryContext context) throws QueryException {
77         selectClause.prepare(context);
78         if (whereClause != null)
79             whereClause.prepare(context);
80         if (orderByClause != null) {
81             orderByClause.prepare(context);
82             ValueExpr[] valueExprs = orderByClause.getArray();
83             for (int i = 0; i < valueExprs.length; i++) {
84                 if (valueExprs[i].isMultiValue() || valueExprs[i].getValueType() == QValueType.UNDEFINED)
85                     throw new QueryException("Sorting not possible on \"" + valueExprs[i].getExpression() + "\".");
86             }
87         }
88         if (fullTextQuery != null)
89             fullTextQuery.prepare(context);
90     }
91
92     public boolean hasSql() {
93         return whereClause != null;
94     }
95
96     /**
97      * This method should only be called if {@link #hasSql()} return true.
98      */

99     public String JavaDoc getSql(JdbcHelper jdbcHelper) throws QueryException {
100         if (whereClause == null)
101             throw new QueryException("This query has no SQL part.");
102
103         this.sqlGenerationContext = new SqlGenerationContext(jdbcHelper);
104
105         StringBuffer JavaDoc whereSql = new StringBuffer JavaDoc(1000);
106         whereClause.generateSql(whereSql, sqlGenerationContext);
107
108         StringBuffer JavaDoc sql = new StringBuffer JavaDoc(whereSql.length() + 5000);
109         sqlGenerationContext.appendDocIdSelectClause(sql);
110         sqlGenerationContext.appendFromClause(sql, searchLastVersion);
111         sql.append(" where ");
112         sql.append("(");
113         sql.append(whereSql);
114         sql.append(")");
115         if (!includeRetired)
116             sql.append(" and document_variants.retired = ?");
117         if (!searchLastVersion)
118             sql.append(" and document_variants.liveversion_id != -1");
119
120         return sql.toString();
121     }
122
123     public FullTextQuery getFullTextQuery() {
124         return fullTextQuery;
125     }
126
127     public void bindSql(PreparedStatement JavaDoc stmt, int bindPos, EvaluationContext evaluationContext) throws SQLException JavaDoc, QueryException {
128         if (whereClause == null)
129             throw new IllegalStateException JavaDoc("This query has no SQL part.");
130
131         if (sqlGenerationContext == null)
132             throw new IllegalStateException JavaDoc("SQL is not yet generated, can not yet be bound.");
133
134         bindPos = sqlGenerationContext.bindJoins(stmt, bindPos);
135         bindPos = whereClause.bindSql(stmt, bindPos, evaluationContext);
136
137         if (!includeRetired)
138             stmt.setBoolean(bindPos, false);
139     }
140
141     public ValueExpr[] getSelectValueExprs() {
142         return selectClause.getArray();
143     }
144
145     public ValueExpr[] getOrderByValueExprs() {
146         if (orderByClause == null)
147             return null;
148         else
149             return orderByClause.getArray();
150     }
151
152     public SortOrder[] getOrderBySortOrders() {
153         if (sortOrders == null)
154             return null;
155         else
156             return (SortOrder[])sortOrders.toArray(new SortOrder[sortOrders.size()]);
157     }
158
159     public int getLimit() {
160         return limit;
161     }
162
163     public void setIncludeRetired(boolean includeRetired) {
164         this.includeRetired = includeRetired;
165     }
166
167     public void setSearchLastVersion(boolean searchLastVersion) {
168         this.searchLastVersion = searchLastVersion;
169     }
170
171     public boolean getSearchLastVersion() {
172         return this.searchLastVersion;
173     }
174
175     public String JavaDoc getStyleHint() {
176         return styleHint;
177     }
178
179     public void setStyleHint(String JavaDoc styleHint) {
180         this.styleHint = styleHint;
181     }
182
183     public boolean getAnnotateLinkFields() {
184         return annotateLinkFields;
185     }
186
187     public void setAnnotateLinkFields(boolean annotateLinkFields) {
188         this.annotateLinkFields = annotateLinkFields;
189     }
190
191     public void setOption(String JavaDoc name, String JavaDoc value) {
192         if (name.equalsIgnoreCase("include_retired"))
193             setIncludeRetired(value.equalsIgnoreCase("true"));
194         else if (name.equalsIgnoreCase("search_last_version"))
195             setSearchLastVersion(value.equalsIgnoreCase("true"));
196         else if (name.equalsIgnoreCase("style_hint"))
197             setStyleHint(value);
198         else if (name.equalsIgnoreCase("annotate_link_fields"))
199             setAnnotateLinkFields(value.equalsIgnoreCase("true"));
200         else
201             throw new RuntimeException JavaDoc("Unrecognized option: " + name);
202     }
203
204     public void setOptions(Map JavaDoc options) {
205         if (options.size() == 0)
206             return;
207
208         Iterator JavaDoc optionsIt = options.entrySet().iterator();
209         while (optionsIt.hasNext()) {
210             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)optionsIt.next();
211             String JavaDoc name = (String JavaDoc)entry.getKey();
212             String JavaDoc value = (String JavaDoc)entry.getValue();
213             setOption(name, value);
214         }
215     }
216
217     /**
218      * Merges the where clause of this query with the given condition using the AND operator.
219      */

220     public void mergeCondition(PredicateExpr predicateExpr) {
221         And and = new And();
222         and.add(whereClause);
223         and.add(predicateExpr);
224         this.whereClause = and;
225     }
226 }
227
Popular Tags