KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > search > basic > BasicQueryImpl


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/search/basic/BasicQueryImpl.java,v 1.16 2004/07/28 09:35:02 ib Exp $
3  * $Revision: 1.16 $
4  * $Date: 2004/07/28 09:35:02 $
5  *
6  * ====================================================================
7  *
8  * Copyright 1999-2002 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24 package org.apache.slide.search.basic;
25
26 import java.util.List JavaDoc;
27
28 import org.apache.slide.common.PropertyParseException;
29 import org.apache.slide.common.RequestedProperties;
30 import org.apache.slide.common.RequestedPropertiesImpl;
31 import org.apache.slide.common.ServiceAccessException;
32 import org.apache.slide.common.Uri;
33 import org.apache.slide.search.BadQueryException;
34 import org.apache.slide.search.InvalidQueryException;
35 import org.apache.slide.search.InvalidScopeException;
36 import org.apache.slide.search.PropertyProvider;
37 import org.apache.slide.search.QueryScope;
38 import org.apache.slide.search.SearchException;
39 import org.apache.slide.search.SearchQueryResult;
40 import org.apache.slide.search.SearchToken;
41 import org.apache.slide.store.AbstractStore;
42 import org.jdom.Element;
43 import org.jdom.Namespace;
44
45 /**
46  * BasicQueryImpl represents the generic (store independent) implementation of
47  * BasicSearch.
48  *
49  * @version $Revision: 1.16 $
50  */

51 public class BasicQueryImpl extends BasicQuery implements IBasicQuery {
52
53     /**
54      * Message of a BadQueryException that is thrown if the query element
55      * is <code>null</code>.
56      */

57         
58     public static final String JavaDoc NO_QUERY_ELEMENT = "No query element";
59
60     /**
61      * Message of a BadQueryException that is thrown if the query element
62      * does not contain a &lt;from&gt; element.
63      */

64     public static final String JavaDoc FROM_ELEMENT_MISSING = "Required element <from> not supplied";
65
66     /**
67      * Message of a BadQueryException that is thrown if the query element
68      * does not contain a &lt;select&gt; element.
69      */

70     public static final String JavaDoc SELECT_ELEMENT_MISSING = "Required element <select> not supplied";
71
72     /**
73      * Message of a BadQueryException that is thrown if the query element
74      * neither contains a &lt;prop&gt; nor a &lt;allprop&gt; element.
75      */

76     public static final String JavaDoc PROP_OR_ALLPROP_ELEMENT_MISSING = "Required element <prop> or <allprop> not supplied";
77
78     /**
79      * Message of a BadQueryException that is thrown if the query element
80      * contains a &lt;limit&gt; element but no &lt;nresults&gt; element.
81      */

82     public static final String JavaDoc NRESULTS_MISSING = "Required element <nresults> (when limit is supplied) not supplied";
83
84     /**
85      * Message of a BadQueryException that is thrown if the &lt;nresults&gt; element
86      * is not an integer.
87      */

88     public static final String JavaDoc NRESULTS_MUST_BE_AN_INTEGER = "<nresults> should be an integer";
89
90     /** the NotNormalizer, may be overridden in extending classes */
91     protected NotNormalizer notNormalizer;
92
93 // IBasicExpressionFactory defaultExpressionFactory = new BasicExpressionFactory ();
94

95     /**
96      * Creates a BasicQueryImpl.
97      */

98     public BasicQueryImpl (SearchToken searchToken) {
99         super.init (searchToken);
100         notNormalizer = new NotNormalizer ();
101     }
102
103     /**
104      * Default constructor, to enable creation by reflection
105      */

106     public BasicQueryImpl() {
107         notNormalizer = new NotNormalizer ();
108     }
109
110     /**
111      * Creates a BasicQueryImpl. Used for testing
112      *
113      * @param expressionCompilerProvider the provider which delivers the
114      * expression compiler to use.
115      */

116     public BasicQueryImpl(SearchToken searchToken, IBasicExpressionCompilerProvider expressionCompilerProvider) {
117         init (searchToken);
118         this.expressionCompilerProvider = expressionCompilerProvider;
119     }
120
121     /**
122      * Executes a request.
123      *
124      * @return a SearchQueryResult
125      *
126      * @throws ServiceAccessException
127      *
128      */

129     public SearchQueryResult execute () throws ServiceAccessException {
130         SearchQueryResult result = null;
131
132         try {
133
134             IBasicResultSet resultSet = getExpression().execute();
135
136             if (orderBy != null) {
137                 if (isLimitDefined()) {
138                     result = new SearchQueryResult (resultSet,
139                                                     orderBy.getComparator(),
140                                                     limit);
141                 }
142                 else {
143                     result = new SearchQueryResult (resultSet,
144                                                     orderBy.getComparator());
145                 }
146
147             }
148             else {
149                 result = new SearchQueryResult (resultSet);
150             }
151             if (resultSet.isPartialResultSet()) {
152                 result.setStatus(SearchQueryResult.STATUS_PARTIAL_RESULT);
153                 result.setDescription ("The server truncated the result set");
154             }
155         }
156
157         catch (InvalidScopeException e) {
158             result = new SearchQueryResult ();
159             result.setStatus (SearchQueryResult.STATUS_INVALID_SCOPE);
160             result.setHref (queryScope.getHref());
161         }
162
163         catch (BadQueryException e) { // is this only INVALID_SCOPE?
164
result = new SearchQueryResult ();
165             result.setStatus (SearchQueryResult.STATUS_BAD_QUERY);
166             result.setDescription (e.getMessage());
167             result.setHref (queryScope.getHref());
168         }
169
170         catch (SearchException e) { // is this only INVALID_SCOPE?
171
result = new SearchQueryResult ();
172             result.setStatus (SearchQueryResult.STATUS_BAD_QUERY);
173             result.setDescription (e.getMessage());
174             result.setHref (queryScope.getHref());
175         }
176
177         return result;
178     }
179
180     /**
181      * builds the internal structure from the JDOM tree
182      *
183      * @param expressionElement the (root) expression Element.
184      * @param propertyProvider the PropertyProvider to use (may be
185      * <code>null</code>).
186      *
187      * @throws BadQueryException
188      */

189     public void parseQuery(Element expressionElement, PropertyProvider propertyProvider)
190         throws BadQueryException {
191
192         parseQueryWithoutExpression (expressionElement);
193         IBasicExpressionCompiler expressionCompiler = expressionCompilerProvider.getCompiler(this, propertyProvider);
194
195         // <where> is not mandatory
196
if (whereElement != null) {
197             List JavaDoc expressionList = whereElement.getChildren();
198             if (expressionList.size() != 1) {
199                 throw new BadQueryException ("where must have exactly one nested element");
200             }
201
202             Element whereWithoutNot =
203                 notNormalizer.getQueryWithoutNotExpression((Element)expressionList.get (0));
204             rootExpression = expressionCompiler.compile(whereWithoutNot);
205         }
206         else {
207             rootExpression = expressionCompiler.compile(null);
208         }
209     }
210
211     /**
212      * Method getSelectedProperties
213      *
214      * @return a SelectedPropertyList
215      */

216     public RequestedProperties requestedProperties () {
217         return requestedProperties;
218     }
219
220
221     /**
222      * Builds the internal structure from the JDOM tree. Concrete implementations
223      * may use parseQueryElementWithoutExpression to create most of the
224      * objects describing the query.
225      *
226      * @param basicSearchElement the (root) expression Element.
227      * @param propertyProvider the PropertyProvider to use (may be
228      * <code>null</code>).
229      *
230      * @throws BadQueryException
231      */

232     public void parseQueryElement (Element basicSearchElement,
233                                    PropertyProvider propertyProvider)
234
235         throws BadQueryException {
236         this.parseQueryElement (basicSearchElement,
237                                 propertyProvider,
238                                 getScope(basicSearchElement));
239     }
240
241     /**
242      * Builds the internal structure from the JDOM tree. Concrete implementations
243      * may use parseQueryElementWithoutExpression to create most of the
244      * objects describing the query.
245      *
246      * @param basicSearchElement the (root) expression Element.
247      * @param propertyProvider the PropertyProvider to use (may be
248      * <code>null</code>).
249      *
250      * @throws BadQueryException
251      */

252     public void parseQueryElement (Element basicSearchElement,
253                                    PropertyProvider propertyProvider,
254                                    QueryScope queryScope)
255
256         throws BadQueryException {
257         this.queryScope = queryScope;
258         this.propertyProvider = propertyProvider;
259
260         // might be null in testsuite
261
if (searchToken.getNamespace() != null) {
262             // Uri uri = new Uri (searchToken.getNamespace(), slideUri.getSlidePath(queryScope.getHref()));
263
Uri uri = searchToken.getNamespace().getUri(this.getSearchToken().getSlideToken(), slideUri.getSlidePath(queryScope.getHref()));
264             store = (AbstractStore)uri.getStore();
265         }
266
267         parseQuery(basicSearchElement, propertyProvider);
268     }
269
270
271
272 // TODO: move to BasicSearchLanguage
273
/**
274      * Needed to decide, which implementation of BasicQuery to load
275      *
276      * @param basicSearchElementJDOM an Element
277      *
278      * @return a QueryScope
279      *
280      * @throws BadQueryException
281      *
282      */

283     public static QueryScope getScope(Element basicSearchElementJDOM)
284         throws BadQueryException {
285         if (basicSearchElementJDOM == null)
286             throw new BadQueryException (NO_QUERY_ELEMENT);
287
288         Namespace namespace = basicSearchElementJDOM.getNamespace();
289         Element fromElement = basicSearchElementJDOM.getChild
290             (Literals.FROM, namespace);
291
292         // FROM is mandatory
293
if (fromElement == null)
294             throw new BadQueryException (FROM_ELEMENT_MISSING);
295
296         return new BasicQueryScope (fromElement);
297     }
298
299     /**
300      * builds the internal structure from the JDOM tree. It may be used by the
301      * concrete implementation of BasicQuery. It does NOT create the tree of
302      * Expressions. This must be done in the specific implementation.
303      *
304      * @param basicSearchElement an Element
305      *
306      * @throws BadQueryException
307      */

308     protected void parseQueryWithoutExpression (Element basicSearchElement)
309         throws BadQueryException {
310
311         if (basicSearchElement == null)
312             throw new BadQueryException (NO_QUERY_ELEMENT);
313
314         namespace = basicSearchElement.getNamespace();
315
316         Element selectElement = basicSearchElement.getChild
317             (Literals.SELECT, namespace);
318
319         // SELECT is mandatory
320
if (selectElement == null)
321             throw new BadQueryException (SELECT_ELEMENT_MISSING);
322
323         Element fromElement = basicSearchElement.getChild
324             (Literals.FROM, namespace);
325
326         // FROM is mandatory
327
if (fromElement == null) {
328             throw new BadQueryException (FROM_ELEMENT_MISSING);
329         }
330
331         whereElement = basicSearchElement.getChild
332             (Literals.WHERE, namespace);
333
334         Element orderByElement = basicSearchElement.getChild
335             (Literals.ORDERBY, namespace);
336
337         Element limitElement = basicSearchElement.getChild
338             (Literals.LIMIT, namespace);
339
340         Element propElement = selectElement.getChild (Literals.PROP, namespace);
341         if (propElement == null) {
342             propElement = selectElement.getChild (Literals.ALLPROP, namespace);
343         }
344
345         if (propElement == null) {
346             throw new BadQueryException(PROP_OR_ALLPROP_ELEMENT_MISSING);
347         }
348
349         requestedProperties = createRequestedProperties (propElement);
350
351         //queryScope = new BasicQueryScope (fromElement);
352

353         if (orderByElement != null) {
354             orderBy = createNewOrderBy (orderByElement);
355         }
356
357         if (limitElement != null) {
358             Element nResElem = limitElement.getChild (Literals.NRESULTS, namespace);
359             if (nResElem == null)
360                 throw new BadQueryException (NRESULTS_MISSING);
361             try {
362                 limit = new Integer JavaDoc (nResElem.getTextTrim()).intValue();
363             }
364             catch (NumberFormatException JavaDoc e) {
365                 throw new BadQueryException(NRESULTS_MUST_BE_AN_INTEGER);
366             }
367             limitDefined = true;
368         }
369     }
370
371     protected OrderBy createNewOrderBy (Element orderByElement) throws InvalidQueryException {
372         OrderBy result = new OrderBy ();
373         result.init(orderByElement);
374         return result;
375     }
376
377
378
379
380     /**
381      * This method may be overridden, if a store specific implementation adds
382      * new property semantic.
383      *
384      * @param propElement an Element
385      *
386      * @return a RequestedProperties
387      *
388      */

389     protected RequestedProperties createRequestedProperties (Element propElement) throws BadQueryException {
390         try {
391             return new RequestedPropertiesImpl (propElement);
392         }
393         catch (PropertyParseException e) {
394             throw new BadQueryException (e.getMessage(), e);
395         }
396     }
397 }
398
399
Popular Tags