KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > amber > gen > LoadGroupGenerator


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.gen;
31
32 import com.caucho.amber.table.LinkColumns;
33 import com.caucho.amber.table.Table;
34 import com.caucho.amber.type.EntityType;
35 import com.caucho.bytecode.JMethod;
36 import com.caucho.java.JavaWriter;
37 import com.caucho.java.gen.ClassComponent;
38 import com.caucho.util.L10N;
39
40 import java.io.IOException JavaDoc;
41 import java.util.ArrayList JavaDoc;
42
43 /**
44  * Generates the Java code for the wrapped object.
45  */

46 public class LoadGroupGenerator extends ClassComponent {
47   private static final L10N L = new L10N(LoadGroupGenerator.class);
48
49   private String JavaDoc _extClassName;
50   private EntityType _entityType;
51   private int _index;
52
53   public LoadGroupGenerator(String JavaDoc extClassName,
54                             EntityType entityType,
55                             int index)
56   {
57     _extClassName = extClassName;
58     _entityType = entityType;
59     _index = index;
60   }
61
62   /**
63    * Generates the load group.
64    */

65   public void generate(JavaWriter out)
66     throws IOException JavaDoc
67   {
68     out.println();
69     out.println("protected void __caucho_load_" + _index + "(com.caucho.amber.manager.AmberConnection aConn)");
70     out.println("{");
71     out.println(" __caucho_load_" + _index + "(aConn, null);");
72     out.println("}");
73
74     out.println();
75     out.println("protected void __caucho_load_" + _index + "(com.caucho.amber.manager.AmberConnection aConn, java.util.Map preloadedProperties)");
76     out.println("{");
77     out.pushDepth();
78
79     int group = _index / 64;
80     long mask = (1L << (_index % 64));
81
82     generateTransactionChecks(out, group, mask);
83
84     int min = 0;
85
86     if (_entityType.getParentType() == null)
87       min = _index;
88
89     // XXX: need to do another check for a long hierarchy and/or many-to-one
90
// if ((_entityType.getParentType() != null) &&
91
// (_index = _entityType.getParentType().getLoadGroupIndex() + 1)) {
92
// min = _entityType.getParentType().getLoadGroupIndex();
93
// }
94

95     int max = _index;
96
97     for (int i = min; i <= max; i++) {
98       out.println("__caucho_load_select_" + i + "(aConn, preloadedProperties);");
99     }
100
101     if (min <= max) {
102       // jpa/0g0k: only makes transactional if exists.
103
out.println();
104       out.println("if ((__caucho_loadMask_0 & 1L) != 0) {");
105       out.println(" aConn.makeTransactional(this);");
106       out.println("}");
107     }
108
109     // needs to be after load to prevent loop if toString() expects data
110
out.println();
111     out.println("if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
112     out.println(" __caucho_log.fine(\"amber loaded-" + _index + " \" + this);");
113
114     out.println();
115     out.println("aConn.postLoad(this);");
116
117     generateCallbacks(out, _entityType.getPostLoadCallbacks());
118
119     out.popDepth();
120     out.println("}");
121
122     if (_index == 0 && _entityType.getHasLoadCallback()) {
123       out.println();
124       out.println("protected void __caucho_load_callback() {}");
125     }
126
127     generateLoadSelect(out, group, mask);
128   }
129
130   private void generateTransactionChecks(JavaWriter out, int group, long mask)
131     throws IOException JavaDoc
132   {
133     // non-read-only entities must be reread in a transaction
134
if (! _entityType.isReadOnly()) {
135       out.println("if (aConn.isInTransaction()) {");
136
137       // deleted objects are not reloaded
138
out.println(" if (com.caucho.amber.entity.Entity.P_DELETING <= __caucho_state) {");
139       out.println(" return;");
140       out.println(" }");
141
142       // from non-transactional to transactional
143
out.println(" else if (__caucho_state < com.caucho.amber.entity.Entity.P_TRANSACTIONAL) {");
144       out.println(" int state = __caucho_state;");
145
146       out.println(" __caucho_state = com.caucho.amber.entity.Entity.P_TRANSACTIONAL;");
147
148       // XXX: ejb/0d01 (create issue?)
149
// jpa/0g0k: see __caucho_load_select
150
// out.println(" aConn.makeTransactional(this);");
151
// out.println(" if ((state > 0) && ((__caucho_loadMask_" + group + " & " + mask + "L) != 0))");
152
// out.println(" return;");
153
out.println();
154
155       int loadCount = _entityType.getLoadGroupIndex();
156       for (int i = 0; i <= loadCount / 64; i++) {
157         out.println(" __caucho_loadMask_" + i + " = 0;");
158       }
159       int dirtyCount = _entityType.getDirtyIndex();
160       for (int i = 0; i <= dirtyCount / 64; i++) {
161         out.println(" __caucho_dirtyMask_" + i + " = 0;");
162       }
163
164       out.println(" }");
165       // ejb/0d01 - already loaded in the transaction
166
out.println(" else if ((__caucho_loadMask_" + group + " & " + mask + "L) != 0)");
167       out.println(" return;");
168       out.println("}");
169       out.print("else ");
170     }
171
172     out.println("if ((__caucho_loadMask_" + group + " & " + mask + "L) != 0)");
173     out.println(" return;");
174
175     // XXX: the load doesn't cover other load groups
176
out.println("else if (__caucho_item != null) {");
177     out.pushDepth();
178     out.println(_extClassName + " item = (" + _extClassName + ") __caucho_item.getEntity();");
179
180     out.println("item.__caucho_load_" + _index + "(aConn);");
181
182     _entityType.generateCopyLoadObject(out, "super", "item", _index);
183
184     // out.println("__caucho_loadMask_" + group + " |= " + mask + "L;");
185
out.println("__caucho_loadMask_" + group + " |= item.__caucho_loadMask_" + group + ";"); // mask + "L;");
186

187     out.println();
188     out.println("return;");
189
190     out.popDepth();
191     out.println("}");
192
193     out.println();
194   }
195
196   private void generateLoadSelect(JavaWriter out, int group, long mask)
197     throws IOException JavaDoc
198   {
199     out.println();
200     out.println("protected void __caucho_load_select_" + _index + "(com.caucho.amber.manager.AmberConnection aConn, java.util.Map preloadedProperties)");
201     out.println("{");
202     out.pushDepth();
203
204     out.println("try {");
205     out.pushDepth();
206
207     Table table = _entityType.getTable();
208
209     String JavaDoc from = null;
210     String JavaDoc select = null;
211     String JavaDoc where = null;
212
213     String JavaDoc subSelect = _entityType.generateLoadSelect(table, "o", _index);
214     Table mainTable = null;
215     String JavaDoc tableName = null;
216
217     if (subSelect != null) {
218       select = subSelect;
219
220       from = table.getName() + " o";
221       where = _entityType.getId().generateMatchArgWhere("o");
222
223       mainTable = table;
224       tableName = "o";
225     }
226
227     ArrayList JavaDoc<Table> subTables = _entityType.getSecondaryTables();
228
229     for (int i = 0; i < subTables.size(); i++) {
230       Table subTable = subTables.get(i);
231
232       subSelect = _entityType.generateLoadSelect(subTable, "o" + i, _index);
233
234       if (subSelect == null)
235         continue;
236
237       if (select != null)
238         select = select + ", " + subSelect;
239       else
240         select = subSelect;
241
242       if (from != null)
243         from = from + ", " + subTable.getName() + " o" + i;
244       else
245         from = subTable.getName() + " o" + i;
246
247       if (where != null) {
248         LinkColumns link = subTable.getDependentIdLink();
249
250         where = where + " and " + link.generateJoin("o" + i, "o");
251       }
252       else
253         throw new IllegalStateException JavaDoc();
254     }
255
256     if (select == null)
257       select = "1";
258
259     if (where == null) {
260       from = table.getName() + " o";
261
262       where = _entityType.getId().generateMatchArgWhere("o");
263     }
264
265     String JavaDoc sql = "select " + select + " from " + from + " where " + where;
266
267     out.println("String sql = \"" + sql + "\";");
268
269     out.println();
270     out.println("java.sql.PreparedStatement pstmt = aConn.prepareStatement(sql);");
271
272     out.println("int index = 1;");
273     _entityType.getId().generateSet(out, "pstmt", "index", "super");
274
275     out.println();
276     out.println("java.sql.ResultSet rs = pstmt.executeQuery();");
277
278     out.println("if (rs.next()) {");
279     out.pushDepth();
280
281     _entityType.generateLoad(out, "rs", "", 1, _index);
282     out.println("__caucho_loadMask_" + group + " |= " + mask + "L;");
283
284     _entityType.generateLoadEager(out, "rs", "", 1, _index);
285
286     // commented out: jpa/0r01
287
// ArrayList<JMethod> postLoadCallbacks = _entityType.getPostLoadCallbacks();
288
// if (postLoadCallbacks.size() > 0 && _index == 0) {
289
// out.println("if (__caucho_state == com.caucho.amber.entity.Entity.P_TRANSACTIONAL) {");
290
// out.pushDepth();
291
// generateCallbacks(out, postLoadCallbacks);
292
// out.popDepth();
293
// out.println("}");
294
// }
295

296     if (_entityType.getHasLoadCallback())
297       out.println("__caucho_load_callback();");
298
299     out.popDepth();
300     out.println("}");
301     out.println("else {");
302     out.println(" rs.close();");
303
304     String JavaDoc errorString = ("(\"amber load: no matching object " +
305                           _entityType.getName() + "[\" + __caucho_getPrimaryKey() + \"]\")");
306
307     out.println(" throw new com.caucho.amber.AmberObjectNotFoundException(" + errorString + ");");
308     out.println("}");
309
310     out.popDepth();
311     out.println("} catch (RuntimeException e) {");
312     out.println(" throw e;");
313     out.println("} catch (Exception e) {");
314     out.println(" throw new com.caucho.amber.AmberRuntimeException(e);");
315     out.println("}");
316
317     out.popDepth();
318     out.println("}");
319   }
320
321   private void generateCallbacks(JavaWriter out, ArrayList JavaDoc<JMethod> callbacks)
322     throws IOException JavaDoc
323   {
324     if (callbacks.size() == 0)
325       return;
326
327     out.println();
328     for (JMethod method : callbacks) {
329       out.println(method.getName() + "();");
330     }
331   }
332 }
333
Popular Tags