001: package org.apache.myfaces.config.annotation;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import javax.naming.NamingException;
021: import javax.naming.Context;
022: import javax.annotation.Resource;
023: import java.lang.reflect.Method;
024: import java.lang.reflect.InvocationTargetException;
025: import java.lang.reflect.Field;
026:
027: // TODO @Resources
028: public class ResourceAnnotationLifecycleProvider extends
029: NoInjectionAnnotationLifecycleProvider {
030:
031: protected Context context;
032: private static final String JAVA_COMP_ENV = "java:comp/env/";
033:
034: public ResourceAnnotationLifecycleProvider(Context context) {
035: this .context = context;
036: }
037:
038: /**
039: * Inject resources in specified instance.
040: */
041: protected void processAnnotations(Object instance)
042: throws IllegalAccessException, InvocationTargetException,
043: NamingException {
044:
045: if (context == null) {
046: // No resource injection
047: return;
048: }
049:
050: checkAnnotation(instance.getClass(), instance);
051:
052: /* TODO the servlet spec is not clear about searching in superclass??
053: * May be only check non private fields and methods
054: * for @Resource (JSR 250), if used all superclasses MUST be examined
055: * to discover all uses of this annotation.
056:
057: Class superclass = instance.getClass().getSuperclass();
058: while (superclass != null && (!superclass.equals(Object.class)))
059: {
060: checkAnnotation(superclass, instance);
061: superclass = superclass.getSuperclass();
062: } */
063: }
064:
065: private void checkAnnotation(Class clazz, Object instance)
066: throws NamingException, IllegalAccessException,
067: InvocationTargetException {
068: // Initialize fields annotations
069: Field[] fields = clazz.getDeclaredFields();
070: for (Field field : fields) {
071: checkFieldAnnotation(field, instance);
072: }
073:
074: // Initialize methods annotations
075: Method[] methods = clazz.getDeclaredMethods();
076: for (Method method : methods) {
077: checkMethodAnnotation(method, instance);
078: }
079: }
080:
081: protected void checkMethodAnnotation(Method method, Object instance)
082: throws NamingException, IllegalAccessException,
083: InvocationTargetException {
084: if (method.isAnnotationPresent(Resource.class)) {
085: Resource annotation = method.getAnnotation(Resource.class);
086: lookupMethodResource(context, instance, method, annotation
087: .name());
088: }
089: }
090:
091: protected void checkFieldAnnotation(Field field, Object instance)
092: throws NamingException, IllegalAccessException {
093: if (field.isAnnotationPresent(Resource.class)) {
094: Resource annotation = field.getAnnotation(Resource.class);
095: lookupFieldResource(context, instance, field, annotation
096: .name());
097: }
098: }
099:
100: /**
101: * Inject resources in specified field.
102: */
103: protected static void lookupFieldResource(
104: javax.naming.Context context, Object instance, Field field,
105: String name) throws NamingException, IllegalAccessException {
106:
107: Object lookedupResource;
108:
109: if ((name != null) && (name.length() > 0)) {
110: // TODO local or global JNDI
111: lookedupResource = context.lookup(JAVA_COMP_ENV + name);
112: } else {
113: // TODO local or global JNDI
114: lookedupResource = context.lookup(JAVA_COMP_ENV
115: + instance.getClass().getName() + "/"
116: + field.getName());
117: }
118:
119: boolean accessibility = field.isAccessible();
120: field.setAccessible(true);
121: field.set(instance, lookedupResource);
122: field.setAccessible(accessibility);
123: }
124:
125: /**
126: * Inject resources in specified method.
127: */
128: protected static void lookupMethodResource(
129: javax.naming.Context context, Object instance,
130: Method method, String name) throws NamingException,
131: IllegalAccessException, InvocationTargetException {
132:
133: if (!method.getName().startsWith("set")
134: || method.getParameterTypes().length != 1
135: || !method.getReturnType().getName().equals("void")) {
136: throw new IllegalArgumentException(
137: "Invalid method resource injection annotation");
138: }
139:
140: Object lookedupResource;
141:
142: if ((name != null) && (name.length() > 0)) {
143: // TODO local or global JNDI
144: lookedupResource = context.lookup(JAVA_COMP_ENV + name);
145: } else {
146: // TODO local or global JNDI
147: lookedupResource = context.lookup(JAVA_COMP_ENV
148: + instance.getClass().getName() + "/"
149: + method.getName().substring(3));
150: }
151:
152: boolean accessibility = method.isAccessible();
153: method.setAccessible(true);
154: method.invoke(instance, lookedupResource);
155: method.setAccessible(accessibility);
156: }
157: }
|