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:
018: package org.apache.catalina.util;
019:
020: import java.lang.reflect.Field;
021: import java.lang.reflect.InvocationTargetException;
022: import java.lang.reflect.Method;
023: import java.lang.reflect.Modifier;
024:
025: import javax.annotation.PostConstruct;
026: import javax.annotation.PreDestroy;
027: import javax.annotation.Resource;
028: import javax.ejb.EJB;
029: import javax.naming.NamingException;
030: import javax.persistence.PersistenceContext;
031: import javax.persistence.PersistenceUnit;
032: import javax.xml.ws.WebServiceRef;
033:
034: import org.apache.AnnotationProcessor;
035:
036: /**
037: * Verify the annotation and Process it.
038: *
039: * @author Fabien Carrion
040: * @author Remy Maucherat
041: * @version $Revision: 467222 $, $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
042: */
043: public class DefaultAnnotationProcessor implements AnnotationProcessor {
044:
045: protected javax.naming.Context context = null;
046:
047: public DefaultAnnotationProcessor(javax.naming.Context context) {
048: this .context = context;
049: }
050:
051: /**
052: * Call postConstruct method on the specified instance.
053: */
054: public void postConstruct(Object instance)
055: throws IllegalAccessException, InvocationTargetException {
056:
057: Method[] methods = instance.getClass().getDeclaredMethods();
058: Method postConstruct = null;
059: for (int i = 0; i < methods.length; i++) {
060: if (methods[i].isAnnotationPresent(PostConstruct.class)) {
061: if ((postConstruct != null)
062: || (methods[i].getParameterTypes().length != 0)
063: || (Modifier
064: .isStatic(methods[i].getModifiers()))
065: || (methods[i].getExceptionTypes().length > 0)
066: || (!methods[i].getReturnType().getName()
067: .equals("void"))) {
068: throw new IllegalArgumentException(
069: "Invalid PostConstruct annotation");
070: }
071: postConstruct = methods[i];
072: }
073: }
074:
075: // At the end the postconstruct annotated
076: // method is invoked
077: if (postConstruct != null) {
078: boolean accessibility = postConstruct.isAccessible();
079: postConstruct.setAccessible(true);
080: postConstruct.invoke(instance);
081: postConstruct.setAccessible(accessibility);
082: }
083:
084: }
085:
086: /**
087: * Call preDestroy method on the specified instance.
088: */
089: public void preDestroy(Object instance)
090: throws IllegalAccessException, InvocationTargetException {
091:
092: Method[] methods = instance.getClass().getDeclaredMethods();
093: Method preDestroy = null;
094: for (int i = 0; i < methods.length; i++) {
095: if (methods[i].isAnnotationPresent(PreDestroy.class)) {
096: if ((preDestroy != null)
097: || (methods[i].getParameterTypes().length != 0)
098: || (Modifier
099: .isStatic(methods[i].getModifiers()))
100: || (methods[i].getExceptionTypes().length > 0)
101: || (!methods[i].getReturnType().getName()
102: .equals("void"))) {
103: throw new IllegalArgumentException(
104: "Invalid PreDestroy annotation");
105: }
106: preDestroy = methods[i];
107: }
108: }
109:
110: // At the end the postconstruct annotated
111: // method is invoked
112: if (preDestroy != null) {
113: boolean accessibility = preDestroy.isAccessible();
114: preDestroy.setAccessible(true);
115: preDestroy.invoke(instance);
116: preDestroy.setAccessible(accessibility);
117: }
118:
119: }
120:
121: /**
122: * Inject resources in specified instance.
123: */
124: public void processAnnotations(Object instance)
125: throws IllegalAccessException, InvocationTargetException,
126: NamingException {
127:
128: if (context == null) {
129: // No resource injection
130: return;
131: }
132:
133: // Initialize fields annotations
134: Field[] fields = instance.getClass().getDeclaredFields();
135: for (int i = 0; i < fields.length; i++) {
136: if (fields[i].isAnnotationPresent(Resource.class)) {
137: Resource annotation = (Resource) fields[i]
138: .getAnnotation(Resource.class);
139: lookupFieldResource(context, instance, fields[i],
140: annotation.name());
141: }
142: if (fields[i].isAnnotationPresent(EJB.class)) {
143: EJB annotation = (EJB) fields[i]
144: .getAnnotation(EJB.class);
145: lookupFieldResource(context, instance, fields[i],
146: annotation.name());
147: }
148: if (fields[i].isAnnotationPresent(WebServiceRef.class)) {
149: WebServiceRef annotation = (WebServiceRef) fields[i]
150: .getAnnotation(WebServiceRef.class);
151: lookupFieldResource(context, instance, fields[i],
152: annotation.name());
153: }
154: if (fields[i].isAnnotationPresent(PersistenceContext.class)) {
155: PersistenceContext annotation = (PersistenceContext) fields[i]
156: .getAnnotation(PersistenceContext.class);
157: lookupFieldResource(context, instance, fields[i],
158: annotation.name());
159: }
160: if (fields[i].isAnnotationPresent(PersistenceUnit.class)) {
161: PersistenceUnit annotation = (PersistenceUnit) fields[i]
162: .getAnnotation(PersistenceUnit.class);
163: lookupFieldResource(context, instance, fields[i],
164: annotation.name());
165: }
166: }
167:
168: // Initialize methods annotations
169: Method[] methods = instance.getClass().getDeclaredMethods();
170: for (int i = 0; i < methods.length; i++) {
171: if (methods[i].isAnnotationPresent(Resource.class)) {
172: Resource annotation = (Resource) methods[i]
173: .getAnnotation(Resource.class);
174: lookupMethodResource(context, instance, methods[i],
175: annotation.name());
176: }
177: if (methods[i].isAnnotationPresent(EJB.class)) {
178: EJB annotation = (EJB) methods[i]
179: .getAnnotation(EJB.class);
180: lookupMethodResource(context, instance, methods[i],
181: annotation.name());
182: }
183: if (methods[i].isAnnotationPresent(WebServiceRef.class)) {
184: WebServiceRef annotation = (WebServiceRef) methods[i]
185: .getAnnotation(WebServiceRef.class);
186: lookupMethodResource(context, instance, methods[i],
187: annotation.name());
188: }
189: if (methods[i]
190: .isAnnotationPresent(PersistenceContext.class)) {
191: PersistenceContext annotation = (PersistenceContext) methods[i]
192: .getAnnotation(PersistenceContext.class);
193: lookupMethodResource(context, instance, methods[i],
194: annotation.name());
195: }
196: if (methods[i].isAnnotationPresent(PersistenceUnit.class)) {
197: PersistenceUnit annotation = (PersistenceUnit) methods[i]
198: .getAnnotation(PersistenceUnit.class);
199: lookupMethodResource(context, instance, methods[i],
200: annotation.name());
201: }
202: }
203:
204: }
205:
206: /**
207: * Inject resources in specified field.
208: */
209: protected static void lookupFieldResource(
210: javax.naming.Context context, Object instance, Field field,
211: String name) throws NamingException, IllegalAccessException {
212:
213: Object lookedupResource = null;
214: boolean accessibility = false;
215:
216: if ((name != null) && (name.length() > 0)) {
217: lookedupResource = context.lookup(name);
218: } else {
219: lookedupResource = context.lookup(instance.getClass()
220: .getName()
221: + "/" + field.getName());
222: }
223:
224: accessibility = field.isAccessible();
225: field.setAccessible(true);
226: field.set(instance, lookedupResource);
227: field.setAccessible(accessibility);
228: }
229:
230: /**
231: * Inject resources in specified method.
232: */
233: protected static void lookupMethodResource(
234: javax.naming.Context context, Object instance,
235: Method method, String name) throws NamingException,
236: IllegalAccessException, InvocationTargetException {
237:
238: if (!method.getName().startsWith("set")
239: || method.getParameterTypes().length != 1
240: || !method.getReturnType().getName().equals("void")) {
241: throw new IllegalArgumentException(
242: "Invalid method resource injection annotation");
243: }
244:
245: Object lookedupResource = null;
246: boolean accessibility = false;
247:
248: if ((name != null) && (name.length() > 0)) {
249: lookedupResource = context.lookup(name);
250: } else {
251: lookedupResource = context.lookup(instance.getClass()
252: .getName()
253: + "/" + method.getName().substring(3));
254: }
255:
256: accessibility = method.isAccessible();
257: method.setAccessible(true);
258: method.invoke(instance, lookedupResource);
259: method.setAccessible(accessibility);
260: }
261:
262: }
|