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.genclass.merger.ejb;
018:
019: import org.objectweb.asm.ClassVisitor;
020: import org.objectweb.asm.CodeVisitor;
021: import org.objectweb.asm.Constants;
022: import org.objectweb.jorm.util.lib.StringReplace;
023: import org.objectweb.speedo.api.SpeedoException;
024: import org.objectweb.speedo.genclass.ejb.EJBGenClass;
025: import org.objectweb.speedo.genclass.merger.GCInfo;
026: import org.objectweb.speedo.genclass.merger.GenClassMerger;
027: import org.objectweb.speedo.generation.enhancer.common.LoggedClassAdapter;
028: import org.objectweb.speedo.lib.Personality;
029: import org.objectweb.util.monolog.api.BasicLevel;
030: import org.objectweb.util.monolog.api.Logger;
031:
032: import java.io.File;
033:
034: /**
035: * Generate the sub class of the generic class dedicated to JDO.
036: *
037: * @author S.Chassande-Barrioz, P. Dechamboux
038: */
039: public class EJBGenClassMerger extends GenClassMerger {
040: public final static String EJB_GEN_CLASS_NAME = EJBGenClass.class
041: .getName().replace('.', '/');
042:
043: public EJBGenClassMerger() {
044: super (Personality.EJB);
045: }
046:
047: protected String getLoggerName() {
048: return super .getLoggerName() + "." + Personality.EJB.getName();
049: }
050:
051: /**
052: * The class to write is into the sub package 'jdo' and the name is prefixed
053: * by JDO.
054: */
055: protected String getClassToWrite(String gcn) {
056: return StringReplace.replaceChar('\\', '/', Personality.EJB
057: .getGenClassName(gcn));
058: }
059:
060: /**
061: * The second class is the defined by #EJB_GEN_CLASS_NAME
062: */
063: protected final String getSecondClass(String gcn) {
064: return EJB_GEN_CLASS_NAME;
065: }
066:
067: /**
068: * return false if the class already implement a mandatory interface
069: * for persistent object, else true.
070: */
071: protected boolean requireEnhancement(GCInfo gc) {
072: return false;
073: }
074:
075: /**
076: * There is no first class, because the class is created.
077: */
078: protected void writeFirstClass(final GCInfo gc, ClassVisitor current)
079: throws SpeedoException {
080: //create the sub class for JDO
081: gc.setSuperName(StringReplace.replaceChar(File.separatorChar,
082: '/', gc.gcn.substring(0, gc.gcn.length() - 6)));
083: }
084:
085: /**
086: * Add a no arg constructor in addition to the normal behavior
087: */
088: protected void writeSecondClass(final GCInfo gc,
089: ClassVisitor current) throws SpeedoException {
090: super .writeSecondClass(gc, new NoArgConstructorAdder(current,
091: gc, logger));
092: }
093:
094: /**
095: * ASM class adapter for adding no arg constructor
096: *
097: * @author S.Chassande-Barrioz
098: */
099: private static class NoArgConstructorAdder extends
100: LoggedClassAdapter {
101: GCInfo gc;
102:
103: public NoArgConstructorAdder(ClassVisitor current, GCInfo gc,
104: Logger l) {
105: super (current, Personality.EJB, l);
106: this .gc = gc;
107: }
108:
109: public void visit(final int version, final int access,
110: final String name, final String super name,
111: final String[] interfaces, final String sourceFile) {
112: super .cv.visit(version, access, name, super name,
113: interfaces, sourceFile);
114: CodeVisitor mv = cv.visitMethod(Constants.ACC_PUBLIC,
115: "<init>", "()V", null, null);
116: mv.visitVarInsn(Constants.ALOAD, 0);
117: mv.visitMethodInsn(Constants.INVOKESPECIAL, gc
118: .getSuperName(), "<init>", "()V");
119: mv.visitInsn(Constants.RETURN);
120: mv.visitMaxs(1, 1);
121: }
122: }
123: }
|