/**************************************************************************************
* 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.joinpoint.management;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.codehaus.aspectwerkz.joinpoint.EnclosingStaticJoinPoint;
import org.codehaus.aspectwerkz.joinpoint.impl.CatchClauseSignatureImpl;
import org.codehaus.aspectwerkz.joinpoint.impl.ConstructorSignatureImpl;
import org.codehaus.aspectwerkz.joinpoint.impl.EnclosingStaticJoinPointImpl;
import org.codehaus.aspectwerkz.joinpoint.impl.FieldSignatureImpl;
import org.codehaus.aspectwerkz.joinpoint.impl.MethodSignatureImpl;
import org.codehaus.aspectwerkz.joinpoint.impl.StaticInitializerSignatureImpl;
import org.codehaus.aspectwerkz.reflect.ReflectHelper;
import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfoRepository;
import org.codehaus.aspectwerkz.transform.TransformationConstants;
import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
/**
* Factory class for the signature hierarchy.
* The helper methods here are called by the JIT jp.
*
* TODO may be worth having a cache
*
* @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r </a>
* @author <a href="mailto:the_mindstorm@evolva.ro">Alex Popescu</a>
*/
public final class SignatureFactory {
/**
* Method signature factory
*
* @param declaringClass
* @param joinPointHash
* @return
*/
public static final MethodSignatureImpl newMethodSignature(final Class declaringClass, final int joinPointHash) {
AsmClassInfoRepository.getRepository(declaringClass.getClassLoader()).removeClassInfo(declaringClass.getName().replace('.', '/'));
Method[] methods = declaringClass.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (ReflectHelper.calculateHash(method) == joinPointHash) {
return new MethodSignatureImpl(declaringClass, method);
}
}
// lookup in the hierarchy
MethodSignatureImpl signature = null;
for (int i = 0; i < declaringClass.getInterfaces().length; i++) {
signature = newMethodSignature(declaringClass.getInterfaces()[i], joinPointHash);
if (signature != null) {
return signature;
}
}
if (declaringClass.getSuperclass() != null) {
signature = newMethodSignature(declaringClass.getSuperclass(), joinPointHash);
} else {
return null;
}
return signature;
}
/**
* Field signature factory
*
* @param declaringClass
* @param joinPointHash
* @return
*/
public static final FieldSignatureImpl newFieldSignature(final Class declaringClass, final int joinPointHash) {
Field[] fields = declaringClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
if (ReflectHelper.calculateHash(field) == joinPointHash) {
return new FieldSignatureImpl(declaringClass, field);
}
}
// lookup in the hierarchy
if (declaringClass.getSuperclass() != null) {
return newFieldSignature(declaringClass.getSuperclass(), joinPointHash);
} else {
return null;
}
}
/**
* Constructor signature factory
*
* @param declaringClass
* @param joinPointHash
* @return
*/
public static final ConstructorSignatureImpl newConstructorSignature(final Class declaringClass,
final int joinPointHash) {
Constructor constructor = null;
for (int i = 0; i < declaringClass.getDeclaredConstructors().length; i++) {
Constructor c = declaringClass.getDeclaredConstructors()[i];
if (ReflectHelper.calculateHash(c) == joinPointHash) {
return new ConstructorSignatureImpl(declaringClass, c);
}
}
// lookup in the hierarchy
if (declaringClass.getSuperclass() != null) {
return newConstructorSignature(declaringClass.getSuperclass(), joinPointHash);
} else {
return null;
}
}
/**
* Handler signature factory
*
* @param exceptionClass
* @return
*/
public static final CatchClauseSignatureImpl newCatchClauseSignature(final Class exceptionClass) {
return new CatchClauseSignatureImpl(exceptionClass);
}
/**
* Enclosing signature factory, wrapped behind an EnclosingStaticJoinPoint for syntax consistency
*
* @param declaringClass
* @param name
* @param description
* @return
*/
public static EnclosingStaticJoinPoint newEnclosingStaticJoinPoint(
final Class declaringClass,
final String name,
final String description) {
if (TransformationConstants.CLINIT_METHOD_NAME.equals(name)) {
return new EnclosingStaticJoinPointImpl(
new StaticInitializerSignatureImpl(declaringClass),
JoinPointType.STATIC_INITIALIZATION
);
} else if (TransformationConstants.INIT_METHOD_NAME.equals(name)) {
return new EnclosingStaticJoinPointImpl(
newConstructorSignature(declaringClass, AsmHelper.calculateConstructorHash(description)),
JoinPointType.CONSTRUCTOR_EXECUTION
);
} else {
// regular method
return new EnclosingStaticJoinPointImpl(
newMethodSignature(declaringClass, AsmHelper.calculateMethodHash(name, description)),
JoinPointType.METHOD_EXECUTION
);
}
}
/**
* Static initialization factory
*
* @param declaringClass
* @return
*/
public static StaticInitializerSignatureImpl newStaticInitializationSignature(final Class declaringClass) {
return new StaticInitializerSignatureImpl(declaringClass);
}
}