Skip to content

Commit

Permalink
Store unknown attributes in DesignContext #19749
Browse files Browse the repository at this point in the history
Change-Id: I1e90d422ec716092e6d407b6965902f48eac1646
  • Loading branch information
johndevs authored and Vaadin Code Review committed Apr 28, 2016
1 parent 635ff2c commit 46556f9
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 12 deletions.
20 changes: 15 additions & 5 deletions server/src/main/java/com/vaadin/ui/AbstractComponent.java
Expand Up @@ -24,6 +24,8 @@
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.logging.Logger; import java.util.logging.Logger;
Expand Down Expand Up @@ -1041,10 +1043,11 @@ public void readDesign(Element design, DesignContext designContext) {
supported.addAll(getDefaultAttributes()); supported.addAll(getDefaultAttributes());
supported.addAll(getCustomAttributes()); supported.addAll(getCustomAttributes());
for (Attribute a : attr) { for (Attribute a : attr) {
if (!a.getKey().startsWith(":") && !supported.contains(a.getKey())) { if (!a.getKey().startsWith(":")
getLogger().info( && !supported.contains(a.getKey())) {
"Unsupported attribute found when reading from design : " // Add unknown attributes as custom attributes to the context
+ a.getKey()); designContext.setCustomAttribute(this, a.getKey(),
a.getValue());
} }
} }
} }
Expand Down Expand Up @@ -1326,7 +1329,14 @@ public void writeDesign(Element design, DesignContext designContext) {
((Focusable) this).getTabIndex(), ((Focusable) this).getTabIndex(),
((Focusable) def).getTabIndex(), Integer.class); ((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());
}
}
} }


/* /*
Expand Down
34 changes: 34 additions & 0 deletions server/src/main/java/com/vaadin/ui/declarative/DesignContext.java
Expand Up @@ -82,6 +82,7 @@ public class DesignContext implements Serializable {
// namespace mappings // namespace mappings
private Map<String, String> packageToPrefix = new HashMap<String, String>(); private Map<String, String> packageToPrefix = new HashMap<String, String>();
private Map<String, String> prefixToPackage = 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 // component creation listeners
private List<ComponentCreationListener> listeners = new ArrayList<ComponentCreationListener>(); private List<ComponentCreationListener> listeners = new ArrayList<ComponentCreationListener>();
Expand Down Expand Up @@ -792,4 +793,37 @@ public ShouldWriteDataDelegate getShouldWriteDataDelegate() {
return shouldWriteDataDelegate; 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);
}
} }
Expand Up @@ -67,16 +67,29 @@ protected T read(String design) {
} }
} }


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) { 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 { try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

context.setRootComponent(object);
DesignContext dc = new DesignContext(); Design.write(context, outputStream);
if (writeData) {
dc.setShouldWriteDataDelegate(DeclarativeTestBaseBase.ALWAYS_WRITE_DATA);
}
dc.setRootComponent(object);
Design.write(dc, outputStream);
return outputStream.toString("UTF-8"); return outputStream.toString("UTF-8");
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
Expand Down Expand Up @@ -216,6 +229,18 @@ public void testWrite(String design, T expected, boolean writeData) {
Assert.assertEquals(comparable, produced); 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) { protected Element createElement(Component c) {
return new DesignContext().createElement(c); return new DesignContext().createElement(c);
} }
Expand Down
Expand Up @@ -15,6 +15,8 @@
*/ */
package com.vaadin.tests.server.component.abstractcomponent; package com.vaadin.tests.server.component.abstractcomponent;


import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
Expand Down Expand Up @@ -222,6 +224,18 @@ public void testReadAlreadyResponsive() {
.getExtensions().size()); .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) { private Element createDesign(boolean responsive) {
Attributes attributes = new Attributes(); Attributes attributes = new Attributes();
attributes.put("responsive", responsive); attributes.put("responsive", responsive);
Expand Down

0 comments on commit 46556f9

Please sign in to comment.