Index: src/main/java/org/jboss/ejb3/aop/BeanContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/aop/BeanContainer.java (revision 92848) +++ src/main/java/org/jboss/ejb3/aop/BeanContainer.java (working copy) @@ -31,6 +31,7 @@ import org.jboss.aop.Domain; import org.jboss.aop.annotation.AnnotationRepository; import org.jboss.ejb3.EJBContainer; +import org.jboss.ejb3.aop.annotation.CachingAnnotationRepository; import org.jboss.ejb3.cluster.metadata.ClusteredMetaDataBridge; import org.jboss.ejb3.interceptors.container.ManagedObjectAdvisor; import org.jboss.ejb3.interceptors.direct.AbstractDirectContainer; @@ -203,7 +204,7 @@ // Ensure that an @Clustered annotation is visible to AOP if the XML says the bean is clustered. annotations.addMetaDataBridge(new ClusteredMetaDataBridge()); - initializeAdvisor(name, domain, beanClass, annotations); + initializeAdvisor(name, domain, beanClass, new CachingAnnotationRepository(annotations, classLoader)); } @Override Index: src/main/java/org/jboss/ejb3/aop/annotation/CachingAnnotationRepository.java =================================================================== --- src/main/java/org/jboss/ejb3/aop/annotation/CachingAnnotationRepository.java (revision 0) +++ src/main/java/org/jboss/ejb3/aop/annotation/CachingAnnotationRepository.java (revision 0) @@ -0,0 +1,268 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2009, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.ejb3.aop.annotation; + +import java.lang.reflect.Member; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javassist.CtMember; + +import org.jboss.aop.annotation.AnnotationRepository; + +/** + * @author Carlo de Wolf + * @version $Revision: $ + */ +public class CachingAnnotationRepository extends AnnotationRepository +{ + // a magic NULL marker for in the cache + private static final Object NULL = new Object(); + + private AnnotationRepository delegate; + // Because AnnotationRepositoryToMetaData also does class loading, we should do this as well to + // cache the String variants of annotation lookup. + private ClassLoader classLoader; + + private Map, Object> classAnnotationsCache = new ConcurrentHashMap, Object>(); + private ConcurrentHashMap, Object>> memberCache = new ConcurrentHashMap, Object>>(); + + public CachingAnnotationRepository(AnnotationRepository delegate, ClassLoader classLoader) + { + assert delegate != null; + assert classLoader != null; + + this.delegate = delegate; + this.classLoader = classLoader; + } + + @Override + public void addAnnotation(CtMember m, String annotation) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public void addAnnotation(Member m, String annotation, Object value) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public void addAnnotation(Member m, Class annotation, Object value) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public void addClassAnnotation(Class annotationType, Object value) + { + classAnnotationsCache.put(annotationType, value); + delegate.addClassAnnotation(annotationType, value); + } + + @Override + public void addClassAnnotation(String annotation, String value) + { + /* + System.err.println("RED FLAG"); + new Exception("addClassAnnotation").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + */ + delegate.addClassAnnotation(annotation, value); + } + + @Override + public void disableAnnotation(Member m, String annotation) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public void disableAnnotation(String annotation) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public void enableAnnotation(String annotation) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public Map getAnnotations() + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public Map getClassAnnotations() + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public boolean hasAnnotation(CtMember m, String annotation) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public boolean hasAnnotation(Member m, Class annotation) + { + return resolveAnnotation(m, annotation) != null; + } + + @Override + public boolean hasAnnotation(Member m, String annotation) + { + // stupid + //return delegate.hasAnnotation(m, annotation); + + return hasAnnotation(m, loadClass(annotation)); + } + + @Override + public boolean hasClassAnnotation(Class annotationType) + { + return resolveClassAnnotation(annotationType) != null; + } + + @Override + public boolean hasClassAnnotation(String annotation) + { + /* + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + */ + // AOP is stupid + return delegate.hasClassAnnotation(annotation); + } + + @Override + public boolean isDisabled(Class annotation) + { + return delegate.isDisabled(annotation); + } + + @Override + public boolean isDisabled(Member m, Class annotation) + { + return delegate.isDisabled(m, annotation); + } + + @Override + public boolean isDisabled(Member m, String annotation) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + @Override + public boolean isDisabled(String annotation) + { + new RuntimeException("NYI").printStackTrace(); + // TODO Auto-generated method stub + throw new RuntimeException("NYI"); + } + + protected Class loadClass(String className) + { + try + { + return classLoader.loadClass(className); + } + catch (ClassNotFoundException e) + { + throw new RuntimeException(e); + } + } + + @Override + public Object resolveAnnotation(Member m, Class annotationType) + { + Map, Object> annotationCache = memberCache.get(m); + if(annotationCache == null) + { + annotationCache = new ConcurrentHashMap, Object>(); + memberCache.put(m, annotationCache); + } + Object annotation = annotationCache.get(annotationType); + if(annotation == null) + { + annotation = delegate.resolveAnnotation(m, annotationType); + if(annotation != null) + annotationCache.put(annotationType, annotation); + else + annotationCache.put(annotationType, NULL); + } + if(annotation == NULL) + annotation = null; + return annotation; + } + + @Override + protected Object resolveAnnotation(Member m, String annotation) + { + new RuntimeException("NYI").printStackTrace(); + throw new RuntimeException("NYI"); + } + + @Override + public Object resolveClassAnnotation(Class annotationType) + { + Object annotation = classAnnotationsCache.get(annotationType); + if(annotation == null) + { + annotation = delegate.resolveClassAnnotation(annotationType); + if(annotation != null) + classAnnotationsCache.put(annotationType, annotation); + else + classAnnotationsCache.put(annotationType, NULL); + } + if(annotation == NULL) + annotation = null; + return annotation; + } +}