Package org.jpox.enhancer.bcel.method

Source Code of org.jpox.enhancer.bcel.method.JdoCopyKeyFieldsFromObjectId2

/**********************************************************************
Copyright (c) 2004 Erik Bengtson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Contributors:
    ...
**********************************************************************/
package org.jpox.enhancer.bcel.method;

import java.lang.reflect.Modifier;

import javax.jdo.identity.ByteIdentity;
import javax.jdo.identity.CharIdentity;
import javax.jdo.identity.IntIdentity;
import javax.jdo.identity.LongIdentity;
import javax.jdo.identity.ObjectIdentity;
import javax.jdo.identity.ShortIdentity;
import javax.jdo.identity.StringIdentity;

import org.apache.bcel.Constants;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.generic.ALOAD;
import org.apache.bcel.generic.ASTORE;
import org.apache.bcel.generic.IFNE;
import org.apache.bcel.generic.Instruction;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;
import org.jpox.enhancer.ClassEnhancer;
import org.jpox.enhancer.bcel.BCELClassEnhancer;
import org.jpox.enhancer.bcel.BCELClassMethod;
import org.jpox.enhancer.bcel.BCELUtils;
import org.jpox.enhancer.bcel.metadata.BCELMember;
import org.jpox.enhancer.bcel.metadata.BCELFieldPropertyMetaData;
import org.jpox.metadata.AbstractClassMetaData;
import org.jpox.metadata.AbstractMemberMetaData;
import org.jpox.metadata.IdentityType;
import org.jpox.metadata.MetaDataManager;
import org.jpox.util.ClassUtils;

/**
* Creates the jdoCopyKeyFieldsFromObjectId(Object oid) method.
*
* @version $Revision: 1.15 $
*/
public class JdoCopyKeyFieldsFromObjectId2 extends BCELClassMethod
{
    /**
     * @param methodName Name of the method
     * @param type Type of object
     * @param resultType Type of result
     * @param argType Types of args
     * @param argName Names of args
     * @param synthetic Whether it is synthetic
     * @param gen Generator base
     */
    public JdoCopyKeyFieldsFromObjectId2(String methodName, int type, Type resultType, Type[] argType,
        String[] argName, boolean synthetic, BCELClassEnhancer gen)
    {
        super(methodName, type, resultType, argType, argName, synthetic, gen);
    }

    /**
     * Create and return instance of this class.
     * @param gen target class generator
     * @return instance of this class
     */
    public static JdoCopyKeyFieldsFromObjectId2 getInstance(BCELClassEnhancer gen)
    {
        return new JdoCopyKeyFieldsFromObjectId2(
            "jdoCopyKeyFieldsFromObjectId",
            Constants.ACC_PROTECTED,
            Type.VOID,
            new Type[] { Type.OBJECT },
            new String[] { "oid" },
            false,
            gen);
    }

    public void execute()
    {
        InstructionHandle lv_o[] = new InstructionHandle[2];

        String objectIdClass = cmd.getObjectidClass();
        AbstractMemberMetaData fields[] = cmd.getManagedMembers();
        int objectIdInstance = 2;
   
        if ((objectIdClass != null) && (objectIdClass.length() > 0))
        {
            ObjectType objectIdClassType = new ObjectType(objectIdClass);
            il.append(InstructionConstants.ALOAD_1);
            IFNE oidClassIsNotNull = new IFNE(null);
            il.append(factory.createInstanceOf(objectIdClassType));
            il.append(oidClassIsNotNull);
            createThrowException(ClassEnhancer.CN_ClassCastException, "key class is not " + objectIdClass + " or null");

            oidClassIsNotNull.setTarget(il.append(InstructionConstants.ALOAD_1));
            il.append(factory.createCast(Type.OBJECT, objectIdClassType));
            lv_o[0] = il.append(new ASTORE(objectIdInstance));

            if (fields != null)
            {
                for (int i = 0; i < fields.length; i++)
                {
                    AbstractMemberMetaData fieldConfig = (AbstractMemberMetaData)fields[i];

                    if (fieldConfig.isPrimaryKey())
                    {
                        //support for identifying relationships
                        //if the class has metadata, it is PersistenceCapable
                        //add JDOHelper.getObjectId(fieldXXXX);
                        MetaDataManager mgr = cmd.getMetaDataManager();
                        AbstractClassMetaData cmd = mgr.getMetaDataForClass(fieldConfig.getType(),
                            enhancer.getClassLoaderResolver());
                        BCELMember fieldMethod = ((BCELFieldPropertyMetaData)fieldConfig).getEnhanceField();
                        if (cmd != null && cmd.getIdentityType() != IdentityType.NONDURABLE)
                        {
                            // Identifying Relationships (PC field as primary key)
                            il.append(InstructionConstants.ALOAD_0);
                            //jdoGetPersistenceManager().getObjectById(id.field,false)
                            //  jdoGetPersistenceManager
                            il.append(InstructionConstants.ALOAD_0);
                            il.append(factory.createInvoke(ClassEnhancer.CN_PersistenceCapable, ClassEnhancer.MN_JdoGetPersistenceManager,
                                BCELClassEnhancer.OT_PersistenceManager, Type.NO_ARGS, Constants.INVOKEINTERFACE));

                            //  getObjectById(id.field,false)
                            //  id.field

                            createGetField(
                                objectIdClass,
                                fieldConfig.getName(),
                                new ObjectType(cmd.getObjectidClass()),
                                fieldConfig.isProperty(),
                                getModifiers(objectIdClass, fieldConfig.getName()),
                                InstructionFactory.createLoad(objectIdClassType, objectIdInstance));

                            //  false
                            il.append(InstructionConstants.ICONST_0);

                            //  getObjectById
                            il.append(factory.createInvoke(ClassEnhancer.CN_PersistenceManager, "getObjectById", Type.OBJECT,
                                new Type[]{Type.OBJECT, Type.BOOLEAN}, Constants.INVOKEINTERFACE));
                            il.append(factory.createCast(Type.OBJECT, fieldMethod.getType()));

                            createPutField(fieldConfig.getName(), fieldMethod.getType(), fieldConfig.isProperty());
                        }
                        else
                        {
                            // Single Field Identity
                            if (mgr.getApiAdapter().isSingleFieldIdentityClass(objectIdClass))
                            {
                                if (Object.class.isAssignableFrom(fieldConfig.getType()) && fieldConfig.getType() != String.class)
                                {
                                    // Object wrapper type
                                    Type primitiveType = null;
                                    if (objectIdClass.equals(LongIdentity.class.getName()))
                                    {
                                        primitiveType = Type.LONG;
                                    }
                                    else if (objectIdClass.equals(CharIdentity.class.getName()))
                                    {
                                        primitiveType = Type.CHAR;
                                    }
                                    else if (objectIdClass.equals(IntIdentity.class.getName()))
                                    {
                                        primitiveType = Type.INT;
                                    }
                                    else if (objectIdClass.equals(ShortIdentity.class.getName()))
                                    {
                                        primitiveType = Type.SHORT;
                                    }
                                    else if (objectIdClass.equals(ByteIdentity.class.getName()))
                                    {
                                        primitiveType = Type.BYTE;
                                    }
                                    else if (objectIdClass.equals(StringIdentity.class.getName()))
                                    {
                                        primitiveType = Type.STRING;
                                    }
                                    else if (objectIdClass.equals(ObjectIdentity.class.getName()))
                                    {
                                        primitiveType = Type.OBJECT;
                                    }
                                    il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
                                   
                                    if (primitiveType == Type.OBJECT)
                                    {
                                        // id = (field_type)o.getKey();
                                        il.append(InstructionFactory.createLoad(Type.OBJECT, 2));
                                        il.append(factory.createInvoke(objectIdClass, "getKey", primitiveType, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
                                        il.append(factory.createCheckCast(new ObjectType(fieldConfig.getTypeName())));
                                        createPutField(fieldConfig.getName(), fieldMethod.getType(), fieldConfig.isProperty());
                                    }
                                    else
                                    {
                                        // id = new Integer(o.getKey());
                                        il.append(factory.createNew(fieldConfig.getType().getName()));
                                        il.append(InstructionConstants.DUP);
                                        il.append(InstructionFactory.createLoad(Type.OBJECT, 2));
                                        il.append(factory.createInvoke(objectIdClass, "getKey", primitiveType, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
                                        il.append(factory.createInvoke(fieldConfig.getType().getName(), "<init>", Type.VOID,
                                            new Type[]{primitiveType}, Constants.INVOKESPECIAL));
                                        createPutField(fieldConfig.getName(), fieldMethod.getType(), fieldConfig.isProperty());
                                    }
                                }
                                else
                                {
                                    // Primitive type
                                    il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
                                    il.append(InstructionFactory.createLoad(Type.OBJECT, 2));
                                    il.append(factory.createInvoke(objectIdClass, "getKey", fieldMethod.getType(), Type.NO_ARGS,
                                        Constants.INVOKEVIRTUAL));
                                    createPutField(fieldConfig.getName(), fieldMethod.getType(), fieldConfig.isProperty());
                                }
                            }
                            // Users Application Identity class
                            else
                            {
                                il.append(InstructionConstants.ALOAD_0);
                                createGetField(
                                    objectIdClass,
                                    fieldConfig.getName(),
                                    fieldMethod.getType(),
                                    fieldConfig.isProperty(),
                                    getModifiers(objectIdClass, fieldConfig.getName()),
                                    InstructionFactory.createLoad(objectIdClassType, objectIdInstance));
                                createPutField(fieldConfig.getName(), fieldMethod.getType(), fieldConfig.isProperty());
                            }
                        }
                    }
                }
            }

            lv_o[1] = il.append(InstructionConstants.RETURN);
            methodGen.addLocalVariable("o", objectIdClassType, lv_o[0], lv_o[1]);
        }
        else
        {
            il.append(InstructionConstants.RETURN);
        }
    }
   
    private void createPutField(String fieldName, Type fieldType, boolean isProperty)
    {
        if( isProperty )
        {
            il.append(factory.createInvoke(
                className,
                "jdo"+BCELUtils.getSetterName(fieldName),
                Type.VOID,
                new Type[] { fieldType },
                Constants.INVOKEVIRTUAL));
        }
        else
        {
            il.append(factory.createPutField(getClassEnhancer().className, fieldName, fieldType));
        }
    }
   
    /**
     * Several forms of accessing the fields : via persistent properties; persistent fields; private/protected fields
     * @param className
     * @param fieldName
     * @param fieldType
     * @param isProperty
     * @param isPrivate
     * @param isProtected
     */
    private void createGetField(String className, String fieldName, Type fieldType, boolean isProperty, int fieldModifiers, Instruction ih)
    {
        if( isProperty )
        {
            il.append(ih);
            il.append(factory.createInvoke(
                className,
                ClassUtils.getJavaBeanGetterName(fieldName, fieldType == Type.BOOLEAN),
                fieldType,
                new Type[] {},
                Constants.INVOKEVIRTUAL));
        }
        else
        {
            if( !Modifier.isPrivate(fieldModifiers) && !Modifier.isProtected(fieldModifiers) )
            {
                il.append(ih);
                il.append(factory.createGetField(className, fieldName, fieldType));
            }
            else
            {
                il.append(ih);
                il.append(factory.createInvoke(
                    "java.lang.Object",
                    "getClass",
                    Type.CLASS,
                    Type.NO_ARGS,
                    Constants.INVOKEVIRTUAL));
                il.append(new PUSH(constantPoolGen, fieldName));
                il.append(factory.createInvoke(
                    "java.lang.Class",
                    "getDeclaredField",
                    new ObjectType("java.lang.reflect.Field"),
                    new Type[] { Type.STRING },
                    Constants.INVOKEVIRTUAL));
                il.append(new ASTORE(4));
                il.append(new ALOAD(4));
                il.append(InstructionConstants.ICONST_1);
                il.append(factory.createInvoke(
                    "java.lang.reflect.Field",
                    "setAccessible",
                    Type.VOID,
                    new Type[] { Type.BOOLEAN },
                    Constants.INVOKEVIRTUAL));
                il.append(new ALOAD(4));
                il.append(ih);
                if( fieldType == Type.BOOLEAN )
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "getBoolean",
                        Type.BOOLEAN,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                }
                else if( fieldType == Type.BYTE )
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "getByte",
                        Type.BYTE,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                }
                else if( fieldType == Type.CHAR )
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "getChar",
                        Type.CHAR,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                }
                else if( fieldType == Type.DOUBLE )
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "getDouble",
                        Type.DOUBLE,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                }
                else if( fieldType == Type.FLOAT )
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "getFloat",
                        Type.FLOAT,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                }
                else if( fieldType == Type.INT )
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "getInt",
                        Type.INT,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                }
                else if( fieldType == Type.LONG )
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "getLong",
                        Type.LONG,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                }
                else if( fieldType == Type.SHORT )
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "getShort",
                        Type.SHORT,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                }
                else
                {
                    il.append(factory.createInvoke(
                        "java.lang.reflect.Field",
                        "get",
                        Type.OBJECT,
                        new Type[] { Type.OBJECT },
                        Constants.INVOKEVIRTUAL));
                    il.append(factory.createCast(Type.OBJECT, fieldType));
                }
            }
        }
    }

    /**
     * Retrieve the field modifiers for the given class
     * @param className
     * @param fieldName
     * @return
     */
    private int getModifiers(String className, String fieldName)
    {
        JavaClass javaClass;
        try
        {
            javaClass = Repository.getRepository().loadClass(className);
            for( int i=0; i<javaClass.getFields().length; i++)
            {
                if( fieldName.equals(javaClass.getFields()[i].getName()) )
                {
                    return javaClass.getFields()[i].getModifiers();
                }
            }
        }
        catch (ClassNotFoundException e)
        {
            //ignore
        }
        return -1;
    }
   
}
TOP

Related Classes of org.jpox.enhancer.bcel.method.JdoCopyKeyFieldsFromObjectId2

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.