OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / beans / beancontext / BeanContextSupport.java
index a12c078..d57f5f8 100644 (file)
@@ -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());
+      }
   }
+
 }