KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > beans > factory > support > AutowireUtils


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.beans.factory.support;
18
19 import java.beans.PropertyDescriptor JavaDoc;
20 import java.lang.reflect.Constructor JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.lang.reflect.Modifier JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import java.util.Comparator JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Set JavaDoc;
27
28 import org.springframework.util.ClassUtils;
29
30 /**
31  * Utility class that contains various methods useful for
32  * the implementation of autowire-capable bean factories.
33  *
34  * @author Juergen Hoeller
35  * @since 1.1.2
36  * @see AbstractAutowireCapableBeanFactory
37  */

38 abstract class AutowireUtils {
39
40     /**
41      * Sort the given constructors, preferring public constructors and "greedy" ones
42      * with a maximum of arguments. The result will contain public constructors first,
43      * with decreasing number of arguments, then non-public constructors, again with
44      * decreasing number of arguments.
45      * @param constructors the constructor array to sort
46      */

47     public static void sortConstructors(Constructor JavaDoc[] constructors) {
48         Arrays.sort(constructors, new Comparator JavaDoc() {
49             public int compare(Object JavaDoc o1, Object JavaDoc o2) {
50                 Constructor JavaDoc c1 = (Constructor JavaDoc) o1;
51                 Constructor JavaDoc c2 = (Constructor JavaDoc) o2;
52                 boolean p1 = Modifier.isPublic(c1.getModifiers());
53                 boolean p2 = Modifier.isPublic(c2.getModifiers());
54                 if (p1 != p2) {
55                     return (p1 ? -1 : 1);
56                 }
57                 int c1pl = c1.getParameterTypes().length;
58                 int c2pl = c2.getParameterTypes().length;
59                 return (new Integer JavaDoc(c1pl)).compareTo(new Integer JavaDoc(c2pl)) * -1;
60             }
61         });
62     }
63
64     /**
65      * Determine a weight that represents the class hierarchy difference between types and
66      * arguments. A direct match, i.e. type Integer -> arg of class Integer, does not increase
67      * the result - all direct matches means weight 0. A match between type Object and arg of
68      * class Integer would increase the weight by 2, due to the superclass 2 steps up in the
69      * hierarchy (i.e. Object) being the last one that still matches the required type Object.
70      * Type Number and class Integer would increase the weight by 1 accordingly, due to the
71      * superclass 1 step up the hierarchy (i.e. Number) still matching the required type Number.
72      * Therefore, with an arg of type Integer, a constructor (Integer) would be preferred to a
73      * constructor (Number) which would in turn be preferred to a constructor (Object).
74      * All argument weights get accumulated.
75      * @param paramTypes the parameter types to match
76      * @param args the arguments to match
77      * @return the accumulated weight for all arguments
78      */

79     public static int getTypeDifferenceWeight(Class JavaDoc[] paramTypes, Object JavaDoc[] args) {
80         int result = 0;
81         for (int i = 0; i < paramTypes.length; i++) {
82             if (!ClassUtils.isAssignableValue(paramTypes[i], args[i])) {
83                 return Integer.MAX_VALUE;
84             }
85             if (args[i] != null) {
86                 Class JavaDoc superClass = args[i].getClass().getSuperclass();
87                 while (superClass != null) {
88                     if (ClassUtils.isAssignable(paramTypes[i], superClass)) {
89                         result++;
90                         superClass = superClass.getSuperclass();
91                     }
92                     else {
93                         superClass = null;
94                     }
95                 }
96             }
97         }
98         return result;
99     }
100
101     /**
102      * Determine whether the given bean property is excluded from dependency checks.
103      * <p>This implementation excludes properties defined by CGLIB.
104      * @param pd the PropertyDescriptor of the bean property
105      * @return whether the bean property is excluded
106      */

107     public static boolean isExcludedFromDependencyCheck(PropertyDescriptor JavaDoc pd) {
108         Method JavaDoc wm = pd.getWriteMethod();
109         if (wm == null) {
110             return false;
111         }
112         if (wm.getDeclaringClass().getName().indexOf("$$") == -1) {
113             // Not a CGLIB method so it's OK.
114
return false;
115         }
116         // It was declared by CGLIB, but we might still want to autowire it
117
// if it was actually declared by the superclass.
118
Class JavaDoc superclass = wm.getDeclaringClass().getSuperclass();
119         return !ClassUtils.hasMethod(superclass, wm.getName(), wm.getParameterTypes());
120     }
121
122     /**
123      * Return whether the setter method of the given bean property is defined
124      * in any of the given interfaces.
125      * @param pd the PropertyDescriptor of the bean property
126      * @param interfaces the Set of interfaces (Class objects)
127      * @return whether the setter method is defined by an interface
128      */

129     public static boolean isSetterDefinedInInterface(PropertyDescriptor JavaDoc pd, Set JavaDoc interfaces) {
130         Method JavaDoc setter = pd.getWriteMethod();
131         if (setter != null) {
132             Class JavaDoc targetClass = setter.getDeclaringClass();
133             for (Iterator JavaDoc it = interfaces.iterator(); it.hasNext();) {
134                 Class JavaDoc ifc = (Class JavaDoc) it.next();
135                 if (ifc.isAssignableFrom(targetClass) &&
136                         ClassUtils.hasMethod(ifc, setter.getName(), setter.getParameterTypes())) {
137                     return true;
138                 }
139             }
140         }
141         return false;
142     }
143
144 }
145
Popular Tags