KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jorm > mapper > rdb > generator > RdbGenInfos


1 /**
2  * JORM: an implementation of a generic mapping system for persistent Java
3  * objects. Two mapping are supported: to RDBMS and to binary files.
4  * Copyright (C) 2001-2004 France Telecom R&D - INRIA
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  * Contact: jorm@objectweb.org
21  *
22  */

23
24 package org.objectweb.jorm.mapper.rdb.generator;
25
26 import org.objectweb.jorm.api.PException;
27 import org.objectweb.jorm.generator.lib.CommonHelper;
28 import org.objectweb.jorm.mapper.rdb.metainfo.RdbClassMapping;
29 import org.objectweb.jorm.mapper.rdb.metainfo.RdbFilter;
30 import org.objectweb.jorm.mapper.rdb.metainfo.RdbMapping;
31 import org.objectweb.jorm.mapper.rdb.metainfo.RdbPrimitiveElementMapping;
32 import org.objectweb.jorm.metainfo.api.Class;
33 import org.objectweb.jorm.metainfo.api.ClassMapping;
34 import org.objectweb.jorm.metainfo.api.ParentClassMapping;
35 import org.objectweb.jorm.metainfo.api.PrimitiveElement;
36 import org.objectweb.jorm.naming.api.PNameGetter;
37 import org.objectweb.medor.expression.api.Expression;
38 import org.objectweb.medor.expression.api.ExpressionException;
39 import org.objectweb.medor.expression.api.ParameterOperand;
40 import org.objectweb.medor.expression.api.VariableOperand;
41 import org.objectweb.medor.expression.converter.rdb.Expression2WhereClauseImpl;
42 import org.objectweb.medor.expression.lib.ExpressionPrinter;
43 import org.objectweb.util.monolog.api.BasicLevel;
44 import org.objectweb.util.monolog.api.Logger;
45
46 import java.util.ArrayList JavaDoc;
47 import java.util.Collection JavaDoc;
48 import java.util.Collections JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.Iterator JavaDoc;
51 import java.util.List JavaDoc;
52 import java.util.Map JavaDoc;
53
54 /**
55  * This is the root class that contains all the required information for
56  * generating Java code specific to the RDB mapping. It allows the support of
57  * all elaborated mapping rules.
58  * @author P. Dechamboux, O. Lobry
59  */

60 public class RdbGenInfos {
61     private static final String JavaDoc COLUMN = ", ";
62     /**
63      * The set of names all tables used to store the generated class. It also contains
64      * the reference table that is supposed to hold the object identifier (see
65      * mainTable). Indexed by their names. < String -> RdbGenTable >
66      */

67     public Map JavaDoc tables = new HashMap JavaDoc();
68     /**
69      * The reference table used in this mapping. It entirely stores the
70      * identifier of the related JORM object, as specified by variable genId.
71      */

72     public RdbGenTable mainTable = null;
73     /**
74      * The set of all columns used to store the generated class. It defines the
75      * order with which the columns will be used within all kinds of queries.
76      * This set is the union of all columns specified with each table involved
77      * in this mapping.
78      */

79     public List JavaDoc readableColumns = new ArrayList JavaDoc();
80     /**
81      * The structure of the identifier of the related JORM object.
82      */

83     public RdbGenRef genId = null;
84     /**
85      * The associated Mapping
86      */

87     public RdbMapping mapping = null;
88     /**
89      * The set of references defined by the generated class.
90      * There is one RdbGenRef object registered for each reference field,
91      * in association with its field name into this map.
92      */

93     public Map JavaDoc genRefs = new HashMap JavaDoc();
94
95
96     String JavaDoc filterExpr = null;
97
98     public Logger logger;
99     public boolean debug = false;
100
101     public static CommonHelper commonHelper = new CommonHelper();
102
103
104     public RdbGenInfos() {
105     }
106
107     public Map JavaDoc getTables() {
108         return tables;
109     }
110
111     public RdbGenTable getReferenceTable() {
112         return mainTable;
113     }
114
115     public List JavaDoc getReadableColumns() {
116         return readableColumns;
117     }
118
119     public RdbGenRef getGenId() {
120         return genId;
121     }
122
123     public Map JavaDoc getGenRefs() {
124         return genRefs;
125     }
126
127     /**
128      * Computes the list of references (i.e., their definition) stored into this
129      * particular table.
130      * @param rgt The table for which to find the reference definitions.
131      * @return The computed list of definitions.
132      */

133     public List JavaDoc getTableCompositeGenRefs(RdbGenTable rgt) {
134         return getTableCompositeGenRefs(rgt, null);
135     }
136
137     public List JavaDoc getTableCompositeGenRefs(RdbGenTable rgt, RdbGenJoin rgj) {
138         ArrayList JavaDoc res = new ArrayList JavaDoc();
139         Iterator JavaDoc it = genRefs.values().iterator();
140         while (it.hasNext()) {
141             RdbGenRef rgr = (RdbGenRef) it.next();
142             if (rgr.refColumn == null && rgr.join == rgj && !res.contains(rgr)) {
143                 res.add(rgr);
144             }
145         }
146         return res;
147     }
148
149     /**
150      * Gets the position (within [1..n] of the given column into the overall
151      * list defined into this RdbGenInfos.
152      * @param irgc The column for which to search the position.
153      * @return Its position into the genColumns list. -1 if not found (BUG:
154      * should never appear).
155      */

156     public int getColumnPosition(RdbGenColumn irgc) {
157         return getColumnPosition(irgc, null);
158     }
159     
160     public int getColumnPosition(RdbGenColumn irgc, RdbGenJoin rgj) {
161         int idx = 1;
162         if (debug) {
163             logger.log(BasicLevel.DEBUG, "getColumnPosition(" + irgc.columnName + ", rgj=" + rgj +")");
164         }
165         for (int i = 0; i < readableColumns.size(); i++) {
166             RdbGenColumn rgc = (RdbGenColumn) readableColumns.get(i);
167             if (debug) {
168                 logger.log(BasicLevel.DEBUG, "\tcurrent column: " + rgc.columnName);
169                 logger.log(BasicLevel.DEBUG, "\tpirgc=" + irgc.toString() + " - current=" + rgc.toString());
170             }
171             if (rgc.equals(irgc)) {
172                 if (rgj != null) {
173                     if (debug) {
174                         logger.log(BasicLevel.DEBUG, "\t\tadd join idx: " + rgj.joinIdx);
175                     }
176                     idx += rgj.joinIdx;
177                 }
178                 if (debug) {
179                     logger.log(BasicLevel.DEBUG, "\treturn " + idx);
180                 }
181                 return idx;
182             } else if (rgc.joins != null) {
183                 if (debug) {
184                     logger.log(BasicLevel.DEBUG, "\t\tcurrent has joins: " + rgc.joins.size());
185                 }
186                 idx += rgc.joins.size();
187             } else {
188                 if (debug) {
189                     logger.log(BasicLevel.DEBUG, "\t\tidx++");
190                 }
191                 idx++;
192             }
193             if (debug) {
194                 logger.log(BasicLevel.DEBUG, "\t\tidx=" + idx);
195             }
196         }
197         return -1;
198     }
199
200     /**
201      * Constructs the string representing the SQL query used for testing the
202      * existence of a JORM object.
203      * @return The query string.
204      */

205     public String JavaDoc getExistStatement() {
206         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("SELECT ");
207         String JavaDoc sep = "";
208         Iterator JavaDoc it;
209         String JavaDoc tabname = null;
210         if (genId.refColumn != null) {
211             sb.append(sep);
212             appendFQColName(sb, genId.refColumn);
213             tabname = genId.refColumn.table.tableName;
214         } else /* genCNId must not be null */ {
215             it = genId.cnFieldColumns.keySet().iterator();
216             while (it.hasNext()) {
217                 String JavaDoc cnfn = (String JavaDoc) it.next();
218                 RdbGenColumn rgc = (RdbGenColumn) genId.cnFieldColumns.get(cnfn);
219                 sb.append(sep);
220                 sep = COLUMN;
221                 appendFQColName(sb, rgc);
222                 if (tabname == null) {
223                     tabname = rgc.table.tableName;
224                 }
225             }
226         }
227         sb.append(" FROM ");
228         sb.append(tabname);
229         sb.append(" WHERE ");
230         sep = "";
231         if (genId.refColumn != null) {
232             sb.append(sep);
233             appendFQColName(sb, genId.refColumn);
234             sb.append(" = ?");
235         } else /* genCNId must not be null */ {
236             it = genId.cnFieldColumns.keySet().iterator();
237             while (it.hasNext()) {
238                 String JavaDoc cnfn = (String JavaDoc) it.next();
239                 RdbGenColumn rgc = (RdbGenColumn) genId.cnFieldColumns.get(cnfn);
240                 sb.append(sep);
241                 sep = " AND ";
242                 appendFQColName(sb, rgc);
243                 sb.append(" = ?");
244             }
245         }
246         return sb.toString();
247     }
248
249     /**
250      * Build the select clause that access all fields of the class.
251      */

252     public String JavaDoc getReadSelectFields() {
253         StringBuffer JavaDoc select = new StringBuffer JavaDoc();
254         String JavaDoc sep = "";
255         for (int i = 0; i < readableColumns.size(); i++) {
256             RdbGenColumn rgc = (RdbGenColumn) readableColumns.get(i);
257             if (rgc.joins != null && rgc.joins.size() > 1) {
258                 String JavaDoc[] s = new String JavaDoc[rgc.joins.size()];
259                 for (int j = 0; j < rgc.joins.size(); j++) {
260                     RdbGenJoin rgj = (RdbGenJoin) rgc.joins.get(j);
261                     s[rgj.joinIdx] = getFQColName(rgc, "_J" + rgj.joinIdx);
262                 }
263                 for (int j = 0; j < s.length; j++) {
264                     select.append(sep);
265                     sep = COLUMN;
266                     select.append(s[j]);
267                 }
268             } else if (rgc.constant == null) { //excludes constant fields
269
select.append(sep);
270                 sep = COLUMN;
271                 appendFQColName(select, rgc);
272             }
273         }
274         return select.toString();
275     }
276
277     public String JavaDoc getReadSelectFieldsAsColArray() {
278         StringBuffer JavaDoc select = new StringBuffer JavaDoc("new String[]{");
279         String JavaDoc sep = "";
280         for (int i = 0; i < readableColumns.size(); i++) {
281             RdbGenColumn rgc = (RdbGenColumn) readableColumns.get(i);
282             if (rgc.joins != null && rgc.joins.size() > 1) {
283                 String JavaDoc[] s = new String JavaDoc[rgc.joins.size()];
284                 for (int j = 0; j < rgc.joins.size(); j++) {
285                     RdbGenJoin rgj = (RdbGenJoin) rgc.joins.get(j);
286                     s[rgj.joinIdx] = getFQColName(rgc, "_J" + rgj.joinIdx);
287                 }
288                 for (int j = 0; j < s.length; j++) {
289                     select.append(sep);
290                     sep = COLUMN;
291                     select.append("\"").append(s[j]).append("\"");
292                 }
293             } else if (rgc.constant == null) { //excludes constant fields
294
select.append(sep);
295                 sep = COLUMN;
296                 select.append("\"");
297                 appendFQColName(select, rgc);
298                 select.append("\"");
299             }
300         }
301         select.append("}");
302         return select.toString();
303     }
304
305     
306     
307     /**
308      * @return a list of RdbGenColumn corresponding to constant fields
309      */

310     public List JavaDoc getConstantVisibleColumns() {
311         List JavaDoc constantCols = new ArrayList JavaDoc();
312         for (int i = 0; i < readableColumns.size(); i++) {
313             RdbGenColumn rgc = (RdbGenColumn) readableColumns.get(i);
314             if (rgc.constant != null && !rgc.hiddenField) {
315                 constantCols.add(rgc);
316             }
317         }
318         return constantCols;
319     }
320
321     /**
322      * @return the number of fields accessed by the select clause of the class.
323      */

324     public int getReadSelectNbFields() {
325         int res = 0;
326         for (int i = 0; i < readableColumns.size(); i++) {
327             RdbGenColumn rgc = (RdbGenColumn) readableColumns.get(i);
328             if (rgc.joins != null && rgc.joins.size() > 1) {
329                 String JavaDoc[] s = new String JavaDoc[rgc.joins.size()];
330                 for (int j = 0; j < rgc.joins.size(); j++) {
331                     RdbGenJoin rgj = (RdbGenJoin) rgc.joins.get(j);
332                     s[rgj.joinIdx] = getFQColName(rgc, "_J" + rgj.joinIdx);
333                 }
334                 for (int j = 0; j < s.length; j++) {
335                     res++;
336                 }
337             } else if (rgc.constant == null) { //excludes constant fields
338
res++;
339             }
340         }
341         return res;
342     }
343
344     /**
345      * Build the data structure representing the from clause and the joins for
346      * accessing all fields of the class.
347      * @return
348      */

349     public List JavaDoc getReadFromTables() {
350         ArrayList JavaDoc al = new ArrayList JavaDoc();
351         al.add("JoinedTable jt = new JoinedTable(\""
352                 + mainTable.tableName + "\");");
353         al.add("JoinedTable.Join jtj = null;");
354         Iterator JavaDoc it = tables.values().iterator();
355         while (it.hasNext()) {
356             RdbGenTable rgt = (RdbGenTable) it.next();
357             if (rgt.joins != null) {
358                 boolean multiJoin = rgt.joins.size() > 1;
359                 for (int i = 0; i < rgt.joins.size(); i++) {
360                     RdbGenJoin join = (RdbGenJoin) rgt.joins.get(i);
361                     String JavaDoc tableSuffix = null;
362                     if (multiJoin) {
363                         tableSuffix = "_J" + ((RdbGenJoin) rgt.joins.get(i)).joinIdx;
364                         al.add("jtj = jt.createChildren(\""
365                                 + rgt.tableName + "\", \""
366                                 + rgt.tableName + tableSuffix + "\");");
367                     } else {
368                         al.add("jtj = jt.createChildren(\""
369                                 + rgt.tableName + "\");");
370                     }
371                     for (int j = 0; j < join.joinColumnsInMain.size(); j++) {
372                         al.add("jtj.addJoinColumn(\""
373                                 + ((RdbGenColumn) join.joinColumnsInMain.get(j)).columnName
374                                 + "\", \""
375                                 + ((RdbGenColumn) join.joinColumnsInExt.get(j)).columnName
376                                 + "\");");
377                     }
378                 }
379             }
380         }
381         return al;
382     }
383
384
385     public String JavaDoc getReadWhereClause() {
386         // build the where clause with only the identifier matching
387
StringBuffer JavaDoc where = new StringBuffer JavaDoc();
388         String JavaDoc sep = "";
389         // apply the identifier matching
390
if (genId.refColumn != null) {
391             where.append(sep);
392             appendFQColName(where, genId.refColumn);
393             where.append(" = ?");
394         } else {
395             Iterator JavaDoc it = genId.cnFieldColumns.keySet().iterator();
396             while (it.hasNext()) {
397                 String JavaDoc cnfn = (String JavaDoc) it.next();
398                 RdbGenColumn rgc = (RdbGenColumn) genId.cnFieldColumns.get(cnfn);
399                 where.append(sep);
400                 sep = " AND ";
401                 appendFQColName(where, rgc);
402                 where.append(" = ?");
403             }
404         }
405         return where.toString();
406     }
407
408     /**
409      * Constructs the string representing the SQL query used to get the extent
410      * of a JORM class (the ID PName of all objects of this class).
411      * @return The query string.
412      */

413     public String JavaDoc getPNameIteratorSelectClause() {
414         StringBuffer JavaDoc select = new StringBuffer JavaDoc();
415         if (genId.getCnFieldColumns() == null) {
416             appendFQColName(select, genId.getRefColumn());
417         } else {
418             String JavaDoc sep = "";
419             Iterator JavaDoc it = genId.getCnFieldColumns().keySet().iterator();
420             while (it.hasNext()) {
421                 RdbGenColumn rgc = (RdbGenColumn) genId.getCnFieldColumns().get(it.next());
422                 if (!colInGenId(rgc)) {
423                 continue;
424                 }
425                 select.append(sep);
426                 sep = COLUMN;
427                 appendFQColName(select, rgc);
428             }
429         }
430         return select.toString();
431     }
432
433
434     public String JavaDoc getPNameIteratorSelectClauseWithPrefetch() {
435         StringBuffer JavaDoc select = new StringBuffer JavaDoc();
436         // build the select clause
437
select.append(getReadSelectFields());
438         if (genId.getCnFieldColumns() == null) {
439             select.append(COLUMN);
440             appendFQColName(select, genId.getRefColumn());
441             select.append("\" + adapter.getColumnAliasExpr(\"pk0\") + \"");
442         } else {
443             Iterator JavaDoc it = genId.getCnFieldColumns().keySet().iterator();
444             int i = 0;
445             while (it.hasNext()) {
446                 RdbGenColumn rgc = (RdbGenColumn) genId.getCnFieldColumns().get(it.next());
447                 if (!colInGenId(rgc)) {
448                     continue;
449                 }
450                 select.append(COLUMN);
451                 appendFQColName(select, rgc);
452                 select.append("\" + adapter.getColumnAliasExpr(\"pk");
453                 select.append(i);
454                 select.append("\") + \"");
455             }
456         }
457         return select.toString();
458     }
459
460
461     /**
462      * Return the filter as a medor expression.
463      */

464     public Expression getFilterMedorExpression() {
465         Expression exp = null;
466         try {
467             // check if there is an explicit mapping filter
468
RdbFilter rdbFilter = ((RdbClassMapping) mapping.getClassMapping())
469                     .getRdbFilter();
470             if (rdbFilter != null) { //there is an explicit mapping filter
471
exp = rdbFilter.getExpression();
472                 if (debug) {
473                     logger.log(BasicLevel.DEBUG, "Rdb filter specified for the class "
474                         + mapping.getClassMapping().getJormClass().getFQName()
475                         + ", expression=" + ExpressionPrinter.e2str(exp));
476                 }
477             } else {
478                 // try to compute it from the naming filter (only in case of
479
// extended or added inheritance rules)
480
if (((RdbClassMapping) mapping.getClassMapping()).inheritsStructures()
481                         || !mapping.getClassMapping().getJormClass().getSubClasses().isEmpty()) {
482                     // if there is no explicit filter but the
483
exp = ((RdbClassMapping) mapping.getClassMapping())
484                             .getMappingFilterFromNamingFilter();
485                     if (debug) {
486                         logger.log(BasicLevel.DEBUG, "Class "
487                                 + mapping.getClassMapping().getJormClass().getFQName()
488                                 + " has a filtered mapping and the filter is computed from the naming filter:"
489                                 + ExpressionPrinter.e2str(exp));
490                     }
491                 } else if (debug) {
492                     logger.log(BasicLevel.DEBUG, "Class "
493                             + mapping.getClassMapping().getJormClass().getFQName()
494                             + " has no filter");
495                 }
496             }
497             return exp;
498         } catch (ExpressionException e) {
499             throw new InternalError JavaDoc("Cannot compute filter expression: " + e);
500         }
501     }
502     
503     /**
504      * Return the filter as a string. It is a where clause.
505      */

506     public String JavaDoc getFilterExpression() {
507         if (filterExpr != null) {
508             return filterExpr;
509         }
510         try {
511             Expression exp = getFilterMedorExpression();
512             if (exp == null) {
513                 filterExpr = "";
514             } else {
515                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
516                 new JormExpression2WhereClause()
517                         .convertExp2WhereClauseBuilder(exp, "adapter", sb);
518                 filterExpr = sb.toString();
519             }
520             return filterExpr;
521         } catch (ExpressionException e) {
522             throw new InternalError JavaDoc("Cannot compute filter expression: " + e);
523         }
524     }
525     
526     String JavaDoc pnameIteratorWhereClause = null;
527
528     public String JavaDoc getPNameIteratorWhereClause() throws ExpressionException {
529         if (pnameIteratorWhereClause == null) {
530             pnameIteratorWhereClause = getFilterExpression();
531         }
532         if (pnameIteratorWhereClause != null
533             && pnameIteratorWhereClause.length() > 0) {
534             return pnameIteratorWhereClause;
535         } else {
536             return null;
537         }
538     }
539
540
541
542
543     /**
544      * Constructs the string representing the SQL query used to update the part
545      * of a JORM object stored into the given table.
546      * @param rgt The description of the table to be modified.
547      * @return The query string.
548      */

549     public String JavaDoc getUpdateStatement(RdbGenTable rgt) throws PException {
550         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("UPDATE ");
551         sb.append(rgt.tableName);
552         sb.append(" SET ");
553         String JavaDoc sep = "";
554         for (int i = 0; i < rgt.inheritedColumns.size(); i++) {
555             if (updatable((RdbGenColumn) rgt.inheritedColumns.get(i))) {
556                 sb.append(sep);
557                 sep = COLUMN;
558                 sb.append(((RdbGenColumn) rgt.inheritedColumns.get(i)).columnName);
559                 sb.append(" = ?");
560             }
561         }
562         for (int i = 0; i < rgt.columns.size(); i++) {
563             if (updatable((RdbGenColumn) rgt.columns.get(i))) {
564                 sb.append(sep);
565                 sep = COLUMN;
566                 sb.append(((RdbGenColumn) rgt.columns.get(i)).columnName);
567                 sb.append(" = ?");
568             }
569         }
570         appendModificationWhereClause(sb, rgt);
571         return sb.toString();
572     }
573
574     public String JavaDoc getUpdateStatement(RdbGenJoin rgj) throws PException {
575         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("UPDATE ");
576         sb.append(rgj.table.tableName);
577         sb.append(" SET ");
578         String JavaDoc sep = "";
579         if (rgj.table.colocatedTable) {
580             for (int i = 0; i < rgj.joinColumnsInExt.size(); i++) {
581                 sb.append(sep);
582                 sep = COLUMN;
583                 sb.append(((RdbGenColumn) rgj.joinColumnsInExt.get(i)).columnName);
584                 sb.append(" = ?");
585             }
586
587         } else {
588             for (int i = 0; i < rgj.table.columns.size(); i++) {
589                 RdbGenColumn rgc = (RdbGenColumn) rgj.table.columns.get(i);
590                 if (rgc.joinCol == null) {
591                     sb.append(sep);
592                     sep = COLUMN;
593                     sb.append(rgc.columnName);
594                     sb.append(" = ?");
595                 }
596             }
597         }
598         appendModificationWhereClause(sb, rgj, rgj.table.colocatedTable);
599         return sb.toString();
600     }
601
602     public String JavaDoc getUpdateNullStatement(RdbGenTable rgt) throws PException {
603         if (rgt.joins != null && rgt.joins.size() > 0) {
604             throw new PException("umanaged case, must use " +
605                                  "getUpdateNullStatement(RdbGenJoin) for each join.");
606         }
607         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("UPDATE ");
608         sb.append(rgt.tableName);
609         sb.append(" SET ");
610         String JavaDoc sep = "";
611         for (int i = 0; i < rgt.columns.size(); i++) {
612             RdbGenColumn rgc = (RdbGenColumn) rgt.columns.get(i);
613             if (updatable(rgc)) {
614                 if (rgt.colocatedColumn(rgc)) {
615                     continue;
616                 }
617                 sb.append(sep);
618                 sep = COLUMN;
619                 sb.append(rgc.columnName);
620                 sb.append(" = null");
621             }
622         }
623         appendModificationWhereClause(sb, rgt);
624         return sb.toString();
625     }
626
627     public String JavaDoc getUpdateNullStatement(RdbGenJoin rgj) throws PException {
628         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("UPDATE ");
629         sb.append(rgj.table.tableName);
630         sb.append(" SET ");
631         String JavaDoc sep = "";
632         for (int i = 0; i < rgj.joinColumnsInExt.size(); i++) {
633             sb.append(sep);
634             sep = COLUMN;
635             sb.append(((RdbGenColumn) rgj.joinColumnsInExt.get(i)).columnName);
636             sb.append(" = null");
637         }
638         appendModificationWhereClause(sb, rgj, false);
639         return sb.toString();
640     }
641
642     /**
643      * Constructs the string representing the SQL query used to insert the part
644      * of a JORM object stored into the given table.
645      * @param rgt The description of the table to be modified.
646      * @return The query string.
647      */

648     public String JavaDoc getInsertStatement(RdbGenTable rgt) throws PException {
649         String JavaDoc sep = "";
650         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("INSERT INTO ");
651         sb.append(rgt.tableName);
652         sb.append(" (");
653         ArrayList JavaDoc columns = new ArrayList JavaDoc();
654         columns.addAll(rgt.inheritedColumns);
655         columns.addAll(rgt.columns);
656         for (int i = 0; i < columns.size(); i++) {
657             sb.append(sep);
658             sep = COLUMN;
659             sb.append(((RdbGenColumn) columns.get(i)).columnName);
660         }
661         sb.append(") VALUES (");
662         sep = "";
663         for (int i = 0; i < columns.size(); i++) {
664             sb.append(sep);
665             sep = COLUMN;
666             sb.append("?");
667         }
668         sb.append(")");
669         return sb.toString();
670     }
671
672     public String JavaDoc getInsertStatement(RdbGenJoin rgj) {
673         RdbGenTable rgt = rgj.getTable();
674         int i = 0;
675         try {
676             String JavaDoc sep = "";
677             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("INSERT INTO ");
678             sb.append(rgt.tableName);
679             sb.append(" (");
680             for (i = 0; i < rgt.columns.size(); i++) {
681                 RdbGenColumn col = (RdbGenColumn) rgt.columns.get(i);
682                 if (col.isInJoin(rgj)) {
683                     sb.append(sep);
684                     sep = COLUMN;
685                     sb.append(((RdbGenColumn) rgt.columns.get(i)).columnName);
686                 }
687             }
688             sb.append(") VALUES (");
689             sep = "";
690             for (i = 0; i < rgt.columns.size(); i++) {
691                 RdbGenColumn col = (RdbGenColumn) rgt.columns.get(i);
692                 if (col.isInJoin(rgj)) {
693                     sb.append(sep);
694                     sep = COLUMN;
695                     sb.append("?");
696                 }
697             }
698             sb.append(")");
699             return sb.toString();
700         } catch (RuntimeException JavaDoc e) {
701             System.out.println(rgt.tableName);
702             System.out.println(rgt.columns.get(i));
703             System.out.println(((RdbGenColumn) rgt.columns.get(i)).joins);
704             e.printStackTrace();
705             throw e;
706         }
707     }
708
709     /**
710      * Constructs the string representing the SQL query used to delete the part
711      * of a JORM object stored into the given table.
712      * @param rgt The description of the table to be modified.
713      * @return The query string.
714      */

715     public String JavaDoc getDeleteStatement(RdbGenTable rgt) throws PException {
716         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("DELETE FROM ");
717         sb.append(rgt.tableName);
718         appendModificationWhereClause(sb, rgt);
719         return sb.toString();
720     }
721
722     public String JavaDoc getDeleteStatement(RdbGenJoin rgj) throws PException {
723         return getDeleteStatement(rgj.getTable());
724     }
725
726     /**
727      * Constructs the string representing the SQL query used to delete the part
728      * of a JORM object stored into the given table.
729      * @param rgj The description of the join between the external table and
730      * the main table
731      * @return The query string.
732      */

733     public String JavaDoc getExtDeleteStatement(RdbGenJoin rgj) throws PException {
734         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("DELETE FROM ");
735         sb.append(rgj.table.tableName);
736         appendModificationWhereClause(sb, rgj, rgj.table.colocatedTable);
737         return sb.toString();
738     }
739
740     public String JavaDoc setIdPnParam(String JavaDoc cnfn,
741                                int idx,
742                                String JavaDoc adapter,
743                                String JavaDoc pstmt,
744                                boolean isSpecific) throws PException {
745         RdbGenColumn rgc = (RdbGenColumn) genId.cnFieldColumns.get(cnfn);
746         return rgc.getSqlSet(adapter, pstmt, setIdPNParameterOperand( cnfn, isSpecific), idx);
747     }
748
749     /**
750      * If isSpecific is true returns a String like this:
751      * ((org.objectweb.speedo.pobjects.detach.VehicleIdPNG) _pngId).pnGetName(null)
752      * else, it returns a String like that:
753      * ((PNameGetter) _pngId).pngetStringField("name", null)
754      */

755     public String JavaDoc setIdPNParameterOperand(String JavaDoc cnfn, boolean isSpecific) throws PException {
756         RdbGenColumn rgc = (RdbGenColumn) genId.cnFieldColumns.get(cnfn);
757         StringBuffer JavaDoc value = new StringBuffer JavaDoc();
758         if (isSpecific) {
759             value.append("((");
760             value.append(genId.getCnFQName());
761             value.append("PNG) _pngId).pnGet");
762             value.append(commonHelper.upperFL(cnfn));
763             value.append("(null)");
764         } else {
765             value.append("((PNameGetter) _pngId).");
766             value.append(commonHelper.getPNameGetterGetFunction(rgc.columnType));
767             value.append("(\"");
768             value.append(cnfn);
769             value.append("\", null)");
770         }
771         return value.toString();
772     }
773     
774     /**
775      * Searches the RdbGenRef object, from the genRefs list, which the given
776      * column belongs to.
777      * @param rgc The column for which to find a RdbGenRef.
778      * @return The relevant RdbGenRef or null if none found.
779      */

780     public RdbGenRef getGenRefOfColumn(RdbGenColumn rgc) {
781         return getGenRefOfColumn(rgc, null);
782     }
783
784     public RdbGenRef getGenRefOfColumn(RdbGenColumn rgc, RdbGenJoin rgj) {
785         if (rgc.joinCol != null) {
786             return getGenRefOfColumn(rgc.joinCol, rgj);
787         }
788         PrimitiveElement pe = null;
789         if (rgj != null && rgc.joins != null) {
790             int idx = rgc.joins.indexOf(rgj);
791             if (idx != -1) {
792                 pe = (PrimitiveElement) rgc.pes.get(idx);
793             }
794         }
795         Iterator JavaDoc it = genRefs.values().iterator();
796         while (it.hasNext()) {
797             RdbGenRef rgr = (RdbGenRef) it.next();
798             if (rgr.refColumn != null) {
799                 if (rgr.refColumn == rgc && (pe == null
800                         || rgr.nd.getFieldName().equals(pe.getName()))) {
801                     //if (rgj !=null) System.out.println("getGenRefOfColumn(" + rgc.columnName + COLUMN + rgj.joinIdx + ") return " + rgr.fieldName);
802
return rgr;
803                 }
804             } else {
805                 Iterator JavaDoc it2 = rgr.cnFieldColumns.values().iterator();
806                 Collection JavaDoc classfields = rgr.nd.getNameRef().getProjection().values();
807                 while (it2.hasNext()) {
808                     RdbGenColumn currentRgc = (RdbGenColumn) it2.next();
809                     if (currentRgc == rgc && (pe == null
810                             || classfields.contains(pe.getName()))) {
811                         //if (rgj !=null) System.out.println("getGenRefOfColumn(" + rgc.columnName + COLUMN + rgj.joinIdx + ") return " + rgr.fieldName);
812
return rgr;
813                     }
814                 }
815             }
816         }
817         if (rgj !=null) System.out.println("getGenRefOfColumn(" + rgc.columnName + COLUMN + rgj.joinIdx + ") return null");
818         return null;
819     }
820
821     /**
822      * Verifies if the given column is used in the identifier of this class,
823      * which is defined by genId.
824      * @param genCol The column for which to verify its belonging to the ID.
825      * @return true if it belongs to genId.
826      */

827     public boolean colInGenId(RdbGenColumn genCol) {
828         if (genCol.joinCol != null) {
829             // the column belongs to an external table and is part
830
// of the join with the main table
831
// then we check if the corresponding column
832
// in the main table is part of the id
833
return colInGenId(genCol.joinCol);
834         }
835         if (genId.refColumn != null) {
836             if (genId.refColumn == genCol) {
837                 return true;
838             }
839         } else {
840             Iterator JavaDoc itCol = genId.cnFieldColumns.values().iterator();
841             while (itCol.hasNext()) {
842                 RdbGenColumn genColOfComposite = (RdbGenColumn) itCol.next();
843                 if (genColOfComposite == genCol) {
844                     return true;
845                 }
846             }
847         }
848         return false;
849     }
850
851     /**
852      * Searches the name of the field which defines the given reference.
853      * @param gr The reference definition.
854      * @return The relevant field name.
855      */

856     public String JavaDoc getGenRefFieldName(RdbGenRef gr) {
857         Iterator JavaDoc it = genRefs.keySet().iterator();
858         while (it.hasNext()) {
859             String JavaDoc res = (String JavaDoc) it.next();
860             if (genRefs.get(res) == gr) {
861                 return res;
862             }
863         }
864         return null;
865     }
866
867     /**
868      * Searches the name of the field in the composite name associated with the
869      * identifier, which is mapped to the given column.
870      * @param rgc The column to search.
871      * @return The name of the mapped field.
872      */

873     public String JavaDoc getPnFieldName(RdbGenColumn rgc) {
874         Iterator JavaDoc it = genId.cnFieldColumns.keySet().iterator();
875         while (it.hasNext()) {
876             String JavaDoc res = (String JavaDoc) it.next();
877             if (rgc == genId.cnFieldColumns.get(res)) {
878                 return res;
879             }
880         }
881         return null;
882     }
883
884     // PRIVATE METHODS
885

886     /**
887      * Appends the definition of a fully qualified name of a field of a table
888      * (example: field F of table T => appends "T.F").
889      * @param sb
890      * @param rgc
891      */

892     private void appendFQColName(StringBuffer JavaDoc sb, RdbGenColumn rgc) {
893         sb.append(rgc.table.tableName);
894         sb.append(".");
895         sb.append(rgc.columnName);
896     }
897
898     private String JavaDoc getFQColName(RdbGenColumn rgc, String JavaDoc tableSuffix) {
899         return rgc.table.tableName + tableSuffix + "." + rgc.columnName;
900     }
901
902     /**
903      * Appends the where clause for a given table for the prupose of a
904      * modification of this table (i.e., an update or a delete).
905      * @param sb The string buffer into which to produce the clause.
906      * @param rgt The involved table.
907      */

908     private void appendModificationWhereClause(StringBuffer JavaDoc sb,
909                                                RdbGenTable rgt)
910             throws PException {
911         String JavaDoc sep = "";
912         sb.append(" WHERE ");
913         if (rgt != mainTable) {
914             throw new PException("umanaged case, the table "
915                                  + rgt.tableName + " is an external table");
916         }
917         if (genId.refColumn != null) {
918             sb.append(genId.refColumn.columnName);
919             sb.append(" = ?");
920         } else {
921             Iterator JavaDoc it = genId.cnFieldColumns.values().iterator();
922             while (it.hasNext()) {
923                 RdbGenColumn cur = (RdbGenColumn) it.next();
924                 sb.append(sep);
925                 sep = " AND ";
926                 sb.append(cur.columnName);
927                 sb.append(" = ?");
928             }
929         }
930     }
931
932     /**
933      * Appends the where clause for a given table for the prupose of a
934      * modification of this table (i.e., an update or a delete).
935      * @param sb The string buffer into which to produce the clause.
936      * @param rgj The involved join.
937      */

938     private void appendModificationWhereClause(StringBuffer JavaDoc sb,
939                                                RdbGenJoin rgj,
940                                                boolean isNotJoinColumn) {
941         String JavaDoc sep = "";
942         sb.append(" WHERE ");
943         sep = "";
944         if (isNotJoinColumn) {
945             for (int i = 0; i < rgj.table.columns.size(); i++) {
946                 RdbGenColumn rgc = (RdbGenColumn) rgj.table.columns.get(i);
947                 if (rgc.joinCol == null) {
948                     sb.append(sep);
949                     sep = " AND ";
950                     sb.append(rgc.columnName);
951                     sb.append(" = ?");
952                 }
953             }
954         } else {
955             for (int i = 0; i < rgj.joinColumnsInExt.size(); i++) {
956                 sb.append(sep);
957                 sep = " AND ";
958                 sb.append(((RdbGenColumn) rgj.joinColumnsInExt.get(i)).columnName);
959                 sb.append(" = ?");
960             }
961         }
962     }
963
964     public boolean updatable(RdbGenColumn rgc) {
965         return (!rgc.hiddenField || rgc.joinCol != null || !colInGenId(rgc))
966                 && rgc.constant == null;
967     }
968
969     public boolean updatable(RdbGenColumn rgc, RdbGenJoin rgj) {
970         if (rgj == null) {
971             return updatable(rgc);
972         }
973         if (rgj.table.colocatedTable) {
974             return rgc.joinCol != null && rgc.isInJoin(rgj);
975         } else {
976             return rgc.joinCol == null;
977         }
978     }
979
980     public boolean hasFilter() {
981         return filterExpr!= null && !"".equals(filterExpr);
982     }
983
984
985
986     class JormExpression2WhereClause extends Expression2WhereClauseImpl {
987
988         public void convertExp2WhereClauseBuilder(Expression expression,
989                                                   String JavaDoc rdbAdapterVarName,
990                                                   StringBuffer JavaDoc sb) throws ExpressionException {
991             if (expression instanceof ParameterOperand) {
992                 // A parameter operand corresponds to a PEM mapped into the
993
// main table
994
String JavaDoc fieldName = ((ParameterOperand) expression).getName();
995                 RdbPrimitiveElementMapping rpem =
996                     getRPEM(fieldName, mapping.getClassMapping());
997                 if (rpem == null) {
998                     throw new ExpressionException(
999                             "No mapping found for the field '" + fieldName
1000                            + "' into the mapping filter");
1001                }
1002                RdbGenColumn rgc = mainTable.getColumn(rpem.getName());
1003                if (rgc == null) {
1004                    throw new ExpressionException(
1005                            "No column found for the field '" + fieldName
1006                            + "' into the mainb table '"
1007                            + mainTable.tableName
1008                            + "' in the mapping filter");
1009                }
1010                appendFQColName(sb, rgc);
1011            } else if (expression instanceof VariableOperand) {
1012                sb.append("\" + ");
1013                sb.append(rdbAdapterVarName);
1014                sb.append(".getValueAsSQLString(getNamingFilterKey(), ");
1015                sb.append(expression.getType().getProgName());
1016                sb.append(".getTypeCode()) + \"");
1017            } else {
1018                super.convertExp2WhereClauseBuilder(expression, rdbAdapterVarName, sb);
1019            }
1020        }
1021        private RdbPrimitiveElementMapping getRPEM(String JavaDoc fieldName,
1022                                                   ClassMapping cm)
1023            throws ExpressionException {
1024            if (debug) {
1025                logger.log(BasicLevel.DEBUG, "Try to find the field " + fieldName
1026                    + " on the class mapping of the class "
1027                    + ((Class JavaDoc) cm.getLinkedMO()).getFQName());
1028            }
1029            RdbPrimitiveElementMapping rpem = (RdbPrimitiveElementMapping)
1030                    cm.getPrimitiveElementMapping(fieldName);
1031            if (rpem == null) {
1032                for(Iterator JavaDoc it = cm.getParentClassMappings().iterator();
1033                    rpem == null && it.hasNext();) {
1034                    ParentClassMapping pcm = (ParentClassMapping) it.next();
1035                    ClassMapping _cm = pcm.getMOClass()
1036                        .getClassProject(pcm.getProjectName())
1037                        .getMapping(pcm.getMapperName()).getClassMapping();
1038                    rpem = getRPEM(fieldName, _cm);
1039                }
1040
1041            }
1042            return rpem;
1043        }
1044    }
1045
1046}
1047
Popular Tags