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: */package org.apache.geronimo.jaxws.annotations;
017:
018: import org.apache.commons.logging.Log;
019: import org.apache.commons.logging.LogFactory;
020:
021: import javax.annotation.PostConstruct;
022: import javax.annotation.PreDestroy;
023: import java.lang.annotation.Annotation;
024: import java.lang.reflect.Field;
025: import java.lang.reflect.InvocationTargetException;
026: import java.lang.reflect.Method;
027: import java.util.Collection;
028: import java.util.HashMap;
029: import java.util.HashSet;
030: import java.util.Iterator;
031: import java.util.Map;
032:
033: public class AnnotationProcessor {
034:
035: private static final Log LOG = LogFactory
036: .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)
049: throws AnnotationException {
050: // process class annotations
051: Class clazz = instance.getClass();
052: Iterator iter = this .handlers.entrySet().iterator();
053: while (iter.hasNext()) {
054: Map.Entry entry = (Map.Entry) iter.next();
055: Class annotationType = (Class) entry.getKey();
056: AnnotationHandler handler = (AnnotationHandler) entry
057: .getValue();
058:
059: if (clazz.isAnnotationPresent(annotationType)) {
060: Annotation annotation = clazz
061: .getAnnotation(annotationType);
062: handler.processClassAnnotation(instance, clazz,
063: annotation);
064: }
065: }
066:
067: // process fields annotations
068: Field[] fields = clazz.getDeclaredFields();
069: for (int i = 0; i < fields.length; i++) {
070: iter = this .handlers.entrySet().iterator();
071: while (iter.hasNext()) {
072: Map.Entry entry = (Map.Entry) iter.next();
073: Class annotationType = (Class) entry.getKey();
074: AnnotationHandler handler = (AnnotationHandler) entry
075: .getValue();
076:
077: if (fields[i].isAnnotationPresent(annotationType)) {
078: Annotation annotation = fields[i]
079: .getAnnotation(annotationType);
080: handler.processFieldAnnotation(instance, fields[i],
081: annotation);
082: }
083: }
084: }
085:
086: // process method annotations
087: Method[] methods = clazz.getDeclaredMethods();
088: for (int i = 0; i < methods.length; i++) {
089: iter = this .handlers.entrySet().iterator();
090: while (iter.hasNext()) {
091: Map.Entry entry = (Map.Entry) iter.next();
092: Class annotationType = (Class) entry.getKey();
093: AnnotationHandler handler = (AnnotationHandler) entry
094: .getValue();
095:
096: if (methods[i].isAnnotationPresent(annotationType)) {
097: Annotation annotation = methods[i]
098: .getAnnotation(annotationType);
099: handler.processMethodAnnotation(instance,
100: methods[i], annotation);
101: }
102: }
103: }
104: }
105:
106: public void invokePostConstruct(Object instance) {
107: for (Method method : getMethods(instance.getClass(),
108: PostConstruct.class)) {
109: PostConstruct pc = method
110: .getAnnotation(PostConstruct.class);
111: if (pc != null) {
112: boolean accessible = method.isAccessible();
113: try {
114: method.setAccessible(true);
115: method.invoke(instance);
116: } catch (IllegalAccessException e) {
117: LOG.warn("@PostConstruct method is not visible: "
118: + method);
119: } catch (InvocationTargetException e) {
120: LOG
121: .warn(
122: "@PostConstruct method threw exception",
123: e);
124: } finally {
125: method.setAccessible(accessible);
126: }
127: }
128: }
129: }
130:
131: public void invokePreDestroy(Object instance) {
132: for (Method method : getMethods(instance.getClass(),
133: PreDestroy.class)) {
134: PreDestroy pc = method.getAnnotation(PreDestroy.class);
135: if (pc != null) {
136: boolean accessible = method.isAccessible();
137: try {
138: method.setAccessible(true);
139: method.invoke(instance);
140: } catch (IllegalAccessException e) {
141: LOG.warn("@PreDestroy method is not visible: "
142: + method);
143: } catch (InvocationTargetException e) {
144: LOG.warn("@PreDestroy method threw exception", e);
145: } finally {
146: method.setAccessible(accessible);
147: }
148: }
149: }
150: }
151:
152: private Collection<Method> getMethods(Class target,
153: Class<? extends Annotation> annotationType) {
154: Collection<Method> methods = new HashSet<Method>();
155: addMethods(target.getMethods(), annotationType, methods);
156: addMethods(target.getDeclaredMethods(), annotationType, methods);
157: return methods;
158: }
159:
160: private void addMethods(Method[] methods,
161: Class<? extends Annotation> annotationType,
162: Collection<Method> methodsCol) {
163: for (Method method : methods) {
164: if (method.isAnnotationPresent(annotationType)) {
165: methodsCol.add(method);
166: }
167: }
168: }
169:
170: }
|