|
22 | 22 | import java.beans.IntrospectionException; |
23 | 23 | import java.beans.Introspector; |
24 | 24 | import java.beans.PropertyDescriptor; |
| 25 | +import java.lang.reflect.InvocationTargetException; |
| 26 | +import java.lang.reflect.Method; |
25 | 27 | import java.util.ArrayList; |
26 | 28 | import java.util.Arrays; |
27 | 29 | import java.util.Comparator; |
|
38 | 40 | import org.apache.cxf.aegis.type.AegisType; |
39 | 41 | import org.apache.cxf.aegis.type.TypeCreator; |
40 | 42 | import org.apache.cxf.aegis.type.TypeMapping; |
41 | | -import org.apache.cxf.common.util.ReflectionUtil; |
| 43 | +import org.apache.cxf.common.classloader.ClassLoaderUtils; |
42 | 44 |
|
43 | 45 | public class BeanTypeInfo { |
| 46 | + private static Method springBeanUtilsDescriptorFetcher; |
| 47 | + private static boolean springChecked; |
| 48 | + |
44 | 49 | private Map<QName, QName> mappedName2typeName = new HashMap<>(); |
45 | 50 | private Map<QName, String> mappedName2pdName = new HashMap<>(); |
46 | 51 | private Map<QName, AegisType> mappedName2type = new HashMap<>(); |
@@ -106,6 +111,61 @@ public void initialize() { |
106 | 111 | } |
107 | 112 | } |
108 | 113 |
|
| 114 | + /** |
| 115 | + * create own array of property descriptors to: |
| 116 | + * <pre> |
| 117 | + * - prevent memory leaks by Introspector's cache |
| 118 | + * - get correct type for generic properties from superclass |
| 119 | + * that are limited to a specific type in beanClass |
| 120 | + * see http://bugs.sun.com/view_bug.do?bug_id=6528714 |
| 121 | + * we cannot use BeanUtils.getPropertyDescriptors because of issue SPR-6063 |
| 122 | + * </pre> |
| 123 | + * @param refClass calling class for class loading. |
| 124 | + * @param beanInfo Bean in question |
| 125 | + * @param beanClass class for bean in question |
| 126 | + * @param propertyDescriptors raw descriptors |
| 127 | + */ |
| 128 | + public static PropertyDescriptor[] getPropertyDescriptorsAvoidSunBug(Class<?> refClass, |
| 129 | + BeanInfo beanInfo, |
| 130 | + Class<?> beanClass, |
| 131 | + PropertyDescriptor[] propertyDescriptors) { |
| 132 | + if (!springChecked) { |
| 133 | + try { |
| 134 | + springChecked = true; |
| 135 | + Class<?> cls = ClassLoaderUtils |
| 136 | + .loadClass("org.springframework.beans.BeanUtils", refClass); |
| 137 | + springBeanUtilsDescriptorFetcher |
| 138 | + = cls.getMethod("getPropertyDescriptor", Class.class, String.class); |
| 139 | + } catch (Exception e) { |
| 140 | + //ignore - just assume it's an unsupported/unknown annotation |
| 141 | + } |
| 142 | + } |
| 143 | + |
| 144 | + if (springBeanUtilsDescriptorFetcher != null) { |
| 145 | + if (propertyDescriptors != null) { |
| 146 | + List<PropertyDescriptor> descriptors = new ArrayList<>(propertyDescriptors.length); |
| 147 | + for (int i = 0; i < propertyDescriptors.length; i++) { |
| 148 | + PropertyDescriptor propertyDescriptor = propertyDescriptors[i]; |
| 149 | + try { |
| 150 | + propertyDescriptor = (PropertyDescriptor)springBeanUtilsDescriptorFetcher.invoke(null, |
| 151 | + beanClass, |
| 152 | + propertyDescriptor.getName()); |
| 153 | + if (propertyDescriptor != null) { |
| 154 | + descriptors.add(propertyDescriptor); |
| 155 | + } |
| 156 | + } catch (IllegalArgumentException | IllegalAccessException e) { |
| 157 | + throw new RuntimeException(e); |
| 158 | + } catch (InvocationTargetException e) { |
| 159 | + throw new RuntimeException(e.getCause()); |
| 160 | + } |
| 161 | + } |
| 162 | + return descriptors.toArray(new PropertyDescriptor[0]); |
| 163 | + } |
| 164 | + return null; |
| 165 | + } |
| 166 | + return beanInfo.getPropertyDescriptors(); |
| 167 | + } |
| 168 | + |
109 | 169 | private synchronized void initializeSync() { |
110 | 170 | if (!initialized) { |
111 | 171 | for (int i = 0; i < descriptors.length; i++) { |
@@ -285,10 +345,10 @@ private void initializeProperties() { |
285 | 345 | PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); |
286 | 346 | if (propertyDescriptors != null) { |
287 | 347 | // see comments on this function. |
288 | | - descriptors = ReflectionUtil.getPropertyDescriptorsAvoidSunBug(getClass(), |
289 | | - beanInfo, |
290 | | - beanClass, |
291 | | - propertyDescriptors); |
| 348 | + descriptors = getPropertyDescriptorsAvoidSunBug(getClass(), |
| 349 | + beanInfo, |
| 350 | + beanClass, |
| 351 | + propertyDescriptors); |
292 | 352 | } |
293 | 353 | } |
294 | 354 |
|
|
0 commit comments