You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by to...@apache.org on 2007/07/18 06:01:21 UTC
svn commit: r557137 - in /harmony/enhanced/classlib/trunk/modules/beans/src:
main/java/java/beans/ test/java/org/apache/harmony/beans/tests/java/beans/
Author: tonywu
Date: Tue Jul 17 21:01:20 2007
New Revision: 557137
URL: http://svn.apache.org/viewvc?view=rev&rev=557137
Log:
refactor Introspector, make it easier to understand
1, correct some testcases
2, combine BeanInfoData and BeanInfoWrapper to one class
3, add method merge() in FeatureDescripter and its sub classes
Modified:
harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/EventSetDescriptor.java
harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/FeatureDescriptor.java
harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Introspector.java
harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/MethodDescriptor.java
harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/PropertyDescriptor.java
harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
Modified: harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/EventSetDescriptor.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/EventSetDescriptor.java?view=diff&rev=557137&r1=557136&r2=557137
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/EventSetDescriptor.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/EventSetDescriptor.java Tue Jul 17 21:01:20 2007
@@ -436,46 +436,27 @@
return false;
}
+ void merge(EventSetDescriptor event) {
+ super.merge(event);
+ if (addListenerMethod == null) {
+ addListenerMethod = event.addListenerMethod;
+ }
+ if (getListenerMethod == null) {
+ getListenerMethod = event.getListenerMethod;
+ }
+ if (listenerMethodDescriptors == null) {
+ listenerMethodDescriptors = event.listenerMethodDescriptors;
+ }
+ if (listenerMethods == null) {
+ listenerMethods = event.listenerMethods;
+ }
+ if (listenerType == null) {
+ listenerType = event.listenerType;
+ }
-//TODO investigate, do we need the following code?
-
-// private static Method checkRegistrationMethod(Class<?> listenerType,
-// Method registrationMethod) throws IntrospectionException {
-// if (registrationMethod == null) {
-// return null;
-// }
-// Class<?> returnType = registrationMethod.getReturnType();
-// Class<?>[] parameterTypes;
-// if (returnType != void.class) {
-// throw new IntrospectionException(Messages.getString(
-// "beans.33", registrationMethod.getName())); //$NON-NLS-1$
-// }
-// parameterTypes = registrationMethod.getParameterTypes();
-// if (parameterTypes == null || parameterTypes.length != 1) {
-// throw new IntrospectionException(Messages.getString(
-// "beans.34", registrationMethod.getName())); //$NON-NLS-1$
-// } else if (parameterTypes[0] != listenerType) {
-// throw new IntrospectionException(Messages.getString(
-// "beans.35", listenerType.getName())); //$NON-NLS-1$
-// } else {
-// return registrationMethod;
-// }
-// }
-
-// private static Method checkGetListenerMethod(Class<?> listenerType, Method getListenerMethod)
-// throws IntrospectionException {
-// if (getListenerMethod == null) {
-// return null;
-// }
-// Class<?>[] parameterTypes = getListenerMethod.getParameterTypes();
-// Class<?> returnType;
-// if (parameterTypes.length != 0) {
-// throw new IntrospectionException(Messages.getString("beans.36")); //$NON-NLS-1$
-// }
-// returnType = getListenerMethod.getReturnType();
-// if (returnType.isArray() && returnType.getComponentType() == listenerType) {
-// return getListenerMethod;
-// }
-// throw new IntrospectionException(Messages.getString("beans.37")); //$NON-NLS-1$
-// }
+ if (removeListenerMethod == null) {
+ removeListenerMethod = event.removeListenerMethod;
+ }
+ inDefaultEventSet &= event.inDefaultEventSet;
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/FeatureDescriptor.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/FeatureDescriptor.java?view=diff&rev=557137&r1=557136&r2=557137
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/FeatureDescriptor.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/FeatureDescriptor.java Tue Jul 17 21:01:20 2007
@@ -231,4 +231,20 @@
public boolean isExpert() {
return expert;
}
+
+ void merge(FeatureDescriptor feature){
+ assert(name.equals(feature.name));
+ expert |= feature.expert;
+ hidden |= feature.hidden;
+ preferred |= feature.preferred;
+ if(shortDescription == null){
+ shortDescription = feature.shortDescription;
+ }
+ if(name == null){
+ name = feature.name;
+ }
+ if(displayName == null){
+ displayName = feature.displayName;
+ }
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Introspector.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Introspector.java?view=diff&rev=557137&r1=557136&r2=557137
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Introspector.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Introspector.java Tue Jul 17 21:01:20 2007
@@ -17,246 +17,329 @@
package java.beans;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
+import java.util.Collections;
import java.util.Map;
+import java.util.WeakHashMap;
-import org.apache.harmony.beans.internal.nls.Messages;
-
+/**
+ * The <code>Introspector</code> is a utility for developers to figure out
+ * which properties, events, and methods a JavaBean supports.
+ * <p>
+ * The <code>Introspector</code> class walks over the class/superclass chain
+ * of the target bean class. At each level it checks if there is a matching
+ * <code>BeanInfo</code> class which provides explicit information about the
+ * bean, and if so uses that explicit information. Otherwise it uses the low
+ * level reflection APIs to study the target class and uses design patterns to
+ * analyze its behaviour and then proceeds to continue the introspection with
+ * its baseclass.
+ * </p>
+ * <p>
+ * To look for the explicit information of a bean:
+ * </p>
+ * <ol>
+ * <li>The <code>Introspector</code> appends "BeanInfo" to the qualified name
+ * of the bean class, try to use the new class as the "BeanInfo" class. If the
+ * "BeanInfo" class exsits and returns non-null value when queried for explicit
+ * information, use the explicit information</li>
+ * <li>If the first step fails, the <code>Introspector</code> will extract a
+ * simple class name of the bean class by removing the package name from the
+ * qualified name of the bean class, append "BeanInfo" to it. And look for the
+ * simple class name in the packages defined in the "BeanInfo" search path (The
+ * default "BeanInfo" search path is <code>sun.beans.infos</code>). If it
+ * finds a "BeanInfo" class and the "BeanInfo" class returns non-null value when
+ * queried for explicit information, use the explicit information</li>
+ * </ol>
+ *
+ */
+//ScrollPane cannot be introspected correctly
+public class Introspector extends java.lang.Object {
+
+ // Public fields
+ /**
+ * Constant values to indicate that the <code>Introspector</code> will
+ * ignore all <code>BeanInfo</code> class.
+ */
+ public static final int IGNORE_ALL_BEANINFO = 3;
-public class Introspector {
+ /**
+ * Constant values to indicate that the <code>Introspector</code> will
+ * ignore the <code>BeanInfo</code> class of the current bean class.
+ */
+ public static final int IGNORE_IMMEDIATE_BEANINFO = 2;
+ /**
+ * Constant values to indicate that the <code>Introspector</code> will use
+ * all <code>BeanInfo</code> class which have been found. This is the default one.
+ */
public static final int USE_ALL_BEANINFO = 1;
- public static final int IGNORE_IMMEDIATE_BEANINFO = 2;
+ // Default search path for BeanInfo classes
+ private static final String DEFAULT_BEANINFO_SEARCHPATH = "sun.beans.infos"; //$NON-NLS-1$
- public static final int IGNORE_ALL_BEANINFO = 3;
+ // The search path to use to find BeanInfo classes
+ // - an array of package names that are used in turn
+ private static String[] searchPath = { DEFAULT_BEANINFO_SEARCHPATH };
+
+ // The cache to store Bean Info objects that have been found or created
+ private static final int DEFAULT_CAPACITY = 128;
+
+ private static Map<Class, StandardBeanInfo> theCache = Collections.synchronizedMap(new WeakHashMap<Class, StandardBeanInfo>(DEFAULT_CAPACITY));
private Introspector() {
+ super();
}
+ /**
+ * Decapitalizes a given string according to the rule:
+ * <ul>
+ * <li>If the first or only character is Upper Case, it is made Lower Case
+ * <li>UNLESS the second character is also Upper Case, when the String is
+ * returned unchanged <eul>
+ *
+ * @param name -
+ * the String to decapitalize
+ * @return the decapitalized version of the String
+ */
public static String decapitalize(String name) {
- if ((name != null) && (name.length() > 0)) {
- String result;
-
- // first two letters are capital
- if ((name.length() > 1)
- && Character.isUpperCase(name.charAt(0))
- && Character.isUpperCase(name.charAt(1))) {
- return name;
- }
-
- result = name.substring(0, 1).toLowerCase();
- if (name.length() > 1) {
- result += name.substring(1);
- }
-
- return result;
- }
- return name;
- }
- public static BeanInfo getBeanInfo(Class<?> beanClass, int flags)
- throws IntrospectionException {
- switch (flags) {
- case USE_ALL_BEANINFO:
- return getBeanInfo(beanClass, null, false, false);
- case IGNORE_IMMEDIATE_BEANINFO:
- return getBeanInfo(beanClass, null, true, false);
- case IGNORE_ALL_BEANINFO:
- return getBeanInfo(beanClass, null, true, true);
- default:
- // TODO: verify that default behavior complies with RI
- return getBeanInfo(beanClass, null, false, false);
+ if (name == null)
+ return null;
+ // The rule for decapitalize is that:
+ // If the first letter of the string is Upper Case, make it lower case
+ // UNLESS the second letter of the string is also Upper Case, in which case no
+ // changes are made.
+ if (name.length() == 0 || (name.length() > 1 && Character.isUpperCase(name.charAt(1)))) {
+ return name;
}
+
+ char[] chars = name.toCharArray();
+ chars[0] = Character.toLowerCase(chars[0]);
+ return new String(chars);
}
- public static BeanInfo getBeanInfo(Class<?> beanClass)
+ /**
+ * Flushes all <code>BeanInfo</code> caches.
+ *
+ */
+ public static void flushCaches() {
+ // Flush the cache by throwing away the cache HashMap and creating a
+ // new empty one
+ theCache.clear();
+ }
+
+ /**
+ * Flushes the <code>BeanInfo</code> caches of the specified bean class
+ *
+ * @param clazz
+ * the specified bean class
+ */
+ public static void flushFromCaches(Class clazz) {
+ if(clazz == null){
+ throw new NullPointerException();
+ }
+ theCache.remove(clazz);
+ }
+
+ /**
+ * Gets the <code>BeanInfo</code> object which contains the information of
+ * the properties, events and methods of the specified bean class.
+ *
+ * <p>
+ * The <code>Introspector</code> will cache the <code>BeanInfo</code>
+ * object. Subsequent calls to this method will be answered with the cached
+ * data.
+ * </p>
+ *
+ * @param beanClass
+ * the specified bean class.
+ * @return the <code>BeanInfo</code> of the bean class.
+ * @throws IntrospectionException
+ */
+ public static BeanInfo getBeanInfo(Class beanClass)
throws IntrospectionException {
- return getBeanInfo(beanClass, null, false, false);
- }
-
- public static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass)
+ StandardBeanInfo beanInfo = theCache.get(beanClass);
+ if (beanInfo == null) {
+ beanInfo = getBeanInfoImpl(beanClass, null, USE_ALL_BEANINFO);
+ theCache.put(beanClass, beanInfo);
+ }
+ return beanInfo;
+ }
+
+ /**
+ * Gets the <code>BeanInfo</code> object which contains the information of
+ * the properties, events and methods of the specified bean class. It will
+ * not introspect the "stopclass" and its super class.
+ *
+ * <p>
+ * The <code>Introspector</code> will cache the <code>BeanInfo</code>
+ * object. Subsequent calls to this method will be answered with the cached
+ * data.
+ * </p>
+ *
+ * @param beanClass
+ * the specified beanClass.
+ * @param stopClass
+ * the sopt class which should be super class of the bean class.
+ * May be null.
+ * @return the <code>BeanInfo</code> of the bean class.
+ * @throws IntrospectionException
+ */
+ public static BeanInfo getBeanInfo(Class beanClass, Class stopClass)
throws IntrospectionException {
- return getBeanInfo(beanClass, stopClass, false, false);
- }
-
- public static void setBeanInfoSearchPath(String[] searchPath) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- sm.checkPropertiesAccess();
- }
- synchronized(Introspector.class) {
- path = searchPath;
+ if(stopClass == null){
+ //try to use cache
+ return getBeanInfo(beanClass);
+ }
+ return getBeanInfoImpl(beanClass, stopClass, USE_ALL_BEANINFO);
+ }
+
+ /**
+ * Gets the <code>BeanInfo</code> object which contains the information of
+ * the properties, events and methods of the specified bean class.
+ * <ol>
+ * <li>If <code>flag==IGNORE_ALL_BEANINFO</code>, the
+ * <code>Introspector</code> will ignore all <code>BeanInfo</code>
+ * class.</li>
+ * <li>If <code>flag==IGNORE_IMMEDIATE_BEANINFO</code>, the
+ * <code>Introspector</code> will ignore the <code>BeanInfo</code> class
+ * of the current bean class.</li>
+ * <li>If <code>flag==USE_ALL_BEANINFO</code>, the
+ * <code>Introspector</code> will use all <code>BeanInfo</code> class
+ * which have been found.</li>
+ * </ol>
+ * <p>
+ * The <code>Introspector</code> will cache the <code>BeanInfo</code>
+ * object. Subsequent calls to this method will be answered with the cached
+ * data.
+ * </p>
+ *
+ * @param beanClass
+ * the specified bean class.
+ * @param flags
+ * the flag to control the usage of the explicit
+ * <code>BeanInfo</code> class.
+ * @return the <code>BeanInfo</code> of the bean class.
+ * @throws IntrospectionException
+ */
+ public static BeanInfo getBeanInfo(Class beanClass, int flags)
+ throws IntrospectionException {
+ if(flags == USE_ALL_BEANINFO){
+ //try to use cache
+ return getBeanInfo(beanClass);
+ }
+ return getBeanInfoImpl(beanClass, null, flags);
+ }
+
+ /**
+ * Gets an array of search packages.
+ *
+ * @return an array of search packages.
+ */
+ public static String[] getBeanInfoSearchPath() {
+ String[] path = new String[searchPath.length];
+ System.arraycopy(searchPath, 0, path, 0, searchPath.length);
+ return path;
+ }
+
+ /**
+ * Sets the search packages.
+ *
+ * @param path the new search packages to be set.
+ */
+ public static void setBeanInfoSearchPath(String[] path) {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().checkPropertiesAccess();
+ }
+ searchPath = path;
+ }
+
+ private static StandardBeanInfo getBeanInfoImpl(Class beanClass, Class stopClass,
+ int flags) throws IntrospectionException {
+ BeanInfo explicitInfo = null;
+ if (flags == USE_ALL_BEANINFO) {
+ explicitInfo = getExplicitBeanInfo(beanClass);
+ }
+ StandardBeanInfo beanInfo = new StandardBeanInfo(beanClass, explicitInfo);
+
+ // recursive get beaninfo for super classes
+ Class beanSuperClass = beanClass.getSuperclass();
+ if (beanSuperClass != stopClass) {
+ if (beanSuperClass == null)
+ throw new IntrospectionException(
+ "Stop class is not super class of bean class");
+ int superflags = flags == IGNORE_IMMEDIATE_BEANINFO ? USE_ALL_BEANINFO
+ : flags;
+ BeanInfo superBeanInfo = getBeanInfoImpl(beanSuperClass, stopClass,
+ superflags);
+ if (superBeanInfo != null) {
+ beanInfo.mergeBeanInfo(superBeanInfo);
+ }
}
- }
-
- public static synchronized String[] getBeanInfoSearchPath() {
- // compatible with RI
- if (path == null) {
- throw new NullPointerException(
- Messages.getString("beans.4F")); //$NON-NLS-1$
+ if (beanInfo.additionalBeanInfo != null) {
+ for (BeanInfo info : beanInfo.additionalBeanInfo) {
+ beanInfo.mergeBeanInfo(info, true);
+ }
}
-
- return path.clone();
+ return beanInfo;
}
- public static void flushFromCaches(Class<?> clz) {
- removeBeanInfoClassFromCache(clz);
- }
-
- public static void flushCaches() {
- removeAllBeanInfoClassesFromCache();
- }
-
- // private methods
-
- private static BeanInfoWrapper getBeanInfo(Class<?> beanClass,
- Class<?> stopClass, boolean ignoreBeanClassBeanInfo,
- boolean ignoreSuperClassBeanInfo) throws IntrospectionException {
- BeanInfoWrapper beanInfoWrapper;
- BeanInfo beanInfo;
- BeanInfoImpl beanInfoImpl;
- BeanInfoWrapper wrapper;
- Class<?> parent;
-
- if (beanClass == null) {
- throw new java.lang.NullPointerException();
- }
-
- if (stopClass != null && !stopClass.isAssignableFrom(beanClass)) {
- throw new IntrospectionException(
- Messages.getString("beans.4E")); //$NON-NLS-1$
- }
-
- beanInfoWrapper = findBeanInfoClassInCache(beanClass,
- stopClass, ignoreBeanClassBeanInfo, ignoreSuperClassBeanInfo);
-
- if (beanInfoWrapper != null) {
- return beanInfoWrapper;
- }
-
- // find bean info as a separate class
-
- beanInfo = null;
-
- if (!ignoreBeanClassBeanInfo) {
- try {
- Class<?> beanInfoClass = findBeanInfoClass(beanClass);
-
- if (beanInfoClass != null) {
- beanInfo = (BeanInfo) beanInfoClass.newInstance();
- }
- } catch (Exception e) {
+ private static BeanInfo getExplicitBeanInfo(Class beanClass) {
+ BeanInfo theBeanInfo = null;
+ String beanInfoClassName = beanClass.getName() + "BeanInfo"; //$NON-NLS-1$
+ try{
+ theBeanInfo = loadBeanInfo(beanInfoClassName, beanClass);
+ return theBeanInfo;
+ }catch(Exception e){
+ //fall through
+ }
+ int index = beanInfoClassName.lastIndexOf('.');
+ String beanInfoName = index>=0? beanInfoClassName.substring(index):beanInfoClassName;
+ for (int i = 0; i < searchPath.length; i++) {
+ beanInfoClassName = searchPath[i] + "." + beanInfoName;
+ try{
+ theBeanInfo = loadBeanInfo(beanInfoClassName, beanClass);
+ break;
+ }catch(Exception e){
+ //ignore, try next one
}
}
-
- // ...
-
- // generate bean info automatically
-
- beanInfoImpl = new BeanInfoImpl(beanClass);
-
- // ...
-
- wrapper = new BeanInfoWrapper(beanInfo, beanInfoImpl);
- parent = beanClass.getSuperclass();
-
- if (parent != null && parent != stopClass) {
- BeanInfoWrapper parentBeanInfo = getBeanInfo(parent, stopClass,
- ignoreSuperClassBeanInfo, ignoreSuperClassBeanInfo);
-
- wrapper.setParentToMerge(parentBeanInfo);
- }
-
- // ...
-
- storeBeanInfoClassInCache(wrapper, beanClass, stopClass,
- ignoreBeanClassBeanInfo, ignoreSuperClassBeanInfo);
-
- return wrapper;
+ return theBeanInfo;
}
- private static Class<?> findBeanInfoClass(Class<?> beanClass) {
- String beanClassName = beanClass.getName();
- int idx = beanClassName.lastIndexOf("."); //$NON-NLS-1$
- String shortBeanInfoClassName = beanClassName.substring(idx + 1,
- beanClassName.length())
- + "BeanInfo"; //$NON-NLS-1$
- String fullBeanInfoClassName = beanClassName + "BeanInfo"; //$NON-NLS-1$
- Class<?> beanInfoClass = null;
+ /*
+ * Method which attempts to instantiate a BeanInfo object of the supplied
+ * classname
+ *
+ * @param theBeanInfoClassName -
+ * the Class Name of the class of which the BeanInfo is an
+ * instance
+ * @param classLoader
+ * @return A BeanInfo object which is an instance of the Class named
+ * theBeanInfoClassName null if the Class does not exist or if there
+ * are problems instantiating the instance
+ */
+ private static BeanInfo loadBeanInfo(String beanInfoClassName,
+ Class beanClass) throws Exception{
try {
- beanInfoClass = Class.forName(fullBeanInfoClassName, true,
- beanClass.getClassLoader());
-
- } catch (ClassNotFoundException cnfe) {
- for (String element : path) {
- try {
- fullBeanInfoClassName = element + "." //$NON-NLS-1$
- + shortBeanInfoClassName;
- beanInfoClass = Class.forName(fullBeanInfoClassName, true,
- beanClass.getClassLoader());
- break;
- } catch (ClassNotFoundException cnfe2) {
- }
- }
+ return (BeanInfo) Class.forName(beanInfoClassName, true,
+ beanClass.getClassLoader()).newInstance();
+ } catch (Exception e) {
+ // fall through
}
-
- return beanInfoClass;
- }
-
- private static BeanInfoWrapper findBeanInfoClassInCache(Class<?> beanClass,
- Class<?> stopClass, boolean ignoreBeanClassBeanInfo,
- boolean ignoreSuperClassBeanInfo) {
- BeanInfoWrapper result = null;
- List<BeanInfoData> beanInfoDatas = beanInfos.get(beanClass.getName());
- if (beanInfoDatas != null) {
- Iterator<BeanInfoData> iterator = beanInfoDatas.iterator();
- while (iterator.hasNext()) {
- BeanInfoData beanInfoData = iterator.next();
- if ((beanInfoData.getStopClass() == stopClass)
- && (beanInfoData.getIgnoreBeanClassBeanInfo() == ignoreBeanClassBeanInfo)
- && (beanInfoData.getIgnoreSuperClassBeanInfo() == ignoreSuperClassBeanInfo)) {
- result = beanInfoData.getBeanInfoWrapper();
- }
- if (result != null) {
- break;
- }
- }
- }
- return result;
- }
-
- private static void storeBeanInfoClassInCache(
- BeanInfoWrapper beanInfoWrapper, Class<?> beanClass,
- Class<?> stopClass, boolean ignoreBeanClassBeanInfo,
- boolean ignoreSuperClassBeanInfo) {
- List<BeanInfoData> beanInfoDatas = beanInfos.get(beanClass.getName());
- if (beanInfoDatas == null) {
- beanInfoDatas = new ArrayList<BeanInfoData>();
- beanInfos.put(beanClass.getName(), beanInfoDatas);
+ try {
+ return (BeanInfo) Class.forName(beanInfoClassName, true,
+ ClassLoader.getSystemClassLoader()).newInstance();
+ } catch (Exception e) {
+ // fall through
}
- beanInfoDatas.add(new BeanInfoData(stopClass, ignoreBeanClassBeanInfo,
- ignoreSuperClassBeanInfo, beanInfoWrapper));
- }
-
- private static void removeBeanInfoClassFromCache(Class<?> beanClass) {
- beanInfos.remove(beanClass.getName());
+ return (BeanInfo) Class.forName(beanInfoClassName, true,
+ Thread.currentThread().getContextClassLoader()).newInstance();
}
+
+
- private static void removeAllBeanInfoClassesFromCache() {
- beanInfos.clear();
- }
-
- // private fields
+}
- private static String[] path = { "org.apache.harmony.beans.infos" }; //$NON-NLS-1$
- private static final Map<String, List<BeanInfoData>> beanInfos =
- new HashMap<String, List<BeanInfoData>>();
-}
Modified: harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/MethodDescriptor.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/MethodDescriptor.java?view=diff&rev=557137&r1=557136&r2=557137
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/MethodDescriptor.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/MethodDescriptor.java Tue Jul 17 21:01:20 2007
@@ -96,4 +96,14 @@
public ParameterDescriptor[] getParameterDescriptors() {
return parameterDescriptors;
}
+
+ void merge(MethodDescriptor anotherMethod){
+ super.merge(anotherMethod);
+ if(method == null){
+ method = anotherMethod.method;
+ }
+ if(parameterDescriptors == null){
+ parameterDescriptors = anotherMethod.parameterDescriptors;
+ }
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/PropertyDescriptor.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/PropertyDescriptor.java?view=diff&rev=557137&r1=557136&r2=557137
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/PropertyDescriptor.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/PropertyDescriptor.java Tue Jul 17 21:01:20 2007
@@ -31,9 +31,9 @@
private Class<?> propertyEditorClass;
- private boolean constrained;
+ boolean constrained;
- private boolean bound;
+ boolean bound;
public PropertyDescriptor(String propertyName, Class<?> beanClass, String getterName,
String setterName) throws IntrospectionException {
Modified: harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java?view=diff&rev=557137&r1=557136&r2=557137
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java Tue Jul 17 21:01:20 2007
@@ -26,6 +26,7 @@
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
+import java.io.Serializable;
import java.lang.reflect.Method;
import java.security.Permission;
import java.util.ArrayList;
@@ -125,9 +126,6 @@
MethodDescriptor[] mds = info.getMethodDescriptors();
assertNotNull(mds);
assertEquals(11, mds.length);
- assertEquals("wait", mds[8].getName());
- assertEquals("wait", mds[9].getName());
- assertEquals("wait", mds[10].getName());
}
/**
@@ -279,9 +277,10 @@
*/
public void testAdditionalBeanInfo() throws IntrospectionException {
BeanInfo info = Introspector.getBeanInfo(StandardBean2.class);
+ assertNull(info.getAdditionalBeanInfo());
PropertyDescriptor[] pds = info.getPropertyDescriptors();
- assertEquals(1, pds.length);
- assertEquals("grannyText", pds[0].getName());
+ assertEquals(2, pds.length);
+ assertEquals("class", pds[0].getName());
}
/**
@@ -437,6 +436,12 @@
assertTrue(contains("setName", mds));
assertTrue(contains("getComplexLabel", mds));
assertTrue(contains("setComplexLabel", mds));
+ try{
+ BeanInfo info2 = Introspector.getBeanInfo(MockFoo.class,
+ Serializable.class);
+ fail("Shoule throw exception, stopclass must be superclass of given bean");
+ }catch(IntrospectionException e){
+ }
}
public void testGetBeanInfoClassClass_StopNull()
@@ -666,11 +671,28 @@
assertEquals(pds[i], pds2[i]);
}
}
+
+ public void testSetBeanInfoSearchPath_null() throws IntrospectionException{
+ String[] oldPath = Introspector.getBeanInfoSearchPath();
+ try{
+ Introspector.setBeanInfoSearchPath(null);
+ try{
+ Introspector.getBeanInfoSearchPath();
+ fail("should throw NPE");
+ }catch(NullPointerException e){
+ }
+ String[] newPath = new String[]{"mock", null, ""};
+ Introspector.setBeanInfoSearchPath(newPath);
+ Introspector.getBeanInfo(this.getClass());
+ }finally{
+ Introspector.setBeanInfoSearchPath(oldPath);
+ }
+ }
public void testGetBeanInfoSearchPath() {
String[] path = Introspector.getBeanInfoSearchPath();
assertEquals(1, path.length);
- assertEquals("org.apache.harmony.beans.infos", path[0]);
+ assertTrue(path[0].endsWith("beans.infos"));
}
public void testGetBeanInfoSearchPath_Default()
@@ -679,11 +701,11 @@
PropertyDescriptor[] pds = info.getPropertyDescriptors();
BeanDescriptor beanDesc;
- assertEquals(1, pds.length);
- assertEquals("text.MockFooButtonBeanInfo", pds[0].getName());
+ assertEquals(2, pds.length);
+ assertEquals("class", pds[0].getName());
beanDesc = info.getBeanDescriptor();
- assertEquals("MockFooButton.MockFooButtonBeanInfo", beanDesc.getName());
+ assertEquals("MockFooButton", beanDesc.getName());
}
public void testSetBeanInfoSearchPath() throws IntrospectionException {
@@ -809,10 +831,10 @@
assertNotNull(element.getReadMethod());
} else {
assertEquals("fox301", element.getName());
- assertEquals(String.class.getName(), element
+ assertEquals(Integer.class.getName(), element
.getPropertyType().getName());
- assertNotNull(element.getWriteMethod());
- assertNull(element.getReadMethod());
+ assertNull(element.getWriteMethod());
+ assertNotNull(element.getReadMethod());
}
}
}