KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > query > jorm > lib > JormQueryTreeHelper


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 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 package org.objectweb.medor.query.jorm.lib;
22
23 import org.objectweb.medor.query.api.QueryTree;
24 import org.objectweb.medor.query.api.QueryNode;
25 import org.objectweb.medor.query.api.CalculatedField;
26 import org.objectweb.medor.query.api.FilteredQueryTree;
27 import org.objectweb.medor.query.api.QueryLeaf;
28 import org.objectweb.medor.query.api.PropagatedField;
29 import org.objectweb.medor.query.api.QueryTreeField;
30 import org.objectweb.medor.query.jorm.api.JormExtent;
31 import org.objectweb.medor.api.Field;
32 import org.objectweb.medor.api.MedorException;
33 import org.objectweb.medor.expression.api.Operator;
34 import org.objectweb.medor.expression.api.ParameterOperand;
35 import org.objectweb.medor.expression.api.Expression;
36 import org.objectweb.medor.type.lib.QType;
37 import org.objectweb.jorm.api.PClassMapping;
38 import org.objectweb.jorm.api.PException;
39 import org.objectweb.jorm.metainfo.api.Class;
40 import org.objectweb.jorm.metainfo.api.ClassMapping;
41 import org.objectweb.jorm.metainfo.api.PrimitiveElementMapping;
42 import org.objectweb.jorm.metainfo.api.PrimitiveElement;
43
44 import java.util.Collection JavaDoc;
45 import java.util.ArrayList JavaDoc;
46 import java.util.Collections JavaDoc;
47 import java.util.List JavaDoc;
48
49 /**
50  * This helper class provides methods to helper the Jorm/Medor users.
51  *
52  * @author S.Chassande-Barrioz
53  */

54 public class JormQueryTreeHelper {
55
56     /**
57      * Retrieves a Collection of JormExtent instance which are used in a given
58      * query tree. This permits to known all JormExtent used in a queries and to
59      * assign some parameters in order to replace a JormExtent by a specific
60      * query leaf during the optimization step. A JormExtent can be a
61      * ClassExtent or a GenClassExtent.
62      * @param qt is the querytree instance containing (or not) JormExtent nodes
63      * @return a collection of JormExtent instances
64      */

65     public static Collection JavaDoc getJormExtents(QueryTree qt) {
66         if (qt == null)
67             return null;
68         ArrayList JavaDoc res = new ArrayList JavaDoc();
69         ArrayList JavaDoc toTreat = new ArrayList JavaDoc();
70         toTreat.add(qt);
71         while (!toTreat.isEmpty()) {
72             QueryTree current = (QueryTree) toTreat.remove(0);
73             if (current instanceof JormExtent) {
74                 res.add(current);
75             } else if (current instanceof QueryNode) {
76                 QueryTree[] children = ((QueryNode) current).getChildren();
77                 for (int i = 0; i < children.length; i++) {
78                     toTreat.add(children[i]);
79                 }
80             }
81         }
82         return res;
83     }
84
85     /**
86      * Retrieves a Collection of ParameterOperand reuiqring in a given query
87      * tree which the type is NAMING_CONTEXT.
88      * It permits to know all parameters needed at evaluation
89      * time for the navigation over classes persitent with Jorm.
90      * @param qt is the query tree requiring PNamingContext parameters
91      * @return a collection of ParameterOperand instance
92      */

93     public static Collection JavaDoc getRequiredPNameManagers(QueryTree qt) {
94         if (qt == null)
95             return null;
96         ArrayList JavaDoc res = new ArrayList JavaDoc();
97         ArrayList JavaDoc toTreat = new ArrayList JavaDoc();
98         toTreat.add(qt);
99         while (!toTreat.isEmpty()) {
100             QueryTree current = (QueryTree) toTreat.remove(0);
101             Field[] fs = qt.getTupleStructure().getFields();
102             for (int i = 0; i < fs.length; i++) {
103                 if (fs[i] instanceof CalculatedField) {
104                     getRequiredPNameManagers(
105                         ((CalculatedField) fs[i]).getExpression(), res);
106                 }
107             }
108             if (current instanceof FilteredQueryTree) {
109                 getRequiredPNameManagers(
110                     ((FilteredQueryTree) current).getQueryFilter(), res);
111             }
112             if (current instanceof QueryNode) {
113                 QueryTree[] children = ((QueryNode) qt).getChildren();
114                 for (int i = 0; i < children.length; i++) {
115                     toTreat.add(children[i]);
116                 }
117             }
118         }
119         return res;
120     }
121
122     /**
123      * Adds the required ParameterOperand which the type is NAMING_CONTEXT.
124      * @param e is the expression requiring PNamingContext parameters
125      * @param c is a non null Collection inside which the required
126      * PNamingContext parameters must be added.
127      */

128     private static void getRequiredPNameManagers(Expression e, Collection JavaDoc c) {
129         if (e instanceof ParameterOperand) {
130             ParameterOperand po = (ParameterOperand) e;
131             if (po.getType().getTypeCode() == QType.TYPECODE_NAMING_CONTEXT) {
132                 c.add(po);
133             }
134         } else if (e instanceof Operator) {
135             Operator op = (Operator) e;
136             int nb = op.getOperandNumber();
137             for (int i = 0; i < nb; i++) {
138                 getRequiredPNameManagers(op.getExpression(i), c);
139             }
140         }
141     }
142
143     public static void addPrefetchFields(ClassExtent ext,
144             QueryTree oldroot,
145             QueryNode newroot) throws MedorException {
146         addPrefetchFields(ext, oldroot, newroot, true);
147     }
148     
149     public static void addPrefetchFields(ClassExtent ext,
150                                          QueryTree oldroot,
151                                          QueryNode newroot,
152                                          boolean withSubClasses) throws MedorException {
153         ClassMapping cm = ((Class JavaDoc) ext.getMetaObject())
154             .getClassProject(ext.getProjectName())
155             .getMapping(getMapperName(ext.getPMapper().getMapperName()))
156             .getClassMapping();
157         List JavaDoc pems = new ArrayList JavaDoc(cm.getAllPrimitiveElementMappings());
158         if (withSubClasses) {
159             Class JavaDoc cl = (Class JavaDoc) ext.getMetaObject();
160             //get the pcm of the super class
161
PClassMapping pcm = ext.getPMapper().lookup(cl.getFQName());
162             try {
163                 //get the sub PClassMappings
164
PClassMapping[] childrenPCMs = pcm.getSubPCMs();
165                 if (childrenPCMs != null) {
166                     //for each child
167
for(int j = 0; j < childrenPCMs.length; j++){
168                         //get the class mapping
169
Class JavaDoc subclass = ext.getPMapper().getMetaInfoManager().getClass(
170                                         childrenPCMs[j].getClassName());
171                         if (subclass == null) {
172                             throw new MedorException("Impossible to retrieve the jorm class " + childrenPCMs[j].getClassName());
173                         }
174                         ClassMapping subCM = subclass.getClassMapping(
175                                             ext.getProjectName(),getMapperName(ext.getPMapper().getMapperName()));
176                         if (subCM != null) {
177                             // add the pems to the list
178
pems.addAll(subCM.getPrimitiveElementMappings());
179                         }
180                     }
181                     //sort the list
182
Collections.sort(pems);
183                 }
184             } catch(PException e){
185                 throw new MedorException("Problem occurred while computing list of pems for sub classes.", e);
186             }
187         }
188         List JavaDoc fields = recurseAPF(ext, oldroot, pems);
189         if (((Class JavaDoc) ext.getMetaObject()).isPolymorphic()) {
190             Collections.sort(fields);
191         }
192         if (fields == null) {
193             throw new MedorException("Impossible to add prefetched field(s) on an extent which is not in the queryTree");
194         }
195         for(int i = 0; i<fields.size(); i++) {
196             QueryTreeField qtf = (QueryTreeField) fields.get(i);
197             newroot.addPropagatedField(
198                 qtf.getName(), qtf.getType(), new QueryTreeField[]{qtf});
199         }
200         //set the prefetch value to true for the ClassExtent ext
201
ext.setPrefetch(true);
202     }
203     
204     /**
205      *
206      */

207     public static void addPrefetchFields(ClassExtent ext,
208                                          QueryTree qt) throws MedorException {
209         ClassMapping cm = ((Class JavaDoc) ext.getMetaObject())
210             .getClassProject(ext.getProjectName())
211             .getMapping(getMapperName(ext.getPMapper().getMapperName()))
212             .getClassMapping();
213         List JavaDoc fields = new ArrayList JavaDoc(cm.getAllPrimitiveElementMappings());
214         recurseAPF(ext, qt, fields);
215         //set the prefetch value to true for the ClassExtent ext
216
ext.setPrefetch(true);
217     }
218
219     private static List JavaDoc recurseAPF(ClassExtent ext,
220                                    QueryTree qt,
221                                    List JavaDoc pems) throws MedorException {
222         if (qt == ext) {
223             //found the extent
224
//check that the extent has the required fields
225
ArrayList JavaDoc result = new ArrayList JavaDoc(pems.size());
226             for (int i = 0; i < pems.size(); i++) {
227                 PrimitiveElement pe = (PrimitiveElement) ((PrimitiveElementMapping) pems.get(i)).getLinkedMO();
228                 String JavaDoc fn = pe.getName();
229                 Field f = null;
230                 if (ext.contains(ext.getFieldName(ext.getName(), fn))) {
231                     f = ext.getField(ext.getFieldName(ext.getName(), fn));
232                 } else {
233                     f = ext.addField(pe);
234                 }
235                 result.add(f);
236             }
237             return result;
238         } else if (qt instanceof QueryLeaf) {
239             return null;
240         }
241         QueryTree[] children = ((QueryNode) qt).getChildren();
242         int i = 0;
243         List JavaDoc childfs = null;
244         while (i < children.length
245             && ((childfs = recurseAPF(ext, children[i], pems)) == null)) {
246             i++;
247         }
248         if (childfs == null) {
249             //ClassExtent is not in the current QueryTree
250
return null;
251         }
252         //ClassExtent found and childfs contains the Fields to be propagated
253
Field[] qtfs = qt.getTupleStructure().getFields();
254         ArrayList JavaDoc result = new ArrayList JavaDoc(pems.size());
255         for (int j = 0; j < childfs.size(); j++) {
256             QueryTreeField previous = (QueryTreeField) childfs.get(j);
257             for (i = 0; i < qtfs.length; i++) {
258                 if ((qtfs[i] instanceof PropagatedField)
259                     && ((PropagatedField) qtfs[i]).getPreviousFields()[0] == previous) {
260                     result.add(qtfs[i]);
261                     break;
262                 }
263             }
264             if (i == qtfs.length) {
265                 //field not found
266
try {
267                     result.add(
268                         ((QueryNode) qt).addPropagatedField(previous.getName(),
269                             previous.getType(),
270                             new QueryTreeField[]{previous}
271                         )
272                     );
273                 } catch (MedorException e) {
274                     //bad luck: name collision
275
}
276             }
277         }
278         return result;
279     }
280
281     private static String JavaDoc getMapperName(String JavaDoc mn) {
282         if (mn == null) {
283             return null;
284         }
285         int idx = mn.indexOf('.');
286         if (idx == -1) {
287             return mn;
288         } else {
289             return mn.substring(0, idx);
290         }
291     }
292 }
293
Popular Tags