You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2019/07/09 06:00:47 UTC

[wicket] branch master updated: [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)

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 <re...@gmail.com>
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 reiern70@gamil.com
+ */
+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>");
+	}
+
+}