KickJava   Java API By Example, From Geeks To Geeks.

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


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.field.*;
33 import com.caucho.amber.table.Column;
34 import com.caucho.amber.table.Table;
35 import com.caucho.amber.type.EntityType;
36 import com.caucho.amber.type.RelatedType;
37 import com.caucho.amber.type.SubEntityType;
38 import com.caucho.amber.type.Type;
39 import com.caucho.bytecode.*;
40 import com.caucho.java.JavaWriter;
41 import com.caucho.java.gen.ClassComponent;
42 import com.caucho.loader.Environment;
43 import com.caucho.util.L10N;
44 import com.caucho.vfs.PersistentDependency;
45
46 import javax.persistence.CascadeType;
47 import java.io.IOException JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.HashSet JavaDoc;
50
51 /**
52  * Generates the Java code for the wrapped object.
53  */

54 public class EntityComponent extends ClassComponent {
55   private static final L10N L = new L10N(EntityComponent.class);
56
57   private String JavaDoc _baseClassName;
58   private String JavaDoc _extClassName;
59
60   private EntityType _entityType;
61
62   private ArrayList JavaDoc<PersistentDependency> _dependencies =
63     new ArrayList JavaDoc<PersistentDependency>();
64
65   public EntityComponent()
66   {
67   }
68
69   /**
70    * Sets the bean info for the generator
71    */

72   public void setEntityType(EntityType entityType)
73   {
74     _entityType = entityType;
75
76     _dependencies.addAll(entityType.getDependencies());
77
78     for (int i = 0; i < _dependencies.size(); i++)
79       Environment.addDependency(_dependencies.get(i));
80   }
81
82   /**
83    * Sets the base class name
84    */

85   public void setBaseClassName(String JavaDoc baseClassName)
86   {
87     _baseClassName = baseClassName;
88   }
89
90   /**
91    * Gets the base class name
92    */

93   public String JavaDoc getBaseClassName()
94   {
95     return _baseClassName;
96   }
97
98   /**
99    * Sets the ext class name
100    */

101   public void setExtClassName(String JavaDoc extClassName)
102   {
103     _extClassName = extClassName;
104   }
105
106   /**
107    * Sets the ext class name
108    */

109   public String JavaDoc getClassName()
110   {
111     return _extClassName;
112   }
113
114   /**
115    * Get bean class name.
116    */

117   public String JavaDoc getBeanClassName()
118   {
119     // return _entityType.getBeanClass().getName();
120
return _baseClassName;
121   }
122
123   /**
124    * Returns the dependencies.
125    */

126   public ArrayList JavaDoc<PersistentDependency> getDependencies()
127   {
128     return _dependencies;
129   }
130
131   /**
132    * Starts generation of the Java code
133    */

134   public void generate(JavaWriter out)
135     throws IOException JavaDoc
136   {
137     try {
138       generateHeader(out);
139
140       generateInit(out);
141
142       HashSet JavaDoc<Object JavaDoc> completedSet = new HashSet JavaDoc<Object JavaDoc>();
143
144       generatePrologue(out, completedSet);
145
146       generateGetEntityType(out);
147
148       if (_entityType.getParentType() == null)
149         generateGetEntityState(out);
150
151       generateMatch(out);
152
153       generateFields(out);
154
155       generateMethods(out);
156
157       generateDetach(out);
158
159       generateLoad(out);
160
161       int min = 0;
162       if (_entityType.getParentType() != null)
163         min = _entityType.getParentType().getLoadGroupIndex() + 1;
164       int max = _entityType.getLoadGroupIndex();
165
166       for (int i = min; i <= max; i++)
167         generateLoadGroup(out, i);
168
169       generateResultSetLoad(out);
170
171       generateSetQuery(out);
172
173       // generateLoadFromObject();
174

175       // generateCopy();
176

177       generateCopy(out);
178
179       generateMakePersistent(out);
180
181       generateCascadePersist(out);
182
183       generateCascadeRemove(out);
184
185       generateCreate(out);
186
187       generateDelete(out);
188
189       generateDeleteForeign(out);
190
191       generateFlush(out);
192
193       generateAfterCommit(out);
194
195       generateAfterRollback(out);
196
197       generateHome(out);
198
199       generateInternals(out);
200
201       // printDependList(out, _dependencies);
202
} catch (IOException JavaDoc e) {
203       throw e;
204     }
205   }
206
207   /**
208    * Generates the class header for the generated code.
209    */

210   private void generateHeader(JavaWriter out)
211     throws IOException JavaDoc
212   {
213     out.println("/*");
214     out.println(" * Generated by Resin Amber");
215     out.println(" * " + com.caucho.Version.VERSION);
216     out.println(" */");
217     out.print("private static final java.util.logging.Logger __caucho_log = ");
218     out.println("java.util.logging.Logger.getLogger(\"" + getBeanClassName() + "\");");
219
220     if (_entityType.getParentType() == null) {
221       out.println();
222       out.println("protected transient com.caucho.amber.type.EntityType __caucho_home;");
223       out.println("public transient com.caucho.amber.entity.EntityItem __caucho_item;");
224       out.println("protected transient com.caucho.amber.manager.AmberConnection __caucho_session;");
225       out.println("protected transient int __caucho_state;");
226
227       int loadCount = _entityType.getLoadGroupIndex();
228       for (int i = 0; i <= loadCount / 64; i++) {
229         out.println("protected transient long __caucho_loadMask_" + i + ";");
230       }
231
232       int dirtyCount = _entityType.getDirtyIndex();
233
234       for (int i = 0; i <= dirtyCount / 64; i++) {
235         out.println("protected transient long __caucho_dirtyMask_" + i + ";");
236         out.println("protected transient long __caucho_updateMask_" + i + ";");
237       }
238
239       out.println("protected transient boolean __caucho_inc_version;");
240     }
241   }
242
243   /**
244    * Generates the init generated code.
245    */

246   private void generateInit(JavaWriter out)
247     throws IOException JavaDoc
248   {
249     if (_entityType.getParentType() != null)
250       return;
251
252     // XXX: needs to handle this with subclasses
253
// but there is an issue in the enhancer fixup
254
// removing the "super." call.
255
/*
256       out.println();
257       out.println("public void __caucho_postConstructor()");
258       out.println("{");
259       out.pushDepth();
260
261       ArrayList<AmberField> fields = _entityType.getFields();
262
263       for (int i = 0; i < fields.size(); i++) {
264       AmberField field = fields.get(i);
265
266       if (field instanceof AbstractField) {
267       AbstractField f = (AbstractField) field;
268       f.generatePostConstructor(out);
269       }
270       }
271
272       out.popDepth();
273       out.println("}");
274     */

275
276     String JavaDoc className = getClassName();
277     int p = className.lastIndexOf('.');
278     if (p > 0)
279       className = className.substring(p + 1);
280
281     ArrayList JavaDoc<AmberField> fields = _entityType.getFields();
282
283     for (JMethod ctor : _entityType.getBeanClass().getConstructors()) {
284       out.println();
285       // XXX: s/b actual access type?
286
out.print("public ");
287
288       out.print(className);
289       out.print("(");
290
291       JClass []args = ctor.getParameterTypes();
292       for (int i = 0; i < args.length; i++) {
293         if (i != 0)
294           out.print(", ");
295
296         out.print(args[i].getPrintName());
297         out.print(" a" + i);
298       }
299       out.println(")");
300       out.println("{");
301       out.pushDepth();
302
303       out.print("super(");
304       for (int i = 0; i < args.length; i++) {
305         if (i != 0)
306           out.print(", ");
307
308         out.print("a" + i);
309       }
310       out.println(");");
311
312       for (AmberField field : fields) {
313         field.generatePostConstructor(out);
314       }
315
316       out.popDepth();
317       out.println("}");
318     }
319
320     Id id = _entityType.getId();
321
322     if (id == null)
323       throw new IllegalStateException JavaDoc(L.l("`{0}' is missing a key.",
324                                           _entityType.getName()));
325
326     // ejb/0623 as a negative test.
327
if (id instanceof CompositeId) {
328       // jpa/0u21
329
out.println();
330       out.println("private " + id.getForeignTypeName() + " __caucho_compound_key = new " + id.getForeignTypeName() + "();");
331     }
332
333     out.println();
334     out.println("public void __caucho_setPrimaryKey(Object key)");
335     out.println("{");
336     out.pushDepth();
337
338     id.generateSet(out, id.generateCastFromObject("key"));
339
340     out.popDepth();
341     out.println("}");
342
343     out.println();
344     out.println("public Object __caucho_getPrimaryKey()");
345     out.println("{");
346     out.pushDepth();
347
348     out.print("return ");
349     out.print(id.toObject(id.generateGetProperty("super")));
350     out.println(";");
351
352     out.popDepth();
353     out.println("}");
354
355     /*
356       println();
357       println("public com.caucho.amber.entity.EntityItem __caucho_getItem()");
358       println("{");
359       pushDepth();
360
361       println("return __caucho_item;");
362
363       popDepth();
364       println("}");
365
366       println();
367       println("public void __caucho_setItem(com.caucho.amber.entity.EntityItem item)");
368       println("{");
369       pushDepth();
370
371       println("__caucho_item = item;");
372
373       popDepth();
374       println("}");
375     */

376
377     out.println();
378     out.println("public void __caucho_setConnection(com.caucho.amber.manager.AmberConnection aConn)");
379     out.println("{");
380     out.pushDepth();
381
382     out.println("__caucho_session = aConn;");
383
384     out.popDepth();
385     out.println("}");
386
387     out.println();
388     out.println("public com.caucho.amber.manager.AmberConnection __caucho_getConnection()");
389     out.println("{");
390     out.pushDepth();
391
392     out.println("return __caucho_session;");
393
394     out.popDepth();
395     out.println("}");
396
397     generateExpire(out);
398   }
399
400   /**
401    * Generates the expire code.
402    */

403   private void generateExpire(JavaWriter out)
404     throws IOException JavaDoc
405   {
406     out.println();
407     out.println("public void __caucho_expire()");
408     out.println("{");
409
410     int loadCount = _entityType.getLoadGroupIndex();
411     for (int i = 0; i <= loadCount / 64; i++) {
412       out.println(" __caucho_loadMask_" + i + " = 0L;");
413     }
414
415     _entityType.generateExpire(out);
416
417     out.println("}");
418   }
419
420   /**
421    * Generates the match code.
422    */

423   private void generateMatch(JavaWriter out)
424     throws IOException JavaDoc
425   {
426     if (_entityType.getParentType() != null)
427       return;
428
429     out.println();
430     out.println("public boolean __caucho_match(String className, Object key)");
431     out.println("{");
432     out.pushDepth();
433
434     /*
435       out.println("if (! (" + getBeanClassName() + ".class.isAssignableFrom(cl)))");
436       out.println(" return false;");
437     */

438     out.println("if (! (\"" + getBeanClassName() + "\".equals(className)))");
439     out.println(" return false;");
440     out.println("else {");
441     out.pushDepth();
442
443     out.println("try {");
444     out.pushDepth();
445     Id id = _entityType.getId();
446     id.generateMatch(out, id.generateCastFromObject("key"));
447     out.popDepth();
448     out.println("} catch (ClassCastException e) {");
449     out.println(" throw new IllegalArgumentException(\"Primary key type is incorrect: '\"+key.getClass().getName()+\"'\");");
450     out.println("}");
451
452     out.popDepth();
453     out.println("}");
454
455     out.popDepth();
456     out.println("}");
457   }
458
459   /**
460    * Generates the prologue.
461    */

462   private void generatePrologue(JavaWriter out, HashSet JavaDoc<Object JavaDoc> completedSet)
463     throws IOException JavaDoc
464   {
465     for (Column column : _entityType.getColumns()) {
466       column.generatePrologue(out);
467     }
468
469     Id id = _entityType.getId();
470
471     if (id != null)
472       id.generatePrologue(out, completedSet);
473
474     ArrayList JavaDoc<AmberField> fields = _entityType.getFields();
475
476     for (int i = 0; i < fields.size(); i++) {
477       AmberField prop = fields.get(i);
478
479       prop.generatePrologue(out, completedSet);
480     }
481   }
482
483   /**
484    * Generates the entity type
485    */

486   private void generateGetEntityType(JavaWriter out)
487     throws IOException JavaDoc
488   {
489     out.println();
490     out.println("public com.caucho.amber.type.EntityType __caucho_getEntityType()");
491     out.println("{");
492     out.pushDepth();
493
494     out.println("return __caucho_home;");
495
496     out.popDepth();
497     out.println("}");
498   }
499
500   /**
501    * Generates the get entity state
502    */

503   private void generateGetEntityState(JavaWriter out)
504     throws IOException JavaDoc
505   {
506     out.println();
507     out.println("public int __caucho_getEntityState()");
508     out.println("{");
509     out.pushDepth();
510
511     out.println("return __caucho_state;");
512
513     out.popDepth();
514     out.println("}");
515   }
516
517   /**
518    * Generates the fields.
519    */

520   private void generateFields(JavaWriter out)
521     throws IOException JavaDoc
522   {
523     ArrayList JavaDoc<AmberField> fields = _entityType.getFields();
524
525     for (int i = 0; i < fields.size(); i++) {
526       AmberField prop = fields.get(i);
527
528       prop.generateSuperGetter(out);
529       prop.generateGetProperty(out);
530
531       prop.generateSuperSetter(out);
532       prop.generateSetProperty(out);
533     }
534   }
535
536   /**
537    * Generates the stub methods (needed for EJB)
538    */

539   private void generateMethods(JavaWriter out)
540     throws IOException JavaDoc
541   {
542     for (StubMethod method : _entityType.getMethods()) {
543       method.generate(out);
544     }
545   }
546
547   /**
548    * Generates the load
549    */

550   private void generateLoad(JavaWriter out)
551     throws IOException JavaDoc
552   {
553     // commented out: jpa/0l03
554
// if (_entityType.getParentType() != null)
555
// return;
556

557     if (_entityType.getParentType() == null) {
558       out.println();
559       out.println("public boolean __caucho_makePersistent(com.caucho.amber.manager.AmberConnection aConn, com.caucho.amber.type.EntityType home)");
560       out.println(" throws java.sql.SQLException");
561       out.println("{");
562       out.pushDepth();
563
564       out.println("__caucho_session = aConn;");
565       out.println("if (home != null)");
566       out.println(" __caucho_home = home;");
567
568       out.println("__caucho_state = com.caucho.amber.entity.Entity.P_NON_TRANSACTIONAL;");
569
570       int loadCount = _entityType.getLoadGroupIndex();
571       for (int i = 0; i <= loadCount / 64; i++) {
572         out.println(" __caucho_loadMask_" + i + " = 0L;");
573       }
574
575       int dirtyCount = _entityType.getDirtyIndex();
576       for (int i = 0; i <= dirtyCount / 64; i++) {
577         out.println(" __caucho_dirtyMask_" + i + " = 0L;");
578         out.println(" __caucho_updateMask_" + i + " = 0L;");
579       }
580
581       out.println();
582       out.println("return true;");
583
584       out.popDepth();
585       out.println("}");
586     }
587
588     int index = _entityType.getLoadGroupIndex();
589
590     boolean hasLoad = (_entityType.getFields().size() > 0);
591
592     if (_entityType.getParentType() == null) {
593       index = 0;
594       hasLoad = hasLoad || (_entityType.getId() != null);
595     }
596
597     out.println();
598     out.println("public void __caucho_retrieve(com.caucho.amber.manager.AmberConnection aConn)");
599     out.println(" throws java.sql.SQLException");
600     out.println("{");
601
602     if (hasLoad)
603       out.println(" __caucho_load_" + index + "(aConn);");
604
605     out.println("}");
606
607     out.println();
608     out.println("public void __caucho_retrieve(com.caucho.amber.manager.AmberConnection aConn, java.util.Map preloadedProperties)");
609     out.println(" throws java.sql.SQLException");
610     out.println("{");
611
612     if (hasLoad)
613       out.println(" __caucho_load_" + index + "(aConn, preloadedProperties);");
614
615     out.println("}");
616   }
617
618   /**
619    * Generates the detach
620    */

621   private void generateDetach(JavaWriter out)
622     throws IOException JavaDoc
623   {
624     if (_entityType.getParentType() != null)
625       return;
626
627     out.println();
628     out.println("public void __caucho_detach()");
629     out.println("{");
630     out.pushDepth();
631
632     out.println("__caucho_session = null;");
633
634     // jpa/0x00
635
// out.println("__caucho_home = null;");
636

637     out.println("__caucho_state = com.caucho.amber.entity.Entity.TRANSIENT;");
638
639     out.popDepth();
640     out.println("}");
641   }
642
643   /**
644    * Generates the load group.
645    */

646   private void generateLoadGroup(JavaWriter out, int groupIndex)
647     throws IOException JavaDoc
648   {
649     if (_entityType.hasLoadGroup(groupIndex)) {
650       new LoadGroupGenerator(_extClassName, _entityType, groupIndex).generate(out);
651     }
652   }
653
654   /**
655    * Generates the load
656    */

657   private void generateResultSetLoad(JavaWriter out)
658     throws IOException JavaDoc
659   {
660     if (_entityType.getParentType() != null)
661       return;
662
663     out.println();
664     out.println("public int __caucho_load(com.caucho.amber.manager.AmberConnection aConn, java.sql.ResultSet rs, int index)");
665     out.println(" throws java.sql.SQLException");
666     out.println("{");
667     out.pushDepth();
668
669     int index = _entityType.generateLoad(out, "rs", "index", 0, 0);
670
671     out.println("__caucho_loadMask_0 |= 1L;");
672
673     int dirtyCount = _entityType.getDirtyIndex();
674
675     for (int i = 0; i <= dirtyCount / 64; i++) {
676       out.println("__caucho_dirtyMask_" + i + " = 0;");
677
678       // ejb/0645
679
// out.println("__caucho_updateMask_" + i + " = 0;");
680
}
681
682     out.println();
683     out.println("if (__caucho_state == com.caucho.amber.entity.Entity.P_TRANSACTIONAL || __caucho_state == com.caucho.amber.entity.Entity.P_NEW) {");
684     out.println("}");
685     out.println("else if (__caucho_session == null ||");
686     out.println(" ! __caucho_session.isInTransaction()) {");
687     out.println(" __caucho_state = com.caucho.amber.entity.Entity.P_NON_TRANSACTIONAL;");
688     out.println(" if (__caucho_item != null)");
689     out.println(" __caucho_item.save(this);");
690     out.println("}");
691     out.println("else {");
692     out.println(" __caucho_state = com.caucho.amber.entity.Entity.P_TRANSACTIONAL;");
693     out.println(" aConn.makeTransactional(this);");
694     out.println("}");
695
696     if (_entityType.getHasLoadCallback()) {
697       out.println();
698       out.println("__caucho_load_callback();");
699     }
700
701     out.println("return " + index + ";");
702     out.popDepth();
703     out.println("}");
704   }
705
706   /**
707    * Generates the load
708    */

709   private void generateSetQuery(JavaWriter out)
710     throws IOException JavaDoc
711   {
712     if (_entityType.getParentType() != null)
713       return;
714
715     out.println();
716     out.println("public void __caucho_setKey(java.sql.PreparedStatement pstmt, int index)");
717     out.println(" throws java.sql.SQLException");
718     out.println("{");
719     out.pushDepth();
720
721     _entityType.generateSet(out, "pstmt", "index", "super");
722
723     out.popDepth();
724     out.println("}");
725   }
726
727   /**
728    * Generates the flush
729    */

730   private void generateFlush(JavaWriter out)
731     throws IOException JavaDoc
732   {
733     out.println();
734     out.println("public void __caucho_increment_version()");
735     out.println("{");
736     out.pushDepth();
737
738     out.println("if (__caucho_inc_version)");
739     out.println(" return;");
740     out.println();
741     out.println("__caucho_inc_version = true;");
742
743     VersionField version = _entityType.getVersionField();
744
745     if (version != null)
746       version.generateIncrementVersion(out);
747
748     out.popDepth();
749     out.println("}");
750
751     out.println();
752     out.println("protected void __caucho_flush_callback()");
753     out.println(" throws java.sql.SQLException");
754     out.println("{");
755     out.println("}");
756
757     out.println();
758     out.println("public boolean __caucho_flush()");
759     out.println(" throws java.sql.SQLException");
760     out.println("{");
761     out.pushDepth();
762
763     out.println("if (__caucho_session == null)");
764     out.println(" return false;");
765     out.println();
766
767     ArrayList JavaDoc<AmberField> fields = _entityType.getFields();
768
769     for (int i = 0; i < fields.size(); i++) {
770       AmberField field = fields.get(i);
771
772       if (field.isCascadable()) {
773         CascadableField cascadable = (CascadableField) field;
774
775         cascadable.generateFlushCheck(out);
776
777         out.println();
778       }
779     }
780
781     out.println();
782     out.println("if (__caucho_state == com.caucho.amber.entity.Entity.P_DELETED) {");
783     out.println(" __caucho_delete_int();");
784     out.println(" return true;");
785     out.println("}");
786     out.println();
787     out.println("boolean isDirty = false;");
788
789     int dirtyCount = _entityType.getDirtyIndex();
790
791     for (int i = 0; i <= dirtyCount / 64; i++) {
792       out.println("long mask_" + i + " = __caucho_dirtyMask_" + i + ";");
793       out.println("__caucho_dirtyMask_" + i + " = 0L;");
794       out.println("__caucho_updateMask_" + i + " |= mask_" + i + ";");
795
796       out.println();
797       out.println("if (mask_" + i + " != 0L)");
798       out.println(" isDirty = true;");
799     }
800
801     out.println("__caucho_session.preUpdate(this);");
802
803     generateCallbacks(out, "this", _entityType.getPreUpdateCallbacks());
804
805     out.println();
806     out.println("__caucho_flush_callback();");
807
808     out.println();
809
810     // if (version == null)
811
out.println("if (! isDirty)");
812     // else {
813
// jpa/0x02
814
// out.println("if (! (isDirty || " + version.generateIsNull() + "))");
815
// }
816
out.println(" return true;");
817
818     out.println("com.caucho.util.CharBuffer cb = new com.caucho.util.CharBuffer();");
819
820     out.println("__caucho_home.generateUpdateSQLPrefix(cb);");
821
822     out.println("boolean isFirst = true;");
823
824     for (int i = 0; i <= dirtyCount / 64; i++) {
825       // jpa/0x02 is a negative test.
826
if (i != 0 || version == null) {
827         out.println("if (mask_" + i + " != 0L)");
828         out.print(" ");
829       }
830
831       out.println("isFirst = __caucho_home.generateUpdateSQLComponent(cb, " + i + ", mask_" + i + ", isFirst);");
832     }
833     out.println("__caucho_home.generateUpdateSQLSuffix(cb);");
834
835     out.println("java.sql.PreparedStatement pstmt = __caucho_session.prepareStatement(cb.toString());");
836
837     out.println("int index = 1;");
838
839     for (int i = 0; i < fields.size(); i++) {
840       AmberField field = fields.get(i);
841
842       field.generateUpdate(out, "mask", "pstmt", "index");
843     }
844
845     out.println();
846     _entityType.getId().generateSet(out, "pstmt", "index");
847
848     if (version != null) {
849       out.println();
850       version.generateSet(out, "pstmt", "index");
851     }
852
853     out.println();
854     out.println("int updateCount = pstmt.executeUpdate();");
855     out.println();
856
857     if (version != null) {
858       out.println("if (updateCount == 0) {");
859       out.println(" throw new javax.persistence.OptimisticLockException(this);");
860       out.println("} else {");
861       out.pushDepth();
862       String JavaDoc value = version.generateGet("super");
863       Type type = version.getColumn().getType();
864       out.println(version.generateSuperSetter(type.generateIncrementVersion(value)) + ";");
865       out.popDepth();
866       out.println("}");
867       out.println();
868     }
869
870     out.println("__caucho_session.postUpdate(this);");
871
872     generateCallbacks(out, "this", _entityType.getPostUpdateCallbacks());
873
874     out.println();
875     out.println("if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
876     out.println(" __caucho_log.fine(\"amber update \" + this.getClass().getName() + \" - PK: \" + __caucho_getPrimaryKey());");
877
878     out.println();
879     out.println("__caucho_inc_version = false;");
880     out.println();
881
882     out.println("return false;");
883     out.popDepth();
884     out.println("}");
885   }
886
887   /**
888    * Generates the update
889    */

890   private void generateFlushUpdate(JavaWriter out)
891     throws IOException JavaDoc
892   {
893     out.println();
894     out.println("protected void __caucho_flushUpdate(long mask, com.caucho.amber.type.EntityType home)");
895     out.println(" throws java.sql.SQLException");
896     out.println("{");
897     out.pushDepth();
898
899     if (_entityType.getParentType() != null) {
900       out.println("super.__caucho_flushUpdate(mask, home.getParentType());");
901     }
902
903     EntityType type = _entityType;
904
905     out.println("String sql = home.generateUpdateSQL(mask);");
906
907     out.println("if (sql != null) {");
908     out.pushDepth();
909
910     out.println("java.sql.PreparedStatement pstmt = __caucho_session.prepareStatement(sql);");
911
912     out.println("int index = 1;");
913
914     ArrayList JavaDoc<AmberField> fields = _entityType.getFields();
915     for (int i = 0; i < fields.size(); i++) {
916       AmberField field = fields.get(i);
917
918       field.generateUpdate(out, "mask", "pstmt", "index");
919     }
920
921     out.println();
922     _entityType.getId().generateSet(out, "pstmt", "index");
923
924     out.println();
925     out.println("pstmt.executeUpdate();");
926
927     out.println();
928     out.println("if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
929     out.println(" __caucho_log.fine(\"amber update \" + this.getClass().getName() + \" - PK: \" + __caucho_getPrimaryKey());");
930
931     // println();
932
// println("pstmt.close();");
933

934     out.popDepth();
935     out.println("}");
936
937     out.popDepth();
938     out.println("}");
939   }
940
941   /**
942    * Generates the after-commit
943    */

944   private void generateAfterCommit(JavaWriter out)
945     throws IOException JavaDoc
946   {
947     // XXX: needs to handle this with subclasses
948
// but there is an issue in the enhancer fixup
949
// removing the "super." call.
950
// if (_entityType.getParentType() != null) {
951
// out.println();
952
// out.println("public void __caucho_super_afterCommit()");
953
// out.println("{");
954
// out.println(" super.__caucho_afterCommit();");
955
// out.println("}");
956
// }
957

958     out.println();
959     out.println("public void __caucho_afterCommit()");
960     out.println("{");
961     out.pushDepth();
962
963     out.println("int state = __caucho_state;");
964     int dirtyCount = _entityType.getDirtyIndex();
965     for (int i = 0; i <= dirtyCount / 64; i++) {
966       out.println("long updateMask_" + i + " = __caucho_updateMask_" + i + ";");
967     }
968
969     // XXX: there is an issue in the enhancer fixup
970
// replacing the super but it should not in this case.
971
// if (_entityType.getParentType() != null) {
972
// out.println();
973
// out.println("__caucho_super_afterCommit();");
974
// }
975

976     out.println();
977     out.println("__caucho_state = com.caucho.amber.entity.Entity.P_NON_TRANSACTIONAL;");
978
979     for (int i = 0; i <= dirtyCount / 64; i++) {
980       out.println("__caucho_updateMask_" + i + " = 0L;");
981     }
982
983     out.print("if (updateMask_0 != 0L");
984     for (int i = 1; i <= dirtyCount / 64; i++)
985       out.print(" || updateMask_" + i + " != 0L");
986     out.println(")");
987     out.println(" __caucho_session.update(this);");
988
989     out.println("if (__caucho_item != null) {");
990     out.pushDepth();
991
992     out.println(_extClassName + " item = (" + _extClassName + ") __caucho_item.getEntity();");
993
994     if (_entityType.getParentType() != null) {
995       // if loaded in transaction, then copy results
996
// ejb/0a06, ejb/0893
997
out.println("if ((__caucho_loadMask_0 & 1L) != 0) {");
998       out.pushDepth();
999       out.println("item.__caucho_loadMask_0 = 1L;");
1000
1001      _entityType.generateCopyLoadObject(out, "item", "super", 0);
1002    }
1003
1004    for (int i = 1; i <= _entityType.getLoadGroupIndex(); i++) {
1005      String JavaDoc loadVar = "__caucho_loadMask_" + (i / 64);
1006      long mask = (1L << (i % 64));
1007
1008      // jpa/0l02: if (_entityType.isLoadGroupOwnedByType(i)) {
1009
out.println("if ((" + loadVar + " & " + mask + "L) != 0) {");
1010      out.pushDepth();
1011
1012      _entityType.generateCopyLoadObject(out, "item", "super", i);
1013
1014      out.println("item." + loadVar + " |= " + mask + "L;");
1015
1016      out.popDepth();
1017      out.println("}");
1018      //}
1019
}
1020
1021    if (_entityType.getParentType() != null) {
1022      out.popDepth();
1023      out.println("}");
1024    }
1025
1026    for (int i = 0; i < _entityType.getDirtyIndex(); i++) {
1027      int group = i / 64;
1028      long mask = (1L << (i % 64));
1029
1030      if (_entityType.isDirtyIndexOwnedByType(i)) {
1031        out.println("if ((updateMask_" + group + " & " + mask + "L) != 0) {");
1032        out.pushDepth();
1033
1034        _entityType.generateCopyUpdateObject(out, "item", "super", i);
1035
1036        out.popDepth();
1037        out.println("}");
1038      }
1039    }
1040
1041    out.popDepth();
1042    out.println("}");
1043
1044    out.popDepth();
1045    out.println("}");
1046  }
1047
1048  /**
1049   * Generates the after-rollback
1050   */

1051  private void generateAfterRollback(JavaWriter out)
1052    throws IOException JavaDoc
1053  {
1054    out.println();
1055    out.println("public void __caucho_afterRollback()");
1056    out.println("{");
1057    out.pushDepth();
1058
1059    out.println("__caucho_state = com.caucho.amber.entity.Entity.P_NON_TRANSACTIONAL;");
1060
1061    int loadCount = _entityType.getLoadGroupIndex();
1062    for (int i = 0; i <= loadCount / 64; i++) {
1063      out.println("__caucho_loadMask_" + i + " = 0L;");
1064    }
1065
1066    int dirtyCount = _entityType.getDirtyIndex();
1067    for (int i = 0; i <= dirtyCount / 64; i++) {
1068      out.println("__caucho_dirtyMask_" + i + " = 0L;");
1069    }
1070
1071    out.popDepth();
1072    out.println("}");
1073  }
1074
1075  private String JavaDoc getDebug()
1076  {
1077    return "this";
1078  }
1079
1080  /**
1081   * Generates the update
1082   */

1083  private void generateCreate(JavaWriter out)
1084    throws IOException JavaDoc
1085  {
1086    ArrayList JavaDoc<IdField> fields = _entityType.getId().getKeys();
1087    IdField idField = fields.size() > 0 ? fields.get(0) : null;
1088
1089    boolean hasReturnGeneratedKeys = false;
1090
1091    try {
1092      hasReturnGeneratedKeys = _entityType.getPersistenceUnit().hasReturnGeneratedKeys();
1093    } catch (Exception JavaDoc e) {
1094      // Meta-data exception which is acceptable or
1095
// no data-source configured. The latter will
1096
// be thrown on web.xml validation. (ejb/06m0)
1097
}
1098
1099    if (! hasReturnGeneratedKeys &&
1100        idField != null && idField.getType().isAutoIncrement()) {
1101      out.println();
1102      out.println("private static com.caucho.amber.field.Generator __caucho_id_gen;");
1103      out.println("static {");
1104      out.pushDepth();
1105      out.println("com.caucho.amber.field.MaxGenerator gen = new com.caucho.amber.field.MaxGenerator();");
1106      out.println("gen.setColumn(\"" + idField.getColumns().get(0).generateInsertName() + "\");");
1107      out.println("gen.setTable(\"" + _entityType.getName() + "\");");
1108      out.println("gen.init();");
1109      out.popDepth();
1110      out.println("}");
1111    }
1112
1113    out.println();
1114    out.println("public boolean __caucho_create(com.caucho.amber.manager.AmberConnection aConn, com.caucho.amber.type.EntityType home)");
1115    out.println(" throws java.sql.SQLException");
1116    out.println("{");
1117    out.pushDepth();
1118
1119    out.println("if (__caucho_session != null)");
1120    out.println(" return true;");
1121
1122    // commented out: jpa/0h25
1123
// out.println(" throw new com.caucho.amber.AmberException(\"object \" + " + getDebug() + " + \" is already persistent.\");");
1124

1125    out.println("__caucho_state = com.caucho.amber.entity.Entity.P_NEW;");
1126
1127    int loadCount = _entityType.getLoadGroupIndex();
1128    for (int i = 0; i <= loadCount / 64; i++) {
1129      out.println("__caucho_loadMask_" + i + " = " + _entityType.getCreateLoadMask(i) + ";");
1130    }
1131
1132    out.println("aConn.prePersist(this);");
1133
1134    for (JMethod method : _entityType.getPrePersistCallbacks()) {
1135      out.println(method.getName() + "();");
1136    }
1137
1138    int dirtyCount = _entityType.getDirtyIndex();
1139    for (int i = 0; i <= dirtyCount / 64; i++) {
1140      out.println("__caucho_dirtyMask_" + i + " = 0L;");
1141    }
1142
1143    Table table = _entityType.getTable();
1144
1145    out.print("String sql = \"");
1146    out.print(_entityType.generateCreateSQL(table));
1147    out.println("\";");
1148
1149    _entityType.getId().generateCheckCreateKey(out);
1150
1151    out.println("java.sql.PreparedStatement pstmt = aConn.prepareInsertStatement(sql);");
1152
1153    out.println("int index = 1;");
1154
1155    out.println();
1156    _entityType.getId().generateSetInsert(out, "pstmt", "index");
1157
1158    _entityType.generateInsertSet(out, table, "pstmt", "index", "super");
1159
1160    out.println();
1161    out.println("pstmt.executeUpdate();");
1162
1163    out.println();
1164    _entityType.getId().generateSetGeneratedKeys(out, "pstmt");
1165
1166    RelatedType parentType = _entityType;
1167
1168    do {
1169      for (Table subTable : parentType.getSecondaryTables()) {
1170        out.println();
1171        out.print("sql = \"");
1172        out.print(parentType.generateCreateSQL(subTable));
1173        out.println("\";");
1174
1175        out.println("pstmt = aConn.prepareStatement(sql);");
1176
1177        out.println("index = 1;");
1178
1179        out.println();
1180        parentType.getId().generateSetInsert(out, "pstmt", "index");
1181
1182        parentType.generateInsertSet(out, subTable, "pstmt", "index", "super");
1183
1184        out.println();
1185        out.println("pstmt.executeUpdate();");
1186
1187        out.println();
1188        parentType.getId().generateSetGeneratedKeys(out, "pstmt");
1189      }
1190    }
1191    while ((parentType = parentType.getParentType()) != null);
1192
1193    out.println();
1194    out.println("__caucho_session = aConn;");
1195    out.println("__caucho_home = home;");
1196
1197    // println("pstmt.close();");
1198

1199    out.println("__caucho_item = new com.caucho.amber.entity.CacheableEntityItem(home.getHome(), new " + getClassName() + "());");
1200    out.println(getClassName() + " entity = (" + getClassName() + ") __caucho_item.getEntity();");
1201    out.println("entity.__caucho_home = home;");
1202
1203    ArrayList JavaDoc<IdField> keys = _entityType.getId().getKeys();
1204    for (IdField key : keys) {
1205      String JavaDoc value = key.generateGet("super");
1206
1207      out.println(key.generateSet("entity", value) + ";");
1208    }
1209
1210    for (int i = 0; i < 1; i++) {
1211      _entityType.generateCopyUpdateObject(out, "entity", "super", i);
1212    }
1213
1214    for (int i = 0; i <= loadCount / 64; i++) {
1215      out.print("entity.__caucho_loadMask_" + i + " = ");
1216      out.println(_entityType.getCreateLoadMask(i) + ";");
1217    }
1218
1219    out.println();
1220    out.println("if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
1221    out.println(" __caucho_log.fine(\"amber create \" + this.getClass().getName() + \" - PK: \" + __caucho_getPrimaryKey());");
1222    out.println();
1223    out.println("if (aConn.isInTransaction()) {");
1224    out.println(" __caucho_state = com.caucho.amber.entity.Entity.P_TRANSACTIONAL;");
1225    out.println(" aConn.makeTransactional(this);");
1226    out.println("}");
1227    out.println();
1228
1229    out.println("aConn.postPersist(this);");
1230
1231    for (JMethod method : _entityType.getPostPersistCallbacks()) {
1232      out.println(method.getName() + "();");
1233    }
1234
1235    out.println();
1236    out.println("return false;");
1237
1238    out.popDepth();
1239    out.println("}");
1240  }
1241
1242  /**
1243   * Generates the delete
1244   */

1245  private void generateDelete(JavaWriter out)
1246    throws IOException JavaDoc
1247  {
1248    out.println();
1249    out.println("public void __caucho_delete()");
1250    out.println("{");
1251    out.pushDepth();
1252
1253    out.println("if (__caucho_state >= com.caucho.amber.entity.Entity.P_DELETING)");
1254    out.println(" return;");
1255    out.println();
1256
1257    out.println("if (__caucho_session != null)");
1258    out.println(" __caucho_session.preRemove(this);");
1259    out.println();
1260
1261    generateCallbacks(out, "this", _entityType.getPreRemoveCallbacks());
1262
1263    _entityType.generatePreDelete(out);
1264
1265    out.println("__caucho_state = com.caucho.amber.entity.Entity.P_DELETING;");
1266
1267    out.println("if (__caucho_session != null) {");
1268    out.pushDepth();
1269    out.println("__caucho_session.update(this);");
1270    out.println("__caucho_home.getTable().beforeEntityDelete(__caucho_session, this);");
1271    out.println("__caucho_state = com.caucho.amber.entity.Entity.P_DELETED;");
1272    _entityType.generatePostDelete(out);
1273    out.popDepth();
1274    out.println("}");
1275    out.println("else");
1276    out.println(" __caucho_state = com.caucho.amber.entity.Entity.P_DELETED;");
1277
1278    out.popDepth();
1279    out.println("}");
1280
1281    Id id = _entityType.getId();
1282
1283    out.println();
1284    out.println("private void __caucho_delete_int()");
1285    out.println(" throws java.sql.SQLException");
1286    out.println("{");
1287    out.pushDepth();
1288
1289    out.print("__caucho_home.delete(__caucho_session, ");
1290    out.print(id.toObject(id.generateGetProperty("this")));
1291    out.println(");");
1292
1293    out.println("__caucho_session.removeEntity(this);");
1294
1295    String JavaDoc table = _entityType.getTable().getName();
1296    String JavaDoc where = _entityType.getId().generateMatchArgWhere(null);
1297
1298    String JavaDoc sql = "delete from " + table + " where " + where;
1299
1300    out.println("String sql = \"" + sql + "\";");
1301
1302    out.println();
1303    out.println("java.sql.PreparedStatement pstmt = __caucho_session.prepareStatement(sql);");
1304
1305    out.println("int index = 1;");
1306    id.generateSet(out, "pstmt", "index", "this");
1307
1308    out.println();
1309    out.println("pstmt.executeUpdate();");
1310
1311    out.println("__caucho_session.postRemove(this);");
1312
1313    generateCallbacks(out, "this", _entityType.getPostRemoveCallbacks());
1314
1315    out.popDepth();
1316    out.println("}");
1317  }
1318
1319  /**
1320   * Generates the foreign delete
1321   */

1322  private void generateDeleteForeign(JavaWriter out)
1323    throws IOException JavaDoc
1324  {
1325    out.println();
1326    out.println("public void __caucho_invalidate_foreign(String table, Object key)");
1327    out.println("{");
1328    out.pushDepth();
1329
1330    _entityType.generateInvalidateForeign(out);
1331
1332    out.popDepth();
1333    out.println("}");
1334  }
1335
1336
1337  /**
1338   * Generates the cache load
1339   */

1340  private void generateLoadFromObject(JavaWriter out)
1341    throws IOException JavaDoc
1342  {
1343    out.println();
1344    out.println("public void __caucho_loadFromObject(Object src)");
1345    out.println("{");
1346    out.pushDepth();
1347
1348    out.println(getClassName() + " o = (" + getClassName() + ") src;");
1349
1350    if (_entityType.getParentType() != null)
1351      out.println("super.__caucho_loadFromObject(src);");
1352    else {
1353      int loadCount = _entityType.getLoadGroupIndex();
1354      for (int i = 0; i <= loadCount / 64; i++) {
1355        out.println("__caucho_loadMask_" + i + " = o.__caucho_loadMask_" + i + ";");
1356      }
1357    }
1358
1359    int dirtyCount = _entityType.getDirtyIndex();
1360    for (int i = 0; i <= dirtyCount / 64; i++) {
1361      out.println("__caucho_dirtyMask_" + i + " = 0;");
1362    }
1363
1364    _entityType.generateLoadFromObject(out, "o");
1365
1366    /* XXX:
1367       if (Lifecycle.class.isAssignableFrom(_entityType.getBeanClass())) {
1368       println("if (src instanceof com.caucho.ormap.Lifecycle)");
1369       println(" ((com.caucho.ormap.Lifecycle) src).afterLoad(__caucho_session, " +
1370       _entityType.getId().getGetterName() + "());");
1371       }
1372    */

1373
1374    out.popDepth();
1375    out.println("}");
1376  }
1377
1378  /**
1379   * Generates the copy
1380   */

1381  /*
1382    private void generateCopy(JavaWriter out)
1383    throws IOException
1384    {
1385    out.println();
1386    out.println("public com.caucho.amber.entity.Entity __caucho_copy()");
1387    out.println("{");
1388    out.pushDepth();
1389
1390    out.println(getClassName() + " o = new " + getClassName() + "();");
1391
1392    // can't load because it doesn't handle timeouts
1393    out.println("o.__caucho_loadFromObject(this);");
1394    out.println("o.__caucho_loadMask = 0;");
1395
1396    out.println("return o;");
1397
1398    out.popDepth();
1399    out.println("}");
1400    }
1401  */

1402
1403  /**
1404   * Generates the create
1405   */

1406  private void generateCopy(JavaWriter out)
1407    throws IOException JavaDoc
1408  {
1409    out.println();
1410    out.println("public com.caucho.amber.entity.Entity __caucho_copy(com.caucho.amber.manager.AmberConnection aConn,");
1411    out.println(" com.caucho.amber.entity.EntityItem item)");
1412    out.println("{");
1413    out.pushDepth();
1414
1415    out.println(getClassName() + " o = new " + getClassName() + "();");
1416
1417    out.println("o.__caucho_home = __caucho_home;");
1418    out.println("o.__caucho_item = item;");
1419
1420    ArrayList JavaDoc<IdField> keys = _entityType.getId().getKeys();
1421
1422    for (int i = 0; i < keys.size(); i++) {
1423      IdField key = keys.get(i);
1424
1425      out.println(key.generateSet("o", key.generateGet("super")) + ";");
1426    }
1427
1428    for (int i = 0; i <= _entityType.getLoadGroupIndex(); i++) {
1429      // jpa/0l02
1430
_entityType.generateCopyLoadObject(out, "o", "super", i);
1431    }
1432
1433    out.println("o.__caucho_session = aConn;");
1434    out.println("o.__caucho_state = __caucho_state;"); // com.caucho.amber.entity.Entity.P_NON_TRANSACTIONAL;");
1435

1436    for (int i = 0; i <= _entityType.getLoadGroupIndex() / 64; i++) {
1437      String JavaDoc mask = "__caucho_loadMask_" + i;
1438
1439      out.println("o." + mask + " = " + mask + ";");
1440    }
1441
1442    int dirtyCount = _entityType.getDirtyIndex();
1443
1444    // jpa/0g06
1445
for (int i = 0; i <= dirtyCount / 64; i++) {
1446      String JavaDoc mask = "__caucho_dirtyMask_" + i;
1447
1448      out.println("o." + mask + " = 0L;");
1449    }
1450
1451    // See LoadGroupGenerator __caucho_load.
1452
//
1453
// out.println("aConn.postLoad(this);");
1454
//
1455
// generateCallbacks(out, "o", _entityType.getPostLoadCallbacks());
1456

1457    out.println();
1458    out.println("return o;");
1459
1460    out.popDepth();
1461    out.println("}");
1462  }
1463
1464  /**
1465   * Generates the copy
1466   */

1467  private void generateMakePersistent(JavaWriter out)
1468    throws IOException JavaDoc
1469  {
1470    out.println();
1471    out.println("public void __caucho_makePersistent(com.caucho.amber.manager.AmberConnection aConn,");
1472    out.println(" com.caucho.amber.entity.EntityItem item)");
1473    out.println("{");
1474    out.pushDepth();
1475
1476    out.println(_extClassName + " entity = (" + _extClassName + ") item.getEntity();");
1477
1478    out.println("__caucho_home = entity.__caucho_home;");
1479    out.println("if (__caucho_home == null) throw new NullPointerException();");
1480    out.println("__caucho_item = item;");
1481
1482    ArrayList JavaDoc<IdField> keys = _entityType.getId().getKeys();
1483
1484    for (int i = 0; i < keys.size(); i++) {
1485      IdField key = keys.get(i);
1486
1487      out.println(key.generateSet("super", key.generateGet("entity")) + ";");
1488    }
1489
1490    out.println("__caucho_session = aConn;");
1491
1492    // out.println("if (__caucho_state != com.caucho.amber.entity.Entity.P_TRANSACTIONAL) {");
1493
out.println("__caucho_state = com.caucho.amber.entity.Entity.P_NON_TRANSACTIONAL;");
1494    // out.println("}");
1495

1496    out.popDepth();
1497    out.println("}");
1498  }
1499
1500  /**
1501   * Generates the cascade persist
1502   */

1503  private void generateCascadePersist(JavaWriter out)
1504    throws IOException JavaDoc
1505  {
1506    out.println();
1507    out.println("public void __caucho_cascadePrePersist(com.caucho.amber.manager.AmberConnection aConn)");
1508    out.println(" throws java.sql.SQLException");
1509    out.println("{");
1510    out.pushDepth();
1511
1512    // out.println("if (aConn == null)");
1513
// out.println(" throw new com.caucho.amber.AmberException(\"Null AmberConnection when object \" + " + getDebug() + " + \" is trying to cascade persist child objects.\");");
1514

1515    ArrayList JavaDoc<AmberField> fields = _entityType.getFields();
1516
1517    for (int i = 0; i < fields.size(); i++) {
1518      AmberField field = fields.get(i);
1519
1520      if (field.isCascadable()) {
1521        CascadableField cascadable = (CascadableField) field;
1522
1523        out.println();
1524
1525        cascadable.generatePreCascade(out, "aConn", CascadeType.PERSIST);
1526      }
1527    }
1528
1529    out.popDepth();
1530    out.println("}");
1531
1532    out.println();
1533    out.println("public void __caucho_cascadePostPersist(com.caucho.amber.manager.AmberConnection aConn)");
1534    out.println(" throws java.sql.SQLException");
1535    out.println("{");
1536    out.pushDepth();
1537
1538    for (int i = 0; i < fields.size(); i++) {
1539      AmberField field = fields.get(i);
1540
1541      if (field.isCascadable()) {
1542        CascadableField cascadable = (CascadableField) field;
1543
1544        out.println();
1545
1546        cascadable.generatePostCascade(out, "aConn", CascadeType.PERSIST);
1547      }
1548    }
1549
1550    out.popDepth();
1551    out.println("}");
1552  }
1553
1554  /**
1555   * Generates the cascade remove
1556   */

1557  private void generateCascadeRemove(JavaWriter out)
1558    throws IOException JavaDoc
1559  {
1560    out.println();
1561    out.println("public void __caucho_cascadePreRemove(com.caucho.amber.manager.AmberConnection aConn)");
1562    out.println(" throws java.sql.SQLException");
1563    out.println("{");
1564    out.pushDepth();
1565
1566    ArrayList JavaDoc<AmberField> fields = _entityType.getFields();
1567
1568    for (int i = 0; i < fields.size(); i++) {
1569      AmberField field = fields.get(i);
1570
1571      if (field.isCascadable()) {
1572        CascadableField cascadable = (CascadableField) field;
1573
1574        out.println();
1575
1576        cascadable.generatePreCascade(out, "aConn", CascadeType.REMOVE);
1577      }
1578    }
1579
1580    out.popDepth();
1581    out.println("}");
1582
1583    out.println();
1584    out.println("public void __caucho_cascadePostRemove(com.caucho.amber.manager.AmberConnection aConn)");
1585    out.println(" throws java.sql.SQLException");
1586    out.println("{");
1587    out.pushDepth();
1588
1589    for (int i = 0; i < fields.size(); i++) {
1590      AmberField field = fields.get(i);
1591
1592      if (field.isCascadable()) {
1593        CascadableField cascadable = (CascadableField) field;
1594
1595        out.println();
1596
1597        cascadable.generatePostCascade(out, "aConn", CascadeType.REMOVE);
1598      }
1599    }
1600
1601    out.popDepth();
1602    out.println("}");
1603  }
1604
1605  /**
1606   * Generates the home methods
1607   */

1608  private void generateHome(JavaWriter out)
1609    throws IOException JavaDoc
1610  {
1611    generateHomeFind(out);
1612
1613    if (! (_entityType instanceof SubEntityType)) {
1614      generateHomeNew(out);
1615    }
1616  }
1617
1618  /**
1619   * Generates the home methods
1620   */

1621  private void generateHomeFind(JavaWriter out)
1622    throws IOException JavaDoc
1623  {
1624    out.println();
1625    out.print("public com.caucho.amber.entity.EntityItem __caucho_home_find(");
1626    out.print("com.caucho.amber.manager.AmberConnection aConn,");
1627    out.print("com.caucho.amber.entity.AmberEntityHome home,");
1628    out.println("java.sql.ResultSet rs, int index)");
1629    out.println(" throws java.sql.SQLException");
1630    out.println("{");
1631    out.pushDepth();
1632
1633
1634    out.print("Object key = ");
1635    int index = _entityType.getId().generateLoadForeign(out, "rs", "index", 0);
1636    out.println(";");
1637
1638    if (_entityType.getDiscriminator() == null) {
1639      out.println("return home.findEntityItem(aConn, key, false);");
1640    }
1641    else {
1642      out.println("String discriminator = rs.getString(index + " + index + ");");
1643      out.println();
1644      out.println("return home.findDiscriminatorEntityItem(aConn, key, discriminator);");
1645    }
1646
1647    out.popDepth();
1648    out.println("}");
1649  }
1650
1651  /**
1652   * Generates the home methods
1653   */

1654  private void generateHomeNew(JavaWriter out)
1655    throws IOException JavaDoc
1656  {
1657    out.println();
1658    out.print("public com.caucho.amber.entity.Entity __caucho_home_new(");
1659    out.print("com.caucho.amber.manager.AmberConnection aConn,");
1660    out.print("com.caucho.amber.entity.AmberEntityHome home,");
1661    out.print("Object key)");
1662    out.println(" throws java.sql.SQLException");
1663    out.println("{");
1664    out.println(" return __caucho_home_new(aConn, home, key, true);");
1665    out.println("}");
1666
1667    out.println();
1668    out.print("public com.caucho.amber.entity.Entity __caucho_home_new(");
1669    out.print("com.caucho.amber.manager.AmberConnection aConn,");
1670    out.print("com.caucho.amber.entity.AmberEntityHome home,");
1671    out.print("Object key,");
1672    out.print("boolean loadFromResultSet)");
1673    out.println(" throws java.sql.SQLException");
1674    out.println("{");
1675    out.pushDepth();
1676
1677    Column discriminator = _entityType.getDiscriminator();
1678
1679    if (discriminator == null) {
1680      out.println(getClassName() + " entity = new " + getClassName() + "();");
1681
1682      out.println("entity.__caucho_home = home.getEntityType();");
1683      out.println("entity.__caucho_setPrimaryKey(key);");
1684
1685      out.println("return entity;");
1686    }
1687    else {
1688
1689      String JavaDoc rootTableName = _entityType.getRootTableName();
1690
1691      generateHomeNewLoading(out, rootTableName);
1692
1693      out.println("com.caucho.amber.entity.EntityItem item = home.findDiscriminatorEntityItem(aConn, key, rs" + rootTableName + ".getString(1));");
1694
1695      // jpa/0l03
1696
out.println("if (loadFromResultSet) {");
1697      out.pushDepth();
1698
1699      // generateHomeNewLoading(out, null);
1700

1701      out.println("item.getEntity().__caucho_load(aConn, rs" + rootTableName + ", 1);");
1702
1703      out.popDepth();
1704      out.println("}");
1705
1706      out.println(getClassName() + " entity = (" + getClassName() + ") item.copy(aConn);");
1707
1708      out.println("rs" + rootTableName + ".close();");
1709      out.println("return entity;");
1710    }
1711
1712    out.popDepth();
1713    out.println("}");
1714  }
1715
1716  /**
1717   * Generates the loading for home_new
1718   */

1719  private void generateHomeNewLoading(JavaWriter out,
1720                                      String JavaDoc rootTableName)
1721    throws IOException JavaDoc
1722  {
1723    String JavaDoc varSuffix = rootTableName == null ? "" : rootTableName;
1724
1725    out.print("String sql" + varSuffix + " = \"select ");
1726    out.print(_entityType.generateLoadSelect("o"));
1727    out.print(" from ");
1728
1729    if (rootTableName == null)
1730      out.print(_entityType.getTable().getName());
1731    else
1732      out.print(rootTableName);
1733
1734    out.print(" o where ");
1735    out.print(_entityType.getId().generateMatchArgWhere("o"));
1736    out.println("\";");
1737
1738    out.println("java.sql.PreparedStatement pstmt" + varSuffix + " = aConn.prepareStatement(sql" + varSuffix + ");");
1739
1740    String JavaDoc keyType = _entityType.getId().getForeignTypeName();
1741
1742    out.println(keyType + " " + "keyValue" + varSuffix + " = (" + keyType + ") key;");
1743
1744    out.println("int index" + varSuffix + " = 1;");
1745    _entityType.getId().generateSetKey(out, "pstmt"+varSuffix,
1746                                       "index"+varSuffix, "keyValue"+varSuffix);
1747
1748    out.println("java.sql.ResultSet rs" + varSuffix + " = pstmt" + varSuffix + ".executeQuery();");
1749    out.println("if (! rs" + varSuffix + ".next()) {");
1750    out.println(" rs" + varSuffix + ".close();");
1751    out.println(" return null;");
1752    // out.println(" throw new com.caucho.amber.AmberException(key + \" has no matching object\");");
1753
out.println("}");
1754  }
1755
1756  private void generateCallbacks(JavaWriter out,
1757                                 String JavaDoc object,
1758                                 ArrayList JavaDoc<JMethod> callbacks)
1759    throws IOException JavaDoc
1760  {
1761    if (callbacks.size() > 0) {
1762
1763      out.println();
1764
1765      for (JMethod method : callbacks) {
1766        out.println(object + "." + method.getName() + "();");
1767      }
1768    }
1769  }
1770
1771  private void generateInternals(JavaWriter out)
1772    throws IOException JavaDoc
1773  {
1774    out.println();
1775    out.println("private void __caucho_setInternalString(java.sql.PreparedStatement pstmt, int index, String s)");
1776    out.println(" throws java.sql.SQLException");
1777    out.println("{");
1778    out.pushDepth();
1779    out.println("if (s == null)");
1780    out.println(" pstmt.setNull(index, java.sql.Types.NULL);");
1781    out.println("else");
1782    out.println(" pstmt.setString(index, s);");
1783    out.popDepth();
1784    out.println("}");
1785  }
1786}
1787
Popular Tags