You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/11/11 19:10:55 UTC

svn commit: r834994 - in /incubator/pivot/trunk: core/src/org/apache/pivot/xml/Element.java core/src/org/apache/pivot/xml/ElementListener.java core/src/org/apache/pivot/xml/XMLSerializer.java wtk/src/org/apache/pivot/wtk/content/TreeBranch.java

Author: gbrown
Date: Wed Nov 11 18:10:54 2009
New Revision: 834994

URL: http://svn.apache.org/viewvc?rev=834994&view=rev
Log:
Complete first pass implementation of org.apache.pivot.xml classes (code has not yet been tested, and writing of XML data is not yet supported).

Modified:
    incubator/pivot/trunk/core/src/org/apache/pivot/xml/Element.java
    incubator/pivot/trunk/core/src/org/apache/pivot/xml/ElementListener.java
    incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeBranch.java

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/xml/Element.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/xml/Element.java?rev=834994&r1=834993&r2=834994&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/xml/Element.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/xml/Element.java Wed Nov 11 18:10:54 2009
@@ -19,10 +19,13 @@
 import java.util.Comparator;
 import java.util.Iterator;
 
+import org.apache.pivot.collections.ArrayList;
 import org.apache.pivot.collections.Dictionary;
+import org.apache.pivot.collections.HashMap;
 import org.apache.pivot.collections.List;
 import org.apache.pivot.collections.ListListener;
 import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.util.ImmutableIterator;
 import org.apache.pivot.util.ListenerList;
 
 /**
@@ -36,84 +39,160 @@
         private NamespaceDictionary() {
         }
 
+        /**
+         * Returns the URI of a namespace declared by this element.
+         *
+         * @param prefix
+         * The namespace prefix.
+         *
+         * @return
+         * The declared namespace, or <tt>null</tt> if no such namespace exists.
+         */
         @Override
         public String get(String prefix) {
-            // TODO Auto-generated method stub
-            return null;
+            return namespaces.get(prefix);
         }
 
+        /**
+         * Sets the URI of a namespace declared by this element.
+         *
+         * @param prefix
+         * The namespace prefix.
+         *
+         * @param uri
+         * The namespace URI.
+         *
+         * @return
+         * The URI previously associated with the given prefix.
+         */
         @Override
         public String put(String prefix, String uri) {
-            // TODO Auto-generated method stub
-            return null;
+            if (uri == null) {
+                throw new IllegalArgumentException("uri is null.");
+            }
+
+            boolean update = containsKey(prefix);
+            String previousURI = namespaces.put(prefix, uri);
+
+            if (update) {
+                elementListeners.namespaceUpdated(Element.this, prefix, previousURI);
+            } else {
+                elementListeners.namespaceAdded(Element.this, prefix);
+            }
+
+            return previousURI;
         }
 
+        /**
+         * Removes a namespace from this element's declared namespaces.
+         *
+         * @param prefix
+         * The namespace prefix.
+         *
+         * @return
+         * The URI previously associated with the given prefix.
+         */
         @Override
         public String remove(String prefix) {
-            // TODO Auto-generated method stub
-            return null;
+            String uri = null;
+
+            if (containsKey(prefix)) {
+                uri = namespaces.remove(prefix);
+                elementListeners.namespaceRemoved(Element.this, prefix, uri);
+            }
+
+            return uri;
         }
 
+        /**
+         * Tests for the existence of a namespace declared by this element.
+         *
+         * @param prefix
+         *
+         * @return
+         * <tt>true</tt> if this element declares a namespace with the given prefix;
+         * <tt>false</tt>, otherwise.
+         */
         @Override
         public boolean containsKey(String prefix) {
-            // TODO Auto-generated method stub
-            return false;
+            return namespaces.containsKey(prefix);
         }
 
+        /**
+         * Determines if this element declares any namespaces.
+         *
+         * @return
+         * <tt>true</tt> if this element does not declare any namespaces;
+         * <tt>false</tt> if the element declares at least one namespace.
+         */
         @Override
         public boolean isEmpty() {
-            // TODO Auto-generated method stub
-            return false;
+            return namespaces.isEmpty();
         }
     }
 
     private static class ElementListenerList extends ListenerList<ElementListener>
         implements ElementListener {
+        @Override
         public void namespacePrefixChanged(Element element, String previousNamespacePrefix) {
             for (ElementListener listener : this) {
                 listener.namespacePrefixChanged(element, previousNamespacePrefix);
             }
         }
 
+        @Override
         public void localNameChanged(Element element, String previousLocalName) {
             for (ElementListener listener : this) {
                 listener.localNameChanged(element, previousLocalName);
             }
         }
 
+        @Override
         public void attributeAdded(Element element, String attribute) {
             for (ElementListener listener : this) {
                 listener.attributeAdded(element, attribute);
             }
         }
 
+        @Override
         public void attributeUpdated(Element element, String attribute, String previousValue) {
             for (ElementListener listener : this) {
                 listener.attributeUpdated(element, attribute, previousValue);
             }
         }
 
-        public void attributeRemoved(Element element, String attribute) {
+        @Override
+        public void attributeRemoved(Element element, String attribute, String value) {
+            for (ElementListener listener : this) {
+                listener.attributeRemoved(element, attribute, value);
+            }
+        }
+
+        @Override
+        public void defaultNamespaceURIChanged(Element element, String previousDefaultNamespaceURI) {
             for (ElementListener listener : this) {
-                listener.attributeRemoved(element, attribute);
+                listener.defaultNamespaceURIChanged(element, previousDefaultNamespaceURI);
             }
         }
 
+        @Override
         public void namespaceAdded(Element element, String prefix) {
             for (ElementListener listener : this) {
                 listener.namespaceAdded(element, prefix);
             }
         }
 
+        @Override
         public void namespaceUpdated(Element element, String prefix, String previousURI) {
             for (ElementListener listener : this) {
                 listener.namespaceUpdated(element, prefix, previousURI);
             }
         }
 
-        public void namespaceRemoved(Element element, String prefix) {
+        @Override
+        public void namespaceRemoved(Element element, String prefix, String uri) {
             for (ElementListener listener : this) {
-                listener.namespaceRemoved(element, prefix);
+                listener.namespaceRemoved(element, prefix, uri);
             }
         }
     }
@@ -121,6 +200,14 @@
     private String namespacePrefix;
     private String localName;
 
+    private HashMap<String, String> namespaces = new HashMap<String, String>();
+    private NamespaceDictionary namespaceDictionary = new NamespaceDictionary();
+    private String defaultNamespaceURI = null;
+
+    private HashMap<String, String> attributes = new HashMap<String, String>();
+    private ArrayList<Node> nodes = new ArrayList<Node>();
+
+    private ListListenerList<Node> listListeners = new ListListenerList<Node>();
     private ElementListenerList elementListeners = new ElementListenerList();
 
     public Element(String localName) {
@@ -133,29 +220,45 @@
     }
 
     /**
-     * Returns the fully-qualified name of the element.
+     * Returns the element's namespace prefix.
+     *
+     * @return
+     * The element's namespace prefix, or <tt>null</tt> if the element belongs to the
+     * default namespace.
      */
-    public String getName() {
-        String name;
-        if (namespacePrefix == null) {
-            name = localName;
-        } else {
-            name = namespacePrefix + ":" + localName;
-        }
-
-        return name;
-    }
-
     public String getNamespacePrefix() {
         return namespacePrefix;
     }
 
+    /**
+     * Sets the element's namespace prefix.
+     * <p>
+     * Note that this method does not ensure that the namespace specified by the
+     * prefix actually exists. It only verifies that the prefix does not contain
+     * invalid characters.
+     *
+     * @param namespacePrefix
+     * The element's namespace prefix, or <tt>null</tt> to use the default namespace.
+     */
     public void setNamespacePrefix(String namespacePrefix) {
         if (namespacePrefix != null) {
-            // TODO Validate name
+            if (namespacePrefix.length() == 0) {
+                throw new IllegalArgumentException("Namespace prefix is empty.");
+            }
+
+            char c = namespacePrefix.charAt(0);
+            if (!Character.isLetter(c)) {
+                throw new IllegalArgumentException("'" + c + "' is not a valid start"
+                    + " character for a namespace prefix.");
+            }
 
-            if (getNamespaceURI(namespacePrefix) == null) {
-                throw new IllegalArgumentException("Namespace \"" + namespacePrefix + "\" does not exist.");
+            for (int i = 1, n = namespacePrefix.length(); i < n; i++) {
+                c = namespacePrefix.charAt(i);
+
+                if (!Character.isLetterOrDigit(c)) {
+                    throw new IllegalArgumentException("'" + c + "' is not a valid character"
+                        + " for a namespace prefix.");
+                }
             }
         }
 
@@ -167,25 +270,44 @@
         }
     }
 
-    public String getNamespaceURI() {
-        return (namespacePrefix == null) ? null : getNamespaceURI(namespacePrefix);
-    }
-
-    public String getNamespaceURI(String prefix) {
-        // TODO Walk up parent tree looking for namespace prefix
-        return null;
-    }
-
+    /**
+     * Returns the element's local name.
+     */
     public String getLocalName() {
         return localName;
     }
 
+    /**
+     * Sets the element's local name.
+     *
+     * @param localName
+     */
     public void setLocalName(String localName) {
         if (localName == null) {
             throw new IllegalArgumentException();
         }
 
-        // TODO Validate name
+        if (localName.length() == 0) {
+            throw new IllegalArgumentException("Local name is empty.");
+        }
+
+        char c = localName.charAt(0);
+        if (!Character.isLetter(c)
+            && c != '_') {
+            throw new IllegalArgumentException("'" + c + "' is not a valid start"
+                + " character for a local name.");
+        }
+
+        for (int i = 1, n = localName.length(); i < n; i++) {
+            c = localName.charAt(i);
+
+            if (!Character.isLetterOrDigit(c)
+                && c != '-'
+                && c != '.') {
+                throw new IllegalArgumentException("'" + c + "' is not a valid character"
+                    + " for a local name.");
+            }
+        }
 
         String previousLocalName = this.localName;
 
@@ -195,110 +317,317 @@
         }
     }
 
+    /**
+     * Returns the fully-qualified name of the element.
+     */
+    public String getName() {
+        String name;
+        if (namespacePrefix == null) {
+            name = localName;
+        } else {
+            name = namespacePrefix + ":" + localName;
+        }
+
+        return name;
+    }
+
+    /**
+     * Returns the element's namespace dictionary.
+     */
+    public NamespaceDictionary getNamespaces() {
+        return namespaceDictionary;
+    }
+
+    /**
+     * Returns the element's default namespace URI.
+     *
+     * @return
+     * The default namespace URI declared by this element, or <tt>null</tt> if
+     * this element does not declare a default namespace.
+     */
+    public String getDefaultNamespaceURI() {
+        return defaultNamespaceURI;
+    }
+
+    /**
+     * Sets the element's default namespace URI.
+     *
+     * @return
+     * The default namespace URI declared by this element, or <tt>null</tt> if
+     * this element does not declare a default namespace.
+     */
+    public void setDefaultNamespaceURI(String defaultNamespaceURI) {
+        String previousDefaultNamespaceURI = this.defaultNamespaceURI;
+
+        if (previousDefaultNamespaceURI != defaultNamespaceURI) {
+            this.defaultNamespaceURI = defaultNamespaceURI;
+            elementListeners.defaultNamespaceURIChanged(this, previousDefaultNamespaceURI);
+        }
+    }
+
+    /**
+     * Determines the namespace URI corresponding to the given prefix by traversing
+     * the element's ancestry.
+     *
+     * @param prefix
+     * The namespace prefix to look up, or <tt>null</tt> to determine the default
+     * namespace for this element.
+     *
+     * @return
+     * The namespace URI corresponding to the given prefix, or <tt>null</tt> if a
+     * URI could not be found.
+     */
+    public String getNamespaceURI(String prefix) {
+        String namespaceURI;
+
+        Element parent = getParent();
+        if (prefix == null) {
+            if (defaultNamespaceURI == null) {
+                namespaceURI = parent.getDefaultNamespaceURI();
+            } else {
+                namespaceURI = defaultNamespaceURI;
+            }
+        } else {
+            if (namespaces.containsKey(prefix)) {
+                namespaceURI = namespaces.get(prefix);
+            } else {
+                namespaceURI = parent.getNamespaceURI(prefix);
+            }
+        }
+
+        return namespaceURI;
+    }
+
+    /**
+     * Returns an attribute value.
+     */
     @Override
     public String get(String attribute) {
-        // TODO Auto-generated method stub
-        return null;
+        return attributes.get(attribute);
     }
 
+    /**
+     * Sets an attribute value.
+     *
+     * @param attribute
+     * @param value
+     *
+     * @return
+     * The value previously associated with the given attribute.
+     */
     @Override
     public String put(String attribute, String value) {
-        // TODO Auto-generated method stub
-        return null;
+        if (value == null) {
+            throw new IllegalArgumentException("value is null.");
+        }
+
+        boolean update = containsKey(attribute);
+        String previousValue = attributes.put(attribute, value);
+
+        if (update) {
+            elementListeners.attributeUpdated(Element.this, attribute, previousValue);
+        } else {
+            elementListeners.attributeAdded(Element.this, attribute);
+        }
+
+        return previousValue;
     }
 
+    /**
+     * Removes an attribute value.
+     *
+     * @param attribute
+     *
+     * @return
+     * The value previously associated with the given attribute.
+     */
     @Override
     public String remove(String attribute) {
-        // TODO Auto-generated method stub
-        return null;
+        String value = null;
+
+        if (containsKey(attribute)) {
+            value = attributes.remove(attribute);
+            elementListeners.namespaceRemoved(Element.this, attribute, value);
+        }
+
+        return value;
     }
 
+    /**
+     * Tests for the existence of an attribute.
+     *
+     * @param attribute
+     *
+     * @return
+     * <tt>true</tt> if this element defines the given attribute; <tt>false<tt>,
+     * otherwise.
+     */
     @Override
     public boolean containsKey(String attribute) {
-        // TODO Auto-generated method stub
-        return false;
+        return attributes.containsKey(attribute);
     }
 
+    /**
+     * Determines if this element defines any attributes.
+     *
+     * @return
+     * <tt>true</tt> if this element does not define any attributes;
+     * <tt>false</tt>, otherwise.
+     */
     @Override
     public boolean isEmpty() {
-        // TODO Auto-generated method stub
-        return false;
+        return attributes.isEmpty();
     }
 
+    /**
+     * Adds a node to this element.
+     *
+     * @param node
+     *
+     * @return
+     * The index at which the node was added.
+     */
     @Override
-    public int add(Node item) {
-        // TODO Auto-generated method stub
-        return 0;
+    public int add(Node node) {
+        int index = nodes.add(node);
+        listListeners.itemInserted(this, index);
+
+        return index;
     }
 
+    /**
+     * Inserts a node at a specific location within this element.
+     *
+     * @param node
+     * @param index
+     */
     @Override
-    public void insert(Node item, int index) {
-        // TODO Auto-generated method stub
-
+    public void insert(Node node, int index) {
+        nodes.insert(node, index);
+        listListeners.itemInserted(this, index);
     }
 
+    /**
+     * Updates the node at the given location.
+     *
+     * @param index
+     * @param node
+     */
     @Override
-    public Node update(int index, Node item) {
-        // TODO Auto-generated method stub
-        return null;
+    public Node update(int index, Node node) {
+        Node previousNode = nodes.update(index, node);
+        listListeners.itemUpdated(this, index, previousNode);
+
+        return previousNode;
     }
 
+    /**
+     * Removes a node from this element.
+     *
+     * @param
+     */
     @Override
-    public int remove(Node item) {
-        // TODO Auto-generated method stub
-        return 0;
+    public int remove(Node node) {
+        int index = nodes.indexOf(node);
+        if (index != -1) {
+            remove(index, 1);
+        }
+
+        return index;
     }
 
+    /**
+     * Removes a range of nodes from this element.
+     *
+     * @param index
+     * @param count
+     *
+     * @return
+     * The removed nodes.
+     */
     @Override
     public Sequence<Node> remove(int index, int count) {
-        // TODO Auto-generated method stub
-        return null;
+        Sequence<Node> removed = nodes.remove(index, count);
+        if (count > 0) {
+            listListeners.itemsRemoved(this, index, removed);
+        }
+
+        return removed;
     }
 
+    /**
+     * Removes all nodes from this element.
+     */
     @Override
     public void clear() {
-        // TODO Auto-generated method stub
-
+        if (getLength() > 0) {
+            nodes.clear();
+            listListeners.listCleared(this);
+        }
     }
 
+    /**
+     * Returns the node at the given index.
+     *
+     * @param index
+     */
     @Override
     public Node get(int index) {
-        // TODO Auto-generated method stub
-        return null;
+        return nodes.get(index);
     }
 
+    /**
+     * Determines the index of the given node within this element.
+     *
+     * @return
+     * The index of the node, or <tt>-1</tt> if the node does not exist in
+     * this element.
+     */
     @Override
-    public int indexOf(Node item) {
-        // TODO Auto-generated method stub
-        return 0;
+    public int indexOf(Node node) {
+        return nodes.indexOf(node);
     }
 
+    /**
+     * Returns the number of nodes contained by this element.
+     */
     @Override
     public int getLength() {
-        // TODO Auto-generated method stub
-        return 0;
+        return nodes.getLength();
     }
 
+    /**
+     * @return
+     * <tt>null</tt>; elements cannot be sorted.
+     */
     @Override
     public Comparator<Node> getComparator() {
         return null;
     }
 
+    /**
+     * @throws UnsupportedOperationException
+     * Elements cannot be sorted.
+     */
     @Override
     public void setComparator(Comparator<Node> comparator) {
         throw new UnsupportedOperationException();
     }
 
+    /**
+     * Returns an iterator over this elements child nodes.
+     */
     @Override
     public Iterator<Node> iterator() {
-        // TODO Auto-generated method stub
-        return null;
+        return new ImmutableIterator<Node>(nodes.iterator());
     }
 
+    /**
+     * Returns the element's listener list.
+     */
     @Override
     public ListenerList<ListListener<Node>> getListListeners() {
-        // TODO Auto-generated method stub
-        return null;
+        return listListeners;
     }
 
     /**

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/xml/ElementListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/xml/ElementListener.java?rev=834994&r1=834993&r2=834994&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/xml/ElementListener.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/xml/ElementListener.java Wed Nov 11 18:10:54 2009
@@ -24,28 +24,40 @@
      * Element listener adapter.
      */
     public static class Adapter implements ElementListener {
+        @Override
         public void namespacePrefixChanged(Element element, String previousNamespacePrefix) {
         }
 
+        @Override
         public void localNameChanged(Element element, String previousLocalName) {
         }
 
+        @Override
         public void attributeAdded(Element element, String attribute) {
         }
 
+        @Override
         public void attributeUpdated(Element element, String attribute, String previousValue) {
         }
 
-        public void attributeRemoved(Element element, String attribute) {
+        @Override
+        public void attributeRemoved(Element element, String attribute, String value) {
         }
 
+        @Override
+        public void defaultNamespaceURIChanged(Element element, String previousDefaultNamespaceURI) {
+        }
+
+        @Override
         public void namespaceAdded(Element element, String prefix) {
         }
 
+        @Override
         public void namespaceUpdated(Element element, String prefix, String previousURI) {
         }
 
-        public void namespaceRemoved(Element element, String prefix) {
+        @Override
+        public void namespaceRemoved(Element element, String prefix, String uri) {
         }
     }
 
@@ -87,8 +99,17 @@
      *
      * @param element
      * @param attribute
+     * @param value
+     */
+    public void attributeRemoved(Element element, String attribute, String value);
+
+    /**
+     * Called when an element's default namespace URI has changed.
+     *
+     * @param element
+     * @param previousDefaultNamespaceURI
      */
-    public void attributeRemoved(Element element, String attribute);
+    public void defaultNamespaceURIChanged(Element element, String previousDefaultNamespaceURI);
 
     /**
      * Called when a namespace has been added to an element.
@@ -112,6 +133,7 @@
      *
      * @param element
      * @param prefix
+     * @param uri
      */
-    public void namespaceRemoved(Element element, String prefix);
+    public void namespaceRemoved(Element element, String prefix, String uri);
 }

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java?rev=834994&r1=834993&r2=834994&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java Wed Nov 11 18:10:54 2009
@@ -20,6 +20,11 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
 import org.apache.pivot.serialization.SerializationException;
 import org.apache.pivot.serialization.Serializer;
 
@@ -29,17 +34,100 @@
 public class XMLSerializer implements Serializer<Element> {
     public static final String MIME_TYPE = "text/xml";
 
+    private XMLInputFactory xmlInputFactory;
+
+    private Element element = null;
+
+    public static final String XMLNS_ATTRIBUTE_PREFIX = "xmlns";
+
+    public XMLSerializer() {
+        this(true);
+    }
+
+    public XMLSerializer(boolean coalesceText) {
+        xmlInputFactory = XMLInputFactory.newInstance();
+        xmlInputFactory.setProperty("javax.xml.stream.isCoalescing", coalesceText);
+    }
+
     @Override
     public Element readObject(InputStream inputStream) throws IOException, SerializationException {
-        // TODO Auto-generated method stub
-        return null;
+        if (inputStream == null) {
+            throw new IllegalArgumentException("inputStream is null.");
+        }
+
+        // Parse the XML stream
+        element = null;
+
+        try {
+            XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(inputStream);
+
+            while (reader.hasNext()) {
+                int event = reader.next();
+
+                switch (event) {
+                    case XMLStreamConstants.CHARACTERS: {
+                        element.add(new TextNode(reader.getText()));
+                        break;
+                    }
+
+                    case XMLStreamConstants.START_ELEMENT: {
+                        // Create the element
+                        String prefix = reader.getPrefix();
+                        String localName = reader.getLocalName();
+
+                        Element element = new Element(prefix, localName);
+
+                        for (int i = 0, n = reader.getAttributeCount(); i < n; i++) {
+                            String attributePrefix = reader.getAttributePrefix(i);
+                            String attributeLocalName = reader.getAttributeLocalName(i);
+                            String attributeValue = reader.getAttributeValue(i);
+
+                            if (attributePrefix != null) {
+                                if (!attributePrefix.equals(XMLNS_ATTRIBUTE_PREFIX)) {
+                                    throw new SerializationException("Attribute namespaces are not supported.");
+                                }
+
+                                element.getNamespaces().put(attributeLocalName, attributeValue);
+                            } else {
+                                element.put(attributeLocalName, attributeValue);
+                            }
+                        }
+
+                        if (this.element == null) {
+                            this.element = element;
+                        } else {
+                            this.element.add(element);
+                        }
+
+                        break;
+                    }
+
+                    case XMLStreamConstants.END_ELEMENT: {
+                        // Move up the stack
+                        Element parent = element.getParent();
+                        if (parent != null) {
+                            element = parent;
+                        }
+
+                        break;
+                    }
+                }
+            }
+
+            reader.close();
+        } catch (XMLStreamException exception) {
+            throw new SerializationException(exception);
+        }
+
+        return element;
     }
 
     @Override
-    public void writeObject(Element object, OutputStream outputStream) throws IOException,
-        SerializationException {
-        // TODO Auto-generated method stub
-
+    public void writeObject(Element object, OutputStream outputStream)
+        throws IOException, SerializationException {
+        // TODO (note that we'll need to check for valid namespace prefixes here,
+        // since we don't do it in Element)
+        throw new UnsupportedOperationException();
     }
 
     @Override

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeBranch.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeBranch.java?rev=834994&r1=834993&r2=834994&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeBranch.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeBranch.java Wed Nov 11 18:10:54 2009
@@ -102,15 +102,19 @@
     @Override
     public Sequence<TreeNode> remove(int index, int count) {
         Sequence<TreeNode> removed = treeNodes.remove(index, count);
-        listListeners.itemsRemoved(this, index, removed);
+        if (count > 0) {
+            listListeners.itemsRemoved(this, index, removed);
+        }
 
         return removed;
     }
 
     @Override
     public void clear() {
-        treeNodes.clear();
-        listListeners.listCleared(this);
+        if (getLength() > 0) {
+            treeNodes.clear();
+            listListeners.listCleared(this);
+        }
     }
 
     @Override