diff options
Diffstat (limited to 'libjava/classpath/java/beans/beancontext/BeanContextSupport.java')
-rw-r--r-- | libjava/classpath/java/beans/beancontext/BeanContextSupport.java | 408 |
1 files changed, 342 insertions, 66 deletions
diff --git a/libjava/classpath/java/beans/beancontext/BeanContextSupport.java b/libjava/classpath/java/beans/beancontext/BeanContextSupport.java index a12c078df6a..d57f5f8842a 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()); + } } + } |