KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > mediator > algebra > AlgSource


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.algebra;
24
25 import java.net.MalformedURLException JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.*;
28
29 import org.xquark.mediator.decomposer.GetVariablePathsVisitor;
30 import org.xquark.mediator.decomposer.IsolateWhereVisitor;
31 import org.xquark.mediator.decomposer.Utils;
32 import org.xquark.mediator.plan.*;
33 import org.xquark.mediator.runtime.MediatorException;
34 import org.xquark.schema.SchemaException;
35 import org.xquark.xquery.metadata.MetaCollection;
36 import org.xquark.xquery.metadata.MetaDataImpl;
37 import org.xquark.xquery.metadata.MetaWrapper;
38 import org.xquark.xquery.parser.*;
39 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.FunctionCOLLECTION;
40 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.FunctionDOC;
41 import org.xquark.xquery.parser.util.Constants;
42 import org.xquark.xquery.typing.*;
43
44 /**
45  * This class represent the terminal leaf of the dependancy tree.
46  * It is generated after atomization (and is resulted from the transformation
47  * of DepSource that disappear).
48  *
49  */

50 public class AlgSource extends Algebra {
51     // **********************************************************************
52
// * VERSIONING
53
// **********************************************************************
54
private static final String JavaDoc RCSRevision = "$Revision: 1.30 $";
55     private static final String JavaDoc RCSName = "$Name: $";
56     // **********************************************************************
57
// * CLASS VARIABLES
58
// **********************************************************************
59
private Set sources;
60     // private boolean hasIdentifier = false;
61
// private boolean flwrcreated = false;
62
// private boolean returncreated = false;
63
// ************************************************************************
64
// * INITIALIZATION
65
// ************************************************************************
66
/**
67      * Create a node from a variable and an expression.
68      *
69      * To create the node, we take the original expression, and we
70      * extract everything relative to variable given by the leaf.
71      * from that, we create a new flower expression that will be associated
72      * to this DepNodeSource, and the old XQueryExpression that is
73      * referenced by it's DepNode is simplified.
74      * (bon, en gros, ça sert a faire une optimisation en faisant
75      * redescendre les restrictions (et plus tard les projection) vers les
76      * sources.
77      *
78      * @param typevisitor
79      * @param origexp
80      * @param varleaf
81      * @param depmanager
82      */

83     public AlgSource(XQueryExpression origexp, ArrayList variables, AlgebraManager depmanager, boolean islet) throws MediatorException {
84         super(origexp, variables, depmanager, islet);
85     }
86
87     public AlgSource(XQueryExpression origexp, Variable varleaf, AlgebraManager depmanager, boolean islet) throws MediatorException {
88         // to satisfy the super constructor, but expression and variable will be changed in following step.
89
super(origexp, varleaf, depmanager, islet);
90     }
91
92     // ******************************************************************
93
// * METHODS
94
// ******************************************************************
95

96     public void ParentHasIdentifier() {
97         hasIdentifier = true;
98     }
99
100     /**
101      * Create the FLWRExpression like this :
102      * - F : is the variable varleaf that we consider with no changes
103      * (even the expression associated to it is kept ;
104      * - L : there is no Let at this point ;
105      * - W : is the major part, we must scan the origexp to see what
106      * to keep
107      * - R : for now, we return just the variable, but later, when
108      * we will care about prjection, we will make good
109      * LocatedExpression with it.
110      * @param origexp
111      * @param varleaf
112      */

113
114     // private void createFLWRExpression() throws MediatorException {
115
// this.createFLWRExpression(null, true);
116
// }
117
// public void createFLWRExpression(boolean doReturn) throws MediatorException {
118
// this.createFLWRExpression(null, doReturn);
119
// }
120
// public void createFLWRExpression(ArrayList vars) throws MediatorException {
121
// this.createFLWRExpression(null, true);
122
// }
123
private void createFLWRExpression(boolean doReturn) throws MediatorException {
124         if (!(expression instanceof FLWRExpression))
125             throw new MediatorException("DepNodeSource : " + expression + " is not a FLWR.");
126
127         try {
128             FLWRExpression origflwr = (FLWRExpression) expression;
129
130             // Variables
131
ArrayList newvariables = (ArrayList) variables.clone();
132             newvariables.addAll(this.parent.getVarsDependingOn());
133             newvariables.addAll(this.getVarsDependingOn());
134             //newvariables.addAll(this.parent.getVarsWhereOn());
135
newvariables.addAll(this.getVarsWhereOn());
136
137             // Where
138
XQueryExpression newWhereClause = origflwr.getWhereClause();
139
140             if (!doReturn) {
141                 // update paths because where clause is not calculate in flwr
142
if (newWhereClause != null) {
143                     GetVariablePathsVisitor gvpv = new GetVariablePathsVisitor(true);
144                     newWhereClause.accept(gvpv);
145                     ArrayList tmplist = gvpv.getPaths(newvariables);
146                     if (tmplist != null)
147                         for (int i = 0; i < tmplist.size(); i++)
148                             if (!this.algManager.getPathsList().contains(tmplist.get(i).toString()))
149                                 paths.add(tmplist.get(i));
150                 }
151             }
152             if (newWhereClause != null) {
153                 newWhereClause = (XQueryExpression) origflwr.getWhereClause().clone();
154                 IsolateWhereVisitor visitor = new IsolateWhereVisitor(newvariables);
155                 newWhereClause.accept(visitor);
156                 newWhereClause = visitor.getIsolatedExpression();
157                 // erase isolated where clause from original where clause
158
((FLWRExpression) expression).setWhereClause(visitor.getRemainingExpression());
159             }
160             // OrderBy
161
ArrayList newOrderbys = null;
162             if (origflwr.getOrderBy() != null) {
163                 newOrderbys = (ArrayList) origflwr.getOrderBy().clone();
164                 for (int i = 0, j = 0; i < newOrderbys.size(); i++, j++) {
165                     XQueryExpression exp = (XQueryExpression) newOrderbys.get(i);
166                     if (exp.getOrder(0) == Constants.PLACE_ORDER)
167                         exp = null;
168                     else {
169                         IsolateWhereVisitor visitor = new IsolateWhereVisitor(variables);
170                         exp.accept(visitor);
171                         exp = visitor.getIsolatedExpression();
172                     }
173                     if (exp != null) {
174                         newOrderbys.set(i, exp);
175                     } else {
176                         newOrderbys.remove(i);
177                         i--;
178                     }
179                 }
180                 if (newOrderbys.isEmpty())
181                     newOrderbys = null;
182             }
183             if (doReturn) {
184                 // create new FLWRExpression
185
// keep only single variable
186
// origflwr.setVariables(vars);
187
// recalculate sources if necessary
188
//if (vars.size() != ((FLWRExpression)expression).getVariables().size()) {
189
sources = expression.getSourceNames();
190                 if (sources != null) {
191                     sources.clear();
192                     for (int i = 0; i < variables.size(); i++) {
193                         Variable vari = (Variable) variables.get(i);
194                         sources.addAll(vari.getSourceNames());
195                     }
196                 }
197             }
198             //}
199
// make return expression
200
FLWRExpression newFlwr = null;
201             if (doReturn) {
202                 if (newWhereClause != null && newWhereClause.getQType() == null)
203                     newWhereClause.setQType(new QTypeAtom(this.algManager.getPlan().getSchemaManager().getBooleanType()));
204                 newFlwr = new FLWRExpression(variables, newOrderbys, newWhereClause, createReturnExpression(), expression.getParentModule());
205             } else
206                 newFlwr = new FLWRExpression(variables, newOrderbys, newWhereClause, new XQueryVoid(expression.getParentModule()), null);
207             newFlwr.setParentModule(origflwr.getParentModule());
208             newFlwr.setSourceNames(sources);
209             expression = newFlwr;
210         } catch (TypeException te) {
211             throw new MediatorException("DepNodeSource.createFLWRExpression : " + te.getMessage(), te);
212         } catch (CloneNotSupportedException JavaDoc e) {
213             throw new MediatorException("DepNodeSource.createFLWRExpression : " + e.getMessage(), e);
214         } catch (XQueryException e) {
215             throw new MediatorException("DepNodeSource.createFLWRExpression : " + e.getMessage(), e);
216         }
217     }
218
219     private XQueryExpression createReturnExpression() throws XQueryException, TypeException {
220         TypeVisitor typevisitor = this.algManager.getTypeVisitor();
221         ArrayList subexpressions = null;
222         if (this.paths != null) {
223             subexpressions = new ArrayList(this.paths.size());
224             for (int i = 0; i < paths.size(); i++) {
225                 //ArrayList tmplist = new ArrayList(1);
226
//tmplist.add((XQueryExpression) paths.get(i));
227
//XQueryExpressionSequence tmpseq = new XQueryExpressionSequence(tmplist, typevisitor);
228
//tmpseq.setBrace(true);
229
XQueryExpression expr = null;
230                 try {
231                     expr = (XQueryExpression) ((XQueryExpression) paths.get(i)).clone();
232                     //expr.setBrace(true);
233
} catch (CloneNotSupportedException JavaDoc e) {
234                     throw new XQueryException(e.getMessage());
235                 }
236                 ArrayList tmpeltexprs = new ArrayList(1);
237                 //tmpeltexprs.add(tmpseq);
238
tmpeltexprs.add(expr);
239                 subexpressions.add(new org.xquark.xquery.parser.Element(new QName(null, null, "R" + Integer.toString(i + 1), null, null), null, null, tmpeltexprs, expression.getParentModule()));
240             }
241         }
242         return new Element(new QName(null, null, "R", null, null), null, null, subexpressions, expression.getParentModule());
243     }
244
245     // ******************************************************************
246
// * CREATE EXECUTION PLAN
247
// ******************************************************************
248
/**
249      *
250      * @param plan
251      * @return
252      */

253     public Operator createOperator(ExecutionPlan plan) throws MediatorException {
254         //if (true) throw new MediatorException("createAlgebra not supported in DepNodeSource");
255
createFLWRExpression(!plan.getQAOnly());
256
257         FLWRExpression newFlwr = (FLWRExpression) expression;
258         if (!plan.getQAOnly()) {
259             QTypeElement flwrqtype = (QTypeElement) newFlwr.getQType();
260             try {
261                 this.getAlgebraManager().getPlan().setTypeName(flwrqtype.getType());
262                 ArrayList attributes = new ArrayList(2);
263                 // change LARS 06/04/04
264
attributes.add(new AttributeValuePair(new ValueText("xmlns:xquark_execution_prefix", null), new ValueString("http://www.xquark.org/EXECUTIONPLAN", null), false, null));
265                 attributes.add(new AttributeValuePair(new ValueText("xsi:type", null), new ValueString("xquark_execution_prefix:" + flwrqtype.getType().getName(), null), false, null));
266                 ((Element) newFlwr.getReturnClause()).setAttributes(attributes);
267             } catch (TypeException te) {
268                 throw new MediatorException("DepNodeSource.createAlgebra : " + te.getMessage(), te);
269             } catch (XQueryException e) {
270                 throw new MediatorException("DepNodeSource.createAlgebra : " + e.getMessage(), e);
271             } catch (SchemaException e) {
272                 throw new MediatorException("DepNodeSource.createAlgebra : " + e.getMessage(), e);
273             }
274
275             sources = expression.getSourceNames();
276             if (sources == null || sources.isEmpty()) {
277                 try {
278                     Utils.fillSources(expression, algManager.getMetaData(), false);
279                 } catch (XQueryException e) {
280                     throw new MediatorException(e.getMessage(), e);
281                 }
282                 sources = expression.getSourceNames();
283             }
284         } else
285             sources = null;
286         if (sources == null || sources.isEmpty()) {
287             if (!plan.getQAOnly())
288                 throw new MediatorException("DepNodeSource.createAlgebra: " + toString() + " has no sources.");
289             //****************************************************************************************************
290
// start special case for QA
291
// get all documents in collection and make a union
292
// test if only one variable
293
if (newFlwr.getVariables().size() != 1)
294                 throw new MediatorException("Collection for QA, flwr should have only one variable");
295             Variable var = (Variable) newFlwr.getVariables().get(0);
296             XQueryExpression expr = var.getExpression();
297             // test expression is located expression starting with collection
298
// first get the collection name
299
FunctionCOLLECTION func = null;
300             boolean onlyFunction = false;
301             if (expr instanceof LocatedExpression && ((LocatedExpression) expr).getExpression() instanceof FunctionCOLLECTION)
302                 func = (FunctionCOLLECTION) ((LocatedExpression) expr).getExpression();
303             else if (expr instanceof FunctionCOLLECTION) {
304                 func = (FunctionCOLLECTION) expr;
305                 onlyFunction = true;
306             } else
307                 throw new MediatorException("Collection for QA, variable should be bound to located expression starting with collection");
308             expr = func.getArgument(0);
309             if (!(expr instanceof ValueString))
310                 throw new MediatorException("Collection for QA, first argument of collection should be value string");
311             String JavaDoc colName = ((ValueString) expr).getStringValue();
312             int index = colName.indexOf(":");
313             if (index != -1)
314                 colName = colName.substring(index + 1);
315             // second, get all documents in the collection
316
Operator operator = null;
317             try {
318                 MetaDataImpl metadata = plan.getMetadata();
319                 MetaWrapper metawrapper = metadata.getMetaWrapper("CONFFILES");
320                 if (metawrapper == null)
321                     throw new MediatorException("Collection for QA, no document wrapper accessible");
322                 // test special case *
323
ArrayList documents = null;
324                 if (colName.equals("*")) {
325                     List list = metawrapper.getCollectionsName();
326                     if (!list.isEmpty()) {
327                         for (Iterator it = list.iterator(); it.hasNext();) {
328                             colName = (String JavaDoc) it.next();
329                             if (documents == null)
330                                 documents = (ArrayList) metawrapper.getMetaCollection(colName).getDocuments();
331                             else
332                                 documents.addAll(metawrapper.getMetaCollection(colName).getDocuments());
333                         }
334                     }
335                 } else {
336                     MetaCollection col = metawrapper.getMetaCollection(colName);
337                     if (col != null)
338                         documents = col.getDocuments();
339                     else
340                         throw new MediatorException("Collection for QA, collection '" + colName + "' does not exist");
341                 }
342                 if (documents == null || documents.isEmpty())
343                     throw new MediatorException("Collection for QA, collection has no documents");
344                 if (documents.size() == 1) {
345                     String JavaDoc docname = (String JavaDoc) documents.get(0);
346                     if (plan.getBaseURI() != null)
347                         docname = (new URL JavaDoc(new URL JavaDoc(plan.getBaseURI()), docname)).toString();
348                     ArrayList args = new ArrayList(1);
349                     args.add(new ValueString(docname, null));
350                     if (onlyFunction)
351                          ((Variable) newFlwr.getVariables().get(0)).setExpression(new FunctionDOC(args, expression.getParentModule()), false);
352                     else
353                          ((LocatedExpression) ((Variable) newFlwr.getVariables().get(0)).getExpression()).getStepNum(0).setExpression(new FunctionDOC(args, expression.getParentModule()));
354                     operator = new OpSourceEval(plan, newFlwr, paths, hasIdentifier);
355                     // finally if some sort clauses are present sort the resultset
356
if (newFlwr.getOrderBy() != null && !newFlwr.getOrderBy().isEmpty())
357                         operator = new OpSort(plan, operator, newFlwr.getOrderBy());
358                 } else {
359                     //throw new MediatorException("Collection for QA, collection with more than one document");
360
Operator[] operators = new Operator[documents.size()];
361                     for (int i = 0; i < documents.size(); i++) {
362                         FLWRExpression cloneflwr = (FLWRExpression) newFlwr.clone(false);
363                         String JavaDoc docname = (String JavaDoc) documents.get(i);
364                         ArrayList args = new ArrayList(1);
365                         args.add(new ValueString(docname, null));
366                         if (onlyFunction)
367                              ((Variable) cloneflwr.getVariables().get(0)).setExpression(new FunctionDOC(args, expression.getParentModule()), false);
368                         else
369                              ((LocatedExpression) ((Variable) cloneflwr.getVariables().get(0)).getExpression()).getStepNum(0).setExpression(new FunctionDOC(args, expression.getParentModule()));
370                         operators[i] = new OpSourceEval(plan, cloneflwr, paths, hasIdentifier);
371                     }
372                     // finally if some sort clauses are present sort the resultset
373
if (newFlwr.getOrderBy() != null && !newFlwr.getOrderBy().isEmpty())
374                         operator = new OpUnionSort(plan, operators, newFlwr.getOrderBy());
375                     else
376                         operator = new OpUnion(plan, operators);
377
378                 }
379             } catch (MalformedURLException JavaDoc e) {
380                 throw new MediatorException("Collection for QA, could not access metadata");
381             } catch (CloneNotSupportedException JavaDoc e) {
382                 throw new MediatorException("Collection for QA, could not access metadata");
383             } catch (MediatorException e) {
384                 throw e;
385             } catch (XQueryException e) {
386                 throw new MediatorException("Collection for QA, could not access metadata");
387             }
388             operator.isLet(islet);
389             return operator;
390             // end special case for QA
391
//****************************************************************************************************
392
}
393
394         // there is at least 1 source
395
Iterator it = sources.iterator();
396         String JavaDoc source = (String JavaDoc) it.next();
397         Operator algebra = null;
398         try {
399             algebra = new OpSource(plan, (XQueryExpression) expression.clone(false), paths, source, hasIdentifier);
400             if (sources.size() > 1) {
401                 // there is at least 2 leaves
402
ArrayList orderbys = ((FLWRExpression) expression).getOrderBy();
403                 Operator[] operators = new Operator[sources.size()];
404                 operators[0] = algebra;
405                 for (int i = 1;it.hasNext();i++)
406                     operators[i] = new OpSource(plan, (XQueryExpression) expression.clone(), paths, (String JavaDoc) it.next(), hasIdentifier);
407                 if (orderbys != null && !orderbys.isEmpty())
408                     algebra = new OpUnionSort(plan, operators, orderbys);
409                 else
410                     algebra = new OpUnion(plan, operators);
411             }
412         } catch (CloneNotSupportedException JavaDoc cnse) {
413             throw new MediatorException(cnse.getMessage());
414         }
415         algebra.isLet(islet);
416         return algebra;
417     }
418
419     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
420         AlgSource newobj = (AlgSource) super.clone();
421         newobj.hasIdentifier = this.hasIdentifier;
422         newobj.sources = this.sources;
423         return newobj;
424     }
425
426     // ******************************************************************
427
// * GET/SET METHODS
428
// ******************************************************************
429
/**
430      *
431      * @return
432      */

433     //public ArrayList getPaths() { return paths ; }
434

435     /**
436      *
437      * @return
438      */

439     // public ArrayList getVarsThatDepend() throws MediatorException { return varsthatdepend ; }
440

441     // ******************************************************************
442
// * DEBUGGING
443
// ******************************************************************
444
/**
445      *
446      * @return
447      */

448     public String JavaDoc toCompleteString(int indent) {
449         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
450
451         buf.append(Utils.makeIndent(indent) + "<" + this.getClass().getName() + ">\n");
452         buf.append(Utils.makeIndent(indent + 1) + "<variables> " + variables + " </variables>\n");
453         buf.append(Utils.makeIndent(indent + 1) + "<sources> " + getSources() + " </sources>\n");
454         buf.append(Utils.makeIndent(indent + 1) + "<urls> " + getUrls() + " </urls>\n");
455         buf.append(Utils.makeIndent(indent + 1) + "<isLet> " + islet + " </isLet>\n");
456         buf.append(Utils.makeIndent(indent + 1) + "<monosource> " + isMonoSource() + " </monosource>\n");
457         buf.append(Utils.makeIndent(indent + 1) + "<hasIdentifier> " + hasIdentifier + " </hasIdentifier>\n");
458         buf.append(Utils.makeIndent(indent + 1) + "<Expression>\n");
459         buf.append(Utils.makeIndent(indent + 2) + expression + "\n");
460         buf.append(Utils.makeIndent(indent + 1) + "</Expression>\n");
461         //buf.append("\t\t<Function>" + funcToString() + "</Function>\n") ;
462
if (sources != null) {
463             buf.append(Utils.makeIndent(indent + 1) + "<Sources>\n");
464             for (Iterator it = sources.iterator(); it.hasNext();)
465                 buf.append(Utils.makeIndent(indent + 2) + "<Source>" + it.next() + "</Sources>\n");
466             buf.append(Utils.makeIndent(indent + 1) + "</Sources>\n");
467         }
468         if (algChildren != null && !algChildren.isEmpty()) {
469             buf.append(Utils.makeIndent(indent + 1) + "<Leaves>\n");
470             for (int i = 0; i < algChildren.size(); i++) {
471                 buf.append(Utils.makeIndent(indent + 2) + "<Leave>\n");
472                 Algebra depchild = (Algebra) algChildren.get(i);
473                 buf.append(depchild.toCompleteString(indent + 3));
474                 buf.append(Utils.makeIndent(indent + 2) + "</Leave>\n");
475             }
476             buf.append(Utils.makeIndent(indent + 1) + "</Leaves>\n");
477         }
478         if (referenceDefinitionVars != null && !referenceDefinitionVars.isEmpty()) {
479             buf.append(Utils.makeIndent(indent + 1) + "<referenceDefinitionVars>\n");
480             for (int i = 0; i < referenceDefinitionVars.size(); i++) {
481                 Variable var = (Variable) referenceDefinitionVars.get(i);
482                 buf.append(Utils.makeIndent(indent + 2) + "<Var>" + var + "</Var>\n");
483             }
484             buf.append(Utils.makeIndent(indent + 1) + "</referenceDefinitionVars>\n");
485         }
486         if (dependDefinitionVars != null && !dependDefinitionVars.isEmpty()) {
487             buf.append(Utils.makeIndent(indent + 1) + "<DependingOn>\n");
488             for (int i = 0; i < dependDefinitionVars.size(); i++) {
489                 Variable var = (Variable) dependDefinitionVars.get(i);
490                 buf.append(Utils.makeIndent(indent + 2) + "<Var>" + var + "</Var>\n");
491             }
492             buf.append(Utils.makeIndent(indent + 1) + "</dependDefinitionVars>\n");
493         }
494         if (paths != null) {
495             buf.append(Utils.makeIndent(indent + 1) + "<Paths>\n");
496             for (int i = 0; i < paths.size(); i++)
497                 buf.append(Utils.makeIndent(indent + 2) + "<Path>" + paths.get(i) + "</Path>\n");
498             buf.append(Utils.makeIndent(indent + 1) + "</Paths>\n");
499         }
500         buf.append(Utils.makeIndent(indent) + "</" + this.getClass().getName() + ">\n");
501         return buf.toString();
502     }
503
504     public void execute(ExecutionPlan plan) throws MediatorException {
505     }
506
507 }
508
Popular Tags