Package org.codehaus.aspectwerkz.reflect.impl.javassist

Source Code of org.codehaus.aspectwerkz.reflect.impl.javassist.JavassistClassInfo

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

* 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.javassist;



import gnu.trove.TIntObjectHashMap;

import org.codehaus.aspectwerkz.annotation.AnnotationInfo;

import org.codehaus.aspectwerkz.annotation.instrumentation.AttributeExtractor;

import org.codehaus.aspectwerkz.annotation.instrumentation.Attributes;

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 java.lang.ref.WeakReference;

import java.util.ArrayList;

import java.util.List;



import javassist.CtClass;

import javassist.CtConstructor;

import javassist.CtField;

import javassist.CtMethod;

import javassist.NotFoundException;



/**

* Implementation of the ClassInfo interface for Javassist.

*

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

* @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>

*/

public class JavassistClassInfo implements ClassInfo {

    /**

     * The class.

     */

    private final CtClass m_class;



    /**

     * The name of the class.

     */

    private String m_name;



    /**

     * Is the class a primitive type.

     */

    private boolean m_isPrimitive = false;



    /**

     * Is the class an interface.

     */

    private boolean m_isInterface = false;



    /**

     * Is the class of type array.

     */

    private boolean m_isArray = false;



    /**

     * A list with the <code>ConstructorMetaData</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>FieldMetaData</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 attributes.

     */

    private List m_annotations = null;



    /**

     * The component type if array type.

     */

    private ClassInfo m_componentType = null;



    /**

     * The class info repository.

     */

    private JavassistClassInfoRepository m_classInfoRepository;



    /**

     * The class loader that loaded the class.

     */

    private transient final WeakReference m_loaderRef;



    /**

     * The attribute extractor.

     */

    private AttributeExtractor m_attributeExtractor;



    /**

     * Creates a new class meta data instance.

     *

     * @param klass

     * @param loader

     */

    JavassistClassInfo(final CtClass klass, final ClassLoader loader) {

        if (klass == null) {

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

        }

        if (loader == null) {

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

        }

        m_class = klass;

        m_loaderRef = new WeakReference(loader);

        m_isInterface = klass.isInterface();

        m_attributeExtractor = Attributes.getAttributeExtractor(m_class, loader);

        m_classInfoRepository = JavassistClassInfoRepository.getRepository(loader);

        if (klass.isPrimitive()) {

            m_name = klass.getName();

            m_isPrimitive = true;

        } else if (klass.isArray()) {

            m_name = klass.getName();

            m_isArray = true;

            m_interfaces = new ClassInfo[0];

        } else {

            m_name = klass.getName();

            CtMethod[] methods = m_class.getDeclaredMethods();

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

                m_methods.put(JavassistMethodInfo.calculateHash(methods[i]), new JavassistMethodInfo(

                    methods[i],

                    this,

                    loader,

                    m_attributeExtractor));

            }

            CtConstructor[] constructors = m_class.getDeclaredConstructors();

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

                CtConstructor constructor = constructors[i];

                m_constructors.put(JavassistConstructorInfo.calculateHash(constructor), new JavassistConstructorInfo(

                    constructor,

                    this,

                    loader,

                    m_attributeExtractor));

            }

            if (m_class.getClassInitializer() != null) {

                CtConstructor constructor = m_class.getClassInitializer();

                m_constructors.put(JavassistConstructorInfo.calculateHash(constructor), new JavassistConstructorInfo(

                    constructor,

                    this,

                    loader,

                    m_attributeExtractor));

            }

            CtField[] fields = m_class.getDeclaredFields();

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

                CtField field = fields[i];

                m_fields.put(JavassistFieldInfo.calculateHash(field), new JavassistFieldInfo(

                    field,

                    this,

                    loader,

                    m_attributeExtractor));

            }

        }

        addAnnotations();

        m_classInfoRepository.addClassInfo(this);

    }



    /**

     * Returns the class info for a specific ctClass.

     *

     * @param clazz

     * @param loader

     * @return the class info

     */

    public static ClassInfo getClassInfo(final CtClass clazz, final ClassLoader loader) {

        JavassistClassInfoRepository repository = JavassistClassInfoRepository.getRepository(loader);

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

        if (classInfo == null) {

            classInfo = new JavassistClassInfo(clazz, loader);

        }

        return classInfo;

    }

   

    /**

     * Marks the class as dirty (since it has been modified and needs to be rebuild).

     * 

     * @param clazz

     * @param loader

     */

    public static void markDirty(final CtClass clazz, final ClassLoader loader) {

        JavassistClassInfoRepository.getRepository(loader).removeClassInfo(clazz);

    }



    /**

     * Returns the annotations.

     *

     * @return the annotations

     */

    public List getAnnotations() {

        return m_annotations;

    }



    /**

     * Returns the name of the class.

     *

     * @return the name of the class

     */

    public String getName() {

        return m_name;

    }



    /**

     * Returns the class modifiers.

     *

     * @return the class modifiers

     */

    public int getModifiers() {

        return m_class.getModifiers();

    }



    /**

     * Returns a constructor info by its hash.

     *

     * @param hash

     * @return

     */

    public ConstructorInfo getConstructor(final int hash) {

        return (ConstructorInfo) m_constructors.get(hash);

    }



    /**

     * Returns a list with all the constructors info.

     *

     * @return the constructors info

     */

    public ConstructorInfo[] getConstructors() {

        Object[] values = m_constructors.getValues();

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

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

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

        }

        return constructorInfos;

    }



    /**

     * Returns a method info by its hash.

     *

     * @param hash

     * @return

     */

    public MethodInfo getMethod(final int hash) {

        return (MethodInfo) m_methods.get(hash);

    }



    /**

     * 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) {

        return (FieldInfo) m_fields.get(hash);

    }



    /**

     * 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) {

            try {

                CtClass[] interfaces = m_class.getInterfaces();

                m_interfaces = new ClassInfo[interfaces.length];

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

                    CtClass anInterface = interfaces[i];

                    ClassInfo classInfo = JavassistClassInfo.getClassInfo(anInterface, (ClassLoader) m_loaderRef.get());

                    m_interfaces[i] = classInfo;

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

                        m_classInfoRepository.addClassInfo(classInfo);

                    }

                }

            } catch (NotFoundException e) {

                // swallow, since ok

            }

        }

        return m_interfaces;

    }



    /**

     * Returns the super class.

     *

     * @return the super class

     */

    public ClassInfo getSuperClass() {

        if (m_superClass == null) {

            try {

                CtClass superclass = m_class.getSuperclass();

                if (superclass != null) {

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

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

                    } else {

                        m_superClass = JavassistClassInfo.getClassInfo(superclass, (ClassLoader) m_loaderRef.get());

                        m_classInfoRepository.addClassInfo(m_superClass);

                    }

                }

            } catch (NotFoundException e) {

                // swallow, since ok

            }

        }

        return m_superClass;

    }



    /**

     * Returns the component type if array type else null.

     *

     * @return the component type

     */

    public ClassInfo getComponentType() {

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

            // TODO: how to impl. array component types? Is it needed?

            //            Class componentType = m_class.getComponentType();

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

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

            //            }

            //            else {

            //                m_componentType = new JavassistClassInfo(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;

    }



    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();

    }



    /**

     * Adds annotations to the class info.

     */

    private void addAnnotations() {

        if (m_attributeExtractor == null) {

            return;

        }

        m_annotations = new ArrayList();

        Object[] attributes = m_attributeExtractor.getClassAttributes();

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

            Object attribute = attributes[i];

            if (attribute instanceof AnnotationInfo) {

                m_annotations.add(attribute);

            }

        }

    }



    public String toString() {

        return getName();

    }

}
TOP

Related Classes of org.codehaus.aspectwerkz.reflect.impl.javassist.JavassistClassInfo

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.