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