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 }