Package org.codehaus.aspectwerkz.transform

Source Code of org.codehaus.aspectwerkz.transform.TransformationUtil

/**************************************************************************************
* Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved.                 *
* http://aspectwerkz.codehaus.org                                                    *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the LGPL license      *
* a copy of which has been included with this distribution in the license.txt file.  *
**************************************************************************************/
package org.codehaus.aspectwerkz.transform;

import org.codehaus.aspectwerkz.MethodComparator;
import org.codehaus.aspectwerkz.definition.DescriptorUtil;
import org.codehaus.aspectwerkz.reflect.ClassInfo;
import org.codehaus.aspectwerkz.reflect.MemberInfo;
import org.codehaus.aspectwerkz.reflect.MethodInfo;
import org.codehaus.aspectwerkz.reflect.impl.java.JavaMethodInfo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.NotFoundException;

/**
* Contains constants and utility method used by the transformers.
*
* @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r</a>
*/
public final class TransformationUtil {
    public static final String ASPECTWERKZ_PREFIX = "___AW_";
    public static final String DELIMITER = "$_AW_$";
    public static final String CALL_SIDE_DELIMITER = "#";
    public static final String UUID_FIELD = ASPECTWERKZ_PREFIX + "uuid";
    public static final String META_DATA_FIELD = ASPECTWERKZ_PREFIX + "metaData";
    public static final String STATIC_CLASS_FIELD = ASPECTWERKZ_PREFIX + "clazz";
    public static final String JOIN_POINT_PREFIX = ASPECTWERKZ_PREFIX + "jp";
    public static final String ORIGINAL_METHOD_PREFIX = ASPECTWERKZ_PREFIX + DELIMITER;
    public static final String CROSS_CUTTING_INFO_CLASS_FIELD = ASPECTWERKZ_PREFIX + "crossCuttingInfo";
    public static final String WRAPPER_METHOD_PREFIX = ASPECTWERKZ_PREFIX + "wrapper";
    public static final String JOIN_POINT_MANAGER_FIELD = ASPECTWERKZ_PREFIX + "joinPointManager";
    public static final String ASPECT_MANAGER_FIELD = ASPECTWERKZ_PREFIX + "aspectManager";
    public static final String GET_JOIN_POINT_MANAGER = "getJoinPointManager";
    public static final String GET_ASPECT_MANAGER_METHOD = "getAspectManager";
    public static final String GET_SYSTEM_METHOD = "getSystem";
    public static final String GET_MIXIN_METHOD = "getMixin";
    public static final String INVOKE_MIXIN_METHOD = "invokeMixin";
    public static final String SERIAL_VERSION_UID_FIELD = "serialVersionUID";
    public static final String PROCEED_WITH_EXECUTION_JOIN_POINT_METHOD = "proceedWithExecutionJoinPoint";
    public static final String PROCEED_WITH_CALL_JOIN_POINT_METHOD = "proceedWithCallJoinPoint";
    public static final String PROCEED_WITH_SET_JOIN_POINT_METHOD = "proceedWithSetJoinPoint";
    public static final String PROCEED_WITH_GET_JOIN_POINT_METHOD = "proceedWithGetJoinPoint";
    public static final String PROCEED_WITH_HANDLER_JOIN_POINT_METHOD = "proceedWithHandlerJoinPoint";
    public static final String SUPER_CALL_WRAPPER_PREFIX = ASPECTWERKZ_PREFIX + DELIMITER + "super_call_wrapper"
                                                           + DELIMITER;
    public static final String MEMBER_METHOD_JOIN_POINT_PREFIX = JOIN_POINT_PREFIX + DELIMITER + "member_method"
                                                                 + DELIMITER;
    public static final String STATIC_METHOD_JOIN_POINT_PREFIX = JOIN_POINT_PREFIX + DELIMITER + "static_method"
                                                                 + DELIMITER;
    public static final String MEMBER_FIELD_GET_JOIN_POINT_PREFIX = JOIN_POINT_PREFIX + DELIMITER + "member_field"
                                                                    + DELIMITER + "get" + DELIMITER;
    public static final String MEMBER_FIELD_SET_JOIN_POINT_PREFIX = JOIN_POINT_PREFIX + DELIMITER + "member_field"
                                                                    + DELIMITER + "set" + DELIMITER;
    public static final String STATIC_FIELD_GET_JOIN_POINT_PREFIX = JOIN_POINT_PREFIX + DELIMITER + "static_field"
                                                                    + DELIMITER + "get" + DELIMITER;
    public static final String STATIC_FIELD_SET_JOIN_POINT_PREFIX = JOIN_POINT_PREFIX + DELIMITER + "static_field"
                                                                    + DELIMITER + "set" + DELIMITER;
    public static final String CALLER_SIDE_JOIN_POINT_PREFIX = JOIN_POINT_PREFIX + DELIMITER + "caller_side_method"
                                                               + DELIMITER;
    public static final String CONSTRUCTOR_JOIN_POINT_PREFIX = JOIN_POINT_PREFIX + DELIMITER + "constructor"
                                                               + DELIMITER;
    public static final String FIELD_JOIN_POINT_PRE_EXECUTION_METHOD = "pre";
    public static final String FIELD_JOIN_POINT_POST_EXECUTION_METHOD = "post";
    public static final String CALLER_SIDE_JOIN_POINT_PRE_EXECUTION_METHOD = "pre";
    public static final String CALLER_SIDE_JOIN_POINT_POST_EXECUTION_METHOD = "post";
    public static final String HANDLER_JOIN_POINT_EXECUTION_METHOD = "proceed";
    public static final String GET_JOIN_POINTS_EXECUTION_METHOD = "getJoinPoints";
    public static final String UUID_EXECUTION_METHOD = "generate";
    public static final String GET_UUID_METHOD = ASPECTWERKZ_PREFIX + "getUuid";
    public static final String GET_META_DATA_METHOD = ASPECTWERKZ_PREFIX + "getMetaData";
    public static final String SET_META_DATA_METHOD = ASPECTWERKZ_PREFIX + "addMetaData";
    public static final String CLASS_LOOKUP_METHOD = "class$";
    public static final String ASPECT_MANAGER_CLASS = "org.codehaus.aspectwerkz.aspect.management.AspectManager";
    public static final String JOIN_POINT_MANAGER_CLASS = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointManager";
    public static final String JOIN_POINT_TYPE_METHOD_EXECUTION = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointType.METHOD_EXECUTION";
    public static final String JOIN_POINT_TYPE_METHOD_CALL = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointType.METHOD_CALL";
    public static final String JOIN_POINT_TYPE_CONSTRUCTOR_EXECUTION = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointType.CONSTRUCTOR_EXECUTION";
    public static final String JOIN_POINT_TYPE_CONSTRUCTOR_CALL = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointType.CONSTRUCTOR_CALL";
    public static final String JOIN_POINT_TYPE_FIELD_SET = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointType.FIELD_SET";
    public static final String JOIN_POINT_TYPE_FIELD_GET = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointType.FIELD_GET";
    public static final String JOIN_POINT_TYPE_HANDLER = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointType.HANDLER";
    public static final String JOIN_POINT_TYPE_STATIC_INITALIZATION = "org.codehaus.aspectwerkz.joinpoint.management.JoinPointType.STATIC_INITIALIZATION";
    public static final String SYSTEM_CLASS = "org.codehaus.aspectwerkz.RuntimeSystem";
    public static final String SYSTEM_LOADER_CLASS = "org.codehaus.aspectwerkz.SystemLoader";
    public static final String MIXIN_CLASS = "org.codehaus.aspectwerkz.Mixin";
    public static final String THREAD_LOCAL_CLASS = "org.codehaus.aspectwerkz.util.SerializableThreadLocal";
    public static final String WEAK_REFERENCE_CLASS = "java.lang.ref.WeakReference";
    public static final String MEMBER_METHOD_JOIN_POINT_CLASS = "org.codehaus.aspectwerkz.joinpoint.MemberMethodJoinPoint";
    public static final String STATIC_METHOD_JOIN_POINT_CLASS = "org.codehaus.aspectwerkz.joinpoint.StaticMethodJoinPoint";
    public static final String MEMBER_FIELD_GET_JOIN_POINT_CLASS = "org.codehaus.aspectwerkz.joinpoint.MemberFieldGetJoinPoint";
    public static final String MEMBER_FIELD_SET_JOIN_POINT_CLASS = "org.codehaus.aspectwerkz.joinpoint.MemberFieldSetJoinPoint";
    public static final String STATIC_FIELD_GET_JOIN_POINT_CLASS = "org.codehaus.aspectwerkz.joinpoint.StaticFieldGetJoinPoint";
    public static final String STATIC_FIELD_SET_JOIN_POINT_CLASS = "org.codehaus.aspectwerkz.joinpoint.StaticFieldSetJoinPoint";
    public static final String CALLER_SIDE_JOIN_POINT_CLASS = "org.codehaus.aspectwerkz.joinpoint.CallerSideJoinPoint";
    public static final String CONSTRUCTOR_JOIN_POINT_CLASS = "org.codehaus.aspectwerkz.joinpoint.ConstructorJoinPoint";
    public static final String IDENTIFIABLE_INTERFACE = "org.codehaus.aspectwerkz.Identifiable";
    public static final String META_DATA_INTERFACE = "org.codehaus.aspectwerkz.MetaDataEnhanceable";
    public static final String UUID_CLASS = "org.codehaus.aspectwerkz.util.UuidGenerator";
    public static final String CROSS_CUTTING_INFO_CLASS = "org.codehaus.aspectwerkz.CrossCuttingInfo";
    public static final String EMPTY_WRAPPER_ATTRIBUTE = ASPECTWERKZ_PREFIX + "empty";
    public static final byte EMPTY_WRAPPER_ATTRIBUTE_VALUE_EMPTY = Byte.MIN_VALUE;
    public static final byte EMPTY_WRAPPER_ATTRIBUTE_VALUE_NOTEMPTY = Byte.MAX_VALUE;
    public static final String JOIN_POINT_INDEX_ATTRIBUTE = ASPECTWERKZ_PREFIX + "JoinPointIndex";
    public static final String SYSTEM_ATTRIBUTE_CLASS_USE = ASPECTWERKZ_PREFIX + "ClassUseAttribute";

    /**
     * Creates a sorted method list of all the public methods in the class and super classes.
     *
     * @param klass the class with the methods
     * @return the sorted method list
     */
    public static List createSortedMethodList(final Class klass) {
        if (klass == null) {
            throw new IllegalArgumentException("class to sort method on can not be null");
        }

        // get all public methods including the inherited methods
        java.lang.reflect.Method[] methods = klass.getMethods();
        List methodList = new ArrayList(methods.length);
        for (int i = 0; i < methods.length; i++) {
            java.lang.reflect.Method method = methods[i];
            if (!method.getName().equals("equals") && !method.getName().equals("hashCode")
                && !method.getName().equals("getClass") && !method.getName().equals("toString")
                && !method.getName().equals("wait") && !method.getName().equals("notify")
                && !method.getName().equals("notifyAll") && !method.getName().startsWith(CLASS_LOOKUP_METHOD)
                && !method.getName().startsWith(GET_UUID_METHOD) && !method.getName().startsWith(GET_META_DATA_METHOD)
                && !method.getName().startsWith(SET_META_DATA_METHOD)
                && !method.getName().startsWith(ORIGINAL_METHOD_PREFIX)
                && !method.getName().startsWith(ASPECTWERKZ_PREFIX)) {
                methodList.add(method);
            }
        }
        Collections.sort(methodList, MethodComparator.getInstance(MethodComparator.NORMAL_METHOD));
        return methodList;
    }

    /**
     * Creates a sorted method list of all the public methods in the class and super classes.
     *
     * @param klass the class with the methods
     * @return the sorted method list
     */
    public static List createSortedMethodList(final CtClass klass) {
        if (klass == null) {
            throw new IllegalArgumentException("class to sort method on can not be null");
        }

        // get all public methods including the inherited methods
        CtMethod[] methods = klass.getDeclaredMethods();
        List methodList = new ArrayList(methods.length);
        for (int i = 0; i < methods.length; i++) {
            CtMethod method = methods[i];
            if (!method.getName().equals("equals") && !method.getName().equals("hashCode")
                && !method.getName().equals("getClass") && !method.getName().equals("toString")
                && !method.getName().equals("wait") && !method.getName().equals("notify")
                && !method.getName().equals("notifyAll") && !method.getName().startsWith(CLASS_LOOKUP_METHOD)
                && !method.getName().startsWith(GET_UUID_METHOD) && !method.getName().startsWith(GET_META_DATA_METHOD)
                && !method.getName().startsWith(SET_META_DATA_METHOD)
                && !method.getName().startsWith(ORIGINAL_METHOD_PREFIX)
                && !method.getName().startsWith(ASPECTWERKZ_PREFIX)) {
                methodList.add(method);
            }
        }
        Collections.sort(methodList, MethodComparator.getInstance(MethodComparator.NORMAL_METHOD));
        return methodList;
    }

    /**
     * Checks if a class has a certain class as super class, somewhere up in the class hierarchy.
     *
     * @param classInfo the meta-data for the class to parse
     * @param className the name of the super class
     * @return true if we have a parse else false
     */
    public static boolean extendsSuperClass(final ClassInfo classInfo, final String className) {
        if ((classInfo == null) || (className == null)) {
            return false;
        } else if (classInfo.getName().equals(null)) {
            return true;
        } else if (className.equals(classInfo.getName())) {
            return true;
        } else {
            return TransformationUtil.extendsSuperClass(classInfo.getSuperClass(), className);
        }
    }

    /**
     * Checks if a class implements a certain inteface, somewhere up in the class hierarchy.
     *
     * @param classInfo
     * @param interfaceName
     * @return true if we have a parse else false
     */
    public static boolean implementsInterface(final ClassInfo classInfo, final String interfaceName) {
        if ((classInfo == null) || (interfaceName == null)) {
            return false;
        } else if (classInfo.getName().equals(null)) {
            return true;
        } else {
            ClassInfo[] interfaces = classInfo.getInterfaces();
            for (int i = 0; i < interfaces.length; i++) {
                ClassInfo anInterface = interfaces[i];
                if (TransformationUtil.implementsInterface(anInterface, interfaceName)) {
                    return true;
                }
            }
            return TransformationUtil.implementsInterface(classInfo.getSuperClass(), interfaceName);
        }
    }

    /**
     * Converts modifiers represented in a string array to an int.
     *
     * @param modifiers the modifiers as strings
     * @return the modifiers as an int
     */
    public static int getModifiersAsInt(final String[] modifiers) {
        int accessFlags = 0;
        for (int i = 0; i < modifiers.length; i++) {
            if (modifiers[i].equals("abstract")) {
                accessFlags |= Modifier.ABSTRACT;
            } else if (modifiers[i].equals("final")) {
                accessFlags |= Modifier.FINAL;
            } else if (modifiers[i].equals("interface")) {
                accessFlags |= Modifier.INTERFACE;
            } else if (modifiers[i].equals("native")) {
                accessFlags |= Modifier.NATIVE;
            } else if (modifiers[i].equals("private")) {
                accessFlags |= Modifier.PRIVATE;
            } else if (modifiers[i].equals("protected")) {
                accessFlags |= Modifier.PROTECTED;
            } else if (modifiers[i].equals("public")) {
                accessFlags |= Modifier.PUBLIC;
            } else if (modifiers[i].equals("static")) {
                accessFlags |= Modifier.STATIC;
            } else if (modifiers[i].equals("strict")) {
                accessFlags |= Modifier.STRICT;
            } else if (modifiers[i].equals("synchronized")) {
                accessFlags |= Modifier.SYNCHRONIZED;
            } else if (modifiers[i].equals("transient")) {
                accessFlags |= Modifier.TRANSIENT;
            } else if (modifiers[i].equals("volatile")) {
                accessFlags |= Modifier.VOLATILE;
            }
        }
        return accessFlags;
    }

    /**
     * Calculate the hash for a class.
     *
     * @param klass the class
     * @return the hash
     */
    public static int calculateHash(final Class klass) {
        int hash = 17;
        Method[] methods = klass.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            hash = (37 * hash) + calculateHash(methods[i]);
        }
        Constructor[] constructors = klass.getDeclaredConstructors();
        for (int i = 0; i < constructors.length; i++) {
            hash = (37 * hash) + calculateHash(constructors[i]);
        }
        Field[] fields = klass.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            hash = (37 * hash) + calculateHash(fields[i]);
        }
        return hash;
    }

    /**
     * Calculate the hash for a class.
     *
     * @param ctClass the class
     * @return the hash
     */
    public static int calculateHash(final CtClass ctClass) throws NotFoundException {
        int hash = 17;
        CtMethod[] methods = ctClass.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            hash = (37 * hash) + calculateHash(methods[i]);
        }
        CtConstructor[] constructors = ctClass.getDeclaredConstructors();
        for (int i = 0; i < constructors.length; i++) {
            hash = (37 * hash) + calculateHash(constructors[i]);
        }
        CtField[] fields = ctClass.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            hash = (37 * hash) + calculateHash(fields[i]);
        }
        return hash;
    }

    /**
     * Calculate the hash for a method.
     *
     * @param method the method
     * @return the hash
     */
    public static int calculateHash(final java.lang.reflect.Method method) {
        int hash = 17;
        hash = (37 * hash) + method.getName().hashCode();
        for (int i = 0; i < method.getParameterTypes().length; i++) {
            Class type = method.getParameterTypes()[i];
            hash = (37 * hash) + type.getName().hashCode();
        }
        return hash;
    }

    /**
     * Calculate the hash for a javassist method.
     *
     * @param method the method
     * @return the hash
     */
    public static int calculateHash(final CtMethod method) throws NotFoundException {
        int hash = 17;
        hash = (37 * hash) + method.getName().hashCode();
        for (int i = 0; i < method.getParameterTypes().length; i++) {
            CtClass type = method.getParameterTypes()[i];
            String name = JavassistHelper.convertJavassistTypeSignatureToReflectTypeSignature(
                    type.getName().replace(
                            '/',
                            '.'
                    )
            );
            hash = (37 * hash) + name.hashCode();
        }
        return hash;
    }

    /**
     * Calculate the hash for a constructor.
     *
     * @param constructor the constructor
     * @return the hash
     */
    public static int calculateHash(final Constructor constructor) {
        int hash = 17;
        hash = (37 * hash) + constructor.getName().hashCode();
        for (int i = 0; i < constructor.getParameterTypes().length; i++) {
            Class type = constructor.getParameterTypes()[i];
            hash = (37 * hash) + type.getName().replace('/', '.').hashCode();
        }
        return hash;
    }

    /**
     * Calculate the hash for a javassist constructor.
     *
     * @param constructor the constructor
     * @return the hash
     */
    public static int calculateHash(final CtConstructor constructor) throws NotFoundException {
        int hash = 17;
        hash = (37 * hash) + constructor.getName().hashCode();
        for (int i = 0; i < constructor.getParameterTypes().length; i++) {
            CtClass type = constructor.getParameterTypes()[i];
            String name = JavassistHelper.convertJavassistTypeSignatureToReflectTypeSignature(
                    type.getName().replace(
                            '/',
                            '.'
                    )
            );
            hash = (37 * hash) + name.hashCode();
        }
        return hash;
    }

    /**
     * Calculate the hash for a field.
     *
     * @param field the field
     * @return the hash
     */
    public static int calculateHash(final Field field) {
        int hash = 17;
        hash = (37 * hash) + field.getName().hashCode();
        Class type = field.getType();
        hash = (37 * hash) + type.getName().hashCode();
        return hash;
    }

    /**
     * Calculate the hash for a javassist field.
     *
     * @param field the field
     * @return the hash
     */
    public static int calculateHash(final CtField field) throws NotFoundException {
        int hash = 17;
        hash = (37 * hash) + field.getName().hashCode();
        String name = JavassistHelper.convertJavassistTypeSignatureToReflectTypeSignature(
                field.getType().getName()
                .replace('/', '.')
        );
        hash = (37 * hash) + name.hashCode();
        return hash;
    }

    /**
     * Returns the prefixed method name.
     *
     * @param methodName     the method name
     * @param methodSequence the method sequence
     * @param className      the class name
     * @return the name of the join point
     */
    public static String getPrefixedMethodName(
            final String methodName, final int methodSequence, final String className) {
        final StringBuffer buf = new StringBuffer();
        buf.append(ORIGINAL_METHOD_PREFIX);
        buf.append(methodName);
        buf.append(DELIMITER);
        buf.append(methodSequence);
        buf.append(DELIMITER);
        buf.append(className.replace('.', '_'));
        return buf.toString();
    }

    /**
     * Returrns the join point index for the class.
     *
     * @param klass
     * @return the index
     */
    public static int getJoinPointIndex(final CtClass klass) {
        byte[] attribute = klass.getAttribute(JOIN_POINT_INDEX_ATTRIBUTE);
        if (attribute == null) {
            klass.setAttribute(JOIN_POINT_INDEX_ATTRIBUTE, new byte[]{new Integer(0).byteValue()});
            return 0;
        }
        return new Integer(attribute[0]).intValue();
    }

    /**
     * Sets the join point index for the class.
     *
     * @param klass
     * @param index
     */
    public static void setJoinPointIndex(final CtClass klass, final int index) {
        klass.setAttribute(JOIN_POINT_INDEX_ATTRIBUTE, new byte[]{new Integer(index).byteValue()});
    }

    /**
     * Checks if a method is static or not.
     *
     * @param methodInfo the info for the method
     * @return boolean
     */
    public static boolean isMethodStatic(final MethodInfo methodInfo) {
        int modifiers = methodInfo.getModifiers();
        if ((modifiers & javassist.Modifier.STATIC) != 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Creates a member info instance based on the signature etc.
     *
     * @param targetClass
     * @param withinMethodName
     * @param withinMethodSignature
     * @return a member info instance
     * @TODO: check if we have a constructor and not a method
     */
    public static MemberInfo createMemberInfo(
            final Class targetClass, final String withinMethodName,
            final String withinMethodSignature) {
        MemberInfo withinMemberInfo = null;
        String[] withinMethodParameterNames = DescriptorUtil.getParameters(withinMethodSignature);
        Method[] targetMethods = targetClass.getDeclaredMethods();
        for (int i = 0; i < targetMethods.length; i++) {
            Method method = targetMethods[i];
            Class[] parameterTypes = method.getParameterTypes();
            if (method.getName().equals(withinMethodName)
                && (withinMethodParameterNames.length == parameterTypes.length)) {
                boolean match = true;
                for (int j = 0; j < parameterTypes.length; j++) {
                    String withinMethodParameterName = JavassistHelper
                            .convertJavassistTypeSignatureToReflectTypeSignature(withinMethodParameterNames[j]);
                    if (!parameterTypes[j].getName().equals(withinMethodParameterName)) {
                        match = false;
                        break;
                    }
                }
                if (match) {
                    withinMemberInfo = JavaMethodInfo.getMethodInfo(method);
                    break;
                }
            }
        }
        return withinMemberInfo;
    }
}
TOP

Related Classes of org.codehaus.aspectwerkz.transform.TransformationUtil

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.