KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > amber > field > EntityEmbeddedField


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.amber.field;
31
32 import com.caucho.amber.expr.AmberExpr;
33 import com.caucho.amber.expr.EmbeddedExpr;
34 import com.caucho.amber.expr.PathExpr;
35 import com.caucho.amber.query.QueryParser;
36 import com.caucho.amber.table.Column;
37 import com.caucho.amber.table.Table;
38 import com.caucho.amber.type.EmbeddableType;
39 import com.caucho.amber.type.RelatedType;
40 import com.caucho.amber.type.Type;
41 import com.caucho.config.ConfigException;
42 import com.caucho.java.JavaWriter;
43 import com.caucho.log.Log;
44 import com.caucho.util.CharBuffer;
45 import com.caucho.util.L10N;
46
47 import java.io.IOException JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.Map JavaDoc;
51 import java.util.logging.Logger JavaDoc;
52
53 /**
54  * Configuration for a bean's embedded field
55  */

56 public class EntityEmbeddedField extends AbstractField {
57   private static final L10N L = new L10N(PropertyField.class);
58   protected static final Logger JavaDoc log = Log.open(PropertyField.class);
59
60   private HashMap JavaDoc<String JavaDoc, Column> _columns;
61   private HashMap JavaDoc<String JavaDoc, String JavaDoc> _fieldNameByColumn;
62   private EmbeddableType _type;
63
64   private boolean _isInsert = true;
65   private boolean _isUpdate = true;
66
67   private boolean _isEmbeddedId = false;
68
69   public EntityEmbeddedField(RelatedType relatedType,
70                              String JavaDoc name)
71     throws ConfigException
72   {
73     super(relatedType, name);
74   }
75
76   public EntityEmbeddedField(RelatedType relatedType)
77   {
78     super(relatedType);
79   }
80
81   public EmbeddableType getEmbeddableType()
82   {
83     return (EmbeddableType) _type;
84   }
85
86   /**
87    * Sets the result type.
88    */

89   public void setType(EmbeddableType type)
90   {
91     _type = type;
92   }
93
94   /**
95    * Sets the result type.
96    */

97   public Type getType()
98   {
99     return _type;
100   }
101
102   /**
103    * Returns the table containing the field's columns.
104    */

105   public Table getTable()
106   {
107     // Assume all columns belong to the same table
108
for (Map.Entry JavaDoc<String JavaDoc, Column> entry : _columns.entrySet()) {
109       Column column = entry.getValue();
110       return column.getTable();
111     }
112
113     return null;
114   }
115
116   /**
117    * Sets the columns.
118    */

119   public void setEmbeddedColumns(HashMap JavaDoc<String JavaDoc, Column> columns)
120   {
121     _columns = columns;
122   }
123
124   /**
125    * Gets the columns.
126    */

127   public HashMap JavaDoc<String JavaDoc, Column> getEmbeddedColumns()
128   {
129     return _columns;
130   }
131
132   /**
133    * Sets the field name by column mapping.
134    */

135   public void setFieldNameByColumn(HashMap JavaDoc<String JavaDoc, String JavaDoc> fieldNameByColumn)
136   {
137     _fieldNameByColumn = fieldNameByColumn;
138   }
139
140   /**
141    * Gets the field name by column mapping.
142    */

143   public HashMap JavaDoc<String JavaDoc, String JavaDoc> getFieldNameByColumn()
144   {
145     return _fieldNameByColumn;
146   }
147
148   /**
149    * Returns true if the property is an @EmbeddedId.
150    */

151   public boolean isEmbeddedId()
152   {
153     return _isEmbeddedId;
154   }
155
156   /**
157    * Set true if the property is an @EmbeddedId.
158    */

159   public void setEmbeddedId(boolean isEmbeddedId)
160   {
161     _isEmbeddedId = isEmbeddedId;
162   }
163
164   /**
165    * Set true if the property should be saved on an insert.
166    */

167   public void setInsert(boolean isInsert)
168   {
169     _isInsert = isInsert;
170   }
171
172   /**
173    * Set true if the property should be saved on an update.
174    */

175   public void setUpdate(boolean isUpdate)
176   {
177     _isUpdate = isUpdate;
178   }
179
180   /**
181    * Initializes the property.
182    */

183   public void init()
184     throws ConfigException
185   {
186     super.init();
187
188     if (getEmbeddedColumns() == null)
189       throw new IllegalStateException JavaDoc(L.l("columns must be set before init"));
190   }
191
192   /**
193    * Returns the null value.
194    */

195   public String JavaDoc generateNull()
196   {
197     return getType().generateNull();
198   }
199
200   /**
201    * Generates the set property.
202    */

203   public void generateGetProperty(JavaWriter out)
204     throws IOException JavaDoc
205   {
206     if (! isFieldAccess() && getGetterMethod() == null)
207       return;
208
209     out.println();
210     out.println("public " + getJavaTypeName() + " " + getGetterName() + "()");
211     out.println("{");
212     out.pushDepth();
213
214     out.println("if (__caucho_session != null)");
215     out.println(" __caucho_load_" + getLoadGroupIndex() + "(__caucho_session);");
216     out.println();
217     out.println("return " + generateSuperGetter() + ";");
218
219     out.popDepth();
220     out.println("}");
221   }
222
223   /**
224    * Generates the set property.
225    */

226   public void generateSetProperty(JavaWriter out)
227     throws IOException JavaDoc
228   {
229     if (! isFieldAccess() && (getGetterMethod() == null ||
230                               getSetterMethod() == null && ! isAbstract()))
231       return;
232
233     out.println();
234     out.println("public void " + getSetterName() + "(" + getJavaTypeName() + " v)");
235     out.println("{");
236     out.pushDepth();
237
238     if (! _isUpdate) {
239       out.println("if (__caucho_session == null)");
240       out.println(" " + generateSuperSetter("v") + ";");
241     }
242     else {
243       out.println(getJavaTypeName() + " oldValue = " + generateSuperGetter() + ";");
244
245       int maskGroup = getLoadGroupIndex() / 64;
246       String JavaDoc loadVar = "__caucho_loadMask_" + maskGroup;
247
248       long mask = 1L << (getLoadGroupIndex() % 64);
249
250       if (getJavaTypeName().equals("java.lang.String")) {
251         out.println("if ((oldValue == v || v != null && v.equals(oldValue)) && (" + loadVar + " & " + mask + "L) != 0L)");
252         out.println(" return;");
253       }
254       else {
255         out.println("if (oldValue == v && (" + loadVar + " & " + mask + "L) != 0)");
256         out.println(" return;");
257       }
258
259       out.println(generateSuperSetter("v") + ";");
260
261       int dirtyGroup = getIndex() / 64;
262       String JavaDoc dirtyVar = "__caucho_dirtyMask_" + dirtyGroup;
263
264       long dirtyMask = 1L << (getIndex() % 64);
265
266       out.println();
267       out.println("long oldMask = " + dirtyVar + ";");
268       out.println(dirtyVar + " |= " + dirtyMask + "L;");
269       out.println();
270       out.println("if (__caucho_session != null && oldMask == 0)");
271       out.println(" __caucho_session.update(this);");
272     }
273
274     out.popDepth();
275     out.println("}");
276   }
277
278   /**
279    * Generates the select clause.
280    */

281   public String JavaDoc generateLoadSelect(Table table, String JavaDoc id)
282   {
283     if (getTable() != table)
284       return null;
285     else
286       return generateSelect(id);
287   }
288
289   /**
290    * Generates the select clause.
291    */

292   public String JavaDoc generateSelect(String JavaDoc id)
293   {
294     return generateSelect(id, getEmbeddableType(),
295                           _fieldNameByColumn, _columns);
296   }
297
298   /**
299    * Generates the select clause.
300    */

301   public static String JavaDoc generateSelect(String JavaDoc id,
302                                       EmbeddableType type,
303                                       HashMap JavaDoc<String JavaDoc, String JavaDoc> fieldNameByColumn,
304                                       HashMap JavaDoc<String JavaDoc, Column> columns)
305   {
306     // XXX: needs to simplify the HashMap and ArrayList
307
// but the same embeddable type could be reused
308
// for different entities with embedded fields
309
// and different column mappings.
310

311     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
312
313     boolean isFirst = true;
314
315     ArrayList JavaDoc<AmberField> fields = type.getFields();
316
317     for (int i = 0; i < fields.size(); i++) {
318       AmberField field = fields.get(i);
319
320       if (! (field instanceof PropertyField))
321         throw new IllegalStateException JavaDoc(L.l("Only property fields are expected for embeddable types in '{0}'", type.getName()));
322
323       if (isFirst)
324         isFirst = false;
325       else
326         sb.append(", ");
327
328       for (Map.Entry JavaDoc<String JavaDoc, String JavaDoc> entry : fieldNameByColumn.entrySet()) {
329         String JavaDoc columnName = entry.getKey();
330         String JavaDoc fieldName = entry.getValue();
331
332         if (fieldName.equals(field.getName())) {
333           Column column = columns.get(columnName);
334           sb.append(column.generateSelect(id));
335         }
336       }
337     }
338
339     return sb.toString();
340   }
341
342   /**
343    * Generates the where clause.
344    */

345   public String JavaDoc generateWhere(String JavaDoc id)
346   {
347     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
348
349     for (Map.Entry JavaDoc<String JavaDoc, Column> entry : _columns.entrySet()) {
350       Column column = entry.getValue();
351       sb.append(column.generateSelect(id));
352     }
353
354     return sb.toString();
355   }
356
357   /**
358    * Generates the insert.
359    */

360   public void generateInsertColumns(ArrayList JavaDoc<String JavaDoc> columns)
361   {
362     if (_isInsert) {
363       for (Map.Entry JavaDoc<String JavaDoc, Column> entry : _columns.entrySet()) {
364         Column column = entry.getValue();
365         columns.add(column.getName());
366       }
367     }
368   }
369
370   /**
371    * Generates the update set clause
372    */

373   public void generateUpdate(CharBuffer sql)
374   {
375     if (_isUpdate) {
376       for (Map.Entry JavaDoc<String JavaDoc, Column> entry : _columns.entrySet()) {
377         Column column = entry.getValue();
378         sql.append(column.generateUpdateSet());
379       }
380     }
381
382     /*
383       sql.append(getColumn());
384       sql.append("=?");
385     */

386   }
387
388   /**
389    * Generates the set clause for the insert clause.
390    */

391   public void generateInsertSet(JavaWriter out, String JavaDoc pstmt,
392                                 String JavaDoc index, String JavaDoc obj)
393     throws IOException JavaDoc
394   {
395     if (_isInsert)
396       generateSet(out, pstmt, index, obj);
397     else if (getLoadGroupIndex() != 0) {
398       int groupIndex = getLoadGroupIndex();
399       int group = groupIndex / 64;
400       long groupMask = 1L << (groupIndex % 64);
401       out.println("__caucho_loadMask_" + group + " &= ~" + groupMask + "L;");
402     }
403   }
404
405   /**
406    * Generates the set clause for the insert clause.
407    */

408   public void generateUpdateSet(JavaWriter out, String JavaDoc pstmt,
409                                 String JavaDoc index, String JavaDoc obj)
410     throws IOException JavaDoc
411   {
412     if (_isUpdate)
413       generateSet(out, pstmt, index, obj);
414   }
415
416   /**
417    * Generates the set clause.
418    */

419   public void generateSet(JavaWriter out, String JavaDoc pstmt,
420                           String JavaDoc index, String JavaDoc obj)
421     throws IOException JavaDoc
422   {
423     if (! isFieldAccess() && getGetterMethod() == null)
424       return;
425
426     for (Map.Entry JavaDoc<String JavaDoc, Column> entry : _columns.entrySet()) {
427       Column column = entry.getValue();
428
429       String JavaDoc getter = _fieldNameByColumn.get(column.getName());
430
431       EmbeddableType embeddableType = getEmbeddableType();
432
433       if (! getSourceType().isFieldAccess())
434         getter = "get" + Character.toUpperCase(getter.charAt(0)) +
435           getter.substring(1) + "()";
436
437       out.println("if (" + generateGet(obj) + " == null) {");
438       out.pushDepth();
439
440       out.println(pstmt + ".setNull(index++, java.sql.Types.NULL);");
441
442       out.popDepth();
443       out.println("} else");
444       out.pushDepth();
445       column.generateSet(out, pstmt, index, generateGet(obj)+"."+getter);
446       out.popDepth();
447     }
448   }
449
450   /**
451    * Generates get property.
452    */

453   public void generateGetPrimaryKey(CharBuffer cb)
454   {
455     if (! isFieldAccess() && getGetterMethod() == null)
456       return;
457
458     String JavaDoc thisGetter = generateGet("this");
459
460     EmbeddableType embeddableType = getEmbeddableType();
461
462     ArrayList JavaDoc<AmberField> fields = embeddableType.getFields();
463     for (int i = 0; i < fields.size(); i++) {
464       if (i != 0)
465         cb.append(", ");
466
467       AmberField field = fields.get(i);
468
469       String JavaDoc getter = field.getName();
470
471       if (! getSourceType().isFieldAccess()) {
472         getter = "get" + Character.toUpperCase(getter.charAt(0)) +
473           getter.substring(1) + "()";
474       }
475
476       cb.append(thisGetter + "." + getter);
477     }
478   }
479
480   /**
481    * Generates loading code
482    */

483   public int generateLoad(JavaWriter out, String JavaDoc rs,
484                           String JavaDoc indexVar, int index)
485     throws IOException JavaDoc
486   {
487     /*
488       if (getSetterMethod() == null)
489       return index;
490     */

491
492     String JavaDoc var = "amber_ld_embedded" + index;
493
494     out.print(getJavaTypeName());
495     out.println(" " + var + " = new "+getJavaTypeName()+"();");
496
497     // jpa/0w01
498
out.println("((com.caucho.amber.entity.Embeddable) " + var + ")."+
499                 "__caucho_load(aConn, rs, " +
500                 indexVar + " + " + index + ");");
501
502     index += _columns.entrySet().size();
503
504     /* jpa/0w01
505     for (Map.Entry<String, Column> entry : _columns.entrySet()) {
506       Column column = entry.getValue();
507       out.print(column.getType().getJavaTypeName());
508       out.print(" amber_ld" + index + " = ");
509       index = column.generateLoad(out, rs, indexVar, index);
510       out.println(";");
511
512       String setter = _fieldNameByColumn.get(column.getName());
513
514       EmbeddableType embeddableType = getEmbeddableType();
515
516       if (getSourceType().isFieldAccess()) {
517         out.println(var + "." + setter + " = amber_ld" + (index-1) + ";");
518       }
519       else {
520         out.println(var + ".set" + Character.toUpperCase(setter.charAt(0)) +
521                     setter.substring(1) + "(amber_ld" + (index-1) + ");");
522       }
523     }
524     */

525
526     out.println(generateSuperSetter(var) + ";");
527
528     // out.println("__caucho_loadMask |= " + (1L << getIndex()) + "L;");
529

530     return index;
531   }
532
533   /**
534    * Creates the expression for the field.
535    */

536   public AmberExpr createExpr(QueryParser parser, PathExpr parent)
537   {
538     return new EmbeddedExpr(parent, _type, _columns, _fieldNameByColumn);
539   }
540 }
541
Popular Tags