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.oid;
018:
019: import org.objectweb.asm.ClassVisitor;
020: import org.objectweb.asm.CodeVisitor;
021: import org.objectweb.asm.Constants;
022: import org.objectweb.speedo.generation.enhancer.common.LoggedClassAdapter;
023: import org.objectweb.speedo.lib.Personality;
024: import org.objectweb.speedo.metadata.SpeedoClass;
025: import org.objectweb.speedo.metadata.SpeedoField;
026: import org.objectweb.speedo.naming.api.UserId;
027: import org.objectweb.speedo.naming.api.UserIdFactory;
028: import org.objectweb.util.monolog.api.Logger;
029: import org.objectweb.util.monolog.api.BasicLevel;
030:
031: import java.util.Iterator;
032:
033: /**
034: * It adds the implementation of the UserIfFactory interface in a PName.
035: *
036: * @author S.Chassande-Barrioz
037: */
038: public class PNameEnhancer extends LoggedClassAdapter {
039: public final static String USER_ID_DESC = "L"
040: + UserId.class.getName().replace('.', '/') + ";";
041: public final static String PTYPE_CLASS_NAME = "org/objectweb/jorm/type/api/PType";
042: public final static String PTYPE_DESC = "L" + PTYPE_CLASS_NAME
043: + ";";
044: protected SpeedoClass speedoClass;
045:
046: public PNameEnhancer(ClassVisitor classVisitor, SpeedoClass sClass,
047: Logger logger, Personality p) {
048: super (classVisitor, p, logger);
049: this .speedoClass = sClass;
050: }
051:
052: public void visit(final int version, final int access,
053: final String className, final String super Name,
054: final String[] interfaces, final String sourceFile) {
055: String[] itfs;
056: String uifcn = UserIdFactory.class.getName().replace('.', '/');
057: boolean alreadyUIF = false;
058: if (interfaces == null || interfaces.length == 0) {
059: itfs = new String[] { uifcn };
060: } else {
061: int i = 0;
062: while (i < interfaces.length
063: && !interfaces[i].equals(uifcn)) {
064: i++;
065: }
066: alreadyUIF = i < interfaces.length;
067: if (alreadyUIF) {
068: itfs = interfaces;
069: } else {
070: itfs = new String[interfaces.length + 1];
071: System.arraycopy(interfaces, 0, itfs, 1,
072: interfaces.length);
073: itfs[0] = uifcn;
074: }
075: }
076: if (alreadyUIF) {
077: logger.log(BasicLevel.DEBUG, "The class " + className
078: + " already contains the interface " + uifcn);
079: super .visit(version, access, className, super Name,
080: interfaces, sourceFile);
081: return;
082: }
083: logger.log(BasicLevel.DEBUG, "Add to the class " + className
084: + " the interface " + uifcn);
085: super .visit(version, access, className, super Name, itfs,
086: sourceFile);
087:
088: //Add the method getNewUserId
089: String uicn = speedoClass.identity.objectidClass.replace('.',
090: '/');
091: String methodName = "getNewUserId";
092: if (debug) {
093: logger
094: .log(BasicLevel.DEBUG, "Add the method '"
095: + methodName + "' in the class '"
096: + className + "'");
097: }
098: logger.log(BasicLevel.DEBUG, "Add to the class " + className
099: + " the method " + methodName);
100: CodeVisitor _cv = this .cv.visitMethod(Constants.ACC_PUBLIC,
101: methodName, "()" + USER_ID_DESC, null, null);
102:
103: // GENERATE: Titi t = new Titi();
104: // GENERATE: Titi is the class of the user identifier
105: logger.log(BasicLevel.DEBUG, "add code: " + uicn + " t = new "
106: + uicn + "();");
107: _cv.visitTypeInsn(Constants.NEW, uicn);
108: _cv.visitInsn(Constants.DUP);
109: _cv.visitMethodInsn(Constants.INVOKESPECIAL, uicn, "<init>",
110: "()V");
111: _cv.visitVarInsn(Constants.ASTORE, 1);
112:
113: //t.f1 = this.f1
114: boolean hasLongOrDouble = false;
115: SpeedoClass current = speedoClass;
116: while (current != null) {
117: for (Iterator it = current.fields.values().iterator(); it
118: .hasNext();) {
119: SpeedoField sp = (SpeedoField) it.next();
120: if (sp.primaryKey) {
121: hasLongOrDouble |= sp.type.charAt(0) == 'D'
122: || sp.type.charAt(0) == 'J';
123: logger.log(BasicLevel.DEBUG, "add code: this."
124: + sp.name + " = t." + sp.name);
125: _cv.visitVarInsn(Constants.ALOAD, 1); //Can be a long|double value
126: _cv.visitVarInsn(Constants.ALOAD, 0);
127: _cv.visitFieldInsn(Constants.GETFIELD, className,
128: sp.name, sp.type);
129: _cv.visitFieldInsn(Constants.PUTFIELD, uicn,
130: sp.name, sp.type);
131: }
132: }
133: SpeedoClass tmp = current.getSuper();
134: current = (tmp == current ? null : tmp);
135: }
136:
137: // GENERATE: t.speedoSetPersistentClassName(this.getPType().getJormName());
138: logger
139: .log(BasicLevel.DEBUG,
140: "add code: t.speedoSetPersistentClassName(this.getPType().getJormName());");
141: _cv.visitVarInsn(Constants.ALOAD, 1);
142: _cv.visitVarInsn(Constants.ALOAD, 0);
143: _cv.visitMethodInsn(Constants.INVOKEVIRTUAL, className,
144: "getPType", "()" + PTYPE_DESC);
145: _cv.visitMethodInsn(Constants.INVOKEVIRTUAL, PTYPE_CLASS_NAME,
146: "getJormName", "()Ljava/lang/String;");
147: _cv
148: .visitMethodInsn(Constants.INVOKEVIRTUAL, uicn,
149: "speedoSetPersistentClassName",
150: "(Ljava/lang/String;)V");
151: logger.log(BasicLevel.DEBUG, "add code: return t;");
152: _cv.visitVarInsn(Constants.ALOAD, 1);
153: _cv.visitInsn(Constants.ARETURN);
154: _cv.visitMaxs((hasLongOrDouble ? 3 : 2), 2);
155: }
156: }
|