KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > mediator > plan > ResultSet


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.mediator.plan;
24
25 import java.util.ArrayList JavaDoc;
26
27 import org.xml.sax.ContentHandler JavaDoc;
28 import org.xquark.mediator.DOMUtils.*;
29 import org.xquark.mediator.runtime.MediatorException;
30 import org.xquark.schema.validation.PSVInfoSetProvider;
31 import org.xquark.xml.xdbc.XMLDBCException;
32 import org.xquark.xquery.parser.Step;
33 import org.xquark.xquery.parser.XQueryException;
34 import org.xquark.xquery.parser.XQueryExpression;
35 import org.xquark.xquery.typing.QAtomicSerializer;
36
37 public abstract class ResultSet {
38     // **********************************************************************
39
// * VERSIONING
40
// **********************************************************************
41
private static final String JavaDoc RCSRevision = "$Revision: 1.16 $";
42     private static final String JavaDoc RCSName = "$Name: $";
43     // **********************************************************************
44
// * CLASS VARIABLES
45
// **********************************************************************
46
protected TypedDOMReader dom2sax = null;
47     protected QAtomicSerializer ser = null;
48
49     protected XQueryExpression expression = null;
50     protected Operator operator;
51     private boolean first_time = true;
52     private boolean finished_when_empty = false;
53
54     protected BufferTuple buftuples = null;
55     private Tuple cur_tuple = null;
56     private Tuple next_tuple = null;
57     protected ArrayList JavaDoc paths;
58
59     protected DynamicContext context = null;
60     
61     // ***********************************************************************
62
// * INITIALIZATION
63
// ***********************************************************************
64
/**
65      *
66      */

67     public ResultSet(Operator operator, DynamicContext context) {
68         this.operator = operator;
69         this.context = context;
70         dom2sax = new TypedDOMReader();
71         ser = new QAtomicSerializer();
72         dom2sax.setQAtomicSerializer(ser);
73         init(operator);
74     }
75
76     public void init(Operator operator) {
77         if (operator != null) {
78             expression = operator.getExpression();
79             paths = operator.getPaths();
80             buftuples = new BufferTuple(paths, operator.getIdSize());
81             buftuples.setIndexesSpec(operator.getIndexesSpec());
82         }
83     }
84
85     protected void generateTuple() throws MediatorException {
86         // if the buffer is not empty, use it before generating the next elements
87
if (!buftuples.isEmpty())
88             return;
89
90         // a LET is a blocking case.
91
evaluate(!operator.isLet());
92     }
93
94     /**
95      * Fill the buffer buftuples with tuple.
96      *
97      * @param non_blocking if the evaluation is blocking, we must
98      * generate all the results before passing.
99      */

100     protected abstract void evaluate(boolean non_blocking) throws MediatorException;
101
102     protected void setFinishedWhenEmpty() throws MediatorException {
103         this.finished_when_empty = true;
104     }
105
106     public Operator getOperator() {
107         return operator;
108     }
109
110     public SortedKeyMap getIndex(int index) {
111         return buftuples.getIndex(index);
112     }
113
114     /**
115      * Give the new current result set (the next one).
116      * @return true if the new current result set is valid, false otherwise
117      * @throws XDBCException if a database access error occurs.
118      */

119     public Tuple next() throws MediatorException {
120         if (next_tuple != null) {
121             cur_tuple = next_tuple;
122             next_tuple = null;
123             return cur_tuple;
124         }
125
126         if (first_time) {
127             hasNext();
128             if (buftuples.isEmpty())
129                 throw new MediatorException("No more results");
130         }
131
132         // CHANGE 04/02/2003
133
if (buftuples.isEmpty()) {
134             generateTuple();
135             if (buftuples.isEmpty())
136                 throw new MediatorException("No more results");
137         }
138
139         if (!buftuples.isEmpty()) {
140             cur_tuple = (Tuple) buftuples.remove(0);
141             return cur_tuple;
142         }
143
144         return cur_tuple;
145     }
146
147     /**
148      * Returns true if the result set has more elements.
149      * @return true if the result set has more elements, false otherwise
150      */

151     public boolean hasNext() throws MediatorException {
152
153         if (next_tuple != null)
154             return true;
155
156         if (first_time) {
157             generateTuple();
158             first_time = false;
159         }
160
161         if ((finished_when_empty) && (buftuples == null || buftuples.isEmpty()))
162             return false;
163
164         if (buftuples.isEmpty())
165             generateTuple();
166
167         return (!((finished_when_empty) && (buftuples == null || buftuples.isEmpty())));
168     }
169
170     /**
171      * Releases this result set object's resources immediately instead of waiting
172      * for this to happen when it is automatically closed.<BR>
173      * <B>Note:</B> A XResultSet object is automatically closed by the XStatement
174      * object that generated it when that XStatement object is closed,
175      * re-executed, or is used to retrieve the next result from a sequence of
176      * multiple results.
177      * @throws XMLDBCException if a data source access error occurs.
178      */

179     public void close() throws MediatorException {
180         buftuples = null;
181     }
182
183     /**
184      * Return the value of the element specified by the path.
185      * @param path
186      * @param nodeAccessor
187      * @param loopID the ID of the loop concerned if any
188      * @return value of the element
189      * @throws XDBCException if a database access error occurs.
190      */

191     public String JavaDoc fetch(String JavaDoc path, int nodeAccessor, String JavaDoc loopID, PSVInfoSetProvider psvisp) throws XMLDBCException {
192         String JavaDoc alias = path;
193         while ((alias = operator.getPlan().getAlias(path)) != null) {
194             path = alias;
195         }
196         //if (alias != null) path = alias;
197
int pos = buftuples.getPos(path);
198         if (pos != -1)
199             return cur_tuple.makeStringPath(pos, ser);
200         switch (nodeAccessor) {
201             case Step.CHILD_TEXT :
202             //case XDBCResultSetInterface.NODE_ACCESSOR_TEXT :
203
pos = buftuples.getPos(path + "/child::text()");
204                 break;
205                 /*
206                 case XDBCResultSetInterface.NODE_ACCESSOR_PROCESSING_INSTRUCTION : break;
207                 case XDBCResultSetInterface.NODE_ACCESSOR_COMMENT : break;
208                 */

209             case Step.CHILD_NODE :
210             //case XDBCResultSetInterface.NODE_ACCESSOR_NODE :
211
pos = buftuples.getPos(path + "/child::node()");
212                 break;
213                 /*
214                 case XDBCResultSetInterface.NODE_ACCESSOR_NAME : break;
215                 case XDBCResultSetInterface.NODE_ACCESSOR_LOCAL_NAME : break;
216                 case XDBCResultSetInterface.NODE_ACCESSOR_NAMESPACE_URI : break;
217                 case XDBCResultSetInterface.NODE_ACCESSOR_PARENT : break;
218                 case XDBCResultSetInterface.NODE_ACCESSOR_STRING_VALUE : break;
219                 case XDBCResultSetInterface.NODE_ACCESSOR_BASE_URI : break;
220                 case XDBCResultSetInterface.NODE_ACCESSOR_CHILDREN : break;
221                 case XDBCResultSetInterface.NODE_ACCESSOR_NAMESPACES : break;
222                 case XDBCResultSetInterface.NODE_ACCESSOR_ATTRIBUTES : break;
223                 case XDBCResultSetInterface.NODE_ACCESSOR_DECLARATION : break;
224                 case XDBCResultSetInterface.NODE_ACCESSOR_TYPE : break;
225                 case XDBCResultSetInterface.NODE_ACCESSOR_TYPE_VALUE : break;
226                 case XDBCResultSetInterface.NODE_ACCESSOR_PREFIX : break;
227                 case XDBCResultSetInterface.NODE_ACCESSOR_URI : break;
228                 */

229             case Step.SELF_TEXT :
230             //case XDBCResultSetInterface.NODE_ACCESSOR_SELF_TEXT :
231
pos = buftuples.getPos(path + "/self::text()");
232                 break;
233             case Step.SELF_NODE :
234             //case XDBCResultSetInterface.NODE_ACCESSOR_SELF_NODE :
235
pos = buftuples.getPos(path + "/self::node()");
236                 break;
237         }
238         if (pos == -1)
239             pos = buftuples.getPos(path);
240         if (pos == -1)
241             throw new XMLDBCException("No column " + path + " in tuple.");
242         return cur_tuple.makeStringPath(pos, ser);
243         //throw new XMLDBCException("Shouldn't be called: a tree can't be cast to a String") ;
244
}
245
246     /**
247      * Generate the value of the result set specified by the path in the handler.
248      * @param path
249      * @param nodeAccessor the type of node to be generated
250      * @param loopID the ID of the loop concerned if any
251      * @throws XDBCException if a database access error occurs.
252      */

253     public void generate(ContentHandler JavaDoc handler, String JavaDoc path, int nodeAccessor, String JavaDoc loopID, PSVInfoSetProvider psvisp) throws XMLDBCException {
254         String JavaDoc alias = path;
255         while ((alias = operator.getPlan().getAlias(path)) != null) {
256             path = alias;
257         }
258         //if (alias != null) path = alias;
259
int pos = -1;
260         switch (nodeAccessor) {
261             case Step.CHILD_TEXT :
262             //case XDBCResultSetInterface.NODE_ACCESSOR_TEXT :
263
pos = buftuples.getPos(path + "/child::text()");
264                 break;
265                 /*
266                 case XDBCResultSetInterface.NODE_ACCESSOR_PROCESSING_INSTRUCTION : break;
267                 case XDBCResultSetInterface.NODE_ACCESSOR_COMMENT : break;
268                 */

269             case Step.CHILD_NODE :
270             //case XDBCResultSetInterface.NODE_ACCESSOR_NODE :
271
pos = buftuples.getPos(path + "/child::node()");
272                 break;
273                 /*
274                 case XDBCResultSetInterface.NODE_ACCESSOR_NAME : break;
275                 case XDBCResultSetInterface.NODE_ACCESSOR_LOCAL_NAME : break;
276                 case XDBCResultSetInterface.NODE_ACCESSOR_NAMESPACE_URI : break;
277                 case XDBCResultSetInterface.NODE_ACCESSOR_PARENT : break;
278                 case XDBCResultSetInterface.NODE_ACCESSOR_STRING_VALUE : break;
279                 case XDBCResultSetInterface.NODE_ACCESSOR_BASE_URI : break;
280                 case XDBCResultSetInterface.NODE_ACCESSOR_CHILDREN : break;
281                 case XDBCResultSetInterface.NODE_ACCESSOR_NAMESPACES : break;
282                 case XDBCResultSetInterface.NODE_ACCESSOR_ATTRIBUTES : break;
283                 case XDBCResultSetInterface.NODE_ACCESSOR_DECLARATION : break;
284                 case XDBCResultSetInterface.NODE_ACCESSOR_TYPE : break;
285                 case XDBCResultSetInterface.NODE_ACCESSOR_TYPE_VALUE : break;
286                 case XDBCResultSetInterface.NODE_ACCESSOR_PREFIX : break;
287                 case XDBCResultSetInterface.NODE_ACCESSOR_URI : break;
288                 */

289             case Step.SELF_TEXT :
290             //case XDBCResultSetInterface.NODE_ACCESSOR_SELF_TEXT :
291
pos = buftuples.getPos(path + "/self::text()");
292                 break;
293             case Step.SELF_NODE :
294             //case XDBCResultSetInterface.NODE_ACCESSOR_SELF_NODE :
295
pos = buftuples.getPos(path + "/self::node()");
296                 break;
297         }
298         if (pos == -1)
299             pos = buftuples.getPos(path);
300         if (pos == -1)
301             throw new XMLDBCException("No column " + path + " in tuple.");
302         try {
303             dom2sax.setPSVInfoSetProvider(psvisp);
304             cur_tuple.makeEventPath(dom2sax, handler, pos);
305         } catch (XQueryException e) {
306             throw new XMLDBCException(e.getMessage());
307         }
308     }
309
310     /**
311      * Recover the identifiers of the current result set and stores them in the table <I>identifiers</I>.
312      * @param identifiers the table of identifiers
313      * @throws XDBCException if a database access error occurs.
314      */

315     public void getIdentifiers(Object JavaDoc[] identifiers) {
316         if (cur_tuple == null)
317             return;
318         cur_tuple.getIdentifiers(identifiers);
319     }
320
321     /**
322      * Recover the identifiers of the next result set and stores them in the tab
323      * le <I>identifiers</I>.
324      * @param identifiers the table of identifiers
325      * @throws XDBCException if a database access error occurs.
326      */

327     public void getNextIdentifiers(Object JavaDoc[] identifiers) throws MediatorException {
328         // because 'getNextIdentifiers' is very special (comprendre
329
// very chiant). We must get identifier of next tuple, but keep
330
// the cursor on the current one.
331
// we solve this by using a "cache" tuple
332
if (next_tuple != null) {
333             next_tuple.getIdentifiers(identifiers);
334             return;
335         }
336         if (!hasNext()) {
337             next_tuple = null;
338             return;
339         }
340         Tuple old_tuple = cur_tuple;
341         next();
342         next_tuple = cur_tuple;
343         next_tuple.getIdentifiers(identifiers);
344         cur_tuple = old_tuple;
345     }
346 }
347
Popular Tags