KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > optim > jorm > JormLeafRewriteRule


1 /**
2  * MEDOR: Middleware Enabling Distributed Object Requests
3  *
4  * Copyright (C) 2001-2003 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, S. Chassande-Barrioz, A. Lefebvre
22  */

23
24 package org.objectweb.medor.optim.jorm;
25
26 import org.objectweb.medor.api.Field;
27 import org.objectweb.medor.api.MedorException;
28 import org.objectweb.medor.filter.api.FieldOperand;
29 import org.objectweb.medor.expression.api.Operator;
30 import org.objectweb.medor.expression.api.Expression;
31 import org.objectweb.medor.optim.api.LeafRewriteRule;
32 import org.objectweb.medor.optim.api.LeafRewriter;
33 import org.objectweb.medor.optim.lib.BasicRule;
34 import org.objectweb.medor.query.api.CalculatedField;
35 import org.objectweb.medor.query.api.FilteredQueryTree;
36 import org.objectweb.medor.query.api.NestedField;
37 import org.objectweb.medor.query.api.PropagatedField;
38 import org.objectweb.medor.query.api.QueryLeaf;
39 import org.objectweb.medor.query.api.QueryNode;
40 import org.objectweb.medor.query.api.QueryTree;
41 import org.objectweb.medor.query.api.QueryTreeField;
42 import org.objectweb.medor.query.jorm.lib.ClassExtent;
43 import org.objectweb.util.monolog.api.BasicLevel;
44 import org.objectweb.util.monolog.api.Logger;
45 import org.objectweb.util.monolog.api.LoggerFactory;
46
47 import java.util.ArrayList JavaDoc;
48 import java.util.Collection JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.Iterator JavaDoc;
51 import java.util.Map JavaDoc;
52 /**
53  * This class represents the rule to transform QueryLeaves
54  * into the corresponding QueryLeaf on the data store (for example into an
55  * RdbQueryLeaf).
56  */

57 public class JormLeafRewriteRule extends BasicRule implements LeafRewriteRule {
58
59     ArrayList JavaDoc leafRewriters = null;
60
61     public JormLeafRewriteRule() {
62         super("JormLeafRewriteRule");
63         leafRewriters = new ArrayList JavaDoc();
64     }
65
66     public JormLeafRewriteRule(LeafRewriter lr) {
67         this();
68         leafRewriters.add(lr);
69     }
70
71     // IMPLEMENTATION OF THE LeafRewriteRule INTERFACE //
72
//-------------------------------------------------//
73

74     public void addLeafRewriter(LeafRewriter lr) {
75         leafRewriters.add(lr);
76     }
77     public void removeLeafRewriter(LeafRewriter lr) {
78         leafRewriters.add(lr);
79     }
80     public Collection JavaDoc getLeafRewriters() {
81         return leafRewriters;
82     }
83     public LeafRewriter getLeafRewriter(QueryLeaf ql) {
84         for (Iterator JavaDoc it=leafRewriters.iterator(); it.hasNext();){
85             LeafRewriter lr = (LeafRewriter) it.next();
86             if (lr.canRewrite(ql))
87                 return lr;
88         }
89         if (debug)
90             log.log(BasicLevel.DEBUG, "No LeafRewriter found (among "
91                 + leafRewriters.size() + ") for this QueryLeaf: " + ql);
92         return null;
93     }
94
95     // IMPLEMENTATION OF THE Loggable INTERFACE //
96
//------------------------------------------//
97

98     public void setLoggerFactory(LoggerFactory loggerFactory) {
99     }
100
101     public LoggerFactory getLoggerFactory() {
102         return null;
103     }
104
105     public void setLogger(Logger logger) {
106         this.log = logger;
107     }
108
109     public Logger getLogger() {
110         return log;
111     }
112
113     // IMPLEMENTATION OF THE RewriteRule INTERFACE //
114
//---------------------------------------------//
115

116     /**
117      */

118     public QueryTree rewrite(QueryTree qt, QueryNode _parent)
119             throws MedorException {
120         debug = log != null && log.isLoggable(BasicLevel.DEBUG);
121
122         if (debug)
123             log.log(BasicLevel.DEBUG, "qt=" + qt);
124         if (qt==null) return null;
125         ClassExtent extent = null;
126         if (qt instanceof ClassExtent) {
127             //Just transform it, there is no user
128
extent = (ClassExtent) qt;
129             return getLeafRewriter(extent).rewrite(extent);
130         }
131         for(Iterator JavaDoc it=getLeafUsers(qt).entrySet().iterator(); it.hasNext();) {
132             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
133             extent = (ClassExtent) entry.getKey();
134             ArrayList JavaDoc users = (ArrayList JavaDoc) entry.getValue();
135
136             //Transform the Jorm extent into a specific QueryTree
137
QueryTree neo = getLeafRewriter(extent).rewrite(extent);
138
139             //Change the reference of the user
140
for(Iterator JavaDoc it2 = users.iterator(); it2.hasNext();) {
141                 Object JavaDoc o = it2.next();
142                 if (o instanceof FieldOperand) {
143                     FieldOperand fo = (FieldOperand) o;
144                     fo.setField(
145                         neo.getTupleStructure().getField(
146                             fo.getField().getName()));
147                 }
148                 else if (o instanceof PropagatedField) {
149                     PropagatedField pf = (PropagatedField) o;
150                     Field[] fs = pf.getPreviousFields();
151                     QueryTreeField[] neos = new QueryTreeField[fs.length];
152                     boolean mustReplace = false;
153                     for(int i=0; i<fs.length; i++) {
154                         if (fs[i] instanceof QueryTreeField
155                             && ((QueryTreeField)fs[i]).getQueryTree()==extent) {
156                             mustReplace = true;
157                             neos[i] = (QueryTreeField)
158                                 neo.getTupleStructure().getField(fs[i].getName());
159                         }
160                         else {
161                             neos[i] = (QueryTreeField) fs[i];
162                         }
163
164                     }
165                     if (mustReplace)
166                         ((QueryNode) pf.getQueryTree())
167                             .updatePropagatedField(pf.getName(), neos);
168                 }
169                 else if (o instanceof NestedField) {
170                     NestedField nf = (NestedField) o;
171                     Field[] fs = nf.getFields();
172                     QueryTreeField[] neos = new QueryTreeField[fs.length];
173                     boolean mustReplace = false;
174                     for(int i=0; i<fs.length; i++) {
175                         if (fs[i] instanceof QueryTreeField
176                             && ((QueryTreeField)fs[i]).getQueryTree()==extent) {
177                             mustReplace = true;
178                             neos[i] = (QueryTreeField)
179                                 neo.getTupleStructure().getField(fs[i].getName());
180                         }
181                         else {
182                             neos[i] = (QueryTreeField) fs[i];
183                         }
184                     }
185                     if (mustReplace)
186                         ((QueryNode) nf.getQueryTree())
187                             .updatePropagatedField(nf.getName(), neos);
188                 }
189             }
190         }
191         return qt;
192     }
193
194     // OTHER METHODS //
195
//---------------//
196

197     /**
198      *
199      */

200     protected Map JavaDoc getLeafUsers(QueryTree qt) throws MedorException {
201         Map JavaDoc res = new HashMap JavaDoc();
202         getLeafUsers(qt, res, new ArrayList JavaDoc());
203         return res;
204     }
205
206     /**
207      * It fetches the QueryTree nodes which are 'parents' of QueryLeaf nodes.
208      * @param qt is the queryTree to analyze.
209      * @param m is the current result of the recusrive evaluation.
210      * key = a queryTree
211      * Value = the users of the querytree key :
212      * ArrayList( FieldOperand | PropagatedField | NestedField )
213      * @param al is the list of the visited queryTree. (It does not contain the
214      * 'qt' parameter)
215      */

216     protected void getLeafUsers(QueryTree qt, Map JavaDoc m, ArrayList JavaDoc al) throws MedorException {
217         al.add(qt);
218         //Look in the filter
219
if (qt instanceof FilteredQueryTree) {
220             getLeafUsers(
221             ((FilteredQueryTree) qt).getQueryFilter(), m, al);
222         }
223
224         //look in projected field
225
if (!(qt instanceof QueryLeaf)) {
226             Field[] fields = qt.getTupleStructure().getFields();
227             for(int i=0; i<fields.length; i++) {
228                 if (fields[i] instanceof PropagatedField) {
229                     getLeafUsers(
230                     ((PropagatedField) fields[i]).getPreviousFields(),
231                     fields[i],
232                     m, al);
233                 }
234                 else if (fields[i] instanceof CalculatedField) {
235                     getLeafUsers(
236                     ((CalculatedField) fields[i]).getExpression(), m, al);
237                 }
238                 else if (fields[i] instanceof NestedField) {
239                     getLeafUsers(
240                     ((NestedField)fields[i]).getFields(),
241                     fields[i],
242                     m, al);
243                 }
244             }
245         }
246     }
247
248     /**
249      * It fetches the QueryTree nodes which are 'parents' of QueryLeaf nodes.
250      * @param e is the expression to analyze.
251      * @param m is the current result of the recusrive evaluation.
252      * key = a queryTree
253      * Value = the users of the querytree key :
254      * ArrayList( FieldOperand | PropagatedField | NestedField )
255      * @param al is the list of the visited queryTree.
256      */

257     private void getLeafUsers(Expression e, Map JavaDoc m, ArrayList JavaDoc al) throws MedorException {
258         if (e instanceof Operator) {
259             for (int i = 0; i< ((Operator) e).getOperandNumber(); i++)
260                 getLeafUsers(((Operator)e).getExpression(i), m, al);
261         }
262         else if (e instanceof FieldOperand) {
263             FieldOperand fo = (FieldOperand) e;
264             QueryTree qt = ((QueryTreeField) fo.getField()).getQueryTree();
265             if (qt instanceof ClassExtent) {
266                 ArrayList JavaDoc users = (ArrayList JavaDoc) m.get(qt);
267                 if (users==null) {
268                     users = new ArrayList JavaDoc();
269                     m.put(qt, users);
270                 }
271                 users.add(fo);
272             }
273             else if (!al.contains(qt)) {
274                 getLeafUsers(qt, m, al);
275             }
276         }
277     }
278
279     /**
280      * It fetches the QueryTree nodes which are 'parents' of QueryLeaf nodes.
281      * @param usedFields are the ancestor of a potentiel users. If one of these
282      * fields is attached to a QueryLeaf the second parameter 'user' is
283      * registered as user in the map.
284      * @param user is the field which is based on the usedFields parameter. In
285      * most case this parameter is a PropagatedField or a NestedField.
286      * @param m is the current result of the recusrive evaluation.
287      * key = a queryTree
288      * Value = the users of the querytree key :
289      * ArrayList( FieldOperand | PropagatedField | NestedField )
290      * @param al is the list of the visited queryTree.
291      */

292     private void getLeafUsers(Field[] usedFields, Object JavaDoc user, Map JavaDoc m, ArrayList JavaDoc al) throws MedorException {
293         for(int i=0; i<usedFields.length; i++) {
294             if (usedFields[i] instanceof QueryTreeField) {
295                 QueryTree qt = ((QueryTreeField)usedFields[i]).getQueryTree();
296                 if (qt instanceof ClassExtent) {
297                     ArrayList JavaDoc users = (ArrayList JavaDoc) m.get(qt);
298                     if (users==null) {
299                         users = new ArrayList JavaDoc();
300                         m.put(qt, users);
301                     }
302                     users.add(user);
303                 } else if (!al.contains(qt)) {
304                     getLeafUsers(qt, m, al);
305                 }
306
307             }
308         }
309     }
310 }
311
Popular Tags