KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > mediator > runtime > MediatorStatement


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.runtime;
24
25 import java.io.PrintStream JavaDoc;
26 import java.io.StringReader JavaDoc;
27 import java.util.*;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.xquark.mediator.algebra.AlgebraManager;
32 import org.xquark.mediator.decomposer.Utils;
33 import org.xquark.mediator.plan.ExecutionPlan;
34 import org.xquark.mediator.plan.OpSource;
35 import org.xquark.xml.xdbc.*;
36 import org.xquark.xquery.metadata.MetaDataImpl;
37 import org.xquark.xquery.metadata.VarCounter;
38 import org.xquark.xquery.normalize.TransformXQueryExpression;
39 import org.xquark.xquery.parser.*;
40 import org.xquark.xquery.typing.TypeVisitor;
41 import org.xquark.xquery.xdbc.XDBCResultSetInterface;
42
43 /**
44  * This class implements XMLStatement interface that is used for executing
45  * constant XQuery or XPath statements
46  * and obtaining the results produced (update statements are not
47  * supported yet).<BR>
48  *
49  */

50 public class MediatorStatement implements XMLStatement {
51     // **********************************************************************
52
// * VERSIONING
53
// **********************************************************************
54
private static final String JavaDoc RCSRevision = "$Revision: 1.14 $";
55     private static final String JavaDoc RCSName = "$Name: $";
56
57     private static Log log = LogFactory.getLog(MediatorStatement.class);
58
59     // **********************************************************************
60
// * CLASS VARIABLE
61
// **********************************************************************
62

63     private _MediatorConnection connection = null;
64     private boolean qaOnly = false;
65     HashMap preparedStatemements = new HashMap();
66     XMLResultSet currentResultSet = null;
67
68     //public XDBCResultSetInterface debug_resultset = null ;
69
//public XQueryExpression debug_qmem = null ;
70
private String JavaDoc baseURI = null;
71     protected boolean isClosed = false;
72
73     // ************************************************************************
74
// * INITIALISATION
75
// ************************************************************************
76
public MediatorStatement(_MediatorConnection connection) throws XMLDBCException {
77         this.connection = connection;
78     }
79
80     public HashMap getVariables() {
81         return null;
82     }
83
84     // ************************************************************************
85
// * XMLStatement IMPLEMENTATION
86
// ************************************************************************
87

88     /*********************************************************************/
89     /*************************** Queries execution management ************/
90     /*********************************************************************/
91     /**
92      * Executes a query statement of the type specified when this
93      * object was built with the createStatement method (see XMLConnection interface)
94      * that may return results.
95      * If the query generates results, use the <I>getResultSet()</I> or
96      * <I>getDocumentSet()</I> methods to get the set of results.
97      * @param query the query string.
98      * @return true if there are available resuts, else false.
99      * @throws XMLDBCException if a data source access error occurs.
100      */

101     public boolean execute(String JavaDoc query) throws XMLDBCException {
102         if (currentResultSet != null) {
103             currentResultSet.close();
104         }
105         currentResultSet = executeQuery(query);
106         return true;
107     }
108
109     /**
110      * Executes a query statement of the specified type
111      * that may return results.
112      * If the query generates results, use the <I>getResultSet()</I> or
113      * <I>getDocumentSet()</I> methods to get the set of results.
114      * @param query the query string.
115      * @param queryType the type of query for this statement (see constants in XMLConnection interface).
116      * @return true if there are available resuts, else false.
117      * @throws XMLDBCException if a data source access error occurs.
118      */

119     public boolean execute(String JavaDoc query, int queryType) throws XMLDBCException {
120         return execute(query);
121     }
122
123     /**
124      * Executes a query statement of the type specified when this
125      * object was built with the createStatement method (see XMLConnection interface)
126      * that returns results.
127      * @param query the query string
128      * @return an XMLResultSet object that contains the data produced by the given query.
129      * @throws XMLDBCException if a data source access error occurs.
130      */

131     public XMLResultSet executeQuery(String JavaDoc query) throws XMLDBCException {
132         try {
133             ExecutionPlan plan = compileXQuery(query, baseURI);
134             if (!preparedStatemements.isEmpty()) {
135                 closePreparedStatements();
136             }
137             if (currentResultSet != null) {
138                 currentResultSet.close();
139             }
140             currentResultSet = plan.executeQuery(this);
141             return currentResultSet;
142         } catch (XQueryException e) {
143             throw new XMLDBCException("MediatorStatement.executeQuery : " + e.getMessage(), e);
144         }
145     }
146     // for regression purposes -> printing the plan
147
private PrintStream JavaDoc plnout = null;
148     public XMLResultSet executeQuery(String JavaDoc query, PrintStream JavaDoc plnout) throws XMLDBCException {
149         this.plnout = plnout;
150         return executeQuery(query, XMLConnection.XQUERY_STRING_TYPE);
151     }
152
153     protected ExecutionPlan compileXQuery(String JavaDoc query, String JavaDoc baseURI) throws XMLDBCException {
154         try {
155             XQueryParser ql = new XQueryParser(new StringReader JavaDoc(query));
156             ql.setBaseURI(baseURI);
157             ql.setFactory("org.xquark.xquery.parser.ParserFactory");
158             MetaDataImpl metadata = connection.getMetadataAccess();
159
160             XQueryModule module = ql.Start(metadata, metadata.getSchemaManager(), metadata.getModuleManager(), new VarCounter(), qaOnly);
161             ArrayList expressions = module.getExpressions();
162             if (expressions == null || expressions.isEmpty())
163                 return null;
164             TypeVisitor typevisitor = ql.getTypeVisitor();
165
166             // get declarations
167

168             // if only one source is concerned, no need to bother about mediating, just pipeline requests to it.
169
// but first normalize and restructure
170
//----------------------------------------------------------
171
// START --> FOR SINGLE SOURCE VERIFICATION
172
//----------------------------------------------------------
173
// comment this bloc if you want the mediator not to overpass single source optimization (for debugging on a simple example)
174

175             module.normalize(typevisitor, connection.getSourceName());
176             // TODO handle several expressions with union !!!
177
if (expressions.size() > 1) {
178                 throw new XMLDBCException("Fusion only handles modules with a single query (for now...)");
179             }
180             for (int j = 0; j < expressions.size(); j++) {
181                 XQueryExpression exprj = (XQueryExpression) expressions.get(j);
182                 Utils.fillSources(exprj, metadata, true);
183             }
184
185             Set sources = module.getSourceNames();
186             Set urls = module.getUrls();
187             String JavaDoc xQueryStringImports = null;
188             if (!qaOnly && sources != null && sources.size() == 1 && (urls == null || urls.isEmpty())) {
189                 xQueryStringImports = module.toString(false, true);
190             }
191
192             //----------------------------------------------------------
193
// STOP --> FOR SINGLE SOURCE VERIFICATION
194
//----------------------------------------------------------
195

196             // !!!!!! danger, only one expression ....
197
ExecutionPlan plan = null;
198             //for (int j = 0; j < expressions.size(); j++) {
199
XQueryExpression exprj = (XQueryExpression) expressions.get(0);
200             String JavaDoc xQueryString = module.toString(false, false);
201
202             TransformXQueryExpression txe = exprj.getParentModule().canonize(exprj, typevisitor);
203             plan = new ExecutionPlan(metadata, typevisitor, txe.getIdVarList(), xQueryStringImports, xQueryString, module, baseURI, qaOnly);
204
205             AlgebraManager depmanager = new AlgebraManager(plan, metadata, typevisitor, txe.getQMEM(), txe.getQDB(), txe.getIdVarList());
206
207             ArrayList qdbs = txe.getQDB();
208
209             if (log.isDebugEnabled()) {
210                 for (int si = 0; si < qdbs.size(); si++)
211                     log.debug("QDB[" + si + "]: " + ((Variable) qdbs.get(si)).getExpression());
212                 log.debug("QMEM: " + txe.getQMEM());
213             }
214
215             XDBCResultSetInterface resultset = null;
216             if (!qdbs.isEmpty()) {
217                 depmanager.generate();
218                 depmanager.computeVarPaths();
219                 if (log.isDebugEnabled()) {
220                     log.debug("Algebra Tree: " + depmanager);
221                 }
222                 depmanager.FillPlan();
223                 if (log.isDebugEnabled()) {
224                     log.info("Execution Tree: " + plan);
225                 }
226                 if (plnout != null) {
227                     plnout.print(plan.toString());
228                 }
229             }
230             plan.setQMEM(txe.getQMEM());
231             if (!module.getExternalVariables().isEmpty() && plan.getRoot() != null)
232                 plan.getRoot().setPrepared();
233
234             //}
235
return plan;
236         } catch (XQueryException xe) {
237             throw new XMLDBCException(xe.getMessage(), xe);
238         } catch (ParseException xe) {
239             throw new XMLDBCException(xe.getMessage(), xe);
240         }
241
242     }
243     /**
244      * Executes a query statement of the specified type
245      * that returns results.
246      * If the query generates results, use the <I>getResultSet()</I> or
247      * <I>getDocumentSet()</I> methods to get the set of results.
248      * @param query the query string.
249      * @param queryType the type of query for this statement (see constants in XMLConnection interface).
250      * @return true if there are available resuts, else false.
251      * @throws XMLDBCException if a data source access error occurs.
252      */

253     public XMLResultSet executeQuery(String JavaDoc query, int queryType) throws XMLDBCException {
254         return executeQuery(query);
255     }
256
257     /**
258      * Executes a query statement of the type specified when this
259      * object was built with the createStatement method (see XMLConnection interface)
260      * that returns complete XML documents. It is a error to call this method with a
261      * query that returns document fragments.
262      * @param query a static and read-only query in the specified type.
263      * @return an XMLResultSet object that contains the data produced by the given query.
264      * @throws XMLDBCException if a data source access error occurs, or if the returned
265      * results are not complete XML documents.
266      */

267     public XMLDocumentSet executeDocumentQuery(String JavaDoc query) throws XMLDBCException {
268         throw new XMLDBCNotSupportedException("Not yet implemented.");
269     }
270
271     /*********************************************************************/
272     /*************************** Results management **********************/
273     /*********************************************************************/
274
275     /**
276      * Returns the current statement results as an XMLResultSet object.
277      * @return the current results as an XMLResultSet object or null if there is no result.
278      * @throws XMLDBCException if a data source access error occurs.
279      */

280     public XMLResultSet getResultSet() throws XMLDBCException {
281         throw new XMLDBCNotSupportedException("Not yet implemented.");
282     }
283
284     /**
285      * Returns the current statement results as an XMLDocumentSet object.
286      * It is a error to call this method for a statement that returned
287      * document fragments.
288      * @return the current results as an XMLDocumentSet object or null if there is no result.
289      * @throws XMLDBCException if a data source access error occurs, or if the returned
290      * results are not complete XML documents.
291      */

292     public XMLDocumentSet getDocumentSet() throws XMLDBCException {
293         throw new XMLDBCNotSupportedException("Not yet implemented.");
294     }
295
296     /*********************************************************************/
297     /*************************** Statement management ********************/
298     /*********************************************************************/
299
300     /**
301      * Returns the connection object that produced this statement.
302      * @return the connection object that produced this statement.
303      */

304     public XMLConnection getConnection() {
305         return connection.getConnection();
306     }
307
308     public _MediatorConnection getMediatorConnection() {
309         return connection;
310     }
311
312     /**
313      * Releases the statement XMLDBC resources immediately instead of waiting for this
314      * to happen when it is automatically closed.
315      * @throws XMLDBCException if a data source access error occurs.
316      */

317     public void close() throws XMLDBCException {
318         if (!isClosed) {
319             if (currentResultSet != null) {
320                 try {
321                     currentResultSet.close();
322                 } catch (XMLDBCException xe) {
323                 }
324                 currentResultSet = null;
325             }
326             connection.statementClosed(this);
327             isClosed = true;
328         }
329     }
330
331     public boolean isClosed() throws XMLDBCException {
332         return isClosed;
333     }
334
335     public void setBaseURI(String JavaDoc baseURI) {
336         this.baseURI = baseURI;
337     }
338
339     public String JavaDoc getBaseURI() {
340         return baseURI;
341     }
342
343     public void setQAOnly(boolean bool) {
344         qaOnly = bool;
345     }
346
347     public void closePreparedStatements() throws XMLDBCException {
348         for (Iterator it = preparedStatemements.values().iterator(); it.hasNext();) {
349             PreparedXMLStatement stat = (PreparedXMLStatement) it.next();
350             if (stat != null)
351                 stat.close();
352         }
353         preparedStatemements.clear();
354     }
355
356     public PreparedXMLStatement getPreparedXMLStatement(OpSource opSource, String JavaDoc sourceName, String JavaDoc requestStr) throws XMLDBCException {
357         //if (true) return null;
358
PreparedXMLStatement stat = (PreparedXMLStatement) preparedStatemements.get(opSource);
359         if (!preparedStatemements.containsKey(opSource)) {
360             XMLConnection xmlConnection = null;
361             try {
362                 xmlConnection = connection.getSubConnectionByName(sourceName);
363             } catch (MediatorException me) {
364                 throw new XMLDBCException(me.getMessage(), me);
365             }
366             try {
367                 stat = xmlConnection.prepareStatement(requestStr);
368             } catch (XMLDBCNotSupportedException xe) {
369                 stat = null;
370             }
371             preparedStatemements.put(opSource, stat);
372         }
373         return stat;
374     }
375 }
376
Popular Tags