Author: jdonnerstag Date: Sun Jun 12 10:48:44 2011 New Revision: 1134907 URL: http://svn.apache.org/viewvc?rev=1134907&view=rev Log: fixed: AjaxRequestTarget#addComponent(..) should guard against improper usage Issue: WICKET-3564
Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java?rev=1134907&r1=1134906&r2=1134907&view=diff ============================================================================== --- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java (original) +++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java Sun Jun 12 10:48:44 2011 @@ -265,6 +265,11 @@ public class AjaxRequestTarget implement /** The associated Page */ private final Page page; + /** see https://issues.apache.org/jira/browse/WICKET-3564 */ + private transient boolean componentsFrozen; + private transient boolean listenersFrozen; + private transient boolean respondersFrozen; + /** * Constructor * @@ -287,6 +292,30 @@ public class AjaxRequestTarget implement return page; } + private void assertNotFrozen(boolean frozen, Class<?> clazz) + { + if (frozen) + { + throw new IllegalStateException(clazz.getSimpleName() + "s can no " + + " longer be added"); + } + } + + private void assertListenersNotFrozen() + { + assertNotFrozen(listenersFrozen, IListener.class); + } + + private void assertComponentsNotFrozen() + { + assertNotFrozen(componentsFrozen, Component.class); + } + + private void assertRespondersNotFrozen() + { + assertNotFrozen(respondersFrozen, ITargetRespondListener.class); + } + /** * Adds a listener to this target * @@ -294,16 +323,15 @@ public class AjaxRequestTarget implement */ public void addListener(IListener listener) { - if (listener == null) - { - throw new IllegalArgumentException("Argument `listener` cannot be null"); - } + Args.notNull(listener, "listener"); if (listeners == null) { listeners = new LinkedList<IListener>(); } + assertListenersNotFrozen(); + if (!listeners.contains(listener)) { listeners.add(listener); @@ -315,20 +343,15 @@ public class AjaxRequestTarget implement * of same type as <code>childCriteria</code> * * @param parent + * Must not be null. * @param childCriteria + * Must not be null. If you want to traverse all components use ` Component.class as + * the value for this argument. */ public final void addChildren(MarkupContainer parent, Class<?> childCriteria) { - if (parent == null) - { - throw new IllegalArgumentException("Argument `parent` cannot be null"); - } - if (childCriteria == null) - { - throw new IllegalArgumentException( - "Argument `childCriteria` cannot be null. If you want to traverse all components use `" + - Component.class.getName() + ".class` as the value for this argument"); - } + Args.notNull(parent, "parent"); + Args.notNull(childCriteria, "childCriteria"); parent.visitChildren(childCriteria, new IVisitor<Component, Void>() { @@ -422,6 +445,8 @@ public class AjaxRequestTarget implement "Instead add its parent or another markup container higher in the hierarchy."); } + assertComponentsNotFrozen(); + component.setMarkupId(markupId); markupIdToComponent.put(markupId, component); } @@ -551,6 +576,7 @@ public class AjaxRequestTarget implement */ public void registerRespondListener(ITargetRespondListener listener) { + assertRespondersNotFrozen(); respondListeners.add(listener); } @@ -577,6 +603,8 @@ public class AjaxRequestTarget implement return; } + listenersFrozen = true; + for (ITargetRespondListener listener : respondListeners) { listener.onTargetRespond(this); @@ -630,6 +658,8 @@ public class AjaxRequestTarget implement bodyResponse.write("\"?>"); bodyResponse.write("<ajax-response>"); + respondersFrozen = true; + // invoke onbeforerespond event on listeners fireOnBeforeRespondListeners(); @@ -641,6 +671,8 @@ public class AjaxRequestTarget implement respondInvocation(bodyResponse, js); } + componentsFrozen = true; + // process added components respondComponents(bodyResponse);