From bc6aad1ba2d9bfaed8597722e067a10a0bc8a5d5 Mon Sep 17 00:00:00 2001
From: Brian Repko <brian.repko@learnthinkcode.com>
Date: Sun, 25 Jul 2010 16:07:37 -0500
Subject: [PATCH 1/3] removal of javassist

---
 jbehave-core/pom.xml                               |    5 -
 .../core/configuration/AnnotationFinder.java       |  277 +++++---------------
 2 files changed, 60 insertions(+), 222 deletions(-)

diff --git a/jbehave-core/pom.xml b/jbehave-core/pom.xml
index 33dbaea..096917b 100644
--- a/jbehave-core/pom.xml
+++ b/jbehave-core/pom.xml
@@ -32,11 +32,6 @@
       <version>2.2.1</version>
     </dependency>
     <dependency>
-      <groupId>javassist</groupId>
-      <artifactId>javassist</artifactId>
-      <version>3.11.0.GA</version>
-    </dependency>
-    <dependency>
       <groupId>javax.inject</groupId>
       <artifactId>javax.inject</artifactId>
       <version>1</version>
diff --git a/jbehave-core/src/main/java/org/jbehave/core/configuration/AnnotationFinder.java b/jbehave-core/src/main/java/org/jbehave/core/configuration/AnnotationFinder.java
index 5599372..5b882ba 100644
--- a/jbehave-core/src/main/java/org/jbehave/core/configuration/AnnotationFinder.java
+++ b/jbehave-core/src/main/java/org/jbehave/core/configuration/AnnotationFinder.java
@@ -1,226 +1,69 @@
 package org.jbehave.core.configuration;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import javassist.ClassClassPath;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtMethod;
-import javassist.NotFoundException;
-import javassist.bytecode.AnnotationDefaultAttribute;
-import javassist.bytecode.AnnotationsAttribute;
-import javassist.bytecode.ClassFile;
-import javassist.bytecode.MethodInfo;
-import javassist.bytecode.annotation.AnnotationMemberValue;
-import javassist.bytecode.annotation.ArrayMemberValue;
-import javassist.bytecode.annotation.BooleanMemberValue;
-import javassist.bytecode.annotation.ClassMemberValue;
-import javassist.bytecode.annotation.EnumMemberValue;
-import javassist.bytecode.annotation.IntegerMemberValue;
-import javassist.bytecode.annotation.MemberValue;
-import javassist.bytecode.annotation.StringMemberValue;
 
 public class AnnotationFinder {
 
-    private final ClassPool classPool = ClassPool.getDefault();
-    private final Map<String, Map<String, Object>> annotationsMap = new HashMap<String, Map<String, Object>>();
-    private final Class<?> annotatedClass;
-
-    public AnnotationFinder(Class<?> annotatedClass) {
-        this.annotatedClass = annotatedClass;
-        findAnnotations();
-    }
-
-    private void findAnnotations() {
-        Stack<Class<?>> stack = new Stack<Class<?>>();
-        stack.push(annotatedClass);
-        Class<?> annotatedSuperClass = annotatedClass.getSuperclass();
-        while (annotatedSuperClass != Object.class) {
-            stack.push(annotatedSuperClass);
-            annotatedSuperClass = annotatedSuperClass.getSuperclass();
-        }
-        while (!stack.empty()) {
-            Class<?> nextClass = stack.pop();
-            classPool.insertClassPath(new ClassClassPath(nextClass));
-            try {
-                scanClass(classPool.get(nextClass.getName()).getClassFile());
-            } catch (NotFoundException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    private void scanClass(ClassFile classFile) {
-        AnnotationsAttribute visible = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.visibleTag);
-        AnnotationsAttribute invisible = (AnnotationsAttribute) classFile
-                .getAttribute(AnnotationsAttribute.invisibleTag);
-
-        if (visible != null) {
-            populate(visible.getAnnotations());
-        }
-        if (invisible != null) {
-            populate(invisible.getAnnotations());
-        }
-    }
-
-    private void populate(javassist.bytecode.annotation.Annotation[] annotations) {
-        if (annotations == null) {
-            return;
-        }
-        // for each annotation on class hierarchy
-        for (javassist.bytecode.annotation.Annotation annotation : annotations) {
-            // a map that contain each member(attribute) of the annotation
-            Map<String, Object> annotationsAttributesMap = annotationsMap.get(annotation.getTypeName());
-            if (annotationsAttributesMap == null) {
-                annotationsAttributesMap = new HashMap<String, Object>();
-                annotationsMap.put(annotation.getTypeName(), annotationsAttributesMap);
-            }
-            processAnnotation(annotation, annotationsAttributesMap);
-        }
-    }
-
-    private void processAnnotation(javassist.bytecode.annotation.Annotation annotation,
-            Map<String, Object> annotationsAttributesMap) {
-
-        try {
-            // Process Default Values
-            CtClass annotationMetaClass = classPool.get(annotation.getTypeName());
-
-            // process annotation members
-            for (CtMethod memberMethod : annotationMetaClass.getDeclaredMethods()) {
-                MemberValue memberValue = null;
-                String memberName = memberMethod.getMethodInfo().getName();
-                Object memberValueObject = annotationsAttributesMap.get(memberName);
-                memberValue = annotation.getMemberValue(memberName);
-                if (memberValue == null) {
-                    CtMethod cm = annotationMetaClass.getDeclaredMethod(memberName);
-                    MethodInfo minfo = cm.getMethodInfo();
-                    AnnotationDefaultAttribute ada = (AnnotationDefaultAttribute) minfo
-                            .getAttribute(AnnotationDefaultAttribute.tag);
-                    memberValue = ada.getDefaultValue(); // default value
-                }
-                if (memberValueObject == null) {
-                    memberValueObject = processMemberValue(memberValue, null);
-                } else {
-                    Object newMemberValue = processMemberValue(memberValue, memberValueObject);
-                    if (newMemberValue != null)
-                        memberValueObject = newMemberValue;
-                }
-                annotationsAttributesMap.put(memberName, memberValueObject);
-
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private <T> T processMemberValue(MemberValue memberValue, Object previousValue) {
-
-        if (memberValue instanceof AnnotationMemberValue) {
-            Map<String, Object> value = new HashMap<String, Object>();
-            processAnnotation(((AnnotationMemberValue) memberValue).getValue(), value);
-            return (T) value;
-        }
-
-        if (memberValue instanceof StringMemberValue) {
-            String value = ((StringMemberValue) memberValue).getValue();
-            return (T) value;
-        }
-
-        if (memberValue instanceof ArrayMemberValue) {
-            List<Object> values;
-            if (previousValue == null) {
-                values = new ArrayList<Object>();
-            } else {
-                values = (List<Object>) previousValue;
-            }
-
-            for (MemberValue arrayMember : ((ArrayMemberValue) memberValue).getValue()) {
-                values.add(processMemberValue(arrayMember, values));
-            }
-            return (T) values;
-        }
-
-        if (memberValue instanceof BooleanMemberValue) {
-            Boolean value = ((BooleanMemberValue) memberValue).getValue();
-            return (T) value;
-        }
-
-        if (memberValue instanceof IntegerMemberValue) {
-            Integer value = ((IntegerMemberValue) memberValue).getValue();
-            return (T) value;
-        }
-
-        if (memberValue instanceof EnumMemberValue) {
-            String value = ((EnumMemberValue) memberValue).getValue();
-            String type = ((EnumMemberValue) memberValue).getType();
-            return (T) Enum.valueOf(loadClass(type), value);
-        }
-
-        if (memberValue instanceof ClassMemberValue) {
-            String value = ((ClassMemberValue) memberValue).getValue();
-            return (T) loadClass(value);
-        }
-
-        throw new RuntimeException("Invalid member value " + memberValue);
-    }
-
-    @SuppressWarnings("unchecked")
-    private Class loadClass(String type) {
-        try {
-            return annotatedClass.getClassLoader().loadClass(type);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-        return annotationsMap.containsKey(annotationClass.getName());
-    }
-
-    public boolean isAnnotationValuePresent(Class<? extends Annotation> annotationClass, String memberName) {
-        if (isAnnotationPresent(annotationClass)) {
-            return annotationsMap.get(annotationClass.getName()).containsKey(memberName);
-        }
-        return false;
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T getAnnotatedValue(Class<? extends Annotation> annotationClass, Class<T> memberType, String memberName) {
-        String annotationName = annotationClass.getName();
-        if (annotationsMap.containsKey(annotationName)) {
-            Map<String, Object> annotationAttributeMap = annotationsMap.get(annotationName);
-            Object value = annotationAttributeMap.get(memberName);
-            if (value != null) {
-                return (T) value;
-            }
-        }
-        throw new MissingAnnotationException(annotationClass, memberName);
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> List<T> getAnnotatedValues(Class<? extends Annotation> annotationClass, Class<T> type, String memberName) {
-        List<T> list = new ArrayList<T>();
-        for (Object value : getAnnotatedValue(annotationClass, List.class, memberName)) {
-            list.add((T) value);
-        }
-        return list;
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> List<Class<T>> getAnnotatedClasses(Class<? extends Annotation> annotationClass, Class<T> type,
-            String memberName) {
-        List<Class<T>> list = new ArrayList<Class<T>>();
-        for (Object value : getAnnotatedValue(annotationClass, List.class, memberName)) {
-            list.add((Class<T>) value);
-        }
-        return list;
-    }
-
+	private final Class<?> annotatedClass;
+
+	public AnnotationFinder(Class<?> annotatedClass) {
+		this.annotatedClass = annotatedClass;
+	}
+
+	public <A extends Annotation> boolean isAnnotationPresent(Class<A> annotationClass) {
+		return getAnnotation(annotationClass) != null;
+	}
+
+	public <A extends Annotation> boolean isAnnotationValuePresent(Class<A> annotationClass, String memberName) {
+		Annotation annotation = getAnnotation(annotationClass);
+		return annotation != null && getAnnotationValue(annotation, memberName) != null;
+	}
+
+	@SuppressWarnings("unchecked")
+	public <T, A extends Annotation> T getAnnotatedValue(Class<A> annotationClass, Class<T> memberType, String memberName) {
+		Annotation annotation = getAnnotation(annotationClass);
+		if (annotation != null) {
+			Object value = getAnnotationValue(annotation, memberName);
+			if (value != null) {
+				return (T) value;
+			}
+		}
+		throw new MissingAnnotationException(annotationClass, memberName);
+	}
+
+	@SuppressWarnings("unchecked")
+	public <T, A extends Annotation> List<T> getAnnotatedValues(Class<A> annotationClass, Class<T> type, String memberName) {
+		List<T> list = new ArrayList<T>();
+		Object[] values = getAnnotatedValue(annotationClass, Object[].class, memberName);
+		for (Object value : values) {
+			list.add((T) value);
+		}
+		return list;
+	}
+
+	@SuppressWarnings("unchecked")
+	public <T, A extends Annotation> List<Class<T>> getAnnotatedClasses(Class<A> annotationClass, Class<T> type, String memberName) {
+		List<Class<T>> list = new ArrayList<Class<T>>();
+		Object[] values = getAnnotatedValue(annotationClass, Object[].class, memberName);
+		for (Object value : values) {
+			list.add((Class<T>) value);
+		}
+		return list;
+	}
+
+	protected <A extends Annotation> Annotation getAnnotation(Class<A> annotationClass) {
+		return annotatedClass.getAnnotation(annotationClass);
+	}
+	
+	protected Object getAnnotationValue(Annotation annotation, String attributeName) {
+		try {
+			Method method = annotation.annotationType().getDeclaredMethod(attributeName, new Class[0]);
+			return method.invoke(annotation);
+		} catch (Exception ex) {
+			return null;
+		}
+	}
 }
-- 
1.7.1.GIT

