summaryrefslogtreecommitdiff
path: root/java/beans/beancontext/BeanContextSupport.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/beans/beancontext/BeanContextSupport.java')
-rw-r--r--java/beans/beancontext/BeanContextSupport.java335
1 files changed, 284 insertions, 51 deletions
diff --git a/java/beans/beancontext/BeanContextSupport.java b/java/beans/beancontext/BeanContextSupport.java
index 2dc2a4e4a..d57f5f884 100644
--- a/java/beans/beancontext/BeanContextSupport.java
+++ b/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,6 +176,8 @@ public class BeanContextSupport extends BeanContextChildSupport
protected transient boolean okToUseGui;
+ private transient boolean serializing;
+
/**
* Construct a BeanContextSupport instance.
*/
@@ -328,7 +367,6 @@ public class BeanContextSupport extends BeanContextChildSupport
* told not to use it.
*/
public boolean avoidingGui()
- throws NotImplementedException
{
return needsGui() && (!okToUseGui);
}
@@ -341,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)
@@ -423,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());
}
/**
@@ -502,34 +582,91 @@ public class BeanContextSupport extends BeanContextChildSupport
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 ()
@@ -577,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;
}
@@ -595,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 ()
@@ -643,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);
+ }
+ }
+ }
}
/**
@@ -689,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.
@@ -765,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));
}
@@ -798,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)
{
@@ -806,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);
@@ -838,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());
+ }
}
+
}