From afdc4a47a79d6fd495d79badedf24865a115f67b Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 8 Jun 2016 10:22:30 +0300 Subject: [PATCH] Resolve sub properties in a template model (#932) --- .../template/AbstractTemplateStrategy.java | 10 ++++ .../template/ModelValueBindingProvider.java | 6 ++- .../dom/TemplateElementStateProviderTest.java | 15 ++++++ .../uitest/ui/template/FormView.java | 52 +++++++++++++++++++ .../uitest/ui/template/Person.java | 41 +++++++++++++++ .../uitest/ui/template/FormView.html | 16 ++++++ .../uitest/ui/template/FormIT.java | 43 +++++++++++++++ 7 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 hummingbird-tests/test-root-context/src/main/java/com/vaadin/hummingbird/uitest/ui/template/FormView.java create mode 100644 hummingbird-tests/test-root-context/src/main/java/com/vaadin/hummingbird/uitest/ui/template/Person.java create mode 100644 hummingbird-tests/test-root-context/src/main/resources/com/vaadin/hummingbird/uitest/ui/template/FormView.html create mode 100644 hummingbird-tests/test-root-context/src/test/java/com/vaadin/hummingbird/uitest/ui/template/FormIT.java diff --git a/hummingbird-client/src/main/java/com/vaadin/client/hummingbird/template/AbstractTemplateStrategy.java b/hummingbird-client/src/main/java/com/vaadin/client/hummingbird/template/AbstractTemplateStrategy.java index da8a88879b6..227d6233efe 100644 --- a/hummingbird-client/src/main/java/com/vaadin/client/hummingbird/template/AbstractTemplateStrategy.java +++ b/hummingbird-client/src/main/java/com/vaadin/client/hummingbird/template/AbstractTemplateStrategy.java @@ -184,6 +184,16 @@ protected MapProperty getModelProperty(StateNode node, Binding binding) { NodeMap model = node.getMap(NodeFeatures.TEMPLATE_MODELMAP); String key = binding.getValue(); assert key != null; + if (key.contains(".")) { + String[] modelPathParts = key.split("\\."); + // The last part is the propertyName + for (int i = 0; i < modelPathParts.length - 1; i++) { + StateNode n = (StateNode) model.getProperty(modelPathParts[i]) + .getValue(); + model = n.getMap(NodeFeatures.TEMPLATE_MODELMAP); + } + key = modelPathParts[modelPathParts.length - 1]; + } return model.getProperty(key); } diff --git a/hummingbird-server/src/main/java/com/vaadin/hummingbird/template/ModelValueBindingProvider.java b/hummingbird-server/src/main/java/com/vaadin/hummingbird/template/ModelValueBindingProvider.java index ac50be38bfd..61edb7a7eef 100644 --- a/hummingbird-server/src/main/java/com/vaadin/hummingbird/template/ModelValueBindingProvider.java +++ b/hummingbird-server/src/main/java/com/vaadin/hummingbird/template/ModelValueBindingProvider.java @@ -16,7 +16,7 @@ package com.vaadin.hummingbird.template; import com.vaadin.hummingbird.StateNode; -import com.vaadin.hummingbird.nodefeature.ModelMap; +import com.vaadin.hummingbird.template.model.ModelPathResolver; import elemental.json.JsonValue; @@ -52,7 +52,9 @@ public ModelValueBindingProvider(String key) { @Override public Object getValue(StateNode node) { - return node.getFeature(ModelMap.class).getValue(key); + ModelPathResolver resolver = new ModelPathResolver(key); + return resolver.resolveModelMap(node) + .getValue(resolver.getPropertyName()); } @Override diff --git a/hummingbird-server/src/test/java/com/vaadin/hummingbird/dom/TemplateElementStateProviderTest.java b/hummingbird-server/src/test/java/com/vaadin/hummingbird/dom/TemplateElementStateProviderTest.java index 976793378b6..ca1c8ee01cd 100644 --- a/hummingbird-server/src/test/java/com/vaadin/hummingbird/dom/TemplateElementStateProviderTest.java +++ b/hummingbird-server/src/test/java/com/vaadin/hummingbird/dom/TemplateElementStateProviderTest.java @@ -50,6 +50,7 @@ import com.vaadin.hummingbird.template.TemplateNode; import com.vaadin.hummingbird.template.TemplateNodeBuilder; import com.vaadin.hummingbird.template.TextTemplateBuilder; +import com.vaadin.hummingbird.template.model.ModelPathResolver; import com.vaadin.hummingbird.template.parser.TemplateParser; import com.vaadin.hummingbird.template.parser.TemplateResolver; @@ -962,4 +963,18 @@ public static Optional getOverrideNode(Element element) { } } + @Test + public void testElementSubProperty() { + String modelPath = "bean.name"; + ElementTemplateBuilder builder = new ElementTemplateBuilder("div") + .setProperty("prop", new ModelValueBindingProvider(modelPath)); + + Element element = createElement(builder); + StateNode stateNode = element.getNode(); + ModelPathResolver r = new ModelPathResolver(modelPath); + r.resolveModelMap(stateNode).setValue(r.getPropertyName(), "John"); + + Assert.assertEquals("John", element.getProperty("prop")); + } + } diff --git a/hummingbird-tests/test-root-context/src/main/java/com/vaadin/hummingbird/uitest/ui/template/FormView.java b/hummingbird-tests/test-root-context/src/main/java/com/vaadin/hummingbird/uitest/ui/template/FormView.java new file mode 100644 index 00000000000..6225feb9e30 --- /dev/null +++ b/hummingbird-tests/test-root-context/src/main/java/com/vaadin/hummingbird/uitest/ui/template/FormView.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.hummingbird.uitest.ui.template; + +import com.vaadin.annotations.EventHandler; +import com.vaadin.hummingbird.template.model.TemplateModel; +import com.vaadin.ui.Template; + +public class FormView extends Template { + + static final String ID_FIRST_NAME = "firstName"; + static final String ID_LAST_NAME = "lastName"; + static final String ID_AGE = "age"; + + public interface ReadonlyFormModel extends TemplateModel { + public void setPerson(Person person); + + public Person getPerson(); + } + + @Override + protected ReadonlyFormModel getModel() { + return (ReadonlyFormModel) super.getModel(); + } + + public FormView() { + Person person = new Person("Hello", "World", 32); + + getModel().setPerson(person); + } + + @EventHandler + public void updateModel() { + Person p = getModel().getPerson(); + p.setFirstName(p.getFirstName() + "!"); + p.setLastName(p.getLastName() + "?"); + p.setAge(p.getAge() + 1); + } +} diff --git a/hummingbird-tests/test-root-context/src/main/java/com/vaadin/hummingbird/uitest/ui/template/Person.java b/hummingbird-tests/test-root-context/src/main/java/com/vaadin/hummingbird/uitest/ui/template/Person.java new file mode 100644 index 00000000000..ebd9d6f6952 --- /dev/null +++ b/hummingbird-tests/test-root-context/src/main/java/com/vaadin/hummingbird/uitest/ui/template/Person.java @@ -0,0 +1,41 @@ +package com.vaadin.hummingbird.uitest.ui.template; + +public class Person { + private String firstName, lastName; + private int age; + + public Person() { + // Needed only for TemplateModel but can't be hidden + } + + public Person(String firstName, String lastName, int age) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/hummingbird-tests/test-root-context/src/main/resources/com/vaadin/hummingbird/uitest/ui/template/FormView.html b/hummingbird-tests/test-root-context/src/main/resources/com/vaadin/hummingbird/uitest/ui/template/FormView.html new file mode 100644 index 00000000000..b3ed1473c0d --- /dev/null +++ b/hummingbird-tests/test-root-context/src/main/resources/com/vaadin/hummingbird/uitest/ui/template/FormView.html @@ -0,0 +1,16 @@ +
+ +
+
First name
+ +
+
+
Last name
+ +
+
+
Age
+ +
+ +
diff --git a/hummingbird-tests/test-root-context/src/test/java/com/vaadin/hummingbird/uitest/ui/template/FormIT.java b/hummingbird-tests/test-root-context/src/test/java/com/vaadin/hummingbird/uitest/ui/template/FormIT.java new file mode 100644 index 00000000000..b3cce60a10e --- /dev/null +++ b/hummingbird-tests/test-root-context/src/test/java/com/vaadin/hummingbird/uitest/ui/template/FormIT.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.hummingbird.uitest.ui.template; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.hummingbird.testutil.PhantomJSTest; +import com.vaadin.testbench.By; + +public class FormIT extends PhantomJSTest { + + @Test + public void updateServerSide() { + open(); + Assert.assertEquals("Hello", getValue(FormView.ID_FIRST_NAME)); + Assert.assertEquals("World", getValue(FormView.ID_LAST_NAME)); + Assert.assertEquals("32", getValue(FormView.ID_AGE)); + + findElement(By.tagName("button")).click(); + + Assert.assertEquals("Hello!", getValue(FormView.ID_FIRST_NAME)); + Assert.assertEquals("World?", getValue(FormView.ID_LAST_NAME)); + Assert.assertEquals("33", getValue(FormView.ID_AGE)); + } + + private String getValue(String inputId) { + return findElement(By.id(inputId)).getAttribute("value"); + } +}