Package org.objectweb.speedo.generation.enhancer.oid

Source Code of org.objectweb.speedo.generation.enhancer.oid.PNameEnhancer

/**
* Copyright (C) 2001-2005 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package org.objectweb.speedo.generation.enhancer.oid;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.CodeVisitor;
import org.objectweb.asm.Constants;
import org.objectweb.speedo.generation.enhancer.common.LoggedClassAdapter;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoField;
import org.objectweb.speedo.naming.api.UserId;
import org.objectweb.speedo.naming.api.UserIdFactory;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.BasicLevel;

import java.util.Iterator;

/**
* It adds the implementation of the UserIfFactory interface in a PName.
*
* @author S.Chassande-Barrioz
*/
public class PNameEnhancer extends LoggedClassAdapter {
    public final static String USER_ID_DESC =
            "L" + UserId.class.getName().replace('.', '/') + ";";
    public final static String PTYPE_CLASS_NAME =
            "org/objectweb/jorm/type/api/PType";
    public final static String PTYPE_DESC = "L" + PTYPE_CLASS_NAME + ";";
    protected SpeedoClass speedoClass;

    public PNameEnhancer(ClassVisitor classVisitor,
        SpeedoClass sClass,
        Logger logger,
        Personality p) {
        super(classVisitor, p, logger);
        this.speedoClass = sClass;
    }

    public void visit(final int version, final int access,
                      final String className,
                      final String superName,
                      final String[] interfaces,
                      final String sourceFile) {
        String[] itfs;
        String uifcn = UserIdFactory.class.getName().replace('.', '/');
        boolean alreadyUIF = false;
        if (interfaces == null || interfaces.length==0) {
            itfs = new String[]{uifcn};
        } else {
            int i=0;
            while(i<interfaces.length && !interfaces[i].equals(uifcn)) {
                i++;
            }
            alreadyUIF = i<interfaces.length;
            if (alreadyUIF) {
                itfs = interfaces;
            } else {
                itfs = new String[interfaces.length + 1];
                System.arraycopy(interfaces, 0, itfs, 1, interfaces.length);
                itfs[0] = uifcn;
            }
        }
        if (alreadyUIF) {
            logger.log(BasicLevel.DEBUG, "The class " + className
                    + " already contains the interface " + uifcn);
            super.visit(version, access, className, superName, interfaces, sourceFile);
            return;
        }
        logger.log(BasicLevel.DEBUG, "Add to the class " + className
                + " the interface " + uifcn);
        super.visit(version, access, className, superName, itfs, sourceFile);

        //Add the method getNewUserId
        String uicn = speedoClass.identity.objectidClass.replace('.', '/');
        String methodName = "getNewUserId";
        if (debug) {
            logger.log(BasicLevel.DEBUG, "Add the method '" + methodName
                    + "' in the class '" + className + "'");
        }
        logger.log(BasicLevel.DEBUG, "Add to the class " + className
                + " the method " + methodName);
        CodeVisitor _cv = this.cv.visitMethod(
                Constants.ACC_PUBLIC,
                methodName,
                "()" + USER_ID_DESC,
                null,
                null);

        // GENERATE: Titi t = new Titi();
        // GENERATE: Titi is the class of the user identifier
        logger.log(BasicLevel.DEBUG, "add code: " + uicn + " t = new " + uicn + "();");
        _cv.visitTypeInsn(Constants.NEW, uicn);
        _cv.visitInsn(Constants.DUP);
        _cv.visitMethodInsn(Constants.INVOKESPECIAL, uicn, "<init>", "()V");
        _cv.visitVarInsn(Constants.ASTORE, 1);

        //t.f1 = this.f1
        boolean hasLongOrDouble = false;
        SpeedoClass current = speedoClass;
        while(current != null) {
          for(Iterator it = current.fields.values().iterator(); it.hasNext();) {
              SpeedoField sp = (SpeedoField) it.next();
              if (sp.primaryKey) {
                  hasLongOrDouble |= sp.type.charAt(0) == 'D'
                        || sp.type.charAt(0) == 'J';
                  logger.log(BasicLevel.DEBUG, "add code: this." + sp.name + " = t." + sp.name);
                  _cv.visitVarInsn(Constants.ALOAD, 1); //Can be a long|double value
                  _cv.visitVarInsn(Constants.ALOAD, 0);
                  _cv.visitFieldInsn(Constants.GETFIELD, className, sp.name, sp.type);
                  _cv.visitFieldInsn(Constants.PUTFIELD, uicn, sp.name, sp.type);
              }
          }
      SpeedoClass tmp = current.getSuper();
      current = (tmp == current ? null : tmp);
    }

        // GENERATE: t.speedoSetPersistentClassName(this.getPType().getJormName());
        logger.log(BasicLevel.DEBUG, "add code: t.speedoSetPersistentClassName(this.getPType().getJormName());");
        _cv.visitVarInsn(Constants.ALOAD, 1);
        _cv.visitVarInsn(Constants.ALOAD, 0);
        _cv.visitMethodInsn(Constants.INVOKEVIRTUAL,
                className, "getPType", "()" + PTYPE_DESC);
        _cv.visitMethodInsn(Constants.INVOKEVIRTUAL,
                PTYPE_CLASS_NAME, "getJormName", "()Ljava/lang/String;");
        _cv.visitMethodInsn(Constants.INVOKEVIRTUAL,
                uicn, "speedoSetPersistentClassName", "(Ljava/lang/String;)V");
        logger.log(BasicLevel.DEBUG, "add code: return t;");
        _cv.visitVarInsn(Constants.ALOAD, 1);
        _cv.visitInsn(Constants.ARETURN);
        _cv.visitMaxs((hasLongOrDouble ? 3 : 2), 2);
    }
}
TOP

Related Classes of org.objectweb.speedo.generation.enhancer.oid.PNameEnhancer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.