Re: AdviseConstructorTransformer

Jonas Bonér <[email protected]> Fri, 02 May 2003 17:02:35 +0200
Newsgroups gmane.comp.java.aspectwerkz
Message-ID <[email protected]>
Hi Shiyiying.

You should have the patch by now.

I think that the patterns:
new(..), new(int,String,..), new(*) and so on is a good idea, since it
resembles the syntax that AspectJ uses. I will implement support for it.

- Jonas

[email protected] wrote:
> Hi Jonas
> Waiting for your patch and I can write AdviseConstructorTransformer with your new selection pattern.
> Will be constructor's selection new(..) ,new(int ,String,..)?
> Best Regards!
> Shiyiying
> ----- Original Message ----- 
> From: "Jonas Bonér" <[email protected]>
> To: "? 娑" <[email protected]>
> Cc: <[email protected]>
> Sent: Friday, May 02, 2003 10:35 PM
> Subject: AdviseConstructorTransformer 
> 
> 
> 
>>Hi Shiyiying.
>>
>>It would be really great if you wanted to help me out writing a
>>AdviseConstructorTransformer class.
>>
>>Thanks for dedicating your time :-)
>>
>>Regarding the the issue about the constructors you are mentioning:
>>it is a bug and I have fixed it (but not committed yet).
>>
>>I have been rewriting some of the the base to support a more
>>fine-grained selection language for the pointcut selections. So I
>>thought that I should wait with this patch (among others) until I am
>>done with this (within a week). But I'm attaching the code for the new
>>AdviseMemberMethodTransformer class so you have something to start with :-).
>>
>>Thanks, once again, and don't hesitate bothering me with questions.
>>
>>Sincerely, Jonas.
>>
>>
>>
>>
>>
>>? 娑 wrote:
>>
>>>Hi Jonas:
>>>We now take a holiday in China.So I decide to write a 
>>>AdviseConstructorTransformer for aspectwerk.
>>>When I'm looking into the source code of AdviseMemberMethodTransformer, 
>>>I found every time AdviseMemberMethodTransformer create a new 
>>>JoinPointField ,it just add this JoinPointField to first constructor:
>>>
>>>               addJoinPointField(cpg, cg, mg, methodSequence, 
>>>isThreadSafe);
>>>
>>>               methods[idxInit] = createJoinPointField(
>>>                       cpg, cg,
>>>                       methods[idxInit],
>>>                       methods[i],
>>>                       factory,
>>>                       methodLookupId,
>>>                       methodSequence,
>>>                       isThreadSafe).getMethod();
>>>
>>>
>>>So I suspect If I have two or more Constructor in one class, Code use 
>>>second constructor will throw a NullPointerException(because 
>>>joinPointField was not added to all constructors).
>>>
>>>package examples.logging;
>>>
>>>/**
>>>*
>>>*/
>>>public class Target {
>>>
>>>   public Target() {
>>>   }
>>>      public Target(String name) {
>>>   }
>>>   /**
>>>    * @attributes:method log
>>>    */
>>>   public void toLog1() {
>>>       System.out.println("\tinvoking toLog1");
>>>   }
>>>
>>>   /**
>>>    * @attributes:method log
>>>    */
>>>   public void toLog2(java.lang.String arg) {
>>>       System.out.println("\tinvoking toLog2");
>>>   }
>>>
>>>   /**
>>>    * @attributes:method log
>>>    */
>>>   public String toLog3() {
>>>       System.out.println("\tinvoking toLog3");
>>>       return "result";
>>>   }
>>>
>>>   public static void main(String[] args) {
>>>       Target target = new Target("dummy");
>>>       target.toLog1();
>>>       target.toLog2("parameter");
>>>       target.toLog3();
>>>   }
>>>}
>>>So I change logging sample code to test it.
>>>I add a new Constructor Target(String name)to it,and use this new 
>>>constructor in main method,here is the result.
>>>   [exec] parsing source files...
>>>   [exec] meta-data for classes in 
>>>C:\eclipse\workspace\aspectwerkz/src/samples
>>>have been generated to C:\eclipse\workspace\aspectwerkz/_metaData
>>>
>>>   [exec] java.lang.NullPointerException
>>>   [exec]      at examples.logging.Target.toLog1(Target.java)
>>>   [exec]      at examples.logging.Target.main(Target.java:37)
>>>   [exec] Exception in thread "main"
>>>Do I miss something? or Is it a bug?
>>>
>>>Best Regards
>>>Shiyiying
>>>
>>>_________________________________________________________________
>>>免费下载 MSN Explorer:   http://explorer.msn.com/lccn/ 
>>>
>>>
>>>-------------------------------------------------------
>>>This sf.net email is sponsored by:ThinkGeek
>>>Welcome to geek heaven.
>>>http://thinkgeek.com/sf
>>>_______________________________________________
>>>aspectwerkz-developer mailing list
>>>[email protected]
>>>https://lists.sourceforge.net/lists/listinfo/aspectwerkz-developer
>>>
>>>
>>
>>
>>-- 
>>Jonas
>>http://freeroller.net/page/jboner
>>
>>
>>
> 
> 
> 
> --------------------------------------------------------------------------------
> 
> 
> 
>>/*
>> * AspectWerkz AOP Framework.
>> *
>> * Distributable under LGPL license.
>> * See terms of license at gnu.org.
>> */
>>package aspectwerkz.transform;
>>
>>import java.util.Map;
>>import java.util.HashMap;
>>import java.util.List;
>>import java.util.ArrayList;
>>import java.util.Iterator;
>>import java.util.Collections;
>>
>>import org.apache.bcel.generic.InstructionFactory;
>>import org.apache.bcel.generic.ConstantPoolGen;
>>import org.apache.bcel.generic.ClassGen;
>>import org.apache.bcel.generic.Type;
>>import org.apache.bcel.generic.InstructionList;
>>import org.apache.bcel.generic.MethodGen;
>>import org.apache.bcel.generic.BasicType;
>>import org.apache.bcel.generic.PUSH;
>>import org.apache.bcel.generic.InstructionConstants;
>>import org.apache.bcel.generic.CPInstruction;
>>import org.apache.bcel.generic.ObjectType;
>>import org.apache.bcel.generic.ArrayType;
>>import org.apache.bcel.generic.FieldGen;
>>import org.apache.bcel.generic.InstructionHandle;
>>import org.apache.bcel.generic.ReturnInstruction;
>>import org.apache.bcel.generic.CodeExceptionGen;
>>import org.apache.bcel.generic.BranchInstruction;
>>import org.apache.bcel.Constants;
>>import org.apache.bcel.classfile.Method;
>>
>>import org.cs3.jmangler.bceltransformer.UnextendableClassSet;
>>import org.cs3.jmangler.bceltransformer.CodeTransformerComponent;
>>
>>import aspectwerkz.definition.metadata.WeaveModel;
>>import aspectwerkz.definition.metadata.MethodMetaData;
>>
>>/**
>> * Transforms member methods to become "aspect-aware".
>> *
>> * @author <a href="mailto:[email protected]">Jonas Bonr</a>
>> * @version $Id: AdviseMemberMethodTransformer.java,v 1.4 2003/04/16 15:25:06 jboner Exp $
>> */
>>public class AdviseMemberMethodTransformer implements CodeTransformerComponent {
>>    ///CLOVER:OFF
>>
>>    /**
>>     * Holds the weave model.
>>     */
>>    private WeaveModel m_weaveModel = WeaveModel.loadModel();
>>
>>    /**
>>     * Constructor.
>>     */
>>    public AdviseMemberMethodTransformer() {
>>        super();
>>    }
>>
>>    /**
>>     * Makes the member method transformations.
>>     *
>>     * @param cs the class set.
>>     */
>>    public void transformCode(final UnextendableClassSet cs) {
>>        final Iterator iterator = cs.getIteratorForTransformableClasses();
>>        while (iterator.hasNext()) {
>>            final ClassGen cg = (ClassGen)iterator.next();
>>
>>            if (classFilter(cg)) continue;
>>
>>            final InstructionFactory factory = new InstructionFactory(cg);
>>            final ConstantPoolGen cpg = cg.getConstantPool();
>>            final Method[] methods = cg.getMethods();
>>
>>
>>            // get the indexes for the <init> methods
>>            List initIndexes = new ArrayList();
>>            for (int i = 0; i < methods.length; i++) {
>>                if (methods[i].getName().equals("<init>")) {
>>                    initIndexes.add(new Integer(i));
>>                }
>>            }
>>            if (initIndexes.size() == 0) throw new RuntimeException("class corrupt: no <init> method found in class " + cg.getClassName());
>>
>>            // build and sort the method lookup list
>>            final List methodLookupList = new ArrayList();
>>            for (int i = 0; i < methods.length; i++) {
>>                if (methodFilter(cg, methods[i])) continue;
>>                methodLookupList.add(methods[i]);
>>            }
>>            Collections.sort(methodLookupList, BCELMethodComparator.getInstance());
>>
>>            final Map methodSequences = new HashMap();
>>            final List proxyMethods = new ArrayList();
>>            for (int i = 0; i < methods.length; i++) {
>>
>>                if (methodFilter(cg, methods[i]) || methods[i].isStatic()) continue;
>>
>>                final MethodGen mg = new MethodGen(methods[i], cg.getClassName(), cpg);
>>
>>                // take care of identification of overloaded methods by inserting a sequence number
>>                if (methodSequences.containsKey(methods[i].getName())) {
>>                    int sequence = ((Integer)methodSequences.get(methods[i].getName())).intValue();
>>                    methodSequences.remove(methods[i].getName());
>>                    sequence++;
>>                    methodSequences.put(methods[i].getName(), new Integer(sequence));
>>                }
>>                else {
>>                    methodSequences.put(methods[i].getName(), new Integer(1));
>>                }
>>
>>                final int methodLookupId = methodLookupList.indexOf(methods[i]);
>>                final int methodSequence = ((Integer)methodSequences.get(methods[i].getName())).intValue();
>>
>>                // check if the pointcut should be deployed as thread safe or not
>>                final boolean isThreadSafe = true; // isThreadSafe(cg, methods[i]);
>>
>>                addJoinPointField(cpg, cg, mg, methodSequence, isThreadSafe);
>>
>>                // advise all the constructors
>>                for (Iterator it = initIndexes.iterator(); it.hasNext();) {
>>                    final int initIndex = ((Integer)it.next()).intValue();
>>
>>                    methods[initIndex] = createJoinPointField(
>>                            cpg, cg,
>>                            methods[initIndex],
>>                            methods[i],
>>                            factory,
>>                            methodLookupId,
>>                            methodSequence,
>>                            isThreadSafe).getMethod();
>>                }
>>
>>                proxyMethods.add(createProxyMethod(
>>                        cpg, cg, mg,
>>                        factory,
>>                        methodLookupId,
>>                        methodSequence,
>>                        methods[i].getAccessFlags(),
>>                        isThreadSafe));
>>
>>                methods[i] = addPrefixToMethod(
>>                        cpg, cg, mg,
>>                        methods[i],
>>                        methodSequence).getMethod();
>>
>>                mg.setMaxStack();
>>            }
>>
>>            // update the old methods
>>            cg.setMethods(methods);
>>
>>            // add the proxy methods
>>            for (Iterator it = proxyMethods.iterator(); it.hasNext();) {
>>                Method method = (Method)it.next();
>>                cg.addMethod(method);
>>            }
>>        }
>>    }
>>
>>    /**
>>     * Adds a join point member field.
>>     *
>>     * @param cp the ConstantPoolGen
>>     * @param cg the ClassGen
>>     * @param mg the MethodGen
>>     * @param methodSequence the methods sequence number
>>     */
>>    private void addJoinPointField(final ConstantPoolGen cp,
>>                                   final ClassGen cg,
>>                                   final MethodGen mg,
>>                                   final int methodSequence,
>>                                   final boolean isThreadSafe) {
>>
>>        final StringBuffer joinPoint =
>>                getJoinPointName(mg.getMethod(), methodSequence);
>>
>>        final FieldGen field;
>>        if (isThreadSafe) {
>>            field = new FieldGen(
>>                    Constants.ACC_PRIVATE | Constants.ACC_FINAL,
>>                    new ObjectType("java.lang.ThreadLocal"),
>>                    joinPoint.toString(),
>>                    cp);
>>        }
>>        else {
>>            field = new FieldGen(
>>                    Constants.ACC_PRIVATE | Constants.ACC_FINAL,
>>                    TransformationUtil.MEMBER_METHOD_JOIN_POINT_TYPE,
>>                    joinPoint.toString(),
>>                    cp);
>>        }
>>        cg.addField(field.getField());
>>    }
>>
>>    /**
>>     * Transforms the init method to create the newly added join point member field.
>>     *
>>     * @param cp the ConstantPoolGen
>>     * @param cg the ClassGen
>>     * @param init the constructor for the class
>>     * @param method the current method
>>     * @param factory the objectfactory
>>     * @param methodId the id of the current method in the lookup tabl
>>     * @param methodSequence the methods sequence number
>>     * @param isThreadSafe
>>     * @return the modified constructor
>>     */
>>    private MethodGen createJoinPointField(final ConstantPoolGen cp,
>>                                           final ClassGen cg,
>>                                           final Method init,
>>                                           final Method method,
>>                                           final InstructionFactory factory,
>>                                           final int methodId,
>>                                           final int methodSequence,
>>                                           final boolean isThreadSafe) {
>>
>>        final MethodGen mg = new MethodGen(init, cg.getClassName(), cp);
>>        final InstructionList il = mg.getInstructionList();
>>
>>        final InstructionHandle[] ihs = il.getInstructionHandles();
>>        for (int i = 0; i < ihs.length; i++) {
>>
>>            // inserts field instantiation into the constructor
>>            final InstructionHandle ih = ihs[i];
>>            if (!(ih.getInstruction() instanceof ReturnInstruction)) continue;
>>
>>            final StringBuffer joinPoint = getJoinPointName(method, methodSequence);
>>
>>            final InstructionHandle ihPost;
>>            if (isThreadSafe) {
>>                ihPost = il.insert(ih, factory.createLoad(Type.OBJECT, 0));
>>                il.insert(ih, factory.createNew("java.lang.ThreadLocal"));
>>
>>                il.insert(ih, InstructionConstants.DUP);
>>
>>                il.insert(ih, factory.createInvoke(
>>                        "java.lang.ThreadLocal",
>>                        "<init>",
>>                        Type.VOID,
>>                        new Type[]{},
>>                        Constants.INVOKESPECIAL));
>>
>>                il.insert(ih, factory.createFieldAccess(
>>                        cg.getClassName(),
>>                        joinPoint.toString(),
>>                        new ObjectType("java.lang.ThreadLocal"),
>>                        Constants.PUTFIELD));
>>            }
>>            else {
>>                // create an new join point
>>                ihPost = il.insert(ih, factory.createLoad(Type.OBJECT, 0));
>>                il.insert(ih, factory.createNew(
>>                        TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS));
>>
>>                // load the parameters (this, methodId and the method signature)
>>                il.insert(ih, InstructionConstants.DUP);
>>                il.insert(ih, factory.createLoad(Type.OBJECT, 0));
>>
>>                il.insert(ih, new PUSH(cp, methodId));
>>
>>                // invokes the constructor
>>                il.insert(ih, factory.createInvoke(
>>                        TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS,
>>                        "<init>",
>>                        Type.VOID,
>>                        new Type[]{Type.OBJECT, Type.INT},
>>                        Constants.INVOKESPECIAL));
>>
>>                // set the join point to the member field specified
>>                il.insert(ih, factory.createFieldAccess(
>>                        cg.getClassName(),
>>                        joinPoint.toString(),
>>                        TransformationUtil.MEMBER_METHOD_JOIN_POINT_TYPE,
>>                        Constants.PUTFIELD));
>>            }
>>            il.redirectBranches(ih, ihPost);
>>        }
>>        mg.setMaxStack();
>>        mg.setMaxLocals();
>>        return mg;
>>    }
>>
>>    /**
>>     * Adds a prefix to the original method.
>>     * To make it callable only from within the framework itself.
>>     *
>>     * @param cp the ConstantPoolGen
>>     * @param cg the ClassGen
>>     * @param mg the MethodGen
>>     * @param method the current method
>>     * @param methodSequence the methods sequence number
>>     * @return the modified method
>>     */
>>    private MethodGen addPrefixToMethod(final ConstantPoolGen cp,
>>                                        final ClassGen cg,
>>                                        final MethodGen mg,
>>                                        final Method method,
>>                                        final int methodSequence) {
>>
>>        final StringBuffer methodName = getPrefixedMethodName(method, methodSequence);
>>
>>        // change the method access flags
>>        int accessFlags = mg.getAccessFlags();
>>        if ((accessFlags & Constants.ACC_PRIVATE) != 0) {
>>            System.out.println("is private");
>>            // clear the private flag
>>            accessFlags &= ~Constants.ACC_PRIVATE;
>>        }
>>        if ((accessFlags & Constants.ACC_PROTECTED) != 0) {
>>            // clear the protected flag
>>            accessFlags &= ~Constants.ACC_PROTECTED;
>>        }
>>        if ((accessFlags & Constants.ACC_PUBLIC) == 0) {
>>            System.out.println("setting it to public");
>>            // set the public flag
>>            accessFlags |= Constants.ACC_PUBLIC;
>>        }
>>        // update the method
>>        final MethodGen prefixedMethod = new MethodGen(
>>                accessFlags,
>>                mg.getReturnType(),
>>                mg.getArgumentTypes(),
>>                mg.getArgumentNames(),
>>                methodName.toString(),
>>                cg.getClassName(),
>>                mg.getInstructionList(),
>>                cp);
>>
>>        // add the exceptions
>>        final String[] exceptions = mg.getExceptions();
>>        for (int i = 0; i < exceptions.length; i++) {
>>            prefixedMethod.addException(exceptions[i]);
>>        }
>>
>>        // add the exception handlers
>>        final CodeExceptionGen[] exceptionHandlers = mg.getExceptionHandlers();
>>        for (int i = 0; i < exceptionHandlers.length; i++) {
>>            prefixedMethod.addExceptionHandler(
>>                    exceptionHandlers[i].getStartPC(),
>>                    exceptionHandlers[i].getEndPC(),
>>                    exceptionHandlers[i].getHandlerPC(),
>>                    exceptionHandlers[i].getCatchType());
>>        }
>>
>>        prefixedMethod.setMaxStack();
>>        prefixedMethod.setMaxLocals();
>>
>>        return prefixedMethod;
>>    }
>>
>>    /**
>>     * Creates a proxy method for the original method specified.
>>     * This method has the same signature as the original method and
>>     * catches the invocation for further processing by the framework
>>     * before redirecting to the original method.
>>     *
>>     * @param cp the ConstantPoolGen
>>     * @param cg the ClassGen
>>     * @param originalMethod the current method
>>     * @param factory the objectfactory
>>     * @param methodId the id of the current method in the lookup tabl
>>     * @param methodSequence the methods sequence number
>>     * @param accessFlags the access flags of the original method
>>     * @param isThreadSafe
>>     * @return the proxy method
>>     */
>>    private Method createProxyMethod(final ConstantPoolGen cp,
>>                                     final ClassGen cg,
>>                                     final MethodGen originalMethod,
>>                                     final InstructionFactory factory,
>>                                     final int methodId,
>>                                     final int methodSequence,
>>                                     final int accessFlags,
>>                                     final boolean isThreadSafe) {
>>
>>        final InstructionList il = new InstructionList();
>>
>>        final Type[] parameterTypes = Type.getArgumentTypes(originalMethod.getSignature());
>>        final Type returnType = Type.getReturnType(originalMethod.getSignature());
>>        final String[] parameterNames = originalMethod.getArgumentNames();
>>
>>        final StringBuffer joinPoint = getJoinPointName(originalMethod.getMethod(), methodSequence);
>>
>>        final MethodGen method = new MethodGen(
>>                accessFlags,
>>                returnType,
>>                parameterTypes,
>>                parameterNames,
>>                originalMethod.getName(),
>>                cg.getClassName(),
>>                il, cp);
>>
>>        method.addException("java.lang.Throwable");
>>
>>        int indexParam = 1;
>>        int indexStack = 0;
>>        int indexJoinPoint = parameterTypes.length * 2 + 1;
>>
>>        BranchInstruction biIfNotNull = null;
>>        InstructionHandle ihIfNotNull = null;
>>        if (isThreadSafe) {
>>            // Object joinPoint = ___jp.get();
>>            il.append(factory.createLoad(Type.OBJECT, 0));
>>            il.append(factory.createFieldAccess(
>>                    cg.getClassName(),
>>                    joinPoint.toString(),
>>                    new ObjectType("java.lang.ThreadLocal"),
>>                    Constants.GETFIELD));
>>            il.append(factory.createInvoke(
>>                    "java.lang.ThreadLocal",
>>                    "get",
>>                    Type.OBJECT,
>>                    Type.NO_ARGS,
>>                    Constants.INVOKEVIRTUAL));
>>            il.append(factory.createStore(Type.OBJECT, indexJoinPoint));
>>
>>            // if (joinPoint == null) {
>>            il.append(factory.createLoad(Type.OBJECT, indexJoinPoint));
>>            biIfNotNull = factory.createBranchInstruction(Constants.IFNONNULL, null);
>>            il.append(biIfNotNull);
>>
>>            // joinPoint = new MemberMethodJoinPoint(this, 10);
>>            il.append(factory.createNew(
>>                    TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS));
>>            il.append(InstructionConstants.DUP);
>>            il.append(factory.createLoad(Type.OBJECT, 0));
>>            il.append(new PUSH(cp, methodId));
>>            il.append(factory.createInvoke(
>>                    TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS,
>>                    "<init>",
>>                    Type.VOID,
>>                    new Type[]{Type.OBJECT, Type.INT},
>>                    Constants.INVOKESPECIAL));
>>            il.append(factory.createStore(Type.OBJECT, indexJoinPoint));
>>
>>            // ___jp.set(joinPoint);
>>            il.append(factory.createLoad(Type.OBJECT, 0));
>>            il.append(factory.createFieldAccess(
>>                    cg.getClassName(),
>>                    joinPoint.toString(),
>>                    new ObjectType("java.lang.ThreadLocal"),
>>                    Constants.GETFIELD));
>>            il.append(factory.createLoad(Type.OBJECT, indexJoinPoint));
>>            il.append(factory.createInvoke(
>>                    "java.lang.ThreadLocal",
>>                    "set",
>>                    Type.VOID,
>>                    new Type[]{Type.OBJECT},
>>                    Constants.INVOKEVIRTUAL));
>>
>>            ihIfNotNull = il.append(factory.createLoad(Type.OBJECT, indexJoinPoint));
>>            il.append(factory.createCheckCast(
>>                    TransformationUtil.MEMBER_METHOD_JOIN_POINT_TYPE));
>>            indexJoinPoint += 2;
>>            il.append(factory.createStore(Type.OBJECT, indexJoinPoint));
>>
>>            biIfNotNull.setTarget(ihIfNotNull);
>>        }
>>
>>        // if we have parameters, wrap them up
>>        if (parameterTypes.length != 0) {
>>
>>            // create and allocate the parameters array
>>            il.append(new PUSH(cp, parameterTypes.length));
>>            il.append((CPInstruction)factory.createNewArray(Type.OBJECT, (short)1));
>>
>>            il.append(InstructionConstants.DUP);
>>            il.append(new PUSH(cp, indexStack));
>>            indexStack++;
>>
>>            // add all the parameters, wrap the primitive types in their object counterparts
>>            for (int count = 0; count < parameterTypes.length; count++) {
>>
>>                String wrapperClass = null;
>>                BasicType type = null;
>>                boolean hasLongOrDouble = false;
>>
>>                if (parameterTypes[count] instanceof ObjectType ||
>>                        parameterTypes[count] instanceof ArrayType) {
>>                    // we have an object or an array
>>                    il.append(factory.createLoad(Type.OBJECT, indexParam));
>>                    il.append(InstructionConstants.AASTORE);
>>                    indexParam++;
>>                }
>>                else if (parameterTypes[count] instanceof ArrayType) {
>>                    // we have an array
>>                    il.append(factory.createLoad(Type.OBJECT, indexParam));
>>                    il.append(InstructionConstants.AASTORE);
>>                    indexParam++;
>>                }
>>                else if (parameterTypes[count] instanceof BasicType) {
>>                    hasLongOrDouble = false;
>>                    // we have a primitive type
>>                    if ((parameterTypes[count]).equals(Type.LONG)) {
>>                        wrapperClass = "java.lang.Long";
>>                        type = Type.LONG;
>>                        hasLongOrDouble = true;
>>                    }
>>                    else if ((parameterTypes[count]).equals(Type.INT)) {
>>                        wrapperClass = "java.lang.Integer";
>>                        type = Type.INT;
>>                    }
>>                    else if ((parameterTypes[count]).equals(Type.SHORT)) {
>>                        wrapperClass = "java.lang.Short";
>>                        type = Type.SHORT;
>>                    }
>>                    else if ((parameterTypes[count]).equals(Type.DOUBLE)) {
>>                        wrapperClass = "java.lang.Double";
>>                        type = Type.DOUBLE;
>>                        hasLongOrDouble = true;
>>                    }
>>                    else if ((parameterTypes[count]).equals(Type.FLOAT)) {
>>                        wrapperClass = "java.lang.Float";
>>                        type = Type.FLOAT;
>>                    }
>>                    else if ((parameterTypes[count]).equals(Type.CHAR)) {
>>                        wrapperClass = "java.lang.Character";
>>                        type = Type.CHAR;
>>                    }
>>                    else if ((parameterTypes[count]).equals(Type.BYTE)) {
>>                        wrapperClass = "java.lang.Byte";
>>                        type = Type.BYTE;
>>                    }
>>                    else if ((parameterTypes[count]).equals(Type.BOOLEAN)) {
>>                        wrapperClass = "java.lang.Boolean";
>>                        type = Type.BOOLEAN;
>>                    }
>>                    else {
>>                        throw new RuntimeException("unknown parameter type: " + parameterTypes[count]);
>>                    }
>>                    il.append(factory.createNew(wrapperClass));
>>                    il.append(InstructionConstants.DUP);
>>                    il.append(factory.createLoad(type, indexParam));
>>                    il.append(factory.createInvoke(
>>                            wrapperClass,
>>                            "<init>",
>>                            Type.VOID,
>>                            new Type[]{type},
>>                            Constants.INVOKESPECIAL));
>>                    il.append(InstructionConstants.AASTORE);
>>                    indexParam++;
>>                } // end handle basic or object type
>>
>>                if (count != parameterTypes.length - 1) {
>>                    // if we don't have the last parameter, create the parameter on the stack
>>                    il.append(InstructionConstants.DUP);
>>                    il.append(new PUSH(cp, indexStack));
>>                    indexStack++;
>>
>>                    // long or double needs two registers to fit
>>                    if (hasLongOrDouble) indexParam++;
>>                }
>>            }
>>
>>            // create the object array
>>            il.append(factory.createStore(Type.OBJECT, indexParam));
>>
>>            if (isThreadSafe) {
>>                // if threadsafe grab the newly retrieved local join point field from the stack
>>                il.append(factory.createLoad(Type.OBJECT, indexJoinPoint));
>>            }
>>            else {
>>                // grab the join point member field
>>                il.append(factory.createLoad(Type.OBJECT, 0));
>>                il.append(factory.createFieldAccess(
>>                        cg.getClassName(),
>>                        joinPoint.toString(),
>>                        TransformationUtil.MEMBER_METHOD_JOIN_POINT_TYPE,
>>                        Constants.GETFIELD));
>>
>>            }
>>            // invoke joinPoint.setParameter(..)
>>            il.append(factory.createLoad(Type.OBJECT, indexParam));
>>            il.append(factory.createInvoke(
>>                    TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS,
>>                    "setParameters",
>>                    Type.VOID,
>>                    new Type[]{new ArrayType(Type.OBJECT, 1)},
>>                    Constants.INVOKEVIRTUAL));
>>            indexParam++;
>>
>>        } // end - if parameters.length != 0
>>
>>        if (isThreadSafe) {
>>            // if threadsafe grab the newly retrieved local join point field from the stack
>>            il.append(factory.createLoad(Type.OBJECT, indexJoinPoint));
>>            il.append(factory.createInvoke(
>>                    TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS,
>>                    "proceed", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
>>        }
>>        else {
>>            // grab the join point member field
>>            il.append(factory.createLoad(Type.OBJECT, 0));
>>            il.append(factory.createFieldAccess(
>>                    cg.getClassName(),
>>                    joinPoint.toString(),
>>                    TransformationUtil.MEMBER_METHOD_JOIN_POINT_TYPE,
>>                    Constants.GETFIELD));
>>
>>            // invoke joinPoint.proceed()
>>            il.append(factory.createInvoke(
>>                    TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS,
>>                    "proceed",
>>                    Type.OBJECT,
>>                    Type.NO_ARGS,
>>                    Constants.INVOKEVIRTUAL));
>>        }
>>
>>        if (!returnType.equals(Type.VOID)) {
>>            // create the result from the invocation
>>            il.append(factory.createStore(Type.OBJECT, indexParam));
>>            il.append(factory.createLoad(Type.OBJECT, indexParam));
>>
>>            // cast the result and return it, if the return type is a
>>            // primitive type, retrieve it from the wrapped object first
>>            if (returnType instanceof BasicType) {
>>                if (returnType.equals(Type.LONG)) {
>>                    il.append(factory.createCheckCast(new ObjectType("java.lang.Long")));
>>                    il.append(factory.createInvoke(
>>                            "java.lang.Long",
>>                            "longValue",
>>                            Type.LONG,
>>                            Type.NO_ARGS,
>>                            Constants.INVOKEVIRTUAL));
>>                }
>>                else if (returnType.equals(Type.INT)) {
>>                    il.append(factory.createCheckCast(new ObjectType("java.lang.Integer")));
>>                    il.append(factory.createInvoke(
>>                            "java.lang.Integer",
>>                            "intValue",
>>                            Type.INT,
>>                            Type.NO_ARGS,
>>                            Constants.INVOKEVIRTUAL));
>>                }
>>                else if (returnType.equals(Type.SHORT)) {
>>                    il.append(factory.createCheckCast(new ObjectType("java.lang.Short")));
>>                    il.append(factory.createInvoke(
>>                            "java.lang.Short",
>>                            "shortValue",
>>                            Type.SHORT,
>>                            Type.NO_ARGS,
>>                            Constants.INVOKEVIRTUAL));
>>                }
>>                else if (returnType.equals(Type.DOUBLE)) {
>>                    il.append(factory.createCheckCast(new ObjectType("java.lang.Double")));
>>                    il.append(factory.createInvoke(
>>                            "java.lang.Double",
>>                            "doubleValue",
>>                            Type.DOUBLE,
>>                            Type.NO_ARGS,
>>                            Constants.INVOKEVIRTUAL));
>>                }
>>                else if (returnType.equals(Type.FLOAT)) {
>>                    il.append(factory.createCheckCast(new ObjectType("java.lang.Float")));
>>                    il.append(factory.createInvoke(
>>                            "java.lang.Float",
>>                            "floatValue",
>>                            Type.FLOAT,
>>                            Type.NO_ARGS,
>>                            Constants.INVOKEVIRTUAL));
>>                }
>>                else if (returnType.equals(Type.CHAR)) {
>>                    il.append(factory.createCheckCast(new ObjectType("java.lang.Character")));
>>                    il.append(factory.createInvoke(
>>                            "java.lang.Character",
>>                            "charValue",
>>                            Type.CHAR,
>>                            Type.NO_ARGS,
>>                            Constants.INVOKEVIRTUAL));
>>                }
>>                else if (returnType.equals(Type.BYTE)) {
>>                    il.append(factory.createCheckCast(new ObjectType("java.lang.Byte")));
>>                    il.append(factory.createInvoke(
>>                            "java.lang.Byte",
>>                            "byteValue",
>>                            Type.BYTE,
>>                            Type.NO_ARGS,
>>                            Constants.INVOKEVIRTUAL));
>>                }
>>                else if (returnType.equals(Type.BOOLEAN)) {
>>                    il.append(factory.createCheckCast(new ObjectType("java.lang.Boolean")));
>>                    il.append(factory.createInvoke(
>>                            "java.lang.Boolean",
>>                            "booleanValue",
>>                            Type.BOOLEAN,
>>                            Type.NO_ARGS,
>>                            Constants.INVOKEVIRTUAL));
>>                }
>>                else if (returnType.equals(Type.VOID)) {
>>                    // skip
>>                }
>>                else {
>>                    throw new Error("unknown return type: " + returnType);
>>                }
>>            }
>>            else {
>>                // cast the result to the right type
>>                il.append(factory.createCast(Type.OBJECT, returnType));
>>            }
>>        }
>>        il.append(factory.createReturn(returnType));
>>
>>        method.setMaxStack();
>>        method.setMaxLocals();
>>        return method.getMethod();
>>    }
>>
>>    /**
>>     * JMangler callback method. Is being called before each transformation.
>>     */
>>    public void sessionStart() {
>>    }
>>
>>    /**
>>     * JMangler callback method. Is being called after each transformation.
>>     */
>>    public void sessionEnd() {
>>    }
>>
>>    /**
>>     * JMangler callback method. Prints a log/status message at each transformation.
>>     *
>>     * @return a log string
>>     */
>>    public String verboseMessage() {
>>        return this.getClass().getName();
>>    }
>>
>>    /**
>>     * Checks if a specific method needs to be thread safe.
>>     *
>>     * @param cg the class gen
>>     * @param method the method
>>     * @return boolean
>>     */
>>//    private boolean isThreadSafe(final ClassGen cg, final Method method) {
>>//        boolean threadSafe = false;
>>//        if (m_weaveModel.hasMethodPointcut(cg.getClassName(), method.getName())) {
>>//            threadSafe = m_weaveModel.isMethodPointcutThreadSafe(
>>//                    cg.getClassName(), method.getName());
>>//        }
>>//        else if (m_weaveModel.hasThrowsPointcut(cg.getClassName(), method.getName())) {
>>//            threadSafe = m_weaveModel.isThrowsPointcutThreadSafe(
>>//                    cg.getClassName(), method.getName());
>>//        }
>>//        return threadSafe;
>>//    }
>>
>>    /**
>>     * Filters the classes to be transformed.
>>     *
>>     * @param cg the class to filter
>>     * @return boolean true if the method should be filtered away
>>     */
>>    private boolean classFilter(final ClassGen cg) {
>>        if (cg.isInterface()) {
>>            return true;
>>        }
>>        else {
>>            return !m_weaveModel.hasAspect(cg.getClassName());
>>        }
>>    }
>>
>>    /**
>>     * Filters the methods to be transformed.
>>     *
>>     * @param cg the ClassGen
>>     * @param method the method to filter
>>     * @return boolean true if the method should be filtered (skipped)
>>     */
>>    private boolean methodFilter(final ClassGen cg, final Method method) {
>>        if (method.getName().equals("<init>")) {
>>            return true;
>>        }
>>        else {
>>            MethodMetaData methodMetaData = new MethodMetaData();
>>            methodMetaData.setName(method.getName());
>>            methodMetaData.setReturnType(method.getReturnType().toString());
>>            Type[] javaParameters = method.getArgumentTypes();
>>            String[] parameterTypes = new String[javaParameters.length];
>>            for (int j = 0; j < javaParameters.length; j++) {
>>                parameterTypes[j] = javaParameters[j].toString();
>>            }
>>            methodMetaData.setParameterTypes(parameterTypes);
>>            if (m_weaveModel.hasMethodPointcut(cg.getClassName(), methodMetaData)) {
>>                return false;
>>            }
>>            if (m_weaveModel.hasThrowsPointcut(cg.getClassName(), methodMetaData)) {
>>                return false;
>>            }
>>        }
>>        return true;
>>    }
>>
>>    /**
>>     * Returns the name of the join point.
>>     *
>>     * @param method the method
>>     * @param methodSequence the method sequence
>>     * @return the name of the join point
>>     */
>>    private static StringBuffer getJoinPointName(final Method method,
>>                                                 final int methodSequence) {
>>        final StringBuffer joinPoint = new StringBuffer();
>>        joinPoint.append(TransformationUtil.MEMBER_METHOD_JOIN_POINT_PREFIX);
>>        joinPoint.append(method.getName());
>>        joinPoint.append(TransformationUtil.DELIMITER);
>>        joinPoint.append(methodSequence);
>>        return joinPoint;
>>    }
>>
>>    /**
>>     * Returns the prefixed method name.
>>     *
>>     * @param method the method
>>     * @param methodSequence the method sequence
>>     * @return the name of the join point
>>     */
>>    private StringBuffer getPrefixedMethodName(final Method method,
>>                                               final int methodSequence) {
>>        final StringBuffer methodName = new StringBuffer();
>>        methodName.append(TransformationUtil.ORIGINAL_METHOD_PREFIX);
>>        methodName.append(method.getName());
>>        methodName.append(TransformationUtil.DELIMITER);
>>        methodName.append(methodSequence);
>>        return methodName;
>>    }
>>    ///CLOVER:ON
>>}
>>


-- 
Jonas
http://freeroller.net/page/jboner





-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf