KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jorm > mapper > rdb > lib > RdbExtentMappingInfos


1 /**
2  * Speedo: an implementation of JDO compliant personality on top of JORM generic
3  * I/O sub-system.
4  * Copyright (C) 2001-2004 France Telecom R&D
5  *
6  * This library 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 of the License, or (at your option) any later version.
10  *
11  * This library 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 library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  *
21  *
22  * Contact: speedo@objectweb.org
23  *
24  */

25
26 package org.objectweb.jorm.mapper.rdb.lib;
27
28 import java.util.ArrayList JavaDoc;
29 import java.util.Arrays JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.Comparator JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.Iterator JavaDoc;
34
35 import org.objectweb.jorm.api.PClassMapping;
36 import org.objectweb.jorm.mapper.rdb.adapter.api.RdbAdapter;
37 import org.objectweb.jorm.mapper.rdb.metainfo.RdbJoin;
38 import org.objectweb.jorm.mapper.rdb.metainfo.RdbTable;
39 import org.objectweb.jorm.metainfo.api.Class;
40 import org.objectweb.util.monolog.api.Logger;
41
42 /**
43  * This class is used to construct extent mapping information when calculating
44  * extents (see getNonFinalClassExtent) and that will then be used to
45  * generate the appropriate union of select/from/where clauses
46  */

47 public class RdbExtentMappingInfos {
48
49     public static final String JavaDoc NULL_COLUMN = "NULL";
50     
51     public static Logger logger;
52     public static boolean debug = false;
53     
54     // class to which the expression is attached
55
Class JavaDoc clazz;
56
57     // a table of columns for the projections
58
private RdbColumnInfo[] columns;
59         
60     // joins required to get the desired columns
61
HashSet JavaDoc joins = new HashSet JavaDoc(); // {RdbJoin}
62
// tables required to get the desired columns
63
RdbTable mainTable;
64
65     // the filter set will contain the name of classes from which filtering
66
// expressions must be retrieved so as to be added to the where clause.
67
HashSet JavaDoc filters = new HashSet JavaDoc(); // {String}
68
// if addfilters is true, then filters of classes mapped on the same
69
// tables (extended/added inheritance) must be added
70
boolean addFilters = false;
71     boolean hasUnmappedFields = false;
72     private boolean emptyEMI = true;
73         
74     // we can give a name to EMIs
75
private String JavaDoc name;
76         
77     RdbExtentMappingInfos(Class JavaDoc clazz, String JavaDoc name, int nbColumns) {
78         this.clazz = clazz;
79         this.name = name;
80         this.columns = new RdbColumnInfo[nbColumns];
81         //debug = logger != null && logger.isLoggable(BasicLevel.DEBUG);
82
}
83
84     /**
85      * @return Returns the name.
86      */

87     public String JavaDoc getName() {
88         return name;
89     }
90     
91     /**
92      * @param name The name to set.
93      */

94     public void setName(String JavaDoc name) {
95         this.name = name;
96     }
97
98     // getters required by Velocity
99
public HashSet JavaDoc getFilters() {
100         return filters;
101     }
102
103     public RdbTable getMainTable() {
104         return mainTable;
105     }
106
107     
108     public void setMainTable(RdbTable mainTable) {
109         this.mainTable = mainTable;
110     }
111     
112     public HashSet JavaDoc getJoins() {
113         return joins;
114     }
115
116     public void addJoin(RdbJoin join){
117         joins.add(join);
118     }
119     
120     public boolean isEmpty() {
121         return emptyEMI;
122     }
123
124     public void addProjection(String JavaDoc tableName, String JavaDoc columnName,
125                                String JavaDoc aliasName, String JavaDoc className, int position) {
126         if (columns[position] != null && columns[position].getName() != null && !columns[position].getName().equals(NULL_COLUMN)) {
127             if (debug) {
128                 String JavaDoc newExpr = tableName + "." + columnName;
129                 if (!columns[position].getName().equals(newExpr)) {
130                     throw new InternalError JavaDoc("expr in select definition (" + newExpr
131                                 + ") not equal to old one (" + columns[position].getName() + ")");
132                 }
133                 if (!columns[position].getAlias().equals(aliasName)) {
134                     throw new InternalError JavaDoc("alias in select definition (" + aliasName
135                             + ") not equal to old one (" + columns[position].getAlias() + ")");
136                     }
137             }
138         } else {
139             emptyEMI = false;
140             //do not add the . if the columnName is NULL, because the tableName is an empty string
141
// and we want to have something like that: select t.a, t.b, NULL, t.d from t
142
columns[position] = new RdbColumnInfo(columnName.equals(NULL_COLUMN)?columnName:tableName + "." + columnName,
143                                 aliasName,
144                                 className);
145         }
146     }
147        
148     /**
149      * get a select parameter to give to the getQuery method of adapter
150      * this method is called in RdbExtentDefinition.vm when generating the
151      * extent definition
152      * @param adapterName the name of the adapter in the generated code
153      * @return a string to include as the first parameter of the call to
154      * getQuery in the generated code
155      */

156     public String JavaDoc getSelectParameter(String JavaDoc adapterName) {
157         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
158         // select parameter
159
for (int pos = 0; pos < columns.length; pos++) {
160            sb.append("\"" + columns[pos].getName() + "\" + " +
161                    adapterName +".getColumnAliasExpr(\"" + columns[pos].getAlias() + "\")");
162            if (pos < columns.length - 1) {
163                sb.append(" + \",\" + ");
164             }
165         }
166         return sb.toString();
167     }
168
169     /**
170      * Returns a String of type "x1 as y1, x2 as y2, x3 as y3" for the prefetch case.
171      * @param adapter
172      * @return
173      */

174     public String JavaDoc getSelectPrefetch(RdbAdapter adapter, Class JavaDoc cl) {
175         RdbColumnInfo[] columnsClone = new RdbColumnInfo[columns.length];
176         for(int i = 0; i < columns.length; i++){
177             columnsClone[i] = columns[i];
178         }
179         //sort the table
180
if (cl.isPolymorphic()) {
181             //Sort by PE name
182
Arrays.sort(columnsClone);
183         } else {
184             //sort by the PEM
185
Arrays.sort(columnsClone, new Comparator JavaDoc() {
186              public int compare(Object JavaDoc o1, Object JavaDoc o2) {
187                  return ((RdbColumnInfo) o1).getName().compareTo(
188                          ((RdbColumnInfo) o2).getName());
189              }
190             });
191         }
192         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
193         // select parameter
194
for (int pos = 0; pos < columnsClone.length; pos++) {
195             sb.append(columnsClone[pos].getName() + " " +
196                     adapter.getColumnAliasExpr(columnsClone[pos].getAlias()));
197             if (pos < columnsClone.length - 1) {
198                 sb.append(" , ");
199             }
200         }
201         return sb.toString();
202     }
203         
204     /**
205      * Returns a String of type "x1 as y1, x2 as y2" for the pk only case,
206      * x1 and x2 composing the primary key.
207      * @param adapter
208      * @param primaryKey the list of columns belonging to the primaryKey
209      * @return
210      */

211     public String JavaDoc getSelectPKOnly(RdbAdapter adapter, String JavaDoc primaryKey) {
212         RdbColumnInfo[] columnsClone = new RdbColumnInfo[columns.length];
213         for(int i = 0; i < columns.length; i++){
214             columnsClone[i] = columns[i];
215         }
216         //sort the table
217
Arrays.sort(columnsClone);
218         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
219         // select parameter
220
for (int pos = 0; pos < columnsClone.length; pos++) {
221             if(primaryKey.indexOf(columnsClone[pos].getName()) != -1){
222                 sb.append(columnsClone[pos].getName() + " " +
223                         adapter.getColumnAliasExpr(columnsClone[pos].getAlias()));
224                 if (pos < columnsClone.length - 1) {
225                     sb.append(" , ");
226                 }
227             }
228         }
229         return sb.toString();
230     }
231         
232     /**
233      * Returns a String of type "x1 as y1, x2 as y2, x3 as y3" for the pk and fields case,
234      * x1 and x2 composing the primary key, x3 being a field that belongs to the class or one of its super classes.
235      */

236     public String JavaDoc getSelectPKAndFields(RdbAdapter adapter, Class JavaDoc cl) {
237         RdbColumnInfo[] columnsClone = new RdbColumnInfo[columns.length];
238         for(int i = 0; i < columns.length; i++){
239             columnsClone[i] = columns[i];
240         }
241         //sort the table
242
if (cl.isPolymorphic()) {
243             Arrays.sort(columnsClone);
244         } else {
245             Arrays.sort(columnsClone, new Comparator JavaDoc() {
246              public int compare(Object JavaDoc o1, Object JavaDoc o2) {
247                  return ((RdbColumnInfo) o1).getName().compareTo(
248                          ((RdbColumnInfo) o2).getName());
249              }
250             });
251         }
252         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
253         Collection JavaDoc superClasses = new ArrayList JavaDoc();
254         //add the current class name to the list of super classes,
255
//not to forget all the fields belonging to this class
256
superClasses.add(cl.getFQName());
257         //get all the ancestors of the class cl
258
Iterator JavaDoc it = cl.getAncestors().iterator();
259         //and add the names of these classes to the superClasses list
260
while(it.hasNext()){
261             Class JavaDoc c = (Class JavaDoc) it.next();
262             superClasses.add(c.getFQName());
263         }
264         for (int pos = 0; pos < columnsClone.length; pos++) {
265             //add the field to the list only if it belongs to one of the super classes
266
//including the class cl
267
if (superClasses.contains(columnsClone[pos].getClassName())) {
268                 sb.append(columnsClone[pos].getName() + " " +
269                         adapter.getColumnAliasExpr(columnsClone[pos].getAlias()));
270                 if (pos < columnsClone.length - 1) {
271                     sb.append(" , ");
272                 }
273             }
274         }
275         return sb.toString();
276     }
277         
278     public String JavaDoc getWhereParameter(PClassMapping pcm) {
279         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
280         if(pcm != null && pcm instanceof RdbPPolymorphicClass){
281             if (this.hasJoins()) {
282                 sb.append(" AND (");
283                 ((RdbPPolymorphicClass)pcm).appendExtentFilters(this.name, sb);
284                 sb.append(")");
285             } else {
286                 sb.append(" WHERE ");
287                 ((RdbPPolymorphicClass)pcm).appendExtentFilters(this.name, sb);
288             }
289          }
290         return sb.toString();
291     }
292         
293     public String JavaDoc getAliasName(int position){
294         if (position >= 0 && position < columns.length && columns[position] != null)
295             return columns[position].getAlias();
296         else
297             return null;
298     }
299         
300     /**
301      *
302      * @param prefetch
303      * @param primaryKey : the String representing the fields composing the primary key
304      * @param cl : if prefetch is true, this parameter is not used and the getColumnAliasesPrefetch method is called
305      * else
306      * if cl is null the getColumnAliasesPKOnly method is called
307      * else the getColumnAliasesPKAndFields method is called
308      * @return
309      */

310     public Collection JavaDoc getColumnAliases(boolean prefetch, String JavaDoc primaryKey, Class JavaDoc cl){
311         if (prefetch) {
312             return getColumnAliasesPrefetch();
313         } else {
314             if(cl == null)
315                 return getColumnAliasesPKOnly(primaryKey);
316             else
317                 return getColumnAliasesPKAndFields(cl);
318         }
319     }
320         
321     private Collection JavaDoc getColumnAliasesPrefetch(){
322         RdbColumnInfo[] columnsClone = new RdbColumnInfo[columns.length];
323         for(int i = 0; i < columns.length; i++){
324             columnsClone[i] = columns[i];
325         }
326         //sort the table
327
Arrays.sort(columnsClone);
328         Collection JavaDoc c = new ArrayList JavaDoc();
329         for(int i=0; i< columnsClone.length; i++)
330             c.add(columnsClone[i].getAlias());
331         return c;
332     }
333         
334     private Collection JavaDoc getColumnAliasesPKOnly(String JavaDoc primaryKey){
335         RdbColumnInfo[] columnsClone = new RdbColumnInfo[columns.length];
336         for(int i = 0; i < columns.length; i++){
337             columnsClone[i] = columns[i];
338         }
339         //sort the table
340
Arrays.sort(columnsClone);
341         Collection JavaDoc c = new ArrayList JavaDoc();
342         for(int i=0; i< columnsClone.length; i++)
343             if(primaryKey.indexOf(columnsClone[i].getName()) != -1)
344                 c.add(columnsClone[i].getAlias());
345         return c;
346     }
347         
348     public Collection JavaDoc getColumnAliasesPKAndFields(Class JavaDoc cl){
349         RdbColumnInfo[] columnsClone = new RdbColumnInfo[columns.length];
350         for(int i = 0; i < columns.length; i++){
351             columnsClone[i] = columns[i];
352         }
353         //sort the table
354
Arrays.sort(columnsClone);
355         Collection JavaDoc c = new ArrayList JavaDoc();
356         Collection JavaDoc superClasses = new ArrayList JavaDoc();
357         //add the current class name to the list of super classes,
358
//not to forget all the fields belonging to this class
359
superClasses.add(cl.getFQName());
360         //get all the ancestors of the class cl
361
Iterator JavaDoc it = cl.getAncestors().iterator();
362         //and add the names of these classes to the superClasses list
363
while(it.hasNext()){
364             Class JavaDoc currentClass = (Class JavaDoc) it.next();
365             superClasses.add(currentClass.getFQName());
366         }
367         for (int pos = 0; pos < columnsClone.length; pos++) {
368             //add the field to the list only if it belongs to one of the super classes
369
//including the class cl
370
if (superClasses.contains(columnsClone[pos].getClassName())) {
371                 c.add(columnsClone[pos].getAlias());
372             }
373         }
374         return c;
375     }
376         
377     public Collection JavaDoc getColumnClasses(){
378         RdbColumnInfo[] columnsClone = new RdbColumnInfo[columns.length];
379         for(int i = 0; i < columns.length; i++){
380             columnsClone[i] = columns[i];
381         }
382         //sort the table
383
Arrays.sort(columnsClone);
384         ArrayList JavaDoc columnClasses = new ArrayList JavaDoc();
385         for(int i = 0; i < columnsClone.length; i++){
386             columnClasses.add(columnsClone[i].getClassName());
387         }
388         return columnClasses;
389     }
390         
391     public boolean mappingDone(int pos) {
392         return (columns[pos] != null && columns[pos].getName() != null);
393     }
394         
395     public boolean mappingNull(int pos) {
396         return (columns[pos] == null || columns[pos].getName().equals(NULL_COLUMN));
397     }
398         
399     public boolean hasJoins() {
400         return (!joins.isEmpty());
401     }
402 }
Popular Tags