Commit 30423ee9 authored by Lubomir Bulej's avatar Lubomir Bulej

Refactor GuardResover.getGuardMethod()

Split of cache lookup from finding the method via reflection
and annotations and rename the field caching the results.
parent fd286572
package ch.usi.dag.disl.resolver;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import ch.usi.dag.disl.exception.GuardException;
......@@ -16,59 +19,69 @@ public class GuardResolver {
// TODO LB: Get rid of guard resolver singleton
private static GuardResolver instance = new GuardResolver ();
// Guard to guard method map
private Map<Class<?>, GuardMethod> guardToMethod =
new HashMap<Class<?>, GuardMethod>();
public static GuardResolver getInstance () {
return instance;
}
public synchronized GuardMethod getGuardMethod(
Class<?> guardClass) throws GuardException {
//
GuardMethod guardMethod = guardToMethod.get(guardClass);
/** A cache of guard methods corresponding to guard classes. */
private final Map <Class <?>, GuardMethod> __guardMethodsByClass = new HashMap <> ();
// resolved from cache
if(guardMethod != null) {
return guardMethod;
}
// no cache hit
public synchronized GuardMethod getGuardMethod (
final Class <?> guardClass
) throws GuardException {
//
// Try to find the guard method by consulting the cache of methods
// corresponding to guard classes. If it does not provide an answer,
// search of a guard method within the class.
//
final GuardMethod cachedResult = __guardMethodsByClass.get (guardClass);
if (cachedResult != null) {
return cachedResult;
}
// check all methods
for(Method method : guardClass.getMethods()) {
return __findGuardMethod (guardClass);
}
if(method.isAnnotationPresent(
ch.usi.dag.disl.annotation.GuardMethod.class)) {
// detect multiple annotations
if(guardMethod != null) {
throw new GuardException("Detected several "
+ GuardMethod.class.getName()
+ " annotations on guard class "
+ guardClass.getName());
}
private GuardMethod __findGuardMethod (
final Class <?> guardClass
) throws GuardException {
final List <Method> candidateMethods = Arrays.stream (guardClass.getDeclaredMethods ())
.filter (m -> __isGuardMethodCandidate (m))
.collect (Collectors.toList ());
guardMethod = new GuardMethod(method);
}
if (candidateMethods.isEmpty ()) {
throw new GuardException (String.format (
"No method annotated using %s found in class %s",
ch.usi.dag.disl.annotation.GuardMethod.class.getName(),
guardClass.getName()
));
}
// detect no annotation
if(guardMethod == null) {
throw new GuardException("No "
+ ch.usi.dag.disl.annotation.GuardMethod.class.getName()
+ " annotation on some public method in guard class "
+ guardClass.getName());
if (candidateMethods.size () > 1) {
throw new GuardException (String.format (
"Multiple (%d) guard methods found in class %s",
candidateMethods.size (), guardClass.getName()
));
}
// make the method accessible and put it into cache
guardMethod.getMethod ().setAccessible (true);
guardToMethod.put(guardClass, guardMethod);
// Now just get the first method and make it accessible
final Method method = candidateMethods.get (0);
method.setAccessible (true);
return guardMethod;
final GuardMethod result = new GuardMethod (method);
__guardMethodsByClass.put (guardClass, result);
return result;
}
private boolean __isGuardMethodCandidate (final Method m) {
return m.isAnnotationPresent(
ch.usi.dag.disl.annotation.GuardMethod.class
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment