1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.geronimo.jaxws.annotations; 18 19 import org.slf4j.Logger; 20 import org.slf4j.LoggerFactory; 21 22 import javax.annotation.PostConstruct; 23 import javax.annotation.PreDestroy; 24 import java.lang.annotation.Annotation; 25 import java.lang.reflect.Field; 26 import java.lang.reflect.InvocationTargetException; 27 import java.lang.reflect.Method; 28 import java.util.Collection; 29 import java.util.HashMap; 30 import java.util.HashSet; 31 import java.util.Iterator; 32 import java.util.Map; 33 34 public class AnnotationProcessor { 35 36 private static final Logger LOG = LoggerFactory.getLogger(AnnotationProcessor.class); 37 38 private Map<Class<? extends Annotation>, AnnotationHandler> handlers; 39 40 public AnnotationProcessor() { 41 this.handlers = new HashMap<Class<? extends Annotation>, AnnotationHandler>(); 42 } 43 44 public void registerHandler(AnnotationHandler handler) { 45 this.handlers.put(handler.getAnnotationType(), handler); 46 } 47 48 public void processAnnotations(Object instance) throws AnnotationException { 49 // process class annotations 50 Class clazz = instance.getClass(); 51 Iterator iter = this.handlers.entrySet().iterator(); 52 while (iter.hasNext()) { 53 Map.Entry entry = (Map.Entry) iter.next(); 54 Class annotationType = (Class) entry.getKey(); 55 AnnotationHandler handler = (AnnotationHandler) entry.getValue(); 56 57 if (clazz.isAnnotationPresent(annotationType)) { 58 Annotation annotation = clazz.getAnnotation(annotationType); 59 handler.processClassAnnotation(instance, clazz, annotation); 60 } 61 } 62 63 // process fields annotations 64 Field[] fields = clazz.getDeclaredFields(); 65 for (int i = 0; i < fields.length; i++) { 66 iter = this.handlers.entrySet().iterator(); 67 while (iter.hasNext()) { 68 Map.Entry entry = (Map.Entry) iter.next(); 69 Class annotationType = (Class) entry.getKey(); 70 AnnotationHandler handler = (AnnotationHandler) entry 71 .getValue(); 72 73 if (fields[i].isAnnotationPresent(annotationType)) { 74 Annotation annotation = fields[i] 75 .getAnnotation(annotationType); 76 handler.processFieldAnnotation(instance, fields[i], 77 annotation); 78 } 79 } 80 } 81 82 // process method annotations 83 Method[] methods = clazz.getDeclaredMethods(); 84 for (int i = 0; i < methods.length; i++) { 85 iter = this.handlers.entrySet().iterator(); 86 while (iter.hasNext()) { 87 Map.Entry entry = (Map.Entry) iter.next(); 88 Class annotationType = (Class) entry.getKey(); 89 AnnotationHandler handler = (AnnotationHandler) entry 90 .getValue(); 91 92 if (methods[i].isAnnotationPresent(annotationType)) { 93 Annotation annotation = methods[i] 94 .getAnnotation(annotationType); 95 handler.processMethodAnnotation(instance, methods[i], 96 annotation); 97 } 98 } 99 } 100 } 101 102 public void invokePostConstruct(Object instance) { 103 for (Method method : getMethods(instance.getClass(), 104 PostConstruct.class)) { 105 PostConstruct pc = method.getAnnotation(PostConstruct.class); 106 if (pc != null) { 107 boolean accessible = method.isAccessible(); 108 try { 109 method.setAccessible(true); 110 method.invoke(instance); 111 } catch (IllegalAccessException e) { 112 LOG.warn("@PostConstruct method is not visible: " + method); 113 } catch (InvocationTargetException e) { 114 LOG.warn("@PostConstruct method threw exception", e); 115 } finally { 116 method.setAccessible(accessible); 117 } 118 } 119 } 120 } 121 122 public void invokePreDestroy(Object instance) { 123 for (Method method : getMethods(instance.getClass(), PreDestroy.class)) { 124 PreDestroy pc = method.getAnnotation(PreDestroy.class); 125 if (pc != null) { 126 boolean accessible = method.isAccessible(); 127 try { 128 method.setAccessible(true); 129 method.invoke(instance); 130 } catch (IllegalAccessException e) { 131 LOG.warn("@PreDestroy method is not visible: " + method); 132 } catch (InvocationTargetException e) { 133 LOG.warn("@PreDestroy method threw exception", e); 134 } finally { 135 method.setAccessible(accessible); 136 } 137 } 138 } 139 } 140 141 private Collection<Method> getMethods(Class target, 142 Class<? extends Annotation> annotationType) { 143 Collection<Method> methods = new HashSet<Method>(); 144 addMethods(target.getMethods(), annotationType, methods); 145 addMethods(target.getDeclaredMethods(), annotationType, methods); 146 return methods; 147 } 148 149 private void addMethods(Method[] methods, 150 Class<? extends Annotation> annotationType, 151 Collection<Method> methodsCol) { 152 for (Method method : methods) { 153 if (method.isAnnotationPresent(annotationType)) { 154 methodsCol.add(method); 155 } 156 } 157 } 158 159 }