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

ivaynberg pushed a commit to branch wicket-7.x
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/wicket-7.x by this push:
     new fdd8517  WICKET-6626 - application wide Component#onComponentTag 
listeners
fdd8517 is described below

commit fdd8517bacc9145e9ec7299245afc3d81794e9db
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          |  42 +++++++
 .../apache/wicket/OnComponentTagListenerTest.java  | 128 +++++++++++++++++++++
 5 files changed, 220 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 22a9971..7502679 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Application.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Application.java
@@ -43,6 +43,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;
@@ -1058,6 +1059,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}
         */
@@ -1098,6 +1101,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 368941a..3a4d0dc 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -2540,6 +2540,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..83efa72
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/application/OnComponentTagListenerCollection.java
@@ -0,0 +1,42 @@
+/*
+ * 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(new INotifier<IOnComponentTagListener>() {
+                       @Override
+                       public void notify(IOnComponentTagListener 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());
+               }
+       }
+}

Reply via email to