KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > extractor > algebra > RemoveProjectVisitor


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

22
23 package org.xquark.extractor.algebra;
24
25 import java.util.*;
26
27 import org.xquark.extractor.common.Debug;
28 import org.xquark.extractor.common.SqlWrapperException;
29 import org.xquark.xquery.parser.XQueryExpression;
30
31 public final class RemoveProjectVisitor extends DefaultAlgebraVisitor {
32     private static final String JavaDoc RCSRevision = "$Revision: 1.5 $";
33     private static final String JavaDoc RCSName = "$Name: $";
34
35     private RemoveProjectReplaceVisitor _rprv;
36     private RemoveProjectGoUpVisitor _rpguv;
37
38     private Stack _scopeStack = new Stack();
39
40     public void reinit() {
41         _scopeStack.clear();
42         createScope();
43     }
44
45     public RemoveProjectVisitor() {
46     }
47
48     // public RemoveProjectVisitor(RemoveProjectGoUpVisitor rpguv) {
49
// setGoUpVisitor(rpguv);
50
// }
51

52     /**
53     Access method for the _rprv property.
54     
55     @return the current value of the _rprv property
56      */

57     public RemoveProjectGoUpVisitor getGoUpVisitor() {
58         if (null == _rpguv) {
59             _rpguv = new RemoveProjectGoUpVisitor();
60         }
61         return _rpguv;
62     }
63
64     /**
65     Sets the value of the _replaceVisitor property.
66     
67     @param aReplaceVisitor the new value of the _replaceVisitor property
68      */

69     public void setGoUpVisitor(RemoveProjectGoUpVisitor rpguv) {
70         _rpguv = rpguv;
71     }
72
73     private boolean isDeletePermitted() {
74         // Trace.enter(this, "isDeletePermitted()");
75
boolean retVal = ((Scope) _scopeStack.peek())._deletePermited;
76         // Trace.exit(this, "isDeletePermitted()", retVal.toString());
77
return retVal;
78     }
79
80     private void permitDelete(Expression node, boolean permit) {
81         //Trace.enter(this, "permitDelete(boolean permit)", node.toString() + "\t" + (permit ? "true" : "false"));
82
Scope currentScope = (Scope) _scopeStack.peek();
83         currentScope._deletePermited = permit;
84         currentScope._node = node;
85         //Trace.exit(this, "permitDelete(boolean permit)", node.toString() + "\t" + (permit ? "true" : "false"));
86
}
87
88     private Expression currentPermiter() {
89         //Trace.enter(this, "currentPermiter()");
90
Scope currentScope = (Scope) _scopeStack.peek();
91         Debug.assertTrue(currentScope._deletePermited, "currentScope._deletePermited");
92         //Trace.exit(this, "currentPermiter()");
93
return currentScope._node;
94     }
95
96     private void createScope() {
97         _scopeStack.push(new Scope());
98     }
99
100     private Scope currentScope() {
101         return (Scope) _scopeStack.peek();
102     }
103
104     private void leaveScope() {
105         //Trace.enter(this, "leaveScope()");
106
RenameRelation rr = currentScope()._unresolvedRenameRelation;
107         if (null != rr) {
108             if (null != rr.getFather() && !(rr.getOperand() instanceof Table)) {
109                 /* remove this RenameRelation*/
110                 //Trace.message(this, "leaveScope()", "Removing unresoled RenameRelation...");
111
/* make up map*/
112                 HashMap map = new HashMap();
113                 Object JavaDoc tableInstance = null;
114                 Set vtis = rr.visibleTableInstances();
115                 int visibleTableInstancesNumber = vtis.size();
116
117                 if (0 == visibleTableInstancesNumber) {
118                     Debug.assertTrue(false, "internal logic error");
119                 } else if (1 == visibleTableInstancesNumber) {
120                     tableInstance = (Expression) vtis.toArray()[0];
121                     if (!(tableInstance instanceof RenameRelation)) {
122                         tableInstance = new NullPointer();
123                     }
124                     map.put(rr, tableInstance);
125                 } else {
126                     Debug.nyi("remove RenameRelation");
127                 }
128
129                 /* */
130                 getGoUpVisitor().setMap(map);
131                 getGoUpVisitor().setEndNode(currentPermiter());
132                 //Trace.message(this, "replace map", getGoUpVisitor().printMap());
133

134                 Expression father = rr.getFather();
135                 boolean replaced = father.replaceChild(rr, rr.getOperand());
136                 Debug.assertTrue(replaced, "replaced");
137                 rr.setFather(null);
138                 //Trace.message(this, "leaveScope()", "RenameRelation removed.");
139
father.accept(_rpguv);
140             }
141         }
142
143         _scopeStack.pop();
144         //Trace.exit(this, "leaveScope()");
145
}
146
147     //public void visit(Expression arg) throws SqlWrapperException;
148

149     // public void visit(BinaryOperator arg) throws SqlWrapperException {
150
// Trace.enter(this,"visit(BinaryOperator arg)",arg.pprint());
151
// Trace.exit(this,"visit(BinaryOperator arg)",arg.pprint());
152
// }
153

154     public void visit(BinaryAlgebra arg) throws SqlWrapperException {
155         //Trace.enter(this, "visit(BinaryAlgebra arg)", arg.pprint());
156
/* implementation or Merg, Union, Intersect and difference, but not for OuterJoin */
157         /* here the process of deepth-first serach re-start */
158         createScope();
159         arg.getLeftOperand().accept(this);
160         leaveScope();
161
162         createScope();
163         arg.getRightOperand().accept(this);
164         leaveScope();
165
166         //Trace.exit(this, "visit(BinaryAlgebra arg)", arg.pprint());
167
}
168
169     public void visit(BinaryAtomicOp arg) throws SqlWrapperException {
170         //Trace.enter(this, "visit(BinaryAtomicOp arg)", arg.pprint());
171

172         createScope();
173         arg.getLeftOperand().accept(this);
174         leaveScope();
175
176         createScope();
177         arg.getRightOperand().accept(this);
178         leaveScope();
179
180         //Trace.exit(this, "visit(BinaryAtomicOp arg)", arg.pprint());
181
}
182
183     public void visit(BinOpOuterJoin arg) throws SqlWrapperException {
184         //Trace.enter(this, "visit(BinOpOuterJoin arg)", arg.pprint());
185

186         arg.getLeftOperand().accept(this);
187         arg.getRightOperand().accept(this);
188
189         //Trace.exit(this, "visit(BinOpOuterJoin arg)", arg.pprint());
190
}
191
192     public void visit(SortSpecification arg) throws SqlWrapperException {
193         //Trace.enter(this, "visit(SortSpecification arg)", arg.pprint());
194
Expression sortExpr = arg.getSortExpression();
195         sortExpr.accept(this);
196         //Trace.exit(this, "visit(SortSpecification arg)", arg.pprint());
197
}
198
199     public void visit(RenameRelation arg) throws SqlWrapperException {
200         //Trace.enter(this, "visit(RenameRelation arg)", arg.pprint());
201

202         /** @todo within a scope, there might be serverl unresolved RenameRelation.
203          * Scope class should keep a list of unresolved RenameRelation instead of one*/

204         if (!(arg.getOperand() instanceof Table || arg.getOperand() instanceof UnOpProject)) {
205             /* when the operand is Table, this RenameRelation should not be removed
206             * when the operand is UnOpProject, this RenameRelation should have been
207             * removed with the UnOpProject */

208             currentScope()._unresolvedRenameRelation = arg;
209             //Trace.message(this, "visit(RenameRelation arg)", "unresolved RenameRelation added to current scope");
210
}
211
212         Expression operand = arg.getOperand();
213         operand.accept(this);
214
215         //Trace.exit(this, "visit(RenameRelation arg)", arg.pprint());
216
}
217
218     public void visit(Table arg) throws SqlWrapperException {
219         //Trace.enter(this, "visit(Table arg)", arg.pprint());
220
/* here, the process reach a leaf node */
221         //Trace.exit(this, "visit(Table arg)", arg.pprint());
222
}
223
224     public void visit(Join arg) throws SqlWrapperException {
225         //Trace.enter(this, "visit(Join arg)", arg.pprint());
226

227         List list = arg.getPredicateList();
228         if (null != list) {
229             Expression expr = null;
230             for (int i = 0; i < list.size(); i++) {
231                 expr = (Expression) list.get(i);
232                 createScope();
233                 expr.accept(this);
234                 leaveScope();
235             }
236         }
237
238         list = arg.getOperands();
239         Debug.assertTrue(null != list, "null!=list");
240         Expression expr = null;
241         for (int i = 0; i < list.size(); i++) {
242             expr = (Expression) list.get(i);
243             expr.accept(this);
244         }
245
246         //Trace.exit(this, "visit(Join arg)", arg.pprint());
247
}
248
249     public void visit(UnaryAlgebra arg) throws SqlWrapperException {
250         //Trace.enter(this, "visit(UnaryAlgebra arg)", arg.pprint());
251

252         List list = arg.getParameterList();
253         if (null != list) {
254             Expression expr = null;
255             for (int i = 0; i < list.size(); i++) {
256                 expr = (Expression) list.get(i);
257                 createScope();
258                 expr.accept(this);
259                 leaveScope();
260             }
261         }
262
263         Expression operand = arg.getOperand();
264         if (isDeletePermitted()) {
265             /* check if this operater permet to delete a underlying UnOpProject*/
266             List opposers = vote(arg);
267             if (null == opposers) {
268                 /* do nothing */
269             } else {
270                 permitDelete(arg, false);
271             }
272         }
273         operand.accept(this);
274
275         //Trace.exit(this, "visit(UnaryAlgebra arg)", arg.pprint());
276
}
277
278     public void visit(UnaryAtomicOp arg) throws SqlWrapperException {
279         //Trace.enter(this, "visit(UnaryAtomicOp arg)", arg.pprint());
280
arg.getOperand().accept(this);
281         //Trace.exit(this, "visit(UnaryAtomicOp arg)", arg.pprint());
282
}
283
284     public void visit(UnOpAggregate arg) throws SqlWrapperException {
285         //Trace.enter(this, "visit(UnOpAggregate arg)", arg.pprint());
286

287         Expression operand = arg.getOperand();
288
289         /* check if this UnOpAggregate permet to delete a underlying UnOpProject*/
290         createScope();
291         List opposers = vote(arg);
292         if (null == opposers) {
293             permitDelete(arg, true);
294             //Trace.message(this, "visit(UnOpAggregate arg)", "removal of project is permitted !");
295
}
296         operand.accept(this);
297         leaveScope();
298
299         List itemList = arg.getItemList();
300         Expression item = null;
301         ;
302         for (int i = 0; i < itemList.size(); i++) {
303             createScope();
304             item = (Expression) itemList.get(i);
305             item.accept(this);
306             leaveScope();
307         }
308
309         //Trace.exit(this, "visit(UnOpAggregate arg)", arg.pprint());
310
}
311
312     public void visit(UnOpExists arg) throws SqlWrapperException {
313         //Trace.enter(this, "visit(UnOpExists arg)", arg.pprint());
314
createScope();
315         permitDelete(arg, true);
316         arg.getOperand().accept(this);
317         leaveScope();
318         //Trace.exit(this, "visit(UnOpExists arg)", arg.pprint());
319
}
320
321     public void visit(UnOpProject arg) throws SqlWrapperException {
322         //Trace.enter(this, "visit(UnOpProject arg)", arg.pprint());
323

324         Expression operand = arg.getOperand();
325
326         /* visit its operand */
327         //Trace.message(this, "visit(UnOpProject arg)", "Visiting its operand...");
328
createScope();
329         /* check if this UnOpProject permet to delete a underlying UnOpProject*/
330         List opposers = vote(arg);
331         if (null == opposers) {
332             permitDelete(arg, true);
333             //Trace.message(this, "visit(UnOpProject arg)", "removal of project is permitted !");
334
}
335         operand.accept(this);
336         leaveScope();
337
338         /*visit its items */
339         //Trace.message(this, "visit(UnOpProject arg)", "Visiting its item list...");
340
List itemList = arg.getItemList();
341         Expression item = null;
342         ;
343         for (int i = 0; i < itemList.size(); i++) {
344             createScope();
345             item = (Expression) itemList.get(i);
346             item.accept(this);
347             leaveScope();
348         }
349
350         /* remove itself if possible */
351         if (isDeletePermitted()) {
352             if (!arg.getDistinct()) {
353                 removeProject(arg, currentPermiter());
354             } else if (currentPermiter() instanceof UnOpAggregate) {
355                 /* @todo verify that currentPermiter contains only aggregation funtions like :
356                  * aggrFunc(attr), but not aggrFunc(*)
357                  */

358                 if (1 == arg.getItemList().size()) {
359                     removeProject(arg, currentPermiter());
360                     ((UnOpAggregate) currentPermiter()).distinctAggregation();
361
362                 } else {
363                     Debug.nyi("1 != arg.getItemList().size()");
364                 }
365             }
366         }
367
368         //Trace.exit(this, "visit(UnOpProject arg)", arg.pprint());
369
}
370
371     private void removeProject(UnOpProject project, Expression permittingNode) {
372         //Trace.enter(this, "removeProject(UnOpProject project, Expression permittingNode)");
373

374         //Trace.message(this, "visit(UnOpProject arg)", "starting GoUpVisitor..");
375
HashMap map = makeMap(project);
376         getGoUpVisitor().setMap(map);
377         getGoUpVisitor().setEndNode(permittingNode);
378         //Trace.message(this, "replace map", getGoUpVisitor().printMap());
379

380         Expression father = project.getFather();
381
382         boolean replaced = father.replaceChild(project, project.getOperand());
383         Debug.assertTrue(replaced, "replaced");
384
385         project.setFather(null);
386         //Trace.message(this, "visit(UnOpProject arg)", "project removed.");
387
father.accept(_rpguv);
388
389         //Trace.exit(this, "removeProject(UnOpProject project, Expression permittingNode)");
390
}
391
392     private List vote(Expression arg) {
393         //Trace.enter(this, "vote(Expression oprtr)", arg.pprint());
394

395         //Trace.exit(this, "vote(Expression oprtr)", arg.pprint());
396
return null;
397     }
398
399     private List vote(UnOpProject arg) {
400         //Trace.enter(this, "vote(Expression oprtr)", arg.pprint());
401
/** @todo */
402         List retVal = null;
403         //Trace.exit(this, "vote(Expression oprtr)", arg.pprint());
404
return retVal;
405     }
406
407     private HashMap makeMap(UnOpProject arg) {
408         //Trace.enter(this, "makeMap(UnOpProject arg))", arg.pprint());
409

410         HashMap retVal = new HashMap();
411         List itemList = arg.getItemList();
412         Expression item = null;
413         String JavaDoc attrName = null;
414         AttributeExpression attrExpr = null;
415         Expression replacer = null;
416         XQueryExpression originalXExpr = null;
417
418         for (int i = 0; i < itemList.size(); i++) {
419             item = (Expression) itemList.get(i);
420             attrName = item.getName();
421             attrExpr = new AttributeExpression(null, attrName);
422
423             // originalXExpr = item.getOrginalXExpr();
424
// Debug.assertTrue(null != originalXExpr, "null != originalXExpr" + item.pprint());
425

426             replacer = findReplacer(item);
427             retVal.put(attrExpr, replacer);
428         }
429         //Trace.exit(this, "makeMap(UnOpProject arg))", arg.pprint());
430
return retVal;
431     }
432
433     private Expression findReplacer(Expression item) {
434         //Trace.enter(this, "findReplacer(Expression item)", item.pprint());
435

436         Expression retVal = null;
437
438         if (item instanceof RenameItem) {
439             retVal = ((RenameItem) item).getOperand();
440             retVal = findReplacer(retVal);
441         }
442         // else if (item instanceof AttributeExpression) {
443
// retVal = ((AttributeExpression)item).getUnderlyinExpr();
444
// if (retVal instanceof Attribute) {
445
// /* item is the first AttributeExpression who refer a Attribute */
446
// retVal = item;
447
// }
448
// retVal = item;
449
// }
450
else {
451             retVal = item;
452             // Debug.assertTrue(false,"internal logic error");
453
}
454
455         //Trace.exit(this, "findReplacer(Expression item)", item.pprint());
456
return retVal;
457     }
458
459     class Scope {
460         private static final String JavaDoc RCSRevision = "$Revision: 1.5 $";
461         private static final String JavaDoc RCSName = "$Name: $";
462
463         boolean _deletePermited = false;
464         Expression _node = null;
465         RenameRelation _unresolvedRenameRelation = null;
466         Scope() {
467         }
468         Scope(Expression node, boolean deletePermited) {
469             _node = node;
470             _deletePermited = deletePermited;
471         }
472     }
473 }
474
Popular Tags