001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.jaxws.annotations; 018 019 import org.apache.commons.logging.Log; 020 import org.apache.commons.logging.LogFactory; 021 022 import javax.annotation.PostConstruct; 023 import javax.annotation.PreDestroy; 024 import java.lang.annotation.Annotation; 025 import java.lang.reflect.Field; 026 import java.lang.reflect.InvocationTargetException; 027 import java.lang.reflect.Method; 028 import java.util.Collection; 029 import java.util.HashMap; 030 import java.util.HashSet; 031 import java.util.Iterator; 032 import java.util.Map; 033 034 public class AnnotationProcessor { 035 036 private static final Log LOG = LogFactory.getLog(AnnotationProcessor.class); 037 038 private Map<Class<? extends Annotation>, AnnotationHandler> handlers; 039 040 public AnnotationProcessor() { 041 this.handlers = new HashMap<Class<? extends Annotation>, AnnotationHandler>(); 042 } 043 044 public void registerHandler(AnnotationHandler handler) { 045 this.handlers.put(handler.getAnnotationType(), handler); 046 } 047 048 public void processAnnotations(Object instance) throws AnnotationException { 049 // process class annotations 050 Class clazz = instance.getClass(); 051 Iterator iter = this.handlers.entrySet().iterator(); 052 while (iter.hasNext()) { 053 Map.Entry entry = (Map.Entry) iter.next(); 054 Class annotationType = (Class) entry.getKey(); 055 AnnotationHandler handler = (AnnotationHandler) entry.getValue(); 056 057 if (clazz.isAnnotationPresent(annotationType)) { 058 Annotation annotation = clazz.getAnnotation(annotationType); 059 handler.processClassAnnotation(instance, clazz, annotation); 060 } 061 } 062 063 // process fields annotations 064 Field[] fields = clazz.getDeclaredFields(); 065 for (int i = 0; i < fields.length; i++) { 066 iter = this.handlers.entrySet().iterator(); 067 while (iter.hasNext()) { 068 Map.Entry entry = (Map.Entry) iter.next(); 069 Class annotationType = (Class) entry.getKey(); 070 AnnotationHandler handler = (AnnotationHandler) entry 071 .getValue(); 072 073 if (fields[i].isAnnotationPresent(annotationType)) { 074 Annotation annotation = fields[i] 075 .getAnnotation(annotationType); 076 handler.processFieldAnnotation(instance, fields[i], 077 annotation); 078 } 079 } 080 } 081 082 // process method annotations 083 Method[] methods = clazz.getDeclaredMethods(); 084 for (int i = 0; i < methods.length; i++) { 085 iter = this.handlers.entrySet().iterator(); 086 while (iter.hasNext()) { 087 Map.Entry entry = (Map.Entry) iter.next(); 088 Class annotationType = (Class) entry.getKey(); 089 AnnotationHandler handler = (AnnotationHandler) entry 090 .getValue(); 091 092 if (methods[i].isAnnotationPresent(annotationType)) { 093 Annotation annotation = methods[i] 094 .getAnnotation(annotationType); 095 handler.processMethodAnnotation(instance, methods[i], 096 annotation); 097 } 098 } 099 } 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 }