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

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

/**
* 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.asm.Type;
import org.objectweb.asm.Attribute;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoField;
import org.objectweb.speedo.generation.enhancer.common.LoggedClassAdapter;
import org.objectweb.speedo.generation.lib.NamingRules;
import org.objectweb.speedo.naming.api.UserId;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.BasicLevel;

import java.util.Iterator;

/**
* It adds the implementation of the UserId and specific PNameGetter interfaces
* in the user identifier.
*
* @author S.Chassande-Barrioz
*/
public class UserIdEnhancer extends LoggedClassAdapter {

    protected SpeedoClass speedoClass;

    public final static String ADDED_FIELD_NAME = "speedoPersistentClassName";
    public final static String ADDED_FIELD_DESC = "Ljava/lang/String;";

    private String className ;

    public UserIdEnhancer(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 cn,
                      final String superName,
                      final String[] interfaces,
                      final String sourceFile) {
        className = cn;
        String[] itfs;
        String pngcn = NamingRules.pngName(speedoClass.identity.objectidClass).replace('.', '/');
        boolean alreadyPNG = false;
        String sncn = UserId.class.getName().replace('.','/');
        if (interfaces == null || interfaces.length==0) {
            itfs = new String[]{pngcn, sncn};
        } else {
            int i=0;
            while(i<interfaces.length && !interfaces[i].equals(pngcn)) {
                i++;
            }
            alreadyPNG = i<interfaces.length;
            if (alreadyPNG) {
                itfs = interfaces;
            } else {
                itfs = new String[interfaces.length + 2];
                System.arraycopy(interfaces, 0, itfs, 2, interfaces.length);
                itfs[0] = pngcn;
                itfs[1] = UserId.class.getName().replace('.','/');
            }
        }
        if (alreadyPNG) {
            logger.log(BasicLevel.DEBUG, "The class " + className
                    + " already contains the interface " + pngcn + " and " + sncn);
            super.visit(version, access, className, superName, interfaces, sourceFile);
            return;
        }
        logger.log(BasicLevel.DEBUG, "Add to the class " + className
                + " the interface " + pngcn);
        logger.log(BasicLevel.DEBUG, "Add to the class " + className
                + " the interface " + sncn);
        super.visit(version, access, className, superName, itfs, sourceFile);

    SpeedoClass pkFieldClassHolder = speedoClass;
    if (speedoClass.getSuperClassName() != null) {
      pkFieldClassHolder = speedoClass.getAncestor();
    }

        for(Iterator it = pkFieldClassHolder.fields.values().iterator(); it.hasNext();) {
            SpeedoField sp = (SpeedoField) it.next();
            if (sp.primaryKey) {
                String methodName = "pnGet" + upperFL(sp.name);
                logger.log(BasicLevel.DEBUG, "Add to the class " + className
                        + " the method " + methodName);
                CodeVisitor _cv = this.cv.visitMethod(
                        Constants.ACC_PUBLIC,
                        methodName,
                        "(Ljava/lang/Object;)" + sp.type,
                        null,
                        null);
                _cv.visitVarInsn(Constants.ALOAD, 0);
                _cv.visitFieldInsn(Constants.GETFIELD, className, sp.name, sp.type);
                Type returnType = Type.getType(sp.type);
                _cv.visitInsn(returnType.getOpcode(Constants.IRETURN));
                _cv.visitMaxs(
                        (sp.type.equals("J") || sp.type.equals("D")) ? 2 : 1,
                        2);
            }
        }
        // declare the field speedoPersistentClassName
        //int access, String name, String desc, Object value
        logger.log(BasicLevel.DEBUG, "Add to the class " + className
                + " the field " + ADDED_FIELD_NAME);
        cv.visitField(Constants.ACC_PRIVATE, ADDED_FIELD_NAME,
                ADDED_FIELD_DESC, null, null);

        //Add the method speedoGetPersistentClassName
        String methodName = "speedoGetPersistentClassName";
        logger.log(BasicLevel.DEBUG, "Add to the class " + className
                + " the method " + methodName);
        CodeVisitor mv = this.cv.visitMethod(
                Constants.ACC_PUBLIC,
                methodName,
                "()Ljava/lang/String;",
                null,
                null);
        mv.visitVarInsn(Constants.ALOAD, 0);
        mv.visitFieldInsn(Constants.GETFIELD,
                className, ADDED_FIELD_NAME, ADDED_FIELD_DESC);
        Type returnType = Type.getType(ADDED_FIELD_DESC);
        mv.visitInsn(returnType.getOpcode(Constants.IRETURN));
        mv.visitMaxs(1, 2);

        //Add the method speedoSetPersistentClassName
        methodName = "speedoSetPersistentClassName";
        logger.log(BasicLevel.DEBUG, "Add to the class " + className
                + " the method " + methodName);
        mv = this.cv.visitMethod(
                Constants.ACC_PUBLIC,
                methodName,
                "(Ljava/lang/String;)V",
                null,
                null);
        mv.visitVarInsn(Constants.ALOAD, 0);
        mv.visitVarInsn(Constants.ALOAD, 1);
        mv.visitFieldInsn(Constants.PUTFIELD,
                className, ADDED_FIELD_NAME, ADDED_FIELD_DESC);
        mv.visitInsn(Constants.RETURN);
        mv.visitMaxs(2, 2);
    }

    public CodeVisitor visitMethod(final int access,
                                   final String name,
                                   final String desc,
                                   final String[] exceptions,
                                   final Attribute attrs) {
        CodeVisitor c = cv.visitMethod(access, name, desc, exceptions, attrs);
        if (name.equals("<init>")) {
            c.visitVarInsn(Constants.ALOAD, 0);
            c.visitLdcInsn(speedoClass.getFQName()); //load a constant
            c.visitFieldInsn(Constants.PUTFIELD, className,
                ADDED_FIELD_NAME, ADDED_FIELD_DESC);
        }
        return c;
    }

    private String upperFL(String str) {
        if (str == null || str.length()==0) {
            return str;
        } else if (str.length() == 1) {
            return String.valueOf(Character.toUpperCase(str.charAt(0)));
        } else {
            return Character.toUpperCase(str.charAt(0)) + str.substring(1);
        }
    }
}
TOP

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

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.