diff options
author | John Ahlroos <john@vaadin.com> | 2016-04-21 08:46:47 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2016-04-28 12:56:26 +0000 |
commit | 46556f9dbbdff6cfbf2b3e689c566e041c741cdf (patch) | |
tree | a7ad5e9c9b6650b12ef85e1c05fc8a8c27143584 /server | |
parent | 635ff2c16ff4b3914ba9cab2e3a4183ee061088a (diff) | |
download | vaadin-framework-46556f9dbbdff6cfbf2b3e689c566e041c741cdf.tar.gz vaadin-framework-46556f9dbbdff6cfbf2b3e689c566e041c741cdf.zip |
Store unknown attributes in DesignContext #19749
Change-Id: I1e90d422ec716092e6d407b6965902f48eac1646
Diffstat (limited to 'server')
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); |