001/* 002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.runtime.annotations; 023 024import java.lang.annotation.Annotation; 025import java.lang.reflect.Method; 026import java.util.ArrayList; 027import java.util.HashMap; 028import java.util.Map; 029 030/** 031 * @author <a href="mailto:[email protected]">Bogdan Stefanescu</a> 032 */ 033public class AnnotatedClass<T> { 034 035 protected AnnotatedClass<?> superClass; 036 037 protected final Class<T> clazz; 038 039 protected final Map<Class<? extends Annotation>, Annotation> annotations; 040 041 protected final Map<Method, AnnotatedMethod> methods; 042 043 public AnnotatedClass(Class<T> clazz) { 044 this.clazz = clazz; 045 methods = new HashMap<Method, AnnotatedMethod>(); 046 annotations = new HashMap<Class<? extends Annotation>, Annotation>(); 047 } 048 049 public Class<?> getAnnotatedClass() { 050 return clazz; 051 } 052 053 @SuppressWarnings("unchecked") 054 public <A extends Annotation> A getAnnotation(Class<A> annotationClass) { 055 return (A) annotations.get(annotationClass); 056 } 057 058 public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) { 059 return clazz.getAnnotation(annotationClass); 060 } 061 062 public Annotation[] getAnnotations() { 063 return annotations.values().toArray(new Annotation[annotations.size()]); 064 } 065 066 public Annotation[] getDeclaredAnnotations() { 067 return clazz.getDeclaredAnnotations(); 068 } 069 070 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { 071 return annotations.containsKey(annotationClass); 072 } 073 074 public boolean isDeclaringAnnotation(Class<? extends Annotation> annotationClass) { 075 return clazz.isAnnotationPresent(annotationClass); 076 } 077 078 public AnnotatedMethod getAnnotatedMethod(Method method) { 079 return methods.get(method); 080 } 081 082 public AnnotatedMethod getAnnotatedMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException { 083 return getAnnotatedMethod(clazz.getMethod(name, parameterTypes)); 084 } 085 086 public AnnotatedMethod getDeclaredAnnotatedMethod(Method method) { 087 AnnotatedMethod am = methods.get(method); 088 return am != null && am.method.getDeclaringClass() == clazz ? am : null; 089 } 090 091 public boolean hasAnnotatedMethods() { 092 return !methods.isEmpty(); 093 } 094 095 public boolean isDeclaringAnnotatedMethods() { 096 if (methods.isEmpty()) { 097 return false; 098 } 099 for (AnnotatedMethod am : methods.values()) { 100 if (am.method.getDeclaringClass() == clazz) { 101 return true; 102 } 103 } 104 return false; 105 } 106 107 public AnnotatedMethod[] getAnnotatedMethods() { 108 return methods.values().toArray(new AnnotatedMethod[methods.size()]); 109 } 110 111 public AnnotatedMethod[] getDeclaredAnnotatedMethods() { 112 ArrayList<AnnotatedMethod> result = new ArrayList<AnnotatedMethod>(); 113 for (AnnotatedMethod am : methods.values()) { 114 if (am.method.getDeclaringClass() == clazz) { 115 result.add(am); 116 } 117 } 118 return result.toArray(new AnnotatedMethod[result.size()]); 119 } 120 121 // TODO: cache this? 122 public AnnotatedMethod[] getAnnotatedMethods(Class<? extends Annotation> annotationClass) { 123 ArrayList<AnnotatedMethod> result = new ArrayList<AnnotatedMethod>(); 124 for (AnnotatedMethod am : methods.values()) { 125 if (am.annotations.containsKey(annotationClass)) { 126 result.add(am); 127 } 128 } 129 return result.toArray(new AnnotatedMethod[result.size()]); 130 } 131 132 public AnnotatedMethod[] getDeclaredAnnotatedMethods(Class<? extends Annotation> annotationClass) { 133 ArrayList<AnnotatedMethod> result = new ArrayList<AnnotatedMethod>(); 134 for (AnnotatedMethod am : methods.values()) { 135 if (am.method.getDeclaringClass() == clazz && am.annotations.containsKey(annotationClass)) { 136 result.add(am); 137 } 138 } 139 return result.toArray(new AnnotatedMethod[result.size()]); 140 } 141 142 public void addMethod(AnnotatedMethod method) { 143 methods.put(method.method, method); 144 // TODO cache annotations to annotated method? 145 } 146 147 @Override 148 public int hashCode() { 149 return clazz.hashCode(); 150 } 151 152 @Override 153 public boolean equals(Object obj) { 154 if (obj == this) { 155 return true; 156 } 157 if (obj == null) { 158 return false; 159 } 160 if (obj.getClass() == AnnotatedClass.class) { 161 return ((AnnotatedClass<?>) obj).clazz == clazz; 162 } 163 return false; 164 } 165 166 @Override 167 public String toString() { 168 return "AnnotatedCass: " + clazz; 169 } 170 171}