KickJava   Java API By Example, From Geeks To Geeks.

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


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.cfg.AbstractConfigIntrospector;
33 import com.caucho.amber.expr.AmberExpr;
34 import com.caucho.amber.expr.ColumnExpr;
35 import com.caucho.amber.expr.EmbeddedExpr;
36 import com.caucho.amber.expr.PathExpr;
37 import com.caucho.amber.query.QueryParser;
38 import com.caucho.amber.table.Column;
39 import com.caucho.amber.table.ForeignColumn;
40 import com.caucho.amber.table.Table;
41 import com.caucho.amber.type.AbstractStatefulType;
42 import com.caucho.amber.type.ArrayType;
43 import com.caucho.amber.type.EmbeddableType;
44 import com.caucho.amber.type.RelatedType;
45 import com.caucho.amber.type.Type;
46 import com.caucho.config.ConfigException;
47 import com.caucho.java.JavaWriter;
48 import com.caucho.log.Log;
49 import com.caucho.util.CharBuffer;
50 import com.caucho.util.L10N;
51
52 import java.io.IOException JavaDoc;
53 import java.util.ArrayList JavaDoc;
54 import java.util.logging.Logger JavaDoc;
55
56 /**
57  * Configuration for a bean's field
58  */

59 public class PropertyField extends AbstractField {
60   private static final L10N L = new L10N(PropertyField.class);
61   protected static final Logger JavaDoc log = Log.open(PropertyField.class);
62
63   private Column _column;
64   private Type _type;
65
66   private KeyManyToOneField _aliasKey;
67
68   private boolean _isInsert = true;
69   private boolean _isUpdate = true;
70
71   public PropertyField(AbstractStatefulType statefulType,
72                        String JavaDoc name)
73     throws ConfigException
74   {
75     super(statefulType, name);
76   }
77
78   public PropertyField(AbstractStatefulType statefulType)
79   {
80     super(statefulType);
81   }
82
83   /**
84    * Sets the result type.
85    */

86   public void setType(Type type)
87   {
88     _type = type;
89   }
90
91   /**
92    * Sets the result type.
93    */

94   public Type getType()
95   {
96     return _type;
97   }
98
99   /**
100    * Returns the source type as
101    * entity or mapped-superclass.
102    */

103   public RelatedType getEntitySourceType()
104   {
105     return (RelatedType) getSourceType();
106   }
107
108   /**
109    * Returns the table containing the field's columns.
110    */

111   public Table getTable()
112   {
113     return getColumn().getTable();
114   }
115
116   /**
117    * Sets the column.
118    */

119   public void setColumn(Column column)
120   {
121     _column = column;
122   }
123
124   /**
125    * Gets the column.
126    */

127   public Column getColumn()
128   {
129     return _column;
130   }
131
132   /**
133    * Set true if the property should be saved on an insert.
134    */

135   public void setInsert(boolean isInsert)
136   {
137     _isInsert = isInsert;
138   }
139
140   /**
141    * Set true if the property should be saved on an update.
142    */

143   public void setUpdate(boolean isUpdate)
144   {
145     _isUpdate = isUpdate;
146   }
147
148   /**
149    * Initializes the property.
150    */

151   public void init()
152     throws ConfigException
153   {
154     super.init();
155
156     if (getColumn() == null)
157       throw new IllegalStateException JavaDoc(L.l("column must be set before init"));
158
159     // Embedded types have no id.
160
// Only entity or mapped-superclass types have id.
161
if (! (getSourceType() instanceof RelatedType))
162       return;
163
164     if (getEntitySourceType().getId() != null) {
165       // resolve any alias
166
for (AmberField field : getEntitySourceType().getId().getKeys()) {
167         if (field instanceof KeyManyToOneField) {
168           KeyManyToOneField key = (KeyManyToOneField) field;
169
170           for (ForeignColumn column : key.getLinkColumns().getColumns()) {
171             if (getColumn().getName().equals(column.getName()))
172               _aliasKey = key;
173           }
174         }
175       }
176     }
177   }
178
179   /**
180    * Returns the null value.
181    */

182   public String JavaDoc generateNull()
183   {
184     return getType().generateNull();
185   }
186
187   /**
188    * Returns the field name.
189    */

190   protected String JavaDoc getFieldName()
191   {
192     // jpa/0w01, jpa/0w10
193
if (getColumn() == null)
194       return "__amber_" + AbstractConfigIntrospector.toSqlName(getName());
195
196     return getColumn().getFieldName();
197   }
198
199   /**
200    * Generates the set property.
201    */

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

228   public void generateSetProperty(JavaWriter out)
229     throws IOException JavaDoc
230   {
231     if (! isFieldAccess() && (getGetterMethod() == null ||
232                               getSetterMethod() == null && ! isAbstract()))
233       return;
234
235     out.println();
236     out.println("public void " + getSetterName() + "(" + getJavaTypeName() + " v)");
237     out.println("{");
238     out.pushDepth();
239
240     int maskGroup = getLoadGroupIndex() / 64;
241     String JavaDoc loadVar = "__caucho_loadMask_" + maskGroup;
242
243     long mask = 1L << (getLoadGroupIndex() % 64);
244
245     // jpa/0gh0
246
if (getSourceType() instanceof EmbeddableType) {
247       out.println(generateSuperSetter("v") + ";");
248       out.popDepth();
249       out.println("}");
250       return;
251     }
252     else {
253       // jpa/0g06, jpa/0g0k
254
out.println("if (__caucho_session != null && __caucho_session.isInTransaction()) {");
255       out.println(" __caucho_load_" + maskGroup + "(__caucho_session);");
256       out.println(" __caucho_session.makeTransactional(this);");
257       out.println("}");
258       out.println();
259     }
260
261     if (! _isUpdate) {
262       out.println("if (__caucho_session == null)");
263       out.println(" " + generateSuperSetter("v") + ";");
264     }
265     else {
266       out.println(getJavaTypeName() + " oldValue = " + generateSuperGetter() + ";");
267
268       if (getJavaTypeName().equals("java.lang.String")) {
269         out.println("if ((oldValue == v || v != null && v.equals(oldValue)) && (" + loadVar + " & " + mask + "L) != 0L)");
270         out.println(" return;");
271       }
272       else {
273         out.println("if (oldValue == v && (" + loadVar + " & " + mask + "L) != 0)");
274         out.println(" return;");
275       }
276
277       out.println("try {");
278       out.pushDepth();
279       out.println(generateSuperSetter("v") + ";");
280       out.popDepth();
281       out.println("} catch (Exception e1) {");
282       out.pushDepth();
283
284       out.println("if (__caucho_session != null) {");
285       out.pushDepth();
286       out.println("try {");
287       out.println(" __caucho_session.rollback();");
288       out.println("} catch (java.sql.SQLException e2) {");
289       out.println(" throw new javax.persistence.PersistenceException(e2);");
290       out.println("}");
291       out.println();
292       out.println("throw new javax.persistence.PersistenceException(e1);");
293       out.popDepth();
294       out.println("}");
295
296       out.popDepth();
297       out.println("}");
298
299       int dirtyGroup = getIndex() / 64;
300       String JavaDoc dirtyVar = "__caucho_dirtyMask_" + dirtyGroup;
301
302       long dirtyMask = 1L << (getIndex() % 64);
303
304       out.println();
305       out.println("long oldMask = " + dirtyVar + ";");
306       out.println(dirtyVar + " |= " + dirtyMask + "L;");
307
308       out.println();
309       out.println("if (__caucho_session != null && oldMask == 0)");
310       out.println(" __caucho_session.update(this);");
311       out.println();
312       out.println("__caucho_increment_version();");
313     }
314
315     out.popDepth();
316     out.println("}");
317   }
318
319   /**
320    * Generates the select clause.
321    */

322   public String JavaDoc generateLoadSelect(Table table, String JavaDoc id)
323   {
324     if (getColumn().getTable() != table)
325       return null;
326     else
327       return generateSelect(id);
328   }
329
330   /**
331    * Generates the select clause.
332    */

333   public String JavaDoc generateSelect(String JavaDoc id)
334   {
335     return getColumn().generateSelect(id);
336   }
337
338   /**
339    * Generates the where clause.
340    */

341   public String JavaDoc generateWhere(String JavaDoc id)
342   {
343     return getColumn().generateSelect(id);
344   }
345
346   /**
347    * Generates the insert.
348    */

349   public void generateInsertColumns(ArrayList JavaDoc<String JavaDoc> columns)
350   {
351     if (_isInsert && _aliasKey == null)
352       columns.add(getColumn().getName());
353   }
354
355   /**
356    * Generates the update set clause
357    */

358   public void generateUpdate(CharBuffer sql)
359   {
360     if (_isUpdate && _aliasKey == null)
361       sql.append(getColumn().generateUpdateSet());
362     /*
363       sql.append(getColumn());
364       sql.append("=?");
365     */

366   }
367
368   /**
369    * Generates the set clause for the insert clause.
370    */

371   public void generateInsertSet(JavaWriter out, String JavaDoc pstmt,
372                                 String JavaDoc index, String JavaDoc obj)
373     throws IOException JavaDoc
374   {
375     if (_aliasKey != null) {
376     }
377     else if (_isInsert)
378       generateSet(out, pstmt, index, obj);
379     else if (getLoadGroupIndex() != 0) {
380       int groupIndex = getLoadGroupIndex();
381       int group = groupIndex / 64;
382       long groupMask = 1L << (groupIndex % 64);
383       out.println("__caucho_loadMask_" + group + " &= ~" + groupMask + "L;");
384     }
385   }
386
387   /**
388    * Generates the set clause for the insert clause.
389    */

390   public void generateUpdateSet(JavaWriter out, String JavaDoc pstmt,
391                                 String JavaDoc index, String JavaDoc obj)
392     throws IOException JavaDoc
393   {
394     if (_isUpdate && _aliasKey == null)
395       generateSet(out, pstmt, index, obj);
396   }
397
398   /**
399    * Generates the set clause.
400    */

401   public void generateSet(JavaWriter out, String JavaDoc pstmt,
402                           String JavaDoc index, String JavaDoc obj)
403     throws IOException JavaDoc
404   {
405     if (! isFieldAccess() && getGetterMethod() == null || _aliasKey != null)
406       return;
407
408     getColumn().generateSet(out, pstmt, index, generateGet(obj));
409   }
410
411   /**
412    * Generates loading code
413    */

414   public int generateLoad(JavaWriter out, String JavaDoc rs,
415                           String JavaDoc indexVar, int index)
416     throws IOException JavaDoc
417   {
418     if (_aliasKey != null)
419       return index;
420     /*
421       if (getSetterMethod() == null)
422       return index;
423     */

424
425     String JavaDoc var = "amber_ld" + index;
426
427     Type columnType;
428
429     // jpa/0w24
430
if (getColumn() == null)
431       columnType = getType();
432     else
433       columnType = getColumn().getType();
434
435     if (columnType instanceof ArrayType)
436       out.print(((ArrayType) columnType).getPrimitiveArrayTypeName());
437     else
438       out.print(getJavaTypeName());
439     out.print(" " + var + " = ");
440
441     // jpa/0w24
442
if (getColumn() == null)
443       index = getType().generateLoad(out, rs, indexVar, index);
444     else
445       index = getColumn().generateLoad(out, rs, indexVar, index);
446
447     out.println(";");
448
449     // jpa/0t17
450
if (columnType instanceof ArrayType) {
451       ArrayType arrayType = (ArrayType) columnType;
452       String JavaDoc primitiveType = arrayType.getPrimitiveArrayTypeName();
453       out.print(getJavaTypeName());
454       out.print(" " + var + "_temp = new ");
455       String JavaDoc instanceJavaType = arrayType.getJavaObjectTypeName();
456       out.println(instanceJavaType + "[" + var + ".length];");
457       out.println("for (int i=0; i < " + var + ".length; i++)");
458       out.print(" " + var + "_temp[i] = new ");
459       out.print(instanceJavaType);
460       out.println("(" + var + "[i]);");
461       out.println(generateSuperSetter(var + "_temp") + ";");
462     }
463     else
464       out.println(generateSuperSetter(var) + ";");
465
466     // out.println("__caucho_loadMask |= " + (1L << getIndex()) + "L;");
467

468     return index;
469   }
470
471   /**
472    * Creates the expression for the field.
473    */

474   public AmberExpr createExpr(QueryParser parser, PathExpr parent)
475   {
476     Column column;
477
478     if (parent instanceof EmbeddedExpr) {
479       column = ((EmbeddedExpr) parent).getColumnByFieldName(getName());
480     }
481     else
482       column = getColumn();
483
484     return new ColumnExpr(parent, column);
485   }
486 }
487
Popular Tags