This is an automated email from the ASF dual-hosted git repository.
ivaynberg pushed a commit to branch wicket-8.x
in repository https://gitbox.apache.org/repos/asf/wicket.git
The following commit(s) were added to refs/heads/wicket-8.x by this push:
new a3aa2a6 WICKET-6626 - application wide Component#onComponentTag
listeners
a3aa2a6 is described below
commit a3aa2a6b5a0232757a79d9802f0bf431ec4cee67
Author: Igor Vaynberg <[email protected]>
AuthorDate: Thu Jan 3 16:27:39 2019 -0800
WICKET-6626 - application wide Component#onComponentTag listeners
---
.../main/java/org/apache/wicket/Application.java | 9 ++
.../src/main/java/org/apache/wicket/Component.java | 3 +
.../application/IOnComponentTagListener.java | 38 ++++++
.../OnComponentTagListenerCollection.java | 37 ++++++
.../apache/wicket/OnComponentTagListenerTest.java | 128 +++++++++++++++++++++
5 files changed, 215 insertions(+)
diff --git a/wicket-core/src/main/java/org/apache/wicket/Application.java
b/wicket-core/src/main/java/org/apache/wicket/Application.java
index 9415afa..5178f3b 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Application.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Application.java
@@ -33,6 +33,7 @@ import
org.apache.wicket.application.ComponentOnConfigureListenerCollection;
import org.apache.wicket.application.HeaderContributorListenerCollection;
import org.apache.wicket.application.IComponentInitializationListener;
import org.apache.wicket.application.IComponentInstantiationListener;
+import org.apache.wicket.application.OnComponentTagListenerCollection;
import org.apache.wicket.core.request.mapper.IMapperContext;
import org.apache.wicket.core.util.lang.PropertyResolver;
import org.apache.wicket.core.util.lang.WicketObjects;
@@ -887,6 +888,8 @@ public abstract class Application implements
UnboundListener, IEventSink
private final BehaviorInstantiationListenerCollection
behaviorInstantiationListeners = new BehaviorInstantiationListenerCollection();
+ private final OnComponentTagListenerCollection onComponentTagListeners
= new OnComponentTagListenerCollection();
+
/**
* @return Gets the application's {@link
HeaderContributorListenerCollection}
*/
@@ -927,6 +930,12 @@ public abstract class Application implements
UnboundListener, IEventSink
return behaviorInstantiationListeners;
}
+ /**
+ * @return collection of application's on-component-tag listeners
+ */
+ public final OnComponentTagListenerCollection
getOnComponentTagListeners() {
+ return onComponentTagListeners;
+ }
/**
* @return Gets the application's
ComponentInstantiationListenerCollection
diff --git a/wicket-core/src/main/java/org/apache/wicket/Component.java
b/wicket-core/src/main/java/org/apache/wicket/Component.java
index 4968843..2e1b935 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -2418,6 +2418,9 @@ public abstract class Component
final ComponentTag openTag = markupStream.getTag();
final ComponentTag tag = openTag.mutable();
+ // call application-wide tag listeners
+
getApplication().getOnComponentTagListeners().onComponentTag(this, tag);
+
// Call any tag handler
onComponentTag(tag);
diff --git
a/wicket-core/src/main/java/org/apache/wicket/application/IOnComponentTagListener.java
b/wicket-core/src/main/java/org/apache/wicket/application/IOnComponentTagListener.java
new file mode 100644
index 0000000..21be8f7
--- /dev/null
+++
b/wicket-core/src/main/java/org/apache/wicket/application/IOnComponentTagListener.java
@@ -0,0 +1,38 @@
+/*
+ * 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.application;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.markup.ComponentTag;
+
+/**
+ * Listener interface that receives messages when components render their
tags. Useful for cross-cutting concerns that
+ * want to output tag attribute or otherwise modify component tags.
+ *
+ * @author Igor Vaynberg (ivaynberg)
+ */
+public interface IOnComponentTagListener {
+ /**
+ * Called before {@link Component#onComponentTag(ComponentTag)}
+ *
+ * @param component
+ * the component whose tag is being modified
+ * @param tag
+ * the component tag being modified
+ */
+ void onComponentTag(Component component, ComponentTag tag);
+}
diff --git
a/wicket-core/src/main/java/org/apache/wicket/application/OnComponentTagListenerCollection.java
b/wicket-core/src/main/java/org/apache/wicket/application/OnComponentTagListenerCollection.java
new file mode 100644
index 0000000..5da49e5
--- /dev/null
+++
b/wicket-core/src/main/java/org/apache/wicket/application/OnComponentTagListenerCollection.java
@@ -0,0 +1,37 @@
+/*
+ * 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.application;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.util.listener.ListenerCollection;
+
+/**
+ * Collection of on-component-tag listeners
+ *
+ * @author Igor Vaynberg (ivaynberg)
+ */
+public class OnComponentTagListenerCollection extends
ListenerCollection<IOnComponentTagListener>
+ implements IOnComponentTagListener {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onComponentTag(final Component component, final
ComponentTag tag) {
+ notify(listener -> listener.onComponentTag(component, tag));
+ }
+}
diff --git
a/wicket-core/src/test/java/org/apache/wicket/OnComponentTagListenerTest.java
b/wicket-core/src/test/java/org/apache/wicket/OnComponentTagListenerTest.java
new file mode 100644
index 0000000..073e143
--- /dev/null
+++
b/wicket-core/src/test/java/org/apache/wicket/OnComponentTagListenerTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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;
+
+import org.apache.commons.collections4.MultiSet;
+import org.apache.commons.collections4.multiset.HashMultiSet;
+import org.apache.wicket.application.IOnComponentTagListener;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.IMarkupResourceStreamProvider;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.StringResourceStream;
+import org.apache.wicket.util.tester.WicketTestCase;
+import org.junit.Test;
+
+/**
+ * Tests {@link IOnComponentTagListener}
+ *
+ * @author Igor Vaynberg (ivaynberg)
+ */
+public class OnComponentTagListenerTest extends WicketTestCase {
+
+
+ @Test
+ public void multipleListeners() {
+ TestListener listener1 = new TestListener();
+ TestListener listener2 = new TestListener();
+
tester.getApplication().getOnComponentTagListeners().add(listener1);
+
tester.getApplication().getOnComponentTagListeners().add(listener2);
+
+ TestPage page = new TestPage();
+ tester.startPage(page);
+
+ assertEquals(1, listener1.components.getCount("c1"));
+ assertEquals(1, listener1.components.getCount("c2"));
+ assertEquals(1, listener1.components.getCount("c3"));
+
+ assertEquals(1, listener2.components.getCount("c1"));
+ assertEquals(1, listener2.components.getCount("c2"));
+ assertEquals(1, listener2.components.getCount("c3"));
+ }
+
+ @Test
+ public void visibility() {
+ TestListener listener = new TestListener();
+
tester.getApplication().getOnComponentTagListeners().add(listener);
+
+ TestPage page = new TestPage();
+ page.c1.setVisible(false);
+ tester.startPage(page);
+
+ assertEquals(0, listener.components.getCount("c1"));
+ assertEquals(0, listener.components.getCount("c2"));
+ assertEquals(1, listener.components.getCount("c3"));
+ }
+
+ @Test
+ public void calledEvenIfNoSuper() {
+
+ class DoesntCallSuper extends WebMarkupContainer {
+ public DoesntCallSuper(String id) {
+ super(id);
+ }
+
+ @Override
+ protected void onComponentTag(ComponentTag tag) {
+ // missing call to super on purpose
+ }
+ }
+
+ TestListener listener = new TestListener();
+
tester.getApplication().getOnComponentTagListeners().add(listener);
+
+ TestPage page = new TestPage();
+ page.c3 = new DoesntCallSuper(page.c3.getId());
+ page.replace(page.c3);
+
+ tester.startPage(page);
+
+ assertEquals(1, listener.components.getCount("c1"));
+ assertEquals(1, listener.components.getCount("c2"));
+ assertEquals(1, listener.components.getCount("c3"));
+ }
+
+ static class TestPage extends WebPage implements
IMarkupResourceStreamProvider {
+ private static final long serialVersionUID = 1L;
+
+ private Component c1, c2, c3;
+
+ TestPage() {
+ c1 = new WebMarkupContainer("c1");
+ c2 = new WebMarkupContainer("c2");
+ c3 = new WebMarkupContainer("c3");
+ queue(c1, c2, c3);
+ }
+
+ @Override
+ public IResourceStream getMarkupResourceStream(MarkupContainer
container,
+ Class<?> containerClass) {
+ return new StringResourceStream("<html><body><div
wicket:id='c1'><div wicket:id='c2'></div></div><div
wicket:id='c3'></div></body></html>");
+ }
+ }
+
+ private static class TestListener implements IOnComponentTagListener {
+
+ private MultiSet<String> components = new HashMultiSet<>();
+
+ @Override
+ public void onComponentTag(Component component, ComponentTag
tag) {
+ components.add(component.getId());
+ }
+ }
+}