KickJava   Java API By Example, From Geeks To Geeks.

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


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

23
24 package org.xquark.mediator.algebra;
25
26 import java.util.*;
27
28 import org.xquark.mediator.decomposer.*;
29 import org.xquark.mediator.plan.*;
30 import org.xquark.mediator.runtime.MediatorException;
31 import org.xquark.xquery.normalize.GetBoundVariablesVisitor;
32 import org.xquark.xquery.parser.*;
33 import org.xquark.xquery.parser.hinttree.HintTree;
34 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.FunctionCOLLECTION;
35 import org.xquark.xquery.parser.util.Constants;
36
37 /**
38  * Represent a node where nodes or leaves can fix to it. Before atomization a DepMem binds only DepSource and DepVar. After atomization, a DepMem binds only DepVar.
39  *
40  */

41 public class AlgFLWR extends Algebra {
42     // **********************************************************************
43
// * VERSIONING
44
// **********************************************************************
45
private static final String JavaDoc RCSRevision = "$Revision: 1.27 $";
46
47     private static final String JavaDoc RCSName = "$Name: $";
48
49     // **********************************************************************
50
// * CLASS VARIABLES
51
// **********************************************************************
52
private ArrayList subDepFLWRs = null;
53
54     private AlgFLWR parentDepFLWR = null;
55
56     //private ArrayList variables = null;
57
private boolean monoSource = false;
58
59     protected Set sources = null;
60
61     protected HintTree hinttree = null;
62
63     // telling if information has already been computed
64
boolean hasInformation = false;
65
66     // telling whether the subelements are done with nested loop
67
int subhandling = -1;
68
69     // relation between variables in where expression
70
VariableDependencies vardependencies = null;
71
72     // private HashMap varVarWhereMap = null;
73
// private ArrayList allExprWhereList = null;
74
// private ArrayList complexExprWhereList = null;
75
// maps for ordering purposes
76
private HashMap varOrderMap = null;
77
78     private HashMap orderVarMap = null;
79
80     private ArrayList complexExprOrderList = null;
81
82     private ArrayList varOrderList = null;
83
84     private ArrayList varReOrderList = null;
85
86     private ArrayList varHintList = null;
87
88     // for compulsery hint
89
private boolean hasCompulseryMerge = false;
90
91     private boolean hasCompulseryNested = false;
92
93     private IsolateWhereVisitor isolateVisitor = null;
94
95     // ******************************************************************
96
// * INITIALIZATION
97
// ******************************************************************
98
/**
99      *
100      * @param typevisitor
101      * @param expression
102      * @param depmanager
103      */

104     public AlgFLWR(XQueryExpression expression, Variable var, AlgebraManager depmanager, boolean islet) throws MediatorException {
105         super(expression, var, depmanager, islet);
106         // set HintTree
107
hinttree = ((FLWRExpression) expression).getHintTree();
108         // fill var lists
109
fillVarLists();
110     }
111
112     // ******************************************************************
113
// * GET/SET METHODS
114
// ******************************************************************
115
public void setDependency(AlgFLWR parentDepFLWR) {
116         if (this.parentDepFLWR != null)
117             this.parentDepFLWR.getDependencyList().remove(this);
118         this.parentDepFLWR = parentDepFLWR;
119         ArrayList tmpList = parentDepFLWR.getDependencyList();
120         if (tmpList == null) {
121             tmpList = new ArrayList();
122             tmpList.add(this);
123             parentDepFLWR.setDependencyList(tmpList);
124         } else if (!tmpList.contains(this))
125             tmpList.add(this);
126     }
127
128     public ArrayList getDependencyList() {
129         return subDepFLWRs;
130     }
131
132     public void setDependencyList(ArrayList subDepFLWRs) {
133         this.subDepFLWRs = subDepFLWRs;
134     }
135
136     public boolean isRootQDB() {
137         return (parentDepFLWR == null && parent == null);
138     }
139
140     public boolean isQDB() {
141         return (isRootQDB() || parent == null);
142     }
143
144     public boolean isMonoSource() {
145         return monoSource;
146     }
147
148     public void setMonoSource(boolean monoSource) {
149         this.monoSource = monoSource;
150     }
151
152     public HintTree getHintTree() {
153         return hinttree;
154     }
155
156     public void setHintTree(HintTree hinttree) {
157         this.hinttree = hinttree;
158     }
159
160     public int getSubHandling() {
161         return subhandling;
162     }
163
164     public void setSubHandling(int subhandling) {
165         this.subhandling = subhandling;
166     }
167
168     public boolean hasCompulseryMerge() {
169         return hasCompulseryMerge;
170     }
171
172     public boolean hasCompulseryNested() {
173         return hasCompulseryNested;
174     }
175
176     public void updateVarDependencyList(ArrayList dependVars) {
177         if (parentDepFLWR == null || dependVars == null || dependVars.isEmpty())
178             return;
179         for (int i = 0; i < dependVars.size(); i++) {
180             Variable tmpvar = (Variable) dependVars.get(i);
181             if (!((FLWRExpression) parentDepFLWR.getExpression()).getVariables().contains(tmpvar))
182                 getParentDepFLWR().addDependSourceVariable(tmpvar);
183             else
184                 dependVars.remove(tmpvar);
185         }
186         if (!dependVars.isEmpty())
187             getParentDepFLWR().updateVarDependencyList(dependVars);
188     }
189
190     private AtomizeWhereVisitor awvisitor = null;
191
192     private void computeVarOrderList() throws MediatorException {
193         ArrayList orders = ((FLWRExpression) expression).getOrderBy();
194         if (orders != null) {
195             varOrderList = new ArrayList(orders.size());
196             complexExprOrderList = new ArrayList(1);
197             orderVarMap = new HashMap();
198             varOrderMap = new HashMap();
199             GetBoundVariablesVisitor gbvv = new GetBoundVariablesVisitor(true, false);
200             for (int i = 0; i < orders.size(); i++) {
201                 XQueryExpression orderExpr = (XQueryExpression) orders.get(i);
202                 // if (orderExpr.getOrder(0) == Constants.PLACE_ORDER)
203
// continue;
204
gbvv.reset();
205                 try {
206                     orderExpr.accept(gbvv);
207                 } catch (XQueryException e) {
208                     throw new MediatorException("Could not extract variables from expression : " + orderExpr, e);
209                 }
210                 ArrayList tmpList = gbvv.getAllVariables();
211                 orderVarMap.put(orderExpr, tmpList);
212                 if (tmpList.size() > 1) {
213                     complexExprOrderList.add(orderExpr);
214                     if (varOrderList != null && !varOrderList.containsAll(tmpList))
215                         varOrderList = null;
216                     ArrayList tmpOrders = (ArrayList) varOrderMap.get(tmpList);
217                     if (tmpOrders == null) {
218                         tmpOrders = new ArrayList(1);
219                         varOrderMap.put(tmpList, tmpOrders);
220                     }
221                     tmpOrders.add(orderExpr);
222                 } else {
223                     Variable tmpVar = (Variable) tmpList.get(0);
224                     if (((FLWRExpression) expression).getVariables().contains(tmpVar)) {
225                         int pos = varOrderList.indexOf(tmpVar);
226                         if (pos >= 0 && pos != varOrderList.size() - 1)
227                             varOrderList = null;
228                         else if (pos == -1)
229                             varOrderList.add(tmpVar);
230                         ArrayList tmpOrders = (ArrayList) varOrderMap.get(tmpVar);
231                         if (tmpOrders == null) {
232                             tmpOrders = new ArrayList(1);
233                             varOrderMap.put(tmpVar, tmpOrders);
234                         }
235                         tmpOrders.add(orderExpr);
236                     }
237                 }
238             }
239             if (complexExprOrderList.isEmpty())
240                 complexExprOrderList = null;
241         }
242     }
243
244     /*
245      * private void updateVarListWithDependencies(ArrayList varlist) { updateVarListWithDependencies(varlist, null, false); }
246      */

247     private void updateVarListWithDependencies(ArrayList varlist, ArrayList rangelist, boolean reorder) {
248         if (varlist == null || varlist.isEmpty())
249             return;
250         int i = 0;
251         while (i < varlist.size()) {
252             Variable tmpVari = (Variable) varlist.get(i);
253             Algebra tmpNode = algManager.getMapNode(tmpVari);
254             if (tmpNode != null) {
255                 ArrayList tmpList = tmpNode.getVarsDependingOn();
256                 if (tmpList != null) {
257                     for (int j = 0; j < tmpList.size(); j++) {
258                         Variable tmpVarj = (Variable) tmpList.get(j);
259                         if (rangelist != null && !rangelist.contains(tmpVarj))
260                             continue;
261                         int posj = varlist.indexOf(tmpVarj);
262                         if (posj > i) {
263                             varlist.remove(tmpVarj);
264                             varlist.add(i, tmpVarj);
265                             if (reorder) {
266                                 if (!varReOrderList.contains(tmpVari))
267                                     varReOrderList.add(tmpVari);
268                                 if (!varReOrderList.contains(tmpVarj))
269                                     varReOrderList.add(tmpVarj);
270                             }
271                             i--;
272                             break;
273                         } else if (posj == -1) {
274                             varlist.add(i, tmpVarj);
275                             i--;
276                             break;
277                         }
278                     }
279                 }
280             }
281             i++;
282         }
283     }
284
285     private void verifyVarOrderList() {
286         if (varOrderList == null) {
287             varOrderList = ((FLWRExpression) expression).getVariables();
288             if (((FLWRExpression) expression).getOrderBy() != null)
289                 varReOrderList = ((FLWRExpression) expression).getVariables();
290         } else {
291             varReOrderList = new ArrayList();
292             // manage depending on variables
293
int i = 0;
294             while (i < varOrderList.size()) {
295                 Variable tmpVari = (Variable) varOrderList.get(i);
296                 Algebra tmpNode = algManager.getMapNode(tmpVari);
297                 ArrayList tmpList = tmpNode.getVarsDependingOn();
298                 if (tmpList != null) {
299                     for (int j = 0; j < tmpList.size(); j++) {
300                         Variable tmpVarj = (Variable) tmpList.get(j);
301                         int posj = varOrderList.indexOf(tmpVarj);
302                         if (posj > i) {
303                             varOrderList.remove(tmpVarj);
304                             varOrderList.add(i, tmpVarj);
305                             if (!varReOrderList.contains(tmpVari))
306                                 varReOrderList.add(tmpVari);
307                             if (!varReOrderList.contains(tmpVarj))
308                                 varReOrderList.add(tmpVarj);
309                             i--;
310                             break;
311                         } else if (posj == -1) {
312                             varOrderList.add(i, tmpVarj);
313                             i--;
314                             break;
315                         }
316                     }
317                 }
318                 i++;
319             }
320             if (varReOrderList.isEmpty())
321                 varReOrderList = null;
322             // manage other variables
323
ArrayList varlist = ((FLWRExpression) expression).getVariables();
324             if (varOrderList.size() < varlist.size()) {
325                 for (i = 0; i < varlist.size(); i++) {
326                     if (!varOrderList.contains(varlist.get(i))) {
327                         varOrderList.add(varlist.get(i));
328                     }
329                 }
330             }
331         }
332     }
333
334     private void fillList(ArrayList varlist, ArrayList allvars) {
335         if (varlist.containsAll(allvars))
336             return;
337         for (int i = 0; i < allvars.size(); i++) {
338             if (!varlist.contains(allvars.get(i))) {
339                 varlist.add(allvars.get(i));
340             }
341         }
342     }
343
344     /*
345      * private boolean verifyHintTree(HintTree hinttree) { return verifyHintTree(hinttree, new ArrayList()); } private boolean verifyHintTree(HintTree hinttree, ArrayList hintVarList) { if (hinttree == null) return false; if (hinttree.getType() == HintTree.NESTED_LOOP_TYPE) { if (hinttree.getLeftHint() instanceof HintTree) { if (!verifyHintTree((HintTree) hinttree.getLeftHint(), hintVarList)) return false; } if (hinttree.getLeftHint() instanceof Variable) { hintVarList.add(hinttree.getLeftHint()); } if (hinttree.getRightHint() instanceof HintTree) { if (!verifyHintTree((HintTree) hinttree.getRightHint(), hintVarList)) return false; } if (hinttree.getRightHint() instanceof Variable) { hintVarList.add(hinttree.getRightHint()); } } else if (hinttree.getType() == HintTree.MERGE_TYPE) { ArrayList tmplistleft = (ArrayList) hintVarList.clone(); if (hinttree.getLeftHint() instanceof HintTree) { if (!verifyHintTree((HintTree) hinttree.getLeftHint(), tmplistleft)) return false;
346      * tmplistleft.removeAll(hintVarList); } ArrayList tmplistright = (ArrayList) hintVarList.clone(); if (hinttree.getRightHint() instanceof HintTree) { if (!verifyHintTree((HintTree) hinttree.getRightHint(), tmplistright)) return false; tmplistright.removeAll(hintVarList); } hintVarList.addAll(tmplistleft); hintVarList.addAll(tmplistright); if (hinttree.getLeftHint() instanceof Variable) { hintVarList.add(hinttree.getLeftHint()); } if (hinttree.getRightHint() instanceof Variable) { hintVarList.add(hinttree.getRightHint()); } } return true; }
347      */

348
349     private boolean verifyVarHintList() {
350         if (varHintList == null)
351             return false;
352         ArrayList vars = ((FLWRExpression) expression).getVariables();
353         // verifying all variables of the hint tree are declared in flwr
354
if (!vars.containsAll(varHintList))
355             return false;
356         // verifying that all variables are used only once
357
for (int i = 0; i < varHintList.size(); i++) {
358             if (varHintList.lastIndexOf(varHintList.get(i)) != i)
359                 return false;
360         }
361         // get all variables in vars but not in varlist
362
ArrayList remainvars = (ArrayList) vars.clone();
363         remainvars.removeAll(varHintList);
364         if (!remainvars.isEmpty()) {
365             updateVarListWithDependencies(remainvars, remainvars, false);
366         }
367         // verifying that variables in hint are bound to DepNodeSource on collections
368
for (int i = 0; i < varHintList.size(); i++) {
369             Variable vari = (Variable) vars.get(i);
370             if (vari.getBindingType() != Constants.FOR_BINDINGTYPE)
371                 return false;
372             XQueryExpression expri = vari.getExpression();
373             if (expri instanceof LocatedExpression)
374                 expri = ((LocatedExpression) expri).getExpression();
375             if (!(expri instanceof FunctionCOLLECTION))
376                 return false;
377         }
378
379         /*
380          * // verifying that all variables of the flwr are used in the hint tree for (int i = 0; i < vars.size(); i++) { Variable vari = (Variable) vars.get(i); if (vari.getBindingType() == Constants.FOR_BINDINGTYPE && !varHintList.contains(vari)) return false; // for now no let if (vari.getBindingType() == Constants.LET_BINDINGTYPE) return false; // if (vari.getBindingType() == Constants.LET_BINDINGTYPE && varHintList.contains(vari)) // return false; }
381          */

382         return true;
383     }
384
385     private boolean updateVarHintList(HintTree hinttree) {
386         if (hinttree == null)
387             return false;
388         ArrayList vars = ((FLWRExpression) expression).getVariables();
389         /*
390          * Object obj = hinttree.getLeftHint(); if (obj instanceof HintTree) updateVarListWithDependencies(((HintTree)obj).getVarList(),vars,false); obj = hinttree.getRightHint(); if (obj instanceof HintTree) updateVarListWithDependencies(((HintTree)obj).getVarList(),vars,false);
391          */

392         updateVarListWithDependencies(hinttree.getVarList(), vars, false);
393         return true;
394     }
395
396     private void compeReOrdering(boolean hasMerge, ArrayList varList) {
397         if (hasMerge)
398             //varReOrderList = (ArrayList) hint.getVarList().clone();
399
varReOrderList = (ArrayList) ((FLWRExpression) expression).getVariables().clone();
400         else {
401             if (varOrderList == null || varOrderList.isEmpty())
402                 return;
403             ArrayList tmplist = (ArrayList) ((FLWRExpression) expression).getVariables().clone();
404             tmplist.removeAll(varList);
405             tmplist.addAll(0, varList);
406             if (varReOrderList == null)
407                 varReOrderList = new ArrayList();
408             else
409                 varReOrderList.clear();
410             int pos = -1;
411             for (int j = 0; j < tmplist.size(); j++) {
412                 Variable tmpVarj = (Variable) tmplist.get(j);
413                 int posj = varOrderList.indexOf(tmpVarj);
414                 if (posj > pos)
415                     pos = posj;
416                 else
417                     for (int i = 0; i < tmplist.size(); i++) {
418                         Variable tmpVari = (Variable) tmplist.get(i);
419                         if (!varReOrderList.contains(tmpVari))
420                             varReOrderList.add(tmpVari);
421                     }
422             }
423             if (varReOrderList.isEmpty())
424                 varReOrderList = null;
425         }
426     }
427
428     /*
429      * private boolean computeVarHintList(HintTree hinttree) { if (hinttree == null) return false; Object obj = hinttree.getLeftHint(); if (obj instanceof Variable) { if (varHintList.contains(obj)) return false; else varHintList.add(obj); } else computeVarHintList((HintTree) obj); obj = hinttree.getRightHint(); if (obj instanceof Variable) { if (varHintList.contains(obj)) return false; else varHintList.add(obj); } else computeVarHintList((HintTree) obj); return true; }
430      */

431
432     public void makeInformation() throws MediatorException {
433         if (hasInformation)
434             return;
435         hasInformation = true;
436         // verify that all children have only one variable
437
if (!isMonoSource()) {
438             if (algChildren != null) {
439                 for (int i = 0; i < algChildren.size(); i++)
440                     if (((Algebra) algChildren.get(i)).getVariables().size() != 1)
441                         throw new MediatorException("Found DepNode of more than one variable as child of DepFLWR");
442             }
443         } else {
444             if (hinttree != null) {
445                 if (hinttree.getOuterType() != HintTree.NO_TYPE)
446                     hinttree.setType(HintTree.NO_TYPE);
447             }
448         }
449         // gather information on joins if any (where clause)
450

451         XQueryExpression wexpr = ((FLWRExpression) expression).getWhereClause();
452         if (wexpr != null) {
453             vardependencies = new VariableDependencies(wexpr);
454             // if (awvisitor == null)
455
// awvisitor = new AtomizeWhereVisitor();
456
// try {
457
// wexpr.accept(awvisitor);
458
// } catch (XQueryException e) {
459
// throw new MediatorException("Could not atomize where clause : " + wexpr, e);
460
// }
461
// varVarWhereMap = awvisitor.getVarVarMap();
462
// allExprWhereList = awvisitor.getAllExprList();
463
// complexExprWhereList = awvisitor.getComplexExprList();
464
}
465         // gather inforamtion on hint tree if any
466
if (hinttree != null && hinttree.getType() != HintTree.NO_TYPE) {
467             varHintList = hinttree.getVarList();
468             if (updateVarHintList(hinttree)) {
469                 if (verifyVarHintList()) {
470                 } else {
471                     hinttree = null;
472                 }
473             } else {
474                 hinttree = null;
475             }
476         }
477         computeVarOrderList();
478         if (hinttree != null)
479             compeReOrdering(hinttree.hasMerge(), hinttree.getVarList());
480         else
481             compeReOrdering(algManager.getPlan().getDefaultSubHandling() == HintTree.MERGE_TYPE, ((FLWRExpression) expression).getVariables());
482     }
483
484     public XQueryExpression getWhereClause() {
485         return ((FLWRExpression) expression).getWhereClause();
486     }
487
488     public VariableDependencies getVarDependencies() {
489         return vardependencies;
490     }
491
492     // ******************************************************************
493
// * CREATE EXECUTION PLAN
494
// ******************************************************************
495
// some documentation
496
/*
497      * for now hint tree only applies on FLWR expressions (not nested for now)
498      *
499      * if (hint tree is correct) for now correct hint tree means that all (for) variables present in the FLWR expression are also present in the hint tree (let) variables are simply merged
500      *
501      * if (hint tree is not present or hint tree is incorrect) variables are ordered in the following order first get the order implied by the order by clauses if any and if possible insert all depending on variables add all variables not in this list make list of variables to be reordered (because of dependencies)
502      */

503
504     //##################################################################################################################################
505
//##################################################################################################################################
506
//##################################################################################################################################
507
private Operator createVarsOperator(ExecutionPlan plan, Operator operator, List varlist, List vars) throws MediatorException {
508         //##################################################################################################################################
509
//##################################################################################################################################
510
//##################################################################################################################################
511
for (int i = 0; i < vars.size(); i++) {
512             operator = createVarOperator(plan, operator, varlist, (Variable) vars.get(i));
513         }
514         return operator;
515     }
516
517     //##################################################################################################################################
518
//##################################################################################################################################
519
//##################################################################################################################################
520
private Operator createVarOperator(ExecutionPlan plan, Operator operator, List varlist, Variable var) throws MediatorException {
521         //##################################################################################################################################
522
//##################################################################################################################################
523
//##################################################################################################################################
524
// getting child
525
Algebra depchildi = algManager.getMapNode(var);
526         XQueryExpression depchildiexpr = depchildi.getExpression();
527         //ArrayList varidependingon = (ArrayList) depchildi.getVarsDependingOn().clone();
528
Variable vari = (Variable) depchildi.getVariables().get(0);
529         if (!isMonoSource())
530             algManager.addVarToScope(vari);
531         else
532             algManager.addVarsToScope(depchildi.getVariables());
533         boolean isleti = depchildi.isLet();
534         varlist.add(vari);
535         // if (log.isDebugEnabled()) {
536
// log.debug("*********** DEPFLWR CHILD STUFF *************************");
537
// log.debug("ClassName = " + depchildi.getClass().getName());
538
// log.debug("is let = " + depchildi.isLet());
539
// log.debug("depchildiexpr = " + depchildiexpr);
540
// log.debugt("vari = " + vari);
541
// log.debug("allVars = " + algManager.getScopeVariables());
542
// log.debug("definition vars depending on = " + depchildi.getVarsDependingOn());
543
// log.debug("where vars depending on = " + depchildi.getVarsWhereOn());
544
// log.debug("vars referenced by = " + depchildi.getVarsReferencedBy());
545
// log.debugt("children = " + depchildi.getChildren());
546
// log.debug("var dependencies = " + vardependencies);
547
// log.debug("---------------------------------------------------------");
548
// }
549
// add where dependencies
550
if (vardependencies != null) {
551             ArrayList tmplist = vardependencies.getAllAssociatedVariables(vari);
552             if (tmplist != null) {
553                 for (int i = 0; i < tmplist.size(); i++) {
554                     Variable tmpvari = (Variable) tmplist.get(i);
555                     if (algManager.getScopeVariables().contains(tmpvari)) {
556                         if (depchildiexpr instanceof FLWRExpression && ((FLWRExpression) depchildiexpr).getVariables().contains(tmpvari)) {
557                             if (!depchildi.getVarsWhereOn().contains(tmpvari))
558                                 depchildi.getVarsWhereOn().add(tmpvari);
559                         } else {
560                             if (!depchildi.getVarsDependingOn().contains(tmpvari))
561                                 depchildi.getVarsDependingOn().add(tmpvari);
562                         }
563                     }
564
565                 }
566             }
567         }
568         boolean doSort = false;
569         if (operator == null) {
570             if (depchildi instanceof AlgLocated || depchildi instanceof AlgVar || depchildi instanceof AlgArithFunction)
571                 //algebra = new AlgNotSource(plan,depchildi.getExpression(),var,depchildi.isLet(),depchildi.hasIdentifier());
572
operator = new OpNotSource(plan, depchildi);
573             else
574                 operator = (Operator) depchildi.createOperator(plan);
575             doSort = true;
576         } else {
577             if (!depchildi.getDepends()) {
578                 Operator tmpOp = depchildi.createOperator(plan);
579                 // test if sort clause and not source -> then sort in place !!!
580
if (!(depchildi instanceof AlgSource) && varOrderMap != null) {
581                     ArrayList orders = (ArrayList) varOrderMap.get(vari);
582                     if (orders != null)
583                         tmpOp = new OpSort(plan, tmpOp, orders);
584                 }
585                 if (isleti) {
586                     operator = new OpMerge(plan, depchildiexpr, operator, tmpOp);
587                 } else {
588                     operator = new OpCartesian(plan, depchildiexpr, operator, tmpOp);
589                 }
590             } else { // varidependingon is not empty
591
if (depchildi instanceof AlgLocated || depchildi instanceof AlgVar || depchildi instanceof AlgArithFunction) {
592                     //algebra = new AlgSimpleMerge(plan, depchildiexpr, vari, algebra, depchildi.isLet());
593
operator = new OpSimpleMerge(plan, depchildi, operator);
594                     doSort = true;
595                 } else if (depchildi instanceof AlgFunction && depchildi.getChildren() == null) {
596                     operator = new OpSimpleMerge(plan, depchildiexpr, vari, operator, depchildi.isLet());
597                     doSort = true;
598                 } else {
599                     Operator[] tmplist = new Operator[2];
600                     tmplist[0] = operator;
601                     Operator tmpOp = depchildi.createOperator(plan);
602                     // test if sort clause and not source -> then sort in place !!!
603
if (!(depchildi instanceof AlgSource) && varOrderMap != null) {
604                         ArrayList orders = (ArrayList) varOrderMap.get(vari);
605                         if (orders != null)
606                             tmpOp = new OpSort(plan, tmpOp, orders);
607                     }
608                     tmpOp.setDepends(depchildi);
609                     tmplist[1] = tmpOp;
610                     operator = new OpSubQuery(plan, depchildiexpr, tmplist, true, false);
611                 }
612
613             }
614         }
615         // handle restriction if any
616

617         XQueryExpression tmpExpr = ((FLWRExpression) expression).getWhereClause();
618         if (tmpExpr != null) {
619             if (operator instanceof OpSource || operator instanceof OpSubQuery) {
620                 if (isolateVisitor == null)
621                     isolateVisitor = new IsolateWhereVisitor(algManager.getScopeVariables());
622                 else
623                     isolateVisitor.reset(algManager.getScopeVariables());
624                 isolateVisitor.putVar(true);
625                 try {
626                     tmpExpr.accept(isolateVisitor);
627                 } catch (XQueryException e) {
628                     throw new MediatorException("Can't isolate where expression : " + tmpExpr, e);
629                 }
630
631                 tmpExpr = isolateVisitor.getIsolatedExpression();
632                 if (tmpExpr != null) {
633                     operator = operator.addCondition(plan, tmpExpr);
634                     //operator = new OpRestrict(plan, tmpExpr, operator);
635
}
636                 ((FLWRExpression) expression).setWhereClause(isolateVisitor.getRemainingExpression());
637             } else {
638
639                 if (isolateVisitor == null)
640                     isolateVisitor = new IsolateWhereVisitor(algManager.getScopeVariables());
641                 else
642                     isolateVisitor.reset(algManager.getScopeVariables());
643                 isolateVisitor.putVar(true);
644                 try {
645                     tmpExpr.accept(isolateVisitor);
646                 } catch (XQueryException e) {
647                     throw new MediatorException("Can't isolate where expression : " + tmpExpr, e);
648                 }
649
650                 tmpExpr = isolateVisitor.getIsolatedExpression();
651                 if (tmpExpr != null) {
652                     operator = operator.addCondition(plan, tmpExpr);
653                     //algebra = new OpRestrict(plan, tmpExpr, algebra);
654
}
655                 ((FLWRExpression) expression).setWhereClause(isolateVisitor.getRemainingExpression());
656
657             }
658         }
659         // test if sort clause and not source -> then sort in place !!!
660
if (doSort && !(depchildi instanceof AlgSource) && varOrderMap != null) {
661             ArrayList orders = (ArrayList) varOrderMap.get(vari);
662             if (orders != null)
663                 operator = new OpSort(plan, operator, orders);
664         }
665         return operator;
666     }
667
668     // utility
669
private boolean extractConditionsfromMap(VariableDependencies dep, List varListLeft, List varListRight, ArrayList leftExpressions, ArrayList rightExpressions, ArrayList mergeRestrictions, ArrayList otherRestrictions) {
670         boolean hasnoteq = false;
671         for (int il = 0; il < varListLeft.size(); il++) {
672             Variable leftvar = (Variable) varListLeft.get(il);
673             if (vardependencies != null) {
674                 HashMap tmpmap = vardependencies.getJoinMap(leftvar);
675                 if (tmpmap != null) {
676                     // there is at least something because of hint tree verification
677
for (int ir = 0; ir < varListRight.size(); ir++) {
678                         Variable rightvar = (Variable) varListRight.get(ir);
679                         ArrayList tmplist = (ArrayList) tmpmap.get(rightvar);
680                         if (tmplist != null) {
681                             for (int i = 0; i < tmplist.size(); i++) {
682                                 XQueryExpression tmpexpr = (XQueryExpression) tmplist.get(i);
683                                 if (tmpexpr instanceof ListOpCompExpression) {
684                                     ListOpCompExpression listopcomp = (ListOpCompExpression) tmpexpr;
685                                     XQueryExpression expr1 = listopcomp.getExpression1();
686                                     XQueryExpression expr2 = listopcomp.getExpression2();
687                                     if ((expr1 instanceof LocatedExpression || expr1 instanceof Variable) && (expr2 instanceof LocatedExpression || expr2 instanceof Variable)) {
688                                         if (listopcomp.getOperator() == Constants.EQ_COMPOP) {
689                                             //if (((LocatedExpression) expr1).startsWith((Variable) rightvar) && ((LocatedExpression) expr2).startsWith((Variable) leftvar)) {
690
// change LARS 11/03/04
691
if (((expr1 instanceof LocatedExpression && ((LocatedExpression) expr1).startsWith(rightvar)) || expr1 == rightvar) && ((expr2 instanceof LocatedExpression && ((LocatedExpression) expr2).startsWith(leftvar)) || expr2 == leftvar)) {
692                                                 XQueryExpression bufexpr = expr2;
693                                                 try {
694                                                     listopcomp.setExpression2(expr1);
695                                                     listopcomp.setExpression1(bufexpr);
696                                                 } catch (XQueryException e) {
697                                                 }
698                                             }
699                                             if (hasnoteq) {
700                                                 leftExpressions.add(mergeRestrictions.size() - 1, listopcomp.getExpression1());
701                                                 rightExpressions.add(mergeRestrictions.size() - 1, listopcomp.getExpression2());
702                                                 mergeRestrictions.add(mergeRestrictions.size() - 1, listopcomp);
703                                             } else {
704                                                 leftExpressions.add(listopcomp.getExpression1());
705                                                 rightExpressions.add(listopcomp.getExpression2());
706                                                 mergeRestrictions.add(listopcomp);
707                                             }
708                                         } else if (!hasnoteq && (listopcomp.getOperator() == Constants.GEQ_COMPOP || listopcomp.getOperator() == Constants.GT_COMPOP || listopcomp.getOperator() == Constants.LEQ_COMPOP || listopcomp.getOperator() == Constants.LT_COMPOP)) {
709                                             hasnoteq = true;
710                                             //if (((LocatedExpression) expr1).startsWith((Variable) rightvar) && ((LocatedExpression) expr2).startsWith((Variable) leftvar)) {
711
// change LARS 11/03/04
712
if (((expr1 instanceof LocatedExpression && ((LocatedExpression) expr1).startsWith(rightvar)) || expr1 == rightvar) && ((expr2 instanceof LocatedExpression && ((LocatedExpression) expr2).startsWith(leftvar)) || expr2 == leftvar)) {
713                                                 XQueryExpression bufexpr = expr2;
714                                                 try {
715                                                     listopcomp.setExpression2(expr1);
716                                                     listopcomp.setExpression1(bufexpr);
717                                                     if (listopcomp.getOperator() == Constants.GEQ_COMPOP)
718                                                         listopcomp.setOperator(Constants.LEQ_COMPOP);
719                                                     else if (listopcomp.getOperator() == Constants.GT_COMPOP)
720                                                         listopcomp.setOperator(Constants.LT_COMPOP);
721                                                     else if (listopcomp.getOperator() == Constants.LEQ_COMPOP)
722                                                         listopcomp.setOperator(Constants.GEQ_COMPOP);
723                                                     else if (listopcomp.getOperator() == Constants.LT_COMPOP)
724                                                         listopcomp.setOperator(Constants.GT_COMPOP);
725                                                 } catch (XQueryException e) {
726                                                 }
727                                             }
728                                             leftExpressions.add(listopcomp.getExpression1());
729                                             rightExpressions.add(listopcomp.getExpression2());
730                                             mergeRestrictions.add(listopcomp);
731                                         } else if (otherRestrictions != null)
732                                             otherRestrictions.add(listopcomp);
733
734                                     } else if (otherRestrictions != null)
735                                         otherRestrictions.add(listopcomp);
736                                 } else if (otherRestrictions != null)
737                                     otherRestrictions.add(tmpexpr);
738                             }
739                         }
740                     }
741                 }
742                 // change LARS 11/03/04 all conditions -> complex conditions
743
ArrayList conds = vardependencies.getAllComplexConditionsWithVar(leftvar);
744                 if (conds != null)
745                     for (int i = 0; i < conds.size(); i++)
746                         if (!otherRestrictions.contains(conds.get(i)))
747                             otherRestrictions.add(conds.get(i));
748             }
749         }
750         return hasnoteq;
751     }
752
753     //##################################################################################################################################
754
//##################################################################################################################################
755
//##################################################################################################################################
756
private ArrayList getMainDependVars(Variable var) {
757         ArrayList reslist = null;
758         ArrayList tmplist = algManager.getMapNode(var).getVarsDependingOn();
759         if (tmplist != null) {
760             reslist = new ArrayList(1);
761             for (int i = 0; i < tmplist.size(); i++) {
762                 ArrayList list = getMainDependVars((Variable) tmplist.get(i));
763                 if (list != null)
764                     reslist.addAll(list);
765                 else
766                     reslist.add(tmplist.get(i));
767             }
768             if (reslist.isEmpty())
769                 reslist = null;
770         }
771         return reslist;
772     }
773
774     private Operator createOperator(ExecutionPlan plan, HintTree hint, List vars) throws MediatorException {
775         return createOperator(plan, hint, plan.getDefaultSubHandling(), vars);
776     }
777
778     private Operator createOperator(ExecutionPlan plan, HintTree hint, byte defaultHintType, List vars) throws MediatorException {
779         //##################################################################################################################################
780
//##################################################################################################################################
781
//##################################################################################################################################
782

783         //int typ = getAlgebraManager().getPlan().getDefaultSubHandling();
784
byte hintType = defaultHintType;
785         Object JavaDoc left = null;
786         Object JavaDoc right = null;
787         List varListLeft = null;
788         List varListRight = null;
789         boolean hasLeftloop = false;
790         boolean hasRightLoop = false;
791         if (hint != null && hint.getType() != HintTree.NO_TYPE) {
792             hintType = hint.getType();
793             left = hint.getLeftHint();
794             right = hint.getRightHint();
795
796             if (left instanceof Variable) {
797                 varListLeft = new ArrayList(1);
798                 varListLeft.add(left);
799             } else
800                 varListLeft = ((HintTree) left).getVarList();
801
802             if (right instanceof Variable) {
803                 varListRight = new ArrayList(1);
804                 varListRight.add(right);
805             } else
806                 varListRight = ((HintTree) right).getVarList();
807         } else if (vars != null) {
808             if (vars.size() < 2)
809                 return null;
810             else {
811                 // TODO make better division whenever possible
812
// 1. find source variables
813
// 2. associate all depending variables
814
// find restriction
815
// find joins
816

817                 boolean hasJoinMap = (vardependencies != null && vardependencies.getJoinsMap() != null && !vardependencies.getJoinsMap().isEmpty());
818                 
819                 varListLeft = new ArrayList();
820                 for (int i = 0; i < vars.size(); i++) {
821                     Variable vari = (Variable) vars.get(i);
822                     if (varListRight == null) {
823                         varListLeft.add(vari);
824                         if (!hasLeftloop && vari.getBindingType() == Constants.FOR_BINDINGTYPE)
825                             hasLeftloop = true;
826                         if (hasJoinMap) {
827                             Map tmpmap = vardependencies.getJoinMap(vari);
828                             if (tmpmap != null) {
829                                 boolean found = false;
830                                 for (Iterator it = tmpmap.keySet().iterator(); it.hasNext();) {
831                                     if (vars.contains(it.next())) {
832                                         found = true;
833                                         break;
834                                     }
835                                 }
836                                 if (found)
837                                     varListRight = new ArrayList();
838                             }
839                         }
840                     } else {
841                         ArrayList depends = getMainDependVars(vari);
842                         if (depends != null) {
843                             if (varListLeft.containsAll(depends)) {
844                                 varListLeft.add(vari);
845                                 if (!hasLeftloop && vari.getBindingType() == Constants.FOR_BINDINGTYPE)
846                                     hasLeftloop = true;
847                             } else if (varListRight.containsAll(depends)) {
848                                 varListRight.add(vari);
849                                 if (!hasRightLoop && vari.getBindingType() == Constants.FOR_BINDINGTYPE)
850                                     hasRightLoop = true;
851                             } else
852                                 return null;
853                         } else {
854                             varListRight.add(vari);
855                             if (!hasRightLoop && vari.getBindingType() == Constants.FOR_BINDINGTYPE)
856                                 hasRightLoop = true;
857                         }
858                     }
859                 }
860                 if (varListRight == null || varListRight.isEmpty())
861                     return null;
862                 if (hintType == HintTree.MERGE_TYPE) {
863                     if (!hasLeftloop || !hasRightLoop) {
864                         hintType = HintTree.NESTED_LOOP_TYPE;
865                     }
866                 }
867                 // exchange left and right if left has loop and right has not
868
if (hintType == HintTree.NESTED_LOOP_TYPE) {
869                     if (hasLeftloop || !hasRightLoop) {
870                         List tmpVarList = varListRight;
871                         varListRight = varListLeft;
872                         varListLeft = tmpVarList;
873                     }
874                 }
875                 // if (hintType == HintTree.MERGE_TYPE) {
876
// // test if simple joins exist
877
// if (vardependencies == null || vardependencies.getJoinsMap() == null || vardependencies.getJoinsMap().isEmpty())
878
// return null;
879
// varListLeft = new ArrayList();
880
// boolean hasLeftloop = false;
881
// boolean hasRightLoop = false;
882
// for (int i = 0; i < vars.size(); i++) {
883
// Variable vari = (Variable) vars.get(i);
884
// if (varListRight == null) {
885
// varListLeft.add(vari);
886
// if (!hasLeftloop && vari.getBindingType() == Constants.FOR_BINDINGTYPE)
887
// hasLeftloop = true;
888
// Map tmpmap = vardependencies.getJoinMap(vari);
889
// if (tmpmap != null) {
890
// boolean found = false;
891
// for (Iterator it = tmpmap.keySet().iterator(); it.hasNext();) {
892
// if (vars.contains(it.next())) {
893
// found = true;
894
// break;
895
// }
896
// }
897
// if (found)
898
// varListRight = new ArrayList();
899
// }
900
// } else {
901
// ArrayList depends = getMainDependVars(vari);
902
// if (depends != null) {
903
// if (varListLeft.containsAll(depends)) {
904
// varListLeft.add(vari);
905
// if (!hasLeftloop && vari.getBindingType() == Constants.FOR_BINDINGTYPE)
906
// hasLeftloop = true;
907
// } else if (varListRight.containsAll(depends)) {
908
// varListRight.add(vari);
909
// if (!hasRightLoop && vari.getBindingType() == Constants.FOR_BINDINGTYPE)
910
// hasRightLoop = true;
911
// } else
912
// return null;
913
// } else {
914
// varListRight.add(vari);
915
// if (!hasRightLoop && vari.getBindingType() == Constants.FOR_BINDINGTYPE)
916
// hasRightLoop = true;
917
// }
918
// }
919
// }
920
// if (!hasLeftloop || !hasRightLoop)
921
// return null;
922
// if (varListRight == null || varListRight.isEmpty())
923
// return null;
924
// } else if (hintType == HintTree.NESTED_TYPE) {
925
// return null;
926
// }
927
}
928         } else
929             return null;
930
931         if (hintType == HintTree.MERGE_TYPE) {
932             ArrayList mergeRestrictions = new ArrayList(1);
933             ArrayList otherRestrictions = new ArrayList(1);
934             ArrayList leftExpressions = new ArrayList(1);
935             ArrayList rightExpressions = new ArrayList(1);
936             boolean hasnoteq = false;
937             if (hint != null || vars.size() >= 2)
938                 hasnoteq = extractConditionsfromMap(vardependencies, varListLeft, varListRight, leftExpressions, rightExpressions, mergeRestrictions, otherRestrictions);
939
940             if (mergeRestrictions.isEmpty() && otherRestrictions.isEmpty()) {
941                 // change 23/06/2003
942
ArrayList varlist = new ArrayList();
943                 Operator leftAlg = null;
944                 if (varListLeft.size() == 1)
945                     leftAlg = createVarOperator(plan, null, varlist, (Variable) varListLeft.get(0));
946                 else {
947                     leftAlg = createOperator(plan, (HintTree) hint.getLeftHint(), null);
948                     if (leftAlg == null)
949                         leftAlg = createVarsOperator(plan, null, varlist, varListLeft);
950                 }
951                 varlist.removeAll(varListLeft);
952                 algManager.removeVarsFromScope(varListLeft);
953                 Operator rightAlg = null;
954                 if (varListRight.size() == 1)
955                     rightAlg = createVarOperator(plan, null, varlist, (Variable) varListRight.get(0));
956                 else {
957                     rightAlg = createOperator(plan, null, varListRight);
958                     if (rightAlg == null)
959                         rightAlg = createVarsOperator(plan, null, varlist, varListRight);
960                 }
961                 algManager.addVarsToScope(varListLeft);
962                 algManager.addVarsToScope(varListRight);
963                 return new OpCartesian(plan, expression, leftAlg, rightAlg);
964             }
965
966             // ATTENTION erase these conditions from dependencies to avoid having them used several times
967
for (int i = 0; i < otherRestrictions.size(); i++) {
968                 XQueryExpression otheri = (XQueryExpression) otherRestrictions.get(i);
969                 ArrayList tmplist = vardependencies.getVarsOfCond(otheri);
970                 for (int j = 0; j < tmplist.size(); j++) {
971                     Variable varj = (Variable) tmplist.get(j);
972                     // change LARS 11/03/04 all condition -> complex condition
973
ArrayList varjlist = vardependencies.getAllComplexConditionsWithVar(varj);
974                     if (varjlist != null)
975                         varjlist.remove(otheri);
976                 }
977             }
978
979             if (mergeRestrictions.isEmpty()) {
980             }
981             if (hasnoteq) {
982                 ListOpCompExpression listopcomp = (ListOpCompExpression) mergeRestrictions.get(mergeRestrictions.size() - 1);
983                 if (listopcomp.getOperator() == Constants.LT_COMPOP || listopcomp.getOperator() == Constants.LEQ_COMPOP) {
984                     ((XQueryExpression) leftExpressions.get(mergeRestrictions.size() - 1)).setOrder(Constants.DESCENDING_ORDER);
985                     ((XQueryExpression) rightExpressions.get(mergeRestrictions.size() - 1)).setOrder(Constants.DESCENDING_ORDER);
986                 }
987             }
988
989             ArrayList varlist = new ArrayList();
990             Operator leftAlg = null;
991             if (hint == null) {
992                 // left = vars.get(0);
993
// leftAlg = createVarOperator(plan, null, varlist, (Variable) left);
994
// varlist.remove(left);
995
// algManager.removeVarFromScope((Variable) left);
996
// change LARS 11/03/04
997
leftAlg = createOperator(plan, null, defaultHintType, varListLeft);
998                 if (leftAlg == null) {
999                     leftAlg = createVarsOperator(plan, null, varlist, varListLeft);
1000                    varlist.removeAll(varListLeft);
1001                }
1002                algManager.removeVarsFromScope(varListLeft);
1003            } else if (left instanceof Variable) {
1004                leftAlg = createVarOperator(plan, null, varlist, (Variable) left);
1005                varlist.remove(left);
1006                algManager.removeVarFromScope((Variable) left);
1007            } else {
1008                leftAlg = createOperator(plan, (HintTree) left, null);
1009                if (leftAlg == null)
1010                    leftAlg = createVarsOperator(plan, null, varlist, varListLeft);
1011                algManager.removeVarsFromScope(((HintTree) left).getVarList());
1012                //leftAlg = new AlgSort(plan, leftAlg, leftExpressions);
1013
}
1014            if (!leftExpressions.isEmpty()) {
1015                if (!(leftAlg instanceof OpSort))
1016                    leftAlg = new OpSort(plan, leftAlg, leftExpressions);
1017                leftAlg.addIndexSpec(leftExpressions);
1018            }
1019            Operator rightAlg = null;
1020            if (hint == null) {
1021                // if (vars.size() == 2) {
1022
// rightAlg = createVarOperator(plan, null, varlist, (Variable) vars.get(1));
1023
// } else {
1024
// rightAlg = createOperator(plan, null, vars.subList(1, vars.size()));
1025
// algManager.removeVarsFromScope(vars.subList(1, vars.size()));
1026
// }
1027
// change LARS 11/03/04
1028
rightAlg = createOperator(plan, null, hintType, varListRight);
1029                if (rightAlg == null) {
1030                    rightAlg = createVarsOperator(plan, null, varlist, varListRight);
1031                    varlist.removeAll(varListRight);
1032                }
1033                algManager.removeVarsFromScope(varListRight);
1034            } else if (right instanceof Variable) {
1035                rightAlg = createVarOperator(plan, null, varlist, (Variable) right);
1036                //varlist.clear();
1037
//depmanager.removeVarFromScope((Variable) right);
1038
} else {
1039                rightAlg = createOperator(plan, (HintTree) right, null);
1040                if (rightAlg == null)
1041                    rightAlg = createVarsOperator(plan, null, varlist, varListRight);
1042                algManager.removeVarsFromScope(((HintTree) right).getVarList());
1043                //rightAlg = new AlgSort(plan, rightAlg, rightExpressions);
1044
}
1045            if (!rightExpressions.isEmpty()) {
1046                if (!(rightAlg instanceof OpSort))
1047                    rightAlg = new OpSort(plan, rightAlg, rightExpressions);
1048                rightAlg.addIndexSpec(rightExpressions);
1049            }
1050            Operator operator = null;
1051            if (mergeRestrictions.isEmpty())
1052                operator = new OpCartesian(plan, expression, leftAlg, rightAlg);
1053            else {
1054                operator = new OpSortMerge(plan, leftAlg, rightAlg, mergeRestrictions);
1055            }
1056            // add restriction if necessary
1057
if (!otherRestrictions.isEmpty()) {
1058                XQueryExpression tmpexpr = null;
1059                if (otherRestrictions.size() == 1)
1060                    tmpexpr = (XQueryExpression) otherRestrictions.get(0);
1061                else {
1062                    try {
1063                        tmpexpr = new BinOpANDExpression((XQueryExpression) otherRestrictions.get(0), (XQueryExpression) otherRestrictions.get(1), expression.getParentModule());
1064                        for (int i = 2; i < otherRestrictions.size(); i++)
1065                            tmpexpr = new BinOpANDExpression(tmpexpr, (XQueryExpression) otherRestrictions.get(i), expression.getParentModule());
1066                    } catch (XQueryException e) {
1067                        throw new MediatorException("Could not build where clause", e);
1068                    }
1069                }
1070                operator = operator.addCondition(plan, tmpexpr);
1071                //operator = new OpRestrict(plan, tmpexpr, operator);
1072
}
1073            // reset scope
1074
algManager.addVarsToScope((hint != null) ? hint.getVarList() : vars);
1075            // reset order list
1076
//((FLWRExpression) expression).getOrderBy().removeAll(rightExpressions);
1077
//((FLWRExpression) expression).getOrderBy().removeAll(leftExpressions);
1078
return operator;
1079        }
1080        if (hintType == HintTree.NESTED_LOOP_TYPE) {
1081            // create algebra
1082
Operator leftOp = null;
1083            ArrayList varlist = new ArrayList();
1084            if (hint == null) {
1085                leftOp = createOperator(plan, null, defaultHintType, varListLeft);
1086                if (leftOp == null)
1087                    leftOp = createVarsOperator(plan, null, varlist, varListLeft);
1088                varlist.addAll(varListLeft);
1089                algManager.addVarsToScope(varListLeft);
1090            } else if (left instanceof Variable) {
1091                //updateVarListWithDependencies(varListLeft, ((FLWRExpression) expression).getVariables());
1092
leftOp = createOperator(plan, null, hintType, varListLeft);
1093                if (leftOp == null)
1094                    leftOp = createVarsOperator(plan, null, varlist, varListLeft);
1095                varlist.addAll(varListLeft);
1096                algManager.addVarToScope((Variable) left);
1097            } else {
1098                leftOp = createOperator(plan, (HintTree) left, null);
1099                if (leftOp == null)
1100                    leftOp = createVarsOperator(plan, null, varlist, varListLeft);
1101                algManager.addVarsToScope(((HintTree) left).getVarList());
1102                varlist.addAll(((HintTree) left).getVarList());
1103            }
1104            Operator rightOp = null;
1105            if (hint == null) {
1106                rightOp = createOperator(plan, null, defaultHintType, varListRight);
1107                if (rightOp == null)
1108                    rightOp = createVarsOperator(plan, null, varlist, varListRight);
1109                varlist.addAll(varListRight);
1110                algManager.addVarsToScope(varListRight);
1111            } else if (right instanceof Variable) {
1112                //updateVarListWithDependencies(varListRight, ((FLWRExpression) expression).getVariables());
1113
rightOp = createOperator(plan, null, hintType, varListRight);
1114                if (rightOp == null)
1115                    rightOp = createVarsOperator(plan, null, varlist, varListRight);
1116                varlist.addAll(varListRight);
1117                algManager.addVarToScope((Variable) right);
1118            } else {
1119                rightOp = createOperator(plan, (HintTree) right, null);
1120                if (rightOp == null)
1121                    rightOp = createVarsOperator(plan, null, varlist, varListRight);
1122                algManager.addVarsToScope(((HintTree) right).getVarList());
1123            }
1124            //if (hint != null)
1125
rightOp.setValueDepends(true);
1126            Operator[] tmplistalg = new Operator[2];
1127            tmplistalg[0] = leftOp;
1128            tmplistalg[1] = rightOp;
1129            return new OpSubQuery(plan, expression, tmplistalg, true, false);
1130        } else {
1131            throw new MediatorException("Unsupported type of hint : " + hintType);
1132        }
1133    }
1134
1135    private void verifySubElements() throws MediatorException {
1136        // rules of sub queries
1137
// if there is no outer hint -> take the default hint for all
1138
// if there is a single nested -> nested for all
1139
// if there is a merge and no nested -> merge for all
1140
if (subDepFLWRs == null || subDepFLWRs.isEmpty())
1141            return;
1142        boolean hasMerge = false;
1143        boolean hasNested = false;
1144        subhandling = HintTree.NO_TYPE; //getDepManager().getPlan().defaultsubqueryhandling;
1145
for (int i = 0; i < subDepFLWRs.size(); i++) {
1146            ((AlgFLWR) subDepFLWRs.get(i)).verifySubElements();
1147        }
1148        if (subhandling != HintTree.NESTED_TYPE) {
1149            for (int i = 0; i < subDepFLWRs.size(); i++) {
1150                AlgFLWR subdepi = (AlgFLWR) subDepFLWRs.get(i);
1151                HintTree ht = ((FLWRExpression) subdepi.getExpression()).getHintTree();
1152                if (ht != null) {
1153                    if (!hasNested && ht.getOuterType() == HintTree.NESTED_TYPE) {
1154                        subhandling = HintTree.NESTED_TYPE;
1155                        hasNested = true;
1156                        break;
1157                    }
1158                    if (!hasMerge && ht.getOuterType() == HintTree.MERGE_TYPE)
1159                        hasMerge = true;
1160                }
1161            }
1162        } else
1163            hasNested = true;
1164
1165        // check that all sub elements have the same sort items for parent element (none is ok too)
1166
if (hasNested)
1167            subhandling = HintTree.NESTED_TYPE;
1168        else if (hasMerge)
1169            subhandling = HintTree.MERGE_TYPE;
1170        else
1171            subhandling = getAlgebraManager().getPlan().getDefaultSubHandling();
1172
1173        algManager.addVarsToScope(getVariables());
1174        for (int i = 0; i < subDepFLWRs.size(); i++) {
1175            AlgFLWR depi = (AlgFLWR) subDepFLWRs.get(i);
1176            depi.makeInformation();
1177        }
1178        // verify that all sub elements can do merge (no condition outside)
1179
IsolateWhereVisitor visitor = new IsolateWhereVisitor();
1180        ArrayList varListLeft = ((FLWRExpression) expression).getVariables();
1181        for (int i = 0; i < subDepFLWRs.size(); i++) {
1182            AlgFLWR depi = (AlgFLWR) subDepFLWRs.get(i);
1183            varListLeft.addAll(((FLWRExpression) depi.getExpression()).getVariables());
1184            visitor.reset(varListLeft);
1185            if (((FLWRExpression) depi.getExpression()).getWhereClause() != null) {
1186                try {
1187                    ((FLWRExpression) depi.getExpression()).getWhereClause().accept(visitor);
1188                } catch (XQueryException e) {
1189                    throw new MediatorException("Could not isolated expression : " + ((FLWRExpression) depi.getExpression()).getWhereClause());
1190                }
1191            }
1192            varListLeft.removeAll(((FLWRExpression) depi.getExpression()).getVariables());
1193
1194            if (visitor.getRemainingExpression() != null) {
1195                if (getParentDepFLWR() != null)
1196                    getParentDepFLWR().setSubHandling(HintTree.NESTED_TYPE);
1197                break;
1198            }
1199        }
1200
1201        algManager.removeVarsFromScope(getVariables());
1202    }
1203
1204    //##################################################################################################################################
1205
//##################################################################################################################################
1206
//##################################################################################################################################
1207
private Operator createOperator(ExecutionPlan plan, ArrayList indexSpecs, ArrayList subRestrictions, ArrayList outsideRestrictions) throws MediatorException {
1208        //##################################################################################################################################
1209
//##################################################################################################################################
1210
//##################################################################################################################################
1211
Operator retval = null;
1212        if (dependDefinitionVars.isEmpty())
1213            retval = createOperator(plan);
1214        else if (((FLWRExpression) expression).getWhereClause() == null)
1215            retval = createOperator(plan);
1216        else if (vardependencies.hasJoins())
1217            retval = createOperator(plan);
1218        else {
1219            ArrayList varListLeft = ((FLWRExpression) getParentDepFLWR().getExpression()).getVariables();
1220            ArrayList varListRight = ((FLWRExpression) getExpression()).getVariables();
1221            ArrayList mergeRestrictions = new ArrayList();
1222            ArrayList otherRestrictions = new ArrayList();
1223            ArrayList leftExpressions = new ArrayList();
1224            ArrayList rightExpressions = new ArrayList();
1225
1226            boolean hasnoteq = extractConditionsfromMap(vardependencies, varListLeft, varListRight, leftExpressions, rightExpressions, mergeRestrictions, otherRestrictions);
1227            if (mergeRestrictions.isEmpty()) {
1228                retval = createOperator(plan);
1229            } else {
1230                if (hasnoteq) {
1231                    ListOpCompExpression listopcomp = (ListOpCompExpression) mergeRestrictions.get(mergeRestrictions.size() - 1);
1232                    if (listopcomp.getOperator() == Constants.LT_COMPOP || listopcomp.getOperator() == Constants.LEQ_COMPOP) {
1233                        ((XQueryExpression) leftExpressions.get(mergeRestrictions.size() - 1)).setOrder(Constants.DESCENDING_ORDER);
1234                        ((XQueryExpression) rightExpressions.get(mergeRestrictions.size() - 1)).setOrder(Constants.DESCENDING_ORDER);
1235                    }
1236                }
1237                // get all conditions only on subquery
1238
for (int i = 0; i < varListLeft.size(); i++) {
1239                    Variable vari = (Variable) varListLeft.get(i);
1240                    HashMap tmpmap = (HashMap) vardependencies.getJoinsMap().get(vari);
1241                    for (Iterator it = tmpmap.values().iterator(); it.hasNext();) {
1242                        ArrayList tmplist = (ArrayList) it.next();
1243                        for (int j = 0; j < tmplist.size(); j++) {
1244                            if (!mergeRestrictions.contains(tmplist.get(j)) && !otherRestrictions.contains(tmplist.get(j)))
1245                                otherRestrictions.add(tmplist.get(j));
1246                        }
1247                    }
1248                }
1249
1250                // add index to parent algebra
1251
indexSpecs.add(leftExpressions);
1252
1253                // modify where expression to contains only conditions on subquery
1254
// and add to ouside restrictions conditions either merge not allowed or all others
1255
XQueryExpression whereExpr = ((FLWRExpression) expression).getWhereClause();
1256                try {
1257                    for (int i = 0; i < mergeRestrictions.size(); i++) {
1258                        whereExpr = whereExpr.erasePart((XQueryExpression) mergeRestrictions.get(i));
1259                    }
1260                    for (int i = 0; i < otherRestrictions.size(); i++) {
1261                        whereExpr = whereExpr.erasePart((XQueryExpression) otherRestrictions.get(i));
1262                    }
1263                } catch (XQueryException e) {
1264                    throw new MediatorException("Could not erase part from expression : " + whereExpr);
1265                }
1266                ((FLWRExpression) expression).setWhereClause(whereExpr);
1267                //outsideRestrictions.add(otherRestrictions);
1268
if (otherRestrictions.isEmpty()) {
1269                    outsideRestrictions.add(null);
1270                } else {
1271                    if (otherRestrictions.size() == 1)
1272                        outsideRestrictions.add(otherRestrictions.get(0));
1273                    else {
1274                        try {
1275                            BinOpANDExpression tmpBinOp = new BinOpANDExpression((XQueryExpression) otherRestrictions.get(0), (XQueryExpression) otherRestrictions.get(1), expression.getParentModule());
1276                            for (int i = 2; i < otherRestrictions.size(); i++)
1277                                tmpBinOp = new BinOpANDExpression(tmpBinOp, (XQueryExpression) otherRestrictions.get(i), expression.getParentModule());
1278                            outsideRestrictions.add(tmpBinOp);
1279                        } catch (XQueryException e) {
1280                            throw new MediatorException("Could not aggregate list of expressions : " + otherRestrictions);
1281                        }
1282                    }
1283                }
1284
1285                // if (localRestrictions.isEmpty()) {
1286
// ((FLWRExpression)getExpression()).setWhereClause(null);
1287
// }
1288
// else {
1289
// if (localRestrictions.size() == 1)
1290
// ((FLWRExpression)getExpression()).setWhereClause((XQueryExpression)localRestrictions.get(0));
1291
// else {
1292
// try {
1293
// BinOpANDExpression tmpBinOp = new BinOpANDExpression((XQueryExpression) localRestrictions.get(0), (XQueryExpression) localRestrictions.get(1), depmanager.getTypeVisitor());
1294
// for (int i = 2; i < localRestrictions.size(); i++)
1295
// tmpBinOp = new BinOpANDExpression(tmpBinOp, (XQueryExpression) localRestrictions.get(i), depmanager.getTypeVisitor());
1296
// ((FLWRExpression)getExpression()).setWhereClause(tmpBinOp);
1297
// } catch (XQueryException e) {
1298
// throw new MediatorException("Could not aggregate list of expressions : " + localRestrictions);
1299
// }
1300
// }
1301
// }
1302

1303                retval = createOperator(plan);
1304                retval.addIndexSpec(rightExpressions);
1305                subRestrictions.add(mergeRestrictions);
1306            }
1307        }
1308        return retval;
1309    }
1310
1311    public Operator createOperator(ExecutionPlan plan) throws MediatorException {
1312        // definition of return value
1313
Operator operator = null;
1314        // gather information concerning where expression if any
1315
makeInformation();
1316        // gather information on subelements if any
1317
if (getParentDepFLWR() == null)
1318            verifySubElements();
1319
1320        Operator[] subOperators = null;
1321        ArrayList subRestrictions = null;
1322        ArrayList outsideExpressions = null;
1323        ArrayList indexSpecs = null;
1324
1325        if (subDepFLWRs != null && !subDepFLWRs.isEmpty()) {
1326
1327            algManager.addVarsToScope(((FLWRExpression) expression).getVariables());
1328
1329            if (subhandling == HintTree.NESTED_TYPE) {
1330                subOperators = new Operator[subDepFLWRs.size() + 1];
1331                //subElements.add(algebra);
1332
//ArrayList subWhereExpressions = new ArrayList();
1333
for (int i = 0; i < subDepFLWRs.size(); i++) {
1334                    AlgFLWR depi = (AlgFLWR) subDepFLWRs.get(i);
1335                    ArrayList varsi = ((FLWRExpression) depi.getExpression()).getVariables();
1336                    // if (log.isDebugEnabled()) {
1337
// log.debug("*********** DEPFLWR SUBDEPFLWR STUFF *************************");
1338
// log.debug("ClassName = " + depi.getClass().getName());
1339
// log.debug("is let = " + depi.isLet());
1340
// log.debug("depiexpr = " + depi.getExpression());
1341
// log.debug("vari = " + depi.getVariables());
1342
// log.debug("definition vars depending on = " + depi.getVarsDependingOn());
1343
// log.debug("where vars depending on = " + depi.getVarsWhereOn());
1344
// log.debug("vars referenced by = " + depi.getVarsReferencedBy());
1345
// log.debug("children = " + depi.getChildren());
1346
// }
1347
Operator subAlg = depi.createOperator(plan);
1348                    if (!depi.getVarsDependingOn().isEmpty()) // add 10/02/2003
1349
subAlg.setValueDepends(true);
1350                    if (!depi.getVarsWhereOn().isEmpty()) // add 10/02/2003
1351
subAlg.setWhereDepends(true);
1352                    subOperators[i + 1] = subAlg;
1353                    //subWhereExpressions.add(depi.getWhereClause());
1354
}
1355            }
1356            if (subhandling == HintTree.MERGE_TYPE) {
1357                subOperators = new Operator[subDepFLWRs.size() + 1];
1358                //subElements.add(algebra);
1359
if (outsideExpressions == null)
1360                    outsideExpressions = new ArrayList();
1361                if (indexSpecs == null)
1362                    indexSpecs = new ArrayList();
1363                subRestrictions = new ArrayList();
1364                for (int i = 0; i < subDepFLWRs.size(); i++) {
1365                    AlgFLWR depi = (AlgFLWR) subDepFLWRs.get(i);
1366                    ArrayList varsi = ((FLWRExpression) depi.getExpression()).getVariables();
1367                    // if (log.isDebugEnabled()) {
1368
// log.debug("*********** DEPFLWR SUBDEPFLWR STUFF *************************");
1369
// log.debug("ClassName = " + depi.getClass().getName());
1370
// log.debug("is let = " + depi.isLet());
1371
// log.debug("depiexpr = " + depi.getExpression());
1372
// log.debug("vari = " + depi.getVariables());
1373
// log.debug("definition vars depending on = " + depi.getVarsDependingOn());
1374
// log.debug("where vars depending on = " + depi.getVarsWhereOn());
1375
// log.debug("vars referenced by = " + depi.getVarsReferencedBy());
1376
// log.debug("children = " + depi.getChildren());
1377
// }
1378
Operator subAlg = depi.createOperator(plan, indexSpecs, subRestrictions, outsideExpressions);
1379                    if (!depi.getVarsDependingOn().isEmpty()) // add 10/02/2003
1380
subAlg.setValueDepends(true);
1381                    if (!depi.getVarsWhereOn().isEmpty()) // add 10/02/2003
1382
subAlg.setWhereDepends(true);
1383                    subOperators[i + 1] = subAlg;
1384                }
1385
1386            }
1387            algManager.removeVarsFromScope(((FLWRExpression) expression).getVariables());
1388        }
1389
1390        //if (hinttree != null && hinttree.getType() != HintTree.NO_TYPE) {
1391
operator = createOperator(plan, hinttree, ((FLWRExpression) expression).getVariables());
1392        if (operator != null) {
1393            // if flwr variables are not in modified hint tree create standard algebra
1394
if (hinttree != null) {
1395                ArrayList othervars = (ArrayList) ((FLWRExpression) expression).getVariables();
1396                if (!varHintList.containsAll(othervars)) {
1397                    othervars.removeAll(varHintList);
1398                    operator = createVarsOperator(plan, operator, varHintList, othervars);
1399                }
1400            }
1401        }
1402        if (operator == null) {
1403            // create order of variable depending on sort list, dependencies and declaration
1404
if (!isMonoSource()) {
1405                computeVarOrderList();
1406                verifyVarOrderList();
1407            } else {
1408                varOrderList = new ArrayList();
1409                varOrderList.add(((FLWRExpression) expression).getVariables().get(0));
1410            }
1411            // if (log.isDebugEnabled()) {
1412
// log.debug("********** WHERE STUFF **************************");
1413
// log.debug("where = " + ((FLWRExpression) expression).getWhereClause());
1414
// log.debug("vardependencies = " + vardependencies);
1415
// log.debug("varOrderMap = " + varOrderMap);
1416
// log.debug("orderVarMap = " + orderVarMap);
1417
// log.debug("varOrderList = " + varOrderList);
1418
// log.debug("varReOrderList = " + varReOrderList);
1419
// log.debug("children = " + algChildren);
1420
// }
1421
ArrayList varlist = new ArrayList(varOrderList.size());
1422            for (int i = 0; i < varOrderList.size(); i++) {
1423                operator = createVarOperator(plan, operator, varlist, (Variable) varOrderList.get(i));
1424                algManager.getScopeVariables().add(varOrderList.get(i));
1425            }
1426            algManager.getScopeVariables().removeAll(varOrderList);
1427        }
1428
1429        if (subOperators != null) {
1430            subOperators[0] = operator;
1431            if (subhandling == HintTree.NESTED_TYPE)
1432                operator = new OpSubQuery(plan, expression, subOperators, true, true);
1433            if (subhandling == HintTree.MERGE_TYPE) {
1434                if (subRestrictions.isEmpty())
1435                    operator = new OpSubQuery(plan, expression, subOperators, true, true);
1436                else {
1437                    operator.addIndexSpecs(indexSpecs);
1438                    operator = new OpSubQuery(plan, expression, subOperators, true, true, subRestrictions, outsideExpressions);
1439                }
1440            }
1441        }
1442
1443        // if it is a root node, than we must add final projection
1444
if (parentDepFLWR == null) {
1445            if (parent != null && (variables != null && !variables.isEmpty())) {
1446                // start add 30/05/2003
1447
boolean retvalue = false;
1448                XQueryExpression retexpr = ((FLWRExpression) expression).getReturnClause();
1449                while (!retvalue) {
1450                    if (retexpr instanceof LocatedExpression || retexpr instanceof Variable)
1451                        retvalue = true;
1452                    else {
1453                        if (retexpr instanceof XQueryExpressionSequence) {
1454                            XQueryExpressionSequence retseq = (XQueryExpressionSequence) retexpr;
1455                            if (retseq.getSubExpressions().size() == 1)
1456                                retexpr = (XQueryExpression) retseq.getSubExpressions().get(0);
1457                            else
1458                                break;
1459                        } else
1460                            break;
1461                    }
1462                }
1463                if (retvalue)
1464                    operator = new OpNotSource(plan, retexpr, (Variable) variables.get(0), operator, islet);
1465                else
1466                    // end add 30/05/2003
1467
operator = new OpNotSource(plan, null, (Variable) variables.get(0), operator, islet);
1468            }
1469        }
1470        if (varReOrderList != null && !varReOrderList.isEmpty()) {
1471            ArrayList neworders = new ArrayList();
1472            ArrayList orders = ((FLWRExpression) expression).getOrderBy();
1473            boolean doit = false;
1474            if (orders != null)
1475                for (int i = 0; i < orders.size(); i++) {
1476                    Variable tmpvar = null;
1477                    XQueryExpression tmpexpr = null;
1478                    if (orders.get(i) instanceof Variable) {
1479                        tmpvar = (Variable) orders.get(i);
1480                        tmpexpr = tmpvar;
1481                    } else {
1482                        tmpexpr = (XQueryExpression) orders.get(i);
1483                        tmpvar = (Variable) ((LocatedExpression) tmpexpr).getExpression();
1484                    }
1485                    if (doit || varReOrderList.contains(tmpvar)) {
1486                        if (!doit)
1487                            doit = true;
1488                        neworders.add(tmpexpr);
1489                    }
1490                }
1491            if (!neworders.isEmpty())
1492                operator = new OpSort(plan, operator, neworders);
1493        }
1494        if (!isQDB())
1495            operator.isLet(islet);
1496        return operator;
1497    }
1498
1499    public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
1500        AlgFLWR newobj = (AlgFLWR) super.clone();
1501        newobj.parentDepFLWR = parentDepFLWR;
1502        if (subDepFLWRs == null)
1503            newobj.subDepFLWRs = null;
1504        else {
1505            newobj.subDepFLWRs = new ArrayList();
1506            for (int i = 0; i < subDepFLWRs.size(); i++)
1507                newobj.subDepFLWRs.add(((AlgFLWR) subDepFLWRs.get(i)).clone());
1508        }
1509        return newobj;
1510    } // ************************************************************************
1511

1512    // * METHODS
1513
// ************************************************************************
1514
/**
1515     *
1516     * @return
1517     */

1518    public ArrayList getPaths() {
1519        if (paths == null)
1520            paths = new ArrayList();
1521        if (paths.isEmpty()) {
1522            if (algChildren != null) {
1523                for (int i = 0; i < algChildren.size(); i++) {
1524                    ArrayList tmplist = ((Algebra) algChildren.get(i)).getPaths();
1525                    if (tmplist != null)
1526                        paths.addAll(tmplist);
1527                }
1528            }
1529            if (subDepFLWRs != null) {
1530                for (int i = 0; i < subDepFLWRs.size(); i++) {
1531                    ArrayList tmplist = ((AlgFLWR) subDepFLWRs.get(i)).getPaths();
1532                    if (tmplist != null)
1533                        paths.addAll(tmplist);
1534                }
1535            }
1536        }
1537        return paths;
1538    }
1539
1540    /*
1541     * public ArrayList getVariables() { return ((FLWRExpression) expression).getVariables(); }
1542     */

1543
1544    public ArrayList getAllVariables() {
1545        ArrayList res = (ArrayList) ((FLWRExpression) expression).getVariables().clone();
1546        if (subDepFLWRs != null)
1547            for (int i = 0; i < subDepFLWRs.size(); i++)
1548                res.addAll(((AlgFLWR) subDepFLWRs.get(i)).getAllVariables());
1549        return res;
1550    }
1551
1552    public AlgFLWR getParentDepFLWR() {
1553        return parentDepFLWR;
1554    }
1555
1556    public ArrayList getAllOrderBys() {
1557        ArrayList parentres = ((FLWRExpression) expression).getOrderBy();
1558        if (subDepFLWRs == null)
1559            return parentres;
1560        ArrayList res = new ArrayList();
1561        for (int i = 0; i < subDepFLWRs.size(); i++) {
1562            ArrayList tmpres = ((AlgFLWR) subDepFLWRs.get(i)).getAllOrderBys();
1563            if (tmpres != null) {
1564                res.addAll(tmpres);
1565                if (parentres != null)
1566                    res.removeAll(parentres);
1567            }
1568        }
1569        if (parentres != null)
1570            res.addAll(0, parentres);
1571        if (res.isEmpty())
1572            return null;
1573        return res;
1574    } // ******************************************************************
1575

1576    // * DEBUGGING
1577
// ******************************************************************
1578
public String JavaDoc toCompleteString() {
1579        return toCompleteString(0);
1580    }
1581
1582    public String JavaDoc toCompleteString(int indent) {
1583        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1584        buf.append(Utils.makeIndent(indent) + "<" + getClass().getName() + ">\n");
1585        buf.append(Utils.makeIndent(indent + 1) + "<variables> " + variables + " </variables>\n");
1586        buf.append(Utils.makeIndent(indent + 1) + "<sources> " + getSources() + " </sources>\n");
1587        buf.append(Utils.makeIndent(indent + 1) + "<isLet> " + islet + " </isLet>\n");
1588        buf.append(Utils.makeIndent(indent + 1) + "<monosource> " + isMonoSource() + " </monosource>\n");
1589        buf.append(Utils.makeIndent(indent + 1) + "<hasIdentifier> " + hasIdentifier + " </hasIdentifier>\n");
1590        if (hinttree != null) {
1591            buf.append(Utils.makeIndent(indent + 1) + "<HintTree>\n");
1592            buf.append(Utils.makeIndent(indent + 2) + hinttree.toString() + "\n");
1593            buf.append(Utils.makeIndent(indent + 1) + "</HintTree>\n");
1594        }
1595        buf.append(Utils.makeIndent(indent + 1) + "<Expression type=\"" + expression.getClass() + "\">\n");
1596        buf.append(Utils.makeIndent(indent + 2) + expression + "\n");
1597        buf.append(Utils.makeIndent(indent + 1) + "</Expression>\n");
1598        if (algChildren != null && !algChildren.isEmpty()) {
1599            buf.append(Utils.makeIndent(indent + 1) + "<Leaves>\n");
1600            for (int i = 0; i < algChildren.size(); i++) {
1601                buf.append(Utils.makeIndent(indent + 2) + "<Leave>\n");
1602                Algebra depchild = (Algebra) algChildren.get(i);
1603                buf.append(depchild.toCompleteString(indent + 3));
1604                buf.append(Utils.makeIndent(indent + 2) + "</Leave>\n");
1605            }
1606            buf.append(Utils.makeIndent(indent + 1) + "</Leaves>\n");
1607        }
1608        if (referenceDefinitionVars != null && !referenceDefinitionVars.isEmpty()) {
1609            buf.append(Utils.makeIndent(indent + 1) + "<referenceDefinitionVars>\n");
1610            for (int i = 0; i < referenceDefinitionVars.size(); i++) {
1611                buf.append(Utils.makeIndent(indent + 2) + "<Variables>" + referenceDefinitionVars.get(i) + "</Variables>\n");
1612            }
1613            buf.append(Utils.makeIndent(indent + 1) + "</referenceDefinitionVars>\n");
1614        }
1615        if (dependDefinitionVars != null && !dependDefinitionVars.isEmpty()) {
1616            buf.append(Utils.makeIndent(indent + 1) + "<dependDefinitionVars>\n");
1617            for (int i = 0; i < dependDefinitionVars.size(); i++) {
1618                buf.append(Utils.makeIndent(indent + 2) + "<Variables>" + dependDefinitionVars.get(i) + "</Variables>\n");
1619            }
1620            buf.append(Utils.makeIndent(indent + 1) + "</dependDefinitionVars>\n");
1621        }
1622        if (paths != null && !paths.isEmpty()) {
1623            buf.append(Utils.makeIndent(indent + 1) + "<Paths>\n");
1624            for (int i = 0; i < paths.size(); i++)
1625                buf.append(Utils.makeIndent(indent + 2) + "<Path>" + paths.get(i) + "</Path>\n");
1626            buf.append(Utils.makeIndent(indent + 1) + "</Paths>\n");
1627        }
1628        if (subDepFLWRs != null) {
1629            buf.append(Utils.makeIndent(indent + 1) + "<subDepFLWRs>\n");
1630            for (int i = 0; i < subDepFLWRs.size(); i++)
1631                buf.append(Utils.makeIndent(indent + 2) + "<depmem>" + ((AlgFLWR) subDepFLWRs.get(i)).getVariables() + "</depmem>\n");
1632            buf.append(Utils.makeIndent(indent + 1) + "</subDepFLWRs>\n");
1633        }
1634        buf.append(Utils.makeIndent(indent) + "</" + getClass().getName() + ">\n");
1635        return buf.toString();
1636    }
1637
1638    public void execute(ExecutionPlan plan) throws MediatorException {
1639    }
1640
1641}
Popular Tags