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.generator.home.ejb;
018:
019: import java.util.ArrayList;
020: import java.util.Collections;
021: import java.util.List;
022: import java.util.Set;
023:
024: import org.objectweb.asm.CodeVisitor;
025: import org.objectweb.asm.Label;
026: import org.objectweb.speedo.generation.generator.home.HomeGenerator;
027: import org.objectweb.speedo.generation.parser.ejb.EJBAnnotationParser;
028: import org.objectweb.speedo.lib.Personality;
029: import org.objectweb.speedo.metadata.SpeedoCallback;
030: import org.objectweb.speedo.mim.ejb.lib.EJBAbstractHomeImpl;
031: import org.objectweb.speedo.query.ejb.EJBQuery;
032:
033: public class EJBHomeGenerator extends HomeGenerator {
034: private final static String LISTENER_FIELD = "eventListener";
035:
036: public EJBHomeGenerator(Personality p) {
037: super (p);
038: }
039:
040: protected Class getSuperClass() {
041: return EJBAbstractHomeImpl.class;
042: }
043:
044: // TODO
045: protected Class getQueryClass() {
046: return EJBQuery.class;
047: }
048:
049: protected void generatePersonalityMethods(HomeContext gc) {
050: if (gc.sc.callBacks.isEmpty()) {
051: return;
052: }
053:
054: // public void sendEvt...
055: CodeVisitor mv = gc.cv
056: .visitMethod(ACC_PUBLIC, "sendEvent",
057: "(ILjava/lang/Object;Ljava/lang/Object;Z)V",
058: null, null);
059: int nbCase = gc.sc.callBacks.size();
060:
061: int[] keys = new int[nbCase];
062: Label[] keyLabels = new Label[nbCase];
063: int i = 0;
064: List keysList = new ArrayList((Set<Integer>) gc.sc.callBacks
065: .keySet());
066: Collections.sort(keysList);
067: for (int cbid : (List<Integer>) keysList) {
068: keys[i] = cbid;
069: keyLabels[i] = new Label();
070: i++;
071: }
072: Label switchEndLabel = new Label();
073: mv.visitVarInsn(ILOAD, 1);
074: mv.visitLookupSwitchInsn(switchEndLabel, keys, keyLabels);
075:
076: String listenclass = null;
077: // switch (evt.type) {
078: for (int j = 0; j < nbCase; j++) {
079: // case [assoc EJB_CB(cbn) <-> evt.type]:
080: mv.visitLabel(keyLabels[j]);
081: ArrayList<SpeedoCallback> cbl = (ArrayList<SpeedoCallback>) gc.sc.callBacks
082: .get(keys[j]);
083: if (cbl == null) {
084: continue;
085: }
086: for (SpeedoCallback actualcbn : cbl) {
087: if (actualcbn.listenerClassName == null) { // this a callback from the persistent class
088: // CALL THE CALLBACK METHOD INTO THE PERSISTENT CLASS
089: mv.visitVarInsn(ALOAD, 2);
090: mv.visitTypeInsn(CHECKCAST, gc.xJCN);
091: mv.visitMethodInsn(INVOKEVIRTUAL, gc.xJCN,
092: actualcbn.callbackName,
093: actualcbn.methodByteCodeSignature);
094: } else { // this is a callback from the listener class
095: if (listenclass == null) {
096: listenclass = actualcbn.listenerClassName;
097: }
098: // CALL THE CALLBACK METHOD INTO THE LISTENER CLASS
099: //this.eventListener.myMethod(param1)
100: mv.visitVarInsn(ALOAD, 0);
101: mv.visitFieldInsn(GETFIELD, gc.xHomeJCN,
102: LISTENER_FIELD,
103: getJVMType(actualcbn.listenerClassName));
104: mv.visitVarInsn(ALOAD, 2);
105: mv.visitTypeInsn(CHECKCAST, gc.xJCN);
106: mv
107: .visitMethodInsn(
108: INVOKEVIRTUAL,
109: getJVMClassName(actualcbn.listenerClassName),
110: actualcbn.callbackName,
111: actualcbn.methodByteCodeSignature);
112: }
113: }
114: // break;
115: mv.visitJumpInsn(GOTO, switchEndLabel);
116: }
117: mv.visitLabel(switchEndLabel);
118: // }
119: mv.visitInsn(RETURN);
120: mv.visitMaxs(0, 0);
121:
122: if (listenclass != null) {
123: // ADD THE DEFINITION OF THE LISTENER CLASS VARIABLE
124: gc.cv.visitField(ACC_PUBLIC + ACC_FINAL, LISTENER_FIELD,
125: getJVMType(listenclass), null, null);
126: gc.ctx.put("listenClass", listenclass);
127: }
128:
129: //public boolean hasInstanceLifeCycleListeners() {
130: mv = gc.cv.visitMethod(ACC_PUBLIC,
131: "hasInstanceLifeCycleListeners", "()Z", null, null);
132: //return true;
133: mv.visitInsn(ICONST_1);
134: mv.visitInsn(IRETURN);
135: mv.visitMaxs(0, 0);
136: //}
137:
138: }
139:
140: protected void generateNoArgConstructor(HomeContext gc) {
141: CodeVisitor mv = gc.cv.visitMethod(ACC_PUBLIC, "<init>", "()V",
142: null, null);
143: mv.visitVarInsn(ALOAD, 0);
144: mv.visitMethodInsn(INVOKESPECIAL, gc.super ClassJCN, "<init>",
145: "()V");
146:
147: String listenclass = (String) gc.ctx.get("listenClass");
148: if (listenclass != null) {
149: //this.eventListener = new MyListener()
150: mv.visitVarInsn(ALOAD, 0);
151: mv.visitTypeInsn(NEW, getJVMClassName(listenclass));
152: mv.visitInsn(DUP);
153: mv.visitMethodInsn(INVOKESPECIAL,
154: getJVMClassName(listenclass), "<init>", "()V");
155: mv.visitFieldInsn(PUTFIELD, gc.xHomeJCN, LISTENER_FIELD,
156: getJVMType(listenclass));
157: }
158: mv.visitInsn(RETURN);
159: mv.visitMaxs(0, 0);
160: }
161:
162: }
|