KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > xquery > normalize > RestructureVisitor


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.xquery.normalize;
25
26 import java.util.ArrayList JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Stack JavaDoc;
29
30 import org.xquark.xpath.Axis;
31 import org.xquark.xpath.NodeKind;
32 import org.xquark.xquery.parser.*;
33 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.*;
34 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.FunctionQNAME;
35 import org.xquark.xquery.parser.util.Constants;
36 import org.xquark.xquery.typing.QType;
37 import org.xquark.xquery.typing.TypeException;
38 import org.xquark.xquery.typing.TypeVisitor;
39
40 // Note :
41
// the visitor return value : resultExpr is null if the expression
42
// has been transformed without creating a new expression
43

44 public class RestructureVisitor extends DefaultParserVisitor {
45
46     private static final String JavaDoc RCSRevision = "$Revision: 1.10 $";
47     private static final String JavaDoc RCSName = "$Name: $";
48
49     private XQueryExpression resultExpr = null;
50     private TypeVisitor typeVisitor = null;
51
52     private final Integer JavaDoc NO_CONTEXT = new Integer JavaDoc(0);
53     private final Integer JavaDoc IN_RETURN = new Integer JavaDoc(1);
54     private final Integer JavaDoc IN_WHERE = new Integer JavaDoc(2);
55     private final Integer JavaDoc IN_FUNCTION = new Integer JavaDoc(3);
56     private final Integer JavaDoc IN_FLWR = new Integer JavaDoc(4);
57
58     private Stack JavaDoc contextStack = new Stack JavaDoc();
59     private Stack JavaDoc inWhereExpressionStack = new Stack JavaDoc();
60     private Stack JavaDoc parentFLWRExpressionStack = new Stack JavaDoc();
61     private Stack JavaDoc varDefinitionStack = new Stack JavaDoc();
62     private int inReturn = 0;
63
64     private int ruleNumber = 0;
65     private boolean isMediator = false;
66     private boolean isRoot = true;
67
68     private final int[] initOrder = { -1, -1 };
69
70     public RestructureVisitor(TypeVisitor typeVisitor) {
71         this.typeVisitor = typeVisitor;
72     }
73
74     public RestructureVisitor(TypeVisitor typeVisitor, boolean isMediator) {
75         this.typeVisitor = typeVisitor;
76         this.isMediator = isMediator;
77     }
78
79     public XQueryExpression getResult() {
80         return resultExpr;
81     }
82     public int getRuleNumber() {
83         return ruleNumber;
84     }
85
86     public void visit(ComputedText arg) throws XQueryException {
87         if (isRoot) {
88             makeDummyOneFlwr(arg);
89             return;
90         }
91         XQueryExpression tmpExpr = arg.getExpression();
92         tmpExpr.accept(this);
93         if (resultExpr != null) {
94             //change = true;
95
arg.setExpression(resultExpr);
96         }
97         resultExpr = null;
98     }
99
100     public void visit(Document arg) throws XQueryException {
101         if (isRoot) {
102             makeDummyOneFlwr(arg);
103             return;
104         }
105         XQueryExpression tmpExpr = arg.getExpression();
106         tmpExpr.accept(this);
107         if (resultExpr != null) {
108             //change = true;
109
arg.setExpression(resultExpr);
110         }
111         resultExpr = null;
112     }
113
114     /*
115     --> Rules for class Element
116     ELT-1. putting computed namespaces first then attributes
117     ELT-2. if not in return clause (root in fact) then create FWLR expression (for cannisation purposes) and restructure it
118     ELT-3. if in return iterate on attributes and subexpressions and restructure each of them
119     */

120     public void visit(Element arg) throws XQueryException {
121         // rule ELT-2.
122
if (isRoot) {
123             makeDummyOneFlwr(arg);
124             return;
125         }
126         // reorder element subexpressions
127
// rule ELT-1.
128
ArrayList JavaDoc subExpressions = arg.getSubExpressions();
129         if (subExpressions != null) {
130             byte nbAtt = 0;
131             byte nbNS = 0;
132             for (int i = 0; i < subExpressions.size(); i++) {
133                 XQueryExpression expri = (XQueryExpression) subExpressions.get(i);
134                 if (expri instanceof ComputedNamespace) {
135                     if (i > nbNS) {
136                         subExpressions.remove(i);
137                         subExpressions.add(nbNS, expri);
138                     }
139                     nbNS++;
140                 } else if (expri instanceof AttributeValuePair) {
141                     subExpressions.remove(i);
142                     arg.addAttributes((AttributeValuePair) expri);
143                 } else if (expri.getQType().getSubClass() == QType.ATTRIBUTE) {
144                     if (i > nbNS + nbAtt) {
145                         subExpressions.remove(i);
146                         subExpressions.add(nbNS + nbAtt, expri);
147                     }
148                     nbAtt++;
149                 }
150             }
151             arg.setComputedAttNum(nbAtt);
152             arg.setComputedNSNum(nbNS);
153         }
154         // rule ELT-3.
155
arg.getStartTag().accept(this);
156         if (resultExpr != null)
157             arg.setStartTag(resultExpr);
158         if (arg.getAttributes() != null) {
159             ArrayList JavaDoc newAttributes = new ArrayList JavaDoc(arg.getAttributes().size());
160             for (int i = 0; i < arg.getAttributes().size(); i++) {
161                 AttributeValuePair expri = (AttributeValuePair) arg.getAttributes().get(i);
162                 expri.accept(this);
163                 if (resultExpr != null)
164                     newAttributes.add(resultExpr);
165                 else
166                     newAttributes.add(expri);
167             }
168             arg.setAttributes(newAttributes);
169         }
170         if (subExpressions != null) {
171             ArrayList JavaDoc newSubExpressions = new ArrayList JavaDoc(subExpressions.size());
172             for (int i = 0; i < subExpressions.size(); i++) {
173                 XQueryExpression expri = (XQueryExpression) subExpressions.get(i);
174                 expri.accept(this);
175                 if (resultExpr != null)
176                     newSubExpressions.add(resultExpr);
177                 else
178                     newSubExpressions.add(expri);
179             }
180             arg.setSubExpressions(newSubExpressions);
181         }
182         // rule ELT-4.
183
// this is special for sequences of atomic values -> insert white space
184
// subExpressions = arg.getSubExpressions();
185
// if (subExpressions != null && subExpressions.size() > 1) {
186
// boolean prevAtom = false;
187
// for (int i = 0; i < subExpressions.size(); i++) {
188
// XQueryExpression expri = (XQueryExpression) subExpressions.get(i);
189
// if (expri.getQType().isAtom()) {
190
// if (prevAtom) {
191
// arg.addSubExpressions(i,new ValueText(" ",typeVisitor));
192
// i++;
193
// } else
194
// prevAtom = true;
195
// } else
196
// prevAtom = false;
197
// }
198
// }
199
resultExpr = null;
200     }
201
202     /*
203     --> Rules for class FLWRExpression
204     FLWR-1. while return clause is FLWR erase 'return'
205     FLWR-2. if return clause is not LocatedExpression, Variable or ElementConstructor create intermediate variable
206     FLWR-3. for all possible variable (see condition!) transform for binding into let binding, restructure all variables anyway
207     FLWR-4. restructure where clause
208     FLWR-5. for all possible variable (see condition!) substitute variable in the other clause and then remove it
209     FLWR-6. If no more variable left depending on context recreate FLWR and restructure result
210     FLWR-7. If only let clauses add dummy for clause in front
211     FLWR-8. restructure return clause
212     */

213     public void visit(FLWRExpression arg) throws XQueryException {
214         if (isRoot) {
215             isRoot = false;
216         }
217         // handling case when variables are bound on union elements
218
// not done yet
219

220         XQueryExpression returnClause = arg.getReturnClause();
221         XQueryExpression whereClause = arg.getWhereClause();
222         // return clause should be either LocatedExpression, Variable, ElementConstructor, SortedExprression
223
// rule FLWR-0.
224
// if (returnClause instanceof SortedExpression) {
225
// returnClause.accept(this);
226
// returnClause = resultExpr;
227
// arg.setReturnClause(resultExpr);
228
// FLWRExpression flwr = (FLWRExpression) returnClause;
229
// if (flwr.getOrderBy() != null)
230
// for (int i=0;i<flwr.getOrderBy().size();i++)
231
// arg.addOrderBy((XQueryExpression)flwr.getOrderBy().get(i));
232
// }
233
// rule FLWR-1.
234
while (returnClause instanceof FLWRExpression) {
235             ArrayList JavaDoc orderBys = ((FLWRExpression) returnClause).getOrderBy();
236             if (orderBys == null || orderBys.isEmpty()) {
237                 ArrayList JavaDoc vars = ((FLWRExpression) returnClause).getVariables();
238                 for (int i = 0; i < vars.size(); i++)
239                     arg.addVariable((Variable) vars.get(i));
240                 if (whereClause == null)
241                     arg.setWhereClause(((FLWRExpression) returnClause).getWhereClause());
242                 else
243                     arg.addWhereClause(((FLWRExpression) returnClause).getWhereClause());
244                 arg.setReturnClause(((FLWRExpression) returnClause).getReturnClause());
245                 returnClause = arg.getReturnClause();
246             } else
247                 break;
248         }
249         // rule FLWR-2.
250
if (!(returnClause instanceof XQueryExpressionSequence) && !(returnClause instanceof LocatedExpression) && !(returnClause instanceof Variable) && !(returnClause instanceof Element) && !(returnClause instanceof ITEExpression) && !(returnClause instanceof SortedExpression) && !(returnClause instanceof XMLComment) && !(returnClause instanceof Document) && !(returnClause instanceof XMLProcessingInstruction) && !(returnClause instanceof FLWRExpression) && !(returnClause instanceof ComputedText) && !(returnClause instanceof AttributeValuePair)) {
251             Variable var = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, returnClause, Variable.RES_CREATOR);
252             arg.addVariable(var);
253             arg.setReturnClause(var);
254             returnClause = arg.getReturnClause();
255         }
256         // restructure variables
257
// rule FLWR-3.
258
ArrayList JavaDoc variables = arg.getVariables();
259         for (int j = 0; j < variables.size(); j++) {
260             Variable tmpVar = (Variable) variables.get(j);
261             // add 22/01/2003
262
// erase 23/06/2003
263
// add 21/07/2003
264
//if (tmpVar.getBindingType() == Constants.FOR_BINDINGTYPE && !tmpVar.isInput() && tmpVar.getExpression().getQType().getOccurence() == QType.OCC_1_1 && variables.size() != 1) {
265
if (tmpVar.getCreator() != Variable.RES_CREATOR && tmpVar.getBindingType() == Constants.FOR_BINDINGTYPE && !tmpVar.isInput() && // for testing only(tmpVar.getExpression().getQType().getOccurence() == QType.OCC_1_1 || tmpVar.getExpression().getQType().getOccurence() == QType.OCC_0_1) &&
266
tmpVar.getExpression().getQType().getOccurence() == QType.OCC_1_1 && (variables.size() != 1 || arg.getParentExpression() != null)) {
267                 tmpVar.setBindingType(Constants.LET_BINDINGTYPE);
268                 ruleNumber++;
269             }
270             contextStack.push(IN_FLWR);
271             parentFLWRExpressionStack.push(arg);
272             tmpVar.accept(this);
273             contextStack.pop();
274             parentFLWRExpressionStack.pop();
275         }
276
277         XQueryExpression tmpSubExpr = null;
278         variables = arg.getVariables();
279         whereClause = arg.getWhereClause();
280         returnClause = arg.getReturnClause();
281         ArrayList JavaDoc orderBys = arg.getOrderBy();
282         // rule FLWR-4.
283
if (whereClause != null) {
284             parentFLWRExpressionStack.push(arg);
285             inWhereExpressionStack.push(arg);
286             contextStack.push(IN_WHERE);
287             whereClause.accept(this);
288             parentFLWRExpressionStack.pop();
289             inWhereExpressionStack.pop();
290             contextStack.pop();
291             XQueryExpression tmpExpr = resultExpr;
292             if (tmpExpr != null)
293                 arg.setWhereClause(tmpExpr);
294         }
295         // rule FLWR-5.
296
boolean noloop = true;
297         for (int j = 0; j < variables.size(); j++) {
298             Variable tmpVar = (Variable) variables.get(j);
299             XQueryExpression tmpVarExpr = tmpVar.getExpression();
300             int bindingtype = tmpVar.getBindingType();
301             // replacing expressions
302
// for $x in value
303
// let $x := notcollection && not aggregatefunctioncall
304
// let $x := collection && locatedexpression starting with variable
305
if (tmpVar.getCreator() != Variable.RES_CREATOR && (tmpVarExpr instanceof Value || // ADD lars 10/02/04
306
//(bindingtype == Constants.LET_BINDINGTYPE && tmpVarExpr instanceof FLWRExpression) ||
307
(bindingtype == Constants.LET_BINDINGTYPE && !tmpVarExpr.getQType().isMultiple() && //!(tmpVarExpr instanceof AggregateFunctionCall) &&
308
!(tmpVarExpr instanceof FunctionCall) && !(tmpVarExpr instanceof ListOpArithExpression) && !(tmpVarExpr instanceof FLWRExpression)) || (bindingtype == Constants.LET_BINDINGTYPE && tmpVarExpr instanceof LocatedExpression && ((LocatedExpression) tmpVarExpr).getSteps().size() != 1 && ((LocatedExpression) tmpVarExpr).getExpression() instanceof Variable && tmpVarExpr.getQType().isMultiple()))) {
309                 //if (tmpVar.getBindingType() == Constants.LET_BINDINGTYPE && tmpVarExpr instanceof LocatedExpression && tmpVarExpr.getQType().isCollection()) {
310
// create substitute map
311
HashMap JavaDoc map = new HashMap JavaDoc(1);
312                 map.put(tmpVar, tmpVarExpr);
313                 // replace in all LET variable after this one
314
for (int i = j + 1; i < variables.size(); i++)
315                      ((Variable) variables.get(i)).getExpression().substitute(map, typeVisitor);
316                 // replace in WHERE clause
317
if (whereClause != null) {
318                     if ((tmpSubExpr = (XQueryExpression) map.get(whereClause)) != null)
319                         arg.setWhereClause(tmpSubExpr);
320                     else
321                         whereClause.substitute(map, typeVisitor);
322                 }
323                 //replace in orderby (not necessary -> only mono values accepted)
324
if (orderBys != null) {
325                     for (int i = 0; i < orderBys.size(); i++) {
326                         XQueryExpression orderby = (XQueryExpression) orderBys.get(i);
327                         if ((tmpSubExpr = (XQueryExpression) map.get(orderby)) != null)
328                             orderBys.set(i, tmpSubExpr);
329                         else
330                             orderby.substitute(map, typeVisitor);
331                     }
332                 }
333                 // replace in RETURN clause
334
if ((tmpSubExpr = (XQueryExpression) map.get(returnClause)) != null)
335                     arg.setReturnClause(tmpSubExpr);
336                 else
337                     returnClause.substitute(map, typeVisitor);
338                 variables.remove(j);
339                 j--;
340                 // } else if (bindingtype == Constants.FOR_BINDINGTYPE || tmpVarExpr.getQType().isMultiple())
341
// change 10/08/2003
342
} else if (bindingtype == Constants.FOR_BINDINGTYPE)
343                 noloop = false;
344         }
345         // rule FLWR-6.
346
if (variables.isEmpty()) {
347             Integer JavaDoc tmpInt = this.NO_CONTEXT;
348             if (!contextStack.isEmpty())
349                 tmpInt = (Integer JavaDoc) contextStack.peek();
350             if (whereClause != null) {
351                 if (tmpInt == this.IN_FLWR) {
352                     ((FLWRExpression) this.parentFLWRExpressionStack.peek()).addWhereClause(whereClause);
353                     resultExpr = arg.getReturnClause();
354                     ruleNumber++;
355                 } else {
356                     // resultExpr = new ITEExpression(whereClause,arg.getReturnClause(),new XQueryVoid(typeVisitor),typeVisitor);
357
Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new ValueInteger("1", arg.getParentModule()), Variable.RES_CREATOR);
358                     var.isDummy(true);
359                     ArrayList JavaDoc vars = new ArrayList JavaDoc(1);
360                     vars.add(var);
361                     // CHANGE 30/08/2002 arg.getReturnClause().setRoot(true);
362
resultExpr = new FLWRExpression(vars, null, whereClause, arg.getReturnClause(), arg.getParentModule());
363                     resultExpr.setParentModule(arg.getParentModule());
364                     isRoot = true;
365                     ruleNumber++;
366                 }
367             } else {
368                 resultExpr = arg.getReturnClause();
369                 isRoot = true;
370             }
371             // change 19/03/2002
372
//resultExpr.clearParentExpression();
373
if (resultExpr != null) {
374                 resultExpr.setParentExpressions(arg.getParentExpression());
375                 XQueryExpression tmpExpr = resultExpr;
376                 resultExpr.accept(this);
377                 if (resultExpr == null)
378                     resultExpr = tmpExpr;
379             }
380             return;
381         }
382         // rule FLWR-7.
383
if (noloop) {
384             Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new ValueInteger("1", arg.getParentModule()), Variable.RES_CREATOR);
385             var.isDummy(true);
386             arg.insertVariable(var);
387         }
388
389         // restructure orderby
390
ArrayList JavaDoc orderby = arg.getOrderBy();
391         if (orderby != null) {
392             for (int i = 0; i < orderby.size(); i++) {
393                 XQueryExpression orderi = (XQueryExpression) orderby.get(i);
394                 // orderi.accept(this);
395
// if (resultExpr != null)
396
// orderby.set(i,resultExpr);
397
// orderi = (XQueryExpression)orderby.get(i);
398
if (orderi instanceof Variable || (orderi instanceof LocatedExpression && ((LocatedExpression) orderi).getExpression() instanceof Variable))
399                     continue;
400                 // replace with variable
401
Variable var = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, orderi, Variable.RES_CREATOR);
402                 arg.addVariable(var);
403                 orderby.set(i, var);
404             }
405         }
406         // rule FLWR-8.
407
// resructure return clause
408
returnClause = arg.getReturnClause();
409         inReturn++;
410         contextStack.push(IN_RETURN);
411         //if (arg.getVariables() != null && !arg.getVariables().isEmpty())
412
this.parentFLWRExpressionStack.push(arg);
413         returnClause.accept(this);
414         //if (arg.getVariables() != null && !arg.getVariables().isEmpty())
415
this.parentFLWRExpressionStack.pop();
416         inReturn--;
417         contextStack.pop();
418         XQueryExpression tmpExpr = resultExpr;
419         if (tmpExpr != null)
420             arg.setReturnClause(tmpExpr);
421
422         // add LARS 09/03/04
423
// handling FLWR in function call
424
Integer JavaDoc tmpInt = this.NO_CONTEXT;
425         if (!contextStack.isEmpty())
426             tmpInt = (Integer JavaDoc) contextStack.peek();
427         if (tmpInt == this.IN_FUNCTION) {
428             // add variable to parentflwr
429
FLWRExpression lastflwr = (FLWRExpression) parentFLWRExpressionStack.peek();
430             Variable addvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR);
431             if (varDefinitionStack.isEmpty()) {
432                 lastflwr.addVariable(addvar);
433             } else {
434                 Variable lastvar = (Variable) varDefinitionStack.peek();
435                 int prevpos = lastflwr.getVarPosition(lastvar);
436                 if (prevpos != -1)
437                     lastflwr.addVariable(prevpos, addvar);
438                 else
439                     lastflwr.addVariable(addvar);
440             }
441             resultExpr = addvar;
442             return;
443         }
444
445         // add LARS 14/06/04
446
// erasing dummy variables for $x in 1 whenever possible
447
if (isMediator) {
448             while (((Variable) arg.getVariables().get(0)).isDummy()) {
449                 if (arg.getVariables().size() > 1)
450                     arg.getVariables().remove(0);
451                 else
452                     break;
453             }
454         }
455
456         // reset result
457
resultExpr = null;
458     }
459
460     public void visit(ListOpArithExpression arg) throws XQueryException {
461         if (isRoot) {
462             makeDummyOneFlwr(arg);
463             return;
464         }
465         //resultExpr = null;
466
// test if variable should be added
467
if (!contextStack.isEmpty()) {
468             Integer JavaDoc tmpInt = (Integer JavaDoc) contextStack.peek();
469             if (tmpInt.equals(IN_RETURN)) {
470                 XQueryExpression parent0Expr = (XQueryExpression) arg.getParentExpression().get(0);
471                 if (!(parent0Expr instanceof Variable)) {
472                     FLWRExpression lastflwr = (FLWRExpression) parentFLWRExpressionStack.peek();
473                     Variable addvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR);
474                     if (varDefinitionStack.isEmpty()) {
475                         lastflwr.addVariable(addvar);
476                     } else {
477                         Variable lastvar = (Variable) varDefinitionStack.peek();
478                         int prevpos = lastflwr.getVarPosition(lastvar);
479                         if (prevpos != -1)
480                             lastflwr.addVariable(prevpos, addvar);
481                         else
482                             lastflwr.addVariable(addvar);
483                     }
484                     resultExpr = addvar;
485                     return;
486                 }
487             }
488         }
489         contextStack.push(IN_FUNCTION);
490         XQueryExpression tmpExpr = arg.getExpression1();
491         tmpExpr.accept(this);
492         if (resultExpr != null) {
493             arg.setExpression1(resultExpr);
494         }
495         tmpExpr = arg.getExpression2();
496         tmpExpr.accept(this);
497         if (resultExpr != null) {
498             arg.setExpression2(resultExpr);
499         }
500         resultExpr = null;
501         contextStack.pop();
502     }
503
504     public void visit(ITEExpression arg) throws XQueryException {
505         if (isRoot) {
506             throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree");
507         }
508         if (contextStack.peek() != IN_RETURN)
509             throw new XQueryException(arg.getClass().getName() + " can only appear in a return clause");
510         // add LARS 09/03/04
511
// special test for empty and exists functions
512
XQueryExpression ifExpr = arg.getIfExpression();
513         while (ifExpr instanceof FunctionNOT) {
514             arg.setIfExpression(((FunctionNOT) ifExpr).getArgument(0));
515             XQueryExpression expr = arg.getElseExpression();
516             arg.setElseExpression(arg.getThenExpression());
517             arg.setThenExpression(expr);
518         }
519         ifExpr = arg.getIfExpression();
520         if (ifExpr instanceof FunctionEMPTY && ((FunctionEMPTY) ifExpr).getArgument(0).getQType().isMultiple()) {
521             ArrayList JavaDoc args = new ArrayList JavaDoc(1);
522             args.add(((FunctionEMPTY) ifExpr).getArgument(0));
523             arg.setIfExpression(new ListOpCompExpression(new FunctionCOUNT(args, arg.getParentModule()), new ValueInteger("0", arg.getParentModule()), Constants.EQ_COMPOP, arg.getParentModule()));
524         } else if (ifExpr instanceof FunctionEXISTS && ((FunctionEXISTS) ifExpr).getArgument(0).getQType().isMultiple()) {
525             ArrayList JavaDoc args = new ArrayList JavaDoc(1);
526             args.add(((FunctionEXISTS) ifExpr).getArgument(0));
527             arg.setIfExpression(new ListOpCompExpression(new FunctionCOUNT(args, arg.getParentModule()), new ValueInteger("0", arg.getParentModule()), Constants.NEQ_COMPOP, arg.getParentModule()));
528         } else {
529             QType qtype = ifExpr.getQType();
530             if (qtype != null && qtype.isMultiple()) {
531                 ArrayList JavaDoc args = new ArrayList JavaDoc(1);
532                 args.add(ifExpr);
533                 arg.setIfExpression(new ListOpCompExpression(new FunctionCOUNT(args, arg.getParentModule()), new ValueInteger("0", arg.getParentModule()), Constants.NEQ_COMPOP, arg.getParentModule()));
534             }
535         }
536         contextStack.push(IN_FUNCTION);
537         arg.getIfExpression().accept(this);
538         if (resultExpr != null) {
539             arg.setIfExpression(resultExpr);
540         }
541         // arg.getThenExpression().accept(this);
542
// if (resultExpr != null) {
543
// arg.setThenExpression(resultExpr);
544
// }
545
// arg.getElseExpression().accept(this);
546
// if (resultExpr != null) {
547
// arg.setElseExpression(resultExpr);
548
// }
549
contextStack.pop();
550         resultExpr = arg;
551     }
552
553     /*
554     --> Rules for class LocatedExpression
555     LOC-1. if no parents or parent is sorted expression create FLWR expression
556     LOC-2. if parents and parent FLWR and parent is not FunctionCall and parent is not variable and first step expression is rooNodeFunctionCall then replace expression with intermediaite variable
557     LOC-3. if in return and qtype is multiple and (first step expression is not variable or first step expression qtype is multiple) and (no parent or parent is variable) then create new FLWR to iterate on expr
558     */

559     public void visit(LocatedExpression arg) throws XQueryException {
560         if (isRoot) {
561             makeDummyFlwr(arg);
562             return;
563         }
564         resultExpr = null;
565         //Step step0 = (Step) arg.getSteps().get(0);
566
ArrayList JavaDoc parents = arg.getParentExpression();
567         boolean noParents = false;
568         if (parents == null || parents.isEmpty())
569             noParents = true;
570         // rule LOC-1.
571
if (noParents || (XQueryExpression) parents.get(0) instanceof SortedExpression) {
572             if (arg.getQType() != null && arg.getQType().isMultiple() && !(arg.getExpression() instanceof Variable)) {
573                 Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg, Variable.RES_CREATOR);
574                 ArrayList JavaDoc varlist = new ArrayList JavaDoc(1);
575                 varlist.add(var);
576                 FLWRExpression tmpFLWR = new FLWRExpression(varlist, null, null, var, arg.getParentModule());
577                 tmpFLWR.setParentModule(arg.getParentModule());
578                 resultExpr = tmpFLWR;
579                 ruleNumber++;
580             }
581         }
582         // rule LOC-2.
583
// add 11/06/2003
584
else if (!noParents && !parentFLWRExpressionStack.isEmpty() && !((XQueryExpression) parents.get(0) instanceof FunctionCall) && !((XQueryExpression) parents.get(0) instanceof Variable) && arg.getExpression() instanceof InputFunctionCall) {
585             Variable var = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR);
586             FLWRExpression parentflwr = (FLWRExpression) parentFLWRExpressionStack.peek();
587             parentflwr.addVariable(var);
588             resultExpr = var;
589         }
590         // end add 11/06/2003
591
// rule LOC-3.
592
else if (!contextStack.isEmpty()) {
593             Integer JavaDoc tmpInt = (Integer JavaDoc) contextStack.peek();
594             if (tmpInt.equals(IN_RETURN)) {
595                 // condition to be added to be ok in repository
596
QType qtype = arg.getQType();
597                 if (qtype != null && qtype.isMultiple() && (!(arg.getExpression() instanceof Variable) || arg.getExpression().getQType().isMultiple()) && (noParents || !(parents.get(0) instanceof Variable))) {
598                     Variable tmpVar = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg, Variable.RES_CREATOR);
599                     ArrayList JavaDoc vars = new ArrayList JavaDoc(1);
600                     vars.add(tmpVar);
601                     FLWRExpression tmpFLWR = new FLWRExpression(vars, null, tmpVar, arg.getParentModule());
602                     tmpFLWR.setParentModule(arg.getParentModule());
603                     resultExpr = tmpFLWR;
604                     ruleNumber++;
605                 }
606             }
607         }
608
609     }
610
611     /*
612     --> Rules for class PrimitiveFunctionCall
613     PRIM-1. iterate on arguments and replace them if necessary
614     */

615     public void visit(PrimitiveFunctionCall arg) throws XQueryException {
616         if (isRoot) {
617             makeDummyFlwr(arg);
618             return;
619         }
620         resultExpr = null;
621         Integer JavaDoc context = null;
622         if (!this.contextStack.isEmpty())
623             context = (Integer JavaDoc) this.contextStack.peek();
624         // test if variable should be added
625
//XQueryExpression parent0Expr = (XQueryExpression) arg.getParentExpression().get(0);
626
if (context != IN_FLWR && !(arg.getQType() != null && arg.getQType().isBoolean()) && ((context == this.IN_RETURN && !(arg instanceof FunctionQNAME) && !(arg instanceof FunctionEXPANDED_QNAME)) || arg instanceof AggregateFunctionCall || arg instanceof InputFunctionCall))
627             // (
628
// !(parent0Expr instanceof Variable) &&
629
// !(arg.getQType() != null && arg.getQType().isBoolean()) &&
630
// (inReturn > 0 || arg instanceof AggregateFunctionCall || arg instanceof InputFunctionCall)
631
// )
632
{
633             FLWRExpression lastflwr = (FLWRExpression) parentFLWRExpressionStack.peek();
634             Variable addvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR);
635             if (varDefinitionStack.isEmpty()) {
636                 lastflwr.addVariable(addvar);
637             } else {
638                 Variable lastvar = (Variable) varDefinitionStack.peek();
639                 int prevpos = lastflwr.getVarPosition(lastvar);
640                 if (prevpos != -1)
641                     lastflwr.addVariable(prevpos, addvar);
642                 else
643                     lastflwr.addVariable(addvar);
644             }
645             resultExpr = addvar;
646             return;
647         }
648         // if (inReturn > 0 && inWhereExpression.isEmpty() && arg.getQType().isBoolean())
649
// throw new TypeException("Boolean expression is not supported : " + arg);
650
contextStack.push(IN_FUNCTION);
651         ArrayList JavaDoc arguments = arg.getArguments();
652         // rule PRIM-1.
653
if (arguments != null) {
654             boolean change = false;
655             ArrayList JavaDoc newArguments = new ArrayList JavaDoc(arguments.size());
656             for (int i = 0; i < arguments.size(); i++) {
657                 XQueryExpression argi = (XQueryExpression) arguments.get(i);
658                 argi.accept(this);
659                 if (resultExpr != null) {
660                     change = true;
661                     newArguments.add(resultExpr);
662                 } else
663                     newArguments.add(argi);
664             }
665             if (change) {
666                 // arg.setBracket(false);
667
arg.setArguments(newArguments);
668                 //resultExpr = arg;
669
ruleNumber++;
670             }
671             //else
672
resultExpr = null;
673         }
674         contextStack.pop();
675     }
676
677     /*
678     --> Rules for class QuantifiedExpression
679     QUANT-1. if mediator change into count otherwise just restructure inner expressions
680     QUANT-2. if mediator dont let any
681     */

682     public void visit(QuantifiedExpression arg) throws XQueryException {
683         if (isRoot) {
684             throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree");
685         }
686         resultExpr = null;
687         // rule QUANT-1.
688
if (isMediator) {
689             FLWRExpression parentFLWR = (FLWRExpression) this.inWhereExpressionStack.peek();
690             ArrayList JavaDoc variables = arg.getVariables();
691             for (int i = 0; i < variables.size(); i++) {
692                 ((Variable) variables.get(i)).setBindingType(Constants.FOR_BINDINGTYPE);
693                 ((Variable) variables.get(i)).addSubPath(((Variable) variables.get(i)));
694             }
695             int kind = arg.getKind();
696             ArrayList JavaDoc countArgs = new ArrayList JavaDoc(1);
697             XQueryExpression tmpExpr = null;
698             Variable tmpvar = null;
699             if (kind == Constants.SOME_QUANTIFIER) {
700                 if (variables.size() > 1)
701                     tmpExpr = new FLWRExpression(variables, arg.getExpression(), new XQueryExpressionSequence((ArrayList JavaDoc) variables.clone(), arg.getParentModule()), arg.getParentModule());
702                 else
703                     tmpExpr = new FLWRExpression(variables, arg.getExpression(), (XQueryExpression) variables.get(0), arg.getParentModule());
704                 tmpExpr.accept(this);
705                 if (resultExpr != null)
706                     tmpExpr = resultExpr;
707                 if (tmpExpr instanceof Variable)
708                     tmpvar = (Variable)tmpExpr;
709                 else {
710                     tmpvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, tmpExpr, Variable.RES_CREATOR);
711                     parentFLWR.addVariable(tmpvar);
712                 }
713                 countArgs.add(tmpvar);
714                 tmpExpr = new FunctionCOUNT(countArgs, arg.getParentModule());
715                 tmpExpr = new ListOpCompExpression(tmpExpr, new ValueInteger("0", arg.getParentModule()), Constants.GT_COMPOP, arg.getParentModule());
716             } else { // if (kind == Constants.EVERY_QUANTIFIER) {
717
ArrayList JavaDoc args = new ArrayList JavaDoc(1);
718                 args.add(arg.getExpression());
719                 if (variables.size() > 1)
720                     tmpExpr = new FLWRExpression(variables, new FunctionNOT(args, arg.getParentModule()), new XQueryExpressionSequence((ArrayList JavaDoc) variables.clone(), arg.getParentModule()), arg.getParentModule());
721                 else
722                     tmpExpr = new FLWRExpression(variables, new FunctionNOT(args, arg.getParentModule()), (XQueryExpression) variables.get(0), arg.getParentModule());
723                 tmpExpr.accept(this);
724                 if (resultExpr != null)
725                     tmpExpr = resultExpr;
726                 if (tmpExpr instanceof Variable)
727                     tmpvar = (Variable)tmpExpr;
728                 else {
729                     tmpvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, tmpExpr, Variable.RES_CREATOR);
730                     parentFLWR.addVariable(tmpvar);
731                 }
732                 countArgs.add(tmpvar);
733                 tmpExpr = new FunctionCOUNT(countArgs, arg.getParentModule());
734                 tmpExpr = new ListOpCompExpression(tmpExpr, new ValueInteger("0", arg.getParentModule()), Constants.EQ_COMPOP, arg.getParentModule());
735             }
736             tmpExpr.accept(this);
737             if (resultExpr == null)
738                 resultExpr = tmpExpr;
739         } else {
740             for (int i = 0; i < arg.getVariables().size(); i++) {
741                 Variable var = (Variable) arg.getVariables().get(i);
742                 XQueryExpression varExpr = var.getExpression();
743                 varExpr.accept(this);
744             }
745             XQueryExpression tmpExpr = arg.getExpression();
746             tmpExpr.accept(this);
747             if (resultExpr != null) {
748                 arg.setExpression(resultExpr);
749             }
750         }
751     }
752
753     /*
754     // to be erased in the latest version of the specification
755     --> Rules for class SortedExpression
756     SORT-1. sort by only supported with located expression or FLWR
757     SORT-2. if qtype is not multiple sort clauses are not useful!
758     SORT-3. restructure expression to FLWR
759     SORT-4. rewrite sort clauses to order by clauses of FLWR
760     SORT-5. verify that resulting sort clauses are not constants
761     */

762     public void visit(SortedExpression arg) throws XQueryException {
763         if (isRoot) {
764             isRoot = false;
765         }
766         XQueryExpression expr = arg.getExpression();
767         // ATTENTION : this must be extended to other possible expressions
768
// for now SORTBY can only be used with sequence of single FLWR expression !!!
769
// rule SORT-1.
770
if (!(expr instanceof FLWRExpression) && !(expr instanceof LocatedExpression))
771             throw new RestructureException("SORTBY can only be used with sequence of single FLWR expression or with a LocatedExpression!!!");
772         // rule SORT-2.
773
if (!expr.getQType().isMultiple()) {
774             expr.accept(this);
775             if (resultExpr == null)
776                 resultExpr = expr;
777             return;
778         }
779         // rule SORT-3.
780
FLWRExpression tmpFLWR = null;
781         if (expr instanceof LocatedExpression) {
782             expr.accept(this);
783             if (resultExpr == null || !(resultExpr instanceof FLWRExpression))
784                 throw new RestructureException("SORTBY used with incorrect path expression");
785             tmpFLWR = (FLWRExpression) resultExpr;
786         } else
787             tmpFLWR = (FLWRExpression) expr;
788         // restructure flwr first to avoid strange(!!!) expression in order by
789
//!!! danger it is assumed that a restructured FLWR is still a FLWR
790
tmpFLWR.accept(this);
791         if (resultExpr != null)
792             tmpFLWR = (FLWRExpression) resultExpr;
793         // rule SORT-4.
794
ArrayList JavaDoc sortClauses = arg.getSortClauses();
795         XQueryExpression returnClause = tmpFLWR.getReturnClause();
796         ArrayList JavaDoc newSortClauses = new ArrayList JavaDoc(sortClauses.size());
797         SubExpressionVisitor subvisitor = new SubExpressionVisitor(typeVisitor);
798         // XQueryExpression tmpExpr = null;
799
for (int i = 0; i < sortClauses.size(); i++) {
800             XQueryExpression sortiexpr = (XQueryExpression) sortClauses.get(i);
801             // W3C WD 16 August 2002
802
int[] order = sortiexpr.getOrder();
803             sortiexpr.setOrder(initOrder);
804             ArrayList JavaDoc resultExprs = null;
805             XQueryExpression tmpExpr = null;
806
807             // to handle qname
808
if (sortiexpr instanceof QName) {
809                 ruleNumber++;
810                 subvisitor.setSubExpression((QName) sortiexpr, true);
811                 returnClause.accept(subvisitor);
812                 resultExprs = subvisitor.getResultExprs();
813                 if (resultExprs.isEmpty() || resultExprs.size() > 1)
814                     throw new TypeException("Invalid sort clause : " + sortiexpr);
815                 tmpExpr = (XQueryExpression) resultExprs.get(0);
816             } else if (sortiexpr instanceof LocatedExpression) {
817                 LocatedExpression tmpLoc = (LocatedExpression) sortiexpr;
818                 ArrayList JavaDoc steps = tmpLoc.getSteps();
819                 Step tmpStep0 = (Step) steps.get(0);
820                 if (tmpStep0.hasSeparator())
821                     throw new TypeException("Invalid sort clause : " + sortiexpr);
822                 XQueryExpression tmpStep0Expr = tmpStep0.getExpression();
823                 if (steps.size() == 1) {
824                     ruleNumber++;
825                     // to handle . or self::node()
826
if (tmpStep0Expr instanceof NodeTest) {
827                         NodeTest tmpNode = (NodeTest) tmpStep0.getExpression();
828                         if (tmpNode.getKind() != NodeKind.NODE)
829                             throw new TypeException("Invalid sort clause : " + sortiexpr);
830                         if (tmpStep0.getAxis() != Axis.SELF)
831                             throw new TypeException("Invalid sort clause : " + sortiexpr);
832                         subvisitor.setSubExpression(null, tmpStep0.getAxis(), 0, true);
833                         returnClause.accept(subvisitor);
834                         resultExprs = subvisitor.getResultExprs();
835                         if (resultExprs.isEmpty() || resultExprs.size() > 1)
836                             throw new TypeException("Invalid sort clause : " + sortiexpr);
837                         tmpExpr = (XQueryExpression) resultExprs.get(0);
838                     }
839                     // to handle @qname or attribute::qname or child::qname
840
else if (tmpStep0Expr instanceof QName) {
841                         QName tmpQName = (QName) tmpStep0.getExpression();
842                         if (tmpStep0.getAxis() != Axis.CHILD && tmpStep0.getAxis() != Axis.ATTRIBUTE)
843                             throw new TypeException("Invalid sort clause : " + sortiexpr);
844                         subvisitor.setSubExpression(tmpQName, tmpStep0.getAxis(), /*(tmpStep0.getAxis() == Axis.CHILD && i!=0) ? 0 :*/
845                         1, true);
846                         returnClause.accept(subvisitor);
847                         resultExprs = subvisitor.getResultExprs();
848                         if (resultExprs.isEmpty() || resultExprs.size() > 1)
849                             throw new TypeException("Invalid sort clause : " + sortiexpr);
850                         tmpExpr = (XQueryExpression) resultExprs.get(0);
851                     } else
852                         throw new TypeException("Invalid sort clause : " + sortiexpr);
853                 } else {
854                     // to handle step/step/.......step
855
ArrayList JavaDoc tmpExprList = new ArrayList JavaDoc(1);
856                     tmpExprList.add(returnClause);
857                     int depth = 1;
858                     for (int j = 0; j < steps.size(); j++) {
859                         ruleNumber++;
860                         //if (depth != -1) if (j != steps.size()-1) depth = 1; else depth = 0;
861
Step stepj = (Step) steps.get(j);
862                         // first step must be without separator!
863
if (j == 0 && stepj.hasSeparator())
864                             throw new TypeException("Invalid sort clause : " + sortiexpr);
865                         XQueryExpression stepjExpr = stepj.getExpression();
866                         if (stepjExpr instanceof QName) {
867                             if (j != 0 && stepj.getAxis() != Axis.CHILD && stepj.getAxis() != Axis.ATTRIBUTE)
868                                 throw new TypeException("Invalid sort clause : " + sortiexpr);
869                             if (stepj.getAxis() == Axis.ATTRIBUTE && j != steps.size() - 1)
870                                 throw new TypeException("Invalid sort clause : " + sortiexpr);
871                             if (depth == -1) {
872                                 depth = 0;
873                                 subvisitor.setSubExpression((QName) stepjExpr, stepj.getAxis(), depth, j == steps.size() - 1 ? true : false);
874                                 for (int k = 0; k < tmpExprList.size(); k++) {
875                                     XQueryExpression tmpExprListk = (XQueryExpression) tmpExprList.get(k);
876                                     tmpExprListk.accept(subvisitor);
877                                     if (resultExprs == null)
878                                         resultExprs = (ArrayList JavaDoc) subvisitor.getResultExprs().clone();
879                                     else
880                                         resultExprs.addAll(subvisitor.getResultExprs());
881                                 }
882                                 depth = -1;
883                             }
884                             if (depth != -1)
885                                 if (j == 0)
886                                     depth = 1;
887                                 else
888                                     depth = 0;
889                             subvisitor.setSubExpression((QName) stepjExpr, stepj.getAxis(), depth, j == steps.size() - 1 ? true : false);
890                             for (int k = 0; k < tmpExprList.size(); k++) {
891                                 XQueryExpression tmpExprListk = (XQueryExpression) tmpExprList.get(k);
892                                 tmpExprListk.accept(subvisitor);
893                                 if (resultExprs == null)
894                                     resultExprs = (ArrayList JavaDoc) subvisitor.getResultExprs().clone();
895                                 else
896                                     resultExprs.addAll(subvisitor.getResultExprs());
897                             }
898                             if (depth == -1)
899                                 if (j != steps.size() - 1)
900                                     depth = 1;
901                                 else
902                                     depth = 0;
903                             //if (depth == -1) depth = 1;
904
if (resultExprs.isEmpty() || (j == steps.size() - 1 && resultExprs.size() > 1))
905                                 throw new TypeException("Invalid sort clause : " + sortiexpr);
906                             tmpExprList = (ArrayList JavaDoc) resultExprs.clone();
907                             resultExprs = null;
908                         } else if (stepjExpr instanceof NodeTest) {
909                             NodeTest tmpNode = (NodeTest) stepj.getExpression();
910                             if (tmpNode.getKind() != NodeKind.NODE)
911                                 throw new TypeException("Invalid sort clause : " + sortiexpr);
912                             if (stepj.getAxis() != Axis.DESCENDANT_OR_SELF)
913                                 throw new TypeException("Invalid sort clause : " + sortiexpr);
914                             if (tmpNode.getKind() == NodeKind.NODE)
915                                 depth = -1;
916                         } else
917                             throw new TypeException("Invalid sort clause : " + sortiexpr);
918                     }
919                     tmpExpr = (XQueryExpression) tmpExprList.get(0);
920                 }
921             }
922             if (tmpExpr != null) {
923                 //tmpExpr.setBrace(false);
924
tmpExpr.setOrder(order);
925                 newSortClauses.add(tmpExpr);
926             }
927
928         }
929
930         // verifcation that sort clauses have correct typing
931
// erase some sort clause that are not interesting -> constants
932
// -> either constants, or expression containing only varibales not used in the current flwr expression
933
// rule SORT-5.
934
if (!newSortClauses.isEmpty()) {
935             GetBoundVariablesVisitor gbvv = new GetBoundVariablesVisitor(true, false);
936             for (int i = 0; i < newSortClauses.size(); i++) {
937                 gbvv.reset();
938                 XQueryExpression sortiexpr = (XQueryExpression) newSortClauses.get(i);
939
940                 sortiexpr.accept(gbvv);
941                 ArrayList JavaDoc tmplist = gbvv.getVariables();
942                 if (tmplist == null || tmplist.isEmpty()) {
943                     newSortClauses.remove(i);
944                     i--;
945                     continue;
946                 }
947                 boolean cont = false;
948                 for (int j = 0; j < tmplist.size(); j++) {
949                     if (tmpFLWR.getVariables().contains(tmplist.get(j))) {
950                         cont = true;
951                         break;
952                     }
953                 }
954                 if (cont == false) {
955                     newSortClauses.remove(i);
956                     i--;
957                     continue;
958                 }
959                 // verify sort clause typing
960
QType qtypei = sortiexpr.getQType();
961                 if (qtypei == null || !qtypei.isAtomic() || qtypei.isMultiple())
962                     throw new TypeException("Invalid sort clause : " + sortiexpr);
963             }
964         }
965         if (!newSortClauses.isEmpty())
966             tmpFLWR.setOrderBy(newSortClauses);
967         resultExpr = tmpFLWR;
968     }
969
970     public void visit(UnOpMinusExpression arg) throws XQueryException {
971         if (isRoot) {
972             makeDummyOneFlwr(arg);
973             return;
974         }
975         // test if variable should be added
976
XQueryExpression parent0Expr = (XQueryExpression) arg.getParentExpression().get(0);
977         if (!(parent0Expr instanceof Variable)) {
978             FLWRExpression lastflwr = (FLWRExpression) parentFLWRExpressionStack.peek();
979             Variable addvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR);
980             if (varDefinitionStack.isEmpty()) {
981                 lastflwr.addVariable(addvar);
982             } else {
983                 Variable lastvar = (Variable) varDefinitionStack.peek();
984                 int prevpos = lastflwr.getVarPosition(lastvar);
985                 if (prevpos != -1)
986                     lastflwr.addVariable(prevpos, addvar);
987                 else
988                     lastflwr.addVariable(addvar);
989             }
990             resultExpr = addvar;
991             return;
992         }
993         contextStack.push(IN_FUNCTION);
994         XQueryExpression tmpExpr = arg.getExpression();
995         tmpExpr.accept(this);
996         if (resultExpr != null) {
997             arg.setExpression(resultExpr);
998         }
999         resultExpr = null;
1000        contextStack.pop();
1001    }
1002
1003    public void visit(ValidateExpression arg) throws XQueryException {
1004        XQueryExpression tmpExpr = arg.getExpression();
1005        tmpExpr.accept(this);
1006        if (resultExpr != null) {
1007            arg.setExpression(resultExpr);
1008        }
1009        resultExpr = null;
1010    }
1011
1012    public void visit(Value arg) throws XQueryException {
1013        if (isRoot) {
1014            makeDummyFlwr(arg);
1015            return;
1016        }
1017        resultExpr = null;
1018    }
1019
1020    /*
1021    --> Rules for class Variable
1022    VAR-1. if variable definition then restructure associated expression
1023    VAR-2. if in return and qtype is multiple then create FLWR to iterate on it
1024    */

1025    public void visit(Variable arg) throws XQueryException {
1026        if (isRoot) {
1027            throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree");
1028        }
1029        resultExpr = null;
1030        Integer JavaDoc context = null;
1031        if (!this.contextStack.isEmpty())
1032            context = (Integer JavaDoc) this.contextStack.peek();
1033        // rule VAR-1.
1034
if (context != null && context.equals(this.IN_FLWR)) {
1035            varDefinitionStack.add(arg);
1036            arg.getExpression().accept(this);
1037            varDefinitionStack.pop();
1038            if (resultExpr != null)
1039                arg.setExpression(resultExpr,true);
1040            resultExpr = arg;
1041            ruleNumber++;
1042        } else if (context != null && (context.equals(this.IN_WHERE))) {
1043            // QType qtype = arg.getQType();
1044
// XQueryExpression tmpExpr = (XQueryExpression) inWhereExpression.peek();
1045
// if (!qtype.isBoolean() && (tmpExpr instanceof BinOpANDExpression || tmpExpr instanceof BinOpORExpression)) {
1046
// ArrayList tmpList = new ArrayList(1);
1047
// tmpList.add(arg);
1048
// resultExpr = new FunctionEXISTS(tmpList, typeVisitor);
1049
// ruleNumber++;
1050
// }
1051
} else {
1052            // rule VAR-2.
1053
if (arg.getExpression() == null)
1054                return;
1055            QType qtype = arg.getQType();
1056            // verification that type is not boolean (not supported yet)
1057
// if (qtype.isBoolean())
1058
// throw new TypeException("Boolean expression is not supported : " + arg.getExpression());
1059
if (context != null && context.equals(this.IN_RETURN) && qtype.isMultiple()) {
1060                // create new variable to iterate on
1061
Variable tmpVar = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg, Variable.RES_CREATOR);
1062                ArrayList JavaDoc vars = new ArrayList JavaDoc(1);
1063                vars.add(tmpVar);
1064                FLWRExpression tmpFLWR = new FLWRExpression(vars, null, tmpVar, arg.getParentModule());
1065                tmpFLWR.setParentModule(arg.getParentModule());
1066                resultExpr = tmpFLWR;
1067                ruleNumber++;
1068            }
1069        }
1070    }
1071
1072    /*
1073    --> Rules for class XQueryBinaryOperatorExpression
1074    BINOP-1. restructure both operands and replace them if necessary
1075    */

1076    public void visit(XQueryBinaryOperatorExpression arg) throws XQueryException {
1077        if (isRoot) {
1078            throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree");
1079        }
1080        XQueryExpression tmpExpr = arg.getExpression1();
1081        tmpExpr.accept(this);
1082        if (resultExpr != null) {
1083            arg.setExpression1(resultExpr);
1084        }
1085        tmpExpr = arg.getExpression2();
1086        tmpExpr.accept(this);
1087        if (resultExpr != null) {
1088            arg.setExpression2(resultExpr);
1089        }
1090        resultExpr = null;
1091    }
1092
1093    // public void visit(XQueryBooleanOperatorExpression arg) throws XQueryException;
1094

1095    public void visit(XQueryExpression arg) throws XQueryException {
1096        // if (isRoot) {
1097
// makeDummyOneFlwr(arg);
1098
// return;
1099
// }
1100
resultExpr = null;
1101    }
1102
1103    /*
1104    --> Rules for class XQueryExpressionSequence
1105    SEQ-1. restructure all operands and replace them if necessary
1106    */

1107    public void visit(XQueryExpressionSequence arg) throws XQueryException {
1108        if (isRoot) {
1109            makeDummyFlwr(arg);
1110            return;
1111        }
1112        resultExpr = null;
1113        ArrayList JavaDoc subExpressions = arg.getSubExpressions();
1114        if (subExpressions != null) {
1115            ArrayList JavaDoc newSubExpressions = new ArrayList JavaDoc(subExpressions.size());
1116            for (int i = 0; i < subExpressions.size(); i++) {
1117                XQueryExpression expri = (XQueryExpression) subExpressions.get(i);
1118                expri.accept(this);
1119                if (resultExpr != null)
1120                    newSubExpressions.add(resultExpr);
1121                else
1122                    newSubExpressions.add(expri);
1123            }
1124            arg.setSubExpressions(newSubExpressions);
1125            resultExpr = arg;
1126        }
1127    }
1128
1129    public void visit(XQueryModule arg) throws XQueryException {
1130        ArrayList JavaDoc expressions = arg.getExpressions();
1131        if (expressions != null)
1132            for (int i = 0; i < expressions.size(); i++) {
1133                ((XQueryExpression) expressions.get(i)).accept(this);
1134                if (resultExpr != null) {
1135                    expressions.set(i, resultExpr);
1136                }
1137            }
1138        resultExpr = null;
1139    }
1140
1141    /*
1142    --> Rules for class XQueryUnaryOperatorExpression
1143    SEQ-1. restructure operand and replace it if necessary
1144    */

1145    public void visit(XQueryUnaryOperatorExpression arg) throws XQueryException {
1146        if (isRoot) {
1147            throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree");
1148        }
1149        XQueryExpression tmpExpr = arg.getExpression();
1150        tmpExpr.accept(this);
1151        if (resultExpr != null) {
1152            arg.setExpression(resultExpr);
1153        }
1154        resultExpr = null;
1155    }
1156
1157    public void visit(XMLComment arg) throws XQueryException {
1158        if (isRoot) {
1159            makeDummyOneFlwr(arg);
1160            return;
1161        }
1162        XQueryExpression tmpExpr = arg.getExpression();
1163        tmpExpr.accept(this);
1164        if (resultExpr != null) {
1165            arg.setExpression(resultExpr);
1166        }
1167        resultExpr = null;
1168    }
1169
1170    // private methods
1171

1172    private void makeDummyFlwr(XQueryExpression arg) throws XQueryException {
1173        isRoot = false;
1174        Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg, Variable.RES_CREATOR);
1175        ArrayList JavaDoc vars = new ArrayList JavaDoc(1);
1176        vars.add(var);
1177        arg.setRoot(true);
1178        FLWRExpression tmpFLWR = new FLWRExpression(vars, null, null, var, arg.getParentModule());
1179        tmpFLWR.setParentModule(arg.getParentModule());
1180        parentFLWRExpressionStack.push(tmpFLWR);
1181        tmpFLWR.accept(this);
1182        parentFLWRExpressionStack.pop();
1183        if (resultExpr == null)
1184            resultExpr = tmpFLWR;
1185    }
1186
1187    private void makeDummyOneFlwr(XQueryExpression arg) throws XQueryException {
1188        isRoot = false;
1189        Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new ValueInteger("1", arg.getParentModule()), Variable.RES_CREATOR);
1190        var.isDummy(true);
1191        ArrayList JavaDoc vars = new ArrayList JavaDoc(1);
1192        vars.add(var);
1193        arg.setRoot(true);
1194        FLWRExpression tmpFLWR = new FLWRExpression(vars, null, null, arg, arg.getParentModule());
1195        tmpFLWR.setParentModule(arg.getParentModule());
1196        parentFLWRExpressionStack.push(tmpFLWR);
1197        tmpFLWR.accept(this);
1198        parentFLWRExpressionStack.pop();
1199        if (resultExpr == null)
1200            resultExpr = tmpFLWR;
1201    }
1202
1203}
1204
Popular Tags