]> source.dussan.org Git - vaadin-framework.git/commitdiff
Show a sensible message for missing extensions (#10799)
authorArtur Signell <artur@vaadin.com>
Tue, 1 Nov 2016 20:52:48 +0000 (22:52 +0200)
committerVaadin Code Review <review@vaadin.com>
Thu, 3 Nov 2016 06:49:34 +0000 (06:49 +0000)
Also remove ComponentMissingFromDefaultWidgetsetTest since it's
identical to UnknownComponentConnectorTest

Change-Id: I4b4b8f40c8376f4ea26b73d41191a3e7e811df01

12 files changed:
client-compiler/src/main/java/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java
client-compiler/src/main/java/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java
client/src/main/java/com/vaadin/client/ApplicationConfiguration.java
client/src/main/java/com/vaadin/client/VUIDLBrowser.java
client/src/main/java/com/vaadin/client/WidgetSet.java
client/src/main/java/com/vaadin/client/debug/internal/OptimizedWidgetsetPanel.java
client/src/main/java/com/vaadin/client/ui/UnknownComponentConnector.java
client/src/main/java/com/vaadin/client/ui/UnknownExtensionConnector.java [new file with mode: 0644]
uitest/src/main/java/com/vaadin/tests/extensions/UnknownExtensionHandling.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/UnknownComponentConnectorTest.java
uitest/src/test/java/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java [deleted file]
uitest/src/test/java/com/vaadin/tests/extensions/UnknownExtensionHandlingTest.java [new file with mode: 0644]

index 510401e739f87da616d6206b3a48b1c5d51f39ce..0b85ede97b1a81457980a7e5d32d5bdb852e49cf 100644 (file)
@@ -58,6 +58,7 @@ import com.vaadin.client.metadata.TypeData;
 import com.vaadin.client.metadata.TypeDataStore;
 import com.vaadin.client.metadata.TypeDataStore.MethodAttribute;
 import com.vaadin.client.ui.UnknownComponentConnector;
+import com.vaadin.client.ui.UnknownExtensionConnector;
 import com.vaadin.server.widgetsetutils.metadata.ClientRpcVisitor;
 import com.vaadin.server.widgetsetutils.metadata.ConnectorBundle;
 import com.vaadin.server.widgetsetutils.metadata.ConnectorInitVisitor;
@@ -1123,6 +1124,8 @@ public class ConnectorBundleLoaderFactory extends Generator {
                 connectorsByLoadStyle.get(LoadStyle.EAGER));
         eagerBundle.processType(eagerLogger, typeOracle
                 .findType(UnknownComponentConnector.class.getCanonicalName()));
+        eagerBundle.processType(eagerLogger, typeOracle
+                .findType(UnknownExtensionConnector.class.getCanonicalName()));
         eagerBundle.processSubTypes(eagerLogger,
                 typeOracle.getType(ClientRpc.class.getName()));
         eagerBundle.processSubTypes(eagerLogger,
index d390ee0338804fd9b50c1c98818b0ec8e29d5be6..34bbaa8f2431c3606a52285bddbb696a2d7e92e2 100644 (file)
@@ -48,6 +48,7 @@ import com.vaadin.client.communication.JSONSerializer;
 import com.vaadin.client.connectors.AbstractRendererConnector;
 import com.vaadin.client.metadata.TypeDataStore.MethodAttribute;
 import com.vaadin.client.ui.UnknownComponentConnector;
+import com.vaadin.client.ui.UnknownExtensionConnector;
 import com.vaadin.shared.communication.ClientRpc;
 import com.vaadin.shared.communication.ServerRpc;
 import com.vaadin.shared.ui.Connect;
@@ -467,7 +468,9 @@ public class ConnectorBundle {
     private static boolean isConnected(JClassType type) {
         return type.isAnnotationPresent(Connect.class)
                 || type.getQualifiedSourceName().equals(
-                        UnknownComponentConnector.class.getCanonicalName());
+                        UnknownComponentConnector.class.getCanonicalName())
+                || type.getQualifiedSourceName().equals(
+                        UnknownExtensionConnector.class.getCanonicalName());
     }
 
     public static boolean isConnectedComponentConnector(JClassType type) {
index 6adb5968e7f1f8055ae32920742d9e5eb1a1ef04..239832014a9d3ffdcccd1d7982e0cce47b5a3325 100644 (file)
@@ -53,6 +53,7 @@ import com.vaadin.client.metadata.ConnectorBundleLoader;
 import com.vaadin.client.metadata.NoDataException;
 import com.vaadin.client.metadata.TypeData;
 import com.vaadin.client.ui.UnknownComponentConnector;
+import com.vaadin.client.ui.UnknownExtensionConnector;
 import com.vaadin.client.ui.ui.UIConnector;
 import com.vaadin.shared.ApplicationConstants;
 import com.vaadin.shared.ui.ui.UIConstants;
@@ -526,7 +527,11 @@ public class ApplicationConfiguration implements EntryPoint {
                 currentTag = getParentTag(currentTag.intValue());
             }
             if (type == null) {
-                type = UnknownComponentConnector.class;
+                if (isExtensionType(tag)) {
+                    type = UnknownExtensionConnector.class;
+                } else {
+                    type = UnknownComponentConnector.class;
+                }
                 if (unknownComponents == null) {
                     unknownComponents = new HashMap<Integer, String>();
                 }
@@ -537,6 +542,20 @@ public class ApplicationConfiguration implements EntryPoint {
         return type;
     }
 
+    private boolean isExtensionType(int tag) {
+        Integer currentTag = Integer.valueOf(tag);
+        while (currentTag != null) {
+            String serverSideClassNameForTag = getServerSideClassNameForTag(
+                    currentTag);
+            if ("com.vaadin.server.AbstractExtension"
+                    .equals(serverSideClassNameForTag)) {
+                return true;
+            }
+            currentTag = getParentTag(currentTag.intValue());
+        }
+        return false;
+    }
+
     public void addComponentInheritanceInfo(ValueMap valueMap) {
         JsArrayString keyArray = valueMap.getKeyArray();
         for (int i = 0; i < keyArray.length(); i++) {
index c0b313dcb7d449355cf4d277816fb2f56bd09c04..1985d6f843c8a05decf87c06ad7995b291495aec 100644 (file)
@@ -36,6 +36,7 @@ import com.google.gwt.event.dom.client.MouseOutHandler;
 import com.google.gwt.user.client.ui.RootPanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.client.ui.UnknownComponentConnector;
+import com.vaadin.client.ui.UnknownExtensionConnector;
 import com.vaadin.client.ui.VWindow;
 
 import elemental.json.JsonArray;
@@ -229,7 +230,8 @@ public class VUIDLBrowser extends SimpleTree {
                 int tag) {
             Class<? extends ServerConnector> widgetClassByDecodedTag = conf
                     .getConnectorClassByEncodedTag(tag);
-            if (widgetClassByDecodedTag == UnknownComponentConnector.class) {
+            if (widgetClassByDecodedTag == UnknownComponentConnector.class
+                    || widgetClassByDecodedTag == UnknownExtensionConnector.class) {
                 return conf.getUnknownServerClassNameByTag(tag)
                         + "(NO CLIENT IMPLEMENTATION FOUND)";
             } else {
index aa35a83822f2e0e6293ea4dc0cd6c41c09361d0f..29ec6ab5ee0465d255a839b1ef9f0d8e5f5979ae 100644 (file)
@@ -26,6 +26,8 @@ import com.vaadin.client.metadata.ConnectorBundleLoader;
 import com.vaadin.client.metadata.NoDataException;
 import com.vaadin.client.metadata.TypeData;
 import com.vaadin.client.ui.UnknownComponentConnector;
+import com.vaadin.client.ui.UnknownExtensionConnector;
+import com.vaadin.client.ui.UnknownExtensionConnector;
 
 public class WidgetSet {
     /**
@@ -55,33 +57,43 @@ public class WidgetSet {
         Class<? extends ServerConnector> classType = resolveInheritedConnectorType(
                 conf, tag);
 
-        if (classType == null || classType == UnknownComponentConnector.class) {
-            String serverSideName = conf.getUnknownServerClassNameByTag(tag);
-            UnknownComponentConnector c = GWT
-                    .create(UnknownComponentConnector.class);
-            c.setServerSideClassName(serverSideName);
-            Profiler.leave("WidgetSet.createConnector");
-            return c;
-        } else {
-            /*
-             * let the auto generated code instantiate this type
-             */
-            try {
+        try {
+            if (classType == null
+                    || classType == UnknownComponentConnector.class
+                    || classType == UnknownExtensionConnector.class) {
+                String serverSideName = conf
+                        .getUnknownServerClassNameByTag(tag);
+                if (classType == UnknownExtensionConnector.class) {
+                    // Display message in the console for non-visual connectors
+                    getLogger().severe(UnknownComponentConnector
+                            .createMessage(serverSideName));
+                    return GWT.create(UnknownExtensionConnector.class);
+                } else {
+                    UnknownComponentConnector c = GWT
+                            .create(UnknownComponentConnector.class);
+                    // Set message to be shown in a widget for visual connectors
+                    c.setServerSideClassName(serverSideName);
+                    return c;
+                }
+            } else {
+                /*
+                 * let the auto generated code instantiate this type
+                 */
                 ServerConnector connector = (ServerConnector) TypeData
                         .getType(classType).createInstance();
                 if (connector instanceof HasJavaScriptConnectorHelper) {
                     ((HasJavaScriptConnectorHelper) connector)
                             .getJavascriptConnectorHelper().setTag(tag);
                 }
-                Profiler.leave("WidgetSet.createConnector");
                 return connector;
-            } catch (NoDataException e) {
-                Profiler.leave("WidgetSet.createConnector");
-                throw new IllegalStateException(
-                        "There is no information about " + classType
-                                + ". Did you remember to compile the right widgetset?",
-                        e);
             }
+        } catch (NoDataException e) {
+            throw new IllegalStateException(
+                    "There is no information about " + classType
+                            + ". Did you remember to compile the right widgetset?",
+                    e);
+        } finally {
+            Profiler.leave("WidgetSet.createConnector");
         }
     }
 
index 4654421361becb061172efafae840866a4dd3753..7f59a1112a1fe42ddd01f3b6dbf20d9839ea68f4 100644 (file)
@@ -26,6 +26,7 @@ import com.vaadin.client.ApplicationConnection;
 import com.vaadin.client.ServerConnector;
 import com.vaadin.client.Util;
 import com.vaadin.client.ui.UnknownComponentConnector;
+import com.vaadin.client.ui.UnknownExtensionConnector;
 
 /**
  * Optimized widgetset view panel of the debug window.
@@ -89,7 +90,8 @@ public class OptimizedWidgetsetPanel extends FlowPanel {
                 break;
             }
 
-            if (connectorClass != UnknownComponentConnector.class) {
+            if (connectorClass != UnknownComponentConnector.class
+                    && connectorClass != UnknownExtensionConnector.class) {
                 usedConnectors.add(connectorClass.getName());
             }
             tag++;
index bb06aa3507dc7c7ed68059bad353c9e23996c561..8b9e3d5951d510f54532f54089a6eedf2b7e3874 100644 (file)
@@ -31,13 +31,17 @@ public class UnknownComponentConnector extends AbstractComponentConnector {
     }
 
     public void setServerSideClassName(String serverClassName) {
-        getWidget().setCaption("Widgetset '" + GWT.getModuleName()
-                + "' does not contain implementation for " + serverClassName
-                + ". Check its component connector's @Connect mapping, widgetsets "
+        getWidget().setCaption(createMessage(serverClassName));
+    }
+
+    public static String createMessage(String serverClassName) {
+        return "Widgetset '" + GWT.getModuleName()
+                + "' does not contain an implementation for " + serverClassName
+                + ". Check the connector's @Connect mapping, the widgetset's "
                 + "GWT module description file and re-compile your"
                 + " widgetset. In case you have downloaded a vaadin"
                 + " add-on package, you might want to refer to "
                 + "<a href='http://vaadin.com/using-addons'>add-on "
-                + "instructions</a>.");
+                + "instructions</a>.";
     }
 }
diff --git a/client/src/main/java/com/vaadin/client/ui/UnknownExtensionConnector.java b/client/src/main/java/com/vaadin/client/ui/UnknownExtensionConnector.java
new file mode 100644 (file)
index 0000000..151b1ad
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.ui;
+
+import com.vaadin.client.ServerConnector;
+import com.vaadin.client.extensions.AbstractExtensionConnector;
+
+/**
+ * Connector used as a placeholder for extensions that are not present in the
+ * widgetset.
+ * 
+ * @since
+ * @author Vaadin Ltd
+ */
+public class UnknownExtensionConnector extends AbstractExtensionConnector {
+    @Override
+    protected void extend(ServerConnector target) {
+        // Noop
+    }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/extensions/UnknownExtensionHandling.java b/uitest/src/main/java/com/vaadin/tests/extensions/UnknownExtensionHandling.java
new file mode 100644 (file)
index 0000000..9356ad2
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.extensions;
+
+import com.vaadin.server.AbstractClientConnector;
+import com.vaadin.server.AbstractExtension;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
+
+public class UnknownExtensionHandling extends AbstractTestUI {
+
+    // Extension without @Connect counterpart
+    public static class MyExtension extends AbstractExtension {
+        @Override
+        public void extend(AbstractClientConnector target) {
+            super.extend(target);
+        }
+    }
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        Label label = new Label(
+                "A label with a missing extension, should cause sensible output in the debug window / browser console");
+
+        MyExtension extension = new MyExtension();
+        extension.extend(label);
+
+        addComponent(label);
+    }
+
+}
\ No newline at end of file
index c73446318043614439a3dfa402022c31be073f4b..d9dfee506d0036f2de93c5b5294eb80b78205d93 100644 (file)
@@ -32,7 +32,7 @@ public class UnknownComponentConnectorTest extends MultiBrowserTest {
         openTestURL();
         WebElement component = vaadinElementById("no-connector-component");
         assertTrue(component.getText().startsWith(
-                "Widgetset 'com.vaadin.DefaultWidgetSet' does not contain "
+                "Widgetset 'com.vaadin.DefaultWidgetSet' does not contain an "
                         + "implementation for com.vaadin.tests.components.UnknownComponentConnector."
                         + "ComponentWithoutConnector."));
     }
diff --git a/uitest/src/test/java/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java b/uitest/src/test/java/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java
deleted file mode 100644 (file)
index 3a2600d..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2000-2014 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.vaadin.tests.components.ui;
-
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.openqa.selenium.WebElement;
-
-import com.vaadin.tests.tb3.MultiBrowserTest;
-
-/**
- * Test for testing if a component is missing from a widgetset.
- *
- * @author Vaadin Ltd
- */
-public class ComponentMissingFromDefaultWidgetsetTest extends MultiBrowserTest {
-
-    @Test
-    public void testComponentInTestingWidgetset() {
-        openTestURL();
-        WebElement component = vaadinElementById("missing-component");
-        assertTrue(component.getText().startsWith(
-                "Widgetset 'com.vaadin.DefaultWidgetSet' does not contain implementation for com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent."));
-
-    }
-}
diff --git a/uitest/src/test/java/com/vaadin/tests/extensions/UnknownExtensionHandlingTest.java b/uitest/src/test/java/com/vaadin/tests/extensions/UnknownExtensionHandlingTest.java
new file mode 100644 (file)
index 0000000..e16abf1
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.extensions;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.extensions.UnknownExtensionHandling.MyExtension;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class UnknownExtensionHandlingTest extends SingleBrowserTest {
+
+    @Test
+    public void testUnknownExtensionHandling() {
+        setDebug(true);
+        openTestURL();
+
+        openDebugLogTab();
+
+        Assert.assertTrue(
+                hasMessageContaining(MyExtension.class.getCanonicalName()));
+
+        Assert.assertFalse(hasMessageContaining("Hierachy claims"));
+    }
+
+    private boolean hasMessageContaining(String needle) {
+        List<WebElement> elements = findElements(
+                By.className("v-debugwindow-message"));
+        for (WebElement messageElement : elements) {
+            // Can't use getText() since element isn't scrolled into view
+            String text = (String) executeScript(
+                    "return arguments[0].textContent", messageElement);
+            if (text.contains(needle)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+}