This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/master by this push:
     new 0ad6bb4  [WICKET-6684] make autolabel functionality more flexible by 
introducing a locator interface that allows to specify the component the 
wicket:for attribute refers to (#373)
0ad6bb4 is described below

commit 0ad6bb437c401d18a50eb1cfe8b248736019eec9
Author: Ernesto Reinaldo Barreiro <[email protected]>
AuthorDate: Tue Jul 9 09:00:43 2019 +0300

    [WICKET-6684] make autolabel functionality more flexible by introducing a 
locator interface that allows to specify the component the wicket:for attribute 
refers to (#373)
---
 .../wicket/markup/html/form/AutoLabelResolver.java |  24 ++--
 .../markup/html/form/ILabelProviderLocator.java    |  36 +++++
 ...AutoLabelLabelProviderLocatorTest$EditPage.html |  11 ++
 ...derLocatorTest$ILabelProviderLocatorPanel1.html |  10 ++
 ...derLocatorTest$ILabelProviderLocatorPanel2.html |  12 ++
 .../form/AutoLabelLabelProviderLocatorTest.java    | 154 +++++++++++++++++++++
 6 files changed, 238 insertions(+), 9 deletions(-)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
index 221082e..96e09c6 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
@@ -93,18 +93,24 @@ public class AutoLabelResolver implements IComponentResolver
                        return null;
                }
 
-               final String id = 
tag.getAttribute(getWicketNamespace(markupStream) + WICKET_FOR).trim();
+               // retrieve the relative path to the component
+               final String path = 
tag.getAttribute(getWicketNamespace(markupStream) + WICKET_FOR).trim();
 
-               Component component = findRelatedComponent(container, id);
+               Component component = findRelatedComponent(container, path);
                if (component == null)
                {
-                       throw new ComponentNotFoundException("Could not find 
form component with id '" + id +
+                       throw new ComponentNotFoundException("Could not find 
form component with path '" + path +
                                "' while trying to resolve wicket:for 
attribute");
                }
+               // check if component implements ILabelProviderLocator
+               if (component instanceof ILabelProviderLocator)
+               {
+                       component = ((ILabelProviderLocator) 
component).getAutoLabelComponent();
+               }
 
                if (!(component instanceof ILabelProvider))
                {
-                       throw new WicketRuntimeException("Component pointed to 
by wicket:for attribute '" + id +
+                       throw new WicketRuntimeException("Component pointed to 
by wicket:for attribute '" + path +
                                "' does not implement " + 
ILabelProvider.class.getName());
                }
 
@@ -134,15 +140,15 @@ public class AutoLabelResolver implements 
IComponentResolver
 
        /**
         * 
-        * @param container
-        * @param id
+        * @param container The container
+        * @param path The relative path to the component
         * @return Component
         */
-       static Component findRelatedComponent(MarkupContainer container, final 
String id)
+       static Component findRelatedComponent(MarkupContainer container, final 
String path)
        {
                // try the quick and easy route first
 
-               Component component = container.get(id);
+               Component component = container.get(path);
                if (component != null)
                {
                        return component;
@@ -165,7 +171,7 @@ public class AutoLabelResolver implements IComponentResolver
                                                        visit.dontGoDeeper();
                                                        return;
                                                }
-                                               if (id.equals(child.getId()))
+                                               if (path.equals(child.getId()))
                                                {
                                                        visit.stop(child);
                                                        return;
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/ILabelProviderLocator.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/ILabelProviderLocator.java
new file mode 100644
index 0000000..a4f244e
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/ILabelProviderLocator.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.markup.html.form;
+
+import org.apache.wicket.Component;
+
+/**
+ * This interface can be used mark some complex component, e.g. a panel, as 
capable of providing a reference to a {@link ILabelProvider},
+ * e.g a form component. The typical use case could be a user has a components 
factory of type "label" --> "panel with some fields". Let's say the structure of
+ * this panel varies but we still would like to use wicket:for="panel". In 
this case this panel could implement ILabelProviderLocator to point
+ * to TextFiled that label should refer to.
+ *
+ * @author [email protected]
+ */
+public interface ILabelProviderLocator
+{
+
+       /**
+        * @return The component the wicket:for attribute is referring to.
+        */
+       Component getAutoLabelComponent();
+}
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$EditPage.html
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$EditPage.html
new file mode 100644
index 0000000..8a84d4d
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$EditPage.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+<body>
+    <form wicket:id="form">
+        <div wicket:id="edit-row">
+            <label wicket:for="edit-component"><span 
wicket:id="label"></span></label>
+            <div wicket:id="edit-component"></div>
+        </div>
+    </form>
+</body>
+</html>
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$ILabelProviderLocatorPanel1.html
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$ILabelProviderLocatorPanel1.html
new file mode 100644
index 0000000..ae8565e
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$ILabelProviderLocatorPanel1.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+<body>
+<wicket:panel>
+    <div wicket:id="dummy">
+        <input wicket:id="text" type="text" id="dummy_text"/>
+    </div>
+</wicket:panel>
+</body>
+</html>
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$ILabelProviderLocatorPanel2.html
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$ILabelProviderLocatorPanel2.html
new file mode 100644
index 0000000..27ebd3f
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest$ILabelProviderLocatorPanel2.html
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+<body>
+<wicket:panel>
+    <div wicket:id="dummy">
+        <div wicket:id="dummy1">
+            <input wicket:id="text" type="text" id="dummy_dummy1_text"/>
+        </div>
+    </div>
+</wicket:panel>
+</body>
+</html>
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest.java
new file mode 100644
index 0000000..10dc0f1
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelLabelProviderLocatorTest.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.markup.html.form;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.Component;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.RepeatingView;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.util.tester.WicketTestCase;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@code wicket:for} attribute functionality using {@link 
ILabelProviderLocator}
+ */
+@SuppressWarnings({ "rawtypes", "serial" })
+class AutoLabelLabelProviderLocatorTest extends WicketTestCase
+{
+       static class ILabelProviderLocatorPanel1 extends Panel implements 
ILabelProviderLocator
+       {
+
+               private TextField<String> text;
+
+               ILabelProviderLocatorPanel1(String id)
+               {
+                       super(id);
+                       WebMarkupContainer dummy = new 
WebMarkupContainer("dummy");
+                       dummy.add(AttributeModifier.replace("class", "dummy1"));
+                       add(dummy);
+                       text = new TextField<>("text", Model.of(""));
+                       dummy.add(text);
+               }
+
+               @Override
+               public Component getAutoLabelComponent()
+               {
+                       return text;
+               }
+       }
+
+       static class ILabelProviderLocatorPanel2 extends Panel implements 
ILabelProviderLocator
+       {
+
+               private TextField<String> text;
+
+               ILabelProviderLocatorPanel2(String id)
+               {
+                       super(id);
+                       WebMarkupContainer dummy = new 
WebMarkupContainer("dummy");
+                       dummy.add(AttributeModifier.replace("class", "dummy"));
+                       add(dummy);
+
+                       WebMarkupContainer dummy1 = new 
WebMarkupContainer("dummy1");
+                       dummy1.add(AttributeModifier.replace("class", 
"dummy1"));
+                       dummy.add(dummy1);
+
+                       text = new TextField<>("text", Model.of(""));
+                       dummy1.add(text);
+               }
+
+               @Override
+               public Component getAutoLabelComponent()
+               {
+                       return text;
+               }
+       }
+
+       private interface IEditPanelProvider
+       {
+               IModel<String> getLabelText();
+
+               Panel createEditPanel(String id);
+       }
+
+       static class EditPage extends WebPage
+       {
+               EditPage(List<IEditPanelProvider> editPanelProviders)
+               {
+                       Form<Void> form = new Form<>("form");
+                       add(form);
+                       RepeatingView editRow = new RepeatingView("edit-row");
+                       form.add(editRow);
+                       for (IEditPanelProvider panelProvider: 
editPanelProviders) {
+                               WebMarkupContainer mc = new 
WebMarkupContainer(editRow.newChildId());
+                               mc.add(new Label("label", 
panelProvider.getLabelText()));
+                               
mc.add(panelProvider.createEditPanel("edit-component"));
+                               editRow.add(mc);
+                       }
+               }
+       }
+
+       @Test
+       void testILabelProviderLocator()
+       {
+               List<IEditPanelProvider> providers = new ArrayList<>();
+
+               providers.add(new IEditPanelProvider()
+               {
+                       @Override
+                       public IModel<String> getLabelText()
+                       {
+                               return Model.of("Example1");
+                       }
+
+                       @Override
+                       public Panel createEditPanel(String id)
+                       {
+                               return new ILabelProviderLocatorPanel1(id);
+                       }
+               });
+
+               providers.add(new IEditPanelProvider()
+               {
+                       @Override
+                       public IModel<String> getLabelText()
+                       {
+                               return Model.of("Example2");
+                       }
+
+                       @Override
+                       public Panel createEditPanel(String id)
+                       {
+                               return new ILabelProviderLocatorPanel2(id);
+                       }
+               });
+
+               EditPage editPage = new EditPage(providers);
+               tester.startPage(editPage);
+               tester.assertRenderedPage(EditPage.class);
+               tester.assertContains("for=\"dummy_text\"><span 
wicket:id=\"label\">Example1</span>");
+               tester.assertContains("for=\"dummy_dummy1_text\"><span 
wicket:id=\"label\">Example2</span>");
+       }
+
+}

Reply via email to