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;
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,
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;
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) {
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;
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>();
}
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++) {
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;
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 {
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 {
/**
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");
}
}
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.
break;
}
- if (connectorClass != UnknownComponentConnector.class) {
+ if (connectorClass != UnknownComponentConnector.class
+ && connectorClass != UnknownExtensionConnector.class) {
usedConnectors.add(connectorClass.getName());
}
tag++;
}
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>.";
}
}
--- /dev/null
+/*
+ * 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
+ }
+}
--- /dev/null
+/*
+ * 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
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."));
}
+++ /dev/null
-/*
- * 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."));
-
- }
-}
--- /dev/null
+/*
+ * 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;
+ }
+
+}