/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.rdfbean.guice;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.springframework.transaction.annotation.NotTransactional;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.google.inject.Provider;
import com.google.inject.matcher.AbstractMatcher;
/**
* @author tiwe
*/
class TransactionalMethodMatcher extends AbstractMatcher<Method> implements Provider<Map<Method, Transactional>> {
private final Map<Method, Transactional> configuration = new HashMap<Method, Transactional>();
@Override
public boolean matches(Method method) {
if (method.getAnnotation(NotTransactional.class) != null) {
return false;
// annotated method
} else if (method.getAnnotation(Transactional.class) != null) {
return handle(method, method.getAnnotation(Transactional.class));
// annotated class
} else if (method.getDeclaringClass().getAnnotation(Transactional.class) != null) {
return handle(method, method.getDeclaringClass().getAnnotation(Transactional.class));
}
for (Class<?> iface : method.getDeclaringClass().getInterfaces()) {
// annotated interface
if (iface.getAnnotation(Transactional.class) != null) {
return handle(method, iface.getAnnotation(Transactional.class));
} else {
for (Method m : iface.getMethods()) {
// annotated interface method
if (m.getName().equals(method.getName())
&& m.getAnnotation(Transactional.class) != null
&& equals(m.getParameterTypes(), method.getParameterTypes())) {
return handle(method, m.getAnnotation(Transactional.class));
}
}
}
}
return false;
}
private boolean handle(Method method, Transactional annotation) {
boolean intercepted = annotation.propagation() != Propagation.SUPPORTS;
if (intercepted) {
configuration.put(method, annotation);
}
return intercepted;
}
private boolean equals(Object[] a, Object[] b) {
if (a.length == b.length) {
return Arrays.asList(a).equals(Arrays.asList(b));
}
return false;
}
@Override
public Map<Method, Transactional> get() {
return configuration;
}
}