package org.nuunframework.ensemble.engine;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Singleton;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.nuunframework.ensemble.util.Primitives;
public class EnsembleRecorder implements MethodInterceptor
{
@Singleton
private final Context context;
EnsembleRecorder(Context context)
{
this.context = context;
}
public Object invoke(MethodInvocation invocation) throws Throwable
{
Method method = invocation.getMethod();
String methodName = method.getName();
Object[] arguments = invocation.getArguments();
invocation.getThis();
Integer operationId = context.getOperationIdAndIncrement();
Object proceed = invocation.proceed();
if ("hashCode() toString()".indexOf(methodName) == -1)
{
Role currentRole = null;
if ( ! context.stackRole.isEmpty())
{
currentRole = context.stackRole.pop();
System.out.println(" =================================== " + operationId);
System.out.println(" poping (" + context.stackRole.size() + ") "+ currentRole.getName() );
}
else
{
System.out.println(" ===================================" );
System.out.println(" stack empty " );
}
if (arguments.length == 0)
{ // getter
if (!Primitives.isJdkLangClass(method.getReturnType()))
{
// Here we create another proxy
proceed = context.injector.getInstance(method.getReturnType());
context.stackRole.push( Roles.BLANK );
}
}
else
{ // setter
}
// Get the invokerclass
Class<?> invokerClass = null;
if (invocation.getThis().getClass().getName().contains("EnhancerByGuice"))
{
invokerClass = invocation.getThis().getClass().getSuperclass();
}
else
{
invokerClass = invocation.getThis().getClass();
}
String currentRoleName = ( currentRole != null ? currentRole.getName() : null);
EnsembleRecordItem item = new EnsembleRecordItem(invokerClass, method, method.getReturnType(), currentRoleName , arguments);
// We record the item
context.recording.record(item);
System.out.println(method.getName() + "(" + display(arguments) + ") return type " + method.getReturnType().getSimpleName());
}
else if ("hashCode()".indexOf(methodName) >= 0)
{
System.out.println(" ===================================" );
System.out.println(" HASHCODE " + context.stackRole.size());
// if (hashcodes.containsKey(this1))
// {
// proceed = (int) hashcodes.get(this1);
// }
// else {
proceed = nextInt();
// hashcodes.put(this1, (Integer) proceed);
// }
} else {
System.out.println(" ===================================" );
System.out.println(" TOSTRING " + context.stackRole.size());
}
// we dismiss the current role
return proceed;
}
static final Map<Object, Integer> hashcodes = new ConcurrentHashMap<Object, Integer>();
String display(Object... args)
{
StringBuilder b = new StringBuilder();
for (Object arg : args)
{
b.append(arg).append(' ');
}
return b.toString();
}
static Integer proxyIds = 0;
static int nextInt()
{
synchronized (proxyIds)
{
return proxyIds++;
}
}
}