|
| 1 | +package org.vaadin.addons.velocitycomponent; |
| 2 | + |
| 3 | +import com.fasterxml.jackson.core.JsonProcessingException; |
| 4 | +import com.fasterxml.jackson.databind.ObjectMapper; |
| 5 | +import com.vaadin.flow.dom.Element; |
| 6 | +import com.vaadin.flow.function.SerializableConsumer; |
| 7 | +import com.vaadin.flow.shared.Registration; |
| 8 | +import elemental.json.JsonType; |
| 9 | +import elemental.json.JsonValue; |
| 10 | +import org.apache.commons.lang3.StringUtils; |
| 11 | + |
| 12 | +import static java.util.Arrays.stream; |
| 13 | + |
| 14 | +public class VElement { |
| 15 | + |
| 16 | + private static ObjectMapper objectMapper = new ObjectMapper(); |
| 17 | + |
| 18 | + private final Element element; |
| 19 | + |
| 20 | + private VElement(Element element) { |
| 21 | + this.element = element; |
| 22 | + } |
| 23 | + |
| 24 | + public static VElement of(Element element) { |
| 25 | + return new VElement(element); |
| 26 | + } |
| 27 | + |
| 28 | + /** |
| 29 | + * Listen to an event of a specific type. The event type is determined by the class of the event, |
| 30 | + * the name can contain optional "Event" postfix which is ignored in DOM event name. |
| 31 | + * The event payload is expected to be a JSON object or a string and serialized to the event type |
| 32 | + * using Jackson ObjectMapper. |
| 33 | + * |
| 34 | + * On the client side, the event should be dispatched with a CustomEvent with the detail property. |
| 35 | + * |
| 36 | + * @param eventType the class of the event |
| 37 | + * @param listener the listener to be called when the event is fired |
| 38 | + * @return a registration that can be used to remove the listener |
| 39 | + * @param <T> the type of the event |
| 40 | + */ |
| 41 | + public <T> Registration on(Class<T> eventType, SerializableConsumer<T> listener) { |
| 42 | + String simpleName = eventType.getSimpleName(); |
| 43 | + if(simpleName.endsWith("Event")) { |
| 44 | + simpleName = simpleName.substring(0, simpleName.length() - 5); |
| 45 | + } |
| 46 | + String kebabCased = stream(StringUtils.splitByCharacterTypeCamelCase(simpleName)) |
| 47 | + .map(s -> s.toLowerCase()) |
| 48 | + .reduce((a, b) -> a + "-" + b).get(); |
| 49 | + |
| 50 | + return element.addEventListener(kebabCased, event -> { |
| 51 | + JsonValue jsonValue = event.getEventData().get("event.detail"); |
| 52 | + T value; |
| 53 | + if(jsonValue.getType() == JsonType.OBJECT) { |
| 54 | + try { |
| 55 | + value = objectMapper.readValue(jsonValue.toJson(), eventType); |
| 56 | + } catch (Exception e) { |
| 57 | + throw new RuntimeException(e); |
| 58 | + } |
| 59 | + } else { |
| 60 | + try { |
| 61 | + value = objectMapper.readValue(jsonValue.asString().toString(), eventType); |
| 62 | + } catch (JsonProcessingException e) { |
| 63 | + throw new RuntimeException(e); |
| 64 | + } |
| 65 | + } |
| 66 | + listener.accept(value); |
| 67 | + }).addEventData("event.detail"); |
| 68 | + } |
| 69 | +} |
0 commit comments