/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.aop;
import gnu.trove.TLongObjectHashMap;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.jboss.aop.advice.AdviceBinding;
import org.jboss.aop.advice.AspectDefinition;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.instrument.ConstructorExecutionTransformer;
import org.jboss.aop.instrument.FieldAccessTransformer;
import org.jboss.aop.instrument.MethodExecutionTransformer;
import org.jboss.aop.introduction.InterfaceIntroduction;
import org.jboss.aop.joinpoint.ConstructorCalledByConstructorInvocation;
import org.jboss.aop.joinpoint.ConstructorCalledByConstructorJoinpoint;
import org.jboss.aop.joinpoint.ConstructorCalledByMethodInvocation;
import org.jboss.aop.joinpoint.ConstructorCalledByMethodJoinpoint;
import org.jboss.aop.joinpoint.ConstructorInvocation;
import org.jboss.aop.joinpoint.FieldJoinpoint;
import org.jboss.aop.joinpoint.FieldReadInvocation;
import org.jboss.aop.joinpoint.FieldWriteInvocation;
import org.jboss.aop.joinpoint.Invocation;
import org.jboss.aop.joinpoint.MethodCalledByConstructorInvocation;
import org.jboss.aop.joinpoint.MethodCalledByConstructorJoinpoint;
import org.jboss.aop.joinpoint.MethodCalledByMethodInvocation;
import org.jboss.aop.joinpoint.MethodCalledByMethodJoinpoint;
import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.aop.metadata.ClassMetaDataBinding;
import org.jboss.aop.metadata.ClassMetaDataLoader;
import org.jboss.aop.util.Advisable;
import org.jboss.aop.util.ConstructorComparator;
import org.jboss.aop.util.FieldComparator;
import org.jboss.aop.util.MethodHashing;
import org.jboss.util.NotImplementedException;
/**
* Advises a class and provides access to the class's aspect chain.
* Each advisable class has an associated <code>Advisor</code> instance.
* References methods using <code>int</code> IDs rather than the actual
* instances for
* optimal performance. Provides ability to invoke methods on an advised
* object without advice (see
* <code>Advisor.invokeWithoutAdvisement()</code>).
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
* @version $Revision: 60812 $
*/
public class ClassAdvisor extends Advisor
{
/**
* Suffix added to unadvised methods.
*/
public static final String NOT_TRANSFORMABLE_SUFFIX = "$aop";
protected TLongObjectHashMap unadvisedMethods = new TLongObjectHashMap();
// caller pointcut support for methods calling methods only
protected TLongObjectHashMap methodCalledByMethodBindings = new TLongObjectHashMap();
protected HashMap backrefMethodCalledByMethodBindings = new HashMap();
protected TLongObjectHashMap methodCalledByMethodInterceptors = new TLongObjectHashMap();
// constructor caller pointcut support for methods calling methods only
protected TLongObjectHashMap conCalledByMethodBindings = new TLongObjectHashMap();
protected HashMap backrefConCalledByMethodBindings = new HashMap();
protected TLongObjectHashMap conCalledByMethodInterceptors = new TLongObjectHashMap();
// caller pointcut support for constructors calling methods
protected HashMap[] methodCalledByConBindings;
protected HashMap[] methodCalledByConInterceptors;
protected HashMap backrefMethodCalledByConstructorBindings = new HashMap();
// caller pointcut support for constructors calling methods
protected HashMap[] conCalledByConBindings;
protected HashMap[] conCalledByConInterceptors;
protected HashMap backrefConCalledByConstructorBindings = new HashMap();
// Used by instrumentor to access separate interceptor chains for read and write access
/** @deprecated Use fieldReadInfos instead*/
private Interceptor[][] fieldReadInterceptors;
private FieldInfo[] fieldReadInfos;
/** @deprecated Use fieldWriteInfos instead */
private Interceptor[][] fieldWriteInterceptors;
private FieldInfo[] fieldWriteInfos;
protected Field[] advisedFields;
//PER_JOINPOINT aspects for static fields or PER_CLASS_JOINPOINT aspects
//all apply to fields, and we need this since the same aspect should be used for
//read and write
private HashMap fieldAspectsWithNoInstance = new HashMap();
protected boolean initialized = false;
public ClassAdvisor(String classname, AspectManager manager)
{
super(classname, manager);
}
public ClassAdvisor(Class clazz, AspectManager manager)
{
this(clazz.getName(), manager);
this.clazz = clazz;
}
/**
* This method is to support PER_JOINPOINT scoping of Aspects for static fields
* Fields are special in that a get and set do not create separate aspect instances.
*
* Also used to support PER_CLASS_JOINPOINT, since that behaves similarly to static fields
*
* @param joinpoint
* @param def
* @return
*/
public Object getFieldAspect(FieldJoinpoint joinpoint, AspectDefinition def)
{
HashMap map = (HashMap)fieldAspectsWithNoInstance.get(def);
if (map == null)
{
synchronized (fieldAspectsWithNoInstance)
{
map = (HashMap)fieldAspectsWithNoInstance.get(def);
if (map == null)
{
map = new HashMap();
fieldAspectsWithNoInstance.put(def, map);
}
}
}
Object aspect = map.get(joinpoint);
if (aspect == null)
{
synchronized (map)
{
aspect = map.get(joinpoint);
if (aspect == null)
{
aspect = def.getFactory().createPerJoinpoint(this, joinpoint);
map.put(joinpoint, aspect);
}
}
}
return aspect;
}
public Field[] getAdvisedFields()
{
return advisedFields;
}
public TLongObjectHashMap getAdvisedMethods()
{
return advisedMethods;
}
protected TLongObjectHashMap getUnadvisedMethods()
{
return unadvisedMethods;
}
public Constructor[] getConstructors()
{
return constructors;
}
public TLongObjectHashMap getMethodCalledByMethodInterceptors()
{
return methodCalledByMethodInterceptors;
}
public HashMap[] getMethodCalledByConInterceptors()
{
return methodCalledByConInterceptors;
}
public HashMap[] getConCalledByConInterceptors()
{
return conCalledByConInterceptors;
}
public TLongObjectHashMap getConCalledByMethodInterceptors()
{
return conCalledByMethodInterceptors;
}
public TLongObjectHashMap getMethodCalledByMethodBindings()
{
return methodCalledByMethodBindings;
}
/** @deprecated use getFieldReadInfos instead */
public Interceptor[][] getFieldReadInterceptors()
{
throw new NotImplementedException("Use getFieldReadInfos");
}
public FieldInfo[] getFieldReadInfos()
{
return fieldReadInfos;
}
/** @deprecated use getFieldWriteInfos instead */
public Interceptor[][] getFieldWriteInterceptors()
{
throw new NotImplementedException("Use getFieldWriteInfos");
}
public FieldInfo[] getFieldWriteInfos()
{
return fieldWriteInfos;
}
public TLongObjectHashMap getMethodInterceptors()
{
return methodInterceptors;
}
/**
* Constructs a new helper.
*/
public synchronized void attachClass(final Class clazz)
{
if (initialized) return;
try
{
//long start = System.currentTimeMillis();
final ClassAdvisor THIS = this;
final AspectManager theManager = manager;
//register class loader: necessary when clazz was precompiled through aopc
manager.registerClassLoader(clazz.getClassLoader());
AccessController.doPrivileged(new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
theManager.attachMetaData(THIS, clazz);
interfaceIntroductions.clear();
// metadata should always come before creation of interceptor chain
// so that the interceptor factories have access to metadata.
// and so that metadata joinpoints can be checked
//
THIS.clazz = clazz;
// Also metadata needs to be applied before applyIntroductionPointcuts because
// an annotation may be triggered by XML metadata as well as
// after populateMixinMethods so that proper metadata is applied to added methods
rebindClassMetaData();
theManager.applyInterfaceIntroductions(THIS, clazz);
createFieldTable();
createMethodTables();
createConstructorTables();
populateMixinMethods();
// metadata should always come before creation of interceptor chain
// so that the interceptor factories have access to metadata.
// and so that metadata joinpoints can be checked
//
// Also metadata needs to be applied before applyIntroductionPointcuts because
// an annotation may be triggered by XML metadata as well as
// after populateMixinMethods so that proper metadata is applied to added methods
rebindClassMetaData();
createInterceptorChains();
initialized = true;
return null;
}
});
/*
System.out.println("******************");
System.out.println("attachClass: " + clazz.getName() + " took " + (System.currentTimeMillis() - start));
System.out.println("******************");
*/
}
catch (PrivilegedActionException e)
{
throw new RuntimeException(e.getException());
}
}
/**
* Get method from clazz .If method not found,get the method
* from the clazz's parent.
*/
static private Method getMethod(Class clazz, Method method) throws NoSuchMethodException
{
if ((clazz == null) || (clazz.equals(Object.class))) throw new NoSuchMethodException(method.getName());
try
{
String wrappedName = ClassAdvisor.notAdvisedMethodName(clazz.getName(), method.getName());
return clazz.getMethod(wrappedName, method.getParameterTypes());
}
catch (NoSuchMethodException e)
{
return getMethod(clazz.getSuperclass(), method);
}
}
/**
* Get a constructor's index in the class. Returns -1 if not there
*/
public int getConstructorIndex(Constructor constructor)
{
for (int i = 0; i < constructors.length; i++)
{
if (constructor.equals(constructors[i]))
{
return i;
}
}
return -1;
}
/**
* Get a field's index in the class. Returns -1 if not there
*/
public int getFieldIndex(Field field)
{
for (int i = 0; i < advisedFields.length; i++)
{
if (field.equals(advisedFields[i]))
{
return i;
}
}
return -1;
}
/**
* Put mixin methods from mixin class into unadvisedMethods map so that
* they can be correctly invoked upon.
*/
protected void populateMixinMethods() throws Exception
{
ArrayList pointcuts = getInterfaceIntroductions();
Iterator it = pointcuts.iterator();
while (it.hasNext())
{
InterfaceIntroduction pointcut = (InterfaceIntroduction) it.next();
ArrayList mixins = pointcut.getMixins();
for (int i = 0; i < mixins.size(); i++)
{
InterfaceIntroduction.Mixin mixin = (InterfaceIntroduction.Mixin) mixins.get(i);
Thread.currentThread().getContextClassLoader().loadClass(mixin.getClassName());
String[] interfaces = mixin.getInterfaces();
for (int j = 0; j < interfaces.length; j++)
{
Class intf = Thread.currentThread().getContextClassLoader().loadClass(interfaces[j]);
if (intf.isAssignableFrom(clazz))//This is a fix for JBAOP-365. Class may have been woven, with the extra mixin information only available at init time
{
Method[] methods = intf.getMethods();
for (int k = 0; k < methods.length; k++)
{
//Put wrapped method in the class itself into the unadvisedMethods map
// String wrappedName = ClassAdvisor.notAdvisedMethodName(clazz.getName(), methods[k].getName());
// Method method = clazz.getMethod(wrappedName, methods[k].getParameterTypes());
Method method = getMethod(clazz, methods[k]);
long hash = MethodHashing.methodHash(method);
unadvisedMethods.put(hash, method);
}
}
}
}
}
}
public synchronized void removeAdviceBinding(AdviceBinding binding)
{
removeCallerPointcut(binding); // if binding is a caller remove references to it
super.removeAdviceBinding(binding);
}
public synchronized void removeAdviceBindings(ArrayList bindings)
{
for (int i = 0; i < bindings.size(); i++)
{
AdviceBinding binding = (AdviceBinding) bindings.get(i);
removeCallerPointcut(binding);
}
adviceBindings.removeAll(bindings);
rebuildInterceptors();
doesHaveAspects = adviceBindings.size() > 0;
}
private void resolveFieldPointcut(ArrayList newFieldInfos, AdviceBinding binding, boolean write)
{
for (int i = 0; i < advisedFields.length; i++)
{
Field field = advisedFields[i];
if ((!write && binding.getPointcut().matchesGet(this, field))
|| (write && binding.getPointcut().matchesSet(this, field)))
{
if (AspectManager.verbose) System.err.println("[debug] field matched " + ((write) ? "write" : "read") + " binding: " + field);
adviceBindings.add(binding);
binding.addAdvisor(this);
FieldInfo info = (FieldInfo)newFieldInfos.get(i);
pointcutResolved(info, binding, new FieldJoinpoint(field));
}
}
}
protected MethodInterceptors initializeMethodChain()
{
MethodInterceptors newInterceptors = new MethodInterceptors(this);
long[] keys = advisedMethods.keys();
for (int i = 0; i < keys.length; i++)
{
MethodInfo info = new MethodInfo();
Method amethod = (Method) advisedMethods.get(keys[i]);
info.setAdvisedMethod(amethod);
Method umethod = (Method) unadvisedMethods.get(keys[i]);
if (umethod == null) umethod = amethod;
info.setUnadvisedMethod(umethod);
info.setHash(keys[i]);
info.setAdvisor(this);
newInterceptors.put(keys[i], info);
try
{
Field infoField = clazz.getDeclaredField(MethodExecutionTransformer.getMethodInfoFieldName(amethod.getName(), keys[i]));
infoField.setAccessible(true);
infoField.set(null, new WeakReference(info));
}
catch (NoSuchFieldException e)
{
// ignore, method may not be advised.
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e); //To change body of catch statement use Options | File Templates.
}
}
return newInterceptors;
}
protected ArrayList initializeFieldReadChain()
{
ArrayList chain = new ArrayList(advisedFields.length);
for (int i = 0; i < advisedFields.length; i++)
{
FieldInfo info = new FieldInfo();
info.setAdvisedField(advisedFields[i]);
info.setAdvisor(this);
info.setIndex(i);
try
{
info.setWrapper(clazz.getDeclaredMethod(
FieldAccessTransformer.fieldRead(advisedFields[i].getName()),
new Class[] {Object.class}));
}
catch (NoSuchMethodException e)
{
//Just means not advised
}
chain.add(info);
try
{
Field infoField = clazz.getDeclaredField(FieldAccessTransformer.getFieldReadInfoFieldName(advisedFields[i].getName()));
infoField.setAccessible(true);
infoField.set(null, new WeakReference(info));
}
catch (NoSuchFieldException e)
{
// ignore, method may not be advised.
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
return chain;
}
protected ArrayList initializeFieldWriteChain()
{
ArrayList chain = new ArrayList(advisedFields.length);
for (int i = 0; i < advisedFields.length; i++)
{
FieldInfo info = new FieldInfo();
info.setAdvisedField(advisedFields[i]);
info.setAdvisor(this);
info.setIndex(i);
try
{
info.setWrapper(clazz.getDeclaredMethod(
FieldAccessTransformer.fieldWrite(advisedFields[i].getName()),
new Class[] {Object.class, advisedFields[i].getType()}));
}
catch (NoSuchMethodException e)
{
//Just means not advised
}
chain.add(info);
try
{
Field infoField = clazz.getDeclaredField(FieldAccessTransformer.getFieldWriteInfoFieldName(advisedFields[i].getName()));
infoField.setAccessible(true);
infoField.set(null, new WeakReference(info));
}
catch (NoSuchFieldException e)
{
// ignore, method may not be advised.
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
return chain;
}
protected void finalizeFieldReadChain(ArrayList newFieldInfos)
{
for (int i = 0; i < newFieldInfos.size(); i++)
{
FieldInfo info = (FieldInfo)newFieldInfos.get(i);
ArrayList list = info.getInterceptorChain();
Interceptor[] interceptors = null;
if (list.size() > 0)
{
interceptors = applyPrecedence((Interceptor[]) list.toArray(new Interceptor[list.size()]));
}
info.setInterceptors(interceptors);
}
}
protected void finalizeFieldWriteChain(ArrayList newFieldInfos)
{
for (int i = 0; i < newFieldInfos.size(); i++)
{
FieldInfo info = (FieldInfo)newFieldInfos.get(i);
ArrayList list = info.getInterceptorChain();
Interceptor[] interceptors = null;
if (list.size() > 0)
{
interceptors = applyPrecedence((Interceptor[]) list.toArray(new Interceptor[list.size()]));
}
info.setInterceptors(interceptors);
}
}
private void createInterceptorChains() throws Exception
{
if (AspectManager.verbose) System.out.println("[debug] Creating chains for " + clazz + " " + ((clazz != null) ? clazz.getClassLoader() : null ));
MethodInterceptors newMethodInfos = initializeMethodChain();
ArrayList newFieldReadInfos = initializeFieldReadChain();
ArrayList newFieldWriteInfos = initializeFieldWriteChain();
ArrayList newConstructorInfos = initializeConstructorChain();
ArrayList newConstructionInfos = initializeConstructionChain();
synchronized (manager.getBindings())
{
Iterator it = manager.getBindings().values().iterator();
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
if (AspectManager.verbose) System.out.println("[debug] iterate binding " + binding.getName() + " " + binding.getPointcut().getExpr());
resolveMethodPointcut(newMethodInfos, binding);
resolveFieldPointcut(newFieldReadInfos, binding, false);
resolveFieldPointcut(newFieldWriteInfos, binding, true);
resolveConstructorPointcut(newConstructorInfos, binding);
resolveConstructionPointcut(newConstructionInfos, binding);
}
}
finalizeMethodChain(newMethodInfos);
finalizeFieldReadChain(newFieldReadInfos);
finalizeFieldWriteChain(newFieldWriteInfos);
finalizeConstructorChain(newConstructorInfos);
finalizeConstructionChain(newConstructionInfos);
fieldReadInfos = (FieldInfo[]) newFieldReadInfos.toArray(new FieldInfo[newFieldReadInfos.size()]);
fieldWriteInfos = (FieldInfo[]) newFieldWriteInfos.toArray(new FieldInfo[newFieldWriteInfos.size()]);
constructorInfos = (ConstructorInfo[]) newConstructorInfos.toArray(new ConstructorInfo[newConstructorInfos.size()]);
constructionInfos = (ConstructionInfo[]) newConstructionInfos.toArray(new ConstructionInfo[newConstructionInfos.size()]);
populateInterceptorsFromInfos();
doesHaveAspects = adviceBindings.size() > 0;
// Notify observer about this change
if (this.interceptorChainObserver != null)
{
this.interceptorChainObserver.interceptorChainsUpdated(fieldReadInterceptors, fieldWriteInterceptors,
constructorInterceptors, methodInterceptors);
}
}
private MethodByMethodInfo initializeCallerInterceptorsMap(long callingMethodHash, String calledClass, long calledMethodHash, Method callingMethod, Method calledMethod) throws Exception
{
HashMap calledClassesMap = (HashMap) methodCalledByMethodInterceptors.get(callingMethodHash);
if (calledClassesMap == null)
{
calledClassesMap = new HashMap();
methodCalledByMethodInterceptors.put(callingMethodHash, calledClassesMap);
}
TLongObjectHashMap calledMethodsMap = (TLongObjectHashMap) calledClassesMap.get(calledClass);
if (calledMethodsMap == null)
{
calledMethodsMap = new TLongObjectHashMap();
calledClassesMap.put(calledClass, calledMethodsMap);
}
//The standard MethodCalledByXXXXInvocation class calls by reflection and needs access
calledMethod.setAccessible(true);
Class calledClazz = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
MethodByMethodInfo info = new MethodByMethodInfo(this, calledClazz, calledMethod, callingMethodHash, calledMethodHash, null);
calledMethodsMap.put(calledMethodHash, info);
return info;
}
private ConByMethodInfo initializeConCalledByMethodInterceptorsMap(long callingMethodHash, String calledClass, long calledConHash, Constructor calledCon) throws Exception
{
HashMap calledClassesMap = (HashMap) conCalledByMethodInterceptors.get(callingMethodHash);
if (calledClassesMap == null)
{
calledClassesMap = new HashMap();
conCalledByMethodInterceptors.put(callingMethodHash, calledClassesMap);
}
TLongObjectHashMap calledMethodsMap = (TLongObjectHashMap) calledClassesMap.get(calledClass);
if (calledMethodsMap == null)
{
calledMethodsMap = new TLongObjectHashMap();
calledClassesMap.put(calledClass, calledMethodsMap);
}
ConByMethodInfo info = createConByMethodInfo(calledClass, callingMethodHash, calledCon, calledConHash);
calledMethodsMap.put(calledConHash, info);
return info;
}
private ConByMethodInfo createConByMethodInfo(String calledClass, long callingMethodHash, Constructor calledCon, long calledConHash) throws Exception
{
//The standard ConstructorCalledByXXXXInvocation class calls by reflection and needs access
calledCon.setAccessible(true);
Class calledClazz = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
try
{
int index = calledClass.lastIndexOf('.');
String baseClassName = calledClass.substring(index + 1);
Method wrapper = calledCon.getDeclaringClass().getDeclaredMethod(ConstructorExecutionTransformer.constructorFactory(baseClassName), calledCon.getParameterTypes());
return new ConByMethodInfo(this, calledClazz, callingMethodHash, calledCon, calledConHash, wrapper, null);
}
catch (NoSuchMethodException e)
{
return new ConByMethodInfo(this, calledClazz, callingMethodHash, calledCon, calledConHash, null, null);
}
}
private MethodByConInfo initializeConstructorCallerInterceptorsMap(int callingIndex, String calledClass, long calledMethodHash, Method calledMethod) throws Exception
{
HashMap calledClassesMap = methodCalledByConInterceptors[callingIndex];
if (calledClassesMap == null)
{
calledClassesMap = new HashMap();
methodCalledByConInterceptors[callingIndex] = calledClassesMap;
}
TLongObjectHashMap calledMethodsMap = (TLongObjectHashMap) calledClassesMap.get(calledClass);
if (calledMethodsMap == null)
{
calledMethodsMap = new TLongObjectHashMap();
calledClassesMap.put(calledClass, calledMethodsMap);
}
//The standard MethodCalledByXXXXInvocation class calls by reflection and needs access
calledMethod.setAccessible(true);
Class calledClazz = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
MethodByConInfo info = new MethodByConInfo(this, calledClazz, callingIndex, calledMethod, calledMethodHash, null);
calledMethodsMap.put(calledMethodHash, info);
return info;
}
private ConByConInfo initializeConCalledByConInterceptorsMap(int callingIndex, String calledClass, long calledConHash, Constructor calledCon) throws Exception
{
HashMap calledClassesMap = conCalledByConInterceptors[callingIndex];
if (calledClassesMap == null)
{
calledClassesMap = new HashMap();
conCalledByConInterceptors[callingIndex] = calledClassesMap;
}
TLongObjectHashMap calledMethodsMap = (TLongObjectHashMap) calledClassesMap.get(calledClass);
if (calledMethodsMap == null)
{
calledMethodsMap = new TLongObjectHashMap();
calledClassesMap.put(calledClass, calledMethodsMap);
}
ConByConInfo info = createConByConInfo(callingIndex, calledClass, calledCon, calledConHash);
calledMethodsMap.put(calledConHash, info);
return info;
}
private ConByConInfo createConByConInfo(int callingIndex, String calledClass, Constructor calledCon, long calledConHash) throws Exception
{
//The standard ConstructorCalledByXXXXInvocation class calls by reflection and needs access
calledCon.setAccessible(true);
Class calledClazz = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
try
{
int index = calledClass.lastIndexOf('.');
String baseClassName = calledClass.substring(index + 1);
Method wrapper = calledCon.getDeclaringClass().getDeclaredMethod(ConstructorExecutionTransformer.constructorFactory(baseClassName), calledCon.getParameterTypes());
return new ConByConInfo(this, calledClazz, callingIndex, calledCon, calledConHash, wrapper, null);
}
catch (NoSuchMethodException e)
{
return new ConByConInfo(this, calledClazz, callingIndex, calledCon, calledConHash, null, null);
}
}
protected void rebuildCallerInterceptors() throws Exception
{
long[] callingKeys = methodCalledByMethodInterceptors.keys();
for (int i = 0; i < callingKeys.length; i++)
{
long callingHash = callingKeys[i];
HashMap calledClasses = (HashMap) methodCalledByMethodInterceptors.get(callingHash);
Iterator classesIterator = calledClasses.entrySet().iterator();
while (classesIterator.hasNext())
{
Map.Entry entry = (Map.Entry) classesIterator.next();
String cname = (String) entry.getKey();
TLongObjectHashMap calledMethods = (TLongObjectHashMap) entry.getValue();
long[] calledKeys = calledMethods.keys();
for (int j = 0; j < calledKeys.length; j++)
{
long calledHash = calledKeys[j];
ArrayList bindings = getCallerBindings(callingHash, cname, calledHash);
Method calling = MethodHashing.findMethodByHash(clazz, callingHash);
bindCallerInterceptorChain(bindings, callingHash, cname, calledHash, calling);
}
}
}
for (int i = 0; i < methodCalledByConInterceptors.length; i++)
{
HashMap calledClasses = methodCalledByConInterceptors[i];
if (calledClasses == null) continue;
Iterator classesIterator = calledClasses.entrySet().iterator();
while (classesIterator.hasNext())
{
Map.Entry entry = (Map.Entry) classesIterator.next();
String cname = (String) entry.getKey();
TLongObjectHashMap calledMethods = (TLongObjectHashMap) entry.getValue();
long[] calledKeys = calledMethods.keys();
for (int j = 0; j < calledKeys.length; j++)
{
long calledHash = calledKeys[j];
ArrayList bindings = getConstructorCallerBindings(i, cname, calledHash);
bindConstructorCallerInterceptorChain(bindings, i, cname, calledHash);
}
}
}
callingKeys = conCalledByMethodInterceptors.keys();
for (int i = 0; i < callingKeys.length; i++)
{
long callingHash = callingKeys[i];
HashMap calledClasses = (HashMap) conCalledByMethodInterceptors.get(callingHash);
Iterator classesIterator = calledClasses.entrySet().iterator();
while (classesIterator.hasNext())
{
Map.Entry entry = (Map.Entry) classesIterator.next();
String cname = (String) entry.getKey();
TLongObjectHashMap calledMethods = (TLongObjectHashMap) entry.getValue();
long[] calledKeys = calledMethods.keys();
for (int j = 0; j < calledKeys.length; j++)
{
long calledHash = calledKeys[j];
ArrayList bindings = getConCalledByMethodBindings(callingHash, cname, calledHash);
bindConCalledByMethodInterceptorChain(bindings, callingHash, cname, calledHash);
}
}
}
for (int i = 0; i < conCalledByConInterceptors.length; i++)
{
HashMap calledClasses = conCalledByConInterceptors[i];
if (calledClasses == null) continue;
Iterator classesIterator = calledClasses.entrySet().iterator();
while (classesIterator.hasNext())
{
Map.Entry entry = (Map.Entry) classesIterator.next();
String cname = (String) entry.getKey();
TLongObjectHashMap calledMethods = (TLongObjectHashMap) entry.getValue();
long[] calledKeys = calledMethods.keys();
for (int j = 0; j < calledKeys.length; j++)
{
long calledHash = calledKeys[j];
ArrayList bindings = getConCalledByConBindings(i, cname, calledHash);
bindConCalledByConInterceptorChain(bindings, i, cname, calledHash);
}
}
}
}
private ArrayList getCallerBindings(long callingHash, String cname, long calledHash)
{
HashMap calledClasses = (HashMap) methodCalledByMethodBindings.get(callingHash);
TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(cname);
return (ArrayList) calledMethods.get(calledHash);
}
private ArrayList getConCalledByMethodBindings(long callingHash, String cname, long calledHash)
{
HashMap calledClasses = (HashMap) conCalledByMethodBindings.get(callingHash);
TLongObjectHashMap calledCons = (TLongObjectHashMap) calledClasses.get(cname);
return (ArrayList) calledCons.get(calledHash);
}
private ArrayList getConstructorCallerBindings(int callingIndex, String cname, long calledHash)
{
HashMap calledClasses = methodCalledByConBindings[callingIndex];
TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(cname);
return (ArrayList) calledMethods.get(calledHash);
}
private ArrayList getConCalledByConBindings(int callingIndex, String cname, long calledHash)
{
HashMap calledClasses = conCalledByConBindings[callingIndex];
TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(cname);
return (ArrayList) calledMethods.get(calledHash);
}
private void bindCallerInterceptorChain(ArrayList bindings, long callingHash, String cname, long calledHash, Method calling)
{
MethodByMethodInfo info = getCallerMethodInfo(callingHash, cname, calledHash);
info.clear();
Iterator it = bindings.iterator();
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
pointcutResolved(info, binding, new MethodCalledByMethodJoinpoint(info.getCallingMethod(), info.getMethod()));
}
finalizeMethodCalledByMethodInterceptorChain(info);
}
protected void finalizeMethodCalledByMethodInterceptorChain(MethodByMethodInfo info)
{
ArrayList list = info.getInterceptorChain();
Interceptor[] interceptors = null;
if (list.size() > 0)
{
interceptors = (Interceptor[]) list.toArray(new Interceptor[list.size()]);
}
info.setInterceptors(interceptors);
}
private void bindConCalledByMethodInterceptorChain(ArrayList bindings, long callingHash, String cname, long calledHash) throws Exception
{
ConByMethodInfo info = getConCalledByMethod(callingHash, cname, calledHash);
info.clear();
Iterator it = bindings.iterator();
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
pointcutResolved(info, binding, new ConstructorCalledByMethodJoinpoint(info.getCallingMethod(), info.getConstructor()));
}
finalizeConCalledByMethodInterceptorChain(info);
}
protected void finalizeConCalledByMethodInterceptorChain(ConByMethodInfo info)
{
ArrayList list = info.getInterceptorChain();
Interceptor[] interceptors = null;
if (list.size() > 0)
{
interceptors = (Interceptor[]) list.toArray(new Interceptor[list.size()]);
}
info.setInterceptors(interceptors);
}
private void bindConCalledByConInterceptorChain(ArrayList bindings, int callingIndex, String cname, long calledHash)
{
ConByConInfo info = getConCalledByCon(callingIndex, cname, calledHash);
info.clear();
Iterator it = bindings.iterator();
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
pointcutResolved(info, binding, new ConstructorCalledByConstructorJoinpoint(info.getCalling(), info.getConstructor()));
}
finalizeConCalledByConInterceptorChain(info);
}
protected void finalizeConCalledByConInterceptorChain(ConByConInfo info)
{
ArrayList list = info.getInterceptorChain();
Interceptor[] interceptors = null;
if (list.size() > 0)
{
interceptors = (Interceptor[]) list.toArray(new Interceptor[list.size()]);
}
info.setInterceptors(interceptors);
}
private void bindConstructorCallerInterceptorChain(ArrayList bindings, int callingIndex, String cname, long calledHash)
{
MethodByConInfo info = getConstructorCallerMethodInfo(callingIndex, cname, calledHash);
info.clear();
Iterator it = bindings.iterator();
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
pointcutResolved(info, binding, new MethodCalledByConstructorJoinpoint(info.getCalling(), info.getMethod()));
}
finalizeMethodCalledByConInterceptorChain(info);
}
protected void finalizeMethodCalledByConInterceptorChain(MethodByConInfo info)
{
ArrayList list = info.getInterceptorChain();
Interceptor[] interceptors = null;
if (list.size() > 0)
{
interceptors = (Interceptor[]) list.toArray(new Interceptor[list.size()]);
}
info.setInterceptors(interceptors);
}
protected void rebuildInterceptors()
{
if (initialized)
{
if (System.getSecurityManager() == null)
{
RebuildInterceptorsAction.NON_PRIVILEGED.rebuildInterceptors(this);
}
else
{
RebuildInterceptorsAction.PRIVILEGED.rebuildInterceptors(this);
}
}
}
protected void doRebuildInterceptors()
{
try
{
adviceBindings.clear();
createInterceptorChains();
rebuildCallerInterceptors();
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
}
protected void bindClassMetaData(ClassMetaDataBinding data)
{
try
{
ClassMetaDataLoader loader = data.getLoader();
Object[] objs = advisedMethods.getValues();
Method[] methods = new Method[objs.length];
Field[] fields = advisedFields;
// set to empty array because advisedFields may not have been initialized yet
if (fields == null) fields = new Field[0];
Constructor[] cons = constructors;
// set to empty array because constructors may not have been initialized yet
if (cons == null) cons = new Constructor[0];
for (int i = 0; i < objs.length; i++) methods[i] = (Method) objs[i];
loader.bind(this, data, methods, fields, cons);
}
catch (Exception ex)
{
// REVISIT: Need to know how errors affects deployment
ex.printStackTrace();
}
}
protected void rebindClassMetaData()
{
defaultMetaData.clear();
methodMetaData.clear();
fieldMetaData.clear();
constructorMetaData.clear();
classMetaData.clear();
for (int i = 0; i < classMetaDataBindings.size(); i++)
{
ClassMetaDataBinding data = (ClassMetaDataBinding) classMetaDataBindings.get(i);
bindClassMetaData(data);
}
deployAnnotationOverrides();
}
public synchronized void addClassMetaData(ClassMetaDataBinding data)
{
classMetaDataBindings.add(data);
if (this.clazz == null) return; // don't bind till later.
bindClassMetaData(data);
// Recalculate interceptorPointcuts because of MetaDataInterceptorPointcuts
adviceBindings.clear();
doesHaveAspects = false;
rebuildInterceptors();
}
public synchronized void removeClassMetaData(ClassMetaDataBinding data)
{
if (classMetaDataBindings.remove(data))
{
if (this.clazz == null) return; // not bound yet
rebindClassMetaData();
// Recalculate interceptorPointcuts because of MetaDataInterceptorPointcuts
adviceBindings.clear();
doesHaveAspects = false;
rebuildInterceptors();
}
}
private void initializeEmptyCallerChain(long callingMethodHash, String calledClass, long calledMethodHash) throws Exception
{
HashMap callingMethod = (HashMap) methodCalledByMethodBindings.get(callingMethodHash);
if (callingMethod == null)
{
callingMethod = new HashMap();
methodCalledByMethodBindings.put(callingMethodHash, callingMethod);
}
TLongObjectHashMap classMap = (TLongObjectHashMap) callingMethod.get(calledClass);
if (classMap == null)
{
classMap = new TLongObjectHashMap();
callingMethod.put(calledClass, classMap);
}
ArrayList bindings = (ArrayList) classMap.get(calledMethodHash);
if (bindings == null)
{
bindings = new ArrayList();
classMap.put(calledMethodHash, bindings);
}
}
private void initializeConCalledByMethodEmptyChain(long callingMethodHash, String calledClass, long calledConHash) throws Exception
{
HashMap callingMethod = (HashMap) conCalledByMethodBindings.get(callingMethodHash);
if (callingMethod == null)
{
callingMethod = new HashMap();
conCalledByMethodBindings.put(callingMethodHash, callingMethod);
}
TLongObjectHashMap classMap = (TLongObjectHashMap) callingMethod.get(calledClass);
if (classMap == null)
{
classMap = new TLongObjectHashMap();
callingMethod.put(calledClass, classMap);
}
ArrayList bindings = (ArrayList) classMap.get(calledConHash);
if (bindings == null)
{
bindings = new ArrayList();
classMap.put(calledConHash, bindings);
}
}
private void initializeEmptyConstructorCallerChain(int callingIndex, String calledClass, long calledMethodHash) throws Exception
{
HashMap callingCon = methodCalledByConBindings[callingIndex];
if (callingCon == null)
{
callingCon = new HashMap();
methodCalledByConBindings[callingIndex] = callingCon;
}
TLongObjectHashMap classMap = (TLongObjectHashMap) callingCon.get(calledClass);
if (classMap == null)
{
classMap = new TLongObjectHashMap();
callingCon.put(calledClass, classMap);
}
ArrayList bindings = (ArrayList) classMap.get(calledMethodHash);
if (bindings == null)
{
bindings = new ArrayList();
classMap.put(calledMethodHash, bindings);
}
}
private void initializeConCalledByConEmptyChain(int callingIndex, String calledClass, long calledConHash) throws Exception
{
HashMap callingCon = conCalledByConBindings[callingIndex];
if (callingCon == null)
{
callingCon = new HashMap();
conCalledByConBindings[callingIndex] = callingCon;
}
TLongObjectHashMap classMap = (TLongObjectHashMap) callingCon.get(calledClass);
if (classMap == null)
{
classMap = new TLongObjectHashMap();
callingCon.put(calledClass, classMap);
}
ArrayList bindings = (ArrayList) classMap.get(calledConHash);
if (bindings == null)
{
bindings = new ArrayList();
classMap.put(calledConHash, bindings);
}
}
private void addMethodCalledByMethodPointcut(long callingMethodHash, String calledClass, long calledMethodHash, AdviceBinding binding) throws Exception
{
if (AspectManager.verbose) System.err.println("method call matched binding " + binding.getPointcut().getExpr());
adviceBindings.add(binding);
binding.addAdvisor(this);
HashMap callingMethod = (HashMap) methodCalledByMethodBindings.get(callingMethodHash);
if (callingMethod == null)
{
callingMethod = new HashMap();
methodCalledByMethodBindings.put(callingMethodHash, callingMethod);
}
TLongObjectHashMap classMap = (TLongObjectHashMap) callingMethod.get(calledClass);
if (classMap == null)
{
classMap = new TLongObjectHashMap();
callingMethod.put(calledClass, classMap);
}
ArrayList bindings = (ArrayList) classMap.get(calledMethodHash);
boolean createdBindings = false;
if (bindings == null)
{
bindings = new ArrayList();
classMap.put(calledMethodHash, bindings);
createdBindings = true;
}
if (!bindings.contains(binding)) bindings.add(binding);
// this is so that we can undeploy a caller
ArrayList backrefs = (ArrayList) backrefMethodCalledByMethodBindings.get(binding.getName());
if (backrefs == null)
{
backrefs = new ArrayList();
backrefMethodCalledByMethodBindings.put(binding.getName(), backrefs);
backrefs.add(bindings);
}
else if (createdBindings) backrefs.add(bindings);
}
private void addConstructorCalledByMethodPointcut(long callingMethodHash, String calledClass, long calledMethodHash, AdviceBinding binding) throws Exception
{
if (AspectManager.verbose) System.err.println("method call matched binding " + binding.getPointcut().getExpr());
adviceBindings.add(binding);
binding.addAdvisor(this);
HashMap callingMethod = (HashMap) conCalledByMethodBindings.get(callingMethodHash);
if (callingMethod == null)
{
callingMethod = new HashMap();
conCalledByMethodBindings.put(callingMethodHash, callingMethod);
}
TLongObjectHashMap classMap = (TLongObjectHashMap) callingMethod.get(calledClass);
if (classMap == null)
{
classMap = new TLongObjectHashMap();
callingMethod.put(calledClass, classMap);
}
ArrayList bindings = (ArrayList) classMap.get(calledMethodHash);
boolean createdBindings = false;
if (bindings == null)
{
bindings = new ArrayList();
classMap.put(calledMethodHash, bindings);
createdBindings = true;
}
if (!bindings.contains(binding)) bindings.add(binding);
// this is so that we can undeploy a caller
ArrayList backrefs = (ArrayList) backrefConCalledByMethodBindings.get(binding.getName());
if (backrefs == null)
{
backrefs = new ArrayList();
backrefConCalledByMethodBindings.put(binding.getName(), backrefs);
backrefs.add(bindings);
}
else if (createdBindings) backrefs.add(bindings);
}
public void addConstructorCallerPointcut(int callingIndex, String calledClass, long calledMethodHash, AdviceBinding binding) throws Exception
{
if (AspectManager.verbose) System.err.println("constructor call matched binding " + binding.getPointcut().getExpr());
adviceBindings.add(binding);
binding.addAdvisor(this);
HashMap callingCon = methodCalledByConBindings[callingIndex];
if (callingCon == null)
{
callingCon = new HashMap();
methodCalledByConBindings[callingIndex] = callingCon;
}
TLongObjectHashMap classMap = (TLongObjectHashMap) callingCon.get(calledClass);
if (classMap == null)
{
classMap = new TLongObjectHashMap();
callingCon.put(calledClass, classMap);
}
ArrayList bindings = (ArrayList) classMap.get(calledMethodHash);
boolean createdBindings = false;
if (bindings == null)
{
bindings = new ArrayList();
classMap.put(calledMethodHash, bindings);
createdBindings = true;
}
if (!bindings.contains(binding)) bindings.add(binding);
// this is so that we can undeploy a caller
ArrayList backrefs = (ArrayList) backrefMethodCalledByConstructorBindings.get(binding.getName());
if (backrefs == null)
{
backrefs = new ArrayList();
backrefMethodCalledByConstructorBindings.put(binding.getName(), backrefs);
backrefs.add(bindings);
}
else if (createdBindings) backrefs.add(bindings);
}
private void addConstructorCalledByConPointcut(int callingIndex, String calledClass, long calledConHash, AdviceBinding binding) throws Exception
{
if (AspectManager.verbose) System.err.println("constructor call matched binding " + binding.getPointcut().getExpr());
adviceBindings.add(binding);
binding.addAdvisor(this);
HashMap callingCon = conCalledByConBindings[callingIndex];
if (callingCon == null)
{
callingCon = new HashMap();
conCalledByConBindings[callingIndex] = callingCon;
}
TLongObjectHashMap classMap = (TLongObjectHashMap) callingCon.get(calledClass);
if (classMap == null)
{
classMap = new TLongObjectHashMap();
callingCon.put(calledClass, classMap);
}
ArrayList bindings = (ArrayList) classMap.get(calledConHash);
boolean createdBindings = false;
if (bindings == null)
{
bindings = new ArrayList();
classMap.put(calledConHash, bindings);
createdBindings = true;
}
if (!bindings.contains(binding)) bindings.add(binding);
// this is so that we can undeploy a caller
ArrayList backrefs = (ArrayList) backrefConCalledByConstructorBindings.get(binding.getName());
if (backrefs == null)
{
backrefs = new ArrayList();
backrefConCalledByConstructorBindings.put(binding.getName(), backrefs);
backrefs.add(bindings);
}
else if (createdBindings) backrefs.add(bindings);
}
private void removeCallerPointcut(AdviceBinding binding)
{
ArrayList backrefs = (ArrayList) backrefMethodCalledByMethodBindings.get(binding.getName());
if (backrefs == null) return;
for (int i = 0; i < backrefs.size(); i++)
{
ArrayList ref = (ArrayList) backrefs.get(i);
ref.remove(binding);
}
}
/**
* Generates internal, unadvised version of a method name.
*/
public static String notAdvisedMethodName(String className,
String methodName)
{
return className.replace('.', '$') + "$" + methodName +
NOT_TRANSFORMABLE_SUFFIX;
}
/**
* Is this the name of a private, unadvised thing?
*/
public static boolean isWithoutAdvisement(String name)
{
return name.endsWith(NOT_TRANSFORMABLE_SUFFIX);
}
/**
* Is the method advisable?
*/
public static boolean isAdvisable(Method method)
{
// note: this should match the implementation in the instrumentor.
int modifiers = method.getModifiers();
return (
!isWithoutAdvisement(method.getName()) &&
!Modifier.isAbstract(modifiers) &&
!Modifier.isNative(modifiers) &&
!(method.getName().equals("_getAdvisor") &&
method.getParameterTypes().length == 0 &&
method.getReturnType().equals(Advisor.class)) &&
!(method.getName().equals("_getClassAdvisor") &&
method.getParameterTypes().length == 0 &&
method.getReturnType().equals(Advisor.class)) &&
!(method.getName().equals("_getInstanceAdvisor") &&
method.getParameterTypes().length == 0 &&
method.getReturnType().equals(InstanceAdvisor.class)) &&
!(method.getName().equals("_setInstanceAdvisor") &&
method.getParameterTypes().length == 1 &&
method.getParameterTypes()[0].equals(InstanceAdvisor.class)));
}
private void populateFieldTable(ArrayList fields, Class superclass)
throws Exception
{
if (superclass == null) return;
if (superclass.equals(Object.class)) return;
populateFieldTable(fields, superclass.getSuperclass());
// if (!isAdvised(superclass)) return;
ArrayList temp = new ArrayList();
Field[] declaredFields = superclass.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++)
{
if (Advisable.isAdvisable(declaredFields[i]))
{
// Need to do this because notadvisable fields maybe private or protected
declaredFields[i].setAccessible(true);
temp.add(declaredFields[i]);
}
}
Collections.sort(temp, FieldComparator.INSTANCE);
fields.addAll(temp);
}
/**
* Gets advised methods.
*/
private void createFieldTable() throws Exception
{
ArrayList fields = new ArrayList();
populateFieldTable(fields, clazz);
advisedFields = (Field[]) fields.toArray(new Field[fields.size()]);
}
protected void addDeclaredMethods(Class superclass) throws Exception
{
Method[] declaredMethods = superclass.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++)
{
if (ClassAdvisor.isAdvisable(declaredMethods[i]))
{
long hash = MethodHashing.methodHash(declaredMethods[i]);
advisedMethods.put(hash, declaredMethods[i]);
try
{
Method m = declaredMethods[i];
Method un = superclass.getDeclaredMethod(ClassAdvisor.notAdvisedMethodName(superclass.getName(),
m.getName()),
m.getParameterTypes());
un.setAccessible(true);
unadvisedMethods.put(hash, un);
}
catch (NoSuchMethodException ignored)
{
}
}
}
}
/**
* Create a HashMap of method hash and Method
* Superclasses get added first so subclasses will override with
* correct overriden method
*/
private void populateMethodTables(Class superclass)
throws Exception
{
if (superclass == null) return;
if (superclass.equals(Object.class)) return;
populateMethodTables(superclass.getSuperclass());
//The advisor for the superclass may be a container
Advisor superAdvisor = manager.getAnyAdvisorIfAdvised(superclass);
if (superAdvisor != null && superAdvisor instanceof ClassAdvisor)
{
TLongObjectHashMap superHash = ((ClassAdvisor)superAdvisor).getUnadvisedMethods();
long[] keys = superHash.keys();
for (int i = 0; i < keys.length; i++)
{
unadvisedMethods.put(keys[i], superHash.get(keys[i]));
}
}
addDeclaredMethods(superclass);
}
private void createMethodTables()
throws Exception
{
populateMethodTables(clazz.getSuperclass());
addDeclaredMethods(clazz);
}
private void createConstructorTables() throws Exception
{
constructors = clazz.getDeclaredConstructors();
methodCalledByConBindings = new HashMap[constructors.length];
methodCalledByConInterceptors = new HashMap[constructors.length];
conCalledByConBindings = new HashMap[constructors.length];
conCalledByConInterceptors = new HashMap[constructors.length];
for (int i = 0; i < constructors.length; i++)
{
constructors[i].setAccessible(true);
}
Arrays.sort(constructors, ConstructorComparator.INSTANCE);
}
public MethodByMethodInfo resolveCallerMethodInfo(long callingMethodHash, String calledClass, long calledMethodHash)
{
if (System.getSecurityManager() == null)
{
return ResolveCallerMethodInfoAction.NON_PRIVILEGED.resolveInfo(this, callingMethodHash, calledClass, calledMethodHash);
}
else
{
return ResolveCallerMethodInfoAction.PRIVILEGED.resolveInfo(this, callingMethodHash, calledClass, calledMethodHash);
}
}
private MethodByMethodInfo doResolveCallerMethodInfo(long callingMethodHash, String calledClass, long calledMethodHash)
{
try
{
Method callingMethod = MethodHashing.findMethodByHash(clazz, callingMethodHash);
if (callingMethod == null) throw new RuntimeException("Unable to figure out calling method of a caller pointcut");
Class called = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
Method calledMethod = MethodHashing.findMethodByHash(called, calledMethodHash);
if (calledMethod == null) throw new RuntimeException("Unable to figure out calledmethod of a caller pointcut");
Iterator it = manager.getBindings().values().iterator();
boolean matched = false;
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
if (binding.getPointcut().matchesCall(this, callingMethod, called, calledMethod))
{
addMethodCalledByMethodPointcut(callingMethodHash, calledClass, calledMethodHash, binding);
matched = true;
}
}
if (!matched) initializeEmptyCallerChain(callingMethodHash, calledClass, calledMethodHash);
MethodByMethodInfo info = initializeCallerInterceptorsMap(callingMethodHash, calledClass, calledMethodHash, callingMethod, calledMethod);
ArrayList bindings = getCallerBindings(callingMethodHash, calledClass, calledMethodHash);
bindCallerInterceptorChain(bindings, callingMethodHash, calledClass, calledMethodHash, callingMethod);
return info;
}
catch (Exception x)
{
throw new RuntimeException(x);
}
}
public WeakReference resolveCallerMethodInfoAsWeakReference(long callingMethodHash, String calledClass, long calledMethodHash)
{
//Javassist doesn't like this in a field initialiser hence this method
return new WeakReference(resolveCallerMethodInfo(callingMethodHash, calledClass, calledMethodHash));
}
public ConByMethodInfo resolveCallerConstructorInfo(long callingMethodHash, String calledClass, long calledConHash)
{
if (System.getSecurityManager() == null)
{
return ResolveCallerConstuctorInfoAction.NON_PRIVILEGED.resolveInfo(this, callingMethodHash, calledClass, calledConHash);
}
else
{
return ResolveCallerConstuctorInfoAction.PRIVILEGED.resolveInfo(this, callingMethodHash, calledClass, calledConHash);
}
}
private ConByMethodInfo doResolveCallerConstructorInfo(long callingMethodHash, String calledClass, long calledConHash)
{
try
{
Method callingMethod = MethodHashing.findMethodByHash(clazz, callingMethodHash);
if (callingMethod == null) throw new RuntimeException("Unable to figure out calling method of a constructor caller pointcut");
Class called = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
Constructor calledCon = MethodHashing.findConstructorByHash(called, calledConHash);
if (calledCon == null) throw new RuntimeException("Unable to figure out calledcon of a constructor caller pointcut");
boolean matched = false;
synchronized (manager.getBindings())
{
Iterator it = manager.getBindings().values().iterator();
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
if (binding.getPointcut().matchesCall(this, callingMethod, called, calledCon))
{
addConstructorCalledByMethodPointcut(callingMethodHash, calledClass, calledConHash, binding);
matched = true;
}
}
}
if (!matched) initializeConCalledByMethodEmptyChain(callingMethodHash, calledClass, calledConHash);
ConByMethodInfo info = initializeConCalledByMethodInterceptorsMap(callingMethodHash, calledClass, calledConHash, calledCon);
ArrayList bindings = getConCalledByMethodBindings(callingMethodHash, calledClass, calledConHash);
bindConCalledByMethodInterceptorChain(bindings, callingMethodHash, calledClass, calledConHash);
return info;
}
catch (Exception x)
{
throw new RuntimeException(x);
}
}
public WeakReference resolveCallerConstructorInfoAsWeakReference(long callingMethodHash, String calledClass, long calledConHash)
{
//Javassist doesn't like this in a field initialiser hence this method
return new WeakReference(resolveCallerConstructorInfo(callingMethodHash, calledClass, calledConHash));
}
public MethodByConInfo resolveConstructorCallerMethodInfo(int callingIndex, String calledClass, long calledMethodHash)
{
if (System.getSecurityManager() == null)
{
return ResolveConstructorCallerMethodInfoAction.NON_PRIVILEGED.resolveInfo(this, callingIndex, calledClass, calledMethodHash);
}
else
{
return ResolveConstructorCallerMethodInfoAction.PRIVILEGED.resolveInfo(this, callingIndex, calledClass, calledMethodHash);
}
}
private MethodByConInfo doResolveConstructorCallerMethodInfo(int callingIndex, String calledClass, long calledMethodHash)
{
try
{
Constructor callingConstructor = constructors[callingIndex];
if (callingConstructor == null) throw new RuntimeException("Unable to figure out calling method of a caller pointcut");
Class called = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
Method calledMethod = MethodHashing.findMethodByHash(called, calledMethodHash);
if (calledMethod == null) throw new RuntimeException("Unable to figure out calledmethod of a caller pointcut");
boolean matched = false;
synchronized (manager.getBindings())
{
Iterator it = manager.getBindings().values().iterator();
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
if (binding.getPointcut().matchesCall(this, callingConstructor, called, calledMethod))
{
addConstructorCallerPointcut(callingIndex, calledClass, calledMethodHash, binding);
matched = true;
}
}
}
if (!matched) initializeEmptyConstructorCallerChain(callingIndex, calledClass, calledMethodHash);
MethodByConInfo info = initializeConstructorCallerInterceptorsMap(callingIndex, calledClass, calledMethodHash, calledMethod);
ArrayList bindings = getConstructorCallerBindings(callingIndex, calledClass, calledMethodHash);
bindConstructorCallerInterceptorChain(bindings, callingIndex, calledClass, calledMethodHash);
return info;
}
catch (Exception x)
{
throw new RuntimeException(x);
}
}
public WeakReference resolveConstructorCallerMethodInfoAsWeakReference(int callingIndex, String calledClass, long calledMethodHash)
{
//Javassist doesn't like this in a field initialiser hence this method
return new WeakReference(resolveConstructorCallerMethodInfo(callingIndex, calledClass, calledMethodHash));
}
public ConByConInfo resolveConstructorCallerConstructorInfo(int callingIndex, String calledClass, long calledConHash)
{
if (System.getSecurityManager() == null)
{
return ResolveConstructorCallerConstructorInfoAction.NON_PRIVILEGED.resolveInfo(this, callingIndex, calledClass, calledConHash);
}
else
{
return ResolveConstructorCallerConstructorInfoAction.PRIVILEGED.resolveInfo(this, callingIndex, calledClass, calledConHash);
}
}
private ConByConInfo doResolveConstructorCallerConstructorInfo(int callingIndex, String calledClass, long calledConHash)
{
try
{
Constructor callingConstructor = constructors[callingIndex];
if (callingConstructor == null) throw new RuntimeException("Unable to figure out calling method of a caller pointcut");
Class called = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
Constructor calledCon = MethodHashing.findConstructorByHash(called, calledConHash);
if (calledCon == null) throw new RuntimeException("Unable to figure out calledcon of a caller pointcut");
boolean matched = false;
synchronized (manager.getBindings())
{
Iterator it = manager.getBindings().values().iterator();
while (it.hasNext())
{
AdviceBinding binding = (AdviceBinding) it.next();
if (binding.getPointcut().matchesCall(this, callingConstructor, called, calledCon))
{
addConstructorCalledByConPointcut(callingIndex, calledClass, calledConHash, binding);
matched = true;
}
}
}
if (!matched) initializeConCalledByConEmptyChain(callingIndex, calledClass, calledConHash);
ConByConInfo info = initializeConCalledByConInterceptorsMap(callingIndex, calledClass, calledConHash, calledCon);
ArrayList bindings = getConCalledByConBindings(callingIndex, calledClass, calledConHash);
bindConCalledByConInterceptorChain(bindings, callingIndex, calledClass, calledConHash);
return info;
}
catch (Exception x)
{
throw new RuntimeException(x);
}
}
public WeakReference resolveConstructorCallerConstructorInfoAsWeakReference(int callingIndex, String calledClass, long calledConHash)
{
//Javassist doesn't like this in a field initialiser hence this method
return new WeakReference(resolveConstructorCallerConstructorInfo(callingIndex, calledClass, calledConHash));
}
/////////////////////////
// Invoking
/**
* Invokes target object without applying interceptors.
*/
public Object invokeWithoutAdvisement(Object target, long methodHash,
Object[] arguments) throws Throwable
{
try
{
Method method = (Method) unadvisedMethods.get(methodHash);
return method.invoke(target, arguments);
}
catch (InvocationTargetException e)
{
throw e.getTargetException();
}
}
public Object invokeNewWithoutAdvisement(Object[] arguments, Constructor constructor) throws Throwable
{
try
{
return constructor.newInstance(arguments);
}
catch (InstantiationException in)
{
throw new RuntimeException("failed to call constructor", in);
}
catch (IllegalAccessException ill)
{
throw new RuntimeException("illegal access", ill);
}
catch (InvocationTargetException ite)
{
throw ite.getCause();
}
}
public Object invokeMethod(long methodHash, Object[] arguments) throws Throwable
{
return invokeMethod(null, methodHash, arguments);
}
public Object invokeMethod(Object target, long methodHash, Object[] arguments) throws Throwable
{
InstanceAdvisor advisor = null;
if (target != null)
{
InstanceAdvised advised = (InstanceAdvised) target;
advisor = advised._getInstanceAdvisor();
}
MethodInfo info = (MethodInfo) methodInterceptors.get(methodHash);
return invokeMethod(advisor, target, methodHash, arguments, info);
}
public Object invokeMethod(InstanceAdvisor instanceAdvisor, Object target, long methodHash, Object[] arguments)
throws Throwable
{
MethodInfo info = (MethodInfo) methodInterceptors.get(methodHash);
if (info == null)
{
System.out.println("info is null for hash: " + methodHash + " of " + clazz.getName());
}
return invokeMethod(instanceAdvisor, target, methodHash, arguments, info);
}
public Object invokeMethod(InstanceAdvisor instanceAdvisor, Object target, long methodHash, Object[] arguments, MethodInfo info)
throws Throwable
{
Interceptor[] aspects = info.getInterceptors();
if (instanceAdvisor != null && (instanceAdvisor.hasInterceptors()))
{
aspects = instanceAdvisor.getInterceptors(aspects);
}
MethodInvocation invocation = new MethodInvocation(info, aspects);
invocation.setArguments(arguments);
invocation.setTargetObject(target);
return invocation.invokeNext();
}
/**
*@deprecated
*/
public Object invokeCaller(long callingMethodHash, Object target, Object[] args, CallerMethodInfo info, Object callingObject)
throws Throwable
{
return invokeCaller((MethodByMethodInfo)info, callingObject, target, args);
}
public Object invokeCaller(MethodByMethodInfo info, Object callingObject, Object target, Object[] args) throws Throwable
{
MethodCalledByMethodInvocation invocation = new MethodCalledByMethodInvocation(info, callingObject, target, args, info.getInterceptors());
invocation.setTargetObject(target);
return invocation.invokeNext();
}
/**
*@deprecated
*/
public Object invokeConCalledByMethod(long callingMethodHash, Object[] args, CallerConstructorInfo info, Object callingObject)
throws Throwable
{
return invokeConCalledByMethod((ConByMethodInfo)info, callingObject, args);
}
public Object invokeConCalledByMethod(ConByMethodInfo info, Object callingObject, Object[] args)
throws Throwable
{
ConstructorCalledByMethodInvocation invocation = new ConstructorCalledByMethodInvocation(info, callingObject, args, info.getInterceptors());
return invocation.invokeNext();
}
/**
*@deprecated
*/
public Object invokeConstructorCaller(int callingIndex, Object target, Object[] args, CallerMethodInfo info)
throws Throwable
{
return invokeConstructorCaller((MethodByConInfo)info, null, target, args);
}
/**
*@deprecated
*/
public Object invokeConstructorCaller(int callingIndex, Object callingObject, Object target, Object[] args, CallerMethodInfo info)
throws Throwable
{
return invokeConstructorCaller((MethodByConInfo)info, callingObject, target, args);
}
/**
* @deprecated
*
* Prefer using the version with <code>callingObject</code> instead of this one,
* since this object is available for call invocations made inside constructors.
*
* @see #invokeConstructorCaller(MethodByConInfo, Object, Object, Object[])
*/
public Object invokeConstructorCaller(MethodByConInfo info, Object target, Object[] args)
throws Throwable
{
return this.invokeConstructorCaller(info, null, target, args);
}
public Object invokeConstructorCaller(MethodByConInfo info, Object callingObject, Object target, Object[] args)
throws Throwable
{
MethodCalledByConstructorInvocation invocation = new MethodCalledByConstructorInvocation(info, callingObject, target, args, info.getInterceptors());
invocation.setTargetObject(target);
return invocation.invokeNext();
}
/**
*@deprecated
*/
public Object invokeConCalledByCon(int callingIndex, Object[] args, CallerConstructorInfo info)
throws Throwable
{
return invokeConCalledByCon((ConByConInfo)info, null, args);
}
/**
*@deprecated
*/
public Object invokeConCalledByCon(int callingIndex, Object callingObject, Object[] args, CallerConstructorInfo info)
throws Throwable
{
return invokeConCalledByCon((ConByConInfo)info, callingObject, args);
}
/**
* @deprecated
*
* Prefer using the version with <code>callingObject</code> instead of this one,
* since this object is available for call invocations made inside constructors.
*
* @see #invokeConCalledByCon(ConByConInfo, Object, Object[])
*/
public Object invokeConCalledByCon(ConByConInfo info, Object[] args)
throws Throwable
{
return invokeConCalledByCon(info, null, args);
}
public Object invokeConCalledByCon(ConByConInfo info, Object callingObject, Object[] args)
throws Throwable
{
ConstructorCalledByConstructorInvocation invocation = new ConstructorCalledByConstructorInvocation(info, callingObject, args, info.getInterceptors());
return invocation.invokeNext();
}
private MethodByMethodInfo getCallerMethodInfo(long callingMethodHash, String calledClass, long calledMethodHash)
{
HashMap calledClasses = (HashMap) methodCalledByMethodInterceptors.get(callingMethodHash);
TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(calledClass);
MethodByMethodInfo info = (MethodByMethodInfo) calledMethods.get(calledMethodHash);
return info;
}
private ConByMethodInfo getConCalledByMethod(long callingMethodHash, String calledClass, long calledConHash)
{
HashMap calledClasses = (HashMap) conCalledByMethodInterceptors.get(callingMethodHash);
TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(calledClass);
ConByMethodInfo info = (ConByMethodInfo) calledMethods.get(calledConHash);
return info;
}
private MethodByConInfo getConstructorCallerMethodInfo(int callingIndex, String calledClass, long calledMethodHash)
{
HashMap calledClasses = methodCalledByConInterceptors[callingIndex];
TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(calledClass);
MethodByConInfo info = (MethodByConInfo) calledMethods.get(calledMethodHash);
return info;
}
private ConByConInfo getConCalledByCon(int callingIndex, String calledClass, long calledConHash)
{
HashMap calledClasses = conCalledByConInterceptors[callingIndex];
TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(calledClass);
ConByConInfo info = (ConByConInfo) calledMethods.get(calledConHash);
return info;
}
public Object invokeNew(Object[] args, int idx) throws Throwable
{
Interceptor[] cInterceptors = constructorInfos[idx].getInterceptors();
if (cInterceptors == null) cInterceptors = new Interceptor[0];
ConstructorInvocation invocation = new ConstructorInvocation(cInterceptors);
invocation.setAdvisor(this);
invocation.setArguments(args);
invocation.setConstructor(constructors[idx]);
return invocation.invokeNext();
}
/**
* Invokes interceptor chain.
* This is the beginning
*/
public Object invokeRead(Object target, int index)
throws Throwable
{
Interceptor[] aspects = fieldReadInfos[index].getInterceptors();
if (aspects == null) aspects = new Interceptor[0];
FieldReadInvocation invocation;
if (target != null)
{
InstanceAdvised advised = (InstanceAdvised) target;
InstanceAdvisor advisor = advised._getInstanceAdvisor();
if (advisor != null && advisor.hasInterceptors())
{
aspects = advisor.getInterceptors(aspects);
}
}
invocation = new FieldReadInvocation(advisedFields[index], index, aspects);
invocation.setAdvisor(this);
invocation.setTargetObject(target);
return invocation.invokeNext();
}
/**
* Invokes interceptor chain.
* This is the beginning
*/
public Object invokeWrite(Object target, int index, Object value)
throws Throwable
{
Interceptor[] aspects = fieldWriteInfos[index].getInterceptors();
if (aspects == null) aspects = new Interceptor[0];
FieldWriteInvocation invocation;
if (target != null)
{
InstanceAdvised advised = (InstanceAdvised) target;
InstanceAdvisor advisor = advised._getInstanceAdvisor();
if (advisor != null && advisor.hasInterceptors())
{
aspects = advised._getInstanceAdvisor().getInterceptors(aspects);
}
}
invocation = new FieldWriteInvocation(advisedFields[index], index, value, aspects);
invocation.setAdvisor(this);
invocation.setTargetObject(target);
return invocation.invokeNext();
}
/**
* Invokes interceptor chain.
* This is the beginning
*/
public Object invoke(Invocation invocation) throws Throwable
{
if (invocation instanceof FieldWriteInvocation)
{
FieldWriteInvocation fieldInvocation = (FieldWriteInvocation) invocation;
Object target = fieldInvocation.getTargetObject();
Object val = fieldInvocation.getValue();
Field field = fieldInvocation.getField();
field.set(target, val);
return null;
}
else if (invocation instanceof FieldReadInvocation)
{
FieldReadInvocation fieldInvocation = (FieldReadInvocation) invocation;
Object target = fieldInvocation.getTargetObject();
Field field = fieldInvocation.getField();
return field.get(target);
}
else if (invocation instanceof MethodInvocation)
{
MethodInvocation methodInvocation = (MethodInvocation) invocation;
return invokeWithoutAdvisement(methodInvocation.getTargetObject(),
methodInvocation.getMethodHash(),
methodInvocation.getArguments());
}
else if (invocation instanceof ConstructorInvocation)
{
ConstructorInvocation cInvocation = (ConstructorInvocation) invocation;
Object[] arguments = cInvocation.getArguments();
Constructor constructor = cInvocation.getConstructor();
return invokeNewWithoutAdvisement(arguments, constructor);
}
throw new IllegalStateException("Unknown Invocation type: " + invocation.getClass().getName());
}
// interceptor chain observer
private InterceptorChainObserver interceptorChainObserver;
/**
* Returns the interceptor chain observer associated with this advisor.
*/
protected InterceptorChainObserver getInterceptorChainObserver()
{
return this.interceptorChainObserver;
}
/**
* Defines the interceptor chain observer associated with this advisor.
* @param observer the interceptor chain observer.
*/
protected void setInterceptorChainObserver(InterceptorChainObserver observer)
{
if (observer != null)
{
observer.initialInterceptorChains(this.clazz, fieldReadInterceptors, fieldWriteInterceptors,
constructorInterceptors, methodInterceptors);
}
this.interceptorChainObserver = observer;
}
/** @deprecated We should just be using xxxxInfos */
protected void populateInterceptorsFromInfos()
{
super.populateInterceptorsFromInfos();
fieldReadInterceptors = new Interceptor[fieldReadInfos.length][];
for (int i = 0 ; i < fieldReadInfos.length ; i++)
{
fieldReadInterceptors[i] = fieldReadInfos[i].getInterceptors();
}
fieldWriteInterceptors = new Interceptor[fieldWriteInfos.length][];
for (int i = 0 ; i < fieldWriteInfos.length ; i++)
{
fieldWriteInterceptors[i] = fieldWriteInfos[i].getInterceptors();
}
constructionInterceptors = new Interceptor[constructionInfos.length][];
for (int i = 0 ; i < constructionInfos.length ; i++)
{
constructionInterceptors[i] = constructionInfos[i].getInterceptors();
}
}
interface ResolveCallerConstuctorInfoAction
{
ConByMethodInfo resolveInfo(ClassAdvisor advisor, long callingMethodHash, String calledClass, long calledConHash);
ResolveCallerConstuctorInfoAction PRIVILEGED = new ResolveCallerConstuctorInfoAction()
{
public ConByMethodInfo resolveInfo(final ClassAdvisor advisor, final long callingMethodHash, final String calledClass, final long calledConHash)
{
try
{
return (ConByMethodInfo)AccessController.doPrivileged(new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
return advisor.doResolveCallerConstructorInfo(callingMethodHash, calledClass, calledConHash);
}
});
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
if (ex instanceof RuntimeException)
{
throw (RuntimeException)ex;
}
throw new RuntimeException(ex);
}
}
};
ResolveCallerConstuctorInfoAction NON_PRIVILEGED = new ResolveCallerConstuctorInfoAction()
{
public ConByMethodInfo resolveInfo(ClassAdvisor advisor, long callingMethodHash, String calledClass, long calledConHash)
{
return advisor.doResolveCallerConstructorInfo(callingMethodHash, calledClass, calledConHash);
}
};
}
interface ResolveCallerMethodInfoAction
{
MethodByMethodInfo resolveInfo(ClassAdvisor advisor, long callingMethodHash, String calledClass, long calledMethodHash);
ResolveCallerMethodInfoAction PRIVILEGED = new ResolveCallerMethodInfoAction()
{
public MethodByMethodInfo resolveInfo(final ClassAdvisor advisor, final long callingMethodHash, final String calledClass, final long calledMethodHash)
{
try
{
return (MethodByMethodInfo)AccessController.doPrivileged(new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
return advisor.doResolveCallerMethodInfo(callingMethodHash, calledClass, calledMethodHash);
}
});
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
if (ex instanceof RuntimeException)
{
throw (RuntimeException)ex;
}
throw new RuntimeException(ex);
}
}
};
ResolveCallerMethodInfoAction NON_PRIVILEGED = new ResolveCallerMethodInfoAction()
{
public MethodByMethodInfo resolveInfo(ClassAdvisor advisor, long callingMethodHash, String calledClass, long calledMethodHash)
{
return advisor.doResolveCallerMethodInfo(callingMethodHash, calledClass, calledMethodHash);
}
};
}
interface ResolveConstructorCallerMethodInfoAction
{
MethodByConInfo resolveInfo(ClassAdvisor advisor, int callingIndex, String calledClass, long calledMethodHash);
ResolveConstructorCallerMethodInfoAction PRIVILEGED = new ResolveConstructorCallerMethodInfoAction()
{
public MethodByConInfo resolveInfo(final ClassAdvisor advisor, final int callingIndex, final String calledClass, final long calledMethodHash)
{
try
{
return (MethodByConInfo)AccessController.doPrivileged(new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
return advisor.doResolveConstructorCallerMethodInfo(callingIndex, calledClass, calledMethodHash);
}
});
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
if (ex instanceof RuntimeException)
{
throw (RuntimeException)ex;
}
throw new RuntimeException(ex);
}
}
};
ResolveConstructorCallerMethodInfoAction NON_PRIVILEGED = new ResolveConstructorCallerMethodInfoAction()
{
public MethodByConInfo resolveInfo(ClassAdvisor advisor, int callingIndex, String calledClass, long calledMethodHash)
{
return advisor.doResolveConstructorCallerMethodInfo(callingIndex, calledClass, calledMethodHash);
}
};
}
interface ResolveConstructorCallerConstructorInfoAction
{
ConByConInfo resolveInfo(ClassAdvisor advisor, int callingIndex, String calledClass, long calledConHash);
ResolveConstructorCallerConstructorInfoAction PRIVILEGED = new ResolveConstructorCallerConstructorInfoAction()
{
public ConByConInfo resolveInfo(final ClassAdvisor advisor, final int callingIndex, final String calledClass, final long calledConHash)
{
try
{
return (ConByConInfo)AccessController.doPrivileged(new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
return advisor.doResolveConstructorCallerConstructorInfo(callingIndex, calledClass, calledConHash);
}
});
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
if (ex instanceof RuntimeException)
{
throw (RuntimeException)ex;
}
throw new RuntimeException(ex);
}
}
};
ResolveConstructorCallerConstructorInfoAction NON_PRIVILEGED = new ResolveConstructorCallerConstructorInfoAction()
{
public ConByConInfo resolveInfo(ClassAdvisor advisor, int callingIndex, String calledClass, long calledConHash)
{
return advisor.doResolveConstructorCallerConstructorInfo(callingIndex, calledClass, calledConHash);
}
};
}
interface RebuildInterceptorsAction
{
void rebuildInterceptors(ClassAdvisor advisor);
RebuildInterceptorsAction PRIVILEGED = new RebuildInterceptorsAction()
{
public void rebuildInterceptors(final ClassAdvisor advisor)
{
try
{
AccessController.doPrivileged(new PrivilegedExceptionAction()
{
public Object run()
{
advisor.doRebuildInterceptors();
return null;
}
});
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
if (ex instanceof RuntimeException)
{
throw (RuntimeException)ex;
}
throw new RuntimeException(ex);
}
}
};
RebuildInterceptorsAction NON_PRIVILEGED = new RebuildInterceptorsAction()
{
public void rebuildInterceptors(ClassAdvisor advisor)
{
advisor.doRebuildInterceptors();
}
};
}
}