package roxcdi.reflection;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class AnnotationProxy {

	@SuppressWarnings("unchecked")
	static public Annotation[] asAnnotations(Class<? extends Annotation>... annotationsClasses) {
		Annotation[] a = new Annotation[ annotationsClasses.length ] ;
		
		for (int i = 0; i < a.length; i++) {
			a[i] = asAnnotation( annotationsClasses[i] ) ;
		}
		
		return a ;
	}
	
	@SuppressWarnings("unchecked")
	static public <T extends Annotation> T asAnnotation(final Class<T> annotationClass) {
		
		T instance = (T) Proxy.newProxyInstance(AnnotationProxy.class.getClassLoader(), new Class<?>[] {annotationClass}, new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				
				if ( method.getName().equals("annotationType") ) {
					return annotationClass ; 
				}
				else if ( method.getName().equals("hashCode") ) {
					return proxy.hashCode() ; 
				}
				else if ( method.getName().equals("equals") ) {
					return proxy.equals(args[0]) ; 
				}
				else if ( method.getName().equals("toString") ) {
					return annotationClass.getName() ; 
				}
				
				throw new UnsupportedOperationException("Can't handler Annotation method: "+ method) ;
			}
		}) ;
    	
		return instance ;
	}
	
}

@@ -169,16 +169,42 @@
 t.Proxy;
+%0Aimport java.util.HashMap;
 %0A%0Apublic
@@ -538,16 +538,131 @@
  ;%0A%09%7D%0A%09%0A
+%09@SuppressWarnings(%22rawtypes%22)%0A%09static final private HashMap%3CClass, Object%3E annotationsProxy = new HashMap%3C%3E() ;%0A%09%0A
 %09@Suppre
@@ -775,16 +775,419 @@
 s) %7B%0A%09%09%0A
+%09%09synchronized (annotationsProxy) %7B%0A%09%09%09T proxy = (T) annotationsProxy.get(annotationClass) ;%0A%09%09%09if (proxy != null) return proxy ;%0A%09%09%09%0A%09%09%09proxy = createAnnotationProxy(annotationClass) ;%0A%09%09%09%0A%09%09%09annotationsProxy.put(annotationClass, proxy) ;%0A%09%09%09%0A%09%09%09return proxy ;%0A%09%09%7D%0A%09%7D%0A%09%0A%09@SuppressWarnings(%22unchecked%22)%0A%09static private %3CT extends Annotation%3E T createAnnotationProxy(final Class%3CT%3E annotationClass) %7B%0A%09%09%0A
 %09%09T inst
@@ -1420,21 +1420,16 @@
 wable %7B%0A
-%09%09%09%09%0A
 %09%09%09%09if (
@@ -1582,23 +1582,32 @@
 urn 
-proxy.h
+System.identityH
 ashCode(
 ) ; 
@@ -1602,16 +1602,21 @@
 ashCode(
+proxy
 ) ; %0A%09%09%09
@@ -1691,27 +1691,21 @@
 roxy
-.equals(
+ == 
 args%5B0%5D
-)
  ;
- 
 %0A%09%09%09
@@ -1757,24 +1757,24 @@
 tring%22) ) %7B%0A
-
 %09%09%09%09%09return 
@@ -1765,32 +1765,36 @@
 ) %7B%0A%09%09%09%09%09return 
+%22@%22+
 annotationClass.

fix proxy invokes and add cache to proxy instances