summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJohn Ahlroos <john@vaadin.com>2016-04-21 08:46:47 +0300
committerVaadin Code Review <review@vaadin.com>2016-04-28 12:56:26 +0000
commit46556f9dbbdff6cfbf2b3e689c566e041c741cdf (patch)
treea7ad5e9c9b6650b12ef85e1c05fc8a8c27143584 /server
parent635ff2c16ff4b3914ba9cab2e3a4183ee061088a (diff)
downloadvaadin-framework-46556f9dbbdff6cfbf2b3e689c566e041c741cdf.tar.gz
vaadin-framework-46556f9dbbdff6cfbf2b3e689c566e041c741cdf.zip
Store unknown attributes in DesignContext #19749
Change-Id: I1e90d422ec716092e6d407b6965902f48eac1646
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractComponent.java20
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/DesignContext.java34
-rw-r--r--server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java39
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java14
4 files changed, 95 insertions, 12 deletions
diff --git a/server/src/main/java/com/vaadin/ui/AbstractComponent.java b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
index d3506e9097..bf13f032d2 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
@@ -24,6 +24,8 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Logger;
@@ -1041,10 +1043,11 @@ public abstract class AbstractComponent extends AbstractClientConnector
supported.addAll(getDefaultAttributes());
supported.addAll(getCustomAttributes());
for (Attribute a : attr) {
- if (!a.getKey().startsWith(":") && !supported.contains(a.getKey())) {
- getLogger().info(
- "Unsupported attribute found when reading from design : "
- + a.getKey());
+ if (!a.getKey().startsWith(":")
+ && !supported.contains(a.getKey())) {
+ // Add unknown attributes as custom attributes to the context
+ designContext.setCustomAttribute(this, a.getKey(),
+ a.getValue());
}
}
}
@@ -1326,7 +1329,14 @@ public abstract class AbstractComponent extends AbstractClientConnector
((Focusable) this).getTabIndex(),
((Focusable) def).getTabIndex(), Integer.class);
}
-
+ // handle custom attributes
+ Map<String, String> customAttributes = designContext
+ .getCustomAttributes(this);
+ if (customAttributes != null) {
+ for (Entry<String, String> entry : customAttributes.entrySet()) {
+ attr.put(entry.getKey(), entry.getValue());
+ }
+ }
}
/*
diff --git a/server/src/main/java/com/vaadin/ui/declarative/DesignContext.java b/server/src/main/java/com/vaadin/ui/declarative/DesignContext.java
index d72ec77d4a..b50719395e 100644
--- a/server/src/main/java/com/vaadin/ui/declarative/DesignContext.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/DesignContext.java
@@ -82,6 +82,7 @@ public class DesignContext implements Serializable {
// namespace mappings
private Map<String, String> packageToPrefix = new HashMap<String, String>();
private Map<String, String> prefixToPackage = new HashMap<String, String>();
+ private final Map<Component, Map<String, String>> customAttributes = new HashMap<Component, Map<String, String>>();
// component creation listeners
private List<ComponentCreationListener> listeners = new ArrayList<ComponentCreationListener>();
@@ -792,4 +793,37 @@ public class DesignContext implements Serializable {
return shouldWriteDataDelegate;
}
+ /**
+ * Gets the attributes that the component did not handle
+ *
+ * @since
+ * @param component
+ * the component to get the attributes for
+ * @return map of the attributes which were not recognized by the component
+ */
+ public Map<String, String> getCustomAttributes(Component component) {
+ return customAttributes.get(component);
+ }
+
+ /**
+ * Sets a custom attribute not handled by the component. These attributes
+ * are directly written to the component tag.
+ *
+ * @since
+ * @param component
+ * the component to set the attribute for
+ * @param attribute
+ * the attribute to set
+ * @param value
+ * the value of the attribute
+ */
+ public void setCustomAttribute(Component component, String attribute,
+ String value) {
+ Map<String, String> map = customAttributes.get(component);
+ if (map == null) {
+ customAttributes.put(component,
+ map = new HashMap<String, String>());
+ }
+ map.put(attribute, value);
+ }
}
diff --git a/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java b/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java
index a7ff7174b2..6153c95592 100644
--- a/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java
+++ b/server/src/test/java/com/vaadin/tests/design/DeclarativeTestBaseBase.java
@@ -67,16 +67,29 @@ public abstract class DeclarativeTestBaseBase<T extends Component> {
}
}
+ protected DesignContext readAndReturnContext(String design) {
+ try {
+ return Design.read(
+ new ByteArrayInputStream(design.getBytes("UTF-8")), null);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
protected String write(T object, boolean writeData) {
+ DesignContext dc = new DesignContext();
+ if (writeData) {
+ dc.setShouldWriteDataDelegate(
+ DeclarativeTestBaseBase.ALWAYS_WRITE_DATA);
+ }
+ return write(object, dc);
+ }
+
+ protected String write(T object, DesignContext context) {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-
- DesignContext dc = new DesignContext();
- if (writeData) {
- dc.setShouldWriteDataDelegate(DeclarativeTestBaseBase.ALWAYS_WRITE_DATA);
- }
- dc.setRootComponent(object);
- Design.write(dc, outputStream);
+ context.setRootComponent(object);
+ Design.write(context, outputStream);
return outputStream.toString("UTF-8");
} catch (Exception e) {
throw new RuntimeException(e);
@@ -216,6 +229,18 @@ public abstract class DeclarativeTestBaseBase<T extends Component> {
Assert.assertEquals(comparable, produced);
}
+ public void testWrite(T component, String expected, DesignContext context) {
+ String written = write(component, context);
+
+ Element producedElem = Jsoup.parse(written).body().child(0);
+ Element comparableElem = Jsoup.parse(expected).body().child(0);
+
+ String produced = elementToHtml(producedElem);
+ String comparable = elementToHtml(comparableElem);
+
+ Assert.assertEquals(comparable, produced);
+ }
+
protected Element createElement(Component c) {
return new DesignContext().createElement(c);
}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java
index fc97c84952..1588471395 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java
@@ -15,6 +15,8 @@
*/
package com.vaadin.tests.server.component.abstractcomponent;
+import static org.junit.Assert.assertTrue;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.lang.reflect.Field;
@@ -222,6 +224,18 @@ public class AbstractComponentDeclarativeTest extends
.getExtensions().size());
}
+ @Test
+ public void testUnknownProperties() {
+ String design = "<vaadin-label foo=\"bar\"/>";
+
+ DesignContext context = readAndReturnContext(design);
+ Label label = (Label) context.getRootComponent();
+ assertTrue("Custom attribute was preserved in custom attributes",
+ context.getCustomAttributes(label).containsKey("foo"));
+
+ testWrite(label, design, context);
+ }
+
private Element createDesign(boolean responsive) {
Attributes attributes = new Attributes();
attributes.put("responsive", responsive);