diff options
author | Tom Tromey <tromey@gcc.gnu.org> | 2007-01-09 19:58:05 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2007-01-09 19:58:05 +0000 |
commit | 97b8365cafc3a344a22d3980b8ed885f5c6d8357 (patch) | |
tree | 996a5f57d4a68c53473382e45cb22f574cb3e4db /libjava/classpath/java/beans | |
parent | c648dedbde727ca3f883bb5fd773aa4af70d3369 (diff) | |
download | gcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.zip gcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.tar.gz gcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.tar.bz2 |
Merged gcj-eclipse branch to trunk.
From-SVN: r120621
Diffstat (limited to 'libjava/classpath/java/beans')
17 files changed, 1028 insertions, 236 deletions
diff --git a/libjava/classpath/java/beans/BeanDescriptor.java b/libjava/classpath/java/beans/BeanDescriptor.java index 21227b2..b4bc687 100644 --- a/libjava/classpath/java/beans/BeanDescriptor.java +++ b/libjava/classpath/java/beans/BeanDescriptor.java @@ -48,14 +48,14 @@ package java.beans; **/ public class BeanDescriptor extends FeatureDescriptor { - Class beanClass; - Class customizerClass; + Class<?> beanClass; + Class<?> customizerClass; /** Create a new BeanDescriptor with the given beanClass and ** no customizer class. ** @param beanClass the class of the Bean. **/ - public BeanDescriptor(Class beanClass) { + public BeanDescriptor(Class<?> beanClass) { this(beanClass,null); } @@ -64,7 +64,7 @@ public class BeanDescriptor extends FeatureDescriptor { ** @param beanClass the class of the Bean. ** @param customizerClass the class of the Bean's Customizer. **/ - public BeanDescriptor(Class beanClass, Class customizerClass) { + public BeanDescriptor(Class<?> beanClass, Class<?> customizerClass) { this.beanClass = beanClass; this.customizerClass = customizerClass; @@ -78,12 +78,12 @@ public class BeanDescriptor extends FeatureDescriptor { } /** Get the Bean's class. **/ - public Class getBeanClass() { + public Class<?> getBeanClass() { return beanClass; } /** Get the Bean's customizer's class. **/ - public Class getCustomizerClass() { + public Class<?> getCustomizerClass() { return customizerClass; } } diff --git a/libjava/classpath/java/beans/Beans.java b/libjava/classpath/java/beans/Beans.java index ffcb83f..b3b0a42 100644 --- a/libjava/classpath/java/beans/Beans.java +++ b/libjava/classpath/java/beans/Beans.java @@ -295,7 +295,7 @@ public class Beans * @return the Bean as a new view, or if the operation * could not be performed, the Bean itself. */ - public static Object getInstanceOf(Object bean, Class newClass) + public static Object getInstanceOf(Object bean, Class<?> newClass) { return bean; } @@ -314,7 +314,7 @@ public class Beans * @return whether the Bean can be cast to the class type * in question. */ - public static boolean isInstanceOf(Object bean, Class newBeanClass) + public static boolean isInstanceOf(Object bean, Class<?> newBeanClass) { return newBeanClass.isInstance(bean); } diff --git a/libjava/classpath/java/beans/DefaultPersistenceDelegate.java b/libjava/classpath/java/beans/DefaultPersistenceDelegate.java index ca1041f..08f6174 100644 --- a/libjava/classpath/java/beans/DefaultPersistenceDelegate.java +++ b/libjava/classpath/java/beans/DefaultPersistenceDelegate.java @@ -154,8 +154,8 @@ public class DefaultPersistenceDelegate extends PersistenceDelegate return new Expression(oldInstance, oldInstance.getClass(), "new", args); } - protected void initialize(Class type, Object oldInstance, Object newInstance, - Encoder out) + protected void initialize(Class<?> type, Object oldInstance, + Object newInstance, Encoder out) { // Calling the supertype's implementation of initialize makes it // possible that descendants of classes like AbstractHashMap diff --git a/libjava/classpath/java/beans/DesignMode.java b/libjava/classpath/java/beans/DesignMode.java index 39805d5..9897f02 100644 --- a/libjava/classpath/java/beans/DesignMode.java +++ b/libjava/classpath/java/beans/DesignMode.java @@ -1,5 +1,5 @@ /* java.beans.DesignMode - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,7 +39,8 @@ exception statement from your version. */ package java.beans; /** - * <code>BeanContextChild</code> implementors implement this to get information about whether they are in a design time or runtime environment. + * <code>BeanContextChild</code> implementors implement this to get information + * about whether they are in a design time or runtime environment. * The reason this is restricted to <code>BeanContextChild</code>ren is that * only things in the <code>BeanContext</code> hierarchy are given this * information in the first place. @@ -48,46 +49,47 @@ package java.beans; * @since JDK1.2 * @see java.beans.beancontext.BeanContextChild */ +public interface DesignMode +{ -public interface DesignMode { - /** - * Use this name when firing <code>PropertyChangeEvent</code>s from your Bean. - * @fixme Check whether PROPERTYNAME is set to same value as Sun. - */ - String PROPERTYNAME = "designTime"; + /** + * Use this name when firing <code>PropertyChangeEvent</code>s from your Bean. + */ + String PROPERTYNAME = "designTime"; - /** - * The environment will call this method on your - * <code>BeanContextChild</code> when it is registered in a parent - * <code>BeanContext</code> or when behavior needs to switch from - * design time to runtime behavior (or vice versa). - * <P> - * - * <code>BeanContext</code>s are required to fire - * <code>PropertyChangeEvent</code>s when properties change. - * <code>designTime</code> is a property, and therefore when you - * implement <code>setDesignTime()</code>, you need to fire a - * <code>PropertyChangeEvent</code> with the old value, the new - * value and using <code>PROPERTYNAME</code> as the property name. - * - * @param designTime the new value of design time, - * <code>true</code> if it is design time, - * <code>false</code> if it is runtime. - * - * @fixme I'm frankly not really sure whether it's the case that - * the BeanContext can <em>change</em> the status of the Bean from - * design time to runtime. But it appears that it may be so. - * - * @see java.util.PropertyChangeEvent - * @see java.beans.beancontext.BeanContext - * @see #PROPERTYNAME - */ - void setDesignTime(boolean designTime); + /** + * The environment will call this method on your + * <code>BeanContextChild</code> when it is registered in a parent + * <code>BeanContext</code> or when behavior needs to switch from + * design time to runtime behavior (or vice versa). + * <P> + * + * <code>BeanContext</code>s are required to fire + * <code>PropertyChangeEvent</code>s when properties change. + * <code>designTime</code> is a property, and therefore when you + * implement <code>setDesignTime()</code>, you need to fire a + * <code>PropertyChangeEvent</code> with the old value, the new + * value and using <code>PROPERTYNAME</code> as the property name. + * + * @param designTime the new value of design time, + * <code>true</code> if it is design time, + * <code>false</code> if it is runtime. + * + * @fixme I'm frankly not really sure whether it's the case that + * the BeanContext can <em>change</em> the status of the Bean from + * design time to runtime. But it appears that it may be so. + * + * @see java.beans.PropertyChangeEvent + * @see java.beans.beancontext.BeanContext + * @see #PROPERTYNAME + */ + void setDesignTime(boolean designTime); + + /** + * This method should tell whether it is design time or runtime. + * @return <code>true</code> if design time, <code>false</code> if + * runtime. + */ + boolean isDesignTime(); - /** - * This method should tell whether it is design time or runtime. - * @return <code>true</code> if design time, <code>false</code> if - * runtime. - */ - boolean isDesignTime(); } diff --git a/libjava/classpath/java/beans/Encoder.java b/libjava/classpath/java/beans/Encoder.java index b9d1358..cde1735 100644 --- a/libjava/classpath/java/beans/Encoder.java +++ b/libjava/classpath/java/beans/Encoder.java @@ -181,7 +181,7 @@ public class Encoder return exceptionListener; } - public PersistenceDelegate getPersistenceDelegate(Class type) + public PersistenceDelegate getPersistenceDelegate(Class<?> type) { // This is not specified but the JDK behaves like this. if (type == null) @@ -215,7 +215,8 @@ public class Encoder * access is thread safe. * </p> */ - public void setPersistenceDelegate(Class type, PersistenceDelegate delegate) + public void setPersistenceDelegate(Class<?> type, + PersistenceDelegate delegate) { // If the argument is null this will cause a NullPointerException // which is expected behavior. diff --git a/libjava/classpath/java/beans/EventHandler.java b/libjava/classpath/java/beans/EventHandler.java index 9c85893..318b274 100644 --- a/libjava/classpath/java/beans/EventHandler.java +++ b/libjava/classpath/java/beans/EventHandler.java @@ -463,7 +463,8 @@ public class EventHandler implements InvocationHandler * @param action Target property or method to invoke. * @return A constructed proxy object. */ - public static Object create(Class listenerInterface, Object target, String action) + public static <T> T create(Class<T> listenerInterface, Object target, + String action) { return create(listenerInterface, target, action, null, null); } @@ -552,8 +553,8 @@ public class EventHandler implements InvocationHandler * @param eventPropertyName Name of property to extract from event. * @return A constructed proxy object. */ - public static Object create(Class listenerInterface, Object target, - String action, String eventPropertyName) + public static <T> T create(Class<T> listenerInterface, Object target, + String action, String eventPropertyName) { return create(listenerInterface, target, action, eventPropertyName, null); } @@ -587,9 +588,9 @@ public class EventHandler implements InvocationHandler * @param listenerMethodName Listener method to implement. * @return A constructed proxy object. */ - public static Object create(Class listenerInterface, Object target, - String action, String eventPropertyName, - String listenerMethodName) + public static <T> T create(Class<T> listenerInterface, Object target, + String action, String eventPropertyName, + String listenerMethodName) { // Create EventHandler instance EventHandler eh = new EventHandler(target, action, eventPropertyName, @@ -597,10 +598,9 @@ public class EventHandler implements InvocationHandler // Create proxy object passing in the event handler Object proxy = Proxy.newProxyInstance(listenerInterface.getClassLoader(), - new Class[] {listenerInterface}, + new Class<?>[] {listenerInterface}, eh); - return proxy; + return (T) proxy; } - } diff --git a/libjava/classpath/java/beans/EventSetDescriptor.java b/libjava/classpath/java/beans/EventSetDescriptor.java index 381a453..69c0742 100644 --- a/libjava/classpath/java/beans/EventSetDescriptor.java +++ b/libjava/classpath/java/beans/EventSetDescriptor.java @@ -164,8 +164,8 @@ public class EventSetDescriptor extends FeatureDescriptor * if listenerType is not an EventListener, or if methods are not * found or are invalid. */ - public EventSetDescriptor(Class eventSourceClass, String eventSetName, - Class listenerType, String listenerMethodName) + public EventSetDescriptor(Class<?> eventSourceClass, String eventSetName, + Class<?> listenerType, String listenerMethodName) throws IntrospectionException { setName(eventSetName); @@ -225,8 +225,8 @@ public class EventSetDescriptor extends FeatureDescriptor * if listenerType is not an EventListener or if methods are not * found or are invalid. */ - public EventSetDescriptor(Class eventSourceClass, String eventSetName, - Class listenerType, String[] listenerMethodNames, + public EventSetDescriptor(Class<?> eventSourceClass, String eventSetName, + Class<?> listenerType, String[] listenerMethodNames, String addListenerMethodName, String removeListenerMethodName) throws IntrospectionException @@ -287,8 +287,8 @@ public class EventSetDescriptor extends FeatureDescriptor * found or are invalid. * @since 1.4 */ - public EventSetDescriptor(Class eventSourceClass, String eventSetName, - Class listenerType, String[] listenerMethodNames, + public EventSetDescriptor(Class<?> eventSourceClass, String eventSetName, + Class<?> listenerType, String[] listenerMethodNames, String addListenerMethodName, String removeListenerMethodName, String getListenerMethodName) @@ -357,7 +357,7 @@ public class EventSetDescriptor extends FeatureDescriptor * methods are invalid. * @since 1.4 */ - public EventSetDescriptor(String eventSetName, Class listenerType, + public EventSetDescriptor(String eventSetName, Class<?> listenerType, Method[] listenerMethods, Method addListenerMethod, Method removeListenerMethod, Method getListenerMethod) @@ -402,7 +402,7 @@ public class EventSetDescriptor extends FeatureDescriptor * if the listenerType is not an EventListener, or any of the * methods are invalid. */ - public EventSetDescriptor(String eventSetName, Class listenerType, + public EventSetDescriptor(String eventSetName, Class<?> listenerType, Method[] listenerMethods, Method addListenerMethod, Method removeListenerMethod) throws IntrospectionException @@ -449,7 +449,7 @@ public class EventSetDescriptor extends FeatureDescriptor * if the listenerType is not an EventListener, or any of the * methods are invalid. */ - public EventSetDescriptor(String eventSetName, Class listenerType, + public EventSetDescriptor(String eventSetName, Class<?> listenerType, MethodDescriptor[] listenerMethodDescriptors, Method addListenerMethod, Method removeListenerMethod) @@ -484,7 +484,7 @@ public class EventSetDescriptor extends FeatureDescriptor /** Returns the class that contains the event firing methods. */ - public Class getListenerType() + public Class<?> getListenerType() { return listenerType; } diff --git a/libjava/classpath/java/beans/FeatureDescriptor.java b/libjava/classpath/java/beans/FeatureDescriptor.java index aeb4094..0508851 100644 --- a/libjava/classpath/java/beans/FeatureDescriptor.java +++ b/libjava/classpath/java/beans/FeatureDescriptor.java @@ -68,14 +68,14 @@ public class FeatureDescriptor boolean hidden; boolean preferred; - Hashtable valueHash; + Hashtable<String,Object> valueHash; /** * Instantiate this FeatureDescriptor with appropriate default values. */ public FeatureDescriptor() { - valueHash = new Hashtable(); + valueHash = new Hashtable<String,Object>(); } /** @@ -225,7 +225,7 @@ public class FeatureDescriptor * @return an Enumerator over all the programmatic key names associated * with this feature. */ - public Enumeration attributeNames() + public Enumeration<String> attributeNames() { return valueHash.keys(); } diff --git a/libjava/classpath/java/beans/IndexedPropertyDescriptor.java b/libjava/classpath/java/beans/IndexedPropertyDescriptor.java index 0ba2ed4..61c3f22 100644 --- a/libjava/classpath/java/beans/IndexedPropertyDescriptor.java +++ b/libjava/classpath/java/beans/IndexedPropertyDescriptor.java @@ -76,7 +76,7 @@ import java.lang.reflect.Method; */ public class IndexedPropertyDescriptor extends PropertyDescriptor { - private Class indexedPropertyType; + private Class<?> indexedPropertyType; private Method setIndex; private Method getIndex; @@ -112,7 +112,7 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor * @exception IntrospectionException if the methods are not found or * invalid. */ - public IndexedPropertyDescriptor(String name, Class beanClass) + public IndexedPropertyDescriptor(String name, Class<?> beanClass) throws IntrospectionException { super(name); @@ -161,7 +161,7 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor * * @exception IntrospectionException if the methods are not found or invalid. */ - public IndexedPropertyDescriptor(String name, Class beanClass, + public IndexedPropertyDescriptor(String name, Class<?> beanClass, String getMethodName, String setMethodName, String getIndexName, String setIndexName) throws IntrospectionException @@ -272,7 +272,7 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor : Array.newInstance(this.indexedPropertyType,0).getClass()); } - public Class getIndexedPropertyType() + public Class<?> getIndexedPropertyType() { return indexedPropertyType; } diff --git a/libjava/classpath/java/beans/Introspector.java b/libjava/classpath/java/beans/Introspector.java index 23c3cde5..28df87f 100644 --- a/libjava/classpath/java/beans/Introspector.java +++ b/libjava/classpath/java/beans/Introspector.java @@ -182,7 +182,8 @@ public class Introspector { public static final int IGNORE_ALL_BEANINFO = 3; static String[] beanInfoSearchPath = {"gnu.java.beans.info"}; - static Hashtable beanInfoCache = new Hashtable(); + static Hashtable<Class<?>,BeanInfo> beanInfoCache = + new Hashtable<Class<?>,BeanInfo>(); private Introspector() {} @@ -195,13 +196,13 @@ public class Introspector { * @param beanClass the class to get BeanInfo about. * @return the BeanInfo object representing the class. */ - public static BeanInfo getBeanInfo(Class beanClass) + public static BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException { BeanInfo cachedInfo; synchronized(beanClass) { - cachedInfo = (BeanInfo)beanInfoCache.get(beanClass); + cachedInfo = beanInfoCache.get(beanClass); if(cachedInfo != null) { return cachedInfo; @@ -245,7 +246,7 @@ public class Introspector { * @throws IntrospectionException If something goes wrong while retrieving * the bean data. */ - public static BeanInfo getBeanInfo(Class beanClass, int flag) + public static BeanInfo getBeanInfo(Class<?> beanClass, int flag) throws IntrospectionException { IntrospectionIncubator ii; @@ -312,7 +313,7 @@ public class Introspector { * @throws NullPointerException if clz is null. * @since 1.2 */ - public static void flushFromCaches(Class clz) + public static void flushFromCaches(Class<?> clz) { synchronized (clz) { @@ -394,7 +395,7 @@ public class Introspector { * @param stopClass the class to stop at. * @return the BeanInfo object representing the class. */ - public static BeanInfo getBeanInfo(Class beanClass, Class stopClass) + public static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass) throws IntrospectionException { ExplicitInfo explicit = new ExplicitInfo(beanClass, stopClass); diff --git a/libjava/classpath/java/beans/PersistenceDelegate.java b/libjava/classpath/java/beans/PersistenceDelegate.java index 77953b6..a6f7157 100644 --- a/libjava/classpath/java/beans/PersistenceDelegate.java +++ b/libjava/classpath/java/beans/PersistenceDelegate.java @@ -52,8 +52,8 @@ package java.beans; public abstract class PersistenceDelegate { - protected void initialize(Class type, Object oldInstance, Object newInstance, - Encoder out) + protected void initialize(Class<?> type, Object oldInstance, + Object newInstance, Encoder out) { if (type != Object.class) { diff --git a/libjava/classpath/java/beans/PropertyDescriptor.java b/libjava/classpath/java/beans/PropertyDescriptor.java index da2ca78..4b586d9 100644 --- a/libjava/classpath/java/beans/PropertyDescriptor.java +++ b/libjava/classpath/java/beans/PropertyDescriptor.java @@ -65,11 +65,11 @@ import java.lang.reflect.Method; **/ public class PropertyDescriptor extends FeatureDescriptor { - Class propertyType; + Class<?> propertyType; Method getMethod; Method setMethod; - Class propertyEditorClass; + Class<?> propertyEditorClass; boolean bound; boolean constrained; @@ -103,7 +103,7 @@ public class PropertyDescriptor extends FeatureDescriptor ** @exception IntrospectionException if the methods are not found ** or invalid. **/ - public PropertyDescriptor(String name, Class beanClass) + public PropertyDescriptor(String name, Class<?> beanClass) throws IntrospectionException { setName(name); @@ -159,7 +159,7 @@ public class PropertyDescriptor extends FeatureDescriptor **/ public PropertyDescriptor( String name, - Class beanClass, + Class<?> beanClass, String getMethodName, String setMethodName) throws IntrospectionException @@ -213,7 +213,7 @@ public class PropertyDescriptor extends FeatureDescriptor ** This is the type the get method returns and the set method ** takes in. **/ - public Class getPropertyType() + public Class<?> getPropertyType() { return propertyType; } @@ -330,7 +330,7 @@ public class PropertyDescriptor extends FeatureDescriptor } /** Get the PropertyEditor class. Defaults to null. **/ - public Class getPropertyEditorClass() + public Class<?> getPropertyEditorClass() { return propertyEditorClass; } @@ -341,7 +341,7 @@ public class PropertyDescriptor extends FeatureDescriptor ** @param propertyEditorClass the PropertyEditor class for this ** class to use. **/ - public void setPropertyEditorClass(Class propertyEditorClass) + public void setPropertyEditorClass(Class<?> propertyEditorClass) { this.propertyEditorClass = propertyEditorClass; } @@ -516,10 +516,10 @@ public class PropertyDescriptor extends FeatureDescriptor * @return The common property type of the two method. * @throws IntrospectionException If any of the above requirements are not met. */ - private Class checkMethods(Method readMethod, Method writeMethod) + private Class<?> checkMethods(Method readMethod, Method writeMethod) throws IntrospectionException { - Class newPropertyType = propertyType; + Class<?> newPropertyType = propertyType; // a valid read method has zero arguments and a non-void return type. if (readMethod != null) diff --git a/libjava/classpath/java/beans/PropertyEditorManager.java b/libjava/classpath/java/beans/PropertyEditorManager.java index da2a5678..0dd3b17 100644 --- a/libjava/classpath/java/beans/PropertyEditorManager.java +++ b/libjava/classpath/java/beans/PropertyEditorManager.java @@ -83,7 +83,8 @@ import java.awt.Font; public class PropertyEditorManager { - static java.util.Hashtable editors = new java.util.Hashtable(); + static java.util.Hashtable<Class<?>,Class<?>> editors = + new java.util.Hashtable<Class<?>,Class<?>>(); static String[] editorSearchPath = { "gnu.java.beans.editors", "sun.beans.editors" }; @@ -118,7 +119,7 @@ public class PropertyEditorManager * will edit. * @param editorClass the PropertyEditor class. */ - public static void registerEditor(Class editedClass, Class editorClass) + public static void registerEditor(Class<?> editedClass, Class<?> editorClass) { editors.put(editedClass, editorClass); } @@ -132,7 +133,7 @@ public class PropertyEditorManager * @return a PropertyEditor instance that can edit the * specified class. */ - public static PropertyEditor findEditor(Class editedClass) + public static PropertyEditor findEditor(Class<?> editedClass) { try { diff --git a/libjava/classpath/java/beans/SimpleBeanInfo.java b/libjava/classpath/java/beans/SimpleBeanInfo.java index cfb9604..56b1f7a 100644 --- a/libjava/classpath/java/beans/SimpleBeanInfo.java +++ b/libjava/classpath/java/beans/SimpleBeanInfo.java @@ -1,5 +1,5 @@ /* java.beans.SimpleBeanInfo - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,6 +40,7 @@ package java.beans; import java.awt.Image; import java.awt.Toolkit; +import java.net.URL; /** ** SimpleBeanInfo is a class you may extend to more easily @@ -130,10 +131,16 @@ public class SimpleBeanInfo implements BeanInfo { ** and its BeanInfo are both loaded by the same ** ClassLoader, generally a reasonable assumption. ** @param location the URL relative - ** @return the Image in question. + ** @return the Image in question (possibly <code>null</code>). **/ - public Image loadImage(String location) { - return Toolkit.getDefaultToolkit().getImage(getClass().getResource(location)); + public Image loadImage(String location) + { + if (location == null) + return null; + URL url = getClass().getResource(location); + if (url == null) + return null; + return Toolkit.getDefaultToolkit().getImage(url); } } diff --git a/libjava/classpath/java/beans/Statement.java b/libjava/classpath/java/beans/Statement.java index 62a5ad7..0a01798 100644 --- a/libjava/classpath/java/beans/Statement.java +++ b/libjava/classpath/java/beans/Statement.java @@ -1,5 +1,5 @@ /* Statement.java - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -346,16 +346,20 @@ public class Statement /** Return the statement object. */ public Object getTarget() { return target; } - /** Return a string representation. */ + /** + * Returns a string representation of this <code>Statement</code>. + * + * @return A string representation of this <code>Statement</code>. + */ public String toString() { StringBuffer result = new StringBuffer(); - String targetName = target.getClass().getName(); - if ( targetName.startsWith("java")) - { - targetName = targetName.substring(targetName.lastIndexOf('.') + 1); - } + String targetName; + if (target != null) + targetName = target.getClass().getSimpleName(); + else + targetName = "null"; result.append(targetName); result.append("."); @@ -369,10 +373,10 @@ public class Statement result.append( ( arguments[i] == null ) ? "null" : ( arguments[i] instanceof String ) ? "\"" + arguments[i] + "\"" : - arguments[i].getClass().getName()); + arguments[i].getClass().getSimpleName()); sep = ", "; } - result.append(")"); + result.append(");"); return result.toString(); } diff --git a/libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java b/libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java index 4da523e..f354ff4 100644 --- a/libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java +++ b/libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java @@ -46,12 +46,21 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.TooManyListenersException; /** + * This is a helper class for implementing a bean context which + * supplies services. It is intended to be used either by + * subclassing or by calling methods of this implementation + * from another. + * * @author Michael Koch + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.2 */ public class BeanContextServicesSupport @@ -77,38 +86,39 @@ public class BeanContextServicesSupport { private static final long serialVersionUID = 7078212910685744490L; - private BCSSProxyServiceProvider() + private BeanContextServiceProvider provider; + + private BCSSProxyServiceProvider(BeanContextServiceProvider p) { + provider = p; } public Iterator getCurrentServiceSelectors (BeanContextServices bcs, Class serviceClass) - throws NotImplementedException { - throw new Error ("Not implemented"); + return provider.getCurrentServiceSelectors(bcs, serviceClass); } public Object getService (BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector) - throws NotImplementedException { - throw new Error ("Not implemented"); + return provider.getService(bcs, requestor, serviceClass, + serviceSelector); } public void releaseService (BeanContextServices bcs, Object requestor, Object service) - throws NotImplementedException { - throw new Error ("Not implemented"); + provider.releaseService(bcs, requestor, service); } public void serviceRevoked (BeanContextServiceRevokedEvent bcsre) - throws NotImplementedException { - throw new Error ("Not implemented"); + if (provider instanceof BeanContextServiceRevokedListener) + ((BeanContextServiceRevokedListener) provider).serviceRevoked(bcsre); } } @@ -119,51 +129,233 @@ public class BeanContextServicesSupport protected BeanContextServiceProvider serviceProvider; - private BCSSServiceProvider() + private Class serviceClass; + + private BCSSServiceProvider(Class serviceClass, + BeanContextServiceProvider provider) { + this.serviceClass = serviceClass; + serviceProvider = provider; } protected BeanContextServiceProvider getServiceProvider() { return serviceProvider; } + + private Class getServiceClass() + { + return serviceClass; + } + } - protected transient ArrayList bcsListeners; + /** + * Represents a request for a service. This is + * a common superclass used by the classes which maintain + * the listener-requestor and service-requestor relationships. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + */ + private static abstract class Request + { + private Object requestor; + + public Request(Object requestor) + { + this.requestor = requestor; + } + + public boolean equals(Object obj) + { + if (obj instanceof Request) + { + Request req = (Request) obj; + return req.getRequestor().equals(requestor); + } + return false; + } + + public Object getRequestor() + { + return requestor; + } + + } + + /** + * Represents a relationship between a service requestor + * and a revocation listener. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + */ + private static class ServiceRequest + extends Request + { + + private BeanContextServiceRevokedListener listener; + + public ServiceRequest(Object requestor, + BeanContextServiceRevokedListener listener) + { + super(requestor); + this.listener = listener; + } + + public boolean equals(Object obj) + { + if (obj instanceof ServiceRequest) + { + ServiceRequest sr = (ServiceRequest) obj; + return (super.equals(obj) && + sr.getListener().equals(listener)); + } + return false; + } + + public BeanContextServiceRevokedListener getListener() + { + return listener; + } + } + + /** + * Represents a relationship between a service requestor + * and a service instance. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + */ + private static class ServiceLease + extends Request + { + private Object service; + + public ServiceLease(Object requestor, Object service) + { + super(requestor); + this.service = service; + } + + public boolean equals(Object obj) + { + if (obj instanceof ServiceLease) + { + ServiceLease sl = (ServiceLease) obj; + return (super.equals(obj) && + sl.getService().equals(service)); + } + return false; + } + + public Object getService() + { + return service; + } + } + + /** + * A collection of listeners who receive availability + * and revocation notifications. + */ + protected transient ArrayList bcsListeners; + protected transient BCSSProxyServiceProvider proxy; + /** + * The number of serializable service providers. + */ protected transient int serializable; + /** + * A map of registered services, linking the service + * class to its associated {@link BCSSServiceProvider}. + */ protected transient HashMap services; + /** + * A map of children to a list of services they + * have obtained. + */ + private transient HashMap serviceUsers; + + /** + * A map of services to {@link ServiceRequest}s. + */ + private transient HashMap serviceRequests; + + /** + * A map of {@link ServiceLease}s to providers. + */ + private transient HashMap serviceLeases; + + /** + * Construct a {@link BeanContextServicesSupport} instance. + */ public BeanContextServicesSupport () { super(); } + /** + * Construct a {@link BeanContextServicesSupport} instance. + * + * @param peer the bean context services peer (<code>null</code> permitted). + */ public BeanContextServicesSupport (BeanContextServices peer) { super(peer); } + /** + * Construct a {@link BeanContextServicesSupport} instance. + * + * @param peer the bean context peer (<code>null</code> permitted). + * @param locale the locale (<code>null</code> permitted, equivalent to + * the default locale). + */ public BeanContextServicesSupport(BeanContextServices peer, Locale locale) { super(peer, locale); } + /** + * Construct a {@link BeanContextServicesSupport} instance. + * + * @param peer the bean context peer (<code>null</code> permitted). + * @param locale the locale (<code>null</code> permitted, equivalent to + * the default locale). + * @param dtime a flag indicating whether or not the bean context is in + * design time mode. + */ public BeanContextServicesSupport(BeanContextServices peer, Locale locale, boolean dtime) { super(peer, locale, dtime); } + /** + * Construct a {@link BeanContextServicesSupport} instance. + * + * @param peer the bean context peer (<code>null</code> permitted). + * @param locale the locale (<code>null</code> permitted, equivalent to + * the default locale). + * @param dtime a flag indicating whether or not the bean context is in + * design time mode. + * @param visible initial value of the <code>okToUseGui</code> flag. + */ public BeanContextServicesSupport(BeanContextServices peer, Locale locale, boolean dtime, boolean visible) { super(peer, locale, dtime, visible); } - + + /** + * Adds a new listener for service availability and + * revocation events. + * + * @param listener the listener to add. + */ public void addBeanContextServicesListener (BeanContextServicesListener listener) { @@ -174,60 +366,168 @@ public class BeanContextServicesSupport } } + /** + * Registers a new service from the specified service provider. + * The service is internally associated with the service provider + * and a <code>BeanContextServiceAvailableEvent</code> is fired. If + * the service is already registered, then this method instead + * returns <code>false</code>. This is equivalent to calling + * <code>addService(serviceClass, bcsp, true)</code>. + * + * @param serviceClass the class of the service to be registered. + * @param bcsp the provider of the given service. + * @return true if the service was registered successfully. + * @see #addService(Class, BeanContextServiceProvider, boolean) + */ public boolean addService (Class serviceClass, BeanContextServiceProvider bcsp) { return addService(serviceClass, bcsp, true); } + /** + * Registers a new service from the specified service provider. + * The service is internally associated with the service provider + * and (if <code>fireEvent</code> is true) a + * <code>BeanContextServiceAvailableEvent</code> is fired. If + * the service is already registered, then this method instead + * returns <code>false</code>. + * + * @param serviceClass the class of the service to be registered. + * @param bcsp the provider of the given service. + * @param fireEvent true if a service availability event should + * be fired. + * @return true if the service was registered successfully. + */ protected boolean addService (Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent) { - synchronized (services) + synchronized (globalHierarchyLock) { - if (services.containsKey(serviceClass)) - return false; - services.put(serviceClass, bcsp); - if (bcsp instanceof Serializable) - ++serializable; - fireServiceAdded(serviceClass); - return true; + synchronized (services) + { + if (services.containsKey(serviceClass)) + return false; + services.put(serviceClass, + createBCSSServiceProvider(serviceClass, bcsp)); + if (bcsp instanceof Serializable) + ++serializable; + if (fireEvent) + fireServiceAdded(serviceClass); + return true; + } } } + /** + * Deserializes any service providers which are serializable. This + * method is called by the <code>readObject</code> method of + * {@link BeanContextSupport} prior to deserialization of the children. + * Subclasses may envelope its behaviour in order to read further + * serialized data to the stream. + * + * @param oos the stream from which data is being deserialized. + * @throws IOException if an I/O error occurs. + * @throws ClassNotFoundException if the class of a deserialized object + * can not be found. + */ protected void bcsPreDeserializationHook (ObjectInputStream ois) - throws ClassNotFoundException, IOException, NotImplementedException + throws ClassNotFoundException, IOException { - throw new Error ("Not implemented"); + serializable = ois.readInt(); + for (int a = 0; a < serializable; ++a) + { + BCSSServiceProvider bcsssp = (BCSSServiceProvider) ois.readObject(); + addService(bcsssp.getServiceClass(), bcsssp.getServiceProvider()); + } } + /** + * Serializes any service providers which are serializable. This + * method is called by the <code>writeObject</code> method of + * {@link BeanContextSupport} prior to serialization of the children. + * Subclasses may envelope its behaviour in order to add further + * serialized data to the stream. + * + * @param oos the stream to which data is being serialized. + * @throws IOException if an I/O error occurs. + */ protected void bcsPreSerializationHook (ObjectOutputStream oos) - throws IOException, NotImplementedException + throws IOException { - throw new Error ("Not implemented"); + oos.writeInt(serializable); + synchronized (services) + { + Iterator i = services.values().iterator(); + while (i.hasNext()) + { + BCSSServiceProvider bcsssp = (BCSSServiceProvider) i.next(); + if (bcsssp.getServiceProvider() instanceof Serializable) + oos.writeObject(bcsssp); + } + } } - + + /** + * Revokes any services used by a child that has just been removed. + * The superclass ({@link BeanContextSupport}) calls this method + * when a child has just been successfully removed. Subclasses can + * extend this method in order to perform additional operations + * on child removal. + * + * @param child the child being removed. + * @param bcsc the support object for the child. + */ protected void childJustRemovedHook (Object child, BeanContextSupport.BCSChild bcsc) - throws NotImplementedException { - throw new Error ("Not implemented"); + if (child instanceof BeanContextChild) + { + BeanContextChild bcchild = (BeanContextChild) child; + Iterator childServices = ((List) serviceUsers.get(bcchild)).iterator(); + while (childServices.hasNext()) + releaseService(bcchild, this, childServices.next()); + serviceUsers.remove(bcchild); + } } + /** + * Overrides the {@link BeanContextSupport#createBCSChild} method + * so as to use a {@link BCSSChild} instead. + * + * @param targetChild the child to create the child for. + * @param peer the peer which relates to the child if a proxy is used. + * @return a new instance of {@link BCSSChild}. + */ protected BeanContextSupport.BCSChild createBCSChild (Object targetChild, Object peer) { return new BCSSChild(targetChild, peer); } + /** + * Provides a hook so that subclasses can replace the + * {@link BCSSServiceProvider} class, used to store registered + * service providers, with a subclass without replacing the + * {@link #addService(Class, BeanContextServiceProvider)} method. + * + * @param sc the class of service being registered. + * @param bcsp the provider of the service. + * @return a instance of {@link BCSSServiceProvider} wrapping the provider. + */ protected BeanContextServicesSupport.BCSSServiceProvider createBCSSServiceProvider (Class sc, BeanContextServiceProvider bcsp) - throws NotImplementedException { - throw new Error ("Not implemented"); + return new BCSSServiceProvider(sc, bcsp); } + /** + * Sends a <code>BeanContextServiceAvailableEvent</code> to all + * registered listeners. + * + * @param bcssae the event to send. + */ protected final void fireServiceAdded (BeanContextServiceAvailableEvent bcssae) { synchronized (bcsListeners) @@ -242,12 +542,25 @@ public class BeanContextServicesSupport } } + /** + * Sends a <code>BeanContextServiceAvailableEvent</code> to all + * registered listeners. + * + * @param serviceClass the service that is now available. + * @see #fireServiceAdded(BeanContextServiceAvailableEvent) + */ protected final void fireServiceAdded (Class serviceClass) { fireServiceAdded(new BeanContextServiceAvailableEvent(this, serviceClass)); } + /** + * Sends a <code>BeanContextServiceRevokedEvent</code> to all + * registered listeners. + * + * @param event the event to send. + */ protected final void fireServiceRevoked(BeanContextServiceRevokedEvent event) { synchronized (bcsListeners) @@ -259,9 +572,26 @@ public class BeanContextServicesSupport = (BeanContextServicesListener) bcsListeners.get(i); bcsl.serviceRevoked(event); } + List requests = (List) serviceRequests.get(event.getServiceClass()); + if (requests != null) + { + Iterator i = requests.iterator(); + while (i.hasNext()) + { + ServiceRequest r = (ServiceRequest) i.next(); + r.getListener().serviceRevoked(event); + } + } } } + /** + * Sends a <code>BeanContextServiceRevokedEvent</code> to all + * registered listeners. + * + * @param serviceClass the service that has been revoked. + * @see #fireServiceRevoked(BeanContextServiceRevokedEvent) + */ protected final void fireServiceRevoked (Class serviceClass, boolean revokeNow) { @@ -269,51 +599,166 @@ public class BeanContextServicesSupport revokeNow)); } + /** + * Returns the services peer given at construction time, + * or <code>null</code> if no peer was given. + * + * @return the {@link BeanContextServices} peer. + */ public BeanContextServices getBeanContextServicesPeer () - throws NotImplementedException { - throw new Error ("Not implemented"); + return (BeanContextServices) beanContextChildPeer; } + /** + * Returns <code>child</code> as an instance of + * {@link BeanContextServicesListener}, or <code>null</code> if + * <code>child</code> does not implement that interface. + * + * @param child the child (<code>null</code> permitted). + * + * @return The child cast to {@link BeanContextServicesListener}. + */ protected static final BeanContextServicesListener - getChildBeanContextServicesListener (Object child) - throws NotImplementedException + getChildBeanContextServicesListener(Object child) { - throw new Error ("Not implemented"); + if (child instanceof BeanContextServicesListener) + return (BeanContextServicesListener) child; + else + return null; } + /** + * Returns an iterator over the currently available + * services. + * + * @return an iterator over the currently available services. + */ public Iterator getCurrentServiceClasses () { - synchronized (services) + synchronized (globalHierarchyLock) { - return services.keySet().iterator(); + synchronized (services) + { + return services.keySet().iterator(); + } } } + /** + * Returns an iterator over the service selectors of the service + * provider for the given service. The iterator is actually + * obtained by calling the + * {@link BeanContextServiceProvider#getCurrentServiceSelectors} + * of the provider itself. If the specified service is not available, + * <code>null</code> is returned. + * + * @param serviceClass the service whose provider's selectors should + * be iterated over. + * @return an {@link Iterator} over the service selectors of the + * provider of the given service. + */ public Iterator getCurrentServiceSelectors (Class serviceClass) { - synchronized (services) + synchronized (globalHierarchyLock) { - // FIXME: what if service does not exist? Must write a test. - BeanContextServiceProvider bcsp - = (BeanContextServiceProvider) services.get(serviceClass); - return bcsp.getCurrentServiceSelectors(this, serviceClass); + synchronized (services) + { + BeanContextServiceProvider bcsp + = ((BCSSServiceProvider) + services.get(serviceClass)).getServiceProvider(); + if (bcsp == null) + return null; + else + return bcsp.getCurrentServiceSelectors(this, serviceClass); + } } } + /** + * Retrieves the specified service. If a provider for the service + * is registered in this context, then the request is passed on to + * the provider and the service returned. Otherwise, the request + * is delegated to a parent {@link BeanContextServices}, if possible. + * If the service can not be found at all, then <code>null</code> + * is returned. + * + * @param child the child obtaining the reference. + * @param requestor the requestor of the service, which may be the + * child itself. + * @param serviceClass the service being requested. + * @param serviceSelector an additional service-dependent parameter + * (may be <code>null</code> if not appropriate). + * @param bcsrl a listener used to notify the requestor that the service + * has since been revoked. + * @return a reference to the service requested, or <code>null</code>. + * @throws TooManyListenersException according to Sun's documentation. + */ public Object getService (BeanContextChild child, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener bcsrl) - throws TooManyListenersException, NotImplementedException + throws TooManyListenersException { - throw new Error ("Not implemented"); + synchronized (globalHierarchyLock) + { + synchronized (services) + { + Object service; + BeanContextServiceProvider provider = ((BCSSServiceProvider) + services.get(serviceClass)).getServiceProvider(); + if (provider != null) + { + service = provider.getService(this, requestor, serviceClass, + serviceSelector); + List childServices = (List) serviceUsers.get(child); + if (childServices == null) + { + childServices = new ArrayList(); + serviceUsers.put(child, childServices); + } + childServices.add(serviceClass); + } + else + { + BeanContextServices peer = getBeanContextServicesPeer(); + if (peer != null) + service = peer.getService(child, requestor, serviceClass, + serviceSelector, bcsrl); + else + service = null; + } + if (service != null) + { + ServiceRequest request = new ServiceRequest(requestor, bcsrl); + Set requests = (Set) serviceRequests.get(serviceClass); + if (requests == null) + { + requests = new HashSet(); + serviceRequests.put(serviceClass, requests); + } + requests.add(request); + ServiceLease lease = new ServiceLease(requestor, service); + serviceLeases.put(lease, provider); + } + return service; + } + } } + /** + * Returns true if the specified service is available. + * + * @param serviceClass the service to check for. + * @return true if the service is available. + */ public boolean hasService (Class serviceClass) { - synchronized (services) + synchronized (globalHierarchyLock) { - return services.containsKey(serviceClass); + synchronized (services) + { + return services.containsKey(serviceClass); + } } } @@ -323,25 +768,62 @@ public class BeanContextServicesSupport bcsListeners = new ArrayList(); services = new HashMap(); + serviceUsers = new HashMap(); + serviceRequests = new HashMap(); + serviceLeases = new HashMap(); } - protected void initializeBeanContextResources () - throws NotImplementedException + /** + * Subclasses may override this method to allocate resources + * from the nesting bean context. + */ + protected void initializeBeanContextResources() { - throw new Error ("Not implemented"); + /* Purposefully left empty */ } - protected void releaseBeanContextResources () - throws NotImplementedException + /** + * Relinquishes any resources obtained from the parent context. + * Specifically, those services obtained from the parent are revoked. + * Subclasses may override this method to deallocate resources + * from the nesting bean context. + */ + protected void releaseBeanContextResources() { - throw new Error ("Not implemented"); + /* Purposefully left empty */ } + /** + * Releases the reference to a service held by a + * {@link BeanContextChild} (or an arbitrary object associated + * with it). It simply calls the appropriate method on the + * underlying provider. + * + * @param child the child who holds the reference. + * @param requestor the object that requested the reference. + * @param service the service being released. + */ public void releaseService (BeanContextChild child, Object requestor, Object service) - throws NotImplementedException { - throw new Error ("Not implemented"); + synchronized (globalHierarchyLock) + { + synchronized (services) + { + ServiceLease lease = new ServiceLease(requestor, service); + BeanContextServiceProvider provider = (BeanContextServiceProvider) + serviceLeases.get(lease); + if (provider != null) + provider.releaseService(this, requestor, service); + else + { + BeanContextServices peer = getBeanContextServicesPeer(); + if (peer != null) + peer.releaseService(child, requestor, service); + } + serviceLeases.remove(lease); + } + } } public void removeBeanContextServicesListener @@ -349,17 +831,35 @@ public class BeanContextServicesSupport { synchronized (bcsListeners) { - int index = bcsListeners.indexOf(listener); - if (index > -1) - bcsListeners.remove(index); + bcsListeners.remove(listener); } } + /** + * Revokes the given service. A {@link BeanContextServiceRevokedEvent} is + * emitted to all registered {@link BeanContextServiceRevokedListener}s + * and {@link BeanContextServiceListener}s. If <code>revokeCurrentServicesNow</code> + * is true, termination of the service is immediate. Otherwise, prior + * acquisitions of the service by requestors remain valid. + * + * @param serviceClass the service to revoke. + * @param bcsp the provider of the revoked service. + * @param revokeCurrentServicesNow true if this is an exceptional circumstance + * where service should be immediately revoked. + */ public void revokeService (Class serviceClass, BeanContextServiceProvider bcsp, boolean revokeCurrentServicesNow) - throws NotImplementedException { - throw new Error ("Not implemented"); + synchronized (globalHierarchyLock) + { + synchronized (services) + { + fireServiceRevoked(serviceClass, revokeCurrentServicesNow); + services.remove(serviceClass); + if (bcsp instanceof Serializable) + --serializable; + } + } } public void serviceAvailable (BeanContextServiceAvailableEvent bcssae) diff --git a/libjava/classpath/java/beans/beancontext/BeanContextSupport.java b/libjava/classpath/java/beans/beancontext/BeanContextSupport.java index a12c078..d57f5f8 100644 --- a/libjava/classpath/java/beans/beancontext/BeanContextSupport.java +++ b/libjava/classpath/java/beans/beancontext/BeanContextSupport.java @@ -38,8 +38,6 @@ exception statement from your version. */ package java.beans.beancontext; -import gnu.classpath.NotImplementedException; - import java.beans.Beans; import java.beans.DesignMode; import java.beans.PropertyChangeEvent; @@ -57,6 +55,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Locale; /** @@ -74,20 +73,52 @@ public class BeanContextSupport extends BeanContextChildSupport { private static final long serialVersionUID = -4879613978649577204L; - // This won't show up in japi, but we mark it as a stub anyway, - // so that searches for NotImplementedException will find it. + /** + * Deserializes a stored bean context. Hook methods are provided to allow + * subclasses to perform their own deserialization after the default + * deserialization but prior to the deserialization of the children. Note that + * {@link #readChildren(ObjectInputStream)} is only called if there + * is no distinct peer. If there is, the peer is expected to call + * the method instead. + * + * @param s the stream to deserialize. + * @throws ClassNotFoundException if the class of an object being deserialized + * could not be found. + * @throws IOException if an I/O error occurs. + */ private void readObject (ObjectInputStream s) - throws ClassNotFoundException, IOException, NotImplementedException + throws ClassNotFoundException, IOException { - throw new Error ("Not implemented"); + s.defaultReadObject(); + bcsPreDeserializationHook(s); + BeanContext peer = getBeanContextPeer(); + if (peer == null || peer == this) + readChildren(s); } - // This won't show up in japi, but we mark it as a stub anyway, - // so that searches for NotImplementedException will find it. + /** + * Serializes a bean context. Hook methods are provided to allow + * subclasses to perform their own serialization after the default + * serialization but prior to serialization of the children. Note that + * {@link #writeChildren(ObjectOutputStream)} is only called if there + * is no distinct peer. If there is, the peer is expected to call + * the method instead. + * + * @param s the stream to serialize. + * @throws ClassNotFoundException if the class of an object being deserialized + * could not be found. + * @throws IOException if an I/O error occurs. + */ private void writeObject (ObjectOutputStream s) - throws ClassNotFoundException, IOException, NotImplementedException + throws ClassNotFoundException, IOException { - throw new Error ("Not implemented"); + serializing = true; + s.defaultWriteObject(); + bcsPreSerializationHook(s); + BeanContext peer = getBeanContextPeer(); + if (peer == null || peer == this) + writeChildren(s); + serializing = false; } protected class BCSChild implements Serializable @@ -102,6 +133,12 @@ public class BeanContextSupport extends BeanContextChildSupport this.targetChild = targetChild; this.peer = peer; } + + private Object getTargetChild() + { + return targetChild; + } + } protected static final class BCSIterator implements Iterator @@ -139,47 +176,68 @@ public class BeanContextSupport extends BeanContextChildSupport protected transient boolean okToUseGui; + private transient boolean serializing; + /** * Construct a BeanContextSupport instance. */ public BeanContextSupport () { - this (null, null, true, true); + this (null, null, false, true); } /** * Construct a BeanContextSupport instance. + * + * @param peer the bean context peer (<code>null</code> permitted). */ - public BeanContextSupport (BeanContext peer) + public BeanContextSupport(BeanContext peer) { - this (peer, null, true, true); + this (peer, null, false, true); } /** * Construct a BeanContextSupport instance. + * + * @param peer the bean context peer (<code>null</code> permitted). + * @param locale the locale (<code>null</code> permitted, equivalent to + * the default locale). */ - public BeanContextSupport (BeanContext peer, Locale lcle) + public BeanContextSupport (BeanContext peer, Locale locale) { - this (peer, lcle, true, true); + this (peer, locale, false, true); } /** * Construct a BeanContextSupport instance. + * + * @param peer the bean context peer (<code>null</code> permitted). + * @param locale the locale (<code>null</code> permitted, equivalent to + * the default locale). + * @param dtime a flag indicating whether or not the bean context is in + * design time mode. */ - public BeanContextSupport (BeanContext peer, Locale lcle, boolean dtime) + public BeanContextSupport (BeanContext peer, Locale locale, boolean dtime) { - this (peer, lcle, dtime, true); + this (peer, locale, dtime, true); } /** * Construct a BeanContextSupport instance. + * + * @param peer the bean context peer (<code>null</code> permitted). + * @param locale the locale (<code>null</code> permitted, equivalent to + * the default locale). + * @param dtime a flag indicating whether or not the bean context is in + * design time mode. + * @param visible initial value of the <code>okToUseGui</code> flag. */ - public BeanContextSupport (BeanContext peer, Locale lcle, boolean dtime, + public BeanContextSupport (BeanContext peer, Locale locale, boolean dtime, boolean visible) { super(peer); - locale = lcle == null ? Locale.getDefault() : lcle; + this.locale = locale == null ? Locale.getDefault() : locale; designTime = dtime; okToUseGui = visible; @@ -309,7 +367,6 @@ public class BeanContextSupport extends BeanContextChildSupport * told not to use it. */ public boolean avoidingGui() - throws NotImplementedException { return needsGui() && (!okToUseGui); } @@ -322,22 +379,49 @@ public class BeanContextSupport extends BeanContextChildSupport } } + /** + * Subclasses may use this method to perform their own deserialization + * after the default deserialization process has taken place, but + * prior to the deserialization of the children. It should not + * be used to replace the implementation of <code>readObject</code> + * in the subclass. + * + * @param ois the input stream. + * @throws ClassNotFoundException if the class of an object being deserialized + * could not be found. + * @throws IOException if an I/O error occurs. + */ protected void bcsPreDeserializationHook (ObjectInputStream ois) - throws ClassNotFoundException, IOException, NotImplementedException + throws ClassNotFoundException, IOException { - throw new Error ("Not implemented"); + /* Purposefully left empty */ } + /** + * Subclasses may use this method to perform their own serialization + * after the default serialization process has taken place, but + * prior to the serialization of the children. It should not + * be used to replace the implementation of <code>writeObject</code> + * in the subclass. + * + * @param oos the output stream. + * @throws IOException if an I/O error occurs. + */ protected void bcsPreSerializationHook (ObjectOutputStream oos) - throws IOException, NotImplementedException + throws IOException { - throw new Error ("Not implemented"); + /* Purposefully left empty */ } + /** + * Called when a child is deserialized. + * + * @param child the deserialized child. + * @param bcsc the deserialized context wrapper for the child. + */ protected void childDeserializedHook (Object child, BeanContextSupport.BCSChild bcsc) - throws NotImplementedException { - throw new Error ("Not implemented"); + // Do nothing in the base class. } protected void childJustAddedHook (Object child, BeanContextSupport.BCSChild bcsc) @@ -404,10 +488,25 @@ public class BeanContextSupport extends BeanContextChildSupport return new BCSChild(targetChild, peer); } + /** + * Deserializes objects (written by {@link #serialize(ObjectOutputStream, + * Collection)}) and adds them to the specified collection. + * + * @param ois the input stream (<code>null</code> not permitted). + * @param coll the collection to add the objects to (<code>null</code> not + * permitted). + * + * @throws ClassNotFoundException + * @throws IOException + * + * @see #serialize(ObjectOutputStream, Collection) + */ protected final void deserialize (ObjectInputStream ois, Collection coll) - throws ClassNotFoundException, IOException, NotImplementedException + throws ClassNotFoundException, IOException { - throw new Error ("Not implemented"); + int itemCount = ois.readInt(); + for (int i = 0; i < itemCount; i++) + coll.add(ois.readObject()); } /** @@ -447,46 +546,127 @@ public class BeanContextSupport extends BeanContextChildSupport } } - public BeanContext getBeanContextPeer () - throws NotImplementedException + /** + * Returns the bean context peer. + * + * @return The bean context peer. + * + * @see BeanContextChildSupport#beanContextChildPeer + */ + public BeanContext getBeanContextPeer() { - throw new Error ("Not implemented"); + return (BeanContext) beanContextChildPeer; } - protected static final BeanContextChild getChildBeanContextChild (Object child) - throws NotImplementedException + /** + * Returns the {@link BeanContextChild} implementation for the given child. + * + * @param child the child (<code>null</code> permitted). + * + * @return The bean context child. + * + * @throws IllegalArgumentException if <code>child</code> implements both + * the {@link BeanContextChild} and {@link BeanContextProxy} interfaces. + */ + protected static final BeanContextChild getChildBeanContextChild(Object child) { - throw new Error ("Not implemented"); + if (child == null) + return null; + if (child instanceof BeanContextChild && child instanceof BeanContextProxy) + throw new IllegalArgumentException("Child cannot implement " + + "BeanContextChild and BeanContextProxy simultaneously."); + if (child instanceof BeanContextChild) + return (BeanContextChild) child; + if (child instanceof BeanContextProxy) + return ((BeanContextProxy) child).getBeanContextProxy(); + return null; } - protected static final BeanContextMembershipListener getChildBeanContextMembershipListener (Object child) - throws NotImplementedException + /** + * Returns <code>child</code> as an instance of + * {@link BeanContextMembershipListener}, or <code>null</code> if + * <code>child</code> does not implement that interface. + * + * @param child the child (<code>null</code> permitted). + * + * @return The child cast to {@link BeanContextMembershipListener}. + */ + protected static final BeanContextMembershipListener + getChildBeanContextMembershipListener(Object child) { - throw new Error ("Not implemented"); + if (child instanceof BeanContextMembershipListener) + return (BeanContextMembershipListener) child; + else + return null; } - protected static final PropertyChangeListener getChildPropertyChangeListener (Object child) - throws NotImplementedException + /** + * Returns <code>child</code> as an instance of + * {@link PropertyChangeListener}, or <code>null</code> if <code>child</code> + * does not implement that interface. + * + * @param child the child (<code>null</code> permitted). + * + * @return The child cast to {@link PropertyChangeListener}. + */ + protected static final PropertyChangeListener getChildPropertyChangeListener( + Object child) { - throw new Error ("Not implemented"); + if (child instanceof PropertyChangeListener) + return (PropertyChangeListener) child; + else + return null; } - protected static final Serializable getChildSerializable (Object child) - throws NotImplementedException + /** + * Returns <code>child</code> as an instance of {@link Serializable}, or + * <code>null</code> if <code>child</code> does not implement that + * interface. + * + * @param child the child (<code>null</code> permitted). + * + * @return The child cast to {@link Serializable}. + */ + protected static final Serializable getChildSerializable(Object child) { - throw new Error ("Not implemented"); + if (child instanceof Serializable) + return (Serializable) child; + else + return null; } - protected static final VetoableChangeListener getChildVetoableChangeListener (Object child) - throws NotImplementedException + /** + * Returns <code>child</code> as an instance of + * {@link VetoableChangeListener}, or <code>null</code> if <code>child</code> + * does not implement that interface. + * + * @param child the child (<code>null</code> permitted). + * + * @return The child cast to {@link VetoableChangeListener}. + */ + protected static final VetoableChangeListener getChildVetoableChangeListener( + Object child) { - throw new Error ("Not implemented"); + if (child instanceof VetoableChangeListener) + return (VetoableChangeListener) child; + else + return null; } - protected static final Visibility getChildVisibility (Object child) - throws NotImplementedException + /** + * Returns <code>child</code> as an instance of {@link Visibility}, or + * <code>null</code> if <code>child</code> does not implement that interface. + * + * @param child the child (<code>null</code> permitted). + * + * @return The child cast to {@link Visibility}. + */ + protected static final Visibility getChildVisibility(Object child) { - throw new Error ("Not implemented"); + if (child instanceof Visibility) + return (Visibility) child; + else + return null; } public Locale getLocale () @@ -534,7 +714,15 @@ public class BeanContextSupport extends BeanContextChildSupport return Beans.instantiate(getClass().getClassLoader(), beanName, this); } - public boolean isDesignTime () + /** + * Returns <code>true</code> if the <code>BeanContext</code> is in + * design time mode, and <code>false</code> if it is in runtime mode. + * + * @return A boolean. + * + * @see #setDesignTime(boolean) + */ + public boolean isDesignTime() { return designTime; } @@ -552,10 +740,15 @@ public class BeanContextSupport extends BeanContextChildSupport } } - public boolean isSerializing () - throws NotImplementedException + /** + * Returns true if the bean context is in the process + * of being serialized. + * + * @return true if the context is being serialized. + */ + public boolean isSerializing() { - throw new Error ("Not implemented"); + return serializing; } public Iterator iterator () @@ -600,10 +793,33 @@ public class BeanContextSupport extends BeanContextChildSupport remove(pce.getSource(), false); } + /** + * Deerializes the children using the + * {@link #deserialize(ObjectInputStream, Collection} method + * and then calls {@link childDeserializedHook(Object, BCSChild)} + * for each child deserialized. + * + * @param oos the output stream. + * @throws IOException if an I/O error occurs. + */ public final void readChildren (ObjectInputStream ois) - throws IOException, ClassNotFoundException, NotImplementedException + throws IOException, ClassNotFoundException { - throw new Error ("Not implemented"); + List temp = new ArrayList(); + deserialize(ois, temp); + Iterator i = temp.iterator(); + synchronized (globalHierarchyLock) + { + synchronized (children) + { + while (i.hasNext()) + { + BCSChild bcs = (BCSChild) i.next(); + childDeserializedHook(bcs.getTargetChild(), bcs); + children.put(bcs.getTargetChild(), bcs); + } + } + } } /** @@ -646,7 +862,7 @@ public class BeanContextSupport extends BeanContextChildSupport * This method is synchronized over the global hierarchy lock. * </p> * - * @param targetChild the child to add. + * @param targetChild the child to remove. * @param callChildSetBC true if the <code>setBeanContext()</code> * method of the child should be called. * @return false if the child doesn't exist. @@ -722,17 +938,55 @@ public class BeanContextSupport extends BeanContextChildSupport throw new UnsupportedOperationException(); } - protected final void serialize (ObjectOutputStream oos, Collection coll) - throws IOException, NotImplementedException + /** + * Writes the items in the collection to the specified output stream. Items + * in the collection that are not instances of {@link Serializable} + * (this includes <code>null</code>) are simply ignored. + * + * @param oos the output stream (<code>null</code> not permitted). + * @param coll the collection (<code>null</code> not permitted). + * + * @throws IOException + * + * @see #deserialize(ObjectInputStream, Collection) + */ + protected final void serialize(ObjectOutputStream oos, Collection coll) + throws IOException { - throw new Error ("Not implemented"); + Object[] items = coll.toArray(); + int itemCount = 0; + for (int i = 0; i < items.length; i++) + { + if (items[i] instanceof Serializable) + itemCount++; + } + oos.writeInt(itemCount); + for (int i = 0; i < items.length; i++) + { + if (items[i] instanceof Serializable) + oos.writeObject(items[i]); + } } - public void setDesignTime (boolean dtime) + /** + * Sets the flag that indicates whether or not the + * <code>BeanContext</code> is in design mode. If the flag changes + * value, a {@link PropertyChangeEvent} (with the property name 'designMode') + * is sent to registered listeners. Note that the property name used here + * does NOT match the specification in the {@link DesignMode} interface, we + * match the reference implementation instead - see bug parade entry 4295174. + * + * @param dtime the new value for the flag. + * + * @see #isDesignTime() + */ + public void setDesignTime(boolean dtime) { boolean save = designTime; designTime = dtime; - firePropertyChange(DesignMode.PROPERTYNAME, Boolean.valueOf(save), + // note that we use the same property name as Sun's implementation, + // even though this is a known bug: see bug parade entry 4295174 + firePropertyChange("designMode", Boolean.valueOf(save), Boolean.valueOf(dtime)); } @@ -755,7 +1009,12 @@ public class BeanContextSupport extends BeanContextChildSupport } } - public Object[] toArray () + /** + * Returns an array containing the children of this <code>BeanContext</code>. + * + * @return An array containing the children. + */ + public Object[] toArray() { synchronized (children) { @@ -763,10 +1022,16 @@ public class BeanContextSupport extends BeanContextChildSupport } } + /** + * Populates, then returns, the supplied array with the children of this + * <code>BeanContext</code>. If the array is too short to hold the + * children, a new array is allocated and returned. If the array is too + * long, it is padded with <code>null</code> items at the end. + * + * @param array an array to populate (<code>null</code> not permitted). + */ public Object[] toArray(Object[] array) - throws NotImplementedException { - // This implementation is incorrect, I think. synchronized (children) { return children.keySet().toArray(array); @@ -795,9 +1060,20 @@ public class BeanContextSupport extends BeanContextChildSupport /* Purposefully left empty */ } + /** + * Serializes the children using the + * {@link #serialize(ObjectOutputStream, Collection} method. + * + * @param oos the output stream. + * @throws IOException if an I/O error occurs. + */ public final void writeChildren (ObjectOutputStream oos) - throws IOException, NotImplementedException + throws IOException { - throw new Error ("Not implemented"); + synchronized (children) + { + serialize(oos, children.values()); + } } + } |