Package org.codehaus.aspectwerkz.reflect.impl.java

Source Code of org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo

/**************************************************************************************

* 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.reflect.impl.java;



import gnu.trove.TIntObjectHashMap;

import org.codehaus.aspectwerkz.annotation.Annotations;

import org.codehaus.aspectwerkz.reflect.ClassInfo;

import org.codehaus.aspectwerkz.reflect.ConstructorInfo;

import org.codehaus.aspectwerkz.reflect.FieldInfo;

import org.codehaus.aspectwerkz.reflect.MethodInfo;

import org.codehaus.aspectwerkz.reflect.ReflectHelper;

import org.codehaus.aspectwerkz.reflect.ReflectHelper;

import org.codehaus.aspectwerkz.reflect.StaticInitializationInfo;

import org.codehaus.aspectwerkz.reflect.StaticInitializationInfoImpl;

import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo;

import org.codehaus.aspectwerkz.transform.TransformationConstants;



import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.util.List;



/**

* Implementation of the ClassInfo interface for java.lang.reflect.*.

*

* @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r </a>

*/

public class JavaClassInfo implements ClassInfo {

    /**

     * The class.

     */

    // TODO might be safer to wrap this member in a weak ref

    private final Class m_class;



    /**

     * The name of the class.

     */

    private String m_name;



    /**

     * The signature of the class.

     */

    private String m_signature;



    /**

     * Is the class an interface.

     */

    private boolean m_isInterface = false;



    /**

     * Is the class a primitive type.

     */

    private boolean m_isPrimitive = false;



    /**

     * Is the class of type array.

     */

    private boolean m_isArray = false;



    /**

     * A list with the <code>ConstructorInfo</code> instances.

     */

    private final TIntObjectHashMap m_constructors = new TIntObjectHashMap();



    /**

     * A list with the <code>MethodInfo</code> instances.

     */

    private final TIntObjectHashMap m_methods = new TIntObjectHashMap();



    /**

     * A list with the <code>FieldInfo</code> instances.

     */

    private final TIntObjectHashMap m_fields = new TIntObjectHashMap();



    /**

     * A list with the interfaces.

     */

    private ClassInfo[] m_interfaces = null;



    /**

     * The super class.

     */

    private ClassInfo m_superClass = null;



    /**

     * The annotations.

     */

    private List m_annotations = null;



    /**

     * The component type if array type.

     */

    private ClassInfo m_componentType = null;



    /**

     * The class info repository.

     */

    private final JavaClassInfoRepository m_classInfoRepository;



    /**

     * Lazy, the static initializer info or null if not present

     */

    private StaticInitializationInfo m_staticInitializer = null;



    /**

     * Creates a new class meta data instance.

     *

     * @param klass

     */

    JavaClassInfo(final Class klass) {

        if (klass == null) {

            throw new IllegalArgumentException("class can not be null");

        }

        m_class = klass;



        m_signature = ReflectHelper.getClassSignature(klass);



        m_classInfoRepository = JavaClassInfoRepository.getRepository(klass.getClassLoader());

        m_isInterface = klass.isInterface();

        if (klass.isPrimitive()) {

            m_name = klass.getName();

            m_isPrimitive = true;

        } else if (klass.getComponentType() != null) {

            m_name = convertJavaArrayTypeNameToHumanTypeName(klass.getName());

            m_isArray = true;

            m_interfaces = new ClassInfo[0];

        } else {

            m_name = klass.getName();

            Method[] methods = m_class.getDeclaredMethods();

            for (int i = 0; i < methods.length; i++) {

                Method method = methods[i];

                m_methods.put(ReflectHelper.calculateHash(method), new JavaMethodInfo(method, this));

            }

            Constructor[] constructors = m_class.getDeclaredConstructors();

            for (int i = 0; i < constructors.length; i++) {

                Constructor constructor = constructors[i];

                m_constructors.put(

                        ReflectHelper.calculateHash(constructor), new JavaConstructorInfo(

                                constructor,

                                this

                        )

                );

            }

            Field[] fields = m_class.getDeclaredFields();

            for (int i = 0; i < fields.length; i++) {

                if (fields[i].getName().startsWith(TransformationConstants.ASPECTWERKZ_PREFIX)) {

                    continue;

                }

                Field field = fields[i];

                m_fields.put(ReflectHelper.calculateHash(field), new JavaFieldInfo(field, this));

            }

        }

        m_classInfoRepository.addClassInfo(this);

    }



    /**

     * Returns the class info for a specific class.

     *

     * @return the class info

     */

    public static ClassInfo getClassInfo(final Class clazz) {

        JavaClassInfoRepository repository = JavaClassInfoRepository.getRepository(clazz.getClassLoader());

        ClassInfo classInfo = repository.getClassInfo(clazz.getName());

        if (classInfo == null) {

            classInfo = new JavaClassInfo(clazz);

        }

        return classInfo;

    }



    /**

     * Returns the annotations infos.

     *

     * @return the annotations infos

     */

    public List getAnnotations() {

        if (m_annotations == null) {

            // TODO this means that JavaClassInfo is always using AsmClassInfo to get that annotations

            // TODO should optimize for Java5

            m_annotations = Annotations.getAnnotationInfos(m_class);

        }

        return m_annotations;

    }



    /**

     * Returns the name of the class.

     *

     * @return the name of the class

     */

    public String getName() {

        return m_name.replace('/', '.');

    }



    /**

     * Checks if the class has a static initalizer.

     *

     * @return

     */

    public boolean hasStaticInitializer() {

        ClassInfo classInfo = AsmClassInfo.getClassInfo(getName(), getClassLoader());

        return classInfo.hasStaticInitializer();

    }



  /**

   * Returns the static initializer info of the current underlying class if any.

   *

   * @see org.codehaus.aspectwerkz.reflect.ClassInfo#staticInitializer()

   */

  public StaticInitializationInfo staticInitializer() {

    if(hasStaticInitializer() && m_staticInitializer == null) {

      m_staticInitializer = new StaticInitializationInfoImpl(this);

    }

    return m_staticInitializer;

  }

 

    /**

     * Returns the signature for the element.

     *

     * @return the signature for the element

     */

    public String getSignature() {

        return m_signature;

    }



    /**

     * Returns the class modifiers.

     *

     * @return the class modifiers

     */

    public int getModifiers() {

        return m_class.getModifiers();

    }



    /**

     * Returns the class loader that loaded this class.

     *

     * @return the class loader

     */

    public ClassLoader getClassLoader() {

        return m_class.getClassLoader();

    }



    /**

     * Returns a constructor info by its hash.

     *

     * @param hash

     * @return

     */

    public ConstructorInfo getConstructor(final int hash) {

        ConstructorInfo constructor = (ConstructorInfo) m_constructors.get(hash);

        if (constructor == null && getSuperclass() != null) {

            constructor = getSuperclass().getConstructor(hash);

        }

        return constructor;

    }



    /**

     * Returns a list with all the constructors info.

     *

     * @return the constructors info

     */

    public ConstructorInfo[] getConstructors() {

        Object[] values = m_constructors.getValues();

        ConstructorInfo[] methodInfos = new ConstructorInfo[values.length];

        for (int i = 0; i < values.length; i++) {

            methodInfos[i] = (ConstructorInfo) values[i];

        }

        return methodInfos;

    }



    /**

     * Returns a method info by its hash.

     *

     * @param hash

     * @return

     */

    public MethodInfo getMethod(final int hash) {

        MethodInfo method = (MethodInfo) m_methods.get(hash);

        if (method == null) {

            for (int i = 0; i < getInterfaces().length; i++) {

                method = getInterfaces()[i].getMethod(hash);

                if (method != null) {

                    break;

                }

            }

        }

        if (method == null && getSuperclass() != null) {

            method = getSuperclass().getMethod(hash);

        }

        return method;

    }



    /**

     * Returns a list with all the methods info.

     *

     * @return the methods info

     */

    public MethodInfo[] getMethods() {

        Object[] values = m_methods.getValues();

        MethodInfo[] methodInfos = new MethodInfo[values.length];

        for (int i = 0; i < values.length; i++) {

            methodInfos[i] = (MethodInfo) values[i];

        }

        return methodInfos;

    }



    /**

     * Returns a field info by its hash.

     *

     * @param hash

     * @return

     */

    public FieldInfo getField(final int hash) {

        FieldInfo field = (FieldInfo) m_fields.get(hash);

        if (field == null && getSuperclass() != null) {

            field = getSuperclass().getField(hash);

        }

        return field;

    }



    /**

     * Returns a list with all the field info.

     *

     * @return the field info

     */

    public FieldInfo[] getFields() {

        Object[] values = m_fields.getValues();

        FieldInfo[] fieldInfos = new FieldInfo[values.length];

        for (int i = 0; i < values.length; i++) {

            fieldInfos[i] = (FieldInfo) values[i];

        }

        return fieldInfos;

    }



    /**

     * Returns the interfaces.

     *

     * @return the interfaces

     */

    public ClassInfo[] getInterfaces() {

        if (m_interfaces == null) {

            Class[] interfaces = m_class.getInterfaces();

            m_interfaces = new ClassInfo[interfaces.length];

            for (int i = 0; i < interfaces.length; i++) {

                Class anInterface = interfaces[i];

                ClassInfo classInfo = JavaClassInfo.getClassInfo(anInterface);

                m_interfaces[i] = classInfo;

                if (!m_classInfoRepository.hasClassInfo(anInterface.getName())) {

                    m_classInfoRepository.addClassInfo(classInfo);

                }

            }

        }

        return m_interfaces;

    }



    /**

     * Returns the super class.

     *

     * @return the super class

     */

    public ClassInfo getSuperclass() {

        if (m_superClass == null) {

            Class superclass = m_class.getSuperclass();

            if (superclass != null) {

                if (m_classInfoRepository.hasClassInfo(superclass.getName())) {

                    m_superClass = m_classInfoRepository.getClassInfo(superclass.getName());

                } else {

                    m_superClass = JavaClassInfo.getClassInfo(superclass);

                    m_classInfoRepository.addClassInfo(m_superClass);

                }

            }

        }

        return m_superClass;

    }



    /**

     * Returns the component type if array type else null.

     *

     * @return the component type

     */

    public ClassInfo getComponentType() {

        if (isArray() && (m_componentType == null)) {

            Class componentType = m_class.getComponentType();

            if (m_classInfoRepository.hasClassInfo(componentType.getName())) {

                m_componentType = m_classInfoRepository.getClassInfo(componentType.getName());

            } else {

                m_componentType = JavaClassInfo.getClassInfo(componentType);

                m_classInfoRepository.addClassInfo(m_componentType);

            }

        }

        return m_componentType;

    }



    /**

     * Is the class an interface.

     *

     * @return

     */

    public boolean isInterface() {

        return m_isInterface;

    }



    /**

     * Is the class a primitive type.

     *

     * @return

     */

    public boolean isPrimitive() {

        return m_isPrimitive;

    }



    /**

     * Is the class an array type.

     *

     * @return

     */

    public boolean isArray() {

        return m_isArray;

    }



    /**

     * Converts an internal Java array type name ([Lblabla) to the a the format used by the expression matcher

     * (blabla[])

     *

     * @param typeName is type name

     * @return

     */

    public static String convertJavaArrayTypeNameToHumanTypeName(final String typeName) {

        int index = typeName.lastIndexOf('[');

        if (index != -1) {

            StringBuffer arrayType = new StringBuffer();

            if (typeName.endsWith("I")) {

                arrayType.append("int");

            } else if (typeName.endsWith("J")) {

                arrayType.append("long");

            } else if (typeName.endsWith("S")) {

                arrayType.append("short");

            } else if (typeName.endsWith("F")) {

                arrayType.append("float");

            } else if (typeName.endsWith("D")) {

                arrayType.append("double");

            } else if (typeName.endsWith("Z")) {

                arrayType.append("boolean");

            } else if (typeName.endsWith("C")) {

                arrayType.append("char");

            } else if (typeName.endsWith("B")) {

                arrayType.append("byte");

            } else {

                arrayType.append(typeName.substring(index + 2, typeName.length() - 1));

            }

            for (int i = 0; i < (index + 1); i++) {

                arrayType.append("[]");

            }

            return arrayType.toString();

        } else {

            return typeName;

        }

    }



    public boolean equals(Object o) {

        if (this == o) {

            return true;

        }

        if (!(o instanceof ClassInfo)) {

            return false;

        }

        ClassInfo classInfo = (ClassInfo) o;

        return m_class.getName().toString().equals(classInfo.getName().toString());

    }



    public int hashCode() {

        return m_class.getName().toString().hashCode();

    }



    public String toString() {

        return getName();

    }

}
TOP

Related Classes of org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo

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.