KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > eval > lib > NestEvaluatedTC


1 /**
2  * MEDOR: Middleware Enabling Distributed Object Requests
3  *
4  * Copyright (C) 2001-2004 France Telecom R&D
5  * Contact: alexandre.lefebvre@rd.francetelecom.com
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  * Initial developers: M. Alia, A. Lefebvre
22  */

23
24 /**
25  * Package definition.
26  */

27
28 package org.objectweb.medor.eval.lib;
29
30 import org.objectweb.medor.api.Field;
31 import org.objectweb.medor.api.MedorException;
32 import org.objectweb.medor.api.TupleStructure;
33 import org.objectweb.medor.eval.api.BinaryEvaluatedTC;
34 import org.objectweb.medor.eval.api.NodeEvaluator;
35 import org.objectweb.medor.eval.api.EvaluationMetaData;
36 import org.objectweb.medor.expression.api.ParameterOperand;
37 import org.objectweb.medor.expression.api.VariableOperand;
38 import org.objectweb.medor.expression.api.Expression;
39 import org.objectweb.medor.expression.api.ExpressionException;
40 import org.objectweb.medor.expression.api.Operand;
41 import org.objectweb.medor.expression.lib.And;
42 import org.objectweb.medor.expression.lib.Equal;
43 import org.objectweb.medor.expression.lib.BasicVariableOperand;
44 import org.objectweb.medor.filter.api.ExpressionHelper;
45 import org.objectweb.medor.filter.api.FieldOperand;
46 import org.objectweb.medor.filter.lib.BasicFieldOperand;
47 import org.objectweb.medor.filter.postfix.PostfixExpressionHelper;
48 import org.objectweb.medor.query.api.NestQueryNode;
49 import org.objectweb.medor.query.api.QueryNode;
50 import org.objectweb.medor.query.api.QueryTreeField;
51 import org.objectweb.medor.query.lib.SelectProject;
52 import org.objectweb.medor.tuple.api.Tuple;
53 import org.objectweb.medor.tuple.api.TupleCollection;
54 import org.objectweb.medor.tuple.lib.MemoryTuple;
55
56 import java.util.LinkedList JavaDoc;
57
58 /**
59  * This class represent is TupleCollection Result of the Nest Operation.
60  * for each GroupBy fields, a SelectProject Operation is evaluated. The result
61  * of this Operation is the NestedField TupleCollection. To select the next Group,
62  * a collection containing indexes of all tuples already grouped.
63  */

64 public class NestEvaluatedTC
65         extends BasicBinaryEvalutedTC
66         implements BinaryEvaluatedTC {
67
68     private NestQueryNode nestedQueryTree;
69     private QueryNode query1, query2;
70     private Expression groupByFilter1,groupByFilter2;
71     private int cursor,tcResultSize;
72     private boolean isTheLast,nextEvaluatorIsFree;
73     /**
74      * Contain indexes of all tuples already visited in the sub-TupleCollection
75     */

76     private LinkedList JavaDoc visitedGroup;
77     private ExpressionHelper expressionHeleper;
78     private NodeEvaluator subNodeEvaluator,nodeEvaluator1,nodeEvaluator2;
79     /**
80      * Buffers containing current and next result Tuple
81      */

82     private MemoryTuple tupleBuffer1,tupleBuffer2;
83     /**
84      * Arrays of buffer's fields
85      */

86     private VariableOperand[] operandBuffer1,operandBuffer2;
87     private TupleCollection nestedTupleCollection;
88     /**
89      * Contains the attributes which are not grouped designed with their new Names
90      */

91     private Field[] groupByFields;
92     private EvaluationMetaData evaluationMetaData;
93
94     public NestEvaluatedTC(NestQueryNode query,
95                            NodeEvaluator subNodeEvaluator,
96                            ParameterOperand[] parameters,
97                            EvaluationMetaData evaluationMetaData)
98         throws MedorException {
99         this.nestedQueryTree = query;
100         this.subNodeEvaluator = subNodeEvaluator;
101         this.evaluationMetaData = evaluationMetaData;
102         visitedGroup = new LinkedList JavaDoc();
103         nestedTupleCollection = subNodeEvaluator.fetchData(parameters);
104         groupByFields = query.getNestingFields();
105         tcResultSize = groupByFields.length;
106
107         /**
108          * We construct a Filter wich is used to group Fields using the
109          * SelectProject Operation (Equality between same fields).
110          * We can use a parametered Filter (ParameterOperand) or FieldOperand.
111          * We have used the second method by upgrading the Filter Operand Values
112          * for each group.
113          */

114         int sizeOfFilter = ((groupByFields.length - 1) * 4) + 3;
115         Expression[] filterExpression = new Expression[sizeOfFilter];
116         Expression[] filterExpressionClone = new Expression[sizeOfFilter];
117         FieldOperand fop;
118
119         int filterIndex = 0;
120         for (int cpt = 0; (cpt < groupByFields.length); cpt++) {
121             fop = new BasicFieldOperand(groupByFields[cpt]);
122             if (filterIndex == 0) {
123                 filterExpression[0] = fop;
124                 filterExpressionClone[0] = fop;
125                 filterExpression[2] = new Equal();
126                 filterExpressionClone[2] = new Equal();
127                 filterIndex = 2;
128             }
129             else {
130                 filterExpression[++filterIndex] = fop;
131                 filterExpressionClone[++filterIndex] = fop;
132                 filterIndex = filterIndex + 2;
133                 filterExpression[filterIndex] = new Equal();
134                 filterExpressionClone[filterIndex] = new Equal();
135                 filterExpression[++filterIndex] = new And();
136                 filterExpressionClone[++filterIndex] = new And();
137             }
138         }
139         expressionHeleper = new PostfixExpressionHelper();
140
141         try {
142             groupByFilter1 = expressionHeleper.join(filterExpression);
143             groupByFilter2 = expressionHeleper.join(filterExpressionClone);
144         }
145         catch (ExpressionException e) {
146             throw new MedorException(e);
147         }
148
149         operandBuffer1 = new VariableOperand[tcResultSize];
150         operandBuffer2 = new VariableOperand[tcResultSize];
151         for (int cpt = 0;
152              (cpt < (nestedQueryTree.getTupleStructure().getSize()));
153              cpt++) {
154
155             // init the buffer Tuple
156
operandBuffer1[cpt] =
157                 new BasicVariableOperand(
158                     nestedQueryTree.getTupleStructure().getField(cpt + 1).getType()
159                 );
160             operandBuffer2[cpt] = new BasicVariableOperand(
161                 nestedQueryTree.getTupleStructure().getField(cpt + 1).getType()
162             );
163         }
164
165         tupleBuffer1 = new MemoryTuple(operandBuffer1);// Buffer Tuple
166
tupleBuffer2 = new MemoryTuple(operandBuffer2); // next Buffer Tuple
167
init();
168     }
169
170     public void close() throws MedorException {
171         super.close();
172         if (nestedTupleCollection != null)
173             nestedTupleCollection.close();
174     }
175
176     /**
177      * This method will change the SelectProject Filter in order to get the next
178      * GroupBy fields. The new values of the BasicFieldOperand are modified
179      * corresponding to the next field values of the next GroupBy Fields values.
180      */

181     private void changeGroupByFilter(Expression filter, Operand[] values)
182         throws ExpressionException {
183         Expression[] exp = expressionHeleper.toStack(filter);
184         exp[1] = values[0];
185         int rg = 4;
186         for (int i = 1; (i < values.length - 1); i++) {
187             exp[rg] = values[i];
188             rg = rg + 4;
189         }
190     }
191
192     /**
193      * This function will move the cursor of the sub TupleCollection at the row
194      * of the next GroupBy fileds and load it.
195      * In oure case, we iterate over all Tuples of the the sub TupleCollection
196      * and surch verify if the current Tuple exists or not in the visitedGroup
197      * collection.
198      * @param dest is the buffer Tuple
199      * @return true if there is next GroupBy and false if not
200      * @throws MedorException if subTupleCollection iteration error
201      */

202     private boolean prepareNextNotVisitedGroupIn(VariableOperand[] dest)
203         throws MedorException, ExpressionException {
204         Tuple tuple = null;
205         boolean stop = false;
206         while (!(stop) && nestedTupleCollection.next()) {
207             if (!(visitedGroup.contains(
208                 new Integer JavaDoc(nestedTupleCollection.getRow())
209             ))) {
210                 visitedGroup.add(new Integer JavaDoc(nestedTupleCollection.getRow()));
211                 stop = true;
212                 tuple = nestedTupleCollection.getTuple();
213             }
214         }
215         if (stop) {
216             // load the next GroupBy fields
217
nestedQueryTree.getTupleLoader().loadTuple(tuple, dest, null);
218             return true;
219         }
220         else
221             return false;
222     }
223
224     /**
225      * This method will get the two first Tuples if possible and tell
226      * if it is the last tuple or not;
227      */

228     private void init() throws MedorException {
229         cursor = 1; //Positionning at the first Tuple
230
nextEvaluatorIsFree = false;
231
232         try {
233             //We prepare the SelectProject Operation wich will represents the
234
//result of the Nested Field
235
nestedQueryTree.getTupleLoader().loadTuple(
236                 nestedTupleCollection.getTuple(), operandBuffer1, null);
237             visitedGroup.add(new Integer JavaDoc(1)); // The first GroupBy Tuple index
238
changeGroupByFilter(groupByFilter1, operandBuffer1);
239
240             query1 = new SelectProject(groupByFilter1, "");
241             //add the projected fields which are the nested fields
242
Field[] nestedFields1 =
243                 (nestedQueryTree.getNestedField()).getFields();
244             for (int i1 = 0; i1 < nestedFields1.length; i1++) {
245                 query1.addPropagatedField(nestedFields1[i1].getName(),
246                     nestedFields1[i1].getType(),
247                     new QueryTreeField[]{(QueryTreeField) nestedFields1[i1]});
248             }
249             nodeEvaluator1 =
250                 new UnaryIteratifNodeEvaluator(query1,
251                         subNodeEvaluator, evaluationMetaData);
252
253             // the nestedField TupleCollection Result
254
TupleCollection tctemp = nodeEvaluator1.fetchData(null);
255             BinaryEvaluatedTC itc = (BinaryEvaluatedTC) tctemp;
256
257             // we mark or the tuples already grouped
258
do {
259                 visitedGroup.add(new Integer JavaDoc(itc.getRightTCCursor()));
260             } while (tctemp.next());
261
262             tctemp.first();
263             // Must be changed for more object management
264
operandBuffer1[tcResultSize - 1].setValue(tctemp);
265
266             //Now we prepare the next group if possible
267
if (!(prepareNextNotVisitedGroupIn(operandBuffer2))) {
268                 isTheLast = true;
269             }
270             else {
271                 changeGroupByFilter(groupByFilter2, operandBuffer2);
272                 query2 = new SelectProject(groupByFilter1, "");
273                 //add the projected fields which are the nested fields
274
Field[] nestedFields2 =
275                     (nestedQueryTree.getNestedField()).getFields();
276                 for (int i2 = 0; i2 < nestedFields2.length; i2++) {
277                     query2.addPropagatedField(nestedFields2[i2].getName(),
278                         nestedFields2[i2].getType(),
279                         new QueryTreeField[]{(QueryTreeField) nestedFields2[i2]});
280                 }
281                 nodeEvaluator2 =
282                     new UnaryIteratifNodeEvaluator(query1,
283                             subNodeEvaluator, evaluationMetaData);
284                 TupleCollection tctemp1 = nodeEvaluator2.fetchData(null);
285                 BinaryEvaluatedTC itc1 = (BinaryEvaluatedTC) tctemp1;
286                 visitedGroup.add(new Integer JavaDoc(nestedTupleCollection.getRow()));
287
288                 do {
289                     visitedGroup.add(new Integer JavaDoc(itc1.getRightTCCursor()));
290                 } while (tctemp1.next());
291                 tctemp1.first();
292
293                 // Affecting the NestedField TupleCollection Result
294
operandBuffer2[tcResultSize - 1].setValue(tctemp1);
295             }
296         }
297         catch (MedorException e) {
298             throw e;
299         }
300         catch (ExpressionException e) {
301             throw new MedorException(e);
302         }
303     }
304
305     public TupleStructure getMetaData() throws MedorException {
306         return nestedQueryTree.getTupleStructure();
307     }
308
309     public boolean isLast() throws MedorException {
310         return isTheLast;
311     }
312
313     public boolean next() throws MedorException {
314         boolean deplacer = false;
315         if (isEmpty() || (cursor == -2))
316             deplacer = false;
317         else if (isLast()) {
318             // we have already visited the last Tuple
319
tupleBuffer1 = null;
320             tupleBuffer2 = null;
321             cursor = -2;
322             deplacer = false;
323         }
324         else {
325             deplacer = true;
326             // we are effectilly passed to the next Tuple.
327
// We verify if it is the last one
328
cursor++;
329             BinaryEvaluatedTC itc = null;
330             TupleCollection tctemp = null;
331             try {
332                 if (nextEvaluatorIsFree) {
333                     // This means that i can use the seconde evaluator
334
if (!(prepareNextNotVisitedGroupIn(operandBuffer2))) {
335                         isTheLast = true;
336                         nextEvaluatorIsFree = false;
337                     }
338                     else {
339                         changeGroupByFilter(groupByFilter2, operandBuffer2);
340                         tctemp = nodeEvaluator2.fetchData(null);
341                         itc = (BinaryEvaluatedTC) tctemp;
342                         visitedGroup.add(
343                             new Integer JavaDoc(nestedTupleCollection.getRow())
344                         );
345                         do {
346                             visitedGroup.add(new Integer JavaDoc(itc.getRightTCCursor()));
347                         } while (tctemp.next());
348                         tctemp.first();
349                         // The last Field is a TupleCollection
350
operandBuffer2[tcResultSize - 1].setValue(tctemp);
351                         nextEvaluatorIsFree = false;
352                     }
353                 }
354                 else {
355                     if (!(prepareNextNotVisitedGroupIn(operandBuffer1))) {
356                         isTheLast = true;
357                         nextEvaluatorIsFree = true;
358                     }
359                     else {
360                         changeGroupByFilter(groupByFilter1, operandBuffer1);
361                         tctemp = nodeEvaluator1.fetchData(null);
362                         itc = (BinaryEvaluatedTC) tctemp;
363                         visitedGroup.add(
364                             new Integer JavaDoc(nestedTupleCollection.getRow())
365                         );
366                         do {
367                             visitedGroup.add(new Integer JavaDoc(itc.getRightTCCursor()));
368                         } while (tctemp.next());
369                         tctemp.first();
370                         // The last field is a TupleCollection;
371
operandBuffer1[tcResultSize - 1].setValue(tctemp);
372                         nextEvaluatorIsFree = true;
373                     }
374                 }
375             }
376             catch (MedorException e) {
377                 throw e;
378             }
379             catch (ExpressionException e) {
380                 throw new MedorException(e);
381             }
382         }
383         return deplacer;
384     }
385
386     public void first() throws MedorException {
387         init();
388     }
389
390     public int getRow() throws MedorException {
391         return cursor;
392     }
393
394     public boolean isEmpty() throws MedorException {
395         return nestedTupleCollection.isEmpty();
396     }
397
398     public Tuple getTuple() throws MedorException {
399         if (!isEmpty() && (getRow() >= 1)) {
400             if (nextEvaluatorIsFree)
401                 return tupleBuffer2;
402             else
403                 return tupleBuffer1;
404         }
405         else
406             throw new MedorException(" No elements fetched in this TupleCollection "
407                 + getRow());
408     }
409
410     public synchronized Tuple getTuple(int numTuple) throws MedorException {
411         return getTuple();
412     }
413
414     public TupleCollection getGroupByTupleCollection() throws MedorException {
415         if ((!(isEmpty())) && (getRow() >= 1)) {
416             TupleCollection otemp =
417                 tupleBuffer1.getTupleCollection(tcResultSize);
418             TupleCollection tc = otemp;
419             return tc;
420         }
421         else
422             throw new MedorException(" No elements fetched in this TupleCollection "
423                 + getRow());
424     }
425
426     public boolean row(int numTuple) throws MedorException {
427         first();
428         int cpt = 1;
429         boolean go = true;
430         while ((cpt <= numTuple) && (cpt > 1) && go) {
431             if (!next()) go = false;
432         }
433         if (!go)
434             return false;
435         else {
436             cursor = numTuple;
437             return true;
438         }
439     }
440
441     public int getLeftTCCursor() throws MedorException {
442         return this.nestedTupleCollection.getRow();
443     }
444
445     public int getRightTCCursor() throws MedorException {
446         return -1;
447     }
448 }
449
Popular Tags