}
/** {@inheritDoc} */
public Object processInvocation(final InvocationContext context) throws Exception {
final Object[] parameters = context.getParameters();
final ObjectClonerFactory clonerFactory = ObjectCloners.getSerializingObjectClonerFactory();
final ObjectCloner cloner = clonerFactory.createCloner(configuration);
final Object[] newParameters;
switch (passMode) {
case REFERENCE_ONLY: {
newParameters = parameters;
break;
}
case SAME_CLASS_LOADER: {
newParameters = parameters.clone();
final int len = newParameters.length;
for (int i = 0; i < len; i++) {
final Object param = parameters[i];
if (param != null) {
final Class<?> origClass = param.getClass();
final Class<?> newClass = classCloner.clone(origClass);
if (newClass != origClass) {
newParameters[i] = cloner.clone(param);
}
}
}
break;
}
case VALUE_ONLY: {
final int len = parameters.length;
newParameters = new Object[len];
for (int i = 0; i < len; i++) {
newParameters[i] = cloner.clone(parameters[i]);
}
break;
}
default: {
// not reachable
throw new IllegalStateException();
}
}
final InvocationContext newContext = new SimpleInvocationContext(targetInstance, targetMethod, newParameters, context.getContextData(), null);
final Object result = targetInterceptor.processInvocation(newContext);
switch (passMode) {
case REFERENCE_ONLY: {
return result;
}
case SAME_CLASS_LOADER: {
if (result == null) {
return null;
}
final ClassLoaderClassCloner classCloner = new ClassLoaderClassCloner(getContextClassLoader());
final Class<?> classClone = classCloner.clone(result.getClass());
if (classClone == result.getClass()) {
return result;
}
// fall through
}
case VALUE_ONLY: {
if (result == null) {
return null;
}
final ClonerConfiguration copyBackConfiguration = new ClonerConfiguration();
copyBackConfiguration.setClassCloner(new ClassLoaderClassCloner(getContextClassLoader()));
return clonerFactory.createCloner(copyBackConfiguration).clone(result);
}
default: {
// not reachable
throw new IllegalStateException();
}