001: /**
002: * Copyright (C) 2001-2005 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.generation.enhancer.pc.jdo;
018:
019: import org.objectweb.asm.ClassVisitor;
020: import org.objectweb.asm.CodeVisitor;
021: import org.objectweb.asm.Label;
022: import org.objectweb.asm.Type;
023: import org.objectweb.speedo.generation.api.SpeedoCompilerParameter;
024: import org.objectweb.speedo.generation.enhancer.pc.AbstractPCModifier;
025: import org.objectweb.speedo.generation.enhancer.pc.POVariableNames;
026: import org.objectweb.speedo.lib.Personality;
027: import org.objectweb.speedo.metadata.SpeedoClass;
028: import org.objectweb.speedo.mim.jdo.api.JDOPersistentObjectItf;
029: import org.objectweb.util.monolog.api.Logger;
030:
031: import javax.jdo.spi.PersistenceCapable;
032:
033: /**
034: * Is an ASM visitor adding the implementation of the PersistenceCapable
035: * interface.
036: *
037: * @author S.Chassande-Barrioz
038: */
039: public class JDOPersistenceCapableAdder extends AbstractPCModifier
040: implements POVariableNames {
041:
042: public JDOPersistenceCapableAdder(ClassVisitor classVisitor,
043: Logger logger, SpeedoClass sc, SpeedoCompilerParameter cp,
044: Personality p) {
045: super (classVisitor, logger, sc, cp, p);
046: }
047:
048: public void visit(final int version, final int access,
049: final String name, final String super Name,
050: final String[] interfaces, final String sourceFile) {
051: String[] itfs;
052: if (interfaces != null && interfaces.length > 0) {
053: itfs = new String[interfaces.length + 2];
054: System.arraycopy(interfaces, 0, itfs, 2, interfaces.length);
055: } else {
056: itfs = new String[2];
057: }
058: itfs[0] = Type.getInternalName(PersistenceCapable.class);
059: itfs[1] = Type.getInternalName(JDOPersistentObjectItf.class);
060: cv.visit(version, access, name, super Name, itfs, sourceFile);
061: }
062:
063: public void visitEnd() {
064: generateJdoGetPersistenceManagerMethod();
065: generateJdoReplaceFlagsMethod();
066: generateJdoNewInstanceSMMethod();
067: generateJdoNewInstanceSMOMethod();
068: generateJdoNewObjectIdInstanceMethod();
069: generateJdoGetObjectIdMethod();
070: generateJdoGetTransactionalObjectIdMethod();
071: generateJdoReplaceFieldIMethod();
072: generateJdoReplaceFieldAIMethod();
073: generateJdoProvideFieldIMethod();
074: generateJdoProvideFieldAIMethod();
075: generateJdoCopyFieldsMethod();
076: generateJdoCopyKeyFieldsToObjectIdOIFMMethod();
077: generateJdoCopyKeyFieldsToObjectIdOMethod();
078: generateJdoCopyKeyFieldsToObjectIdOIFSMethod();
079: generateJdoCopyKeyFieldsFromObjectIdMethod();
080: generateJdoMakeDirtyMethod();
081: generateJdoIsDirtyMethod();
082: generateJdoIsTransactionalMethod();
083: generateJdoIsPersistentMethod();
084: generateJdoIsNewMethod();
085: generateJdoIsDeletedMethod();
086: generateJdoIsDetachedMethod();
087: generateJdoReplaceObjectIdMethod();
088: generateJdoReplaceStateManagerMethod();
089: super .visitEnd();
090: }
091:
092: private void generateReturnFalseIfNotIsActive(CodeVisitor mv) {
093: //if (!speedoIsActive) {
094: // return false;
095: //}
096: mv.visitVarInsn(ALOAD, 0);
097: mv.visitFieldInsn(GETFIELD, classToWrite, ISACTIVE_FIELD_NAME,
098: "Z");
099: Label l1 = new Label();
100: mv.visitJumpInsn(IFNE, l1);
101: mv.visitInsn(ICONST_0);
102: mv.visitInsn(IRETURN);
103: mv.visitLabel(l1);
104: }
105:
106: private void generateThrowJDOUnsupportedOptionException(
107: CodeVisitor mv) {
108: mv
109: .visitTypeInsn(NEW,
110: "javax/jdo/JDOUnsupportedOptionException");
111: mv.visitInsn(DUP);
112: mv.visitMethodInsn(INVOKESPECIAL,
113: "javax/jdo/JDOUnsupportedOptionException", "<init>",
114: "()V");
115: mv.visitInsn(ATHROW);
116: }
117:
118: private void generateJdoGetPersistenceManagerMethod() {
119: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC,
120: "jdoGetPersistenceManager",
121: "()Ljavax/jdo/PersistenceManager;", null, null);
122: //return (speedoIsActive
123: //? speedoGetHome().getPOManagerFactory().lookup()
124: //: null);
125:
126: mv.visitVarInsn(ALOAD, 0);
127: mv.visitFieldInsn(GETFIELD, classToWrite, ISACTIVE_FIELD_NAME,
128: "Z");
129: Label l1 = new Label();
130: mv.visitJumpInsn(IFEQ, l1);
131: mv.visitVarInsn(ALOAD, 0);
132: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite,
133: "speedoGetHome", "()" + JT_HOME);
134: mv.visitMethodInsn(INVOKEINTERFACE, JCN_HOME,
135: "getPOManagerFactory", "()" + JT_POMF);
136: mv.visitMethodInsn(INVOKEINTERFACE, JCN_POMF, "lookup", "()"
137: + JT_POM);
138: Label l2 = new Label();
139: mv.visitJumpInsn(GOTO, l2);
140: mv.visitLabel(l1);
141: mv.visitInsn(ACONST_NULL);
142: mv.visitLabel(l2);
143: mv.visitInsn(ARETURN);
144: mv.visitMaxs(0, 0);
145: }
146:
147: private void generateJdoReplaceFlagsMethod() {
148: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "jdoReplaceFlags",
149: "()V", null, null);
150: generateThrowJDOUnsupportedOptionException(mv);
151: mv.visitMaxs(0, 0);
152: }
153:
154: private void generateJdoNewInstanceSMMethod() {
155: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "jdoNewInstance",
156: "(Ljavax/jdo/spi/StateManager;)"
157: + "Ljavax/jdo/spi/PersistenceCapable;", null,
158: null);
159: generateThrowJDOUnsupportedOptionException(mv);
160: mv.visitMaxs(0, 0);
161: }
162:
163: private void generateJdoNewInstanceSMOMethod() {
164: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "jdoNewInstance",
165: "(Ljavax/jdo/spi/StateManager;Ljava/lang/Object;)"
166: + "Ljavax/jdo/spi/PersistenceCapable;", null,
167: null);
168: generateThrowJDOUnsupportedOptionException(mv);
169: mv.visitMaxs(0, 0);
170: }
171:
172: private void generateJdoNewObjectIdInstanceMethod() {
173: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC,
174: "jdoNewObjectIdInstance", "()Ljava/lang/Object;", null,
175: null);
176: generateThrowJDOUnsupportedOptionException(mv);
177: mv.visitMaxs(0, 0);
178: }
179:
180: private void generateJdoGetObjectIdMethod() {
181: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "jdoGetObjectId",
182: "()Ljava/lang/Object;", null, null);
183: mv.visitVarInsn(ALOAD, 0);
184: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite, "getPName",
185: "()Lorg/objectweb/jorm/naming/api/PName;");
186: mv.visitInsn(ARETURN);
187: mv.visitMaxs(0, 0);
188: }
189:
190: private void generateJdoGetTransactionalObjectIdMethod() {
191: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC,
192: "jdoGetTransactionalObjectId", "()Ljava/lang/Object;",
193: null, null);
194: mv.visitVarInsn(ALOAD, 0);
195: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite, "getPName",
196: "()Lorg/objectweb/jorm/naming/api/PName;");
197: mv.visitInsn(ARETURN);
198: mv.visitMaxs(0, 0);
199: }
200:
201: private void generateJdoReplaceFieldIMethod() {
202: CodeVisitor mv;
203: mv = cv.visitMethod(ACC_PUBLIC, "jdoReplaceField", "(I)V",
204: null, null);
205: generateThrowJDOUnsupportedOptionException(mv);
206: mv.visitMaxs(0, 0);
207: }
208:
209: private void generateJdoReplaceFieldAIMethod() {
210: CodeVisitor mv;
211: mv = cv.visitMethod(ACC_PUBLIC, "jdoReplaceField", "([I)V",
212: null, null);
213: generateThrowJDOUnsupportedOptionException(mv);
214: mv.visitMaxs(0, 0);
215: }
216:
217: private void generateJdoProvideFieldIMethod() {
218: CodeVisitor mv;
219: mv = cv.visitMethod(ACC_PUBLIC, "jdoProvideField", "(I)V",
220: null, null);
221: generateThrowJDOUnsupportedOptionException(mv);
222: mv.visitMaxs(0, 0);
223: }
224:
225: private void generateJdoProvideFieldAIMethod() {
226: CodeVisitor mv;
227: mv = cv.visitMethod(ACC_PUBLIC, "jdoProvideField", "([I)V",
228: null, null);
229: generateThrowJDOUnsupportedOptionException(mv);
230: mv.visitMaxs(0, 0);
231: }
232:
233: private void generateJdoCopyFieldsMethod() {
234: CodeVisitor mv;
235: mv = cv.visitMethod(ACC_PUBLIC, "jdoCopyFields",
236: "(Ljava/lang/Object;[I)V", null, null);
237: generateThrowJDOUnsupportedOptionException(mv);
238: mv.visitMaxs(0, 0);
239: }
240:
241: private void generateJdoCopyKeyFieldsToObjectIdOIFMMethod() {
242: CodeVisitor mv;
243: mv = cv
244: .visitMethod(
245: ACC_PUBLIC,
246: "jdoCopyKeyFieldsToObjectId",
247: "(Ljavax/jdo/spi/PersistenceCapable$ObjectIdFieldManager;Ljava/lang/Object;)V",
248: null, null);
249: generateThrowJDOUnsupportedOptionException(mv);
250: mv.visitMaxs(0, 0);
251: }
252:
253: private void generateJdoCopyKeyFieldsToObjectIdOMethod() {
254: CodeVisitor mv;
255: mv = cv.visitMethod(ACC_PUBLIC, "jdoCopyKeyFieldsToObjectId",
256: "(Ljava/lang/Object;)V", null, null);
257: generateThrowJDOUnsupportedOptionException(mv);
258: mv.visitMaxs(0, 0);
259: }
260:
261: private void generateJdoCopyKeyFieldsToObjectIdOIFSMethod() {
262: CodeVisitor mv;
263: mv = cv
264: .visitMethod(
265: ACC_PUBLIC,
266: "jdoCopyKeyFieldsToObjectId",
267: "(Ljavax/jdo/spi/PersistenceCapable$ObjectIdFieldSupplier;Ljava/lang/Object;)V",
268: null, null);
269: generateThrowJDOUnsupportedOptionException(mv);
270: mv.visitMaxs(0, 0);
271: }
272:
273: private void generateJdoCopyKeyFieldsFromObjectIdMethod() {
274: CodeVisitor mv;
275: mv = cv
276: .visitMethod(
277: ACC_PUBLIC,
278: "jdoCopyKeyFieldsFromObjectId",
279: "(Ljavax/jdo/spi/PersistenceCapable$ObjectIdFieldConsumer;Ljava/lang/Object;)V",
280: null, null);
281: generateThrowJDOUnsupportedOptionException(mv);
282: mv.visitMaxs(0, 0);
283: }
284:
285: private void generateJdoMakeDirtyMethod() {
286: CodeVisitor mv;
287: mv = cv.visitMethod(ACC_PUBLIC, "jdoMakeDirty",
288: "(Ljava/lang/String;)V", null, null);
289: mv.visitInsn(RETURN);
290: mv.visitMaxs(0, 0);
291: }
292:
293: private void generateJdoIsDirtyMethod() {
294: CodeVisitor mv;
295: mv = cv
296: .visitMethod(ACC_PUBLIC, "jdoIsDirty", "()Z", null,
297: null);
298:
299: generateReturnFalseIfNotIsActive(mv);
300:
301: //StateItf sa = speedoGetState();
302: mv.visitVarInsn(ALOAD, 0);
303: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite,
304: M_SPEEDO_GET_STATE, "()" + JT_STATE);
305: mv.visitVarInsn(ASTORE, 1);
306:
307: //if (sa == null) {
308: // return false;
309: //}
310: mv.visitVarInsn(ALOAD, 1);
311: Label l4 = new Label();
312: mv.visitJumpInsn(IFNONNULL, l4);
313: mv.visitInsn(ICONST_0);
314: mv.visitInsn(IRETURN);
315: mv.visitLabel(l4);
316:
317: //byte status = sa.jdoGetStatus();
318: mv.visitVarInsn(ALOAD, 1);
319: mv.visitMethodInsn(INVOKEINTERFACE, JCN_STATE,
320: M_SPEEDO_GET_STATUS, "()B");
321: mv.visitVarInsn(ISTORE, 2);
322:
323: //return !LifeCycle.isTransient(status) && LifeCycle.isDirty(status);
324: mv.visitVarInsn(ILOAD, 2);
325: mv.visitMethodInsn(INVOKESTATIC, JCN_LIFE_CYCLE, "isTransient",
326: "(B)Z");
327: Label l7 = new Label();
328: mv.visitJumpInsn(IFNE, l7);
329:
330: mv.visitVarInsn(ILOAD, 2);
331: mv.visitMethodInsn(INVOKESTATIC, JCN_LIFE_CYCLE, "isDirty",
332: "(B)Z");
333: mv.visitJumpInsn(IFEQ, l7);
334:
335: mv.visitInsn(ICONST_1);
336: Label l8 = new Label();
337: mv.visitJumpInsn(GOTO, l8);
338:
339: mv.visitLabel(l7);
340: mv.visitInsn(ICONST_0);
341:
342: mv.visitLabel(l8);
343: mv.visitInsn(IRETURN);
344: mv.visitMaxs(0, 0);
345: }
346:
347: private void generateJdoIsTransactionalMethod() {
348: CodeVisitor mv;
349: mv = cv.visitMethod(ACC_PUBLIC, "jdoIsTransactional", "()Z",
350: null, null);
351: generateReturnFalseIfNotIsActive(mv);
352:
353: //StateItf sa = speedoGetState();
354: mv.visitVarInsn(ALOAD, 0);
355: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite,
356: M_SPEEDO_GET_STATE, "()" + JT_STATE);
357: mv.visitVarInsn(ASTORE, 1);
358:
359: //if (sa == null) {
360: // return false;
361: //}
362: mv.visitVarInsn(ALOAD, 1);
363: Label l4 = new Label();
364: mv.visitJumpInsn(IFNONNULL, l4);
365: mv.visitInsn(ICONST_0);
366: mv.visitInsn(IRETURN);
367: mv.visitLabel(l4);
368:
369: //byte status = sa.jdoGetStatus();
370: mv.visitVarInsn(ALOAD, 1);
371: mv.visitMethodInsn(INVOKEINTERFACE, JCN_STATE,
372: M_SPEEDO_GET_STATUS, "()B");
373: mv.visitVarInsn(ISTORE, 2);
374:
375: //return !LifeCycle.isTransient(status) && LifeCycle.isTransactional(status);
376: mv.visitVarInsn(ILOAD, 2);
377: mv.visitMethodInsn(INVOKESTATIC, JCN_LIFE_CYCLE, "isTransient",
378: "(B)Z");
379: Label l7 = new Label();
380: mv.visitJumpInsn(IFNE, l7);
381: mv.visitVarInsn(ILOAD, 2);
382: mv.visitMethodInsn(INVOKESTATIC, JCN_LIFE_CYCLE,
383: "isTransactional", "(B)Z");
384: mv.visitJumpInsn(IFEQ, l7);
385: mv.visitInsn(ICONST_1);
386: Label l8 = new Label();
387: mv.visitJumpInsn(GOTO, l8);
388: mv.visitLabel(l7);
389:
390: mv.visitInsn(ICONST_0);
391: mv.visitLabel(l8);
392:
393: mv.visitInsn(IRETURN);
394: mv.visitMaxs(0, 0);
395: }
396:
397: private void generateJdoIsPersistentMethod() {
398: CodeVisitor mv;
399: mv = cv.visitMethod(ACC_PUBLIC, "jdoIsPersistent", "()Z", null,
400: null);
401:
402: generateReturnFalseIfNotIsActive(mv);
403:
404: //StateItf sa = speedoGetState();
405: mv.visitVarInsn(ALOAD, 0);
406: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite,
407: M_SPEEDO_GET_STATE, "()" + JT_STATE);
408: mv.visitVarInsn(ASTORE, 1);
409:
410: //return sa == null || LifeCycle.isPersistent(sa.jdoGetStatus());
411: mv.visitVarInsn(ALOAD, 1);
412: Label l4 = new Label();
413: mv.visitJumpInsn(IFNULL, l4);
414: mv.visitVarInsn(ALOAD, 1);
415: mv.visitMethodInsn(INVOKEINTERFACE, JCN_STATE,
416: M_SPEEDO_GET_STATUS, "()B");
417: mv.visitMethodInsn(INVOKESTATIC, JCN_LIFE_CYCLE,
418: "isPersistent", "(B)Z");
419: Label l5 = new Label();
420: mv.visitJumpInsn(IFEQ, l5);
421: mv.visitLabel(l4);
422: mv.visitInsn(ICONST_1);
423: Label l6 = new Label();
424: mv.visitJumpInsn(GOTO, l6);
425:
426: mv.visitLabel(l5);
427: mv.visitInsn(ICONST_0);
428:
429: mv.visitLabel(l6);
430: mv.visitInsn(IRETURN);
431: mv.visitMaxs(0, 0);
432: }
433:
434: private void generateJdoIsNewMethod() {
435: CodeVisitor mv;
436: mv = cv.visitMethod(ACC_PUBLIC, "jdoIsNew", "()Z", null, null);
437:
438: generateReturnFalseIfNotIsActive(mv);
439:
440: //StateItf sa = speedoGetState();
441: mv.visitVarInsn(ALOAD, 0);
442: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite,
443: M_SPEEDO_GET_STATE, "()" + JT_STATE);
444: mv.visitVarInsn(ASTORE, 1);
445:
446: //return sa != null && LifeCycle.isNew(sa.jdoGetStatus());
447: Label l4 = new Label();
448: mv.visitVarInsn(ALOAD, 1);
449: mv.visitJumpInsn(IFNULL, l4);
450: mv.visitVarInsn(ALOAD, 1);
451: mv.visitMethodInsn(INVOKEINTERFACE, JCN_STATE,
452: M_SPEEDO_GET_STATUS, "()B");
453: mv.visitMethodInsn(INVOKESTATIC, JCN_LIFE_CYCLE, "isNew",
454: "(B)Z");
455: mv.visitJumpInsn(IFEQ, l4);
456: mv.visitInsn(ICONST_1);
457: Label l5 = new Label();
458: mv.visitJumpInsn(GOTO, l5);
459:
460: mv.visitLabel(l4);
461: mv.visitInsn(ICONST_0);
462:
463: mv.visitLabel(l5);
464: mv.visitInsn(IRETURN);
465: mv.visitMaxs(0, 0);
466: }
467:
468: private void generateJdoIsDeletedMethod() {
469: CodeVisitor mv;
470: mv = cv.visitMethod(ACC_PUBLIC, "jdoIsDeleted", "()Z", null,
471: null);
472:
473: generateReturnFalseIfNotIsActive(mv);
474:
475: //StateItf sa = speedoGetState();
476: mv.visitVarInsn(ALOAD, 0);
477: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite,
478: M_SPEEDO_GET_STATE, "()" + JT_STATE);
479: mv.visitVarInsn(ASTORE, 1);
480:
481: //return sa != null && LifeCycle.isDeleted(sa.jdoGetStatus());
482: Label l4 = new Label();
483: mv.visitVarInsn(ALOAD, 1);
484: mv.visitJumpInsn(IFNULL, l4);
485: mv.visitVarInsn(ALOAD, 1);
486: mv.visitMethodInsn(INVOKEINTERFACE, JCN_STATE,
487: M_SPEEDO_GET_STATUS, "()B");
488: mv.visitMethodInsn(INVOKESTATIC, JCN_LIFE_CYCLE, "isDeleted",
489: "(B)Z");
490: mv.visitJumpInsn(IFEQ, l4);
491: mv.visitInsn(ICONST_1);
492: Label l5 = new Label();
493: mv.visitJumpInsn(GOTO, l5);
494:
495: mv.visitLabel(l4);
496: mv.visitInsn(ICONST_0);
497:
498: mv.visitLabel(l5);
499: mv.visitInsn(IRETURN);
500: mv.visitMaxs(0, 0);
501: }
502:
503: private void generateJdoIsDetachedMethod() {
504: CodeVisitor mv;
505: mv = cv.visitMethod(ACC_PUBLIC, "jdoIsDetached", "()Z", null,
506: null);
507: mv.visitInsn(ICONST_0);
508: mv.visitInsn(IRETURN);
509: mv.visitMaxs(0, 0);
510: }
511:
512: private void generateJdoReplaceObjectIdMethod() {
513: CodeVisitor mv;
514: mv = cv.visitMethod(ACC_PUBLIC, "jdoReplaceObjectId",
515: "(Ljava/lang/Object;)V", null, null);
516: mv.visitInsn(RETURN);
517: mv.visitMaxs(0, 0);
518: }
519:
520: private void generateJdoReplaceStateManagerMethod() {
521: CodeVisitor mv;
522: mv = cv.visitMethod(ACC_PUBLIC, "jdoReplaceStateManager",
523: "(Ljavax/jdo/spi/StateManager;)V", null, null);
524: mv.visitInsn(RETURN);
525: mv.visitMaxs(0, 0);
526: }
527: }
|