You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by cm...@apache.org on 2014/08/18 11:14:04 UTC
git commit: WICKET-5677: add onAddToPage lifecycle event
Repository: wicket
Updated Branches:
refs/heads/WICKET-5677 [created] 9a6ba692a
WICKET-5677: add onAddToPage lifecycle event
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/9a6ba692
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/9a6ba692
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/9a6ba692
Branch: refs/heads/WICKET-5677
Commit: 9a6ba692a48b76c30ead6915d4bc43275a255b3c
Parents: 64c8567
Author: Carl-Eric Menzel <cm...@wicketbuch.de>
Authored: Mon Aug 18 10:42:33 2014 +0200
Committer: Carl-Eric Menzel <cm...@apache.org>
Committed: Mon Aug 18 11:07:45 2014 +0200
----------------------------------------------------------------------
.../main/java/org/apache/wicket/Component.java | 18 +++
.../java/org/apache/wicket/MarkupContainer.java | 47 ++++++
.../test/java/org/apache/wicket/OnAddTest.java | 160 +++++++++++++++++++
3 files changed, 225 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/9a6ba692/wicket-core/src/main/java/org/apache/wicket/Component.java
----------------------------------------------------------------------
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 7f115ae..932a954 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -447,6 +447,7 @@ public abstract class Component
private static final short RFLAG_CONFIGURED = 0x10;
private static final short RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED = 0x20;
private static final short RFLAG_INITIALIZE_SUPER_CALL_VERIFIED = 0x40;
+ private static final short RFLAG_ONADD_SUPER_CALL_VERIFIED = 0x80;
/**
* Flags that only keep their value during the request. Useful for cache markers, etc. At the
@@ -4486,4 +4487,21 @@ public abstract class Component
return getBehaviors(null);
}
+ final void internalOnAdd()
+ {
+ setRequestFlag(RFLAG_ONADD_SUPER_CALL_VERIFIED, false);
+ onAddToPage();
+ if (!getRequestFlag(RFLAG_ONADD_SUPER_CALL_VERIFIED))
+ {
+ throw new IllegalStateException(Component.class.getName() +
+ " has not been properly added. Something in the hierarchy of " +
+ getClass().getName() +
+ " has not called super.onAddToPage() in the override of onAddToPage() method");
+ }
+ }
+
+ protected void onAddToPage()
+ {
+ setRequestFlag(RFLAG_ONADD_SUPER_CALL_VERIFIED, true);
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/9a6ba692/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
index ab2db9e..cbb1d05 100644
--- a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
@@ -937,6 +937,17 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
{
child.internalInitialize();
}
+
+ }
+ // onAdd should only be triggered
+ // - after onInitialize
+ // - if we are not initialized ourselves yet, then we delay calling onAdd until onInitialize
+ // - if we are initialized already, we can just call onAdd now
+ // - AND if we already have a page. See #onAdd
+ // - if we don't have a page yet, our own onAdd will be called when we get added to the page component tree.
+ if (page != null && this.isInitialized())
+ {
+ child.internalOnAdd();
}
// if the PREPARED_FOR_RENDER flag is set, we have already called
@@ -947,6 +958,37 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
}
}
+ @Override protected void onAddToPage()
+ {
+ super.onAddToPage();
+ Component[] children = copyChildren();
+ try
+ {
+ for (final Component child : children)
+ {
+ // We need to check whether the child's wasn't removed from the
+ // component in the meanwhile (e.g. from another's child
+ // onAddToPage)
+ if (child.getParent() == this)
+ {
+ child.internalOnAdd();
+ }
+ }
+ }
+ catch (RuntimeException ex)
+ {
+ if (ex instanceof WicketRuntimeException)
+ {
+ throw ex;
+ }
+ else
+ {
+ throw new WicketRuntimeException("Error adding this container: " +
+ this, ex);
+ }
+ }
+ }
+
/**
* THIS METHOD IS NOT PART OF THE PUBLIC API, DO NOT CALL IT
*
@@ -1947,4 +1989,9 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
}
}
+ @Override protected void onInitialize()
+ {
+ super.onInitialize();
+ internalOnAdd();
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/9a6ba692/wicket-core/src/test/java/org/apache/wicket/OnAddTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/OnAddTest.java b/wicket-core/src/test/java/org/apache/wicket/OnAddTest.java
new file mode 100644
index 0000000..117b22d
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/OnAddTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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 static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+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.util.tester.WicketTesterScope;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class OnAddTest
+{
+ @Rule
+ public WicketTesterScope scope = new WicketTesterScope();
+
+ private boolean onAddCalled = false;
+
+ private Component createProbe()
+ {
+ return new Label("foo")
+ {
+ @Override
+ protected void onAddToPage()
+ {
+ super.onAddToPage();
+ onAddCalled = true;
+ }
+ };
+ }
+
+ @Test
+ public void onAddIsCalledIfParentIsInitialized()
+ {
+ Page page = createPage();
+ page.internalInitialize();
+ page.add(createProbe());
+ assertTrue(onAddCalled);
+ }
+
+ private WebPage createPage()
+ {
+ return new WebPage()
+ {
+ };
+ }
+
+ @Test
+ public void onAddIsNotCalledIfParentIsNotInitialized()
+ {
+ Page page = createPage();
+ page.add(createProbe());
+ assertFalse(onAddCalled);
+ }
+
+ @Test
+ public void onAddIsCalledWhenParentIsInitialized()
+ {
+ Page page = createPage();
+ page.add(createProbe());
+ page.internalInitialize();
+ assertTrue(onAddCalled);
+ }
+
+ @Test
+ public void onAddIsNotCalledWhenParentIsNotConnectedToPage()
+ {
+ MarkupContainer container = createContainer();
+ container.internalInitialize();
+ container.add(createProbe());
+ assertFalse(onAddCalled);
+ }
+
+ @Test
+ public void onAddIsCalledWhenParentIsAddedToPage()
+ {
+ MarkupContainer container = createContainer();
+ container.internalInitialize();
+ container.add(createProbe());
+ assertFalse(onAddCalled);
+ WebPage page = createPage();
+ page.internalInitialize();
+ page.add(container);
+ assertTrue(onAddCalled);
+ }
+
+ @Test
+ public void onAddIsCalledAfterRemoveAndAdd()
+ {
+ Page page = createPage();
+ page.internalInitialize();
+ Component probe = createProbe();
+ page.add(probe);
+ assertTrue(onAddCalled);
+ onAddCalled = false;
+ page.remove(probe);
+ assertFalse(onAddCalled);
+ page.add(probe);
+ assertTrue(onAddCalled);
+ }
+
+ @Test
+ public void onAddRecursesToChildren()
+ {
+ Page page = createPage();
+ page.internalInitialize();
+ page.add(createNestedProbe());
+ assertTrue(onAddCalled);
+ }
+
+ @Test
+ public void onAddEnforcesSuperCall()
+ {
+ Page page = createPage();
+ page.internalInitialize();
+ try
+ {
+ page.add(new Label("foo")
+ {
+ @Override
+ protected void onAddToPage()
+ {
+ ; // I should call super, but since I don't, this should throw an exception
+ }
+ });
+ fail("should have thrown exception");
+ } catch (IllegalStateException e)
+ {
+ assertTrue(e.getMessage().contains("super.onAddToPage"));
+ }
+ }
+
+ private Component createNestedProbe()
+ {
+ return createContainer().add(createProbe());
+ }
+
+ private MarkupContainer createContainer()
+ {
+ return new WebMarkupContainer("bar");
+ }
+}