]> source.dussan.org Git - vaadin-framework.git/commitdiff
Avoid object creation in getAllChildrenIterable in most cases. (#14142)
authorFabian Lange <lange.fabian@gmail.com>
Thu, 3 Jul 2014 21:52:05 +0000 (23:52 +0200)
committerFabian Lange <lange.fabian@gmail.com>
Fri, 4 Jul 2014 10:11:50 +0000 (12:11 +0200)
API change from:
    public static Iterable<ClientConnector> getAllChildrenIterable(final ClientConnector connector)
to
    public static Iterable<? extends ClientConnector> getAllChildrenIterable(final ClientConnector connector)

avoids creating wrappers in case the component has either no subcomponents
or no extensions. This covers the vast majority of components.

Change-Id: I48ffd2f26f09c265fae6e1aaabdbaa655d52ffb8

server/src/com/vaadin/server/AbstractClientConnector.java
server/src/com/vaadin/ui/ConnectorTracker.java
server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java

index bafecdabf4b1c73efa7dabb6027fbf47c41388d2..03300b20e2287494fb6e2c8f836faffee436bbcd 100644 (file)
@@ -41,6 +41,7 @@ import com.vaadin.shared.communication.ClientRpc;
 import com.vaadin.shared.communication.ServerRpc;
 import com.vaadin.shared.communication.SharedState;
 import com.vaadin.shared.ui.ComponentStateUtil;
+import com.vaadin.ui.Component;
 import com.vaadin.ui.Component.Event;
 import com.vaadin.ui.HasComponents;
 import com.vaadin.ui.LegacyComponent;
@@ -339,31 +340,6 @@ public abstract class AbstractClientConnector implements ClientConnector,
         }
     }
 
-    private static final class AllChildrenIterable implements
-            Iterable<ClientConnector>, Serializable {
-        private final ClientConnector connector;
-
-        private AllChildrenIterable(ClientConnector connector) {
-            this.connector = connector;
-        }
-
-        @Override
-        public Iterator<ClientConnector> iterator() {
-            CombinedIterator<ClientConnector> iterator = new CombinedIterator<ClientConnector>();
-
-            if (connector instanceof HasComponents) {
-                HasComponents hasComponents = (HasComponents) connector;
-                iterator.addIterator(hasComponents.iterator());
-            }
-
-            Collection<Extension> extensions = connector.getExtensions();
-            if (extensions.size() > 0) {
-                iterator.addIterator(extensions.iterator());
-            }
-            return iterator;
-        }
-    }
-
     private class RpcInvocationHandler implements InvocationHandler,
             Serializable {
 
@@ -493,41 +469,6 @@ public abstract class AbstractClientConnector implements ClientConnector,
         }
     }
 
-    private static final class CombinedIterator<T> implements Iterator<T>,
-            Serializable {
-
-        private final Collection<Iterator<? extends T>> iterators = new ArrayList<Iterator<? extends T>>();
-
-        public void addIterator(Iterator<? extends T> iterator) {
-            iterators.add(iterator);
-        }
-
-        @Override
-        public boolean hasNext() {
-            for (Iterator<? extends T> i : iterators) {
-                if (i.hasNext()) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public T next() {
-            for (Iterator<? extends T> i : iterators) {
-                if (i.hasNext()) {
-                    return i.next();
-                }
-            }
-            throw new NoSuchElementException();
-        }
-
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-    }
-
     /**
      * Get an Iterable for iterating over all child connectors, including both
      * extensions and child components.
@@ -536,9 +477,62 @@ public abstract class AbstractClientConnector implements ClientConnector,
      *            the connector to get children for
      * @return an Iterable giving all child connectors.
      */
-    public static Iterable<ClientConnector> getAllChildrenIterable(
+    public static Iterable<? extends ClientConnector> getAllChildrenIterable(
             final ClientConnector connector) {
-        return new AllChildrenIterable(connector);
+
+        Collection<Extension> extensions = connector.getExtensions();
+        boolean hasComponents = connector instanceof HasComponents;
+        boolean hasExtensions = extensions.size() > 0;
+        if (!hasComponents && !hasExtensions) {
+            // If has neither component nor extensions, return immutable empty
+            // list as iterable.
+            return Collections.emptyList();
+        }
+        if (hasComponents && !hasExtensions) {
+            // only components
+            return (HasComponents) connector;
+        }
+        if (!hasComponents && hasExtensions) {
+            // only extensions
+            return extensions;
+        }
+
+        // combine the iterators of extensions and components to a new iterable.
+        final Iterator<Component> componentsIterator = ((HasComponents) connector)
+                .iterator();
+        final Iterator<Extension> extensionsIterator = extensions.iterator();
+        Iterable<? extends ClientConnector> combinedIterable = new Iterable<ClientConnector>() {
+
+            @Override
+            public Iterator<ClientConnector> iterator() {
+                return new Iterator<ClientConnector>() {
+
+                    @Override
+                    public boolean hasNext() {
+                        return componentsIterator.hasNext()
+                                || extensionsIterator.hasNext();
+                    }
+
+                    @Override
+                    public ClientConnector next() {
+                        if (componentsIterator.hasNext()) {
+                            return componentsIterator.next();
+                        }
+                        if (extensionsIterator.hasNext()) {
+                            return extensionsIterator.next();
+                        }
+                        throw new NoSuchElementException();
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+
+                };
+            }
+        };
+        return combinedIterable;
     }
 
     @Override
index c0f973106be9fd651b63a78d2ab367cd05cf08c2..b5a0227d99d33e268de7066ef10b7b5e40c70e3b 100644 (file)
@@ -366,7 +366,7 @@ public class ConnectorTracker implements Serializable {
             ClientConnector connector = stack.pop();
             danglingConnectors.remove(connector);
 
-            Iterable<ClientConnector> children = AbstractClientConnector
+            Iterable<? extends ClientConnector> children = AbstractClientConnector
                     .getAllChildrenIterable(connector);
             for (ClientConnector child : children) {
                 stack.add(child);
index e938a1cd37a2a9f259b485714f8b9a2aa5aca7bc..63f79504ffb0a9aa657d8fcf2d6d2a361fe11264 100644 (file)
@@ -63,6 +63,8 @@ public class TestClassesSerializable extends TestCase {
             "com\\.vaadin\\.sass.*", //
             "com\\.vaadin\\.testbench.*", //
             "com\\.vaadin\\.util\\.CurrentInstance\\$1", //
+            "com\\.vaadin\\.server\\.AbstractClientConnector\\$1", //
+            "com\\.vaadin\\.server\\.AbstractClientConnector\\$1\\$1", //
             "com\\.vaadin\\.server\\.JsonCodec\\$1", //
             "com\\.vaadin\\.server\\.communication\\.PushConnection", //
             "com\\.vaadin\\.server\\.communication\\.AtmospherePushConnection", //