/*
* Copyright 2012 NGDATA nv
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lilyproject.repository.impl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.lilyproject.repository.api.IdGenerator;
import org.lilyproject.repository.api.Repository;
import org.lilyproject.repository.api.TypeManager;
public class TracingRepository {
private TracingRepository() {
}
public static Repository wrap(Repository repository) {
TypeManager typeManager = (TypeManager) Proxy.newProxyInstance(TypeManager.class.getClassLoader(),
new Class[]{TypeManager.class}, new TracingTypeManagerIH(repository.getTypeManager()));
IdGenerator idGenerator = (IdGenerator) Proxy.newProxyInstance(IdGenerator.class.getClassLoader(),
new Class[]{IdGenerator.class}, new TracingIdGeneratorIH(repository.getIdGenerator()));
return (Repository) Proxy.newProxyInstance(Repository.class.getClassLoader(),
new Class[]{Repository.class}, new TracingRepositoryIH(repository, typeManager, idGenerator));
}
private static final class TracingRepositoryIH implements InvocationHandler {
private final Repository delegate;
private final TypeManager typeManager;
private final IdGenerator idGenerator;
private TracingRepositoryIH(Repository delegate, TypeManager typeManager, IdGenerator idGenerator) {
this.delegate = delegate;
this.typeManager = typeManager;
this.idGenerator = idGenerator;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("getTypeManager")) {
return typeManager;
} else if (method.getName().equals("getIdGenerator")) {
return idGenerator;
}
logMethodCall(method, args);
try {
return method.invoke(delegate, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
}
private static void logMethodCall(Method method, Object[] args) {
StringBuilder builder = new StringBuilder();
builder.append(method.getDeclaringClass().getSimpleName()).append(".").append(method.getName());
if (args != null) {
for (int i = 0; i < args.length; i++) {
builder.append(i > 0 ? ", " : " ");
builder.append("arg").append(i).append(" = ");
if (args[i] != null && args[i].getClass().isArray()) {
Object[] values = (Object[]) args[i];
builder.append("[");
for (int j = 0; j < values.length; j++) {
if (j > 0) {
builder.append(", ");
}
builder.append(values[i]);
}
builder.append("]");
} else {
builder.append(args[i]);
}
}
}
System.out.println("===== " + builder.toString());
}
private static final class TracingTypeManagerIH implements InvocationHandler {
private final TypeManager delegate;
private TracingTypeManagerIH(TypeManager delegate) {
this.delegate = delegate;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(delegate, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
}
private static final class TracingIdGeneratorIH implements InvocationHandler {
private final IdGenerator delegate;
private TracingIdGeneratorIH(IdGenerator delegate) {
this.delegate = delegate;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(delegate, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
}
}