]> source.dussan.org Git - vaadin-framework.git/commitdiff
Initial extension support (#6690)
authorLeif Åstrand <leif@vaadin.com>
Fri, 25 May 2012 13:09:54 +0000 (16:09 +0300)
committerLeif Åstrand <leif@vaadin.com>
Wed, 6 Jun 2012 06:32:52 +0000 (09:32 +0300)
67 files changed:
src/com/vaadin/terminal/AbstractClientConnector.java [new file with mode: 0644]
src/com/vaadin/terminal/AbstractExtension.java [new file with mode: 0644]
src/com/vaadin/terminal/Extension.java [new file with mode: 0644]
src/com/vaadin/terminal/PaintTarget.java
src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
src/com/vaadin/terminal/gwt/client/ComponentConnector.java
src/com/vaadin/terminal/gwt/client/ComponentContainerConnector.java
src/com/vaadin/terminal/gwt/client/ComponentLocator.java
src/com/vaadin/terminal/gwt/client/ComponentState.java
src/com/vaadin/terminal/gwt/client/Connector.java
src/com/vaadin/terminal/gwt/client/ConnectorMap.java
src/com/vaadin/terminal/gwt/client/LayoutManager.java
src/com/vaadin/terminal/gwt/client/ServerConnector.java
src/com/vaadin/terminal/gwt/client/Util.java
src/com/vaadin/terminal/gwt/client/VDebugConsole.java
src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java
src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java
src/com/vaadin/terminal/gwt/client/WidgetMap.java
src/com/vaadin/terminal/gwt/client/WidgetSet.java
src/com/vaadin/terminal/gwt/client/communication/SharedState.java
src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java
src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java
src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java
src/com/vaadin/terminal/gwt/client/ui/absolutelayout/AbsoluteLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/customcomponent/CustomComponentConnector.java
src/com/vaadin/terminal/gwt/client/ui/customlayout/CustomLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/GreetAgainRpc.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldExtensionConnector.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldRpc.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldState.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/layout/LayoutDependencyTree.java
src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java
src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java
src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java
src/com/vaadin/terminal/gwt/client/ui/table/TableConnector.java
src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java
src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
src/com/vaadin/terminal/gwt/server/ClientConnector.java
src/com/vaadin/terminal/gwt/server/DragAndDropService.java
src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java
src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java
src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java
src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java
src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java
src/com/vaadin/ui/AbsoluteLayout.java
src/com/vaadin/ui/AbstractComponent.java
src/com/vaadin/ui/AbstractComponentContainer.java
src/com/vaadin/ui/Component.java
src/com/vaadin/ui/CssLayout.java
src/com/vaadin/ui/CustomField.java
src/com/vaadin/ui/DirtyConnectorTracker.java
src/com/vaadin/ui/Form.java
src/com/vaadin/ui/HasComponents.java
src/com/vaadin/ui/HelloWorldExtension.java [new file with mode: 0644]
src/com/vaadin/ui/Panel.java
src/com/vaadin/ui/Root.java
src/com/vaadin/ui/Table.java
tests/server-side/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java
tests/server-side/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java
tests/testbench/com/vaadin/tests/features/HelloWorldFeatureTest.java [new file with mode: 0644]

diff --git a/src/com/vaadin/terminal/AbstractClientConnector.java b/src/com/vaadin/terminal/AbstractClientConnector.java
new file mode 100644 (file)
index 0000000..ad7c98b
--- /dev/null
@@ -0,0 +1,452 @@
+package com.vaadin.terminal;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.logging.Logger;
+
+import com.vaadin.Application;
+import com.vaadin.terminal.gwt.client.communication.ClientRpc;
+import com.vaadin.terminal.gwt.client.communication.ServerRpc;
+import com.vaadin.terminal.gwt.client.communication.SharedState;
+import com.vaadin.terminal.gwt.server.ClientConnector;
+import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
+import com.vaadin.terminal.gwt.server.RpcManager;
+import com.vaadin.terminal.gwt.server.RpcTarget;
+import com.vaadin.terminal.gwt.server.ServerRpcManager;
+import com.vaadin.ui.HasComponents;
+import com.vaadin.ui.Root;
+
+/**
+ *
+ */
+public abstract class AbstractClientConnector implements ClientConnector {
+    /**
+     * A map from client to server RPC interface class to the RPC call manager
+     * that handles incoming RPC calls for that interface.
+     */
+    private Map<Class<?>, RpcManager> rpcManagerMap = new HashMap<Class<?>, RpcManager>();
+
+    /**
+     * A map from server to client RPC interface class to the RPC proxy that
+     * sends ourgoing RPC calls for that interface.
+     */
+    private Map<Class<?>, ClientRpc> rpcProxyMap = new HashMap<Class<?>, ClientRpc>();
+
+    /**
+     * Shared state object to be communicated from the server to the client when
+     * modified.
+     */
+    private SharedState sharedState;
+
+    /**
+     * Pending RPC method invocations to be sent.
+     */
+    private ArrayList<ClientMethodInvocation> pendingInvocations = new ArrayList<ClientMethodInvocation>();
+
+    private String connectorId;
+
+    private ArrayList<Extension> extensions = new ArrayList<Extension>();
+
+    private ClientConnector parent;
+
+    /* Documentation copied from interface */
+    public void requestRepaint() {
+        Root root = getRoot();
+        if (root != null) {
+            root.getDirtyConnectorTracker().markDirty(this);
+        }
+    }
+
+    /**
+     * Registers an RPC interface implementation for this component.
+     * 
+     * A component can listen to multiple RPC interfaces, and subclasses can
+     * register additional implementations.
+     * 
+     * @since 7.0
+     * 
+     * @param implementation
+     *            RPC interface implementation
+     * @param rpcInterfaceType
+     *            RPC interface class for which the implementation should be
+     *            registered
+     */
+    protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
+        rpcManagerMap.put(rpcInterfaceType, new ServerRpcManager<T>(
+                implementation, rpcInterfaceType));
+    }
+
+    /**
+     * Registers an RPC interface implementation for this component.
+     * 
+     * A component can listen to multiple RPC interfaces, and subclasses can
+     * register additional implementations.
+     * 
+     * @since 7.0
+     * 
+     * @param implementation
+     *            RPC interface implementation. Also used to deduce the type.
+     */
+    protected <T extends ServerRpc> void registerRpc(T implementation) {
+        Class<?> cls = implementation.getClass();
+        Class<?>[] interfaces = cls.getInterfaces();
+        while (interfaces.length == 0) {
+            // Search upwards until an interface is found. It must be found as T
+            // extends ServerRpc
+            cls = cls.getSuperclass();
+            interfaces = cls.getInterfaces();
+        }
+        if (interfaces.length != 1
+                || !(ServerRpc.class.isAssignableFrom(interfaces[0]))) {
+            throw new RuntimeException(
+                    "Use registerRpc(T implementation, Class<T> rpcInterfaceType) if the Rpc implementation implements more than one interface");
+        }
+        Class<T> type = (Class<T>) interfaces[0];
+        registerRpc(implementation, type);
+    }
+
+    public SharedState getState() {
+        if (null == sharedState) {
+            sharedState = createState();
+        }
+        return sharedState;
+    }
+
+    /**
+     * Creates the shared state bean to be used in server to client
+     * communication.
+     * <p>
+     * By default a state object of the defined return type of
+     * {@link #getState()} is created. Subclasses can override this method and
+     * return a new instance of the correct state class but this should rarely
+     * be necessary.
+     * </p>
+     * <p>
+     * No configuration of the values of the state should be performed in
+     * {@link #createState()}.
+     * 
+     * @since 7.0
+     * 
+     * @return new shared state object
+     */
+    protected SharedState createState() {
+        try {
+            return getStateType().newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Error creating state of type " + getStateType().getName()
+                            + " for " + getClass().getName(), e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.vaadin.terminal.gwt.server.ClientConnector#getStateType()
+     */
+    public Class<? extends SharedState> getStateType() {
+        try {
+            Method m = getClass().getMethod("getState", (Class[]) null);
+            Class<?> type = m.getReturnType();
+            return type.asSubclass(SharedState.class);
+        } catch (Exception e) {
+            throw new RuntimeException("Error finding state type for "
+                    + getClass().getName(), e);
+        }
+    }
+
+    /**
+     * Returns an RPC proxy for a given server to client RPC interface for this
+     * component.
+     * 
+     * TODO more javadoc, subclasses, ...
+     * 
+     * @param rpcInterface
+     *            RPC interface type
+     * 
+     * @since 7.0
+     */
+    public <T extends ClientRpc> T getRpcProxy(final Class<T> rpcInterface) {
+        // create, initialize and return a dynamic proxy for RPC
+        try {
+            if (!rpcProxyMap.containsKey(rpcInterface)) {
+                Class<?> proxyClass = Proxy.getProxyClass(
+                        rpcInterface.getClassLoader(), rpcInterface);
+                Constructor<?> constructor = proxyClass
+                        .getConstructor(InvocationHandler.class);
+                T rpcProxy = rpcInterface.cast(constructor
+                        .newInstance(new RpcInvoicationHandler(rpcInterface)));
+                // cache the proxy
+                rpcProxyMap.put(rpcInterface, rpcProxy);
+            }
+            return (T) rpcProxyMap.get(rpcInterface);
+        } catch (Exception e) {
+            // TODO exception handling?
+            throw new RuntimeException(e);
+        }
+    }
+
+    private class RpcInvoicationHandler implements InvocationHandler,
+            Serializable {
+
+        private String rpcInterfaceName;
+
+        public RpcInvoicationHandler(Class<?> rpcInterface) {
+            rpcInterfaceName = rpcInterface.getName().replaceAll("\\$", ".");
+        }
+
+        public Object invoke(Object proxy, Method method, Object[] args)
+                throws Throwable {
+            addMethodInvocationToQueue(rpcInterfaceName, method, args);
+            // TODO no need to do full repaint if only RPC calls
+            requestRepaint();
+            return null;
+        }
+
+    }
+
+    /**
+     * For internal use: adds a method invocation to the pending RPC call queue.
+     * 
+     * @param interfaceName
+     *            RPC interface name
+     * @param method
+     *            RPC method
+     * @param parameters
+     *            RPC all parameters
+     * 
+     * @since 7.0
+     */
+    protected void addMethodInvocationToQueue(String interfaceName,
+            Method method, Object[] parameters) {
+        // add to queue
+        pendingInvocations.add(new ClientMethodInvocation(this, interfaceName,
+                method, parameters));
+    }
+
+    /**
+     * @see RpcTarget#getRpcManager(Class)
+     * 
+     * @param rpcInterface
+     *            RPC interface for which a call was made
+     * @return RPC Manager handling calls for the interface
+     * 
+     * @since 7.0
+     */
+    public RpcManager getRpcManager(Class<?> rpcInterface) {
+        return rpcManagerMap.get(rpcInterface);
+    }
+
+    public List<ClientMethodInvocation> retrievePendingRpcCalls() {
+        if (pendingInvocations.isEmpty()) {
+            return Collections.emptyList();
+        } else {
+            List<ClientMethodInvocation> result = pendingInvocations;
+            pendingInvocations = new ArrayList<ClientMethodInvocation>();
+            return Collections.unmodifiableList(result);
+        }
+    }
+
+    public String getConnectorId() {
+        if (connectorId == null) {
+            if (getApplication() == null) {
+                throw new RuntimeException(
+                        "Component must be attached to an application when getConnectorId() is called for the first time");
+            }
+            connectorId = getApplication().createConnectorId(this);
+        }
+        return connectorId;
+    }
+
+    /**
+     * Finds the Application to which this connector belongs. If the connector
+     * has not been attached, <code>null</code> is returned.
+     * 
+     * @return The connector's application, or <code>null</code> if not attached
+     */
+    protected Application getApplication() {
+        Root root = getRoot();
+        if (root == null) {
+            return null;
+        } else {
+            return root.getApplication();
+        }
+    }
+
+    /**
+     * Finds a Root ancestor of this connector. <code>null</code> is returned if
+     * no Root ancestor is found (typically because the connector is not
+     * attached to a proper hierarchy).
+     * 
+     * @return the Root ancestor of this connector, or <code>null</code> if none
+     *         is found.
+     */
+    protected Root getRoot() {
+        ClientConnector connector = this;
+        while (connector != null) {
+            if (connector instanceof Root) {
+                return (Root) connector;
+            }
+            connector = connector.getParent();
+        }
+        return null;
+    }
+
+    private static Logger getLogger() {
+        return Logger.getLogger(AbstractClientConnector.class.getName());
+    }
+
+    public void requestRepaintAll() {
+        requestRepaint();
+
+        for (ClientConnector connector : getAllChildrenIteratable(this)) {
+            connector.requestRepaintAll();
+        }
+    }
+
+    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);
+        }
+
+        public boolean hasNext() {
+            for (Iterator<? extends T> i : iterators) {
+                if (i.hasNext()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public T next() {
+            for (Iterator<? extends T> i : iterators) {
+                if (i.hasNext()) {
+                    return i.next();
+                }
+            }
+            throw new NoSuchElementException();
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public static Iterable<ClientConnector> getAllChildrenIteratable(
+            final ClientConnector connector) {
+        return new Iterable<ClientConnector>() {
+            public Iterator<ClientConnector> iterator() {
+                CombinedIterator<ClientConnector> iterator = new CombinedIterator<ClientConnector>();
+                iterator.addIterator(connector.getExtensionIterator());
+
+                if (connector instanceof HasComponents) {
+                    HasComponents hasComponents = (HasComponents) connector;
+                    iterator.addIterator(hasComponents.iterator());
+                }
+
+                return iterator;
+            }
+        };
+    }
+
+    public Iterator<Extension> getExtensionIterator() {
+        return Collections.unmodifiableList(extensions).iterator();
+    }
+
+    protected void addExtension(Extension extension) {
+        addExtensionAtIndex(extension, extensions.size());
+    }
+
+    protected void addExtensionAtIndex(Extension extension, int index) {
+        ClientConnector previousParent = extension.getParent();
+        if (previousParent == this) {
+            int oldIndex = extensions.indexOf(extension);
+            if (oldIndex < index) {
+                index--;
+            }
+            extensions.remove(oldIndex);
+            extensions.add(index, extension);
+        } else {
+            if (previousParent != null) {
+                previousParent.removeExtension(extension);
+            }
+            extensions.add(index, extension);
+            extension.setParent(this);
+        }
+        requestRepaint();
+    }
+
+    public void removeExtension(Extension extension) {
+        extension.setParent(null);
+        extensions.remove(extension);
+        requestRepaint();
+    }
+
+    public void setParent(ClientConnector parent) {
+
+        // If the parent is not changed, don't do anything
+        if (parent == this.parent) {
+            return;
+        }
+
+        if (parent != null && this.parent != null) {
+            throw new IllegalStateException(getClass().getName()
+                    + " already has a parent.");
+        }
+
+        // Send detach event if the component have been connected to a window
+        if (getApplication() != null) {
+            detach();
+        }
+
+        // Connect to new parent
+        this.parent = parent;
+
+        // Send attach event if connected to an application
+        if (getApplication() != null) {
+            attach();
+        }
+    }
+
+    public ClientConnector getParent() {
+        return parent;
+    }
+
+    public void attach() {
+        requestRepaint();
+
+        for (ClientConnector connector : getAllChildrenIteratable(this)) {
+            connector.attach();
+        }
+    }
+
+    public void detach() {
+        for (ClientConnector connector : getAllChildrenIteratable(this)) {
+            connector.detach();
+        }
+    }
+
+    public boolean isConnectorEnabled() {
+        if (getParent() == null) {
+            // No parent -> the component cannot receive updates from the client
+            return false;
+        } else {
+            return getParent().isConnectorEnabled();
+        }
+    }
+}
diff --git a/src/com/vaadin/terminal/AbstractExtension.java b/src/com/vaadin/terminal/AbstractExtension.java
new file mode 100644 (file)
index 0000000..d01f754
--- /dev/null
@@ -0,0 +1,25 @@
+package com.vaadin.terminal;
+
+import com.vaadin.terminal.gwt.server.ClientConnector;
+
+public abstract class AbstractExtension extends AbstractClientConnector implements
+        Extension {
+
+    protected Class<? extends ClientConnector> getAcceptedParentType() {
+        return ClientConnector.class;
+    }
+
+    @Override
+    public void setParent(ClientConnector parent) {
+        Class<? extends ClientConnector> acceptedParentType = getAcceptedParentType();
+        if (parent == null || acceptedParentType.isInstance(parent)) {
+            super.setParent(parent);
+        } else {
+            throw new IllegalArgumentException(getClass().getName()
+                    + " can only be attached to parents of type "
+                    + acceptedParentType.getName() + " but attach to "
+                    + parent.getClass().getName() + " was attempted.");
+        }
+    }
+
+}
diff --git a/src/com/vaadin/terminal/Extension.java b/src/com/vaadin/terminal/Extension.java
new file mode 100644 (file)
index 0000000..7e4b928
--- /dev/null
@@ -0,0 +1,7 @@
+package com.vaadin.terminal;
+
+import com.vaadin.terminal.gwt.server.ClientConnector;
+
+public interface Extension extends ClientConnector {
+
+}
index 9cfa324133427cff1b51910c5d15f29d28016721..b658c9f4a30dfec3cf150e7c76a1d5a9c5768c35 100644 (file)
@@ -9,7 +9,9 @@ import java.util.Map;
 
 import com.vaadin.terminal.StreamVariable.StreamingStartEvent;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.Paintable;
 import com.vaadin.terminal.gwt.server.ClientConnector;
+import com.vaadin.ui.Component;
 
 /**
  * This interface defines the methods for painting XML to the UIDL stream.
@@ -39,7 +41,7 @@ public interface PaintTarget extends Serializable {
 
     /**
      * Result of starting to paint a Paintable (
-     * {@link PaintTarget#startPaintable(ClientConnector, String)}).
+     * {@link PaintTarget#startPaintable(Component, String)}).
      * 
      * @since 7.0
      */
@@ -55,7 +57,7 @@ public interface PaintTarget extends Serializable {
          * changes.
          */
         CACHED
-    };
+    }
 
     /**
      * Prints element start tag of a paintable section. Starts a paintable
@@ -73,8 +75,8 @@ public interface PaintTarget extends Serializable {
      * </p>
      * <p>
      * Each paintable being painted should be closed by a matching
-     * {@link #endPaintable(ClientConnector)} regardless of the
-     * {@link PaintStatus} returned.
+     * {@link #endPaintable(Component)} regardless of the {@link PaintStatus}
+     * returned.
      * </p>
      * 
      * @param paintable
@@ -89,15 +91,15 @@ public interface PaintTarget extends Serializable {
      * @see #startTag(String)
      * @since 7.0 (previously using startTag(Paintable, String))
      */
-    public PaintStatus startPaintable(ClientConnector paintable, String tag)
+    public PaintStatus startPaintable(Component paintable, String tag)
             throws PaintException;
 
     /**
      * Prints paintable element end tag.
      * 
-     * Calls to {@link #startPaintable(ClientConnector, String)}should be
-     * matched by {@link #endPaintable(ClientConnector)}. If the parent tag is
-     * closed before every child tag is closed a PaintException is raised.
+     * Calls to {@link #startPaintable(Component, String)}should be matched by
+     * {@link #endPaintable(Component)}. If the parent tag is closed before
+     * every child tag is closed a PaintException is raised.
      * 
      * @param paintable
      *            the paintable to close.
@@ -105,7 +107,7 @@ public interface PaintTarget extends Serializable {
      *             if the paint operation failed.
      * @since 7.0 (previously using engTag(String))
      */
-    public void endPaintable(ClientConnector paintable) throws PaintException;
+    public void endPaintable(Component paintable) throws PaintException;
 
     /**
      * Prints element start tag.
@@ -289,7 +291,7 @@ public interface PaintTarget extends Serializable {
      *            the Paintable to be referenced on client side
      * @throws PaintException
      */
-    public void addAttribute(String name, ClientConnector value)
+    public void addAttribute(String name, Component value)
             throws PaintException;
 
     /**
@@ -421,8 +423,8 @@ public interface PaintTarget extends Serializable {
      * @throws PaintException
      *             if the paint oparation fails
      */
-    public void addVariable(VariableOwner owner, String name,
-            ClientConnector value) throws PaintException;
+    public void addVariable(VariableOwner owner, String name, Component value)
+            throws PaintException;
 
     /**
      * Adds a upload stream type variable.
index 8eeccb828dd10d607e53a041c09efd89895dbb45..244f310c1a3c3e9d29567ba7ee89d3838b678766 100644 (file)
@@ -209,7 +209,7 @@ public class ApplicationConfiguration implements EntryPoint {
 
     private HashMap<Integer, String> unknownComponents;
 
-    private Class<? extends ComponentConnector>[] classes = new Class[1024];
+    private Class<? extends ServerConnector>[] classes = new Class[1024];
 
     private boolean browserDetailsSent = false;
     private boolean widgetsetVersionSent = false;
@@ -393,7 +393,7 @@ public class ApplicationConfiguration implements EntryPoint {
         return useDebugIdInDom;
     }
 
-    public Class<? extends ComponentConnector> getWidgetClassByEncodedTag(
+    public Class<? extends ServerConnector> getConnectorClassByEncodedTag(
             int tag) {
         try {
             return classes[tag];
@@ -508,7 +508,7 @@ public class ApplicationConfiguration implements EntryPoint {
         public void run() {
             pending = false;
             if (!isBusy()) {
-                Class<? extends ComponentConnector> nextType = getNextType();
+                Class<? extends ServerConnector> nextType = getNextType();
                 if (nextType == null) {
                     // ensured that all widgets are loaded
                     deferredWidgetLoader = null;
@@ -521,13 +521,13 @@ public class ApplicationConfiguration implements EntryPoint {
             }
         }
 
-        private Class<? extends ComponentConnector> getNextType() {
-            Class<? extends ComponentConnector>[] deferredLoadedWidgets = widgetSet
-                    .getDeferredLoadedWidgets();
-            if (deferredLoadedWidgets.length <= nextWidgetIndex) {
+        private Class<? extends ServerConnector> getNextType() {
+            Class<? extends ServerConnector>[] deferredLoadedConnectors = widgetSet
+                    .getDeferredLoadedConnectors();
+            if (deferredLoadedConnectors.length <= nextWidgetIndex) {
                 return null;
             } else {
-                return deferredLoadedWidgets[nextWidgetIndex++];
+                return deferredLoadedConnectors[nextWidgetIndex++];
             }
         }
 
index 51a0ec3f020767034a17b068904c2e9269a3e311..4e7213e7772cdc02fd15b55ed1d691c7b45abfe0 100644 (file)
@@ -1271,27 +1271,24 @@ public class ApplicationConnection {
                 List<ServerConnector> currentConnectors = new ArrayList<ServerConnector>(
                         connectorMap.getConnectors());
                 for (ServerConnector c : currentConnectors) {
-                    if (c instanceof ComponentConnector) {
-                        ComponentConnector cc = (ComponentConnector) c;
-                        if (cc.getParent() != null) {
-                            if (!cc.getParent().getChildren().contains(cc)) {
-                                VConsole.error("ERROR: Connector is connected to a parent but the parent does not contain the connector");
-                            }
-                        } else if ((cc instanceof RootConnector && cc == getRootConnector())) {
-                            // RootConnector for this connection, leave as-is
-                        } else if (cc instanceof WindowConnector
-                                && getRootConnector().hasSubWindow(
-                                        (WindowConnector) cc)) {
-                            // Sub window attached to this RootConnector, leave
-                            // as-is
-                        } else {
-                            // The connector has been detached from the
-                            // hierarchy, unregister it and any possible
-                            // children. The RootConnector should never be
-                            // unregistered even though it has no parent.
-                            connectorMap.unregisterConnector(cc);
-                            unregistered++;
+                    if (c.getParent() != null) {
+                        if (!c.getParent().getChildren().contains(c)) {
+                            VConsole.error("ERROR: Connector is connected to a parent but the parent does not contain the connector");
                         }
+                    } else if ((c instanceof RootConnector && c == getRootConnector())) {
+                        // RootConnector for this connection, leave as-is
+                    } else if (c instanceof WindowConnector
+                            && getRootConnector().hasSubWindow(
+                                    (WindowConnector) c)) {
+                        // Sub window attached to this RootConnector, leave
+                        // as-is
+                    } else {
+                        // The connector has been detached from the
+                        // hierarchy, unregister it and any possible
+                        // children. The RootConnector should never be
+                        // unregistered even though it has no parent.
+                        connectorMap.unregisterConnector(c);
+                        unregistered++;
                     }
 
                 }
@@ -1319,8 +1316,8 @@ public class ApplicationConnection {
                             continue;
                         }
 
-                        Class<? extends ComponentConnector> connectorClass = configuration
-                                .getWidgetClassByEncodedTag(connectorType);
+                        Class<? extends ServerConnector> connectorClass = configuration
+                                .getConnectorClassByEncodedTag(connectorType);
 
                         // Connector does not exist so we must create it
                         if (connectorClass != RootConnector.class) {
@@ -1454,47 +1451,44 @@ public class ApplicationConnection {
                 for (int i = 0; i < hierarchyKeys.length(); i++) {
                     try {
                         String connectorId = hierarchyKeys.get(i);
-                        ServerConnector connector = connectorMap
+                        ServerConnector parentConnector = connectorMap
                                 .getConnector(connectorId);
-                        if (!(connector instanceof ComponentContainerConnector)) {
-                            VConsole.error("Retrieved a hierarchy update for a connector ("
-                                    + connectorId
-                                    + ") that is not a ComponentContainerConnector");
-                            continue;
-                        }
-                        ComponentContainerConnector ccc = (ComponentContainerConnector) connector;
-
                         JsArrayString childConnectorIds = hierarchies
                                 .getJSStringArray(connectorId);
                         int childConnectorSize = childConnectorIds.length();
 
                         List<ServerConnector> newChildren = new ArrayList<ServerConnector>();
+                        List<ComponentConnector> newComponents = new ArrayList<ComponentConnector>();
                         for (int connectorIndex = 0; connectorIndex < childConnectorSize; connectorIndex++) {
                             String childConnectorId = childConnectorIds
                                     .get(connectorIndex);
-                            ComponentConnector childConnector = (ComponentConnector) connectorMap
+                            ServerConnector childConnector = connectorMap
                                     .getConnector(childConnectorId);
                             if (childConnector == null) {
                                 VConsole.error("Hierarchy claims that "
                                         + childConnectorId + " is a child for "
                                         + connectorId + " ("
-                                        + connector.getClass().getName()
+                                        + parentConnector.getClass().getName()
                                         + ") but no connector with id "
                                         + childConnectorId
                                         + " has been registered");
                                 continue;
                             }
                             newChildren.add(childConnector);
-                            if (childConnector.getParent() != ccc) {
+                            if (childConnector instanceof ComponentConnector) {
+                                newComponents
+                                        .add((ComponentConnector) childConnector);
+                            }
+                            if (childConnector.getParent() != parentConnector) {
                                 // Avoid extra calls to setParent
-                                childConnector.setParent(ccc);
+                                childConnector.setParent(parentConnector);
                             }
                         }
 
                         // TODO This check should be done on the server side in
                         // the future so the hierarchy update is only sent when
                         // something actually has changed
-                        List<ComponentConnector> oldChildren = ccc
+                        List<ServerConnector> oldChildren = parentConnector
                                 .getChildren();
                         boolean actuallyChanged = !Util.collectionsEquals(
                                 oldChildren, newChildren);
@@ -1503,19 +1497,34 @@ public class ApplicationConnection {
                             continue;
                         }
 
-                        // Fire change event if the hierarchy has changed
-                        ConnectorHierarchyChangeEvent event = GWT
-                                .create(ConnectorHierarchyChangeEvent.class);
-                        event.setOldChildren(oldChildren);
-                        event.setConnector(ccc);
-                        ccc.setChildren((List) newChildren);
-                        events.add(event);
+                        if (parentConnector instanceof ComponentContainerConnector) {
+                            ComponentContainerConnector ccc = (ComponentContainerConnector) parentConnector;
+                            List<ComponentConnector> oldComponents = ccc
+                                    .getChildComponents();
+                            if (!Util.collectionsEquals(oldComponents,
+                                    newComponents)) {
+                                // Fire change event if the hierarchy has
+                                // changed
+                                ConnectorHierarchyChangeEvent event = GWT
+                                        .create(ConnectorHierarchyChangeEvent.class);
+                                event.setOldChildren(oldComponents);
+                                event.setConnector(parentConnector);
+                                ccc.setChildComponents(newComponents);
+                                events.add(event);
+                            }
+                        } else if (!newComponents.isEmpty()) {
+                            VConsole.error("Hierachy claims "
+                                    + Util.getConnectorString(parentConnector)
+                                    + " has component children even though it isn't a ComponentContainerConnector");
+                        }
+
+                        parentConnector.setChildren(newChildren);
 
                         // Remove parent for children that are no longer
                         // attached to this (avoid updating children if they
                         // have already been assigned to a new parent)
-                        for (ComponentConnector oldChild : oldChildren) {
-                            if (oldChild.getParent() != ccc) {
+                        for (ServerConnector oldChild : oldChildren) {
+                            if (oldChild.getParent() != parentConnector) {
                                 continue;
                             }
 
@@ -2079,7 +2088,9 @@ public class ApplicationConnection {
 
     @Deprecated
     public ComponentConnector getPaintable(UIDL uidl) {
-        return getConnector(uidl.getId(), Integer.parseInt(uidl.getTag()));
+        // Non-component connectors shouldn't be painted from legacy connectors
+        return (ComponentConnector) getConnector(uidl.getId(),
+                Integer.parseInt(uidl.getTag()));
     }
 
     /**
@@ -2098,17 +2109,17 @@ public class ApplicationConnection {
      * @return Either an existing ComponentConnector or a new ComponentConnector
      *         of the given type
      */
-    public ComponentConnector getConnector(String connectorId, int connectorType) {
+    public ServerConnector getConnector(String connectorId, int connectorType) {
         if (!connectorMap.hasConnector(connectorId)) {
             return createAndRegisterConnector(connectorId, connectorType);
         }
-        return (ComponentConnector) connectorMap.getConnector(connectorId);
+        return connectorMap.getConnector(connectorId);
     }
 
     /**
-     * Creates a new ComponentConnector with the given type and id.
+     * Creates a new ServerConnector with the given type and id.
      * 
-     * Creates and registers a new ComponentConnector of the given type. Should
+     * Creates and registers a new ServerConnector of the given type. Should
      * never be called with the connector id of an existing connector.
      * 
      * @param connectorId
@@ -2116,13 +2127,13 @@ public class ApplicationConnection {
      * @param connectorType
      *            Type of the connector, as passed from the server side
      * 
-     * @return A new ComponentConnector of the given type
+     * @return A new ServerConnector of the given type
      */
-    private ComponentConnector createAndRegisterConnector(String connectorId,
+    private ServerConnector createAndRegisterConnector(String connectorId,
             int connectorType) {
         // Create and register a new connector with the given type
-        ComponentConnector p = widgetSet.createWidget(connectorType,
-                configuration);
+        ServerConnector p = widgetSet
+                .createWidget(connectorType, configuration);
         connectorMap.registerConnector(connectorId, p);
         p.doInit(connectorId, this);
 
index 5f9171084e1708d047e42e61c5ba57b67ea4f36f..4e6a690a3c64a3b4bea50cb951140c17932fe366 100644 (file)
@@ -70,29 +70,6 @@ public interface ComponentConnector extends ServerConnector {
      */
     public boolean isRelativeHeight();
 
-    /**
-     * Returns the parent of this connector. Can be null for only the root
-     * connector.
-     * 
-     * @return The parent of this connector, as set by
-     *         {@link #setParent(ComponentContainerConnector)}.
-     */
-    public ComponentContainerConnector getParent();
-
-    /**
-     * Sets the parent for this connector. This method should only be called by
-     * the framework to ensure that the connector hierarchy on the client side
-     * and the server side are in sync.
-     * <p>
-     * Note that calling this method does not fire a
-     * {@link ConnectorHierarchyChangeEvent}. The event is fired only when the
-     * whole hierarchy has been updated.
-     * 
-     * @param parent
-     *            The new parent of the connector
-     */
-    public void setParent(ComponentContainerConnector parent);
-
     /**
      * Checks if the connector is read only.
      * 
index 05334e8049b026ab05885a5c732a7bee2294d13e..08ce3d31dc19c87db9bc0432c76748a6eaa93a1d 100644 (file)
@@ -14,7 +14,7 @@ import com.vaadin.terminal.gwt.client.ConnectorHierarchyChangeEvent.ConnectorHie
  * An interface used by client-side connectors whose widget is a component
  * container (implements {@link HasWidgets}).
  */
-public interface ComponentContainerConnector extends ComponentConnector {
+public interface ComponentContainerConnector extends ServerConnector {
 
     /**
      * Update child components caption, description and error message.
@@ -42,7 +42,7 @@ public interface ComponentContainerConnector extends ComponentConnector {
      * @return A collection of children for this connector. An empty collection
      *         if there are no children. Never returns null.
      */
-    public List<ComponentConnector> getChildren();
+    public List<ComponentConnector> getChildComponents();
 
     /**
      * Sets the children for this connector. This method should only be called
@@ -50,14 +50,14 @@ public interface ComponentContainerConnector extends ComponentConnector {
      * side and the server side are in sync.
      * <p>
      * Note that calling this method does not call
-     * {@link #connectorHierarchyChanged(ConnectorHierarchyChangeEvent)}. The
-     * event method is called only when the hierarchy has been updated for all
-     * connectors.
+     * {@link ConnectorHierarchyChangeHandler#onConnectorHierarchyChange(ConnectorHierarchyChangeEvent)}
+     * . The event method is called only when the hierarchy has been updated for
+     * all connectors.
      * 
      * @param children
      *            The new child connectors
      */
-    public void setChildren(List<ComponentConnector> children);
+    public void setChildComponents(List<ComponentConnector> children);
 
     /**
      * Adds a handler that is called whenever the child hierarchy of this
index d847d49e6fd51e97817588bfac676d2567392403..205317542f02732319ed2d6a59d29a902bef30a9 100644 (file)
@@ -11,7 +11,9 @@ import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.communication.SharedState;
 import com.vaadin.terminal.gwt.client.ui.SubPartAware;
 import com.vaadin.terminal.gwt.client.ui.gridlayout.VGridLayout;
 import com.vaadin.terminal.gwt.client.ui.orderedlayout.VMeasuringOrderedLayout;
@@ -440,8 +442,8 @@ public class ComponentLocator {
             } else if (w == null) {
                 String id = part;
                 // Must be old static pid (PID_S*)
-                ComponentConnector connector = (ComponentConnector) ConnectorMap
-                        .get(client).getConnector(id);
+                ServerConnector connector = ConnectorMap.get(client)
+                        .getConnector(id);
                 if (connector == null) {
                     // Lookup by debugId
                     // TODO Optimize this
@@ -449,8 +451,8 @@ public class ComponentLocator {
                             id.substring(5));
                 }
 
-                if (connector != null) {
-                    w = connector.getWidget();
+                if (connector instanceof ComponentConnector) {
+                    w = ((SimplePanel) connector).getWidget();
                 } else {
                     // Not found
                     return null;
@@ -588,19 +590,16 @@ public class ComponentLocator {
         return w;
     }
 
-    private ComponentConnector findConnectorById(ComponentConnector root,
-            String id) {
-        if (root instanceof ComponentConnector
-                && id.equals(root.getState().getDebugId())) {
+    private ServerConnector findConnectorById(ServerConnector root, String id) {
+        SharedState state = root.getState();
+        if (state instanceof ComponentState
+                && id.equals(((ComponentState) state).getDebugId())) {
             return root;
         }
-        if (root instanceof ComponentContainerConnector) {
-            ComponentContainerConnector ccc = (ComponentContainerConnector) root;
-            for (ComponentConnector child : ccc.getChildren()) {
-                ComponentConnector found = findConnectorById(child, id);
-                if (found != null) {
-                    return found;
-                }
+        for (ServerConnector child : root.getChildren()) {
+            ServerConnector found = findConnectorById(child, id);
+            if (found != null) {
+                return found;
             }
         }
 
index 10cd14251b65b606a99450f00d51504a04d6b8cf..9cd5c6f6686f77b094d2a9a439ff0e4a1b592e00 100644 (file)
@@ -24,7 +24,6 @@ public class ComponentState extends SharedState {
     private String width = "";
     private boolean readOnly = false;
     private boolean immediate = false;
-    private boolean enabled = true;
     private String description = "";
     // Note: for the caption, there is a difference between null and an empty
     // string!
@@ -174,29 +173,6 @@ public class ComponentState extends SharedState {
         return styles != null && !styles.isEmpty();
     }
 
-    /**
-     * Returns true if the component is enabled.
-     * 
-     * @see com.vaadin.ui.Component#isEnabled()
-     * 
-     * @return true if the component is enabled
-     */
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    /**
-     * Enables or disables the component.
-     * 
-     * @see com.vaadin.ui.Component#setEnabled(boolean)
-     * 
-     * @param enabled
-     *            new mode for the component
-     */
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
     /**
      * Gets the description of the component (typically shown as tooltip).
      * 
index 1c6105273514d279bc2735e811f5677ec1573ef1..9b2fcf61f18ec4401fb55c39d847489cb500e25e 100644 (file)
@@ -46,4 +46,12 @@ public interface Connector extends Serializable {
      */
     public String getConnectorId();
 
+    /**
+     * Gets the parent connector of this connector, or <code>null</code> if the
+     * connector is not attached to any parent.
+     * 
+     * @return the parent connector, or <code>null</code> if there is no parent.
+     */
+    public Connector getParent();
+
 }
index e57776cf1c628a3c57028303ba3e1a1272802e75..816c4f62e3757654f6402de98cca3e0efebfe8a1 100644 (file)
@@ -159,17 +159,16 @@ public class ConnectorMap {
         idToConnector.remove(connectorId);
         connector.onUnregister();
 
-        if (connector instanceof ComponentContainerConnector) {
-            for (ComponentConnector child : ((ComponentContainerConnector) connector)
-                    .getChildren()) {
-                if (child.getParent() == connector) {
-                    // Only unregister children that are actually connected to
-                    // this parent. For instance when moving connectors from one
-                    // layout to another and removing the first layout it will
-                    // still contain references to its old children, which are
-                    // now attached to another connector.
-                    unregisterConnector(child);
-                }
+        for (ServerConnector child : connector.getChildren()) {
+            if (child.getParent() == connector) {
+                /*
+                 * Only unregister children that are actually connected to this
+                 * parent. For instance when moving connectors from one layout
+                 * to another and removing the first layout it will still
+                 * contain references to its old children, which are now
+                 * attached to another connector.
+                 */
+                unregisterConnector(child);
             }
         }
     }
index 9390c719fc919123acdb2284d0ddccd928a6be88..2281b4ab9c04bcc469a0a5ba6ddc194f42280a4c 100644 (file)
@@ -416,11 +416,13 @@ public class LayoutManager {
             for (ComponentConnector componentConnector : pendingOverflowFixes) {
                 // Delay the overflow fix if the involved connectors might still
                 // change
-                if (!currentDependencyTree
-                        .noMoreChangesExpected(componentConnector)
-                        || !currentDependencyTree
-                                .noMoreChangesExpected(componentConnector
-                                        .getParent())) {
+                boolean connectorChangesExpected = !currentDependencyTree
+                        .noMoreChangesExpected(componentConnector);
+                boolean parentChangesExcpected = componentConnector.getParent() instanceof ComponentConnector
+                        && !currentDependencyTree
+                                .noMoreChangesExpected((ComponentConnector) componentConnector
+                                        .getParent());
+                if (connectorChangesExpected || parentChangesExcpected) {
                     delayedOverflowFixes.add(componentConnector);
                     continue;
                 }
index 44f65fc6a7b6be8e19c53695c6dd78a0a3bc7dd9..3809073076febee20a184a1535dd0b04f57e5bf3 100644 (file)
@@ -4,6 +4,7 @@
 package com.vaadin.terminal.gwt.client;
 
 import java.util.Collection;
+import java.util.List;
 
 import com.google.gwt.event.shared.GwtEvent;
 import com.google.web.bindery.event.shared.HandlerRegistration;
@@ -85,4 +86,32 @@ public interface ServerConnector extends Connector {
      */
     public void onUnregister();
 
+    /**
+     * Returns the parent of this connector. Can be null for only the root
+     * connector.
+     * 
+     * @return The parent of this connector, as set by
+     *         {@link #setParent(ServerConnector)}.
+     */
+    public ServerConnector getParent();
+
+    /**
+     * Sets the parent for this connector. This method should only be called by
+     * the framework to ensure that the connector hierarchy on the client side
+     * and the server side are in sync.
+     * <p>
+     * Note that calling this method does not fire a
+     * {@link ConnectorHierarchyChangeEvent}. The event is fired only when the
+     * whole hierarchy has been updated.
+     * 
+     * @param parent
+     *            The new parent of the connector
+     */
+    public void setParent(ServerConnector parent);
+
+    public void updateEnabledState(boolean enabledState);
+
+    public void setChildren(List<ServerConnector> children);
+
+    public List<ServerConnector> getChildren();
 }
index c392a0ba9c82e62463da952de926b371068f98a3..87bf27fc2700e137f9fdc8449dea0d1d858c5b91 100644 (file)
@@ -812,13 +812,12 @@ public class Util {
         return idx;
     }
 
-    private static void printPaintablesInvocations(
+    private static void printConnectorInvocations(
             ArrayList<MethodInvocation> invocations, String id,
             ApplicationConnection c) {
-        ComponentConnector paintable = (ComponentConnector) ConnectorMap.get(c)
-                .getConnector(id);
-        if (paintable != null) {
-            VConsole.log("\t" + id + " (" + paintable.getClass() + ") :");
+        ServerConnector connector = ConnectorMap.get(c).getConnector(id);
+        if (connector != null) {
+            VConsole.log("\t" + id + " (" + connector.getClass() + ") :");
             for (MethodInvocation invocation : invocations) {
                 Object[] parameters = invocation.getParameters();
                 String formattedParams = null;
@@ -842,7 +841,7 @@ public class Util {
                         + ")");
             }
         } else {
-            VConsole.log("\t" + id + ": Warning: no corresponding paintable!");
+            VConsole.log("\t" + id + ": Warning: no corresponding connector!");
         }
     }
 
@@ -858,14 +857,14 @@ public class Util {
                 if (curId == null) {
                     curId = id;
                 } else if (!curId.equals(id)) {
-                    printPaintablesInvocations(invocations, curId, c);
+                    printConnectorInvocations(invocations, curId, c);
                     invocations.clear();
                     curId = id;
                 }
                 invocations.add(loggedBurst.get(i));
             }
             if (!invocations.isEmpty()) {
-                printPaintablesInvocations(invocations, curId, c);
+                printConnectorInvocations(invocations, curId, c);
             }
         } catch (Exception e) {
             VConsole.error(e);
index 5eaf78f255cef3b7879c90422b74abd4bf1686a8..09e939336e34c632b7c727eea1585c8c787f3784 100644 (file)
@@ -560,23 +560,27 @@ public class VDebugConsole extends VOverlay implements Console {
             Set<ComponentConnector> zeroHeightComponents,
             ApplicationConnection ac) {
         for (final ComponentConnector paintable : zeroHeightComponents) {
-            final Widget layout = paintable.getParent().getWidget();
+            final ServerConnector parent = paintable.getParent();
 
             VerticalPanel errorDetails = new VerticalPanel();
             errorDetails.add(new Label("" + Util.getSimpleName(paintable)
-                    + " inside " + Util.getSimpleName(layout)));
-            final CheckBox emphasisInUi = new CheckBox(
-                    "Emphasize components parent in UI (the actual component is not visible)");
-            emphasisInUi.addClickHandler(new ClickHandler() {
-                public void onClick(ClickEvent event) {
-                    if (paintable != null) {
+                    + " inside " + Util.getSimpleName(parent)));
+            if (parent instanceof ComponentConnector) {
+                ComponentConnector parentComponent = (ComponentConnector) parent;
+                final Widget layout = parentComponent.getWidget();
+
+                final CheckBox emphasisInUi = new CheckBox(
+                        "Emphasize components parent in UI (the actual component is not visible)");
+                emphasisInUi.addClickHandler(new ClickHandler() {
+                    public void onClick(ClickEvent event) {
                         Element element2 = layout.getElement();
                         Widget.setStyleName(element2, "invalidlayout",
-                                emphasisInUi.getValue());
+                                emphasisInUi.getValue().booleanValue());
                     }
-                }
-            });
-            errorDetails.add(emphasisInUi);
+                });
+
+                errorDetails.add(emphasisInUi);
+            }
             panel.add(errorDetails);
         }
     }
@@ -862,7 +866,7 @@ public class VDebugConsole extends VOverlay implements Console {
         log("================");
         log("Connector hierarchy for Root: " + root.getState().getCaption()
                 + " (" + root.getConnectorId() + ")");
-        Set<ComponentConnector> connectorsInHierarchy = new HashSet<ComponentConnector>();
+        Set<ServerConnector> connectorsInHierarchy = new HashSet<ServerConnector>();
         SimpleTree rootHierachy = dumpConnectorHierarchy(root, "",
                 connectorsInHierarchy);
         if (panel.isAttached()) {
@@ -874,7 +878,7 @@ public class VDebugConsole extends VOverlay implements Console {
         Collection<? extends ServerConnector> registeredConnectors = connectorMap
                 .getConnectors();
         log("Sub windows:");
-        Set<ComponentConnector> subWindowHierarchyConnectors = new HashSet<ComponentConnector>();
+        Set<ServerConnector> subWindowHierarchyConnectors = new HashSet<ServerConnector>();
         for (WindowConnector wc : root.getSubWindows()) {
             SimpleTree windowHierachy = dumpConnectorHierarchy(wc, "",
                     subWindowHierarchyConnectors);
@@ -908,14 +912,15 @@ public class VDebugConsole extends VOverlay implements Console {
 
     }
 
-    private SimpleTree dumpConnectorHierarchy(
-            final ComponentConnector connector, String indent,
-            Set<ComponentConnector> connectors) {
+    private SimpleTree dumpConnectorHierarchy(final ServerConnector connector,
+            String indent, Set<ServerConnector> connectors) {
         SimpleTree simpleTree = new SimpleTree(getConnectorString(connector)) {
             @Override
             protected void select(ClickEvent event) {
                 super.select(event);
-                VUIDLBrowser.highlight(connector);
+                if (connector instanceof ComponentConnector) {
+                    VUIDLBrowser.highlight((ComponentConnector) connector);
+                }
             }
         };
         simpleTree.addDomHandler(new MouseOutHandler() {
@@ -930,12 +935,8 @@ public class VDebugConsole extends VOverlay implements Console {
         consoleLog(msg);
         System.out.println(msg);
 
-        if (connector instanceof ComponentContainerConnector) {
-            for (ComponentConnector c : ((ComponentContainerConnector) connector)
-                    .getChildren()) {
-                simpleTree.add(dumpConnectorHierarchy(c, indent + " ",
-                        connectors));
-            }
+        for (ServerConnector c : connector.getChildren()) {
+            simpleTree.add(dumpConnectorHierarchy(c, indent + " ", connectors));
         }
         return simpleTree;
     }
index 9fa973dc290e4becc95eb11e45230785e726a1a7..4230eda2982fab14300a2776177496daea5978e3 100644 (file)
@@ -98,8 +98,8 @@ public class VUIDLBrowser extends SimpleTree {
 
         private String getNodeName(UIDL uidl, ApplicationConfiguration conf,
                 int tag) {
-            Class<? extends ComponentConnector> widgetClassByDecodedTag = conf
-                    .getWidgetClassByEncodedTag(tag);
+            Class<? extends ServerConnector> widgetClassByDecodedTag = conf
+                    .getConnectorClassByEncodedTag(tag);
             if (widgetClassByDecodedTag == UnknownComponentConnector.class) {
                 return conf.getUnknownServerClassNameByTag(tag)
                         + "(NO CLIENT IMPLEMENTATION FOUND)";
index dd69883d5850c0a5f1b06f936b0c71d7e9f74b3a..0a4f92bc79d1c562a33835d3ae54bdbf8fe7b442 100644 (file)
@@ -7,5 +7,5 @@ package com.vaadin.terminal.gwt.client;
  * A helper class used by WidgetMap implementation. Used by the generated code.
  */
 interface WidgetInstantiator {
-    public ComponentConnector get();
+    public ServerConnector get();
 }
index af84a11ced7d6da92d9dfabf809fbbf5ac5b31b8..b77041445788f1bc1f0be3684462a2954877b850 100644 (file)
@@ -17,7 +17,7 @@ import com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator;
  */
 abstract class WidgetMap {
 
-    protected static HashMap<Class, WidgetInstantiator> instmap = new HashMap<Class, WidgetInstantiator>();
+    protected static HashMap<Class<? extends ServerConnector>, WidgetInstantiator> instmap = new HashMap<Class<? extends ServerConnector>, WidgetInstantiator>();
 
     /**
      * Create a new instance of a connector based on its type.
@@ -26,8 +26,8 @@ abstract class WidgetMap {
      *            {@link ComponentConnector} class to instantiate
      * @return new instance of the connector
      */
-    public ComponentConnector instantiate(
-            Class<? extends ComponentConnector> classType) {
+    public ServerConnector instantiate(
+            Class<? extends ServerConnector> classType) {
         return instmap.get(classType).get();
     }
 
@@ -39,7 +39,7 @@ abstract class WidgetMap {
      *            fully qualified name of the server side component class
      * @return component connector class to use
      */
-    public abstract Class<? extends ComponentConnector> getConnectorClassForServerSideClassName(
+    public abstract Class<? extends ServerConnector> getConnectorClassForServerSideClassName(
             String fullyqualifiedName);
 
     /**
@@ -49,7 +49,7 @@ abstract class WidgetMap {
      * @return component connector class to load after the initial widgetset
      *         loading
      */
-    public abstract Class<? extends ComponentConnector>[] getDeferredLoadedWidgets();
+    public abstract Class<? extends ServerConnector>[] getDeferredLoadedConnectors();
 
     /**
      * Make sure the code for a (deferred or lazy) component connector type has
@@ -60,6 +60,6 @@ abstract class WidgetMap {
      *            component connector class
      */
     public abstract void ensureInstantiator(
-            Class<? extends ComponentConnector> classType);
+            Class<? extends ServerConnector> classType);
 
 }
index e47837296d0a49e43cab3d3ec2df8fd62e98e857..a973c4fd05f667e9ea0afbe37a2ce811ef398c66 100644 (file)
@@ -18,20 +18,19 @@ public class WidgetSet {
     private WidgetMap widgetMap = GWT.create(WidgetMap.class);
 
     /**
-     * Create an uninitialized component that best matches given UIDL. The
-     * component must be a {@link Widget} that implements
-     * {@link ComponentConnector}.
+     * Create an uninitialized connector that best matches given UIDL. The
+     * connector must be a {@link Widget} that implements
+     * {@link ServerConnector}.
      * 
      * @param tag
-     *            component type tag for the component to create
+     *            connector type tag for the connector to create
      * @param client
      *            the application connection that whishes to instantiate widget
      * 
-     * @return New uninitialized and unregistered component that can paint given
+     * @return New uninitialized and unregistered connector that can paint given
      *         UIDL.
      */
-    public ComponentConnector createWidget(int tag,
-            ApplicationConfiguration conf) {
+    public ServerConnector createWidget(int tag, ApplicationConfiguration conf) {
         /*
          * Yes, this (including the generated code in WidgetMap) may look very
          * odd code, but due the nature of GWT, we cannot do this any cleaner.
@@ -40,7 +39,7 @@ public class WidgetSet {
          * has no "native" counterpart on client side.
          */
 
-        Class<? extends ComponentConnector> classType = resolveInheritedWidgetType(
+        Class<? extends ServerConnector> classType = resolveInheritedWidgetType(
                 conf, tag);
 
         if (classType == null || classType == UnknownComponentConnector.class) {
@@ -57,9 +56,9 @@ public class WidgetSet {
         }
     }
 
-    private Class<? extends ComponentConnector> resolveInheritedWidgetType(
+    private Class<? extends ServerConnector> resolveInheritedWidgetType(
             ApplicationConfiguration conf, int tag) {
-        Class<? extends ComponentConnector> classType = null;
+        Class<? extends ServerConnector> classType = null;
         Integer t = tag;
         do {
             classType = resolveWidgetType(t, conf);
@@ -68,10 +67,10 @@ public class WidgetSet {
         return classType;
     }
 
-    protected Class<? extends ComponentConnector> resolveWidgetType(int tag,
+    protected Class<? extends ServerConnector> resolveWidgetType(int tag,
             ApplicationConfiguration conf) {
-        Class<? extends ComponentConnector> widgetClass = conf
-                .getWidgetClassByEncodedTag(tag);
+        Class<? extends ServerConnector> widgetClass = conf
+                .getConnectorClassByEncodedTag(tag);
 
         return widgetClass;
     }
@@ -85,9 +84,9 @@ public class WidgetSet {
      * @param applicationConfiguration
      * @return
      */
-    public Class<? extends ComponentConnector> getConnectorClassByTag(int tag,
+    public Class<? extends ServerConnector> getConnectorClassByTag(int tag,
             ApplicationConfiguration conf) {
-        Class<? extends ComponentConnector> connectorClass = null;
+        Class<? extends ServerConnector> connectorClass = null;
         Integer t = tag;
         do {
             String serverSideClassName = conf.getServerSideClassNameForTag(t);
@@ -99,11 +98,11 @@ public class WidgetSet {
         return connectorClass;
     }
 
-    public Class<? extends ComponentConnector>[] getDeferredLoadedWidgets() {
-        return widgetMap.getDeferredLoadedWidgets();
+    public Class<? extends ServerConnector>[] getDeferredLoadedConnectors() {
+        return widgetMap.getDeferredLoadedConnectors();
     }
 
-    public void loadImplementation(Class<? extends ComponentConnector> nextType) {
+    public void loadImplementation(Class<? extends ServerConnector> nextType) {
         widgetMap.ensureInstantiator(nextType);
     }
 
index 266d6bcbf21eb262a96377c295c831df0e69458e..b087907f9e18de491164e13eb370e8a4030bd607 100644 (file)
@@ -38,4 +38,30 @@ import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector;
  * @since 7.0
  */
 public class SharedState implements Serializable {
+
+    private boolean enabled = true;
+
+    /**
+     * Returns true if the component is enabled.
+     * 
+     * @see com.vaadin.ui.Component#isEnabled()
+     * 
+     * @return true if the component is enabled
+     */
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    /**
+     * Enables or disables the component.
+     * 
+     * @see com.vaadin.ui.Component#setEnabled(boolean)
+     * 
+     * @param enabled
+     *            new mode for the component
+     */
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
 }
index d690bdded18f605a06c2a35efdc8a09403de074d..67dbd2d9d95c56e5764c4376cea8ab22f68f015e 100644 (file)
@@ -12,8 +12,10 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
 import com.vaadin.terminal.gwt.client.ComponentContainerConnector;
 import com.vaadin.terminal.gwt.client.ComponentState;
+import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.ConnectorMap;
 import com.vaadin.terminal.gwt.client.LayoutManager;
+import com.vaadin.terminal.gwt.client.ServerConnector;
 import com.vaadin.terminal.gwt.client.TooltipInfo;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
@@ -24,8 +26,6 @@ import com.vaadin.terminal.gwt.client.ui.root.RootConnector;
 public abstract class AbstractComponentConnector extends AbstractConnector
         implements ComponentConnector {
 
-    private ComponentContainerConnector parent;
-
     private Widget widget;
 
     private String lastKnownWidth = "";
@@ -73,8 +73,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
 
     @Override
     public void onStateChanged(StateChangeEvent stateChangeEvent) {
-        super.onStateChanged(stateChangeEvent);
-
         ConnectorMap paintableMap = ConnectorMap.get(getConnection());
 
         if (getState().getDebugId() != null) {
@@ -86,7 +84,8 @@ public abstract class AbstractComponentConnector extends AbstractConnector
 
         /*
          * Disabled state may affect (override) tabindex so the order must be
-         * first setting tabindex, then enabled state.
+         * first setting tabindex, then enabled state (through super
+         * implementation).
          */
         if (getState() instanceof TabIndexState
                 && getWidget() instanceof Focusable) {
@@ -94,7 +93,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector
                     .getTabIndex());
         }
 
-        setWidgetEnabled(isEnabled());
+        super.onStateChanged(stateChangeEvent);
 
         // Style names
         String styleName = getStyleNames(getWidget().getStylePrimaryName());
@@ -112,10 +111,10 @@ public abstract class AbstractComponentConnector extends AbstractConnector
 
         // Set captions
         if (delegateCaptionHandling()) {
-            ComponentContainerConnector parent = getParent();
-            if (parent != null) {
-                parent.updateCaption(this);
-            } else if (!(this instanceof RootConnector)) {
+            ServerConnector parent = getParent();
+            if (parent instanceof ComponentContainerConnector) {
+                ((ComponentContainerConnector) parent).updateCaption(this);
+            } else if (parent == null && !(this instanceof RootConnector)) {
                 VConsole.error("Parent of connector "
                         + Util.getConnectorString(this)
                         + " is null. This is typically an indication of a broken component hierarchy");
@@ -143,7 +142,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         // Parent should be updated if either dimension changed between relative
         // and non-relative
         if (newWidth.endsWith("%") != lastKnownWidth.endsWith("%")) {
-            ComponentContainerConnector parent = getParent();
+            Connector parent = getParent();
             if (parent instanceof ManagedLayout) {
                 getLayoutManager().setNeedsHorizontalLayout(
                         (ManagedLayout) parent);
@@ -151,7 +150,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         }
 
         if (newHeight.endsWith("%") != lastKnownHeight.endsWith("%")) {
-            ComponentContainerConnector parent = getParent();
+            Connector parent = getParent();
             if (parent instanceof ManagedLayout) {
                 getLayoutManager().setNeedsVerticalLayout(
                         (ManagedLayout) parent);
@@ -187,23 +186,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         return getState().getWidth().length() == 0;
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see com.vaadin.terminal.gwt.client.Connector#isEnabled()
-     */
-    public boolean isEnabled() {
-        if (!getState().isEnabled()) {
-            return false;
-        }
-
-        if (getParent() == null) {
-            return true;
-        } else {
-            return getParent().isEnabled();
-        }
-    }
-
     /*
      * (non-Javadoc)
      * 
@@ -284,26 +266,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         return LayoutManager.get(getConnection());
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see com.vaadin.terminal.gwt.client.Connector#getParent()
-     */
-    public ComponentContainerConnector getParent() {
-        return parent;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.vaadin.terminal.gwt.client.Connector#setParent(com.vaadin.terminal
-     * .gwt.client.ComponentContainerConnector)
-     */
-    public void setParent(ComponentContainerConnector parent) {
-        this.parent = parent;
-    }
-
     /**
      * Checks if there is a registered server side listener for the given event
      * identifier.
@@ -318,6 +280,13 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         return (reg != null && reg.contains(eventIdentifier));
     }
 
+    @Override
+    public void updateEnabledState(boolean enabledState) {
+        super.updateEnabledState(enabledState);
+
+        setWidgetEnabled(isEnabled());
+    }
+
     @Override
     public void onUnregister() {
         super.onUnregister();
index 526631e4b2197265fc792f325cc0fdf6c421b3bd..c6bfba5023d800cff592f7adfa6a9500516a0650 100644 (file)
@@ -3,7 +3,7 @@
  */
 package com.vaadin.terminal.gwt.client.ui;
 
-import java.util.LinkedList;
+import java.util.Collections;
 import java.util.List;
 
 import com.google.gwt.event.shared.HandlerRegistration;
@@ -18,18 +18,10 @@ public abstract class AbstractComponentContainerConnector extends
         AbstractComponentConnector implements ComponentContainerConnector,
         ConnectorHierarchyChangeHandler {
 
-    List<ComponentConnector> children;
+    List<ComponentConnector> childComponents;
 
     private final boolean debugLogging = false;
 
-    /**
-     * Temporary storage for last enabled state to be able to see if it has
-     * changed. Can be removed once we are able to listen specifically for
-     * enabled changes in the state. Widget.isEnabled() cannot be used as all
-     * Widgets do not implement HasEnabled
-     */
-    private boolean lastWidgetEnabledState = true;
-
     /**
      * Default constructor
      */
@@ -43,12 +35,12 @@ public abstract class AbstractComponentContainerConnector extends
      * @see
      * com.vaadin.terminal.gwt.client.ComponentContainerConnector#getChildren()
      */
-    public List<ComponentConnector> getChildren() {
-        if (children == null) {
-            return new LinkedList<ComponentConnector>();
+    public List<ComponentConnector> getChildComponents() {
+        if (childComponents == null) {
+            return Collections.emptyList();
         }
 
-        return children;
+        return childComponents;
     }
 
     /*
@@ -58,8 +50,8 @@ public abstract class AbstractComponentContainerConnector extends
      * com.vaadin.terminal.gwt.client.ComponentContainerConnector#setChildren
      * (java.util.Collection)
      */
-    public void setChildren(List<ComponentConnector> children) {
-        this.children = children;
+    public void setChildComponents(List<ComponentConnector> childComponents) {
+        this.childComponents = childComponents;
     }
 
     /*
@@ -80,7 +72,7 @@ public abstract class AbstractComponentContainerConnector extends
             VConsole.log(oldChildren);
 
             String newChildren = "* New children: ";
-            for (ComponentConnector child : getChildren()) {
+            for (ComponentConnector child : getChildComponents()) {
                 newChildren += Util.getConnectorString(child) + " ";
             }
             VConsole.log(newChildren);
@@ -92,19 +84,4 @@ public abstract class AbstractComponentContainerConnector extends
         return ensureHandlerManager().addHandler(
                 ConnectorHierarchyChangeEvent.TYPE, handler);
     }
-
-    @Override
-    public void setWidgetEnabled(boolean widgetEnabled) {
-        if (lastWidgetEnabledState == widgetEnabled) {
-            return;
-        }
-        lastWidgetEnabledState = widgetEnabled;
-
-        super.setWidgetEnabled(widgetEnabled);
-        for (ComponentConnector c : getChildren()) {
-            // Update children as they might be affected by the enabled state of
-            // their parent
-            c.setWidgetEnabled(c.isEnabled());
-        }
-    }
 }
index dc960f90a5a508009b65eb55e21835cbfb1e7ec1..bee9c75165169dc7d1b8ff951c6e4c422a2ecd62 100644 (file)
@@ -7,6 +7,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import com.google.gwt.event.shared.GwtEvent;
@@ -40,6 +41,16 @@ public abstract class AbstractConnector implements ServerConnector,
     private final boolean debugLogging = false;
 
     private SharedState state;
+    private ServerConnector parent;
+
+    /**
+     * Temporary storage for last enabled state to be able to see if it has
+     * changed. Can be removed once we are able to listen specifically for
+     * enabled changes in the state. Widget.isEnabled() cannot be used as all
+     * Widgets do not implement HasEnabled
+     */
+    private boolean lastEnabledState = true;
+    private List<ServerConnector> children;
 
     /*
      * (non-Javadoc)
@@ -137,16 +148,6 @@ public abstract class AbstractConnector implements ServerConnector,
         return (Collection<T>) rpcImplementations.get(rpcInterfaceId);
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see com.vaadin.terminal.gwt.client.Connector#isConnectorEnabled()
-     */
-    public boolean isConnectorEnabled() {
-        // Client side can always receive message from the server
-        return true;
-    }
-
     public void fireEvent(GwtEvent<?> event) {
         if (handlerManager != null) {
             handlerManager.fireEvent(event);
@@ -172,6 +173,8 @@ public abstract class AbstractConnector implements ServerConnector,
                     + Util.getConnectorString(stateChangeEvent.getConnector())
                     + " received by " + Util.getConnectorString(this));
         }
+
+        updateEnabledState(isEnabled());
     }
 
     /*
@@ -214,4 +217,47 @@ public abstract class AbstractConnector implements ServerConnector,
         return ConnectorStateFactory.createState(getClass());
     }
 
+    public ServerConnector getParent() {
+        return parent;
+    }
+
+    public void setParent(ServerConnector parent) {
+        this.parent = parent;
+    }
+
+    public List<ServerConnector> getChildren() {
+        if (children == null) {
+            return Collections.emptyList();
+        }
+        return children;
+    }
+
+    public void setChildren(List<ServerConnector> children) {
+        this.children = children;
+    }
+
+    public boolean isEnabled() {
+        if (!getState().isEnabled()) {
+            return false;
+        }
+
+        if (getParent() == null) {
+            return true;
+        } else {
+            return getParent().isEnabled();
+        }
+    }
+
+    public void updateEnabledState(boolean enabledState) {
+        if (lastEnabledState == enabledState) {
+            return;
+        }
+        lastEnabledState = enabledState;
+
+        for (ServerConnector c : getChildren()) {
+            // Update children as they might be affected by the enabled state of
+            // their parent
+            c.updateEnabledState(c.isEnabled());
+        }
+    }
 }
index b42c0acea7ff8d3ab3b67c21d97d92072e37ba8e..91436f5353cfcd815cd33a5334b095a8196b250d 100644 (file)
@@ -109,7 +109,7 @@ public class AbsoluteLayoutConnector extends
 
         // TODO Margin handling
 
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             getWrapper(child).setPosition(
                     getState().getConnectorPosition(child));
         }
@@ -133,7 +133,7 @@ public class AbsoluteLayoutConnector extends
     public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) {
         super.onConnectorHierarchyChange(event);
 
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             getWrapper(child);
         }
 
@@ -149,7 +149,7 @@ public class AbsoluteLayoutConnector extends
 
     public void layoutVertically() {
         VAbsoluteLayout layout = getWidget();
-        for (ComponentConnector paintable : getChildren()) {
+        for (ComponentConnector paintable : getChildComponents()) {
             Widget widget = paintable.getWidget();
             AbsoluteWrapper wrapper = (AbsoluteWrapper) widget.getParent();
             Style wrapperStyle = wrapper.getElement().getStyle();
@@ -181,7 +181,7 @@ public class AbsoluteLayoutConnector extends
 
     public void layoutHorizontally() {
         VAbsoluteLayout layout = getWidget();
-        for (ComponentConnector paintable : getChildren()) {
+        for (ComponentConnector paintable : getChildComponents()) {
             AbsoluteWrapper wrapper = getWrapper(paintable);
             Style wrapperStyle = wrapper.getElement().getStyle();
 
index 71d670fe9d4fe38e70b623564446ea80ddc4b244..4d341bddfc687b987ce4c4e99444e7cc48d1098a 100644 (file)
@@ -64,7 +64,7 @@ public class CssLayoutConnector extends AbstractLayoutConnector {
         getWidget().setMarginStyles(
                 new VMarginInfo(getState().getMarginsBitmask()));
 
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             if (!getState().getChildCss().containsKey(child)) {
                 continue;
             }
@@ -92,7 +92,7 @@ public class CssLayoutConnector extends AbstractLayoutConnector {
 
         int index = 0;
         FlowPane cssLayoutWidgetContainer = getWidget().panel;
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             VCaption childCaption = childToCaption.get(child);
             if (childCaption != null) {
                 cssLayoutWidgetContainer.addOrMove(childCaption, index++);
index 981818fc6987f40684154ef7020cdbe14d31ed4e..5001711d6ca163ae48647e3aefb558382fc80123 100644 (file)
@@ -28,8 +28,8 @@ public class CustomComponentConnector extends
         super.onConnectorHierarchyChange(event);
 
         ComponentConnector newChild = null;
-        if (getChildren().size() == 1) {
-            newChild = getChildren().get(0);
+        if (getChildComponents().size() == 1) {
+            newChild = getChildComponents().get(0);
         }
 
         VCustomComponent customComponent = getWidget();
index ca24cfc91a7b1e2590658a58891fdde091c66761..f8861caf9219a7deca0135454d6df0ac182f9186 100644 (file)
@@ -75,7 +75,7 @@ public class CustomLayoutConnector extends AbstractLayoutConnector implements
         updateHtmlTemplate();
 
         // For all contained widgets
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             String location = getState().getChildLocations().get(child);
             try {
                 getWidget().setWidget(child.getWidget(), location);
index cdac73a771760540260f9673842a50000adfaecf..ca21947a6ce63500ecf519619256fa984f48f4ed 100644 (file)
@@ -46,9 +46,9 @@ public class FormLayoutConnector extends AbstractLayoutConnector {
 
         int childId = 0;
 
-        formLayoutTable.setRowCount(getChildren().size());
+        formLayoutTable.setRowCount(getChildComponents().size());
 
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             Widget childWidget = child.getWidget();
 
             Caption caption = formLayoutTable.getCaption(childWidget);
index 50afbc5913ce32f76b5950b36e741848823ebab8..2cd82313c277bc94a635fee37ea9b56f57144031 100644 (file)
@@ -63,7 +63,7 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector
                 layout.spacingMeasureElement);
 
         // Unregister caption size dependencies
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             Cell cell = layout.widgetToCell.get(child.getWidget());
             cell.slot.setCaption(null);
         }
@@ -155,7 +155,7 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector
         if (needCaptionUpdate) {
             needCaptionUpdate = false;
 
-            for (ComponentConnector child : getChildren()) {
+            for (ComponentConnector child : getChildComponents()) {
                 updateCaption(child);
             }
         }
diff --git a/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/GreetAgainRpc.java b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/GreetAgainRpc.java
new file mode 100644 (file)
index 0000000..0bfb8f3
--- /dev/null
@@ -0,0 +1,12 @@
+/* 
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.helloworldfeature;
+
+import com.vaadin.terminal.gwt.client.communication.ClientRpc;
+
+public interface GreetAgainRpc extends ClientRpc {
+
+    public void greetAgain();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldExtensionConnector.java b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldExtensionConnector.java
new file mode 100644 (file)
index 0000000..ff444fe
--- /dev/null
@@ -0,0 +1,48 @@
+/* 
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.helloworldfeature;
+
+import com.google.gwt.user.client.Window;
+import com.vaadin.terminal.gwt.client.ServerConnector;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.communication.RpcProxy;
+import com.vaadin.terminal.gwt.client.ui.AbstractConnector;
+import com.vaadin.terminal.gwt.client.ui.Connect;
+import com.vaadin.ui.HelloWorldExtension;
+
+@Connect(HelloWorldExtension.class)
+public class HelloWorldExtensionConnector extends AbstractConnector {
+    HelloWorldRpc rpc = RpcProxy.create(HelloWorldRpc.class, this);
+
+    @Override
+    public HelloWorldState getState() {
+        return (HelloWorldState) super.getState();
+    }
+
+    @Override
+    protected void init() {
+        registerRpc(GreetAgainRpc.class, new GreetAgainRpc() {
+            public void greetAgain() {
+                greet();
+            }
+        });
+    }
+
+    @Override
+    public void setParent(ServerConnector parent) {
+        super.setParent(parent);
+        greet();
+    }
+
+    private void greet() {
+        String msg = getState().getGreeting() + " from "
+                + Util.getConnectorString(this) + " attached to "
+                + Util.getConnectorString(getParent());
+        VConsole.log(msg);
+
+        String response = Window.prompt(msg, "");
+        rpc.onMessageSent(response);
+    }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldRpc.java b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldRpc.java
new file mode 100644 (file)
index 0000000..0289713
--- /dev/null
@@ -0,0 +1,10 @@
+/* 
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.helloworldfeature;
+
+import com.vaadin.terminal.gwt.client.communication.ServerRpc;
+
+public interface HelloWorldRpc extends ServerRpc {
+    public void onMessageSent(String message);
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldState.java b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldState.java
new file mode 100644 (file)
index 0000000..9524a5e
--- /dev/null
@@ -0,0 +1,18 @@
+/* 
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.helloworldfeature;
+
+import com.vaadin.terminal.gwt.client.communication.SharedState;
+
+public class HelloWorldState extends SharedState {
+    private String greeting = "Hello world";
+
+    public String getGreeting() {
+        return greeting;
+    }
+
+    public void setGreeting(String greeting) {
+        this.greeting = greeting;
+    }
+}
index 1ca8933ff2fd1226ccee28466f28c3ba55c4b5ee..18843057f3e87ab8570e13b1cf7e9adf277ca1cc 100644 (file)
@@ -13,6 +13,7 @@ import java.util.Set;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
 import com.vaadin.terminal.gwt.client.ComponentContainerConnector;
 import com.vaadin.terminal.gwt.client.ComponentState;
+import com.vaadin.terminal.gwt.client.ServerConnector;
 import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VConsole;
 import com.vaadin.terminal.gwt.client.ui.ManagedLayout;
@@ -154,9 +155,9 @@ public class LayoutDependencyTree {
                 needsSize.add(connector);
             }
             if (!isRelativeInDirection(connector, direction)) {
-                ComponentConnector parent = connector.getParent();
-                if (parent != null) {
-                    needsSize.add(parent);
+                ServerConnector parent = connector.getParent();
+                if (parent instanceof ComponentConnector) {
+                    needsSize.add((ComponentConnector) parent);
                 }
             }
 
@@ -193,7 +194,7 @@ public class LayoutDependencyTree {
 
             if (connector instanceof ComponentContainerConnector) {
                 ComponentContainerConnector container = (ComponentContainerConnector) connector;
-                for (ComponentConnector child : container.getChildren()) {
+                for (ComponentConnector child : container.getChildComponents()) {
                     if (isRelativeInDirection(child, direction)) {
                         resized.add(child);
                     }
@@ -246,16 +247,15 @@ public class LayoutDependencyTree {
         private LayoutDependency findPotentiallyChangedScrollbar() {
             ComponentConnector currentConnector = connector;
             while (true) {
-                ComponentContainerConnector parent = currentConnector
-                        .getParent();
-                if (parent == null) {
+                ServerConnector parent = currentConnector.getParent();
+                if (!(parent instanceof ComponentConnector)) {
                     return null;
                 }
                 if (parent instanceof MayScrollChildren) {
                     return getDependency(currentConnector,
                             getOppositeDirection());
                 }
-                currentConnector = parent;
+                currentConnector = (ComponentConnector) parent;
             }
         }
 
@@ -504,12 +504,11 @@ public class LayoutDependencyTree {
     public ComponentConnector getScrollingBoundary(ComponentConnector connector) {
         LayoutDependency dependency = getDependency(connector, HORIZONTAL);
         if (!dependency.scrollingParentCached) {
-            ComponentContainerConnector parent = dependency.connector
-                    .getParent();
+            ServerConnector parent = dependency.connector.getParent();
             if (parent instanceof MayScrollChildren) {
                 dependency.scrollingBoundary = connector;
-            } else if (parent != null) {
-                dependency.scrollingBoundary = getScrollingBoundary(parent);
+            } else if (parent instanceof ComponentConnector) {
+                dependency.scrollingBoundary = getScrollingBoundary((ComponentConnector) parent);
             } else {
                 // No scrolling parent
             }
index d15766db217c51a4c223e385123be348747567ae..9a89553fd2cfaced063501362ff36fd94a430310 100644 (file)
@@ -61,7 +61,7 @@ public abstract class AbstractOrderedLayoutConnector extends
         lm.unregisterDependency(this, layout.spacingMeasureElement);
 
         // Unregister child caption listeners
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             VLayoutSlot slot = layout.getSlotForChild(child.getWidget());
             slot.setCaption(null);
         }
@@ -105,7 +105,7 @@ public abstract class AbstractOrderedLayoutConnector extends
 
         VMeasuringOrderedLayout layout = getWidget();
 
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             VLayoutSlot slot = layout.getSlotForChild(child.getWidget());
 
             AlignmentInfo alignment = new AlignmentInfo(getState()
@@ -285,7 +285,7 @@ public abstract class AbstractOrderedLayoutConnector extends
         int currentIndex = 0;
         VMeasuringOrderedLayout layout = getWidget();
 
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             Widget childWidget = child.getWidget();
             VLayoutSlot slot = layout.getSlotForChild(childWidget);
 
index 35a0ede3908b932ccebd53af7494d3a16d6edb74..5b97fc110f84b909f957a6aad2a8081608993530 100644 (file)
@@ -226,8 +226,8 @@ public class PanelConnector extends AbstractComponentContainerConnector
         super.onConnectorHierarchyChange(event);
         // We always have 1 child, unless the child is hidden
         Widget newChildWidget = null;
-        if (getChildren().size() == 1) {
-            ComponentConnector newChild = getChildren().get(0);
+        if (getChildComponents().size() == 1) {
+            ComponentConnector newChild = getChildComponents().get(0);
             newChildWidget = newChild.getWidget();
         }
 
index e02bcc93306e70164192ef96ee92e1a185773ea9..9be41a962348d60ce0c9297a4b848c5623295636 100644 (file)
@@ -329,7 +329,7 @@ public class RootConnector extends AbstractComponentContainerConnector
      */
     @Deprecated
     public boolean hasSubWindow(WindowConnector wc) {
-        return getChildren().contains(wc);
+        return getChildComponents().contains(wc);
     }
 
     /**
@@ -340,7 +340,7 @@ public class RootConnector extends AbstractComponentContainerConnector
      */
     public List<WindowConnector> getSubWindows() {
         ArrayList<WindowConnector> windows = new ArrayList<WindowConnector>();
-        for (ComponentConnector child : getChildren()) {
+        for (ComponentConnector child : getChildComponents()) {
             if (child instanceof WindowConnector) {
                 windows.add((WindowConnector) child);
             }
@@ -380,7 +380,7 @@ public class RootConnector extends AbstractComponentContainerConnector
             onChildSizeChange();
         }
 
-        for (ComponentConnector c : getChildren()) {
+        for (ComponentConnector c : getChildComponents()) {
             if (c instanceof WindowConnector) {
                 WindowConnector wc = (WindowConnector) c;
                 wc.setWindowOrderAndPosition();
index a2f1f26c1594b217179a0890252146fd519822a4..10e5dbe37a7cadf971c5de111d03c64873507edb 100644 (file)
@@ -143,7 +143,7 @@ public abstract class AbstractSplitPanelConnector extends
         splitPanel.setSplitPosition(splitPanel.position);
         splitPanel.updateSizes();
         // Report relative sizes in other direction for quicker propagation
-        List<ComponentConnector> children = getChildren();
+        List<ComponentConnector> children = getChildComponents();
         for (ComponentConnector child : children) {
             reportOtherDimension(child);
         }
index 73bc5da83f0879d5cce614675aaed7291590d502..ada0f2424f12c79018099e4e601517d8f57e8717 100644 (file)
@@ -16,6 +16,7 @@ import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
 import com.vaadin.terminal.gwt.client.DirectionalManagedLayout;
 import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.ServerConnector;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.ui.AbstractComponentContainerConnector;
@@ -283,8 +284,11 @@ public class TableConnector extends AbstractComponentContainerConnector
             Scheduler.get().scheduleFinally(new ScheduledCommand() {
                 public void execute() {
                     getLayoutManager().setNeedsMeasure(TableConnector.this);
-                    getLayoutManager().setNeedsMeasure(
-                            TableConnector.this.getParent());
+                    ServerConnector parent = getParent();
+                    if (parent instanceof ComponentConnector) {
+                        getLayoutManager().setNeedsMeasure(
+                                (ComponentConnector) parent);
+                    }
                     getLayoutManager().setNeedsVerticalLayout(
                             TableConnector.this);
                     getLayoutManager().layoutNow();
index 3a37baafbb359b9b76b04521adf86b831c0eab10..83de039f0b2a757b6807585b661b490b8884236a 100644 (file)
@@ -201,8 +201,8 @@ public class WindowConnector extends AbstractComponentContainerConnector
         // We always have 1 child, unless the child is hidden
         Widget newChildWidget = null;
         ComponentConnector newChild = null;
-        if (getChildren().size() == 1) {
-            newChild = getChildren().get(0);
+        if (getChildComponents().size() == 1) {
+            newChild = getChildComponents().get(0);
             newChildWidget = newChild.getWidget();
         }
 
index 5b2be308a34e0102a0ff197bd44a15984fb449b8..1acc9d128a93d59e53133a5b7ba553ee2b9f9b01 100644 (file)
@@ -67,7 +67,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
     private static final Logger logger = Logger
             .getLogger(AbstractApplicationPortlet.class.getName());
 
-    public static class WrappedHttpAndPortletRequest extends
+    private static class WrappedHttpAndPortletRequest extends
             WrappedPortletRequest {
 
         public WrappedHttpAndPortletRequest(PortletRequest request,
@@ -112,7 +112,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         }
     }
 
-    public static class WrappedGateinRequest extends
+    private static class WrappedGateinRequest extends
             WrappedHttpAndPortletRequest {
         public WrappedGateinRequest(PortletRequest request,
                 DeploymentConfiguration deploymentConfiguration) {
@@ -134,7 +134,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         }
     }
 
-    public static class WrappedLiferayRequest extends
+    private static class WrappedLiferayRequest extends
             WrappedHttpAndPortletRequest {
 
         public WrappedLiferayRequest(PortletRequest request,
@@ -169,7 +169,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
 
     }
 
-    public static class AbstractApplicationPortletWrapper implements Callback {
+    private static class AbstractApplicationPortletWrapper implements Callback {
 
         private final AbstractApplicationPortlet portlet;
 
@@ -500,7 +500,20 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         AbstractApplicationPortletWrapper portletWrapper = new AbstractApplicationPortletWrapper(
                 this);
 
-        WrappedPortletRequest wrappedRequest = createWrappedRequest(request);
+        WrappedPortletRequest wrappedRequest;
+
+        String portalInfo = request.getPortalContext().getPortalInfo()
+                .toLowerCase();
+        if (portalInfo.contains("liferay")) {
+            wrappedRequest = new WrappedLiferayRequest(request,
+                    getDeploymentConfiguration());
+        } else if (portalInfo.contains("gatein")) {
+            wrappedRequest = new WrappedGateinRequest(request,
+                    getDeploymentConfiguration());
+        } else {
+            wrappedRequest = new WrappedPortletRequest(request,
+                    getDeploymentConfiguration());
+        }
 
         WrappedPortletResponse wrappedResponse = new WrappedPortletResponse(
                 response, getDeploymentConfiguration());
@@ -699,30 +712,6 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         }
     }
 
-    /**
-     * Wraps the request in a (possibly portal specific) wrapped portlet
-     * request.
-     * 
-     * @param request
-     *            The original PortletRequest
-     * @return A wrapped version of the PorletRequest
-     */
-    protected WrappedPortletRequest createWrappedRequest(PortletRequest request) {
-        String portalInfo = request.getPortalContext().getPortalInfo()
-                .toLowerCase();
-        if (portalInfo.contains("liferay")) {
-            return new WrappedLiferayRequest(request,
-                    getDeploymentConfiguration());
-        } else if (portalInfo.contains("gatein")) {
-            return new WrappedGateinRequest(request,
-                    getDeploymentConfiguration());
-        } else {
-            return new WrappedPortletRequest(request,
-                    getDeploymentConfiguration());
-        }
-
-    }
-
     private DeploymentConfiguration getDeploymentConfiguration() {
         return deploymentConfiguration;
     }
index c08d70aa37215d2886639ffcd409b43af57b45cd..186126c9c6a4911373cdf14afb7e0060d842fc7d 100644 (file)
@@ -49,6 +49,7 @@ import com.vaadin.Version;
 import com.vaadin.external.json.JSONArray;
 import com.vaadin.external.json.JSONException;
 import com.vaadin.external.json.JSONObject;
+import com.vaadin.terminal.AbstractClientConnector;
 import com.vaadin.terminal.CombinedRequest;
 import com.vaadin.terminal.LegacyPaint;
 import com.vaadin.terminal.PaintException;
@@ -74,7 +75,6 @@ import com.vaadin.ui.AbstractField;
 import com.vaadin.ui.Component;
 import com.vaadin.ui.DirtyConnectorTracker;
 import com.vaadin.ui.HasComponents;
-import com.vaadin.ui.Panel;
 import com.vaadin.ui.Root;
 import com.vaadin.ui.Window;
 
@@ -769,7 +769,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
         logger.log(Level.FINE, "* Creating response to client");
         if (repaintAll) {
             getClientCache(root).clear();
-            rootConnectorTracker.markAllComponentsDirty();
+            rootConnectorTracker.markAllConnectorsDirty();
 
             // Reset sent locales
             locales = null;
@@ -777,7 +777,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
         }
 
         dirtyVisibleConnectors
-                .addAll(getDirtyVisibleComponents(rootConnectorTracker));
+                .addAll(getDirtyVisibleConnectors(rootConnectorTracker));
 
         logger.log(Level.FINE, "Found " + dirtyVisibleConnectors.size()
                 + " dirty connectors to paint");
@@ -786,7 +786,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
                 ((Component) connector).updateState();
             }
         }
-        rootConnectorTracker.markAllComponentsClean();
+        rootConnectorTracker.markAllConnectorsClean();
 
         outWriter.print("\"changes\":[");
 
@@ -893,26 +893,24 @@ public abstract class AbstractCommunicationManager implements Serializable {
         outWriter.print("\"hierarchy\":");
 
         JSONObject hierarchyInfo = new JSONObject();
-        for (Connector connector : dirtyVisibleConnectors) {
-            if (connector instanceof HasComponents) {
-                HasComponents parent = (HasComponents) connector;
-                String parentConnectorId = parent.getConnectorId();
-                JSONArray children = new JSONArray();
-
-                for (Component child : getChildComponents(parent)) {
-                    if (isVisible(child)) {
-                        children.put(child.getConnectorId());
-                    }
-                }
-                try {
-                    hierarchyInfo.put(parentConnectorId, children);
-                } catch (JSONException e) {
-                    throw new PaintException(
-                            "Failed to send hierarchy information about "
-                                    + parentConnectorId + " to the client: "
-                                    + e.getMessage(), e);
+        for (ClientConnector connector : dirtyVisibleConnectors) {
+            String connectorId = connector.getConnectorId();
+            JSONArray children = new JSONArray();
+
+            for (ClientConnector child : AbstractClientConnector
+                    .getAllChildrenIteratable(connector)) {
+                if (isVisible(child)) {
+                    children.put(child.getConnectorId());
                 }
             }
+            try {
+                hierarchyInfo.put(connectorId, children);
+            } catch (JSONException e) {
+                throw new PaintException(
+                        "Failed to send hierarchy information about "
+                                + connectorId + " to the client: "
+                                + e.getMessage(), e);
+            }
         }
         outWriter.append(hierarchyInfo.toString());
         outWriter.print(", "); // close hierarchy
@@ -1222,6 +1220,30 @@ public abstract class AbstractCommunicationManager implements Serializable {
         return cache;
     }
 
+    /**
+     * Checks if the connector is visible in context. For Components,
+     * {@link #isVisible(Component)} is used. For other types of connectors, the
+     * contextual visibility of its first Component ancestor is used. If no
+     * Component ancestor is found, the connector is not visible.
+     * 
+     * @param connector
+     *            The connector to check
+     * @return <code>true</code> if the connector is visible to the client,
+     *         <code>false</code> otherwise
+     */
+    static boolean isVisible(ClientConnector connector) {
+        if (connector instanceof Component) {
+            return isVisible((Component) connector);
+        } else {
+            ClientConnector parent = connector.getParent();
+            if (parent == null) {
+                return false;
+            } else {
+                return isVisible(parent);
+            }
+        }
+    }
+
     /**
      * Checks if the component is visible in context, i.e. returns false if the
      * child is hidden, the parent is hidden or the parent says the child should
@@ -1256,30 +1278,6 @@ public abstract class AbstractCommunicationManager implements Serializable {
 
     }
 
-    public static Iterable<Component> getChildComponents(HasComponents cc) {
-        // TODO This must be moved to Root/Panel
-        if (cc instanceof Root) {
-            Root root = (Root) cc;
-            List<Component> children = new ArrayList<Component>();
-            if (root.getContent() != null) {
-                children.add(root.getContent());
-            }
-            for (Window w : root.getWindows()) {
-                children.add(w);
-            }
-            return children;
-        } else if (cc instanceof Panel) {
-            // This is so wrong.. (#2924)
-            if (((Panel) cc).getContent() == null) {
-                return Collections.emptyList();
-            } else {
-                return Collections.singleton((Component) ((Panel) cc)
-                        .getContent());
-            }
-        }
-        return cc;
-    }
-
     /**
      * Collects all pending RPC calls from listed {@link ClientConnector}s and
      * clears their RPC queues.
@@ -2016,16 +2014,16 @@ public abstract class AbstractCommunicationManager implements Serializable {
      *            root window for which dirty components is to be fetched
      * @return
      */
-    private ArrayList<Component> getDirtyVisibleComponents(
+    private ArrayList<ClientConnector> getDirtyVisibleConnectors(
             DirtyConnectorTracker dirtyConnectorTracker) {
-        ArrayList<Component> dirtyComponents = new ArrayList<Component>();
-        for (Component c : dirtyConnectorTracker.getDirtyComponents()) {
+        ArrayList<ClientConnector> dirtyConnectors = new ArrayList<ClientConnector>();
+        for (ClientConnector c : dirtyConnectorTracker.getDirtyConnectors()) {
             if (isVisible(c)) {
-                dirtyComponents.add(c);
+                dirtyConnectors.add(c);
             }
         }
 
-        return dirtyComponents;
+        return dirtyConnectors;
     }
 
     /**
index 7e74c26fb1ccd17fa24b45bd1ad1c7a124fb9362..6830aa8e14d0b0356c13090ffaef04875b661775 100644 (file)
@@ -3,10 +3,16 @@
  */
 package com.vaadin.terminal.gwt.server;
 
+import java.util.Iterator;
 import java.util.List;
 
+import com.vaadin.terminal.AbstractClientConnector;
+import com.vaadin.terminal.Extension;
 import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.communication.SharedState;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.ComponentContainer;
+import com.vaadin.ui.Root;
 
 /**
  * Interface implemented by all connectors that are capable of communicating
@@ -44,4 +50,94 @@ public interface ClientConnector extends Connector, RpcTarget {
      */
     public Class<? extends SharedState> getStateType();
 
+    public ClientConnector getParent();
+
+    /**
+     * Requests that the connector should be repainted as soon as possible.
+     */
+    public void requestRepaint();
+
+    /**
+     * Causes a repaint of this connector, and all connectors below it.
+     * 
+     * This should only be used in special cases, e.g when the state of a
+     * descendant depends on the state of a ancestor.
+     */
+    public void requestRepaintAll();
+
+    /**
+     * Sets the parent connector of the connector.
+     * 
+     * <p>
+     * This method automatically calls {@link #attach()} if the parent becomes
+     * attached to the application, regardless of whether it was attached
+     * previously. Conversely, if the parent is {@code null} and the connector
+     * is attached to the application, {@link #detach()} is called for the
+     * connector.
+     * </p>
+     * <p>
+     * This method is rarely called directly. One of the
+     * {@link ComponentContainer#addComponent(Component)} or
+     * {@link AbstractClientConnector#addFeature(Feature)} methods is normally
+     * used for adding connectors to a container and it will call this method
+     * implicitly.
+     * </p>
+     * 
+     * <p>
+     * It is not possible to change the parent without first setting the parent
+     * to {@code null}.
+     * </p>
+     * 
+     * @param parent
+     *            the parent connector
+     * @throws IllegalStateException
+     *             if a parent is given even though the connector already has a
+     *             parent
+     */
+    public void setParent(ClientConnector parent);
+
+    /**
+     * Notifies the connector that it is connected to an application.
+     * 
+     * <p>
+     * The caller of this method is {@link #setParent(ClientConnector)} if the
+     * parent is itself already attached to the application. If not, the parent
+     * will call the {@link #attach()} for all its children when it is attached
+     * to the application. This method is always called before the connector is
+     * painted for the first time.
+     * </p>
+     * 
+     * <p>
+     * The attachment logic is implemented in {@link AbstractClientConnector}.
+     * </p>
+     * 
+     * @see #getApplication()
+     */
+    public void attach();
+
+    /**
+     * Notifies the component that it is detached from the application.
+     * 
+     * <p>
+     * The {@link #getApplication()} and {@link #getRoot()} methods might return
+     * <code>null</code> after this method is called.
+     * </p>
+     * 
+     * <p>
+     * This method must call {@link Root#componentDetached(Component)} to let
+     * the Root know that a new Component has been attached.
+     * </p>
+     * *
+     * <p>
+     * The caller of this method is {@link #setParent(Component)} if the parent
+     * is in the application. When the parent is detached from the application
+     * it is its response to call {@link #detach()} for all the children and to
+     * detach itself from the terminal.
+     * </p>
+     */
+    public void detach();
+
+    public Iterator<Extension> getExtensionIterator();
+
+    public void removeExtension(Extension feature);
 }
index f6c96557ea213ac884dd78974f368d94a60ed279..e2358bcbb9ff9292f8f28af366cba19a8b0eaa6d 100644 (file)
@@ -4,6 +4,7 @@
 package com.vaadin.terminal.gwt.server;
 
 import java.io.PrintWriter;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
@@ -17,6 +18,7 @@ import com.vaadin.event.dd.DropTarget;
 import com.vaadin.event.dd.TargetDetails;
 import com.vaadin.event.dd.TargetDetailsImpl;
 import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
+import com.vaadin.terminal.Extension;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.VariableOwner;
 import com.vaadin.terminal.gwt.client.communication.SharedState;
@@ -242,4 +244,44 @@ public class DragAndDropService implements VariableOwner, ClientConnector {
     public Class<? extends SharedState> getStateType() {
         return SharedState.class;
     }
+
+    public void requestRepaint() {
+        // TODO Auto-generated method stub
+
+    }
+
+    public ClientConnector getParent() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public void requestRepaintAll() {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void setParent(ClientConnector parent) {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void attach() {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void detach() {
+        // TODO Auto-generated method stub
+
+    }
+
+    public Iterator<Extension> getExtensionIterator() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public void removeExtension(Extension feature) {
+        // TODO Auto-generated method stub
+
+    }
 }
index def334290eaee7673c6313a7dc28be3708deaa16..1cde1646189ee84df6ba86a0a4b5351d37ea226f 100644 (file)
@@ -26,6 +26,7 @@ import com.vaadin.terminal.ThemeResource;
 import com.vaadin.terminal.VariableOwner;
 import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Component;
 import com.vaadin.ui.CustomLayout;
 
 /**
@@ -399,7 +400,7 @@ public class JsonPaintTarget implements PaintTarget {
 
     }
 
-    public void addAttribute(String name, ClientConnector value)
+    public void addAttribute(String name, Component value)
             throws PaintException {
         final String id = value.getConnectorId();
         addAttribute(name, id);
@@ -468,7 +469,7 @@ public class JsonPaintTarget implements PaintTarget {
     }
 
     public void addVariable(VariableOwner owner, String name,
-            ClientConnector value) throws PaintException {
+            Component value) throws PaintException {
         tag.addVariable(new StringVariable(owner, name, value.getConnectorId()));
     }
 
@@ -645,7 +646,7 @@ public class JsonPaintTarget implements PaintTarget {
      * @see com.vaadin.terminal.PaintTarget#startPaintable(com.vaadin.terminal
      * .Paintable, java.lang.String)
      */
-    public PaintStatus startPaintable(ClientConnector connector, String tagName)
+    public PaintStatus startPaintable(Component connector, String tagName)
             throws PaintException {
         boolean topLevelPaintable = openPaintables.isEmpty();
 
@@ -670,7 +671,7 @@ public class JsonPaintTarget implements PaintTarget {
         return PaintStatus.PAINTING;
     }
 
-    public void endPaintable(ClientConnector paintable) throws PaintException {
+    public void endPaintable(Component paintable) throws PaintException {
         logger.fine("endPaintable for " + paintable.getClass().getName() + "@"
                 + Integer.toHexString(paintable.hashCode()));
 
index f0d6f0453b96aeec67d73cced5233a7cc164bb12..f0f3df20b00c5baac7aa7a1fc5bc80778855570e 100644 (file)
@@ -7,6 +7,7 @@ import java.util.Collection;
 import java.util.HashSet;
 
 import com.vaadin.terminal.gwt.client.ComponentConnector;
+import com.vaadin.terminal.gwt.client.ServerConnector;
 import com.vaadin.terminal.gwt.client.ui.Connect;
 import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle;
 
@@ -25,8 +26,7 @@ public abstract class CustomWidgetMapGenerator extends WidgetMapGenerator {
     private Collection<Class<? extends ComponentConnector>> deferredPaintables = new HashSet<Class<? extends ComponentConnector>>();
 
     @Override
-    protected LoadStyle getLoadStyle(
-            Class<? extends ComponentConnector> connector) {
+    protected LoadStyle getLoadStyle(Class<? extends ServerConnector> connector) {
         if (eagerPaintables == null) {
             init();
         }
index 8a1dfee3b592281c7f21f69885aa94956a79b1f3..084e1c3857c5d7de0c0041dab192fe147c064380 100644 (file)
@@ -3,7 +3,7 @@
  */
 package com.vaadin.terminal.gwt.widgetsetutils;
 
-import com.vaadin.terminal.gwt.client.ComponentConnector;
+import com.vaadin.terminal.gwt.client.ServerConnector;
 import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle;
 
 /**
@@ -23,8 +23,7 @@ import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle;
 public class EagerWidgetMapGenerator extends WidgetMapGenerator {
 
     @Override
-    protected LoadStyle getLoadStyle(
-            Class<? extends ComponentConnector> connector) {
+    protected LoadStyle getLoadStyle(Class<? extends ServerConnector> connector) {
         return LoadStyle.EAGER;
     }
 }
index 729a999a21eca3b98376f10757ad6bf5a80e27b3..f8366beb46a7b7de2b5b4c6e5fbe8c569636642f 100644 (file)
@@ -3,7 +3,7 @@
  */
 package com.vaadin.terminal.gwt.widgetsetutils;
 
-import com.vaadin.terminal.gwt.client.ComponentConnector;
+import com.vaadin.terminal.gwt.client.ServerConnector;
 import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle;
 
 /**
@@ -16,8 +16,7 @@ import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle;
  */
 public class LazyWidgetMapGenerator extends WidgetMapGenerator {
     @Override
-    protected LoadStyle getLoadStyle(
-            Class<? extends ComponentConnector> connector) {
+    protected LoadStyle getLoadStyle(Class<? extends ServerConnector> connector) {
         return LoadStyle.LAZY;
     }
 
index 07efcda91baaff92157a418a1aced479201a0920..268877543587da1378df668f629f83c419ce7b8b 100644 (file)
@@ -203,6 +203,7 @@ public class SerializerMapGenerator extends Generator {
         // Generate serializer classes for each subclass of SharedState
         JClassType serializerType = typeOracle.findType(SharedState.class
                 .getName());
+        types.add(serializerType);
         JClassType[] serializerSubtypes = serializerType.getSubtypes();
         for (JClassType type : serializerSubtypes) {
             types.add(type);
index 6d4289b1735419ccf59455d569e7cdf014864349..b264a9c7fed5eb7b8ab0dc385d701c247d805141 100644 (file)
@@ -22,8 +22,8 @@ import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
-import com.vaadin.terminal.gwt.client.ComponentConnector;
 import com.vaadin.terminal.gwt.client.Connector;
+import com.vaadin.terminal.gwt.client.ServerConnector;
 import com.vaadin.terminal.gwt.client.ui.Connect;
 import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle;
 import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector;
@@ -71,7 +71,7 @@ import com.vaadin.terminal.gwt.server.ClientConnector;
  */
 public class WidgetMapGenerator extends Generator {
 
-    private static String componentConnectorClassName = ComponentConnector.class
+    private static String serverConnectorClassName = ServerConnector.class
             .getName();
 
     private String packageName;
@@ -115,7 +115,7 @@ public class WidgetMapGenerator extends Generator {
             return;
         }
         logger.log(Type.INFO,
-                "Detecting Vaadin components in classpath to generate WidgetMapImpl.java ...");
+                "Detecting Vaadin connectors in classpath to generate WidgetMapImpl.java ...");
         Date date = new Date();
 
         // init composer, set class properties, create source writer
@@ -128,7 +128,7 @@ public class WidgetMapGenerator extends Generator {
         SourceWriter sourceWriter = composer.createSourceWriter(context,
                 printWriter);
 
-        Collection<Class<? extends ComponentConnector>> connectors = getUsedConnectors(context
+        Collection<Class<? extends ServerConnector>> connectors = getUsedConnectors(context
                 .getTypeOracle());
 
         validateConnectors(logger, connectors);
@@ -149,12 +149,11 @@ public class WidgetMapGenerator extends Generator {
     }
 
     private void validateConnectors(TreeLogger logger,
-            Collection<Class<? extends ComponentConnector>> connectors) {
+            Collection<Class<? extends ServerConnector>> connectors) {
 
-        Iterator<Class<? extends ComponentConnector>> iter = connectors
-                .iterator();
+        Iterator<Class<? extends ServerConnector>> iter = connectors.iterator();
         while (iter.hasNext()) {
-            Class<? extends ComponentConnector> connectorClass = iter.next();
+            Class<? extends ServerConnector> connectorClass = iter.next();
             Connect annotation = connectorClass.getAnnotation(Connect.class);
             if (!ClientConnector.class.isAssignableFrom(annotation.value())) {
                 logger.log(
@@ -173,13 +172,13 @@ public class WidgetMapGenerator extends Generator {
     }
 
     private void logConnectors(TreeLogger logger, GeneratorContext context,
-            Collection<Class<? extends ComponentConnector>> connectors) {
+            Collection<Class<? extends ServerConnector>> connectors) {
         logger.log(Type.INFO,
                 "Widget set will contain implementations for following component connectors: ");
 
         TreeSet<String> classNames = new TreeSet<String>();
         HashMap<String, String> loadStyle = new HashMap<String, String>();
-        for (Class<? extends ComponentConnector> connectorClass : connectors) {
+        for (Class<? extends ServerConnector> connectorClass : connectors) {
             String className = connectorClass.getCanonicalName();
             classNames.add(className);
             if (getLoadStyle(connectorClass) == LoadStyle.DEFERRED) {
@@ -208,16 +207,16 @@ public class WidgetMapGenerator extends Generator {
      *         widgetset
      */
     @SuppressWarnings("unchecked")
-    private Collection<Class<? extends ComponentConnector>> getUsedConnectors(
+    private Collection<Class<? extends ServerConnector>> getUsedConnectors(
             TypeOracle typeOracle) {
         JClassType connectorType = typeOracle.findType(Connector.class
                 .getName());
-        Collection<Class<? extends ComponentConnector>> connectors = new HashSet<Class<? extends ComponentConnector>>();
+        Collection<Class<? extends ServerConnector>> connectors = new HashSet<Class<? extends ServerConnector>>();
         for (JClassType jClassType : connectorType.getSubtypes()) {
             Connect annotation = jClassType.getAnnotation(Connect.class);
             if (annotation != null) {
                 try {
-                    Class<? extends ComponentConnector> clazz = (Class<? extends ComponentConnector>) Class
+                    Class<? extends ServerConnector> clazz = (Class<? extends ServerConnector>) Class
                             .forName(jClassType.getQualifiedSourceName());
                     connectors.add(clazz);
                 } catch (ClassNotFoundException e) {
@@ -242,15 +241,14 @@ public class WidgetMapGenerator extends Generator {
      * @return true iff the widget for given component should be lazy loaded by
      *         the client side engine
      */
-    protected LoadStyle getLoadStyle(
-            Class<? extends ComponentConnector> connector) {
+    protected LoadStyle getLoadStyle(Class<? extends ServerConnector> connector) {
         Connect annotation = connector.getAnnotation(Connect.class);
         return annotation.loadStyle();
     }
 
     private void generateInstantiatorMethod(
             SourceWriter sourceWriter,
-            Collection<Class<? extends ComponentConnector>> connectorsHavingComponentAnnotation) {
+            Collection<Class<? extends ServerConnector>> connectorsHavingComponentAnnotation) {
 
         Collection<Class<?>> deferredWidgets = new LinkedList<Class<?>>();
 
@@ -258,16 +256,16 @@ public class WidgetMapGenerator extends Generator {
         // lookup with index than with the hashmap
 
         sourceWriter.println("public void ensureInstantiator(Class<? extends "
-                + componentConnectorClassName + "> classType) {");
+                + serverConnectorClassName + "> classType) {");
         sourceWriter.println("if(!instmap.containsKey(classType)){");
         boolean first = true;
 
-        ArrayList<Class<? extends ComponentConnector>> lazyLoadedWidgets = new ArrayList<Class<? extends ComponentConnector>>();
+        ArrayList<Class<? extends ServerConnector>> lazyLoadedConnectors = new ArrayList<Class<? extends ServerConnector>>();
 
-        HashSet<Class<? extends com.vaadin.terminal.gwt.client.ComponentConnector>> connectorsWithInstantiator = new HashSet<Class<? extends com.vaadin.terminal.gwt.client.ComponentConnector>>();
+        HashSet<Class<? extends ServerConnector>> connectorsWithInstantiator = new HashSet<Class<? extends ServerConnector>>();
 
-        for (Class<? extends ComponentConnector> class1 : connectorsHavingComponentAnnotation) {
-            Class<? extends ComponentConnector> clientClass = class1;
+        for (Class<? extends ServerConnector> class1 : connectorsHavingComponentAnnotation) {
+            Class<? extends ServerConnector> clientClass = class1;
             if (connectorsWithInstantiator.contains(clientClass)) {
                 continue;
             }
@@ -284,7 +282,7 @@ public class WidgetMapGenerator extends Generator {
                     + ".class) {");
 
             String instantiator = "new WidgetInstantiator() {\n public "
-                    + componentConnectorClassName
+                    + serverConnectorClassName
                     + " get() {\n return GWT.create(" + clientClass.getName()
                     + ".class );\n}\n}\n";
 
@@ -298,7 +296,7 @@ public class WidgetMapGenerator extends Generator {
                                 + clientClass.getName()
                                 + ".class,"
                                 + instantiator + ");}});\n");
-                lazyLoadedWidgets.add(class1);
+                lazyLoadedConnectors.add(class1);
 
                 if (loadStyle == LoadStyle.DEFERRED) {
                     deferredWidgets.add(class1);
@@ -321,8 +319,8 @@ public class WidgetMapGenerator extends Generator {
         sourceWriter.println("}");
 
         sourceWriter.println("public Class<? extends "
-                + componentConnectorClassName
-                + ">[] getDeferredLoadedWidgets() {");
+                + serverConnectorClassName
+                + ">[] getDeferredLoadedConnectors() {");
 
         sourceWriter.println("return new Class[] {");
         first = true;
@@ -344,11 +342,11 @@ public class WidgetMapGenerator extends Generator {
 
         // TODO an index of last ensured widget in array
 
-        sourceWriter.println("public " + componentConnectorClassName
-                + " instantiate(Class<? extends " + componentConnectorClassName
+        sourceWriter.println("public " + serverConnectorClassName
+                + " instantiate(Class<? extends " + serverConnectorClassName
                 + "> classType) {");
         sourceWriter.indent();
-        sourceWriter.println(componentConnectorClassName
+        sourceWriter.println(serverConnectorClassName
                 + " p = super.instantiate(classType); if(p!= null) return p;");
         sourceWriter.println("return instmap.get(classType).get();");
 
@@ -365,17 +363,17 @@ public class WidgetMapGenerator extends Generator {
      */
     private void generateImplementationDetector(
             SourceWriter sourceWriter,
-            Collection<Class<? extends ComponentConnector>> paintablesHavingWidgetAnnotation) {
+            Collection<Class<? extends ServerConnector>> paintablesHavingWidgetAnnotation) {
         sourceWriter
                 .println("public Class<? extends "
-                        + componentConnectorClassName
+                        + serverConnectorClassName
                         + "> "
                         + "getConnectorClassForServerSideClassName(String fullyQualifiedName) {");
         sourceWriter.indent();
         sourceWriter
                 .println("fullyQualifiedName = fullyQualifiedName.intern();");
 
-        for (Class<? extends ComponentConnector> connectorClass : paintablesHavingWidgetAnnotation) {
+        for (Class<? extends ServerConnector> connectorClass : paintablesHavingWidgetAnnotation) {
             Class<? extends ClientConnector> clientConnectorClass = getClientConnectorClass(connectorClass);
             sourceWriter.print("if ( fullyQualifiedName == \"");
             sourceWriter.print(clientConnectorClass.getName());
@@ -393,7 +391,7 @@ public class WidgetMapGenerator extends Generator {
     }
 
     private static Class<? extends ClientConnector> getClientConnectorClass(
-            Class<? extends ComponentConnector> connectorClass) {
+            Class<? extends ServerConnector> connectorClass) {
         Connect annotation = connectorClass.getAnnotation(Connect.class);
         return (Class<? extends ClientConnector>) annotation.value();
     }
index 9ba005f75a1cf04988f0c36c9abf723b3ee7af73..7d8c402fc997ada6d9aaa43cc37dc616ea021906 100644 (file)
@@ -161,7 +161,8 @@ public class AbsoluteLayout extends AbstractLayout implements
         // connectorId unless the component is attached to the application so
         // the String->String map cannot be populated in internal* either.
         Map<String, String> connectorToPosition = new HashMap<String, String>();
-        for (Component c : this) {
+        for (Iterator<Component> ci = getComponentIterator(); ci.hasNext();) {
+            Component c = ci.next();
             connectorToPosition.put(c.getConnectorId(), getPosition(c)
                     .getCSSString());
         }
index 554d7806f931c8f4f8a9f2001deb65e4acaeae45..25695e3c0c028f66338786753f984f8099bcaa44 100644 (file)
@@ -5,20 +5,13 @@
 package com.vaadin.ui;
 
 import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
-import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -27,18 +20,14 @@ import com.vaadin.event.ActionManager;
 import com.vaadin.event.EventRouter;
 import com.vaadin.event.MethodEventSource;
 import com.vaadin.event.ShortcutListener;
+import com.vaadin.terminal.AbstractClientConnector;
 import com.vaadin.terminal.ErrorMessage;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.Terminal;
 import com.vaadin.terminal.gwt.client.ComponentState;
-import com.vaadin.terminal.gwt.client.communication.ClientRpc;
-import com.vaadin.terminal.gwt.client.communication.ServerRpc;
-import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
+import com.vaadin.terminal.gwt.server.ClientConnector;
 import com.vaadin.terminal.gwt.server.ComponentSizeValidator;
 import com.vaadin.terminal.gwt.server.ResourceReference;
-import com.vaadin.terminal.gwt.server.RpcManager;
-import com.vaadin.terminal.gwt.server.RpcTarget;
-import com.vaadin.terminal.gwt.server.ServerRpcManager;
 import com.vaadin.tools.ReflectTools;
 
 /**
@@ -53,7 +42,8 @@ import com.vaadin.tools.ReflectTools;
  * @since 3.0
  */
 @SuppressWarnings("serial")
-public abstract class AbstractComponent implements Component, MethodEventSource {
+public abstract class AbstractComponent extends AbstractClientConnector
+        implements Component, MethodEventSource {
 
     /* Private members */
 
@@ -63,11 +53,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      */
     private Object applicationData;
 
-    /**
-     * The container this component resides in.
-     */
-    private HasComponents parent = null;
-
     /**
      * The EventRouter used for the event model.
      */
@@ -88,11 +73,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      */
     private boolean delayedFocus;
 
-    /**
-     * List of repaint request listeners or null if not listened at all.
-     */
-    private LinkedList<RepaintRequestListener> repaintRequestListeners = null;
-
     /* Sizeable fields */
 
     private float width = SIZE_UNDEFINED;
@@ -110,31 +90,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      */
     private ActionManager actionManager;
 
-    /**
-     * A map from client to server RPC interface class to the RPC call manager
-     * that handles incoming RPC calls for that interface.
-     */
-    private Map<Class<?>, RpcManager> rpcManagerMap = new HashMap<Class<?>, RpcManager>();
-
-    /**
-     * A map from server to client RPC interface class to the RPC proxy that
-     * sends ourgoing RPC calls for that interface.
-     */
-    private Map<Class<?>, ClientRpc> rpcProxyMap = new HashMap<Class<?>, ClientRpc>();
-
-    /**
-     * Shared state object to be communicated from the server to the client when
-     * modified.
-     */
-    private ComponentState sharedState;
-
-    /**
-     * Pending RPC method invocations to be sent.
-     */
-    private ArrayList<ClientMethodInvocation> pendingInvocations = new ArrayList<ClientMethodInvocation>();
-
-    private String connectorId;
-
     /* Constructor */
 
     /**
@@ -287,6 +242,7 @@ public abstract class AbstractComponent implements Component, MethodEventSource
         if (locale != null) {
             return locale;
         }
+        HasComponents parent = getParent();
         if (parent != null) {
             return parent.getLocale();
         }
@@ -378,21 +334,18 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * 
      * @see com.vaadin.terminal.gwt.client.Connector#isConnectorEnabled()
      */
+    @Override
     public boolean isConnectorEnabled() {
-        if (getParent() == null) {
-            // No parent -> the component cannot receive updates from the client
+        if (!isVisible()) {
+            return false;
+        } else if (!isEnabled()) {
+            return false;
+        } else if (!super.isConnectorEnabled()) {
+            return false;
+        } else if (!getParent().isComponentVisible(this)) {
             return false;
         } else {
-            boolean thisEnabledAndVisible = isEnabled() && isVisible();
-            if (!thisEnabledAndVisible) {
-                return false;
-            }
-
-            if (!getParent().isConnectorEnabled()) {
-                return false;
-            }
-
-            return getParent().isComponentVisible(this);
+            return true;
         }
     }
 
@@ -529,8 +482,20 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * Gets the component's parent component. Don't add a JavaDoc comment here,
      * we use the default documentation from implemented interface.
      */
+    @Override
     public HasComponents getParent() {
-        return parent;
+        return (HasComponents) super.getParent();
+    }
+
+    @Override
+    public void setParent(ClientConnector parent) {
+        if (parent == null || parent instanceof HasComponents) {
+            super.setParent(parent);
+        } else {
+            throw new IllegalArgumentException(
+                    "The parent of a Component must implement HasComponents, which "
+                            + parent.getClass() + " doesn't do.");
+        }
     }
 
     /**
@@ -558,36 +523,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource
         return null;
     }
 
-    /*
-     * Sets the parent component. Don't add a JavaDoc comment here, we use the
-     * default documentation from implemented interface.
-     */
-    public void setParent(HasComponents parent) {
-
-        // If the parent is not changed, don't do anything
-        if (parent == this.parent) {
-            return;
-        }
-
-        if (parent != null && this.parent != null) {
-            throw new IllegalStateException(getClass().getName()
-                    + " already has a parent.");
-        }
-
-        // Send detach event if the component have been connected to a window
-        if (getApplication() != null) {
-            detach();
-        }
-
-        // Connect to new parent
-        this.parent = parent;
-
-        // Send attach event if connected to a window
-        if (getApplication() != null) {
-            attach();
-        }
-    }
-
     /**
      * Gets the error message for this component.
      * 
@@ -648,12 +583,10 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * Gets the parent window of the component. Don't add a JavaDoc comment
      * here, we use the default documentation from implemented interface.
      */
+    @Override
     public Root getRoot() {
-        if (parent == null) {
-            return null;
-        } else {
-            return parent.getRoot();
-        }
+        // Just make method from implemented Component interface public
+        return super.getRoot();
     }
 
     /*
@@ -661,9 +594,9 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * comment here, we use the default documentation from implemented
      * interface.
      */
+    @Override
     public void attach() {
-        getRoot().componentAttached(this);
-        requestRepaint();
+        super.attach();
         if (delayedFocus) {
             focus();
         }
@@ -674,13 +607,13 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * Detach the component from application. Don't add a JavaDoc comment here,
      * we use the default documentation from implemented interface.
      */
+    @Override
     public void detach() {
         if (actionManager != null) {
             // Remove any existing viewer. Root cast is just to make the
             // compiler happy
             actionManager.setViewer((Root) null);
         }
-        getRoot().componentDetached(this);
     }
 
     /**
@@ -717,12 +650,10 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * @return the parent application of the component or <code>null</code>.
      * @see #attach()
      */
+    @Override
     public Application getApplication() {
-        if (parent == null) {
-            return null;
-        } else {
-            return parent.getApplication();
-        }
+        // Just make method inherited from Component interface public
+        return super.getApplication();
     }
 
     /**
@@ -762,11 +693,9 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * 
      * @return updated component shared state
      */
+    @Override
     public ComponentState getState() {
-        if (null == sharedState) {
-            sharedState = createState();
-        }
-        return sharedState;
+        return (ComponentState) super.getState();
     }
 
     /*
@@ -801,95 +730,15 @@ public abstract class AbstractComponent implements Component, MethodEventSource
         }
     }
 
-    /**
-     * Creates the shared state bean to be used in server to client
-     * communication.
-     * <p>
-     * By default a state object of the defined return type of
-     * {@link #getState()} is created. Subclasses can override this method and
-     * return a new instance of the correct state class but this should rarely
-     * be necessary.
-     * </p>
-     * <p>
-     * No configuration of the values of the state should be performed in
-     * {@link #createState()}.
-     * 
-     * @since 7.0
-     * 
-     * @return new shared state object
-     */
-    protected ComponentState createState() {
-        try {
-            return getStateType().newInstance();
-        } catch (Exception e) {
-            throw new RuntimeException(
-                    "Error creating state of type " + getStateType().getName()
-                            + " for " + getClass().getName(), e);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see com.vaadin.terminal.gwt.server.ClientConnector#getStateType()
-     */
-    public Class<? extends ComponentState> getStateType() {
-        try {
-            Method m = getClass().getMethod("getState", (Class[]) null);
-            Class<? extends ComponentState> type = (Class<? extends ComponentState>) m
-                    .getReturnType();
-            return type;
-        } catch (Exception e) {
-            throw new RuntimeException("Error finding state type for "
-                    + getClass().getName(), e);
-        }
-    }
-
     /* Documentation copied from interface */
+    @Override
     public void requestRepaint() {
         // Invisible components (by flag in this particular component) do not
         // need repaints
         if (!getState().isVisible()) {
             return;
         }
-
-        fireRequestRepaintEvent();
-    }
-
-    /**
-     * Fires the repaint request event.
-     * 
-     * @param alreadyNotified
-     */
-    // Notify listeners only once
-    private void fireRequestRepaintEvent() {
-        // Notify the listeners
-        if (repaintRequestListeners != null
-                && !repaintRequestListeners.isEmpty()) {
-            final Object[] listeners = repaintRequestListeners.toArray();
-            final RepaintRequestEvent event = new RepaintRequestEvent(this);
-            for (int i = 0; i < listeners.length; i++) {
-                ((RepaintRequestListener) listeners[i]).repaintRequested(event);
-            }
-        }
-    }
-
-    /* Documentation copied from interface */
-    public void addListener(RepaintRequestListener listener) {
-        if (repaintRequestListeners == null) {
-            repaintRequestListeners = new LinkedList<RepaintRequestListener>();
-        }
-        if (!repaintRequestListeners.contains(listener)) {
-            repaintRequestListeners.add(listener);
-        }
-    }
-
-    /* Documentation copied from interface */
-    public void removeListener(RepaintRequestListener listener) {
-        if (repaintRequestListeners != null) {
-            repaintRequestListeners.remove(listener);
-            if (repaintRequestListeners.isEmpty()) {
-                repaintRequestListeners = null;
-            }
-        }
+        super.requestRepaint();
     }
 
     /* General event framework */
@@ -1155,15 +1004,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      *         are found.
      */
     public Collection<?> getListeners(Class<?> eventType) {
-        if (eventType.isAssignableFrom(RepaintRequestEvent.class)) {
-            // RepaintRequestListeners are not stored in eventRouter
-            if (repaintRequestListeners == null) {
-                return Collections.EMPTY_LIST;
-            } else {
-                return Collections
-                        .unmodifiableCollection(repaintRequestListeners);
-            }
-        }
         if (eventRouter == null) {
             return Collections.EMPTY_LIST;
         }
@@ -1512,159 +1352,4 @@ public abstract class AbstractComponent implements Component, MethodEventSource
             actionManager.removeAction(shortcut);
         }
     }
-
-    /**
-     * Registers an RPC interface implementation for this component.
-     * 
-     * A component can listen to multiple RPC interfaces, and subclasses can
-     * register additional implementations.
-     * 
-     * @since 7.0
-     * 
-     * @param implementation
-     *            RPC interface implementation
-     * @param rpcInterfaceType
-     *            RPC interface class for which the implementation should be
-     *            registered
-     */
-    protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
-        rpcManagerMap.put(rpcInterfaceType, new ServerRpcManager<T>(
-                implementation, rpcInterfaceType));
-    }
-
-    /**
-     * Registers an RPC interface implementation for this component.
-     * 
-     * A component can listen to multiple RPC interfaces, and subclasses can
-     * register additional implementations.
-     * 
-     * @since 7.0
-     * 
-     * @param implementation
-     *            RPC interface implementation. Also used to deduce the type.
-     */
-    protected <T extends ServerRpc> void registerRpc(T implementation) {
-        Class<?> cls = implementation.getClass();
-        Class<?>[] interfaces = cls.getInterfaces();
-        while (interfaces.length == 0) {
-            // Search upwards until an interface is found. It must be found as T
-            // extends ServerRpc
-            cls = cls.getSuperclass();
-            interfaces = cls.getInterfaces();
-        }
-        if (interfaces.length != 1
-                || !(ServerRpc.class.isAssignableFrom(interfaces[0]))) {
-            throw new RuntimeException(
-                    "Use registerRpc(T implementation, Class<T> rpcInterfaceType) if the Rpc implementation implements more than one interface");
-        }
-        Class<T> type = (Class<T>) interfaces[0];
-        registerRpc(implementation, type);
-    }
-
-    /**
-     * Returns an RPC proxy for a given server to client RPC interface for this
-     * component.
-     * 
-     * TODO more javadoc, subclasses, ...
-     * 
-     * @param rpcInterface
-     *            RPC interface type
-     * 
-     * @since 7.0
-     */
-    public <T extends ClientRpc> T getRpcProxy(final Class<T> rpcInterface) {
-        // create, initialize and return a dynamic proxy for RPC
-        try {
-            if (!rpcProxyMap.containsKey(rpcInterface)) {
-                Class<T> proxyClass = (Class) Proxy.getProxyClass(
-                        rpcInterface.getClassLoader(), rpcInterface);
-                Constructor<T> constructor = proxyClass
-                        .getConstructor(InvocationHandler.class);
-                T rpcProxy = constructor.newInstance(new RpcInvoicationHandler(
-                        rpcInterface));
-                // cache the proxy
-                rpcProxyMap.put(rpcInterface, rpcProxy);
-            }
-            return (T) rpcProxyMap.get(rpcInterface);
-        } catch (Exception e) {
-            // TODO exception handling?
-            throw new RuntimeException(e);
-        }
-    }
-
-    private class RpcInvoicationHandler implements InvocationHandler,
-            Serializable {
-
-        private String rpcInterfaceName;
-
-        public RpcInvoicationHandler(Class<?> rpcInterface) {
-            rpcInterfaceName = rpcInterface.getName().replaceAll("\\$", ".");
-        }
-
-        public Object invoke(Object proxy, Method method, Object[] args)
-                throws Throwable {
-            addMethodInvocationToQueue(rpcInterfaceName, method, args);
-            // TODO no need to do full repaint if only RPC calls
-            requestRepaint();
-            return null;
-        }
-
-    }
-
-    /**
-     * For internal use: adds a method invocation to the pending RPC call queue.
-     * 
-     * @param interfaceName
-     *            RPC interface name
-     * @param methodName
-     *            RPC method name
-     * @param parameters
-     *            RPC vall parameters
-     * 
-     * @since 7.0
-     */
-    protected void addMethodInvocationToQueue(String interfaceName,
-            Method method, Object[] parameters) {
-        // add to queue
-        pendingInvocations.add(new ClientMethodInvocation(this, interfaceName,
-                method, parameters));
-    }
-
-    /**
-     * @see RpcTarget#getRpcManager(Class)
-     * 
-     * @param rpcInterface
-     *            RPC interface for which a call was made
-     * @return RPC Manager handling calls for the interface
-     * 
-     * @since 7.0
-     */
-    public RpcManager getRpcManager(Class<?> rpcInterface) {
-        return rpcManagerMap.get(rpcInterface);
-    }
-
-    public List<ClientMethodInvocation> retrievePendingRpcCalls() {
-        if (pendingInvocations.isEmpty()) {
-            return Collections.emptyList();
-        } else {
-            List<ClientMethodInvocation> result = pendingInvocations;
-            pendingInvocations = new ArrayList<ClientMethodInvocation>();
-            return Collections.unmodifiableList(result);
-        }
-    }
-
-    public String getConnectorId() {
-        if (connectorId == null) {
-            if (getApplication() == null) {
-                throw new RuntimeException(
-                        "Component must be attached to an application when getConnectorId() is called for the first time");
-            }
-            connectorId = getApplication().createConnectorId(this);
-        }
-        return connectorId;
-    }
-
-    private Logger getLogger() {
-        return Logger.getLogger(AbstractComponent.class.getName());
-    }
 }
index 1c857a03cde27618674794fa8f035e13583702a1..8ef458b704bc443cd21ec26582061c013da37d79 100644 (file)
@@ -71,36 +71,6 @@ public abstract class AbstractComponentContainer extends AbstractComponent
         }
     }
 
-    /**
-     * Notifies all contained components that the container is attached to a
-     * window.
-     * 
-     * @see com.vaadin.ui.Component#attach()
-     */
-    @Override
-    public void attach() {
-        super.attach();
-
-        for (final Iterator<Component> i = getComponentIterator(); i.hasNext();) {
-            (i.next()).attach();
-        }
-    }
-
-    /**
-     * Notifies all contained components that the container is detached from a
-     * window.
-     * 
-     * @see com.vaadin.ui.Component#detach()
-     */
-    @Override
-    public void detach() {
-        super.detach();
-
-        for (final Iterator<Component> i = getComponentIterator(); i.hasNext();) {
-            (i.next()).detach();
-        }
-    }
-
     /* Events */
 
     private static final Method COMPONENT_ATTACHED_METHOD;
@@ -355,46 +325,6 @@ public abstract class AbstractComponentContainer extends AbstractComponent
                 true);
     }
 
-    public void requestRepaintAll() {
-        requestRepaintAll(this);
-    }
-
-    /**
-     * Helper that implements the logic needed by requestRepaintAll. Calls
-     * requestRepaintAll/requestRepaint for the component container and all its
-     * children recursively.
-     * 
-     * @param container
-     */
-    public static void requestRepaintAll(HasComponents container) {
-        container.requestRepaint();
-        if (container instanceof Panel) {
-            Panel p = (Panel) container;
-            // #2924 Panel is invalid, really invalid.
-            // Panel.getComponentIterator returns the children of content, not
-            // of Panel...
-            if (p.getContent() != null) {
-                p.getContent().requestRepaint();
-            }
-        }
-        for (Iterator<Component> childIterator = container
-                .getComponentIterator(); childIterator.hasNext();) {
-            Component c = childIterator.next();
-            if (c instanceof HasComponents) {
-                requestRepaintAll((HasComponents) c);
-            } else {
-                c.requestRepaint();
-            }
-        }
-    }
-
-    /**
-     * Returns an iterator for the child components.
-     * 
-     * @return An iterator for the child components.
-     * @see #getComponentIterator()
-     * @since 7.0.0
-     */
     public Iterator<Component> iterator() {
         return getComponentIterator();
     }
index 3632c4ca5efa7a14ec80be961d9ab776f1c3e8ff..ce6df9854f485c79b5d4950c1c0d0b7912609296 100644 (file)
@@ -304,40 +304,9 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
      * </p>
      * 
      * @return the parent component
-     * @see #setParent(Component)
      */
     public HasComponents getParent();
 
-    /**
-     * Sets the parent component of the component.
-     * 
-     * <p>
-     * This method automatically calls {@link #attach()} if the parent becomes
-     * attached to the application, regardless of whether it was attached
-     * previously. Conversely, if the parent is {@code null} and the component
-     * is attached to the application, {@link #detach()} is called for the
-     * component.
-     * </p>
-     * <p>
-     * This method is rarely called directly. The
-     * {@link ComponentContainer#addComponent(Component)} method is normally
-     * used for adding components to a container and it will call this method
-     * implicitly.
-     * </p>
-     * 
-     * <p>
-     * It is not possible to change the parent without first setting the parent
-     * to {@code null}.
-     * </p>
-     * 
-     * @param parent
-     *            the parent component
-     * @throws IllegalStateException
-     *             if a parent is given even though the component already has a
-     *             parent
-     */
-    public void setParent(HasComponents parent);
-
     /**
      * Tests whether the component is in the read-only mode. The user can not
      * change the value of a read-only component. As only {@link Field}
@@ -564,15 +533,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
     public Application getApplication();
 
     /**
-     * Notifies the component that it is connected to an application.
-     * 
-     * <p>
-     * The caller of this method is {@link #setParent(Component)} if the parent
-     * is itself already attached to the application. If not, the parent will
-     * call the {@link #attach()} for all its children when it is attached to
-     * the application. This method is always called before the component is
-     * painted for the first time.
-     * </p>
+     * {@inheritDoc}
      * 
      * <p>
      * Reimplementing the {@code attach()} method is useful for tasks that need
@@ -624,37 +585,9 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
      *     }
      * }
      * </pre>
-     * 
-     * <p>
-     * The attachment logic is implemented in {@link AbstractComponent}.
-     * </p>
-     * 
-     * @see #getApplication()
      */
     public void attach();
 
-    /**
-     * Notifies the component that it is detached from the application.
-     * 
-     * <p>
-     * The {@link #getApplication()} and {@link #getRoot()} methods might return
-     * <code>null</code> after this method is called.
-     * </p>
-     * 
-     * <p>
-     * This method must call {@link Root#componentDetached(Component)} to let
-     * the Root know that a new Component has been attached.
-     * </p>
-     * *
-     * <p>
-     * The caller of this method is {@link #setParent(Component)} if the parent
-     * is in the application. When the parent is detached from the application
-     * it is its response to call {@link #detach()} for all the children and to
-     * detach itself from the terminal.
-     * </p>
-     */
-    public void detach();
-
     /**
      * Gets the locale of the component.
      * 
@@ -719,75 +652,6 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
      */
     public String getDebugId();
 
-    /**
-     * Requests that the component should be repainted as soon as possible.
-     */
-    public void requestRepaint();
-
-    /**
-     * Repaint request event is thrown when the connector needs to be repainted.
-     * This is typically done when the <code>paint</code> method would return
-     * dissimilar UIDL from the previous call of the method.
-     */
-    @SuppressWarnings("serial")
-    public static class RepaintRequestEvent extends EventObject {
-
-        /**
-         * Constructs a new event.
-         * 
-         * @param source
-         *            the paintable needing repaint.
-         */
-        public RepaintRequestEvent(ClientConnector source) {
-            super(source);
-        }
-
-        /**
-         * Gets the connector needing repainting.
-         * 
-         * @return Paintable for which the <code>paint</code> method will return
-         *         dissimilar UIDL from the previous call of the method.
-         */
-        public ClientConnector getConnector() {
-            return (ClientConnector) getSource();
-        }
-    }
-
-    /**
-     * Listens repaint requests. The <code>repaintRequested</code> method is
-     * called when the paintable needs to be repainted. This is typically done
-     * when the <code>paint</code> method would return dissimilar UIDL from the
-     * previous call of the method.
-     */
-    public interface RepaintRequestListener extends Serializable {
-
-        /**
-         * Receives repaint request events.
-         * 
-         * @param event
-         *            the repaint request event specifying the paintable source.
-         */
-        public void repaintRequested(RepaintRequestEvent event);
-    }
-
-    /**
-     * Adds repaint request listener. In order to assure that no repaint
-     * requests are missed, the new repaint listener should paint the paintable
-     * right after adding itself as listener.
-     * 
-     * @param listener
-     *            the listener to be added.
-     */
-    public void addListener(RepaintRequestListener listener);
-
-    /**
-     * Removes repaint request listener.
-     * 
-     * @param listener
-     *            the listener to be removed.
-     */
-    public void removeListener(RepaintRequestListener listener);
-
     /* Component event framework */
 
     /**
index 0a2656af3154cbf80d9947c98a69969ef9cb1a2e..e8ec6bd041d1454f60f1de14155a367b9282a537 100644 (file)
@@ -11,9 +11,9 @@ import com.vaadin.event.LayoutEvents.LayoutClickListener;
 import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
 import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
+import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler;
 import com.vaadin.terminal.gwt.client.ui.csslayout.CssLayoutServerRpc;
 import com.vaadin.terminal.gwt.client.ui.csslayout.CssLayoutState;
-import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler;
 
 /**
  * CssLayout is a layout component that can be used in browser environment only.
@@ -185,7 +185,8 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
     public void updateState() {
         super.updateState();
         getState().getChildCss().clear();
-        for (Component child : this) {
+        for (Iterator<Component> ci = getComponentIterator(); ci.hasNext();) {
+            Component child = ci.next();
             String componentCssString = getCss(child);
             if (componentCssString != null) {
                 getState().getChildCss().put(child, componentCssString);
index 806ee91335f50ae2fd265e2d953b86814551c016..269f24fb2cb5a6fac57f7cc23f8fe85457121c06 100644 (file)
@@ -63,11 +63,9 @@ public abstract class CustomField<T> extends AbstractField<T> implements
     @Override
     public void attach() {
         root = getContent();
-        super.attach();
         getContent().setParent(this);
-        getContent().attach();
-
         fireComponentAttachEvent(getContent());
+        super.attach();
     }
 
     /**
@@ -79,7 +77,6 @@ public abstract class CustomField<T> extends AbstractField<T> implements
     @Override
     public void detach() {
         super.detach();
-        getContent().detach();
     }
 
     /**
@@ -154,10 +151,6 @@ public abstract class CustomField<T> extends AbstractField<T> implements
         return (null != getContent()) ? 1 : 0;
     }
 
-    public void requestRepaintAll() {
-        AbstractComponentContainer.requestRepaintAll(this);
-    }
-
     /**
      * Fires the component attached event. This should be called by the
      * addComponent methods after the component have been added to this
index 84df7e7c7c2d1821d82775cb636a8b43538913d9..a4e509422ceb4858513cf786a9b2ddfd10dca22e 100644 (file)
@@ -9,10 +9,8 @@ import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.vaadin.terminal.gwt.server.AbstractCommunicationManager;
+import com.vaadin.terminal.AbstractClientConnector;
 import com.vaadin.terminal.gwt.server.ClientConnector;
-import com.vaadin.ui.Component.RepaintRequestEvent;
-import com.vaadin.ui.Component.RepaintRequestListener;
 
 /**
  * A class that tracks dirty {@link ClientConnector}s. A {@link ClientConnector}
@@ -25,8 +23,8 @@ import com.vaadin.ui.Component.RepaintRequestListener;
  * @since 7.0.0
  * 
  */
-public class DirtyConnectorTracker implements RepaintRequestListener {
-    private Set<Component> dirtyComponents = new HashSet<Component>();
+public class DirtyConnectorTracker {
+    private Set<ClientConnector> dirtyConnectors = new HashSet<ClientConnector>();
     private Root root;
 
     /**
@@ -43,90 +41,72 @@ public class DirtyConnectorTracker implements RepaintRequestListener {
         this.root = root;
     }
 
-    public void repaintRequested(RepaintRequestEvent event) {
-        markDirty((Component) event.getConnector());
-    }
-
-    public void componentAttached(Component component) {
-        component.addListener(this);
-        markDirty(component);
-    }
-
-    private void markDirty(Component component) {
+    public void markDirty(ClientConnector connector) {
         if (getLogger().isLoggable(Level.FINE)) {
-            if (!dirtyComponents.contains(component)) {
+            if (!dirtyConnectors.contains(connector)) {
                 getLogger()
-                        .fine(getDebugInfo(component) + " " + "is now dirty");
+                        .fine(getDebugInfo(connector) + " " + "is now dirty");
             }
         }
 
-        dirtyComponents.add(component);
+        dirtyConnectors.add(connector);
     }
 
-    private void markClean(Component component) {
+    public void markClean(ClientConnector connector) {
         if (getLogger().isLoggable(Level.FINE)) {
-            if (dirtyComponents.contains(component)) {
+            if (dirtyConnectors.contains(connector)) {
                 getLogger().fine(
-                        getDebugInfo(component) + " " + "is no longer dirty");
+                        getDebugInfo(connector) + " " + "is no longer dirty");
             }
         }
 
-        dirtyComponents.remove(component);
+        dirtyConnectors.remove(connector);
     }
 
-    private String getDebugInfo(Component component) {
-        String message = getObjectString(component);
-        if (component.getParent() != null) {
-            message += " (parent: " + getObjectString(component.getParent())
+    private String getDebugInfo(ClientConnector connector) {
+        String message = getObjectString(connector);
+        if (connector.getParent() != null) {
+            message += " (parent: " + getObjectString(connector.getParent())
                     + ")";
         }
         return message;
     }
 
-    private String getObjectString(Object component) {
-        return component.getClass().getName() + "@"
-                + Integer.toHexString(component.hashCode());
+    private String getObjectString(Object connector) {
+        return connector.getClass().getName() + "@"
+                + Integer.toHexString(connector.hashCode());
     }
 
-    public void componentDetached(Component component) {
-        component.removeListener(this);
-        markClean(component);
+    public void markAllConnectorsDirty() {
+        markConnectorsDirtyRecursively(root);
+        getLogger().fine("All connectors are now dirty");
     }
 
-    public void markAllComponentsDirty() {
-        markComponentsDirtyRecursively(root);
-        getLogger().fine("All components are now dirty");
-    }
-
-    public void markAllComponentsClean() {
-        dirtyComponents.clear();
-        getLogger().fine("All components are now clean");
+    public void markAllConnectorsClean() {
+        dirtyConnectors.clear();
+        getLogger().fine("All connectors are now clean");
     }
 
     /**
-     * Marks all visible components dirty, starting from the given component and
+     * Marks all visible connectors dirty, starting from the given connector and
      * going downwards in the hierarchy.
      * 
      * @param c
      *            The component to start iterating downwards from
      */
-    private void markComponentsDirtyRecursively(Component c) {
-        if (!c.isVisible()) {
+    private void markConnectorsDirtyRecursively(ClientConnector c) {
+        if (c instanceof Component && !((Component) c).isVisible()) {
             return;
         }
         markDirty(c);
-        if (c instanceof HasComponents) {
-            HasComponents container = (HasComponents) c;
-            for (Component child : AbstractCommunicationManager
-                    .getChildComponents(container)) {
-                markComponentsDirtyRecursively(child);
-            }
+        for (ClientConnector child : AbstractClientConnector
+                .getAllChildrenIteratable(c)) {
+            markConnectorsDirtyRecursively(child);
         }
-
     }
 
-    public Collection<Component> getDirtyComponents() {
-        return dirtyComponents;
+    public Collection<ClientConnector> getDirtyConnectors() {
+        return dirtyConnectors;
     }
 
 }
index 5f5516b21f66d8cf247b8e52534d60d4551ae6aa..39b12e67e2b7d18ec2dae5724a682f9dbfd3f0b5 100644 (file)
@@ -1411,10 +1411,6 @@ public class Form extends AbstractField<Object> implements Item.Editor,
         return new ComponentIterator();
     }
 
-    public void requestRepaintAll() {
-        AbstractComponentContainer.requestRepaintAll(this);
-    }
-
     public int getComponentCount() {
         int count = 0;
         if (getLayout() != null) {
index eca89ddcd2e6294cb1e4e5b41eaa01d48b805134..3ebd63bff2eaaf1e30a7a24f723b708ce6d56cab 100644 (file)
@@ -21,7 +21,10 @@ public interface HasComponents extends Component, Iterable<Component> {
      * container.
      * 
      * @return the component iterator.
+     * 
+     * @deprecated Use {@link #iterator()} instead.
      */
+    @Deprecated
     public Iterator<Component> getComponentIterator();
 
     /**
@@ -43,12 +46,4 @@ public interface HasComponents extends Component, Iterable<Component> {
      */
     public boolean isComponentVisible(Component childComponent);
 
-    /**
-     * Causes a repaint of this component, and all components below it.
-     * 
-     * This should only be used in special cases, e.g when the state of a
-     * descendant depends on the state of a ancestor.
-     */
-    public void requestRepaintAll();
-
 }
diff --git a/src/com/vaadin/ui/HelloWorldExtension.java b/src/com/vaadin/ui/HelloWorldExtension.java
new file mode 100644 (file)
index 0000000..6d9ce9b
--- /dev/null
@@ -0,0 +1,38 @@
+/* 
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.ui;
+
+import com.vaadin.terminal.AbstractExtension;
+import com.vaadin.terminal.gwt.client.ui.helloworldfeature.GreetAgainRpc;
+import com.vaadin.terminal.gwt.client.ui.helloworldfeature.HelloWorldRpc;
+import com.vaadin.terminal.gwt.client.ui.helloworldfeature.HelloWorldState;
+
+public class HelloWorldExtension extends AbstractExtension {
+
+    public HelloWorldExtension() {
+        registerRpc(new HelloWorldRpc() {
+            public void onMessageSent(String message) {
+                getRoot().showNotification(message);
+            }
+        });
+    }
+
+    @Override
+    public HelloWorldState getState() {
+        return (HelloWorldState) super.getState();
+    }
+
+    public void setGreeting(String greeting) {
+        getState().setGreeting(greeting);
+        requestRepaint();
+    }
+
+    public String getGreeting() {
+        return getState().getGreeting();
+    }
+
+    public void greetAgain() {
+        getRpcProxy(GreetAgainRpc.class).greetAgain();
+    }
+}
index a0fd84bbef963f49dfdeef5e12c3424495971b52..37e03ffb379d49849d2a516b6d92cb43d872ff03 100644 (file)
@@ -193,15 +193,6 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
         }
     }
 
-    @Override
-    public void requestRepaintAll() {
-        // Panel has odd structure, delegate to layout
-        requestRepaint();
-        if (getContent() != null) {
-            getContent().requestRepaintAll();
-        }
-    }
-
     /**
      * Adds the component into this container.
      * 
@@ -354,35 +345,6 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
         }
     }
 
-    /**
-     * Notifies the component that it is connected to an application.
-     * 
-     * @see com.vaadin.ui.Component#attach()
-     */
-    @Override
-    public void attach() {
-        getRoot().componentAttached(this);
-        // can't call parent here as this is Panels hierarchy is a hack
-        requestRepaint();
-        if (content != null) {
-            content.attach();
-        }
-    }
-
-    /**
-     * Notifies the component that it is detached from the application.
-     * 
-     * @see com.vaadin.ui.Component#detach()
-     */
-    @Override
-    public void detach() {
-        // can't call parent here as this is Panels hierarchy is a hack
-        if (content != null) {
-            content.detach();
-        }
-        getRoot().componentDetached(this);
-    }
-
     /**
      * Removes all components from this container.
      * 
index 9c3aef4152fd96f8fd1d6e88f031a0d91f82b1be..0ba8ef27fb1a1555bf6ad850c544d96e99150fe6 100644 (file)
@@ -1584,12 +1584,4 @@ public abstract class Root extends AbstractComponentContainer implements
         return dirtyConnectorTracker;
     }
 
-    public void componentAttached(Component component) {
-        getDirtyConnectorTracker().componentAttached(component);
-    }
-
-    public void componentDetached(Component component) {
-        getDirtyConnectorTracker().componentDetached(component);
-    }
-
 }
index 299eace16d8fa89ac402a7cb7a65bd54dc3deaaf..e41c3d2a424c67d5a43c3124498c5f386fa9d8cc 100644 (file)
@@ -3705,13 +3705,6 @@ public class Table extends AbstractSelect implements Action.Container,
         super.attach();
 
         refreshRenderedCells();
-
-        if (visibleComponents != null) {
-            for (final Iterator<Component> i = visibleComponents.iterator(); i
-                    .hasNext();) {
-                i.next().attach();
-            }
-        }
     }
 
     /**
@@ -3722,13 +3715,6 @@ public class Table extends AbstractSelect implements Action.Container,
     @Override
     public void detach() {
         super.detach();
-
-        if (visibleComponents != null) {
-            for (final Iterator<Component> i = visibleComponents.iterator(); i
-                    .hasNext();) {
-                i.next().detach();
-            }
-        }
     }
 
     /**
@@ -4453,10 +4439,6 @@ public class Table extends AbstractSelect implements Action.Container,
         }
     }
 
-    public void requestRepaintAll() {
-        AbstractComponentContainer.requestRepaintAll(this);
-    }
-
     /**
      * Sets the drag start mode of the Table. Drag start mode controls how Table
      * behaves as a drag source.
index b1c4a8f4bed275c1cc1ec949a8dce469be163298..1903e66f9275238fc1a4783adfcbe0c0a9b53dee 100644 (file)
@@ -58,5 +58,4 @@ public class TestAbstractComponentStyleNames extends TestCase {
         return new AbstractComponent() {
         };
     }
-
 }
index 0749dc299e4fe0b1c01173c7dc396cc890d9213b..c6af98a87338921f58f3ede5f7a2577a6de973a1 100644 (file)
@@ -9,8 +9,6 @@ import com.vaadin.data.Property.ValueChangeEvent;
 import com.vaadin.data.Property.ValueChangeListener;
 import com.vaadin.data.util.ObjectProperty;
 import com.vaadin.data.util.PropertyFormatter;
-import com.vaadin.ui.Component.RepaintRequestEvent;
-import com.vaadin.ui.Component.RepaintRequestListener;
 import com.vaadin.ui.TextField;
 
 public class TextFieldWithPropertyFormatter extends TestCase {
@@ -30,7 +28,13 @@ public class TextFieldWithPropertyFormatter extends TestCase {
     protected void setUp() throws Exception {
         super.setUp();
 
-        field = new TextField();
+        field = new TextField() {
+            @Override
+            public void requestRepaint() {
+                repainted++;
+                super.requestRepaint();
+            }
+        };
 
         formatter = new PropertyFormatter<String>() {
 
@@ -61,11 +65,6 @@ public class TextFieldWithPropertyFormatter extends TestCase {
         };
 
         field.addListener(listener);
-        field.addListener(new RepaintRequestListener() {
-            public void repaintRequested(RepaintRequestEvent event) {
-                repainted++;
-            }
-        });
         listenerCalled = 0;
         repainted = 0;
     }
diff --git a/tests/testbench/com/vaadin/tests/features/HelloWorldFeatureTest.java b/tests/testbench/com/vaadin/tests/features/HelloWorldFeatureTest.java
new file mode 100644 (file)
index 0000000..3d26b92
--- /dev/null
@@ -0,0 +1,38 @@
+/* 
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.tests.features;
+
+import com.vaadin.terminal.WrappedRequest;
+import com.vaadin.tests.components.AbstractTestRoot;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.HelloWorldExtension;
+
+public class HelloWorldFeatureTest extends AbstractTestRoot {
+
+    @Override
+    protected void setup(WrappedRequest request) {
+        final HelloWorldExtension extension = new HelloWorldExtension();
+        extension.setGreeting("Kind words");
+        addExtension(extension);
+
+        addComponent(new Button("Greet again", new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                extension.greetAgain();
+            }
+        }));
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "Testing basic Feature";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}