Skip to content

Commit

Permalink
Support Element.setProperty for lists and maps
Browse files Browse the repository at this point in the history
Fixes #7308
  • Loading branch information
Artur- committed Jun 22, 2020
1 parent 33c2f65 commit cf5b648
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 0 deletions.
53 changes: 53 additions & 0 deletions flow-server/src/main/java/com/vaadin/flow/dom/Element.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -690,6 +691,58 @@ public Element setPropertyBean(String name, Object value) {
return setPropertyJson(name, JsonUtils.beanToJson(value));
}

/**
* Sets the given property to the given list of beans or primitive values,
* converted to a JSON array.
* <p>
* Note that properties changed on the server are updated on the client but
* changes made on the client side are not reflected back to the server
* unless configured using
* {@link #addPropertyChangeListener(String, String, PropertyChangeListener)}
* or {@link DomListenerRegistration#synchronizeProperty(String)}.
*
* @param <T>
* the type of items in the list
* @param name
* the property name, not <code>null</code>
* @param value
* the property value, not <code>null</code>
* @return this element
*/
public <T> Element setPropertyList(String name, List<T> value) {
if (value == null) {
throw new IllegalArgumentException(
"setProperty(name, Json.createNull()) must be used to set a property to null");
}

return setPropertyJson(name, JsonUtils.listToJson(value));
}

/**
* Sets the given property to the given map of beans or primitive values,
* converted to a JSON object.
* <p>
* Note that properties changed on the server are updated on the client but
* changes made on the client side are not reflected back to the server
* unless configured using
* {@link #addPropertyChangeListener(String, String, PropertyChangeListener)}
* or {@link DomListenerRegistration#synchronizeProperty(String)}.
*
* @param name
* the property name, not <code>null</code>
* @param value
* the property value, not <code>null</code>
* @return this element
*/
public Element setPropertyMap(String name, Map<String, ?> value) {
if (value == null) {
throw new IllegalArgumentException(
"setProperty(name, Json.createNull()) must be used to set a property to null");
}

return setPropertyJson(name, JsonUtils.mapToJson(value));
}

/**
* Adds a property change listener which is triggered when the property's
* value is updated on the server side.
Expand Down
39 changes: 39 additions & 0 deletions flow-server/src/main/java/com/vaadin/flow/internal/JsonUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.AbstractList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -298,4 +299,42 @@ public static JsonObject beanToJson(Object bean) {
throw new RuntimeException("Error converting bean to JSON", e);
}
}

/**
* Converts the given list to JSON.
*
* @param list
* the list to convert, not {@code null}
* @return a JSON representation of the bean
*/
public static JsonArray listToJson(List<?> list) {
if (list == null) {
throw new RuntimeException("Cannot convert null to a JSON object");
}
try {
return Json.instance().parse(objectMapper.writeValueAsString(list));
} catch (JsonProcessingException e) {
throw new RuntimeException(
"Error converting list to JSON: " + e.getMessage());
}
}

/**
* Converts the given map to JSON.
*
* @param map
* the map to convert, not {@code null}
* @return a JSON representation of the bean
*/
public static JsonObject mapToJson(Map<String, ?> map) {
if (map == null) {
throw new RuntimeException("Cannot convert null to a JSON object");
}
try {
return Json.instance().parse(objectMapper.writeValueAsString(map));
} catch (JsonProcessingException e) {
throw new RuntimeException(
"Error converting map to JSON: " + e.getMessage());
}
}
}
27 changes: 27 additions & 0 deletions flow-server/src/test/java/com/vaadin/flow/dom/ElementTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
Expand Down Expand Up @@ -50,6 +52,7 @@
import com.vaadin.tests.util.TestUtil;

import elemental.json.Json;
import elemental.json.JsonArray;
import elemental.json.JsonObject;
import elemental.json.JsonValue;
import elemental.json.impl.JreJsonObject;
Expand Down Expand Up @@ -573,6 +576,30 @@ public void propertyRawValues() {
Assert.assertEquals(1.0, json.getNumber("number"), 0.0);
Assert.assertEquals(2.3, json.getNumber("flt"), 0.0);
Assert.assertEquals(4.56, json.getNumber("dbl"), 0.0);

List<SimpleBean> list = new ArrayList<>();
SimpleBean bean1 = new SimpleBean();
bean1.string = "bean1";
SimpleBean bean2 = new SimpleBean();
bean2.string = "bean2";
list.add(bean1);
list.add(bean2);
element.setPropertyList("p", list);
JsonArray jsonArray = (JsonArray) element.getPropertyRaw("p");
Assert.assertEquals("bean1",
jsonArray.getObject(0).getString("string"));
Assert.assertEquals("bean2",
jsonArray.getObject(1).getString("string"));

Map<String, SimpleBean> map = new HashMap<>();
map.put("one", bean1);
map.put("two", bean2);
element.setPropertyMap("p", map);
JsonObject jsonObject = (JsonObject) element.getPropertyRaw("p");
Assert.assertEquals("bean1",
jsonObject.getObject("one").getString("string"));
Assert.assertEquals("bean2",
jsonObject.getObject("two").getString("string"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,35 @@ public void beanWithListAndMap() {
((JsonObject) childBeanList.get(1)).getString("childValue"));
}

@Test
public void simpleBeanListToJson() {
ArrayList<SimpleBean> list = new ArrayList<>();
SimpleBean bean1 = new SimpleBean();
bean1.string = "bean1";
SimpleBean bean2 = new SimpleBean();
bean2.string = "bean2";
list.add(bean1);
list.add(bean2);
JsonArray json = JsonUtils.listToJson(list);

Assert.assertEquals("bean1", json.getObject(0).getString("string"));
Assert.assertEquals("bean2", json.getObject(1).getString("string"));
}

@Test
public void simpleMapToJson() {
Map<Object, Object> map = new HashMap<>();
SimpleBean bean1 = new SimpleBean();
bean1.string = "bean1";
SimpleBean bean2 = new SimpleBean();
bean2.string = "bean2";

map.put("one", bean1);
map.put("two", bean2);
JsonObject json = JsonUtils.mapToJson(map);

Assert.assertEquals("bean1", json.getObject("one").getString("string"));
Assert.assertEquals("bean2", json.getObject("two").getString("string"));
}

}

0 comments on commit cf5b648

Please sign in to comment.