You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jc...@apache.org on 2007/05/04 13:14:20 UTC

svn commit: r535170 - in /incubator/wicket/trunk/jdk-1.4/wicket/src: main/java/org/apache/wicket/ main/java/org/apache/wicket/ajax/form/ main/java/org/apache/wicket/markup/html/ main/java/org/apache/wicket/markup/html/form/upload/ main/java/org/apache/...

Author: jcompagner
Date: Fri May  4 04:14:19 2007
New Revision: 535170

URL: http://svn.apache.org/viewvc?view=rev&rev=535170
Log:
reattach refactor and improvements in the FilePageStore

Added:
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/form/AjaxFormChoiceComponentUpdatingBehavior.java   (with props)
    incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/PageInPageVersionTest.java   (with props)
Modified:
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Component.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Page.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Session.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/WebPage.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/form/upload/MultiFileUploadField.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/Loop.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/tree/AbstractTree.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/repeater/RefreshingView.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/FilePageStore.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/SecondLevelCacheSessionStore.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/TestErrorPage.java

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Component.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Component.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Component.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Component.java Fri May  4 04:14:19 2007
@@ -222,7 +222,7 @@
  * @author Juergen Donnerstag
  * @author Igor Vaynberg (ivaynberg)
  */
-public abstract class Component implements IClusterable
+public abstract class Component implements IClusterable, IConverterLocator
 {
 	/**
 	 * Change record of a model.
@@ -599,9 +599,13 @@
 	protected static final int FLAG_RESERVED8 = 0x80000;
 
 	private static final int FLAG_ATTACHED = 0x20000000;
-	private static final int FLAG_ATTACHING = 0x40000000;
+	protected static final int FLAG_ATTACHING = 0x40000000;
 	private static final int FLAG_DETACHING = 0x80000000;
 
+	private static final int FLAG_RENDERING = 0x2000000;
+	private static final int FLAG_BEFORE_RENDERING = 0x4000000;
+	private static final int FLAG_AFTER_RENDERING = 0x8000000;
+
 
 	/** meta data key for missing body tags logging. */
 	private static final MetaDataKey BORDER_KEY = new MetaDataKey(IComponentBorder.class)
@@ -1640,26 +1644,17 @@
 			try
 			{
 				// Call implementation to render component
-				onBeforeRender();
 				notifyBehaviorsComponentBeforeRender();
-				try
+				final IComponentBorder border = getComponentBorder();
+				if (border != null)
 				{
-					final IComponentBorder border = getComponentBorder();
-					if (border != null)
-					{
-						border.renderBefore(this);
-					}
-					onRender(markupStream);
-					if (border != null)
-					{
-						border.renderAfter(this);
-					}
+					border.renderBefore(this);
 				}
-				finally
+				onRender(markupStream);
+				if (border != null)
 				{
-					onAfterRender();
+					border.renderAfter(this);
 				}
-
 				// Component has been rendered
 				rendered();
 			}
@@ -2799,7 +2794,7 @@
 	 * 
 	 * Called when a request begins.
 	 * 
-	 * @Deprecated use {@link #onAttach()} instead
+	 * @Deprecated use {@link #onBeforeRender()} instead
 	 */
 	protected final void internalOnAttach()
 	{
@@ -2811,7 +2806,7 @@
 	 * 
 	 * Called when a request ends.
 	 * 
-	 * @Deprecated use {@link #onAttach()} instead
+	 * @Deprecated use {@link #onBeforeRender()} instead
 	 * 
 	 */
 	protected final void internalOnDetach()
@@ -2896,18 +2891,10 @@
 	}
 
 	/**
-	 * Called just after a component is rendered.
-	 */
-	protected void onAfterRender()
-	{
-	}
-
-
-	/**
 	 * Attaches any child components
 	 * 
 	 * This method is here only for {@link MarkupContainer}. It is broken out
-	 * of {@link #onAttach()} so we can guarantee that it executes as the last
+	 * of {@link #onBeforeRender()} so we can guarantee that it executes as the last
 	 * in onAttach() chain no matter where user places the
 	 * <code>super.onAttach()</code> call
 	 */
@@ -2918,6 +2905,8 @@
 
 	/**
 	 * Attaches the component.
+	 * This is called when the page is starting to be used for rendering or when
+	 * a component listener call is executed on it. 
 	 */
 	public final void attach()
 	{
@@ -2937,6 +2926,14 @@
 
 		attachChildren();
 	}
+	
+	/**
+	 * @return true if this component is attached
+	 */
+	protected final boolean isAttached()
+	{
+		return getFlag(FLAG_ATTACHED);
+	}
 
 	/**
 	 * Detaches any child components
@@ -2950,6 +2947,8 @@
 
 	/**
 	 * Detaches the component.
+	 * This is called at the end of the request for all the pages that are touched
+	 * in that request.
 	 */
 	public final void detach()
 	{
@@ -2996,16 +2995,86 @@
 	protected void onAttach()
 	{
 		setFlag(FLAG_ATTACHING, false);
-
 	}
+	
+	/**
+	 * Called for every component when the page is getting to be rendered.
+	 * it will call onBeforeRender for this component and all the child components
+	 */
+	public final void beforeRender()
+	{
+		if (!getFlag(FLAG_RENDERING))
+		{
+			setFlag(FLAG_BEFORE_RENDERING, true);
+			setFlag(FLAG_RENDERING, true);
+			onBeforeRender();
+			if (getFlag(FLAG_BEFORE_RENDERING))
+			{
+				throw new IllegalStateException(Component.class.getName()
+						+ " has not been properly rendered. Something in the hierarchy of "
+						+ getClass().getName()
+						+ " has not called super.onBeforeRender() in the override of onBeforeRender() method");
+			}
+		}
 
+		onBeforeRenderChildren();
+	}
 	/**
 	 * Called just before a component is rendered.
 	 */
 	protected void onBeforeRender()
 	{
+		setFlag(FLAG_BEFORE_RENDERING, false);
+	}
+	
+	/**
+	 * This method is here only for {@link MarkupContainer}. It is broken out
+	 * of {@link #onBeforeRender()} so we can guarantee that it executes as the last
+	 * in onAttach() chain no matter where user places the
+	 * <code>super.onAttach()</code> call
+	 */
+	void onBeforeRenderChildren()
+	{
+		// noop
 	}
 
+	/**
+	 * Called on very component after the page is renderd
+	 * It will call onAfterRender for it self and its childeren.
+	 */
+	public final void afterRender()
+	{
+		// if the component has been previously attached via attach()
+		// detach it now
+		setFlag(FLAG_AFTER_RENDERING, true);
+		onAfterRender();
+		if (getFlag(FLAG_AFTER_RENDERING))
+		{
+			throw new IllegalStateException(Component.class.getName()
+					+ " has not been properly detached. Something in the hierarchy of "
+					+ getClass().getName()
+					+ " has not called super.onAfterRender() in the override of onAfterRender() method");
+		}
+		setFlag(FLAG_RENDERING, false);
+
+		// always detach children because components can be attached
+		// independently of their parents
+		onAfterRenderChildren();
+	}
+
+	/**
+	 * Called just after a component is rendered.
+	 */
+	protected void onAfterRender()
+	{
+		setFlag(FLAG_AFTER_RENDERING, false);
+	}
+	
+	void onAfterRenderChildren()
+	{
+		// noop
+	}
+	
 	/**
 	 * Processes the component tag.
 	 * 

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java Fri May  4 04:14:19 2007
@@ -215,7 +215,7 @@
 		}
 		component.setAuto(true);
 		add(component);
-		component.attach();
+		component.onBeforeRender();
 		component.render();
 		return true;
 	}
@@ -1359,11 +1359,52 @@
 				// Get next child
 				final Component child = children_get(i);
 
+				// Call begin request on the child
+				child.attach();
+			}
+		}
+		catch (RuntimeException ex)
+		{
+			if (ex instanceof WicketRuntimeException)
+				throw ex;
+			else
+				throw new WicketRuntimeException("Error attaching this container for rendering: "
+						+ this, ex);
+		}
+	}
+
+	void detachChildren()
+	{
+		// Loop through child components
+		final Iterator iter = iterator();
+		while (iter.hasNext())
+		{
+			// Get next child
+			final Component child = (Component)iter.next();
+
+			// Call end request on the child
+			child.detach();
+		}
+		super.detachChildren();
+	}
+
+	void onBeforeRenderChildren()
+	{
+		super.onBeforeRenderChildren();
+		try
+		{
+			// Loop through child components
+			final int size = children_size();
+			for (int i = 0; i < size; i++)
+			{
+				// Get next child
+				final Component child = children_get(i);
+
 				// Ignore feedback as that was done in Page
 				if (!(child instanceof IFeedback))
 				{
 					// Call begin request on the child
-					child.attach();
+					child.beforeRender();
 				}
 			}
 		}
@@ -1377,7 +1418,7 @@
 		}
 	}
 
-	void detachChildren()
+	void onAfterRenderChildren()
 	{
 		// Loop through child components
 		final Iterator iter = iterator();
@@ -1387,11 +1428,10 @@
 			final Component child = (Component)iter.next();
 
 			// Call end request on the child
-			child.detach();
+			child.afterRender();
 		}
-		super.detachChildren();
+		super.onAfterRenderChildren();
 	}
-
 	/**
 	 * @return True if this markup container has associated markup
 	 */

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Page.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Page.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Page.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Page.java Fri May  4 04:14:19 2007
@@ -16,6 +16,7 @@
  */
 package org.apache.wicket;
 
+import java.io.ObjectStreamException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -161,6 +162,13 @@
 	/** Log. */
 	private static final Logger log = LoggerFactory.getLogger(Page.class);
 
+	/**
+	 * This is a thread local that is used for serializing page references in this 
+	 * page.It stores a {@link IPageSerializer} which can be set by the outside world
+	 * to do the serialization of this page.  
+	 */
+	public static final ThreadLocal serializer = new ThreadLocal();
+
 	/** Used to create page-unique numbers */
 	private short autoIndex;
 
@@ -242,7 +250,17 @@
 		init(pageMap);
 	}
 
-
+	protected Object writeReplace() throws ObjectStreamException
+	{
+		IPageSerializer ps = (IPageSerializer)serializer.get();
+		if (ps != null)
+		{
+			return ps.serializePage(this);
+		}
+		return this;
+	}
+	
+	
 	/**
 	 * Called right after a component's listener method (the provided method
 	 * argument) was called. This method may be used to clean up dependencies,
@@ -764,6 +782,11 @@
 	 */
 	public final void renderPage()
 	{
+		// if not attached then attach the whole page.
+		if (!isAttached())
+		{
+			attach();
+		}
 		// first try to check if the page can be rendered:
 		if (!isActionAuthorized(RENDER))
 		{
@@ -791,7 +814,7 @@
 			public Object component(Component component)
 			{
 				((IFeedback)component).updateFeedback();
-				component.attach();
+				component.beforeRender();
 				return IVisitor.CONTINUE_TRAVERSAL;
 			}
 		});
@@ -801,9 +824,6 @@
 			((IFeedback)this).updateFeedback();
 		}
 
-		// Now, do the initialization for the other components
-		attach();
-
 		// Visit all this page's children to reset markup streams and check
 		// rendering authorization, as appropriate. We set any result; positive
 		// or negative as a temporary boolean in the components, and when a
@@ -826,8 +846,11 @@
 			}
 		});
 
+		beforeRender();
 		// Handle request by rendering page
 		render(null);
+		
+		afterRender();
 
 		// Check rendering if it happened fully
 		checkRendering(this);
@@ -935,7 +958,7 @@
 	private void checkHierarchyChange(Component component)
 	{
 		// Throw exception if modification is attempted during rendering
-		if ((!component.isAuto()) && getFlag(FLAG_IS_RENDERING))
+		if ((!component.isAuto()) && getFlag(FLAG_IS_RENDERING) || getFlag(FLAG_ATTACHING))
 		{
 			throw new WicketRuntimeException(
 					"Cannot modify component hierarchy during render phase");
@@ -1373,5 +1396,26 @@
 	void setPageStateless(Boolean stateless)
 	{
 		this.stateless = stateless;
+	}
+	
+	/**
+	 * You can set implementation of the interface in the {@link Page#serializer}
+	 * then that implementation will handle the serialization of this page.
+	 * The serializePage method is called from the writeReplace then the implementation
+	 * can give another object to serialize instead. Which should have a readResolve method
+	 * for constructing back the page.
+	 * 
+	 * @author jcompagner
+	 */
+	public static interface IPageSerializer
+	{
+		/**
+		 * Called from the {@link Page#writeReplace()} method.
+		 * 
+		 * @param page The page that must be serialized.
+		 * 
+		 * @return The page or another Object that should be replaced for the page.
+		 */
+		public Object serializePage(Page page);
 	}
 }

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Session.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Session.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Session.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Session.java Fri May  4 04:14:19 2007
@@ -714,6 +714,12 @@
 					pageMapsUsedInRequest.remove(pageMap);
 					pageMapsUsedInRequest.notifyAll();
 				}
+				else
+				{
+					// attach the page now.
+					page.attach();
+					touch(page);
+				}
 				return page;
 			}
 		}

Added: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/form/AjaxFormChoiceComponentUpdatingBehavior.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/form/AjaxFormChoiceComponentUpdatingBehavior.java?view=auto&rev=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/form/AjaxFormChoiceComponentUpdatingBehavior.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/form/AjaxFormChoiceComponentUpdatingBehavior.java Fri May  4 04:14:19 2007
@@ -0,0 +1,156 @@
+/**
+ * 
+ */
+package org.apache.wicket.ajax.form;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.IHeaderResponse;
+import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.form.RadioChoice;
+import org.apache.wicket.markup.html.form.RadioGroup;
+import org.apache.wicket.util.string.AppendingStringBuffer;
+
+/**
+ * @author jcompagner
+ *
+ */
+public abstract class AjaxFormChoiceComponentUpdatingBehavior extends AbstractDefaultAjaxBehavior
+{
+	private static final long serialVersionUID = 1L;
+
+	protected Component component;
+
+	/**
+	 * Default constructor
+	 */
+	public AjaxFormChoiceComponentUpdatingBehavior()
+	{
+		super();
+	}
+
+	/**
+	 * @see wicket.ajax.AbstractDefaultAjaxBehavior#renderHead(wicket.markup.html.IHeaderResponse)
+	 */
+	public void renderHead(IHeaderResponse response)
+	{
+		super.renderHead(response);
+		
+		AppendingStringBuffer asb = new AppendingStringBuffer();
+		asb.append("function attachChoiceHandlers(markupid, callbackscript) {\n");
+		asb.append(" var choiceElement = document.getElementById(markupid);\n");
+		asb.append(" for( var x = 0; x < choiceElement.childNodes.length; x++ ) {\n");
+		asb.append("   if (choiceElement.childNodes[x] && choiceElement.childNodes[x].tagName) {\n");
+		asb.append("     var tag = choiceElement.childNodes[x].tagName.toLowerCase();\n");
+		asb.append("     if (tag == 'input') {\n");
+		asb.append("       Wicket.Event.add(choiceElement.childNodes[x],'click', callbackscript);");
+		asb.append("     }\n");		
+		asb.append("   }\n");
+		asb.append(" }\n");
+		asb.append("}\n");
+		
+		response.renderJavascript(asb, "attachChoice");
+		
+		response.renderOnLoadJavascript("attachChoiceHandlers('" + component.getMarkupId()+ "', function() {" + getEventHandler()+ "});");
+		
+	}
+	
+	/**
+	 * Listener invoked on the ajax request. This listener is invoked after the
+	 * component's model has been updated.
+	 * 
+	 * @param target
+	 */
+	protected abstract void onUpdate(AjaxRequestTarget target);
+	
+	/**
+	 * Called to handle any error resulting from updating form component. Errors
+	 * thrown from {@link #onUpdate(AjaxRequestTarget)} will not be caught here.
+	 * 
+	 * The RuntimeException will be null if it was just a validation or conversion 
+	 * error of the FormComponent
+	 * 
+	 * @param target
+	 * @param e
+	 */
+	protected void onError(AjaxRequestTarget target, RuntimeException e)
+	{
+		if(e != null) throw e;
+	}
+
+
+	/**
+	 * 
+	 * @see wicket.behavior.AbstractAjaxBehavior#onBind()
+	 */
+	protected void onBind()
+	{
+		super.onBind();
+
+
+		if (!(getComponent() instanceof RadioChoice) &&
+				!(getComponent() instanceof CheckBoxMultipleChoice) &&
+				!(getComponent() instanceof RadioGroup) &&
+				!(getComponent() instanceof CheckGroup))
+		{
+			throw new WicketRuntimeException("Behavior " + getClass().getName()
+					+ " can only be added to an instance of a RadioChoice/CheckboxChoice/RadioGroup/CheckGroup");
+		}
+	}
+
+	/**
+	 * 
+	 * @return FormComponent
+	 */
+	protected final FormComponent getFormComponent()
+	{
+		return (FormComponent)getComponent();
+	}
+
+	/**
+	 * @return event handler
+	 */
+	protected final CharSequence getEventHandler()
+	{
+		return getCallbackScript(new AppendingStringBuffer("wicketAjaxPost('").append(
+				getCallbackUrl()).append(
+				"', wicketSerializeForm(document.getElementById('" + getComponent().getMarkupId()
+						+ "',false))"), null, null);
+	}
+
+	/**
+	 * 
+	 * @see wicket.ajax.AbstractDefaultAjaxBehavior#respond(wicket.ajax.AjaxRequestTarget)
+	 */
+	protected final void respond(final AjaxRequestTarget target)
+	{
+		final FormComponent formComponent = getFormComponent();
+
+		try
+		{
+			formComponent.inputChanged();
+			formComponent.validate();
+			if (formComponent.hasErrorMessage())
+			{
+				formComponent.invalid();
+				
+				onError(target, null);
+			}
+			else
+			{
+				formComponent.valid();
+				formComponent.updateModel();
+				onUpdate(target);
+			}
+		}
+		catch (RuntimeException e)
+		{
+			onError(target, e);
+
+		}
+	}
+}

Propchange: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/form/AjaxFormChoiceComponentUpdatingBehavior.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/WebPage.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/WebPage.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/WebPage.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/WebPage.java Fri May  4 04:14:19 2007
@@ -231,9 +231,9 @@
 		return compressor;
 	}
 
-	protected void onAttach()
+	protected void onBeforeRender()
 	{
-		super.onAttach();
+		super.onBeforeRender();
 
 		if (!bodyContainerAdded)
 		{

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/form/upload/MultiFileUploadField.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/form/upload/MultiFileUploadField.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/form/upload/MultiFileUploadField.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/form/upload/MultiFileUploadField.java Fri May  4 04:14:19 2007
@@ -182,11 +182,11 @@
 	}
 
 	/**
-	 * @see org.apache.wicket.Component#onAttach()
+	 * @see org.apache.wicket.Component#onBeforeRender()
 	 */
-	protected void onAttach()
+	protected void onBeforeRender()
 	{
-		super.onAttach();
+		super.onBeforeRender();
 
 		// auto toggle form's multipart property
 		Form form = (Form)findParent(Form.class);

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java Fri May  4 04:14:19 2007
@@ -109,9 +109,9 @@
 		this.beforeDisabledLink = beforeDisabledLink;
 	}
 
-	protected void onAttach()
+	protected void onBeforeRender()
 	{
-		super.onAttach();
+		super.onBeforeRender();
 
 		// Set default for before/after link text
 		if (beforeDisabledLink == null)

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java Fri May  4 04:14:19 2007
@@ -278,11 +278,11 @@
 			private static final long serialVersionUID = 1L;
 
 			/**
-			 * @see org.apache.wicket.Component#onAttach()
+			 * @see org.apache.wicket.Component#onBeforeRender()
 			 */
-			protected void onAttach()
+			protected void onBeforeRender()
 			{
-				super.onAttach();
+				super.onBeforeRender();
 				setAutoEnable(false);
 				if (getList().indexOf(item.getModelObject()) == (getList().size() - 1))
 				{
@@ -335,11 +335,11 @@
 			private static final long serialVersionUID = 1L;
 
 			/**
-			 * @see org.apache.wicket.Component#onAttach()
+			 * @see org.apache.wicket.Component#onBeforeRender()
 			 */
-			protected void onAttach()
+			protected void onBeforeRender()
 			{
-				super.onAttach();
+				super.onBeforeRender();
 				setAutoEnable(false);
 				if (getList().indexOf(item.getModelObject()) == 0)
 				{
@@ -551,11 +551,11 @@
 	}
 
 	/**
-	 * @see org.apache.wicket.MarkupContainer#onAttach()
+	 * @see org.apache.wicket.MarkupContainer#onBeforeRender()
 	 */
-	protected void onAttach()
+	protected void onBeforeRender()
 	{
-		super.onAttach();
+		super.onBeforeRender();
 
 		if (isVisibleInHierarchy())
 		{

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/Loop.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/Loop.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/Loop.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/Loop.java Fri May  4 04:14:19 2007
@@ -109,11 +109,11 @@
 	}
 
 	/**
-	 * @see org.apache.wicket.Component#onAttach()
+	 * @see org.apache.wicket.Component#onBeforeRender()
 	 */
-	protected void onAttach()
+	protected void onBeforeRender()
 	{
-		super.onAttach();
+		super.onBeforeRender();
 
 		// Remove any previous loop contents
 		removeAll();

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/navigation/paging/PagingNavigation.java Fri May  4 04:14:19 2007
@@ -276,9 +276,9 @@
 	}
 
 	/**
-	 * @see org.apache.wicket.Component#onAttach()
+	 * @see org.apache.wicket.Component#onBeforeRender()
 	 */
-	protected void onAttach()
+	protected void onBeforeRender()
 	{
 		
 		// PagingNavigation itself (as well as the PageableListView)
@@ -287,7 +287,7 @@
 		// The index of the first page link depends on the PageableListView's
 		// page currently printed.
 		this.setStartIndex();
-		super.onAttach();
+		super.onBeforeRender();
 	}
 
 	/**

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/tree/AbstractTree.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/tree/AbstractTree.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/tree/AbstractTree.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/tree/AbstractTree.java Fri May  4 04:14:19 2007
@@ -234,10 +234,10 @@
 			}
 		}
 		
-		protected void onAttach()
+		protected void onBeforeRender()
 		{
 			AbstractTree.this.attach();
-			super.onAttach();
+			super.onBeforeRender();
 		}
 	}
 
@@ -471,9 +471,9 @@
 	 * Called at the beginning of the request (not ajax request, unless we are
 	 * rendering the entire component)
 	 */
-	public void onAttach()
+	public void onBeforeRender()
 	{
-		super.onAttach();
+		super.onBeforeRender();
 		if (attached == false)
 		{
 			onBeforeAttach();
@@ -904,6 +904,7 @@
 	 */
 	protected void onAfterRender()
 	{
+		super.onAfterRender();
 		// rendering is complete, clear all dirty flags and items
 		updated();
 	}

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/repeater/RefreshingView.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/repeater/RefreshingView.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/repeater/RefreshingView.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/repeater/RefreshingView.java Fri May  4 04:14:19 2007
@@ -89,9 +89,9 @@
 	 * Refresh the items in the view. Delegates the creation of items to the
 	 * selected item reuse strategy
 	 */
-	protected void onAttach()
+	protected void onBeforeRender()
 	{
-		super.onAttach();
+		super.onBeforeRender();
 
 		if (isVisibleInHierarchy())
 		{

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/FilePageStore.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/FilePageStore.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/FilePageStore.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/FilePageStore.java Fri May  4 04:14:19 2007
@@ -21,7 +21,10 @@
 import java.io.FileOutputStream;
 import java.io.FilenameFilter;
 import java.io.IOException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -30,6 +33,7 @@
 
 import org.apache.wicket.Application;
 import org.apache.wicket.Page;
+import org.apache.wicket.Session;
 import org.apache.wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore;
 import org.apache.wicket.util.concurrent.ConcurrentHashMap;
 import org.apache.wicket.util.lang.Objects;
@@ -217,7 +221,6 @@
 									else
 									{
 										sessionList.remove(0);
-										System.err.println("shouldn't happen");
 										continue;
 									}
 								}
@@ -647,79 +650,97 @@
 
 	private byte[] serializePage(SessionPageKey key, Page page)
 	{
+		byte[] bytes = null;
+		System.err.println("SERIALIZING " + key);
 		long t1 = System.currentTimeMillis();
-		byte[] bytes = Objects.objectToByteArray(page);
-		totalSerializationTime += (System.currentTimeMillis() - t1);
-		serialized++;
-		if (log.isDebugEnabled() && bytes != null)
-		{
-			log.debug("serializing page " + key.pageClass + "[" + key.id + "," + key.versionNumber
-					+ "] size: " + bytes.length + " for session " + key.sessionId + " took "
-					+ (System.currentTimeMillis() - t1) + " miliseconds to serialize");
+		Page.serializer.set(new PageSerializer(key));
+		try
+		{
+			bytes = Objects.objectToByteArray(page);
+			totalSerializationTime += (System.currentTimeMillis() - t1);
+			serialized++;
+			if (log.isDebugEnabled() && bytes != null)
+			{
+				log.debug("serializing page " + key.pageClass + "[" + key.id + "," + key.versionNumber
+						+ "] size: " + bytes.length + " for session " + key.sessionId + " took "
+						+ (System.currentTimeMillis() - t1) + " miliseconds to serialize");
+			}
+		}
+		finally
+		{
+			Page.serializer.set(null);
 		}
+		System.err.println("SERIALIZING " + key + " bytes: " + bytes);
 		return bytes;
 	}
 
-	private byte[] testMap(SessionPageKey currentKey)
+	private byte[] testMap(final SessionPageKey currentKey)
 	{
-		SessionPageKey previousPage = (SessionPageKey)pagesToBeSaved.get(currentKey);
-		if (previousPage != null)
-		{
-			return (byte[])previousPage.data;
-		}
+		System.err.println("TESTMAP:" + currentKey);
+		byte[] bytes = null;
 		List list = (List)pagesToBeSerialized.get(currentKey.sessionId);
-
 		if (list == null)
-			return null;
-
-		synchronized (list)
 		{
-			int index = list.indexOf(currentKey);
-			if (index != -1)
+			SessionPageKey previousPage = (SessionPageKey)pagesToBeSaved.get(currentKey);
+			if (previousPage != null)
 			{
-				currentKey = (SessionPageKey)list.get(index);
-				Object object = currentKey.data;
-				if (object instanceof Page)
-				{
-					list.remove(index);
-				}
-				else if (object == SERIALIZING)
+				bytes = (byte[])previousPage.data;
+			}
+		}
+		else
+		{
+			while(true)
+			{
+				SessionPageKey listKey = null;
+				synchronized (list)
 				{
-					try
+					if (list.size() > 0)
 					{
-						list.wait();
-					}
-					catch (InterruptedException ex)
-					{
-						throw new RuntimeException(ex);
+						listKey = (SessionPageKey)list.get(list.size()-1);
+						Object object = listKey.data;
+						if (object instanceof Page)
+						{
+							list.remove(list.size()-1);
+						}
+						else if (object == SERIALIZING)
+						{
+							try
+							{
+								list.wait();
+							}
+							catch (InterruptedException ex)
+							{
+								throw new RuntimeException(ex);
+							}
+						}
 					}
-					object = currentKey.data;
-					if (object instanceof byte[])
+					else
 					{
-						return (byte[])object;
+						break;
 					}
-					else
+				}
+				if (listKey.data instanceof Page)
+				{
+					byte[] ser = serializePage(listKey, (Page)listKey.data);
+					if (ser != null)
 					{
-						previousPage = (SessionPageKey)pagesToBeSaved.get(currentKey);
-						if (previousPage != null)
-						{
-							return (byte[])previousPage.data;
-						}
-						return null;
+						listKey.setObject(ser);
+						pagesToBeSaved.put(listKey, listKey);
 					}
 				}
-			}
-			else
-			{
-				return null;
+				if (listKey.equals(currentKey) && listKey.data instanceof byte[])
+				{
+					bytes = (byte[])listKey.data;
+				}
 			}
 		}
-
-		byte[] bytes = serializePage(currentKey, (Page)currentKey.data);
-		if (bytes != null)
+		if (bytes == null)
 		{
-			currentKey.setObject(bytes);
-			pagesToBeSaved.put(currentKey, currentKey);
+			SessionPageKey previousPage = (SessionPageKey)pagesToBeSaved.get(currentKey);
+			if (previousPage != null)
+			{
+				bytes = (byte[])previousPage.data;
+			}
 		}
 		return bytes;
 	}
@@ -734,5 +755,65 @@
 	protected File getWorkDir()
 	{
 		return defaultWorkDir;
+	}
+	
+	private class PageSerializer implements Page.IPageSerializer
+	{
+		private SessionPageKey current;
+		
+		private List previous = new ArrayList();
+		private List completed = new ArrayList();
+	
+
+		/**
+		 * Construct.
+		 * @param key
+		 */
+		public PageSerializer(SessionPageKey key)
+		{
+			this.current = key;
+		}
+
+		/**
+		 * @see org.apache.wicket.Page.IPageSerializer#serializePage(org.apache.wicket.Page)
+		 */
+		public Object serializePage(Page page)
+		{
+			if (current.id == page.getNumericId())
+			{
+				return page;
+			}
+			SessionPageKey spk = new SessionPageKey(current.sessionId,page);
+			if (!completed.contains(spk))
+			{
+				previous.add(current);
+				current = spk;
+				byte[] bytes = Objects.objectToByteArray(page);
+				current.setObject(bytes);
+				pagesToBeSaved.put(spk, spk);
+				completed.add(current);
+				current = (SessionPageKey)previous.remove(previous.size()-1);
+			}
+			return new PageHolder(page);
+		}
+	}
+	
+	private static class PageHolder implements Serializable
+	{
+		private static final long serialVersionUID = 1L;
+
+		private final int pageid;
+		private final String pagemap;
+		
+		PageHolder(Page page)
+		{
+			this.pageid = page.getNumericId();
+			this.pagemap = page.getPageMap().getName();
+		}
+		
+		protected Object readResolve() throws ObjectStreamException
+		{
+			return Session.get().getPage(pagemap, Integer.toString(pageid), -1);
+		}
 	}
 }

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/SecondLevelCacheSessionStore.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/SecondLevelCacheSessionStore.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/SecondLevelCacheSessionStore.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/protocol/http/SecondLevelCacheSessionStore.java Fri May  4 04:14:19 2007
@@ -17,6 +17,8 @@
 package org.apache.wicket.protocol.http;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.wicket.Application;
 import org.apache.wicket.Component;
@@ -106,6 +108,9 @@
 		private static final long serialVersionUID = 1L;
 
 		private Page lastPage = null;
+		
+		private List pageVersions = new ArrayList();
+		
 
 		/**
 		 * Construct.
@@ -119,6 +124,13 @@
 
 		public Page get(int id, int versionNumber)
 		{
+			PageVersions pv = null;
+			if (versionNumber == -1)
+			{
+				int index = pageVersions.indexOf(new PageVersions(id,-1,-1));
+				pv = (PageVersions)pageVersions.get(index);
+				versionNumber = pv.versionid;
+			}
 			String sessionId = getSession().getId();
 			if (lastPage != null && lastPage.getNumericId() == id)
 			{
@@ -132,9 +144,20 @@
 			}
 			if (sessionId != null)
 			{
-				// this is really a page request for a default page. (so without
-				// an ajax version)
-				return getStore().getPage(sessionId, getName(), id, versionNumber, 0);
+				int ajaxVersionNumber = 0;
+				if (pv == null)
+				{
+					int index = pageVersions.indexOf(new PageVersions(id,-1,-1));
+					if (index != -1)
+					{
+						pv = (PageVersions)pageVersions.get(index);
+					}
+				}
+				if (pv != null)
+				{
+					ajaxVersionNumber = pv.ajaxversionid;
+				}
+				return getStore().getPage(sessionId, getName(), id, versionNumber, ajaxVersionNumber);
 			}
 			return null;
 		}
@@ -149,6 +172,14 @@
 					getStore().storePage(sessionId, page);
 					lastPage = page;
 					dirty();
+					
+					PageVersions pv = new PageVersions(page.getNumericId(),page.getCurrentVersionNumber(),page.getAjaxVersionNumber());
+					pageVersions.remove(pv);
+					pageVersions.add(pv);
+					if (pageVersions.size() > 100)
+					{
+						pageVersions.remove(0);
+					}
 				}
 			}
 		}
@@ -165,6 +196,40 @@
 		private IPageStore getStore()
 		{
 			return ((SecondLevelCacheSessionStore)Application.get().getSessionStore()).getStore();
+		}
+		
+		private static class PageVersions
+		{
+			private final int pageid;
+			private int versionid;
+			private int ajaxversionid;
+			
+			PageVersions(int pageid, int versionid, int ajaxversionid)
+			{
+				this.pageid = pageid;
+				this.versionid = versionid;
+				this.ajaxversionid = versionid;
+			}
+			
+			/**
+			 * @see java.lang.Object#equals(java.lang.Object)
+			 */
+			public boolean equals(Object obj)
+			{
+				if (obj instanceof PageVersions)
+				{
+					return ((PageVersions)obj).pageid == pageid; 
+				}
+				return false;
+			}
+			
+			/**
+			 * @see java.lang.Object#hashCode()
+			 */
+			public int hashCode()
+			{
+				return pageid;
+			}
 		}
 	}
 

Added: incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/PageInPageVersionTest.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/PageInPageVersionTest.java?view=auto&rev=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/PageInPageVersionTest.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/PageInPageVersionTest.java Fri May  4 04:14:19 2007
@@ -0,0 +1,48 @@
+/*
+ * 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.wicket.markup.html.WebPage;
+import org.apache.wicket.util.lang.Objects;
+
+/**
+ * @author jcompagner
+ */
+public class PageInPageVersionTest extends WicketTestCase
+{
+	public void testPageInPage() throws Exception
+	{
+		Page1 page = new Page1();
+		
+		byte[] array = Objects.objectToByteArray(page);
+		
+		Page1 page2 = (Page1)Objects.byteArrayToObject(array);
+		
+		System.err.println(page2);
+	}
+	
+	
+	private static class Page1 extends WebPage
+	{
+		Page2 page = new Page2(); 
+	}
+	
+	private static class Page2 extends WebPage
+	{
+		
+	}
+}

Propchange: incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/PageInPageVersionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/TestErrorPage.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/TestErrorPage.java?view=diff&rev=535170&r1=535169&r2=535170
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/TestErrorPage.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/protocol/http/TestErrorPage.java Fri May  4 04:14:19 2007
@@ -47,6 +47,7 @@
 
 			protected void onAfterRender()
 			{
+				super.onAfterRender();
 				if (clicked)
 					throw new IllegalStateException("Intentional error");
 			}