0001: /*
0002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003: *
0004: * This file is part of Resin(R) Open Source
0005: *
0006: * Each copy or derived work must preserve the copyright notice and this
0007: * notice unmodified.
0008: *
0009: * Resin Open Source is free software; you can redistribute it and/or modify
0010: * it under the terms of the GNU General Public License as published by
0011: * the Free Software Foundation; either version 2 of the License, or
0012: * (at your option) any later version.
0013: *
0014: * Resin Open Source is distributed in the hope that it will be useful,
0015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017: * of NON-INFRINGEMENT. See the GNU General Public License for more
0018: * details.
0019: *
0020: * You should have received a copy of the GNU General Public License
0021: * along with Resin Open Source; if not, write to the
0022: *
0023: * Free Software Foundation, Inc.
0024: * 59 Temple Place, Suite 330
0025: * Boston, MA 02111-1307 USA
0026: *
0027: * @author Scott Ferguson
0028: */
0029:
0030: package com.caucho.amber.gen;
0031:
0032: import com.caucho.amber.field.*;
0033: import com.caucho.amber.table.Column;
0034: import com.caucho.amber.table.Table;
0035: import com.caucho.amber.type.EmbeddableType;
0036: import com.caucho.amber.type.EntityType;
0037: import com.caucho.amber.type.MappedSuperclassType;
0038: import com.caucho.amber.type.RelatedType;
0039: import com.caucho.amber.type.SubEntityType;
0040: import com.caucho.amber.type.Type;
0041: import com.caucho.bytecode.*;
0042: import com.caucho.java.JavaWriter;
0043: import com.caucho.java.gen.ClassComponent;
0044: import com.caucho.loader.Environment;
0045: import com.caucho.util.CharBuffer;
0046: import com.caucho.util.L10N;
0047: import com.caucho.vfs.PersistentDependency;
0048:
0049: import javax.persistence.CascadeType;
0050: import java.io.IOException;
0051: import java.util.ArrayList;
0052: import java.util.HashSet;
0053:
0054: /**
0055: * Generates the Java code for the wrapped object.
0056: */
0057: abstract public class AmberMappedComponent extends ClassComponent {
0058: private static final L10N L = new L10N(AmberMappedComponent.class);
0059:
0060: String _baseClassName;
0061: String _extClassName;
0062:
0063: RelatedType _relatedType;
0064:
0065: private ArrayList<PersistentDependency> _dependencies = new ArrayList<PersistentDependency>();
0066:
0067: public AmberMappedComponent() {
0068: }
0069:
0070: /**
0071: * Sets the bean info for the generator
0072: */
0073: void setRelatedType(RelatedType relatedType) {
0074: _relatedType = relatedType;
0075:
0076: _dependencies.addAll(relatedType.getDependencies());
0077:
0078: for (int i = 0; i < _dependencies.size(); i++)
0079: Environment.addDependency(_dependencies.get(i));
0080: }
0081:
0082: /**
0083: * Sets the base class name
0084: */
0085: public void setBaseClassName(String baseClassName) {
0086: _baseClassName = baseClassName;
0087: }
0088:
0089: /**
0090: * Gets the base class name
0091: */
0092: public String getBaseClassName() {
0093: return _baseClassName;
0094: }
0095:
0096: /**
0097: * Sets the ext class name
0098: */
0099: public void setExtClassName(String extClassName) {
0100: _extClassName = extClassName;
0101: }
0102:
0103: /**
0104: * Sets the ext class name
0105: */
0106: public String getClassName() {
0107: return _extClassName;
0108: }
0109:
0110: /**
0111: * Get bean class name.
0112: */
0113: public String getBeanClassName() {
0114: // return _relatedType.getBeanClass().getName();
0115: return _baseClassName;
0116: }
0117:
0118: /**
0119: * Returns the dependencies.
0120: */
0121: public ArrayList<PersistentDependency> getDependencies() {
0122: return _dependencies;
0123: }
0124:
0125: /**
0126: * Generates the class header for the generated code.
0127: */
0128: void generateHeader(JavaWriter out, boolean isEntityParent)
0129: throws IOException {
0130: out.println("/*");
0131: out.println(" * Generated by Resin Amber");
0132: out.println(" * " + com.caucho.Version.VERSION);
0133: out.println(" */");
0134: out
0135: .print("private static final java.util.logging.Logger __caucho_log = ");
0136: out.println("java.util.logging.Logger.getLogger(\""
0137: + getBeanClassName() + "\");");
0138:
0139: // jpa/0ge3 if (! isEntityParent) {
0140: if (_relatedType.getParentType() == null) {
0141: out.println();
0142: out
0143: .println("protected transient com.caucho.amber.type.EntityType __caucho_home;");
0144: out
0145: .println("public transient com.caucho.amber.entity.EntityItem __caucho_cacheItem;");
0146: out
0147: .println("protected transient com.caucho.amber.manager.AmberConnection __caucho_session;");
0148: out
0149: .println("protected transient com.caucho.amber.entity.EntityState __caucho_state = com.caucho.amber.entity.EntityState.TRANSIENT;");
0150:
0151: // XXX: needs to generate load masks for groups in the subclasses,
0152: // but the group numbering should not always start at zero.
0153:
0154: int loadCount = _relatedType.getLoadGroupIndex();
0155: for (int i = 0; i <= loadCount / 64; i++) {
0156: out
0157: .println("protected transient long __caucho_loadMask_"
0158: + i + ";");
0159: }
0160:
0161: int dirtyCount = _relatedType.getDirtyIndex();
0162:
0163: for (int i = 0; i <= dirtyCount / 64; i++) {
0164: out
0165: .println("protected transient long __caucho_dirtyMask_"
0166: + i + ";");
0167: out
0168: .println("protected transient long __caucho_updateMask_"
0169: + i + ";");
0170: }
0171:
0172: out
0173: .println("protected transient boolean __caucho_inc_version;");
0174: }
0175: }
0176:
0177: /**
0178: * Generates the init generated code.
0179: */
0180: void generateInit(JavaWriter out, boolean isEntityParent)
0181: throws IOException {
0182: if (isEntityParent)
0183: return;
0184:
0185: // XXX: needs to handle this with subclasses
0186: // but there is an issue in the enhancer fixup
0187: // removing the "super." call.
0188: /*
0189: out.println();
0190: out.println("public void __caucho_postConstructor()");
0191: out.println("{");
0192: out.pushDepth();
0193:
0194: ArrayList<AmberField> fields = _relatedType.getFields();
0195:
0196: for (int i = 0; i < fields.size(); i++) {
0197: AmberField field = fields.get(i);
0198:
0199: if (field instanceof AbstractField) {
0200: AbstractField f = (AbstractField) field;
0201: f.generatePostConstructor(out);
0202: }
0203: }
0204:
0205: out.popDepth();
0206: out.println("}");
0207: */
0208:
0209: String className = getClassName();
0210: int p = className.lastIndexOf('.');
0211: if (p > 0)
0212: className = className.substring(p + 1);
0213:
0214: ArrayList<AmberField> fields = _relatedType.getFields();
0215:
0216: for (JMethod ctor : _relatedType.getBeanClass()
0217: .getConstructors()) {
0218: out.println();
0219: // XXX: s/b actual access type?
0220: out.print("public ");
0221:
0222: out.print(className);
0223: out.print("(");
0224:
0225: JClass[] args = ctor.getParameterTypes();
0226: for (int i = 0; i < args.length; i++) {
0227: if (i != 0)
0228: out.print(", ");
0229:
0230: out.print(args[i].getPrintName());
0231: out.print(" a" + i);
0232: }
0233: out.println(")");
0234: out.println("{");
0235: out.pushDepth();
0236:
0237: out.print("super(");
0238: for (int i = 0; i < args.length; i++) {
0239: if (i != 0)
0240: out.print(", ");
0241:
0242: out.print("a" + i);
0243: }
0244: out.println(");");
0245:
0246: // jpa/0l14
0247: out
0248: .println("__caucho_state = com.caucho.amber.entity.EntityState.TRANSIENT;");
0249:
0250: // jpa/0gh2: compound pk and constructor with arguments.
0251: if (_relatedType.getId() instanceof CompositeId) {
0252: out.println("try {");
0253: out
0254: .println(" __caucho_setPrimaryKey(__caucho_getPrimaryKey());");
0255: out.println("} catch (Exception e) {");
0256: out
0257: .println(" __caucho_log.fine(\"amber unable to set primary key within argument constructor \" + this.getClass().getName() + \"[PK: unknown]\");");
0258: out.println("}");
0259: }
0260:
0261: for (AmberField field : fields) {
0262: field.generatePostConstructor(out);
0263: }
0264:
0265: out.popDepth();
0266: out.println("}");
0267: }
0268:
0269: Id id = _relatedType.getId();
0270:
0271: if (id == null) {
0272: if (_relatedType instanceof EntityType)
0273: throw new IllegalStateException(L.l(
0274: "'{0}' is missing a key.", _relatedType
0275: .getName()));
0276: } // ejb/0623 as a negative test.
0277: else if (id instanceof CompositeId) {
0278: }
0279:
0280: boolean isAbstract = (_relatedType.getBeanClass().isAbstract() && _relatedType
0281: .getPersistenceUnit().isJPA());
0282:
0283: out.println();
0284: out.println("public void __caucho_setPrimaryKey(Object key)");
0285: out.println("{");
0286: out.pushDepth();
0287:
0288: if (id != null && !isAbstract)
0289: id.generateSet(out, id.generateCastFromObject("key"));
0290:
0291: out.popDepth();
0292: out.println("}");
0293:
0294: out.println();
0295: out.println("public Object __caucho_getPrimaryKey()");
0296: out.println("{");
0297: out.pushDepth();
0298:
0299: out.println("try {");
0300: out.pushDepth();
0301:
0302: out.print("return ");
0303:
0304: if (id == null || isAbstract)
0305: out.print("null");
0306: else
0307: out.print(id.toObject(id.generateGetProperty("super")));
0308:
0309: out.println(";");
0310:
0311: out.popDepth();
0312: out.println("} catch (Exception e) {");
0313: out
0314: .println(" throw new com.caucho.amber.AmberRuntimeException(e);");
0315: out.println("}");
0316:
0317: out.popDepth();
0318: out.println("}");
0319:
0320: /*
0321: println();
0322: println("public com.caucho.amber.entity.EntityItem __caucho_getCacheItem()");
0323: println("{");
0324: pushDepth();
0325:
0326: println("return __caucho_cacheItem;");
0327:
0328: popDepth();
0329: println("}");
0330:
0331: println();
0332: println("public void __caucho_setCacheItem(com.caucho.amber.entity.EntityItem item)");
0333: println("{");
0334: pushDepth();
0335:
0336: println("__caucho_cacheItem = item;");
0337:
0338: popDepth();
0339: println("}");
0340: */
0341:
0342: out.println();
0343: out
0344: .println("public void __caucho_setConnection(com.caucho.amber.manager.AmberConnection aConn)");
0345: out.println("{");
0346: out.pushDepth();
0347:
0348: out.println("__caucho_session = aConn;");
0349:
0350: out.popDepth();
0351: out.println("}");
0352:
0353: out.println();
0354: out
0355: .println("public com.caucho.amber.manager.AmberConnection __caucho_getConnection()");
0356: out.println("{");
0357: out.pushDepth();
0358:
0359: out.println("return __caucho_session;");
0360:
0361: out.popDepth();
0362: out.println("}");
0363:
0364: generateExpire(out);
0365: }
0366:
0367: /**
0368: * Generates the expire code.
0369: */
0370: void generateExpire(JavaWriter out) throws IOException {
0371: out.println();
0372: out.println("public void __caucho_expire()");
0373: out.println("{");
0374: out.pushDepth();
0375:
0376: out
0377: .println("if (__caucho_log.isLoggable(java.util.logging.Level.FINE)) {");
0378: out.pushDepth();
0379:
0380: out
0381: .println("__caucho_log.fine(\"amber expire \" + this.getClass().getName() + \"[\" + __caucho_getPrimaryKey() + \"]\");");
0382:
0383: out.popDepth();
0384: out.println("}");
0385: out.println();
0386:
0387: int loadCount = _relatedType.getLoadGroupIndex();
0388: for (int i = 0; i <= loadCount / 64; i++) {
0389: out.println("__caucho_loadMask_" + i + " = 0L;");
0390: }
0391:
0392: _relatedType.generateExpire(out);
0393:
0394: out.popDepth();
0395: out.println("}");
0396: }
0397:
0398: /**
0399: * Generates checks for entity-relationship consistency.
0400: */
0401: void generateDumpRelationships(JavaWriter out) throws IOException {
0402: out.println();
0403: out.println("public void __caucho_dumpRelationships()");
0404: out.println("{");
0405: out.pushDepth();
0406:
0407: out
0408: .println("if (! __caucho_log.isLoggable(java.util.logging.Level.FINEST))");
0409: out.println(" return;");
0410: out.println();
0411:
0412: out.println("if (__caucho_session == null)");
0413: out.println(" return;");
0414: out.println();
0415:
0416: out
0417: .println("com.caucho.amber.manager.AmberPersistenceUnit unit = __caucho_session.getPersistenceUnit();");
0418: out.println();
0419:
0420: out.println("com.caucho.amber.entity.Entity thisRef;");
0421:
0422: for (int i = 0; i <= _relatedType.getLoadGroupIndex(); i++) {
0423: _relatedType.generateDumpRelationships(out, i);
0424: }
0425:
0426: out.popDepth();
0427: out.println("}");
0428: }
0429:
0430: /**
0431: * Generates the isDirty code.
0432: */
0433: void generateIsDirty(JavaWriter out) throws IOException {
0434: out.println();
0435: out.println("public boolean __caucho_isDirty()");
0436: out.println("{");
0437: out.pushDepth();
0438:
0439: int dirtyCount = _relatedType.getDirtyIndex();
0440:
0441: for (int i = 0; i <= dirtyCount / 64; i++) {
0442: out.println("if (__caucho_dirtyMask_" + i + " != 0L)");
0443: out.println(" return true;");
0444: out.println();
0445: }
0446:
0447: out.println("return false;");
0448:
0449: out.popDepth();
0450: out.println("}");
0451: }
0452:
0453: /**
0454: * Generates the match code.
0455: */
0456: void generateMatch(JavaWriter out) throws IOException {
0457: out.println();
0458: out
0459: .println("public boolean __caucho_match(String className, Object key)");
0460: out.println("{");
0461: out.pushDepth();
0462:
0463: /*
0464: out.println("if (! (" + getBeanClassName() + ".class.isAssignableFrom(cl)))");
0465: out.println(" return false;");
0466: */
0467: out.println("if (! (\"" + getBeanClassName()
0468: + "\".equals(className)))");
0469: out.println(" return false;");
0470: out.println("else {");
0471: out.pushDepth();
0472:
0473: Id id = _relatedType.getId();
0474:
0475: // jpa/0gg0
0476: if (id == null || _relatedType.getBeanClass().isAbstract()) {
0477: // jpa/0ge6: MappedSuperclass
0478:
0479: out.println("return true;");
0480: out.popDepth();
0481: out.println("}");
0482: out.popDepth();
0483: out.println("}");
0484:
0485: return;
0486: }
0487:
0488: out.println("try {");
0489: out.pushDepth();
0490:
0491: id.generateMatch(out, id.generateCastFromObject("key"));
0492:
0493: out.popDepth();
0494: out.println("} catch (ClassCastException e) {");
0495: out
0496: .println(" throw new IllegalArgumentException(\"Primary key type is incorrect: '\"+key.getClass().getName()+\"'\");");
0497: out.println("}");
0498:
0499: out.popDepth();
0500: out.println("}");
0501:
0502: out.popDepth();
0503: out.println("}");
0504: }
0505:
0506: /**
0507: * Generates the prologue.
0508: */
0509: void generatePrologue(JavaWriter out, HashSet<Object> completedSet)
0510: throws IOException {
0511: if (_relatedType.getColumns() != null) {
0512: for (Column column : _relatedType.getColumns())
0513: column.generatePrologue(out);
0514: }
0515:
0516: Id id = _relatedType.getId();
0517:
0518: boolean isAbstractParent = _relatedType.getParentType() == null
0519: || _relatedType.getParentType().getBeanClass()
0520: .isAbstract();
0521:
0522: // jpa/0m02
0523: if (id != null && isAbstractParent)
0524: id.generatePrologue(out, completedSet);
0525:
0526: ArrayList<AmberField> fields = _relatedType.getFields();
0527:
0528: for (int i = 0; i < fields.size(); i++) {
0529: AmberField prop = fields.get(i);
0530:
0531: prop.generatePrologue(out, completedSet);
0532: }
0533: }
0534:
0535: /**
0536: * Generates the __caucho_getCacheEntity()
0537: */
0538: void generateGetCacheEntity(JavaWriter out) throws IOException {
0539: out.println();
0540: out
0541: .println("public com.caucho.amber.entity.Entity __caucho_getCacheEntity()");
0542: out.println("{");
0543: out.pushDepth();
0544:
0545: out.println("if (__caucho_cacheItem == null)");
0546: out.println(" return null;");
0547:
0548: out.println();
0549: out.println("return __caucho_cacheItem.getEntity();");
0550:
0551: out.popDepth();
0552: out.println("}");
0553:
0554: out.println();
0555: out
0556: .println("public com.caucho.amber.entity.EntityItem __caucho_getCacheItem()");
0557: out.println("{");
0558: out.pushDepth();
0559:
0560: out.println("return __caucho_cacheItem;");
0561:
0562: out.popDepth();
0563: out.println("}");
0564:
0565: out.println();
0566: out
0567: .println("public void __caucho_setCacheItem(com.caucho.amber.entity.EntityItem cacheItem)");
0568: out.println("{");
0569: out.pushDepth();
0570:
0571: out.println("__caucho_cacheItem = cacheItem;");
0572:
0573: out.popDepth();
0574: out.println("}");
0575: }
0576:
0577: /**
0578: * Generates the entity type
0579: */
0580: void generateGetEntityType(JavaWriter out) throws IOException {
0581: out.println();
0582: out
0583: .println("public com.caucho.amber.type.EntityType __caucho_getEntityType()");
0584: out.println("{");
0585: out.pushDepth();
0586:
0587: out.println("return __caucho_home;");
0588:
0589: out.popDepth();
0590: out.println("}");
0591: }
0592:
0593: /**
0594: * Generates the get entity state
0595: */
0596: void generateGetEntityState(JavaWriter out) throws IOException {
0597: out.println();
0598: out
0599: .println("public com.caucho.amber.entity.EntityState __caucho_getEntityState()");
0600: out.println("{");
0601: out.pushDepth();
0602:
0603: out.println("return __caucho_state;");
0604:
0605: out.popDepth();
0606: out.println("}");
0607:
0608: out.println();
0609: out
0610: .println("public void __caucho_setEntityState(com.caucho.amber.entity.EntityState state)");
0611: out.println("{");
0612: out.pushDepth();
0613:
0614: out.println("__caucho_state = state;");
0615:
0616: out.popDepth();
0617: out.println("}");
0618: }
0619:
0620: /**
0621: * Generates the fields.
0622: */
0623: void generateFields(JavaWriter out) throws IOException {
0624: ArrayList<AmberField> fields = _relatedType.getFields();
0625:
0626: for (int i = 0; i < fields.size(); i++) {
0627: AmberField prop = fields.get(i);
0628:
0629: prop.generateSuperGetter(out);
0630: prop.generateGetProperty(out);
0631:
0632: prop.generateSuperSetter(out);
0633: prop.generateSetProperty(out);
0634: }
0635: }
0636:
0637: /**
0638: * Generates the stub methods (needed for EJB)
0639: */
0640: void generateMethods(JavaWriter out) throws IOException {
0641: for (StubMethod method : _relatedType.getMethods()) {
0642: method.generate(out);
0643: }
0644: }
0645:
0646: /**
0647: * Generates the load
0648: */
0649: void generateLoad(JavaWriter out, boolean isEntityParent)
0650: throws IOException {
0651: // commented out: jpa/0l03
0652: // if (_relatedType.getParentType() != null)
0653: // return;
0654:
0655: if (!isEntityParent) {
0656: out.println();
0657: out
0658: .println("public boolean __caucho_makePersistent(com.caucho.amber.manager.AmberConnection aConn, com.caucho.amber.type.EntityType home)");
0659: out.println(" throws java.sql.SQLException");
0660: out.println("{");
0661: out.pushDepth();
0662:
0663: out.println("__caucho_session = aConn;");
0664: out.println("if (home != null)");
0665: out.println(" __caucho_home = home;");
0666:
0667: // XXX: makePersistent is called in contexts other than the P_NON_TRANSACTIONAL one, so this setting is inappropriate
0668: // out.println("__caucho_state = com.caucho.amber.entity.EntityState.P_NON_TRANSACTIONAL;");
0669:
0670: int loadCount = _relatedType.getLoadGroupIndex();
0671: for (int i = 0; i <= loadCount / 64; i++) {
0672: out.println("__caucho_loadMask_" + i + " = 0L;");
0673: }
0674:
0675: int dirtyCount = _relatedType.getDirtyIndex();
0676: for (int i = 0; i <= dirtyCount / 64; i++) {
0677: out.println("__caucho_dirtyMask_" + i + " = 0L;");
0678: out.println("__caucho_updateMask_" + i + " = 0L;");
0679: }
0680:
0681: out.println();
0682: out.println("return true;");
0683:
0684: out.popDepth();
0685: out.println("}");
0686: }
0687:
0688: int index = _relatedType.getLoadGroupIndex();
0689:
0690: boolean hasLoad = (_relatedType.getFields().size() > 0);
0691:
0692: if (!isEntityParent) {
0693: index = 0;
0694: hasLoad = hasLoad || (_relatedType.getId() != null);
0695: }
0696:
0697: // jpa/0l20
0698: if (true || hasLoad || !isEntityParent) {
0699: out.println();
0700: out
0701: .println("public void __caucho_retrieve_eager(com.caucho.amber.manager.AmberConnection aConn)");
0702: out.println("{");
0703:
0704: generateRetrieveEager(out, _relatedType);
0705:
0706: out.println("}");
0707: out.println();
0708: out
0709: .println("public void __caucho_retrieve_self(com.caucho.amber.manager.AmberConnection aConn)");
0710: out.println("{");
0711: out.pushDepth();
0712:
0713: generateRetrieveSelf(out, _relatedType);
0714:
0715: out.popDepth();
0716: out.println("}");
0717: }
0718: }
0719:
0720: private void generateRetrieveEager(JavaWriter out,
0721: RelatedType relatedType) throws IOException {
0722: if (relatedType == null)
0723: return;
0724:
0725: int index = relatedType.getLoadGroupIndex();
0726:
0727: boolean hasLoad = (relatedType.getFields().size() > 0);
0728:
0729: if (relatedType.getParentType() == null) {
0730: index = 0;
0731: hasLoad = true;
0732: }
0733:
0734: generateRetrieveEager(out, relatedType.getParentType());
0735:
0736: if (hasLoad)
0737: out.println("__caucho_load_" + index + "(aConn);");
0738: }
0739:
0740: private void generateRetrieveSelf(JavaWriter out,
0741: RelatedType relatedType) throws IOException {
0742: if (relatedType == null)
0743: return;
0744:
0745: int index = relatedType.getLoadGroupIndex();
0746:
0747: boolean hasLoad = (relatedType.getFields().size() > 0);
0748:
0749: if (relatedType.getParentType() != null) {
0750: generateRetrieveSelf(out, relatedType.getParentType());
0751: } else {
0752: index = 0;
0753: hasLoad = true;
0754: }
0755:
0756: if (hasLoad) {
0757: int group = index / 64;
0758: long mask = (1L << (index % 64));
0759:
0760: out.println("if ((__caucho_loadMask_" + group + " & "
0761: + mask + "L) == 0)");
0762:
0763: out.println(" __caucho_load_select_" + index + "(aConn);");
0764: }
0765: }
0766:
0767: /**
0768: * Generates the detach
0769: */
0770: void generateDetach(JavaWriter out, boolean isEntityParent)
0771: throws IOException {
0772: if (isEntityParent)
0773: return;
0774:
0775: out.println();
0776: out.println("public void __caucho_detach()");
0777: out.println("{");
0778: out.pushDepth();
0779:
0780: out
0781: .println("if (__caucho_log.isLoggable(java.util.logging.Level.FINEST))");
0782: out
0783: .println(" __caucho_log.finest(\"amber detach \" + this.getClass().getName() + \"[\" + __caucho_getPrimaryKey() + \"]\");");
0784: out.println();
0785:
0786: out.println();
0787: out.println("__caucho_session = null;");
0788:
0789: // jpa/0x00
0790: // out.println("__caucho_home = null;");
0791:
0792: out
0793: .println("__caucho_state = com.caucho.amber.entity.EntityState.TRANSIENT;");
0794:
0795: out.popDepth();
0796: out.println("}");
0797: }
0798:
0799: /**
0800: * Generates the load group.
0801: */
0802: void generateLoadGroup(JavaWriter out, int groupIndex)
0803: throws IOException {
0804: if (_relatedType.hasLoadGroup(groupIndex)) {
0805: new LoadGroupGenerator(_extClassName, _relatedType,
0806: groupIndex).generate(out);
0807: }
0808: }
0809:
0810: /**
0811: * Generates the load
0812: */
0813: void generateResultSetLoad(JavaWriter out, boolean isEntityParent)
0814: throws IOException {
0815: if (isEntityParent)
0816: return;
0817:
0818: out.println();
0819: out
0820: .println("public int __caucho_load(com.caucho.amber.manager.AmberConnection aConn, java.sql.ResultSet rs, int index)");
0821: out.println(" throws java.sql.SQLException");
0822: out.println("{");
0823: out.pushDepth();
0824:
0825: int index = _relatedType.generateLoad(out, "rs", "index", 0, 0,
0826: null);
0827:
0828: out.println("__caucho_loadMask_0 |= 1L;");
0829:
0830: int dirtyCount = _relatedType.getDirtyIndex();
0831:
0832: for (int i = 0; i <= dirtyCount / 64; i++) {
0833: out.println("__caucho_dirtyMask_" + i + " = 0;");
0834:
0835: // ejb/0645
0836: // out.println("__caucho_updateMask_" + i + " = 0;");
0837: }
0838:
0839: out.println();
0840: out.println("if (__caucho_cacheItem == null) {");
0841: // the cache item does not have its state changed
0842: out.println("}");
0843: out.println("else if (__caucho_state.isTransactional()) {");
0844: out.println("}");
0845: out.println("else if (__caucho_session == null");
0846: out
0847: .println(" || ! __caucho_session.isActiveTransaction()) {");
0848: out
0849: .println(" __caucho_state = com.caucho.amber.entity.EntityState.P_NON_TRANSACTIONAL;");
0850: out.println(" if (__caucho_cacheItem != null)");
0851: out
0852: .println(" __caucho_cacheItem.save((com.caucho.amber.entity.Entity) this);");
0853: out.println("}");
0854: out.println("else {");
0855: out
0856: .println(" __caucho_state = com.caucho.amber.entity.EntityState.P_TRANSACTIONAL;");
0857: out
0858: .println(" aConn.makeTransactional((com.caucho.amber.entity.Entity) this);");
0859: out.println("}");
0860:
0861: if (_relatedType.getHasLoadCallback()) {
0862: out.println();
0863: out.println("__caucho_load_callback();");
0864: }
0865:
0866: out.println("return " + index + ";");
0867: out.popDepth();
0868: out.println("}");
0869: }
0870:
0871: /**
0872: * Generates the load
0873: */
0874: void generateSetQuery(JavaWriter out, boolean isEntityParent)
0875: throws IOException {
0876: if (isEntityParent)
0877: return;
0878:
0879: out.println();
0880: out
0881: .println("public void __caucho_setKey(java.sql.PreparedStatement pstmt, int index)");
0882: out.println(" throws java.sql.SQLException");
0883: out.println("{");
0884: out.pushDepth();
0885:
0886: // jpa/0gg0 vs jpa/06c5
0887: if (!_relatedType.isAbstractClass())
0888: _relatedType.generateSet(out, "pstmt", "index", "super");
0889:
0890: out.popDepth();
0891: out.println("}");
0892: }
0893:
0894: /**
0895: * Generates the increment version
0896: */
0897: void generateIncrementVersion(JavaWriter out) throws IOException {
0898: out.println();
0899: out.println("public void __caucho_increment_version()");
0900: out.println("{");
0901: out.pushDepth();
0902:
0903: if (_relatedType instanceof EntityType) {
0904: out.println("if (__caucho_inc_version)");
0905: out.println(" return;");
0906: out.println();
0907: out.println("__caucho_inc_version = true;");
0908:
0909: VersionField version = _relatedType.getVersionField();
0910:
0911: if (version != null)
0912: version.generateIncrementVersion(out);
0913: }
0914:
0915: out.popDepth();
0916: out.println("}");
0917: }
0918:
0919: /**
0920: * Generates the flush
0921: */
0922: void generateFlush(JavaWriter out) throws IOException {
0923: out.println();
0924: out.println("protected void __caucho_flush_callback()");
0925: out.println(" throws java.sql.SQLException");
0926: out.println("{");
0927: out.println("}");
0928:
0929: out.println();
0930: out.println("public boolean __caucho_flush()");
0931: out.println(" throws java.sql.SQLException");
0932: out.println("{");
0933: out.pushDepth();
0934:
0935: boolean isAbstract = (_relatedType.getBeanClass().isAbstract() && _relatedType
0936: .getPersistenceUnit().isJPA());
0937:
0938: if (_relatedType.getId() == null || isAbstract) {
0939: // jpa/0ge6: MappedSuperclass
0940:
0941: out.println("return false;");
0942: out.popDepth();
0943: out.println("}");
0944:
0945: return;
0946: }
0947:
0948: out.println("if (__caucho_session == null)");
0949: out.println(" return false;");
0950: out.println();
0951:
0952: ArrayList<AmberField> fields = _relatedType.getFields();
0953:
0954: for (int i = 0; i < fields.size(); i++) {
0955: AmberField field = fields.get(i);
0956:
0957: if (field.isCascadable()) {
0958: CascadableField cascadable = (CascadableField) field;
0959:
0960: cascadable.generateFlushCheck(out);
0961:
0962: out.println();
0963: }
0964: }
0965:
0966: out.println();
0967: out
0968: .println("if (__caucho_state == com.caucho.amber.entity.EntityState.P_DELETED) {");
0969: out.println(" __caucho_delete_int();");
0970: out.println(" return true;");
0971: out.println("}");
0972: out
0973: .println("else if (__caucho_state == com.caucho.amber.entity.EntityState.P_PERSISTING) {");
0974: // jpa/0ga2
0975: out
0976: .println(" __caucho_create(__caucho_session, __caucho_home);");
0977: out.println("}");
0978: out
0979: .println("else if (__caucho_state == com.caucho.amber.entity.EntityState.P_PERSISTED) {");
0980: out.println(" __caucho_cascadePrePersist(__caucho_session);");
0981: out.println("}");
0982: out.println();
0983:
0984: out.println("boolean isDirty = false;");
0985:
0986: int dirtyCount = _relatedType.getDirtyIndex();
0987:
0988: for (int i = 0; i <= dirtyCount / 64; i++) {
0989: out.println("long mask_" + i + " = __caucho_dirtyMask_" + i
0990: + ";");
0991: out.println("__caucho_dirtyMask_" + i + " = 0L;");
0992: out.println("__caucho_updateMask_" + i + " |= mask_" + i
0993: + ";");
0994:
0995: out.println();
0996: out.println("if (mask_" + i + " != 0L)");
0997: out.println(" isDirty = true;");
0998: }
0999:
1000: out.println();
1001:
1002: // if (version == null)
1003: out.println("if (isDirty) {");
1004: out.pushDepth();
1005:
1006: // ejb/0605
1007: out.println();
1008: out.println("__caucho_flush_callback();");
1009:
1010: // else {
1011: // jpa/0x02
1012: // out.println("if (! (isDirty || " + version.generateIsNull() + "))");
1013: // }
1014: // out.println(" return true;");
1015:
1016: // jpa/0r10
1017: out.println("__caucho_home.preUpdate(this);");
1018:
1019: // jpa/0r10
1020: generateCallbacks(out, "this", _relatedType
1021: .getPreUpdateCallbacks());
1022:
1023: out
1024: .println("com.caucho.util.CharBuffer cb = new com.caucho.util.CharBuffer();");
1025:
1026: out.println("__caucho_home.generateUpdateSQLPrefix(cb);");
1027:
1028: out.println("boolean isFirst = true;");
1029:
1030: VersionField version = _relatedType.getVersionField();
1031:
1032: for (int i = 0; i <= dirtyCount / 64; i++) {
1033: // jpa/0x02 is a negative test.
1034: if (i != 0 || version == null) {
1035: out.println("if (mask_" + i + " != 0L)");
1036: out.print(" ");
1037: }
1038:
1039: out
1040: .println("isFirst = __caucho_home.generateUpdateSQLComponent(cb, "
1041: + i + ", mask_" + i + ", isFirst);");
1042: }
1043: out.println("__caucho_home.generateUpdateSQLSuffix(cb);");
1044:
1045: out.println();
1046: out.println("java.sql.PreparedStatement pstmt = null;");
1047: out.println("String sql = cb.toString();");
1048: out.println();
1049: out.println("try {");
1050: out.pushDepth();
1051:
1052: out.println("pstmt = __caucho_session.prepareStatement(sql);");
1053:
1054: out.println("int index = 1;");
1055:
1056: for (int i = 0; i < fields.size(); i++) {
1057: AmberField field = fields.get(i);
1058:
1059: field.generateUpdate(out, "mask", "pstmt", "index");
1060: }
1061:
1062: out.println();
1063: _relatedType.getId().generateSet(out, "pstmt", "index");
1064:
1065: if (version != null) {
1066: out.println();
1067: version.generateSet(out, "pstmt", "index");
1068: }
1069:
1070: out.println();
1071: out.println("int updateCount = pstmt.executeUpdate();");
1072: out.println();
1073:
1074: if (version != null) {
1075: out.println("if (updateCount == 0) {");
1076: out
1077: .println(" throw new javax.persistence.OptimisticLockException((com.caucho.amber.entity.Entity) this);");
1078: out.println("} else {");
1079: out.pushDepth();
1080: String value = version.generateGet("super");
1081: Type type = version.getColumn().getType();
1082: out.println(version.generateSuperSetter(type
1083: .generateIncrementVersion(value))
1084: + ";");
1085: out.popDepth();
1086: out.println("}");
1087: out.println();
1088: }
1089:
1090: out.println("__caucho_home.postUpdate(this);");
1091:
1092: generateCallbacks(out, "this", _relatedType
1093: .getPostUpdateCallbacks());
1094:
1095: out.println();
1096: out
1097: .println("if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
1098: out
1099: .println(" __caucho_log.fine(\"amber update \" + this.getClass().getName() + \" - PK: \" + __caucho_getPrimaryKey());");
1100:
1101: out.println();
1102: out.println("__caucho_inc_version = false;");
1103: out.println();
1104:
1105: out.popDepth();
1106: out.println("} catch (Exception e) {");
1107: out.println(" if (pstmt != null)");
1108: out.println(" __caucho_session.closeStatement(sql);");
1109: out.println();
1110: out.println(" if (e instanceof java.sql.SQLException)");
1111: out.println(" throw (java.sql.SQLException) e;");
1112: out.println();
1113: out.println(" if (e instanceof RuntimeException)");
1114: out.println(" throw (RuntimeException) e;");
1115: out.println();
1116: out
1117: .println(" throw new com.caucho.amber.AmberRuntimeException(e);");
1118: out.println("}");
1119:
1120: out.popDepth();
1121: out.println("}");
1122:
1123: out
1124: .println("if (__caucho_state == com.caucho.amber.entity.EntityState.P_PERSISTED) {");
1125: out.println(" __caucho_cascadePostPersist(__caucho_session);");
1126: out.println("}");
1127:
1128: out.println();
1129: out.println("return false;");
1130:
1131: out.popDepth();
1132: out.println("}");
1133: }
1134:
1135: /**
1136: * Generates the update
1137: */
1138: void generateFlushUpdate(JavaWriter out, boolean isEntityParent)
1139: throws IOException {
1140: out.println();
1141: out
1142: .println("protected void __caucho_flushUpdate(long mask, com.caucho.amber.type.EntityType home)");
1143: out.println(" throws java.sql.SQLException");
1144: out.println("{");
1145: out.pushDepth();
1146:
1147: if (isEntityParent) {
1148: out
1149: .println("super.__caucho_flushUpdate(mask, home.getParentType());");
1150: }
1151:
1152: out.println("String sql = home.generateUpdateSQL(mask);");
1153:
1154: out.println("if (sql != null) {");
1155: out.pushDepth();
1156:
1157: out
1158: .println("java.sql.PreparedStatement pstmt = __caucho_session.prepareStatement(sql);");
1159:
1160: out.println("int index = 1;");
1161:
1162: ArrayList<AmberField> fields = _relatedType.getFields();
1163: for (int i = 0; i < fields.size(); i++) {
1164: AmberField field = fields.get(i);
1165:
1166: field.generateUpdate(out, "mask", "pstmt", "index");
1167: }
1168:
1169: out.println();
1170: _relatedType.getId().generateSet(out, "pstmt", "index");
1171:
1172: out.println();
1173: out.println("pstmt.executeUpdate();");
1174:
1175: out.println();
1176: out
1177: .println("if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
1178: out
1179: .println(" __caucho_log.fine(\"amber update \" + this.getClass().getName() + \"[\" + __caucho_getPrimaryKey() + \"]\");");
1180:
1181: // println();
1182: // println("pstmt.close();");
1183:
1184: out.popDepth();
1185: out.println("}");
1186:
1187: out.popDepth();
1188: out.println("}");
1189: }
1190:
1191: /**
1192: * Generates the after-commit
1193: */
1194: void generateAfterCommit(JavaWriter out, boolean isEntityParent)
1195: throws IOException {
1196: // XXX: needs to handle this with subclasses
1197: // but there is an issue in the enhancer fixup
1198: // removing the "super." call.
1199: // if (_relatedType.getParentType() != null) {
1200: // out.println();
1201: // out.println("public void __caucho_super_afterCommit()");
1202: // out.println("{");
1203: // out.println(" super.__caucho_afterCommit();");
1204: // out.println("}");
1205: // }
1206:
1207: out.println();
1208: out.println("public void __caucho_afterCommit()");
1209: out.println("{");
1210: out.pushDepth();
1211:
1212: // ejb/06c9
1213: out
1214: .println("com.caucho.amber.entity.EntityState state = __caucho_state;");
1215: out.println();
1216:
1217: out
1218: .println("__caucho_state = com.caucho.amber.entity.EntityState.P_NON_TRANSACTIONAL;");
1219:
1220: out.println();
1221: out.println("if (__caucho_session == null) {");
1222:
1223: int dirtyCount = _relatedType.getDirtyIndex();
1224: for (int i = 0; i <= dirtyCount / 64; i++) {
1225: out.println(" __caucho_updateMask_" + i + " = 0L;");
1226: }
1227:
1228: out.println(" return;");
1229: out.println("}");
1230: out.println();
1231:
1232: // jpa/0h20, jpa/0l20, jpa/0l43
1233: out.println("if (__caucho_cacheItem == null)");
1234: out.println(" return;");
1235: out.println();
1236:
1237: // ejb/06c9
1238: out
1239: .println("if (com.caucho.amber.entity.EntityState.P_DELETING.ordinal() <= state.ordinal())");
1240: out.println(" return;");
1241: out.println();
1242:
1243: out.println("Object pk = __caucho_getPrimaryKey();");
1244: out
1245: .println("__caucho_session.getPersistenceUnit().updateCacheItem((com.caucho.amber.type.EntityType) __caucho_home.getRootType(), pk, this, __caucho_cacheItem);");
1246:
1247: out.popDepth();
1248: out.println("}");
1249: }
1250:
1251: /**
1252: * Generates the update cache item.
1253: */
1254: void generateUpdateCacheItem(JavaWriter out, boolean isEntityParent)
1255: throws IOException {
1256: out.println();
1257: out
1258: .println("public void __caucho_updateCacheItem(com.caucho.amber.entity.Entity cacheEntity)");
1259: out.println("{");
1260: out.pushDepth();
1261:
1262: out
1263: .println("com.caucho.amber.manager.AmberConnection aConn = __caucho_session;");
1264:
1265: out
1266: .println("com.caucho.amber.entity.EntityState state = __caucho_state;");
1267: int dirtyCount = _relatedType.getDirtyIndex();
1268: for (int i = 0; i <= dirtyCount / 64; i++) {
1269: out.println("long updateMask_" + i
1270: + " = __caucho_updateMask_" + i + ";");
1271: }
1272:
1273: for (int i = 0; i <= dirtyCount / 64; i++) {
1274: out.println("__caucho_updateMask_" + i + " = 0L;");
1275: }
1276:
1277: out.println();
1278: out.println(_extClassName + " item = (" + _extClassName
1279: + ") cacheEntity;");
1280:
1281: out.println("try {");
1282: out.pushDepth();
1283:
1284: // jpa/0o01
1285: out.println("Object child;");
1286:
1287: if (!isEntityParent) {
1288: // if loaded in transaction, then copy results
1289: // ejb/0600, ejb/0a06, ejb/0893
1290: out.println("if ((__caucho_loadMask_0 & 1L) != 0) {");
1291: out.pushDepth();
1292: out.println("item.__caucho_loadMask_0 = 1L;");
1293:
1294: _relatedType
1295: .generateCopyLoadObject(out, "item", "super", 0);
1296: }
1297:
1298: for (int i = 1; i <= _relatedType.getLoadGroupIndex(); i++) {
1299: String loadVar = "__caucho_loadMask_" + (i / 64);
1300: long mask = (1L << (i % 64));
1301:
1302: // jpa/0l02: if (_relatedType.isLoadGroupOwnedByType(i)) {
1303: out
1304: .println("if ((" + loadVar + " & " + mask
1305: + "L) != 0) {");
1306: out.pushDepth();
1307:
1308: _relatedType
1309: .generateCopyLoadObject(out, "item", "super", i);
1310:
1311: out.println("item." + loadVar + " |= " + mask + "L;");
1312:
1313: out.popDepth();
1314: out.println("}");
1315: //}
1316: }
1317:
1318: if (!isEntityParent) {
1319: out.popDepth();
1320: out.println("}");
1321: }
1322:
1323: for (int i = 0; i < _relatedType.getDirtyIndex(); i++) {
1324: int group = i / 64;
1325: long mask = (1L << (i % 64));
1326:
1327: if (_relatedType.isDirtyIndexOwnedByType(i)) {
1328: out.println("if ((updateMask_" + group + " & " + mask
1329: + "L) != 0) {");
1330: out.pushDepth();
1331:
1332: _relatedType.generateCopyUpdateObject(out, "item",
1333: "super", i);
1334:
1335: out.popDepth();
1336: out.println("}");
1337: }
1338: }
1339:
1340: out.popDepth();
1341: out.println("} catch (RuntimeException e) {");
1342: out.println(" throw e;");
1343: out.println("} catch (Exception e) {");
1344: out
1345: .println(" throw new com.caucho.amber.AmberRuntimeException(e);");
1346: out.println("}");
1347:
1348: out.popDepth();
1349: out.println("}");
1350: }
1351:
1352: /**
1353: * Generates the after-rollback
1354: */
1355: void generateAfterRollback(JavaWriter out) throws IOException {
1356: out.println();
1357: out.println("public void __caucho_afterRollback()");
1358: out.println("{");
1359: out.pushDepth();
1360:
1361: out
1362: .println("__caucho_state = com.caucho.amber.entity.EntityState.P_NON_TRANSACTIONAL;");
1363:
1364: int loadCount = _relatedType.getLoadGroupIndex();
1365: for (int i = 0; i <= loadCount / 64; i++) {
1366: out.println("__caucho_loadMask_" + i + " = 0L;");
1367: }
1368:
1369: int dirtyCount = _relatedType.getDirtyIndex();
1370: for (int i = 0; i <= dirtyCount / 64; i++) {
1371: out.println("__caucho_dirtyMask_" + i + " = 0L;");
1372: }
1373:
1374: out.popDepth();
1375: out.println("}");
1376: }
1377:
1378: String getDebug() {
1379: return "this";
1380: }
1381:
1382: /**
1383: * Generates the update
1384: */
1385: void generateCreate(JavaWriter out) throws IOException {
1386: boolean isAbstract = (_relatedType.getBeanClass().isAbstract() && _relatedType
1387: .getPersistenceUnit().isJPA());
1388:
1389: boolean isGeneratedValue = false;
1390:
1391: // jpa/0gg0
1392: if (_relatedType.getId() != null && !isAbstract) {
1393: ArrayList<IdField> fields = _relatedType.getId().getKeys();
1394: IdField idField = fields.size() > 0 ? fields.get(0) : null;
1395:
1396: boolean hasReturnGeneratedKeys = false;
1397:
1398: try {
1399: hasReturnGeneratedKeys = _relatedType
1400: .getPersistenceUnit().hasReturnGeneratedKeys();
1401: } catch (Exception e) {
1402: // Meta-data exception which is acceptable or
1403: // no data-source configured. The latter will
1404: // be thrown on web.xml validation. (ejb/06m0)
1405: }
1406:
1407: if (idField != null && idField.isAutoGenerate())
1408: isGeneratedValue = true;
1409:
1410: if (!hasReturnGeneratedKeys && idField != null
1411: && idField.getType().isAutoIncrement()) {
1412: out.println();
1413: out
1414: .println("private static com.caucho.amber.field.Generator __caucho_id_gen;");
1415: out.println("static {");
1416: out.pushDepth();
1417: out
1418: .println("com.caucho.amber.field.MaxGenerator gen = new com.caucho.amber.field.MaxGenerator();");
1419: out.print("gen.setColumn(\"");
1420: out.printJavaString(idField.getColumns().get(0)
1421: .generateInsertName());
1422: out.println("\");");
1423: out.print("gen.setTable(\"");
1424: out.printJavaString(_relatedType.getName());
1425: out.println("\");");
1426: out.println("gen.init();");
1427: out.popDepth();
1428: out.println("}");
1429: }
1430: }
1431:
1432: // jpa/0ga2
1433: out.println();
1434: out
1435: .println("public boolean __caucho_lazy_create(com.caucho.amber.manager.AmberConnection aConn, com.caucho.amber.type.EntityType home)");
1436: out.println(" throws java.sql.SQLException");
1437: out.println("{");
1438: out.pushDepth();
1439:
1440: int loadCount = 0;
1441:
1442: // jpa/0ge2: MappedSuperclassType
1443: if ((_relatedType.getTable() == null)
1444: || (_relatedType.getId() == null)) {
1445: out.println("return false;");
1446:
1447: out.popDepth();
1448: out.println("}");
1449: } else {
1450: out.println("if (__caucho_session != null)");
1451: out.println(" return true;");
1452: out.println();
1453:
1454: // commented out: jpa/0h25
1455: // out.println(" throw new com.caucho.amber.AmberException(\"object \" + " + getDebug() + " + \" is already persistent.\");");
1456:
1457: out
1458: .println("__caucho_state = com.caucho.amber.entity.EntityState.P_PERSISTING;");
1459:
1460: loadCount = _relatedType.getLoadGroupIndex();
1461: for (int i = 0; i <= loadCount / 64; i++) {
1462: out.println("__caucho_loadMask_" + i + " = 0L;");
1463:
1464: // XXX: jpa/0l21
1465:
1466: RelatedType parentType = _relatedType;
1467:
1468: do {
1469: out.println("__caucho_loadMask_" + i + " |= "
1470: + parentType.getCreateLoadMask(i) + ";");
1471: } while ((parentType = parentType.getParentType()) != null);
1472: }
1473:
1474: out.println();
1475: out.println("__caucho_session = aConn;");
1476: out.println("__caucho_home = home;");
1477:
1478: out.println("__caucho_home.prePersist(this);");
1479:
1480: // jpa/0r20
1481: for (JMethod method : _relatedType.getPrePersistCallbacks()) {
1482: out.println(method.getName() + "();");
1483: }
1484:
1485: if (isGeneratedValue) {
1486: // jpa/0g50: generated id needs to flush the insert statement at persist() time.
1487: out.println("__caucho_create(aConn, home);");
1488: } else {
1489: // jpa/0j5e: persist() is lazy but should cascade to add entities to the context.
1490: out.println();
1491: out.println("__caucho_cascadePrePersist(aConn);");
1492:
1493: out.println("__caucho_cascadePostPersist(aConn);");
1494: }
1495:
1496: out.println("__caucho_home.postPersist(this);");
1497:
1498: for (JMethod method : _relatedType
1499: .getPostPersistCallbacks()) {
1500: out.println(method.getName() + "();");
1501: }
1502:
1503: out.println();
1504: out.println("return true;");
1505:
1506: out.popDepth();
1507: out.println("}");
1508: }
1509:
1510: out.println();
1511: out
1512: .println("public boolean __caucho_create(com.caucho.amber.manager.AmberConnection aConn, com.caucho.amber.type.EntityType home)");
1513: out.println(" throws java.sql.SQLException");
1514: out.println("{");
1515: out.pushDepth();
1516:
1517: // jpa/0ge2: MappedSuperclassType
1518: if ((_relatedType.getTable() == null)
1519: || (_relatedType.getId() == null)) {
1520: out.println("return false;");
1521:
1522: out.popDepth();
1523: out.println("}");
1524:
1525: return;
1526: }
1527:
1528: out
1529: .println("if (__caucho_state != com.caucho.amber.entity.EntityState.P_PERSISTING)");
1530: out.println(" return false;");
1531:
1532: out.println();
1533: out
1534: .println("__caucho_state = com.caucho.amber.entity.EntityState.P_PERSISTED;");
1535:
1536: out.println();
1537: out.println("__caucho_cascadePrePersist(aConn);");
1538:
1539: int dirtyCount = _relatedType.getDirtyIndex();
1540: for (int i = 0; i <= dirtyCount / 64; i++) {
1541: out.println("__caucho_dirtyMask_" + i + " = 0L;");
1542: }
1543:
1544: Table table = _relatedType.getTable();
1545:
1546: String sql = null;
1547:
1548: out.println("String sql;");
1549:
1550: boolean isAutoInsert = false;
1551:
1552: // jpa/0gg0, jpa/0gh0
1553: if (_relatedType.getId() != null && !isAbstract
1554: && _relatedType.getId().isIdentityGenerator()) {
1555: isAutoInsert = true;
1556:
1557: out.print("sql = \"");
1558: out.printJavaString(_relatedType
1559: .generateAutoCreateSQL(table));
1560: out.println("\";");
1561: }
1562:
1563: _relatedType.getId().generateCheckCreateKey(out);
1564:
1565: if (!isAutoInsert) {
1566: out.print("sql = \"");
1567: out.printJavaString(_relatedType.generateCreateSQL(table));
1568: out.println("\";");
1569: }
1570:
1571: out.println();
1572: out
1573: .println("java.sql.PreparedStatement pstmt = aConn.prepareInsertStatement(sql);");
1574:
1575: out.println("int index = 1;");
1576:
1577: if (!isAutoInsert) {
1578: out.println();
1579: _relatedType.getId().generateSetInsert(out, "pstmt",
1580: "index");
1581: }
1582:
1583: _relatedType.generateInsertSet(out, table, "pstmt", "index",
1584: "super");
1585:
1586: out.println();
1587: out.println("pstmt.executeUpdate();");
1588:
1589: out.println();
1590: _relatedType.getId().generateSetGeneratedKeys(out, "pstmt");
1591:
1592: RelatedType parentType = _relatedType;
1593:
1594: do {
1595: for (Table subTable : parentType.getSecondaryTables()) {
1596: sql = parentType.generateCreateSQL(subTable);
1597:
1598: out.println();
1599: out.print("sql = \"");
1600: out.printJavaString(sql);
1601: out.println("\";");
1602:
1603: out.println("pstmt = aConn.prepareStatement(sql);");
1604:
1605: out.println("index = 1;");
1606:
1607: out.println();
1608: parentType.getId().generateSetInsert(out, "pstmt",
1609: "index");
1610:
1611: parentType.generateInsertSet(out, subTable, "pstmt",
1612: "index", "super");
1613:
1614: out.println();
1615: out.println("pstmt.executeUpdate();");
1616:
1617: out.println();
1618: parentType.getId().generateSetGeneratedKeys(out,
1619: "pstmt");
1620: }
1621: } while ((parentType = parentType.getParentType()) != null);
1622:
1623: // println("pstmt.close();");
1624:
1625: out
1626: .println("__caucho_cacheItem = new com.caucho.amber.entity.CacheableEntityItem(home.getHome(), new "
1627: + getClassName() + "());");
1628:
1629: out.println(getClassName() + " cacheEntity = ("
1630: + getClassName() + ") __caucho_cacheItem.getEntity();");
1631: out.println("cacheEntity.__caucho_home = home;");
1632:
1633: Id id = _relatedType.getId();
1634:
1635: out.println("Object pk = null;");
1636:
1637: if (!id.isEmbeddedId()) {
1638:
1639: ArrayList<IdField> keys = id.getKeys();
1640:
1641: for (IdField key : keys) {
1642: String value;
1643:
1644: if (keys.size() == 1)
1645: value = key.getType().generateCastFromObject(
1646: "(pk = __caucho_getPrimaryKey())");
1647: else
1648: value = key.generateGet("super");
1649:
1650: out
1651: .println(key.generateSet("cacheEntity", value)
1652: + ";");
1653: }
1654: } else {
1655: // jpa/0gh0
1656:
1657: id.generateCopy(out, "cacheEntity", "this");
1658:
1659: // out.println("pk = __caucho_compound_key;");
1660:
1661: // out.println(id.getEmbeddedIdField().generateSet("cacheEntity", "__caucho_compound_key") + ";");
1662: }
1663:
1664: out.println("try {");
1665: out.pushDepth();
1666:
1667: // jpa/0o01
1668: out.println("Object child;");
1669:
1670: // jpa/0l21
1671: for (int i = 0; i <= loadCount; i++) {
1672: _relatedType.generateCopyLoadObject(out, "cacheEntity",
1673: "super", i);
1674: }
1675:
1676: out.popDepth();
1677: out.println("} catch (RuntimeException e) {");
1678: out.println(" throw e;");
1679: out.println("} catch (Exception e) {");
1680: out
1681: .println(" throw new com.caucho.amber.AmberRuntimeException(e);");
1682: out.println("}");
1683:
1684: parentType = _relatedType;
1685:
1686: // jpa/0l21
1687: for (int i = 0; i <= loadCount / 64; i++) {
1688: out
1689: .println("cacheEntity.__caucho_loadMask_" + i
1690: + " = 0L;");
1691:
1692: do {
1693: out.println("cacheEntity.__caucho_loadMask_" + i
1694: + " |= " + parentType.getCreateLoadMask(i)
1695: + ";");
1696: } while ((parentType = parentType.getParentType()) != null);
1697: }
1698:
1699: out.println();
1700: out.println("if (pk == null)");
1701: out.println(" pk = __caucho_getPrimaryKey();");
1702:
1703: // jpa/0i5e, jpa/1641
1704: // caching entity must only occur after the commit completes to
1705: // handle rollbacks and also so the cache doesn't have an
1706: // item in the middle of a transaction
1707: /*
1708: out.println();
1709: out.println("aConn.getPersistenceUnit().putEntity((com.caucho.amber.type.EntityType) __caucho_home.getRootType(),");
1710: out.println(" pk, __caucho_cacheItem);");
1711: */
1712:
1713: out.println();
1714: out
1715: .println("if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
1716: out
1717: .println(" __caucho_log.fine(\"amber create \" + this.getClass().getName() + \"[\" + __caucho_getPrimaryKey() + \"]\");");
1718: out.println();
1719: out.println("if (aConn.isActiveTransaction()) {");
1720:
1721: // jpa/0i60
1722: // out.println(" __caucho_state = com.caucho.amber.entity.EntityState.P_TRANSACTIONAL;");
1723: out
1724: .println(" aConn.makeTransactional((com.caucho.amber.entity.Entity) this);");
1725: out.println("} else {");
1726: out
1727: .println(" __caucho_state = com.caucho.amber.entity.EntityState.P_NON_TRANSACTIONAL;");
1728: out.println("}");
1729:
1730: out.println();
1731:
1732: out.println();
1733: out.println("return false;");
1734:
1735: out.popDepth();
1736: out.println("}");
1737: }
1738:
1739: /**
1740: * Generates the delete
1741: */
1742: void generateDelete(JavaWriter out) throws IOException {
1743: out.println();
1744: out.println("public void __caucho_delete()");
1745: out.println("{");
1746: out.pushDepth();
1747:
1748: out
1749: .println("if (com.caucho.amber.entity.EntityState.P_DELETING.ordinal() <= __caucho_state.ordinal())");
1750: out.println(" return;");
1751: out.println();
1752:
1753: out.println("if (__caucho_home != null)");
1754: out.println(" __caucho_home.preRemove(this);");
1755: out.println();
1756:
1757: generateCallbacks(out, "this", _relatedType
1758: .getPreRemoveCallbacks());
1759:
1760: _relatedType.generatePreDelete(out);
1761:
1762: out
1763: .println("__caucho_state = com.caucho.amber.entity.EntityState.P_DELETING;");
1764:
1765: out.println("if (__caucho_session != null) {");
1766: out.pushDepth();
1767: out
1768: .println("__caucho_session.update((com.caucho.amber.entity.Entity) this);");
1769: out
1770: .println("__caucho_home.getTable().beforeEntityDelete(__caucho_session, (com.caucho.amber.entity.Entity) this);");
1771: out
1772: .println("__caucho_state = com.caucho.amber.entity.EntityState.P_DELETED;");
1773: _relatedType.generatePostDelete(out);
1774: out.popDepth();
1775: out.println("}");
1776: out.println("else");
1777: out
1778: .println(" __caucho_state = com.caucho.amber.entity.EntityState.P_DELETED;");
1779:
1780: out.popDepth();
1781: out.println("}");
1782:
1783: Id id = _relatedType.getId();
1784:
1785: out.println();
1786: out.println("private void __caucho_delete_int()");
1787: out.println(" throws java.sql.SQLException");
1788: out.println("{");
1789: out.pushDepth();
1790:
1791: // jpa/0ge2: MappedSuperclassType
1792: if ((_relatedType.getTable() == null) || (id == null)) {
1793: out.println("return;");
1794:
1795: out.popDepth();
1796: out.println("}");
1797:
1798: return;
1799: }
1800:
1801: out.println("java.sql.PreparedStatement pstmt = null;");
1802: out.println("String sql = null;");
1803: out.println();
1804:
1805: out.println("try {");
1806: out.pushDepth();
1807:
1808: out.print("__caucho_home.delete(__caucho_session, ");
1809: out.print(id.toObject(id.generateGetProperty("this")));
1810: out.println(");");
1811:
1812: out
1813: .println("__caucho_session.removeEntity((com.caucho.amber.entity.Entity) this);");
1814:
1815: String table = _relatedType.getTable().getName();
1816: String where = _relatedType.getId().generateMatchArgWhere(null);
1817:
1818: String sql = ("delete from " + table + " where " + where);
1819:
1820: out.print("sql = \"");
1821: out.printJavaString(sql);
1822: out.println("\";");
1823:
1824: out.println();
1825: out.println("pstmt = __caucho_session.prepareStatement(sql);");
1826:
1827: out.println("int index = 1;");
1828: id.generateSet(out, "pstmt", "index", "this");
1829:
1830: out.println();
1831: out.println("pstmt.executeUpdate();");
1832:
1833: out.println("__caucho_home.postRemove(this);");
1834:
1835: generateCallbacks(out, "this", _relatedType
1836: .getPostRemoveCallbacks());
1837:
1838: out.popDepth();
1839: out.println("} catch (Exception e) {");
1840: out.println(" if (pstmt != null)");
1841: out.println(" __caucho_session.closeStatement(sql);");
1842: out.println();
1843: out.println(" if (e instanceof java.sql.SQLException)");
1844: out.println(" throw (java.sql.SQLException) e;");
1845: out.println();
1846: out.println(" if (e instanceof RuntimeException)");
1847: out.println(" throw (RuntimeException) e;");
1848: out.println();
1849: out
1850: .println(" throw new com.caucho.amber.AmberRuntimeException(e);");
1851: out.println("}");
1852:
1853: out.popDepth();
1854: out.println("}");
1855: }
1856:
1857: /**
1858: * Generates the foreign delete
1859: */
1860: void generateDeleteForeign(JavaWriter out) throws IOException {
1861: out.println();
1862: out
1863: .println("public void __caucho_invalidate_foreign(String table, Object key)");
1864: out.println("{");
1865: out.pushDepth();
1866:
1867: _relatedType.generateInvalidateForeign(out);
1868:
1869: out.popDepth();
1870: out.println("}");
1871: }
1872:
1873: /**
1874: * Generates the cache load
1875: */
1876: void generateLoadFromObject(JavaWriter out, boolean isEntityParent)
1877: throws IOException {
1878: out.println();
1879: out.println("public void __caucho_loadFromObject(Object src)");
1880: out.println("{");
1881: out.pushDepth();
1882:
1883: out.println(getClassName() + " o = (" + getClassName()
1884: + ") src;");
1885:
1886: if (isEntityParent)
1887: out.println("super.__caucho_loadFromObject(src);");
1888: else {
1889: int loadCount = _relatedType.getLoadGroupIndex();
1890: for (int i = 0; i <= loadCount / 64; i++) {
1891: out.println("__caucho_loadMask_" + i
1892: + " = o.__caucho_loadMask_" + i + ";");
1893: }
1894: }
1895:
1896: int dirtyCount = _relatedType.getDirtyIndex();
1897: for (int i = 0; i <= dirtyCount / 64; i++) {
1898: out.println("__caucho_dirtyMask_" + i + " = 0;");
1899: }
1900:
1901: _relatedType.generateLoadFromObject(out, "o");
1902:
1903: /* XXX:
1904: if (Lifecycle.class.isAssignableFrom(_relatedType.getBeanClass())) {
1905: println("if (src instanceof com.caucho.ormap.Lifecycle)");
1906: println(" ((com.caucho.ormap.Lifecycle) src).afterLoad(__caucho_session, " +
1907: _relatedType.getId().getGetterName() + "());");
1908: }
1909: */
1910:
1911: out.popDepth();
1912: out.println("}");
1913: }
1914:
1915: /**
1916: * Generates the copy
1917: */
1918: /*
1919: void generateCopy(JavaWriter out)
1920: throws IOException
1921: {
1922: out.println();
1923: out.println("public com.caucho.amber.entity.Entity __caucho_copy()");
1924: out.println("{");
1925: out.pushDepth();
1926:
1927: out.println(getClassName() + " o = new " + getClassName() + "();");
1928:
1929: // can't load because it doesn't handle timeouts
1930: out.println("o.__caucho_loadFromObject((com.caucho.amber.entity.Entity) this);");
1931: out.println("o.__caucho_loadMask = 0;");
1932:
1933: out.println("return o;");
1934:
1935: out.popDepth();
1936: out.println("}");
1937: }
1938: */
1939:
1940: /**
1941: * Generates the create
1942: */
1943: void generateCopy(JavaWriter out) throws IOException {
1944: out.println();
1945: out
1946: .println("public com.caucho.amber.entity.Entity __caucho_copy(com.caucho.amber.manager.AmberConnection aConn,");
1947: out
1948: .println(" com.caucho.amber.entity.EntityItem item)");
1949: out.println("{");
1950: out.pushDepth();
1951:
1952: out.println(getClassName() + " o = new " + getClassName()
1953: + "();");
1954:
1955: out.println();
1956: out
1957: .println("return __caucho_copyTo((com.caucho.amber.entity.Entity) o, aConn, item);");
1958:
1959: out.popDepth();
1960: out.println("}");
1961:
1962: out.println();
1963: out
1964: .println("public com.caucho.amber.entity.Entity __caucho_copyTo(com.caucho.amber.entity.Entity targetEntity,");
1965: out
1966: .println(" com.caucho.amber.manager.AmberConnection aConn,");
1967: out
1968: .println(" com.caucho.amber.entity.EntityItem cacheItem)");
1969: out.println("{");
1970: out.pushDepth();
1971:
1972: out.println(getClassName() + " o = (" + getClassName()
1973: + ") targetEntity;");
1974:
1975: out.println("o.__caucho_cacheItem = cacheItem;");
1976: out.println();
1977: out
1978: .println("this.__caucho_copyTo((com.caucho.amber.entity.Entity) o, aConn);");
1979:
1980: out.println("o.__caucho_session = aConn;");
1981: out.println("o.__caucho_state = __caucho_state;"); // com.caucho.amber.entity.Entity.P_NON_TRANSACTIONAL;");
1982:
1983: for (int i = 0; i <= _relatedType.getLoadGroupIndex() / 64; i++) {
1984: String mask = "__caucho_loadMask_" + i;
1985:
1986: out.println("o." + mask + " = " + mask + ";");
1987: }
1988:
1989: int dirtyCount = _relatedType.getDirtyIndex();
1990:
1991: // jpa/0g06
1992: for (int i = 0; i <= dirtyCount / 64; i++) {
1993: String mask = "__caucho_dirtyMask_" + i;
1994:
1995: out.println("o." + mask + " = 0L;");
1996: }
1997:
1998: // jpa/0r00 vs. jpa/0r01
1999: // It will only copyTo() within a transaction if
2000: // the cache item is new, i.e. the very first load.
2001: out.println();
2002: out.println("if (! aConn.isActiveTransaction()) {");
2003: out.pushDepth();
2004:
2005: out.println("__caucho_home.postLoad(targetEntity);");
2006:
2007: // jpa/0r00: @PostLoad, without transaction.
2008: // When there is no transaction the entity is copied
2009: // directly from cache. The cache copy is the object
2010: // that is loaded in __caucho_load() and we cannot call
2011: // postLoad() there. After copyTo(), the targetEntity
2012: // has been loaded into the current persistence context
2013: // and it is safe to call the post load callbacks.
2014: generateCallbacks(out, "o", _relatedType.getPostLoadCallbacks());
2015:
2016: out.popDepth();
2017: out.println("}");
2018:
2019: out.println();
2020: out.println("return (com.caucho.amber.entity.Entity) o;");
2021:
2022: out.popDepth();
2023: out.println("}");
2024:
2025: out.println();
2026: out
2027: .println("public void __caucho_copyTo(com.caucho.amber.entity.Entity targetEntity,");
2028: out
2029: .println(" com.caucho.amber.manager.AmberConnection aConn)");
2030: out.println("{");
2031: out.pushDepth();
2032:
2033: out.println("__caucho_copyTo(targetEntity, aConn, false);");
2034:
2035: out.popDepth();
2036: out.println("}");
2037:
2038: out.println();
2039: out
2040: .println("public void __caucho_copyTo(com.caucho.amber.entity.Entity targetEntity,");
2041: out
2042: .println(" com.caucho.amber.manager.AmberConnection aConn,");
2043: out.println(" boolean isFullMerge)");
2044: out.println("{");
2045: out.pushDepth();
2046:
2047: out.println("if (this == targetEntity)");
2048: out.println(" return;");
2049: out.println();
2050:
2051: out.println(getClassName() + " o = (" + getClassName()
2052: + ") targetEntity;");
2053:
2054: out.println("if (o.__caucho_home == null)");
2055: out.println(" o.__caucho_home = __caucho_home;");
2056:
2057: // jpa/0ge6: MappedSuperclass
2058: if (_relatedType.getId() != null) {
2059: _relatedType.getId().generateCopy(out, "o", "super");
2060: }
2061:
2062: out.println("try {");
2063: out.pushDepth();
2064:
2065: // jpa/0o01
2066: out.println("Object child;");
2067:
2068: for (int i = 0; i <= _relatedType.getLoadGroupIndex(); i++) {
2069: // jpa/0l02
2070: _relatedType.generateCopyLoadObject(out, "o", "super", i);
2071: }
2072:
2073: out.popDepth();
2074: out.println("} catch (RuntimeException e) {");
2075: out.println(" throw e;");
2076: out.println("} catch (Exception e) {");
2077: out
2078: .println(" throw new com.caucho.amber.AmberRuntimeException(e);");
2079: out.println("}");
2080:
2081: out.popDepth();
2082: out.println("}");
2083:
2084: out.println();
2085: out
2086: .println("public void __caucho_merge(com.caucho.amber.entity.Entity targetEntity,");
2087: out
2088: .println(" com.caucho.amber.manager.AmberConnection aConn,");
2089: out.println(" boolean isFullMerge)");
2090: out.println("{");
2091: out.pushDepth();
2092:
2093: out.println("if (isFullMerge)");
2094: out
2095: .println(" this.__caucho_copyTo(targetEntity, aConn, true);");
2096: out.println();
2097:
2098: out.println(getClassName() + " other = (" + getClassName()
2099: + ") targetEntity;");
2100:
2101: for (int i = 0; i <= _relatedType.getLoadGroupIndex(); i++) {
2102: _relatedType.generateCopyMergeObject(out, "other", "super",
2103: i);
2104: }
2105:
2106: out.println();
2107: out.println("try {");
2108: out.pushDepth();
2109:
2110: // jpa/1622
2111: out.println("targetEntity.__caucho_cascadePostPersist(aConn);");
2112:
2113: out.popDepth();
2114: out.println("} catch (java.sql.SQLException e) {");
2115: out
2116: .println(" throw new com.caucho.amber.AmberRuntimeException(e);");
2117: out.println("}");
2118:
2119: out.popDepth();
2120: out.println("}");
2121:
2122: out.println();
2123: out
2124: .println("public void __caucho_copyDirtyMaskFrom(com.caucho.amber.entity.Entity sourceEntity)");
2125: out.println("{");
2126: out.pushDepth();
2127:
2128: out.println(getClassName() + " o = (" + getClassName()
2129: + ") sourceEntity;");
2130:
2131: for (int i = 0; i <= dirtyCount / 64; i++) {
2132: out.println("__caucho_dirtyMask_" + i
2133: + " = o.__caucho_dirtyMask_" + i + ";");
2134: }
2135:
2136: out.popDepth();
2137: out.println("}");
2138:
2139: out.println();
2140: out
2141: .println("public void __caucho_copyLoadMaskFrom(com.caucho.amber.entity.Entity sourceEntity)");
2142: out.println("{");
2143: out.pushDepth();
2144:
2145: out.println(getClassName() + " o = (" + getClassName()
2146: + ") sourceEntity;");
2147:
2148: int loadCount = _relatedType.getLoadGroupIndex();
2149:
2150: for (int i = 0; i <= loadCount / 64; i++) {
2151: out.println("__caucho_loadMask_" + i
2152: + " = o.__caucho_loadMask_" + i + ";");
2153: }
2154:
2155: out.popDepth();
2156: out.println("}");
2157: }
2158:
2159: void generateSetLoadMask(JavaWriter out) throws IOException {
2160: out.println();
2161: out.println("public long __caucho_getLoadMask(int loadGroup)");
2162: out.println("{");
2163: out.pushDepth();
2164:
2165: out.println("switch (loadGroup) {");
2166: out.pushDepth();
2167:
2168: int loadCount = _relatedType.getLoadGroupIndex();
2169:
2170: for (int i = 0; i <= loadCount / 64; i++) {
2171: out.println("case " + i + ":");
2172: out.println(" return __caucho_loadMask_" + i + ";");
2173: }
2174:
2175: out.popDepth();
2176: out.println("}");
2177:
2178: out.println("return 0;");
2179:
2180: out.popDepth();
2181: out.println("}");
2182:
2183: out.println();
2184: out
2185: .println("public void __caucho_setLoadMask(long loadMask, int loadGroup)");
2186: out.println("{");
2187: out.pushDepth();
2188:
2189: out.println("switch (loadGroup) {");
2190: out.pushDepth();
2191:
2192: for (int i = 0; i <= loadCount / 64; i++) {
2193: out.println("case " + i + ":");
2194: out.println(" __caucho_loadMask_" + i + " = loadMask;");
2195: out.println(" break;");
2196: }
2197:
2198: out.popDepth();
2199: out.println("}");
2200:
2201: out.popDepth();
2202: out.println("}");
2203: }
2204:
2205: /**
2206: * Generates the copy
2207: */
2208: void generateMakePersistent(JavaWriter out) throws IOException {
2209: out.println();
2210: out
2211: .println("public void __caucho_makePersistent(com.caucho.amber.manager.AmberConnection aConn,");
2212: out
2213: .println(" com.caucho.amber.entity.EntityItem cacheItem)");
2214: out.println("{");
2215: out.pushDepth();
2216:
2217: out.println(_extClassName + " entity = (" + _extClassName
2218: + ") cacheItem.getEntity();");
2219:
2220: out.println("__caucho_home = entity.__caucho_home;");
2221: out
2222: .println("if (__caucho_home == null) throw new NullPointerException();");
2223: out.println("__caucho_cacheItem = cacheItem;");
2224:
2225: // jpa/0ge6: MappedSuperclass
2226: if (_relatedType.getId() != null) {
2227: _relatedType.getId().generateCopy(out, "super", "entity");
2228: }
2229:
2230: out.println("__caucho_session = aConn;");
2231:
2232: out
2233: .println("__caucho_state = com.caucho.amber.entity.EntityState.P_NON_TRANSACTIONAL;");
2234:
2235: out.popDepth();
2236: out.println("}");
2237: }
2238:
2239: /**
2240: * Generates the cascade persist
2241: */
2242: void generateCascadePersist(JavaWriter out) throws IOException {
2243: out.println();
2244: out
2245: .println("public void __caucho_cascadePrePersist(com.caucho.amber.manager.AmberConnection aConn)");
2246: out.println(" throws java.sql.SQLException");
2247: out.println("{");
2248: out.pushDepth();
2249:
2250: // jpa/0i60
2251: /*
2252: out.println("if (__caucho_state == com.caucho.amber.entity.EntityState.P_TRANSACTIONAL)");
2253: out.println(" __caucho_state = com.caucho.amber.entity.EntityState.P_PERSIST;");
2254: */
2255:
2256: // out.println("if (aConn == null)");
2257: // out.println(" throw new com.caucho.amber.AmberException(\"Null AmberConnection when object \" + " + getDebug() + " + \" is trying to cascade persist child objects.\");");
2258: ArrayList<AmberField> fields = _relatedType.getFields();
2259:
2260: for (int i = 0; i < fields.size(); i++) {
2261: AmberField field = fields.get(i);
2262:
2263: if (field.isCascadable()) {
2264: CascadableField cascadable = (CascadableField) field;
2265:
2266: out.println();
2267:
2268: cascadable.generatePreCascade(out, "aConn",
2269: CascadeType.PERSIST);
2270: }
2271: }
2272:
2273: out.popDepth();
2274: out.println("}");
2275:
2276: out.println();
2277: out
2278: .println("public void __caucho_cascadePostPersist(com.caucho.amber.manager.AmberConnection aConn)");
2279: out.println(" throws java.sql.SQLException");
2280: out.println("{");
2281: out.pushDepth();
2282:
2283: for (int i = 0; i < fields.size(); i++) {
2284: AmberField field = fields.get(i);
2285:
2286: if (field.isCascadable()) {
2287: CascadableField cascadable = (CascadableField) field;
2288:
2289: out.println();
2290:
2291: cascadable.generatePostCascade(out, "aConn",
2292: CascadeType.PERSIST);
2293: }
2294: }
2295:
2296: out.popDepth();
2297: out.println("}");
2298: }
2299:
2300: /**
2301: * Generates the cascade remove
2302: */
2303: void generateCascadeRemove(JavaWriter out) throws IOException {
2304: out.println();
2305: out
2306: .println("public void __caucho_cascadePreRemove(com.caucho.amber.manager.AmberConnection aConn)");
2307: out.println(" throws java.sql.SQLException");
2308: out.println("{");
2309: out.pushDepth();
2310:
2311: ArrayList<AmberField> fields = _relatedType.getFields();
2312:
2313: for (int i = 0; i < fields.size(); i++) {
2314: AmberField field = fields.get(i);
2315:
2316: if (field.isCascadable()) {
2317: CascadableField cascadable = (CascadableField) field;
2318:
2319: out.println();
2320:
2321: cascadable.generatePreCascade(out, "aConn",
2322: CascadeType.REMOVE);
2323: }
2324: }
2325:
2326: out.popDepth();
2327: out.println("}");
2328:
2329: out.println();
2330: out
2331: .println("public void __caucho_cascadePostRemove(com.caucho.amber.manager.AmberConnection aConn)");
2332: out.println(" throws java.sql.SQLException");
2333: out.println("{");
2334: out.pushDepth();
2335:
2336: for (int i = 0; i < fields.size(); i++) {
2337: AmberField field = fields.get(i);
2338:
2339: if (field.isCascadable()) {
2340: CascadableField cascadable = (CascadableField) field;
2341:
2342: out.println();
2343:
2344: cascadable.generatePostCascade(out, "aConn",
2345: CascadeType.REMOVE);
2346: }
2347: }
2348:
2349: out.popDepth();
2350: out.println("}");
2351: }
2352:
2353: /**
2354: * Generates the home methods
2355: */
2356: void generateHome(JavaWriter out) throws IOException {
2357: generateHomeFind(out);
2358:
2359: boolean generateHomeNew = true;
2360:
2361: // jpa/0ge2
2362: if (_relatedType instanceof MappedSuperclassType)
2363: generateHomeNew = false;
2364:
2365: /* XXX
2366: if (_relatedType instanceof SubEntityType) {
2367: SubEntityType sub = (SubEntityType) _relatedType;
2368:
2369: // jpa/0ge2
2370: if (! sub.isParentMappedSuperclass()) {
2371: if (! sub.getParentType().isAbstractClass())
2372: generateHomeNew = false;
2373: }
2374: }
2375: */
2376:
2377: if (generateHomeNew) {
2378: generateHomeNew(out);
2379: generateHomeFindNew(out);
2380: }
2381: }
2382:
2383: /**
2384: * Generates the load key.
2385: */
2386: void generateLoadKey(JavaWriter out) throws IOException {
2387: out.println();
2388: out.print("public Object __caucho_load_key(");
2389: out.print("com.caucho.amber.manager.AmberConnection aConn,");
2390: out.println("java.sql.ResultSet rs, int index)");
2391: out.println(" throws java.sql.SQLException");
2392: out.println("{");
2393: out.pushDepth();
2394:
2395: boolean isAbstract = (_relatedType.getBeanClass().isAbstract() && _relatedType
2396: .getPersistenceUnit().isJPA());
2397:
2398: // jpa/0gg0
2399: if (_relatedType.getId() == null || isAbstract) {
2400: // jpa/0ge6: MappedSuperclass
2401:
2402: out.println("return null;");
2403: out.popDepth();
2404: out.println("}");
2405:
2406: return;
2407: }
2408:
2409: out.print("return ");
2410: int index = _relatedType.getId().generateLoadForeign(out, "rs",
2411: "index", 0);
2412: out.println(";");
2413:
2414: out.popDepth();
2415: out.println("}");
2416: }
2417:
2418: /**
2419: * Generates the home methods
2420: */
2421: void generateHomeFind(JavaWriter out) throws IOException {
2422: out.println();
2423: out
2424: .print("public com.caucho.amber.entity.EntityItem __caucho_home_find(");
2425: out.print("com.caucho.amber.manager.AmberConnection aConn,");
2426: out.print("com.caucho.amber.entity.AmberEntityHome home,");
2427: out.println("java.sql.ResultSet rs, int index)");
2428: out.println(" throws java.sql.SQLException");
2429: out.println("{");
2430: out.pushDepth();
2431:
2432: boolean isAbstract = (_relatedType.getBeanClass().isAbstract() && _relatedType
2433: .getPersistenceUnit().isJPA());
2434:
2435: if (_relatedType.getId() == null || isAbstract) {
2436: // jpa/0ge6: MappedSuperclass
2437:
2438: out.println("return null;");
2439: out.popDepth();
2440: out.println("}");
2441:
2442: return;
2443: }
2444:
2445: out.print("Object key = ");
2446: int index = _relatedType.getId().generateLoadForeign(out, "rs",
2447: "index", 0);
2448: out.println(";");
2449:
2450: if (_relatedType.getDiscriminator() == null) {
2451: out
2452: .println("return aConn.loadCacheItem(home.getJavaClass(), key, home);");
2453: } else {
2454: out.println("String discriminator = rs.getString(index + "
2455: + index + ");");
2456: out.println();
2457: out
2458: .println("return home.findDiscriminatorEntityItem(aConn, key, discriminator);");
2459: }
2460:
2461: out.popDepth();
2462: out.println("}");
2463: }
2464:
2465: /**
2466: * Generates the home methods
2467: */
2468: /*
2469: void generateHomeNew(JavaWriter out)
2470: throws IOException
2471: {
2472: out.println();
2473: out.print("public com.caucho.amber.entity.Entity __caucho_home_new(");
2474: out.print("com.caucho.amber.manager.AmberConnection aConn,");
2475: out.print("com.caucho.amber.entity.AmberEntityHome home,");
2476: out.print("Object key)");
2477: out.println(" throws java.sql.SQLException");
2478: out.println("{");
2479: out.println(" return __caucho_home_new(aConn, home, key, true);");
2480: out.println("}");
2481:
2482: out.println();
2483: out.print("public com.caucho.amber.entity.Entity __caucho_home_new(");
2484: out.print("com.caucho.amber.manager.AmberConnection aConn,");
2485: out.print("com.caucho.amber.entity.AmberEntityHome home,");
2486: out.print("Object key,");
2487: out.print("boolean loadFromResultSet)");
2488: out.println(" throws java.sql.SQLException");
2489: out.println("{");
2490: out.pushDepth();
2491:
2492: if (_relatedType.isAbstractClass() || _relatedType.getId() == null) {
2493: out.println("return null;");
2494: out.popDepth();
2495: out.println("}");
2496: return;
2497: }
2498:
2499: String rootTableName = _relatedType.getRootTableName();
2500:
2501: if (rootTableName == null)
2502: rootTableName = "";
2503:
2504: out.println("java.sql.ResultSet rs" + rootTableName + " = null;");
2505: out.println("java.sql.PreparedStatement pstmt" + rootTableName + " = null;");
2506: out.println("String sql" + rootTableName + " = null;");
2507: out.println();
2508: out.println("try {");
2509: out.pushDepth();
2510:
2511: Column discriminator = _relatedType.getDiscriminator();
2512:
2513: if (discriminator == null) {
2514: // Adds the copy object to the context before anything.
2515: // This will avoid the cache object to be added to the context.
2516: out.println("com.caucho.amber.entity.Entity copy = aConn.addNewEntity(" + getClassName() + ".class, key);");
2517:
2518: out.println(getClassName() + " entity = (" + getClassName() + ") __caucho_home_new();");
2519:
2520: out.println("entity.__caucho_home = home.getEntityType();");
2521: out.println("entity.__caucho_setPrimaryKey(key);");
2522:
2523: /*
2524: out.println();
2525: out.println("if (copy == null) {");
2526: out.pushDepth();
2527:
2528: // jpa/0l42: eagerly loading optimization.
2529: out.println("copy = aConn.getEntity(entity);");
2530:
2531: out.println("((com.caucho.amber.entity.Entity) entity).__caucho_copyLoadMaskFrom(copy);");
2532:
2533: // jpa/0o05
2534: out.println("copy.__caucho_copyTo(((com.caucho.amber.entity.Entity) entity), aConn);");
2535:
2536: out.popDepth();
2537: out.println("}");
2538: out.println();
2539:
2540: out.println("return (com.caucho.amber.entity.Entity) entity;");
2541: }
2542: else {
2543: // jpa/0l40: inheritance optimization.
2544: out.println("try {");
2545:
2546: String keyType = _relatedType.getId().getForeignTypeName();
2547:
2548: out.println(" __caucho_session = aConn;");
2549: out.println(" __caucho_loadMask_0 = 0L;");
2550: out.println(" __caucho_cacheItem = null;");
2551: out.println();
2552: out.println(" __caucho_setPrimaryKey((" + keyType + ") key);");
2553: out.println(" __caucho_load_0(aConn);");
2554: out.println("} catch (com.caucho.amber.AmberObjectNotFoundException e) {");
2555: out.println(" return null;");
2556: out.println("}");
2557:
2558: // generateHomeNewLoading(out, rootTableName);
2559:
2560: out.println("com.caucho.amber.entity.EntityItem item = home.findDiscriminatorEntityItem(aConn, key, __caucho_discriminator);"); // rs" + rootTableName + ".getString(1));");
2561:
2562: // Adds the copy object to the context before anything.
2563: // This will avoid the cache object to be added to the context.
2564: out.println("com.caucho.amber.entity.Entity copy = aConn.addNewEntity(item.getEntity().getClass(), key);");
2565:
2566: out.println();
2567: out.println("if (copy == null) {");
2568: out.pushDepth();
2569:
2570: // jpa/0l47: eagerly loading optimization.
2571: out.println("copy = aConn.getEntity(cacheItem.getEntity());");
2572:
2573: out.println("item.getEntity().__caucho_copyLoadMaskFrom(copy);");
2574:
2575: // jpa/0o05
2576: out.println("copy.__caucho_copyTo(item.getEntity(), aConn);");
2577:
2578: out.popDepth();
2579: out.println("}");
2580: out.println();
2581:
2582: // jpa/0l03
2583: out.println("if (loadFromResultSet) {");
2584: out.pushDepth();
2585:
2586: // generateHomeNewLoading(out, null);
2587:
2588: out.println("item.getEntity().__caucho_load(aConn, rs" + rootTableName + ", 1);");
2589:
2590: out.popDepth();
2591: out.println("}");
2592:
2593: // jpa/0l40
2594: out.println("item.getEntity().__caucho_setLoadMask(1L, 0);");
2595: out.println("__caucho_copyTo(item.getEntity(), aConn, true);");
2596:
2597: // jpa/0l00
2598: // out.println(getClassName() + " entity = (" + getClassName() + ") item.copy(aConn);");
2599: // out.println("return (com.caucho.amber.entity.Entity) entity;");
2600:
2601: out.println("return (com.caucho.amber.entity.Entity) item.getEntity();");
2602: }
2603:
2604: out.popDepth();
2605: out.println("} catch (Exception e) {");
2606: out.println(" if (pstmt" + rootTableName + " != null)");
2607: out.println(" aConn.closeStatement(sql" + rootTableName + ");");
2608: out.println();
2609: out.println(" if (e instanceof java.sql.SQLException)");
2610: out.println(" throw (java.sql.SQLException) e;");
2611: out.println();
2612: out.println(" if (e instanceof RuntimeException)");
2613: out.println(" throw (RuntimeException) e;");
2614: out.println();
2615: out.println(" throw new com.caucho.amber.AmberRuntimeException(e);");
2616: out.println("}");
2617: out.println("finally {");
2618: out.println(" if (rs" + rootTableName + " != null)");
2619: out.println(" rs" + rootTableName + ".close();");
2620: out.println("}");
2621:
2622: out.popDepth();
2623: out.println("}");
2624:
2625: out.println();
2626: out.print("protected com.caucho.amber.entity.Entity __caucho_home_new()");
2627: out.println("{");
2628: out.println(" return new " + getClassName() + "();");
2629: out.println("}");
2630: }
2631: */
2632:
2633: void generateHomeNew(JavaWriter out) throws IOException {
2634: out.println();
2635: out
2636: .print("public com.caucho.amber.entity.Entity __caucho_home_new(");
2637: out.print("com.caucho.amber.entity.AmberEntityHome home");
2638: out.println(", Object key");
2639: out.println(", AmberConnection aConn");
2640: out.println(", EntityItem cacheItem");
2641: out.println(")");
2642: out.println("{");
2643: out.pushDepth();
2644:
2645: if (_relatedType.isAbstractClass()
2646: || _relatedType.getId() == null) {
2647: out.println("return null;");
2648: out.popDepth();
2649: out.println("}");
2650: return;
2651: }
2652:
2653: out.println(getClassName() + " entity = new " + getClassName()
2654: + "();");
2655:
2656: out.println("entity.__caucho_home = home.getEntityType();");
2657: out.println("entity.__caucho_setPrimaryKey(key);");
2658: out.println("entity.__caucho_session = aConn;");
2659: out.println("entity.__caucho_cacheItem = cacheItem;");
2660:
2661: out.println("return entity;");
2662:
2663: out.popDepth();
2664: out.println("}");
2665: }
2666:
2667: void generateHomeFindNew(JavaWriter out) throws IOException {
2668: RelatedType parentType = _relatedType.getParentType();
2669:
2670: // jpa/0ge3
2671: // jpa/0l32: find(SubBean.class, "2") would try to select the
2672: // discriminator column from the "sub-table".
2673: if (parentType != null && (parentType instanceof EntityType)
2674: && !parentType.isAbstractClass()) {
2675: return;
2676: }
2677:
2678: out.println();
2679: out
2680: .print("public com.caucho.amber.entity.Entity __caucho_home_find(");
2681: out.print("com.caucho.amber.manager.AmberConnection aConn, ");
2682: out.print("com.caucho.amber.entity.AmberEntityHome home, ");
2683: out.println("Object key)");
2684: out.println("{");
2685: out.pushDepth();
2686:
2687: Column discriminator = _relatedType.getDiscriminator();
2688:
2689: if (_relatedType.isAbstractClass()
2690: || _relatedType.getId() == null
2691: || discriminator == null) {
2692: out
2693: .println("return __caucho_home_new(home, key, aConn, null);");
2694: out.popDepth();
2695: out.println("}");
2696: return;
2697: }
2698:
2699: String rootTableName = _relatedType.getRootTableName();
2700:
2701: if (rootTableName == null)
2702: rootTableName = "";
2703:
2704: out.println("java.sql.ResultSet rs = null;");
2705: out.println("java.sql.PreparedStatement pstmt = null;");
2706: out.println("String sql = null;");
2707: out.println();
2708: out.println("try {");
2709: out.pushDepth();
2710:
2711: String keyType = _relatedType.getId().getForeignTypeName();
2712:
2713: String discriminatorVar = "discriminator";
2714:
2715: out.println("String " + discriminatorVar + " = null;");
2716:
2717: generateHomeNewLoading(out, discriminatorVar);
2718:
2719: out
2720: .println("com.caucho.amber.entity.Entity entity = home.newDiscriminatorEntity(key, "
2721: + discriminatorVar + ");");
2722:
2723: out.println("entity.__caucho_load(aConn, rs, 1);");
2724:
2725: out.println("return entity;");
2726:
2727: out.popDepth();
2728: out.println("} catch (RuntimeException e) {");
2729: out.println(" throw e;");
2730: out.println("} catch (Exception e) {");
2731: out
2732: .println(" throw new com.caucho.amber.AmberRuntimeException(e);");
2733: out.println("} finally {");
2734: /*
2735: out.println(" if (rs != null)");
2736: out.println(" rs.close();");
2737: out.println(" if (pstmt != null)");
2738: out.println(" aConn.closeStatement(sql);");
2739: */
2740: out.println("}");
2741:
2742: out.popDepth();
2743: out.println("}");
2744: }
2745:
2746: /**
2747: * Generates the loading for home_new
2748: */
2749: void generateHomeNewLoading(JavaWriter out, String discriminatorVar)
2750: throws IOException {
2751: out.print("sql = \"select ");
2752:
2753: RelatedType parentType = _relatedType;
2754:
2755: /* XXX: jpa/0gg3
2756: // jpa/0l32
2757: if (_relatedType.getDiscriminator() != null) {
2758: while (parentType.getParentType() != null)
2759: parentType = parentType.getParentType();
2760: }
2761: */
2762:
2763: out.printJavaString(parentType.generateLoadSelect("o"));
2764: out.print(" from ");
2765:
2766: /*
2767: if (rootTableName == null)
2768: out.print(_relatedType.getTable().getName());
2769: else
2770: out.print(rootTableName);
2771: */
2772: out.printJavaString(_relatedType.getTable().getName());
2773:
2774: out.print(" o where ");
2775: // jpa/0s27
2776: out.printJavaString((parentType.getId()
2777: .generateMatchArgWhere("o")));
2778: out.println("\";");
2779:
2780: out.println("pstmt = aConn.prepareStatement(sql);");
2781:
2782: String keyType = _relatedType.getId().getForeignTypeName();
2783:
2784: out
2785: .println(keyType + " " + "keyValue = (" + keyType
2786: + ") key;");
2787:
2788: out.println("int index = 1;");
2789: _relatedType.getId().generateSetKey(out, "pstmt", "index",
2790: "keyValue");
2791:
2792: out.println("rs = pstmt.executeQuery();");
2793: out.println("if (rs.next()) {");
2794: out.println(" " + discriminatorVar + " = rs.getString(1);"); // XXX:
2795:
2796: out.println("}");
2797: }
2798:
2799: void generateCallbacks(JavaWriter out, String object,
2800: ArrayList<JMethod> callbacks) throws IOException {
2801: if (callbacks.size() > 0) {
2802:
2803: out.println();
2804:
2805: for (JMethod method : callbacks) {
2806: out.println(object + "." + method.getName() + "();");
2807: }
2808: }
2809: }
2810:
2811: void generateInternals(JavaWriter out) throws IOException {
2812: out.println();
2813: out
2814: .println("private void __caucho_setInternalString(java.sql.PreparedStatement pstmt, int index, String s)");
2815: out.println(" throws java.sql.SQLException");
2816: out.println("{");
2817: out.pushDepth();
2818: out.println("if (s == null)");
2819: out.println(" pstmt.setNull(index, java.sql.Types.VARCHAR);");
2820: out.println("else");
2821: out.println(" pstmt.setString(index, s);");
2822: out.popDepth();
2823: out.println("}");
2824: }
2825: }
|