KickJava   Java API By Example, From Geeks To Geeks.

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


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

12
13 package org.xquark.mediator.plan;
14
15 import java.util.ArrayList JavaDoc;
16
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.xml.sax.ErrorHandler JavaDoc;
20 import org.xml.sax.SAXException JavaDoc;
21 import org.xml.sax.SAXParseException JavaDoc;
22 import org.xquark.mediator.DOMUtils.GetUnknownPathsVisitor;
23 import org.xquark.mediator.DOMUtils.SAX2DOM;
24 import org.xquark.mediator.DOMUtils.Tuple;
25 import org.xquark.mediator.decomposer.Utils;
26 import org.xquark.mediator.runtime.MediatorException;
27 import org.xquark.schema.validation.PSVInfoSetProvider;
28 import org.xquark.schema.validation.SchemaValidationContext;
29 import org.xquark.schema.validation.ValidatingSchemaHandler;
30 import org.xquark.util.NamespaceContextStack;
31 import org.xquark.xml.xdbc.*;
32 import org.xquark.xquery.parser.*;
33 import org.xquark.xquery.typing.QType;
34
35 public class OpSource extends ZeroOp {
36     // **********************************************************************
37
// * VERSIONING
38
// **********************************************************************
39
private static final String JavaDoc RCSRevision = "$Revision: 1.51 $";
40
41     private static final String JavaDoc RCSName = "$Name: $";
42
43     // **********************************************************************
44
// * CLASS VARIABLES
45
// **********************************************************************
46
//private XMLConnection connection = null;
47
private PreparedXMLStatement preparedStatement = null;
48
49     private ArrayList JavaDoc externalVariables = null;
50
51     private String JavaDoc requestStr = null;
52
53     private String JavaDoc preparedRequestStr = null;
54
55     private String JavaDoc source = null;
56
57     private boolean cannotBePrepared = false;
58
59     // ***********************************************************************
60
// * INITIALIZATION
61
// ***********************************************************************
62
/**
63      *
64      */

65     public OpSource(ExecutionPlan plan, XQueryExpression expression, ArrayList JavaDoc origpaths, String JavaDoc source, boolean hasIdentifier) throws MediatorException {
66         super(plan, expression);
67         try {
68             for (int i = 0; i < origpaths.size(); i++) {
69                 addPath((XQueryExpression) ((XQueryExpression) origpaths.get(i)).clone());
70             }
71         } catch (CloneNotSupportedException JavaDoc cnse) {
72         }
73         //addPaths(origpaths);
74
this.source = source;
75         this.size = this.getPaths().size();
76         if (hasIdentifier)
77             this.idsize = 1;
78         if (source == null)
79             throw new MediatorException("AlgSource: no source !");
80         // creating if necessary and if possible prepared statement
81
createRequestString();
82         GetUnknownPathsVisitor gupv = new GetUnknownPathsVisitor(getSchemaManager(), getTypeVisitor());
83         try {
84             expression.accept(gupv);
85         } catch (XQueryException xqe) {
86             throw new MediatorException(xqe.getMessage());
87         }
88         externalVariables = gupv.getNewVariables();
89         // test if an external variable can be multivaluated
90
if (externalVariables != null)
91             for (int i = 0; i < externalVariables.size(); i++) {
92                 Variable vari = (Variable) externalVariables.get(i);
93                 QType qtypei = vari.getQType();
94                 if (qtypei.isMultiple()) {
95                     cannotBePrepared = true;
96                     break;
97                 }
98             }
99     }
100
101     // #############################################################################
102
// VISITOR STUFF
103
// #############################################################################
104

105     public void accept(OperatorVisitor visitor) throws MediatorException {
106         visitor.visit(this);
107     }
108
109     // ***********************************************************************
110
// * EXECUTE QUERY
111
// ***********************************************************************
112
/**
113      *
114      */

115     protected ResultSet getResultSet(DynamicContext context) throws MediatorException {
116         ResultSet resultset = null;
117         if (!cannotBePrepared)
118             if (preparedRequestStr != null) {
119                 try {
120                     preparedStatement = context.getPreparedXMLStatement(this, source, preparedRequestStr);
121                 } catch (XMLDBCException xe) {
122                     preparedRequestStr = null;
123                     preparedStatement = null;
124                     throw new MediatorException(xe.getMessage(), xe);
125                 }
126             }
127         if (preparedStatement != null)
128             resultset = new SourceResultSet(this, context, preparedStatement);
129         else {
130             XMLConnection connection = null;
131             connection = context.getConnection().getSubConnectionByName(source);
132             if (connection == null)
133                 throw new MediatorException("AlgSource: couldn't established connection to " + source);
134             resultset = new SourceResultSet(this, context, connection);
135         }
136         return resultset;
137     }
138
139     /**
140      * Return all the sources depending of this node.
141      */

142     public ArrayList JavaDoc getSources() {
143         if (sources == null) {
144             sources = new ArrayList JavaDoc();
145             sources.add(source);
146         }
147         return sources;
148     }
149
150     public String JavaDoc getSourceName() {
151         return source;
152     }
153
154     public void setPrepared() throws MediatorException {
155         if (!cannotBePrepared || prepared)
156             return;
157         // find in FLWRExpression (only in where clause) all expression that do not start with a variable of the FLWRExpression
158
StringBuffer JavaDoc sbvars = new StringBuffer JavaDoc();
159         sbvars.append(requestStr);
160         if (externalVariables != null && !externalVariables.isEmpty()) {
161             plan.appendExternalVariables(sbvars, externalVariables);
162             if (sbvars.length() == 0) {
163                 preparedStatement = null;
164                 prepared = false;
165                 return;
166             }
167         }
168         // TODO find a better way to modify prefixes of included modules
169
sbvars.append(expression.getStringValue(plan.getModule().getDeclarations()));
170         preparedRequestStr = sbvars.toString();
171         prepared = true;
172     }
173
174     // creates request string
175
private void createRequestString() {
176         if (requestStr == null) {
177             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
178             sb.append("declare validation preserve;\n");
179             String JavaDoc tmpstr = plan.getDeclarations();
180             if (tmpstr != null)
181                 sb.append(tmpstr);
182             sb.append("declare namespace xsi = \"http://www.w3.org/2001/XMLSchema-instance\";\n");
183             requestStr = sb.toString();
184         }
185     }
186
187     public ArrayList JavaDoc getExternalVariables() {
188         return externalVariables;
189     }
190
191     public String JavaDoc getRequestStr() {
192         return requestStr;
193     }
194
195     public String JavaDoc getPreparedRequestStr() {
196         return preparedRequestStr;
197     }
198
199     // **********************************************************************
200
// * PRINT
201
// **********************************************************************
202
public String JavaDoc toCompleteString(int indent) {
203         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
204         buf.append(Utils.makeIndent(indent) + "<" + getClass().getName() + " isLet=\"" + islet + "\" valueDepends=\"" + valueDepends + "\" whereDepends=\"" + whereDepends + "\">\n");
205         buf.append(Utils.makeIndent(indent + 1) + "<Expression>\n");
206         buf.append(Utils.makeIndent(indent + 2) + expression + "\n");
207         buf.append(Utils.makeIndent(indent + 1) + "</Expression>\n");
208         buf.append(Utils.makeIndent(indent + 1) + "<Source>" + source + "</Source>\n");
209         // if (variables != null) {
210
// buf.append(Utils.makeIndent(indent + 1) + "<Variables>\n");
211
// for (int i = 0; i < variables.size(); i++) {
212
// buf.append(Utils.makeIndent(indent + 2) + "<Variable>" + variables.get(i) + "</Variable>\n");
213
// }
214
// buf.append(Utils.makeIndent(indent + 1) + "</Variables>\n");
215
// }
216
if (paths != null) {
217             buf.append(Utils.makeIndent(indent + 1) + "<Paths>\n");
218             for (int i = 0; i < paths.size(); i++) {
219                 buf.append(Utils.makeIndent(indent + 2) + "<Path>" + paths.get(i) + "</Path>\n");
220             }
221             buf.append(Utils.makeIndent(indent + 1) + "</Paths>\n");
222         }
223         buf.append(Utils.makeIndent(indent) + "</" + getClass().getName() + ">\n");
224         return buf.toString();
225     }
226
227 }
228
229 class SourceResultSet extends ZeroResultSet {
230     // **********************************************************************
231
// * VERSIONING
232
// **********************************************************************
233
private static final String JavaDoc RCSRevision = "$Revision: 1.51 $";
234
235     private static final String JavaDoc RCSName = "$Name: $";
236
237     private static Log log = LogFactory.getLog(SourceResultSet.class);
238
239     // **********************************************************************
240
// * CLASS VARIABLES
241
// **********************************************************************
242
private XMLStatement statement = null;
243
244     private XMLResultSet resultset = null;
245
246     private PSVInfoSetProvider psvip = null;
247
248     //private SchemaValidationContext svc = null;
249
private ValidatingSchemaHandler vsh = null;
250
251     private SAX2DOM thandler = null;
252
253     // ***********************************************************************
254
// * INITIALIZATION
255
// ***********************************************************************
256
/**
257      *
258      */

259     public SourceResultSet(OpSource operator, DynamicContext context, XMLConnection connection) throws MediatorException {
260         super(operator, context);
261         try {
262             statement = connection.createStatement();
263         } catch (XMLDBCException xe) {
264             throw new MediatorException(xe.getMessage(), xe);
265         }
266
267         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
268
269         sb.append(operator.getRequestStr());
270
271         ArrayList JavaDoc externalVariables = operator.getExternalVariables();
272         if (externalVariables != null) {
273             try {
274                 for (int i = 0; i < externalVariables.size(); i++) {
275                     Variable vari = (Variable) externalVariables.get(i);
276                     Object JavaDoc strvalue = context.getVariableValue(vari);
277                     if (strvalue == null)
278                         throw new MediatorException("Could not find expression while replacing variable");
279                     sb.append("declare variable $");
280                     //sb.append(vari.getStringValue());
281
QName qname = vari.getVarName();
282                     NamespaceContextStack contextSatck = operator.getPlan().getModule().getDeclarations();
283                     if (contextSatck != null) {
284                         String JavaDoc prefix = contextSatck.getPrefix(qname.getNameSpace());
285                         if (prefix != null && prefix.length() != 0) {
286                             sb.append(prefix);
287                             sb.append(":");
288                         }
289                     }
290                     sb.append(qname.getLocalName());
291                     sb.append(" := {");
292                     if (strvalue instanceof ArrayList JavaDoc) {
293                         sb.append("(");
294                         ArrayList JavaDoc list = (ArrayList JavaDoc)strvalue;
295                         for (int j=0;j<list.size();j++) {
296                             if (j!=0)
297                                 sb.append(",");
298                             strvalue = list.get(j);
299                             if (strvalue instanceof String JavaDoc) {
300                                 sb.append("\"");
301                                 sb.append(strvalue.toString());
302                                 sb.append("\"");
303                             } else
304                                 sb.append(strvalue.toString());
305                         }
306                         sb.append(")");
307                     } else {
308                         if (strvalue instanceof String JavaDoc) {
309                             sb.append("\"");
310                             sb.append(strvalue.toString());
311                             sb.append("\"");
312                         } else
313                             sb.append(strvalue.toString());
314                     }
315                     sb.append("};\n");
316                 }
317             } catch (XQueryException xqe) {
318                 throw new MediatorException(xqe.getMessage(), xqe);
319             }
320         }
321         // TODO find a better way to modify prefixes of included modules
322
sb.append(expression.getStringValue(operator.getPlan().getModule().getDeclarations()));
323
324         if (log.isDebugEnabled())
325             log.debug("SOURCE EXECUTING \n" + sb.toString());
326
327         try {
328             resultset = statement.executeQuery(sb.toString());
329
330             if (!resultset.hasNext()) {
331                 resultset.close();
332                 resultset = null;
333                 statement.close();
334                 setFinishedWhenEmpty();
335             }
336         } catch (XMLDBCException xe) {
337             throw new MediatorException(xe.getMessage(), xe);
338         }
339     }
340
341     public SourceResultSet(OpSource operator, DynamicContext context, PreparedXMLStatement statement) throws MediatorException {
342         super(operator, context);
343
344         try {
345             ArrayList JavaDoc externalVariables = operator.getExternalVariables();
346             if (externalVariables != null) {
347                 try {
348                     for (int i = 0; i < externalVariables.size(); i++) {
349                         Variable vari = (Variable) externalVariables.get(i);
350                         Object JavaDoc strvalue = context.getVariableValue(vari);
351                         if (strvalue == null)
352                             throw new MediatorException("Could not find expression while replacing variable");
353                         ((PreparedXMLStatement) statement).setObject(vari.getVarName().getNameSpace(), vari.getVarName().getName(), strvalue);
354                     }
355                 } catch (XQueryException xqe) {
356                     throw new XMLDBCException(xqe.getMessage());
357                 }
358             }
359             resultset = ((PreparedXMLStatement) statement).executeQuery();
360
361             if (!resultset.hasNext()) {
362                 resultset.close();
363                 resultset = null;
364                 setFinishedWhenEmpty();
365             }
366         } catch (XMLDBCException xe) {
367             throw new MediatorException(xe.getMessage(), xe);
368         }
369     }
370
371     // ***********************************************************************
372
// * EVALUATE IMPLEMENTATION
373
// ***********************************************************************
374
/**
375      *
376      * @param non_blocking
377      * if the evaluation is blocking, we must generate all the results before passing.
378      */

379     protected void evaluate(boolean non_blocking) throws MediatorException {
380
381         if (resultset == null)
382             return;
383
384         //non_blocking = false;
385

386         if (this.operator.isLet())
387             non_blocking = false;
388         try {
389             if (thandler == null) {
390                 psvip = this.resultset.getPSVInfoSetProvider();
391                 if (psvip == null) {
392                     SchemaValidationContext svc = new SchemaValidationContext(this.operator.getPlan().getSchemaManager());
393                     vsh = new ValidatingSchemaHandler(svc, false);
394                     thandler = new SAX2DOM(svc);
395                     vsh.setContentHandler(thandler);
396                     vsh.setErrorHandler(new ErrorHandler JavaDoc() {
397                         public void warning(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
398                         }
399
400                         public void error(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
401                             System.err.println(ex);
402                         }
403
404                         public void fatalError(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
405                         }
406                     });
407                     resultset.setContentHandler(vsh);
408                 } else {
409                     thandler = new SAX2DOM(psvip);
410                     resultset.setContentHandler(thandler);
411                 }
412             }
413             while (true) {
414                 Tuple tuple = new Tuple(this);
415                 thandler.init(tuple);
416                 if (resultset.hasNext()) {
417                     if (vsh != null)
418                         vsh.startDocument();
419                     else
420                         thandler.startDocument();
421                     resultset.nextAsSAX();
422                     if (vsh != null)
423                         vsh.endDocument();
424                     else
425                         thandler.endDocument();
426                     if (this.operator.isLet()) {
427                         if (this.buftuples.size() == 0) {
428                             tuple.fillIdentifiers();
429                             buftuples.add(tuple);
430                         } else {
431                             Tuple first = (Tuple) this.buftuples.get(0);
432                             first.appendTuple(tuple);
433                         }
434                     } else {
435                         tuple.fillIdentifiers();
436                         buftuples.add(tuple);
437                     }
438                     // can make higher buffering by modifying this test
439
if (non_blocking && !buftuples.isEmpty()) {
440                         if (resultset != null && !resultset.hasNext()) {
441                             resultset.close();
442                             resultset = null;
443                             if (statement != null)
444                                 statement.close();
445                             setFinishedWhenEmpty();
446                         }
447                         break;
448                     }
449                 } else {
450                     resultset.close();
451                     resultset = null;
452                     if (statement != null)
453                         statement.close();
454                     setFinishedWhenEmpty();
455                     return;
456                 }
457             }
458         } catch (XMLDBCException xe) {
459             throw new MediatorException("AlgSource.evaluate: " + xe.getMessage(), xe);
460         } catch (SAXException JavaDoc saxe) {
461             throw new MediatorException("AlgSource.evaluate: " + saxe.getMessage(), saxe);
462         }
463     }
464
465     protected void finalize() {
466         try {
467             if (null != resultset) {
468                 resultset.close();
469                 if (statement != null)
470                     statement.close();
471             }
472         } catch (Exception JavaDoc ex) {
473         }
474         ;
475     }
476 }
Popular Tags