You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by kn...@apache.org on 2008/09/18 14:20:56 UTC

svn commit: r696647 - in /wicket/sandbox/knopp/experimental/wicket/src: main/java/org/apache/_wicket/request/ main/java/org/apache/_wicket/request/encoder/ main/java/org/apache/_wicket/request/encoder/info/ main/java/org/apache/_wicket/request/handler/...

Author: knopp
Date: Thu Sep 18 05:20:56 2008
New Revision: 696647

URL: http://svn.apache.org/viewvc?rev=696647&view=rev
Log:
made behaviors 1st class citizens

Modified:
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/BookmarkableEncoder.java
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/PageInstanceEncoder.java
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/info/ComponentInfo.java
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/BookmarkableListenerInterfaceRequestHandler.java
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/ListenerInterfaceRequestHandler.java
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/url-format.txt
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/RequestListenerInterface.java
    wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/BookmarkableEncoderTest.java
    wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/PageInstanceEncoderTest.java
    wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/info/ComponentInfoTest.java

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/BookmarkableEncoder.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/BookmarkableEncoder.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/BookmarkableEncoder.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/BookmarkableEncoder.java Thu Sep 18 05:20:56 2008
@@ -51,6 +51,7 @@
  *  /wicket/bookmarkable/org.apache.wicket.MyPage?2-click-foo-bar-baz
  *  /wicket/bookmarkable/org.apache.wicket.MyPage?2.4-click-foo-bar-baz
  *  /wicket/bookmarkable/org.apache.wicket.MyPage?pageMap.2.4-click-foo-bar-baz
+ *  /wicket/bookmarkable/org.apache.wicket.MyPage?2.4-click.1-foo-bar-baz (1 is behavior index)
  *  (these will redirect to hybrid if page is not stateless)
  * </pre>
  * 
@@ -102,7 +103,8 @@
 		IComponent component = getComponent(page, componentInfo.getComponentPath());
 		RequestListenerInterface listenerInterface = requestListenerInterfaceFromString(componentInfo.getListenerInterface());
 
-		return new ListenerInterfaceRequestHandler(page, component, listenerInterface);
+		return new ListenerInterfaceRequestHandler(page, component, listenerInterface,
+			componentInfo.getBehaviorIndex());
 	}
 
 	public RequestHandler decode(Request request)
@@ -135,7 +137,8 @@
 			else if (info.getPageInfo().getPageId() != null && info.getComponentInfo() == null)
 			{
 				// if there is page instance ifnromation in the URL but no component and listener
-				// interface then this is a hybrid URL - we need to try to reuse existing cpage instance
+				// interface then this is a hybrid URL - we need to try to reuse existing cpage
+				// instance
 				return processHybrid(info.getPageInfo(), pageClass, pageParameters);
 			}
 			else if (info.getComponentInfo() != null)
@@ -174,7 +177,7 @@
 		{
 			// possibly hybrid URL - bookmarkable URL with page instance information
 			// but only allowed if the page was created by bookamarkable URL
-			
+
 			IPage page = ((RenderPageRequestHandler)requestHandler).getPage();
 
 			// necessary check so that we won't generate bookmarkable URLs for all pages
@@ -192,13 +195,13 @@
 		}
 		else if (requestHandler instanceof BookmarkableListenerInterfaceRequestHandler)
 		{
-			// listener interface URL with page class information			
+			// listener interface URL with page class information
 			BookmarkableListenerInterfaceRequestHandler handler = (BookmarkableListenerInterfaceRequestHandler)requestHandler;
 			IPage page = handler.getPage();
 			PageInfo pageInfo = new PageInfo(page);
 			ComponentInfo componentInfo = new ComponentInfo(
 				requestListenerInterfaceToString(handler.getListenerInterface()),
-				handler.getComponent().getPath());
+				handler.getComponent().getPath(), handler.getBehaviorIndex());
 			Url url = newUrl(page.getClass());
 			encodePageComponentInfo(url, new PageComponentInfo(pageInfo, componentInfo));
 			return encodePageParameters(url, page.getPageParameters(), pageParametersEncoder);

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/PageInstanceEncoder.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/PageInstanceEncoder.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/PageInstanceEncoder.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/PageInstanceEncoder.java Thu Sep 18 05:20:56 2008
@@ -41,6 +41,7 @@
  *  /wicket/page?2-click-foo-bar-baz
  *  /wicket/page?2.4-click-foo-bar-baz
  *  /wicket/page?pageMap.2.4-click-foo-bar-bazr-baz
+ *  /wicket/page?2.4-click.1-foo-bar-baz (1 is behavior index)  
  * </pre>
  * 
  * @author Matej Knopp
@@ -77,7 +78,8 @@
 					IComponent component = getComponent(page, componentInfo.getComponentPath());
 					RequestListenerInterface listenerInterface = requestListenerInterfaceFromString(componentInfo.getListenerInterface());
 
-					return new ListenerInterfaceRequestHandler(page, component, listenerInterface);
+					return new ListenerInterfaceRequestHandler(page, component, listenerInterface,
+						componentInfo.getBehaviorIndex());
 				}
 			}
 		}
@@ -104,7 +106,8 @@
 
 			PageInfo pageInfo = new PageInfo(page);
 			ComponentInfo componentInfo = new ComponentInfo(
-				requestListenerInterfaceToString(listenerInterface), componentPath);
+				requestListenerInterfaceToString(listenerInterface), componentPath,
+				handler.getBehaviorIndex());
 			info = new PageComponentInfo(pageInfo, componentInfo);
 		}
 

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/info/ComponentInfo.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/info/ComponentInfo.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/info/ComponentInfo.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/encoder/info/ComponentInfo.java Thu Sep 18 05:20:56 2008
@@ -20,8 +20,9 @@
 
 /**
  * Encodes listener inteface and component path in form of
- * &lt;listenerInterface&gt-&lt;componentPath&gt; Also component path is escaped (':' characters are
- * replaced by '-')
+ * &lt;listenerInterface&gt-&lt;componentPath&gt; or &lt;listenerInterface&gt.&lt;behaviorIndex&gt;-&lt;componentPath&gt;
+ * <p>
+ * Component path is escaped (':' characters are replaced by '-')
  * 
  * @author Matej Knopp
  */
@@ -29,18 +30,31 @@
 {
 	private final String listenerInterface;
 	private final String componentPath;
+	private final Integer behaviorIndex;
 
+	private static final char BEHAVIOR_INDEX_SEPARATOR = '.';
 	private static final char SEPARATOR = '-';
 
 	/**
 	 * Construct.
+	 * 
 	 * @param listenerInterface
 	 * @param componentPath
+	 * @param behaviorIndex
 	 */
-	public ComponentInfo(String listenerInterface, String componentPath)
+	public ComponentInfo(String listenerInterface, String componentPath, Integer behaviorIndex)
 	{
+		if (listenerInterface == null)
+		{
+			throw new IllegalArgumentException("Argument 'listenerInterface' may not be null.");
+		}
+		if (componentPath == null)
+		{
+			throw new IllegalArgumentException("Argument 'componentPath' may not be null.");
+		}
 		this.listenerInterface = listenerInterface;
 		this.componentPath = componentPath;
+		this.behaviorIndex = behaviorIndex;
 	}
 
 	/**
@@ -59,6 +73,14 @@
 		return listenerInterface;
 	}
 
+	/**
+	 * @return behavior index
+	 */
+	public Integer getBehaviorIndex()
+	{
+		return behaviorIndex;
+	}
+
 	private static final String TMP_PLACEHOLDER = "[[[[[[[WICKET[[TMP]]DASH]]" + Math.random() +
 		"]]]]";
 
@@ -96,15 +118,17 @@
 	public String toString()
 	{
 		StringBuilder result = new StringBuilder();
-		if (listenerInterface != null)
+
+		result.append(listenerInterface);
+
+		if (behaviorIndex != null)
 		{
-			result.append(listenerInterface);
+			result.append(BEHAVIOR_INDEX_SEPARATOR);
+			result.append(behaviorIndex);
 		}
 		result.append(SEPARATOR);
-		if (componentPath != null)
-		{
-			result.append(encodeComponentPath(componentPath));
-		}
+		result.append(encodeComponentPath(componentPath));
+
 		return result.toString();
 	}
 
@@ -132,13 +156,30 @@
 
 			if (Strings.isEmpty(listenerInterface))
 			{
-				listenerInterface = null;
+				return null;
 			}
 			if (Strings.isEmpty(componentPath))
 			{
-				componentPath = null;
+				return null;
+			}
+
+			Integer behaviorIndex = null;
+			i = listenerInterface.indexOf(BEHAVIOR_INDEX_SEPARATOR);
+			if (i != -1)
+			{				
+				String behavior = listenerInterface.substring(i + 1);
+				listenerInterface = listenerInterface.substring(0, i);
+				try
+				{
+					behaviorIndex = Integer.valueOf(behavior);
+				}
+				catch (Exception e)
+				{
+					return null;
+				}
 			}
-			return new ComponentInfo(listenerInterface, componentPath);
+
+			return new ComponentInfo(listenerInterface, componentPath, behaviorIndex);
 		}
 	}
 

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/BookmarkableListenerInterfaceRequestHandler.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/BookmarkableListenerInterfaceRequestHandler.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/BookmarkableListenerInterfaceRequestHandler.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/BookmarkableListenerInterfaceRequestHandler.java Thu Sep 18 05:20:56 2008
@@ -38,6 +38,7 @@
 	private final IComponent component;
 	private final IPage page;
 	private final RequestListenerInterface listenerInterface;
+	private final Integer behaviorIndex;
 
 	/**
 	 * Construct.
@@ -45,9 +46,10 @@
 	 * @param page
 	 * @param component
 	 * @param listenerInterface
+	 * @param behaviorIndex 
 	 */
 	public BookmarkableListenerInterfaceRequestHandler(IPage page, IComponent component,
-		RequestListenerInterface listenerInterface)
+		RequestListenerInterface listenerInterface, Integer behaviorIndex)
 	{
 		if (component == null)
 		{
@@ -64,6 +66,20 @@
 		this.component = component;
 		this.page = page;
 		this.listenerInterface = listenerInterface;
+		this.behaviorIndex = behaviorIndex;
+	}
+	
+	/**
+	 * Construct.
+	 * 
+	 * @param page
+	 * @param component
+	 * @param listenerInterface
+	 */
+	public BookmarkableListenerInterfaceRequestHandler(IPage page, IComponent component,
+		RequestListenerInterface listenerInterface)
+	{
+		this(page, component, listenerInterface, null);
 	}
 
 	public IComponent getComponent()
@@ -106,6 +122,17 @@
 		return listenerInterface;
 	}
 
+	/**
+	 * Returns index of behavior this listener is targeted on or <code>null</code> if component
+	 * is the target
+	 * 
+	 * @return behavior index or <code>null</code>
+	 */
+	public Integer getBehaviorIndex()
+	{
+		return behaviorIndex;
+	}
+
 	public void respond(RequestCycle requestCycle)
 	{
 		// nothing to do here, this handler is only used to generate URLs

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/ListenerInterfaceRequestHandler.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/ListenerInterfaceRequestHandler.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/ListenerInterfaceRequestHandler.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/handler/impl/ListenerInterfaceRequestHandler.java Thu Sep 18 05:20:56 2008
@@ -26,6 +26,7 @@
 import org.apache.wicket.Page;
 import org.apache.wicket.RequestListenerInterface;
 import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.behavior.IBehavior;
 
 /**
  * Request handler that invokes the listener interface on component and renders page afterwards.
@@ -37,6 +38,7 @@
 	private final IComponent component;
 	private final IPage page;
 	private final RequestListenerInterface listenerInterface;
+	private final Integer behaviorIndex;
 
 	/**
 	 * Construct.
@@ -44,9 +46,10 @@
 	 * @param page
 	 * @param component
 	 * @param listenerInterface
+	 * @param behaviorIndex
 	 */
 	public ListenerInterfaceRequestHandler(IPage page, IComponent component,
-		RequestListenerInterface listenerInterface)
+		RequestListenerInterface listenerInterface, Integer behaviorIndex)
 	{
 		if (component == null)
 		{
@@ -63,6 +66,20 @@
 		this.component = component;
 		this.page = page;
 		this.listenerInterface = listenerInterface;
+		this.behaviorIndex = behaviorIndex;
+	}
+	
+	/**
+	 * Construct.
+	 * 
+	 * @param page
+	 * @param component
+	 * @param listenerInterface
+	 */
+	public ListenerInterfaceRequestHandler(IPage page, IComponent component,
+		RequestListenerInterface listenerInterface)
+	{
+		this(page, component, listenerInterface, null);
 	}
 
 	public IComponent getComponent()
@@ -105,12 +122,41 @@
 		return listenerInterface;
 	}
 
+	/**
+	 * Index of target behavior or <code>null</code> if component is the target.
+	 * 
+	 * @return behavior index or <code>null</code>
+	 */
+	public Integer getBehaviorIndex()
+	{
+		return behaviorIndex;
+	}
+
 	public void respond(RequestCycle requestCycle)
 	{
 		if (component.getPage() == page)
 		{
-			listenerInterface.invoke((Page)page, (Component)component);
-			requestCycle.replaceCurrentRequestHandler(new RenderPageRequestHandler(page));
+			Page page = (Page)this.page;
+			Component component = (Component)this.component;
+
+			if (getBehaviorIndex() == null)
+			{
+				listenerInterface.invoke(page, component);
+			}
+			else
+			{
+				try
+				{
+					IBehavior behavior = component.getBehaviors().get(behaviorIndex);
+					listenerInterface.invoke(page, component, behavior);
+				}
+				catch (IndexOutOfBoundsException e)
+				{
+					throw new WicketRuntimeException("Couldn't find component behavior.");
+				}
+
+			}
+			requestCycle.replaceCurrentRequestHandler(new RenderPageRequestHandler(this.page));
 		}
 		else
 		{

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/url-format.txt
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/url-format.txt?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/url-format.txt (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/_wicket/request/url-format.txt Thu Sep 18 05:20:56 2008
@@ -18,6 +18,7 @@
 /wicket/page?2-click-foo-bar-baz
 /wicket/page?2.4-click-foo-bar-baz
 /wicket/page?pageMap.2.4-click-foo-bar-baz
+/wicket/page?2.4-click.1-foo-bar-baz (1 is behavior index)  
 
 BOOKMARKABLE - NOT MOUNTED
 --------------------------
@@ -36,6 +37,7 @@
 /wicket/bookmarkable/org.apache.wicket.MyPage?2-click-foo-bar-baz
 /wicket/bookmarkable/org.apache.wicket.MyPage?2.4-click-foo-bar-baz
 /wicket/bookmarkable/org.apache.wicket.MyPage?pageMap.2.4-click-foo-bar-baz
+/wicket/bookmarkable/org.apache.wicket.MyPage?2.4-click.1-foo-bar-baz (1 is behavior index)
 (these will redirect to hybrid if page is not stateless)
 
 BOOKMARKABLE - MOUNTED
@@ -55,4 +57,5 @@
 /mount/point?2-click-foo-bar-baz
 /mount/point?2.4-click-foo-bar-baz
 /mount/point?pageMap.2.4-click-foo-bar-baz
+/mount/point?2.4-click.1-foo-bar-baz (1 is behavior index)
 (these will redirect to hybrid if page is not stateless)
\ No newline at end of file

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/RequestListenerInterface.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/RequestListenerInterface.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/RequestListenerInterface.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/RequestListenerInterface.java Thu Sep 18 05:20:56 2008
@@ -23,6 +23,7 @@
 import java.util.Map;
 
 import org.apache.wicket.authorization.AuthorizationException;
+import org.apache.wicket.behavior.IBehavior;
 import org.apache.wicket.request.RequestParameters;
 import org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget;
 import org.apache.wicket.util.lang.Classes;
@@ -75,7 +76,7 @@
 	 * @param listenerInterfaceClass
 	 *            The interface class, which must extend IRequestListener.
 	 */
-	public RequestListenerInterface(final Class< ? extends IRequestListener> listenerInterfaceClass)
+	public RequestListenerInterface(final Class<? extends IRequestListener> listenerInterfaceClass)
 	{
 		this(listenerInterfaceClass, true);
 	}
@@ -89,8 +90,8 @@
 	 *            Whether or not urls encoded for this interface contain the page version. If set to
 	 *            false the latest page version is always used.
 	 */
-	public RequestListenerInterface(
-		final Class< ? extends IRequestListener> listenerInterfaceClass, boolean recordsPageVersion)
+	public RequestListenerInterface(final Class<? extends IRequestListener> listenerInterfaceClass,
+		boolean recordsPageVersion)
 	{
 		// Ensure that it extends IRequestListener
 		if (!IRequestListener.class.isAssignableFrom(listenerInterfaceClass))
@@ -207,6 +208,57 @@
 	}
 
 	/**
+	 * Invokes a given interface on a component's behavior.
+	 * 
+	 * @param page
+	 *            The Page that contains the component
+	 * @param component
+	 *            The component
+	 * @param behavior
+	 */
+	public final void invoke(final Page page, final Component component, final IBehavior behavior)
+	{
+		if (!component.isEnabled() || !component.isVisibleInHierarchy())
+		{
+			// just return so that we have a silent fail and just re-render the
+			// page
+			log.info("component not enabled or visible; ignoring call. Component: " + component);
+			return;
+		}
+
+		page.beforeCallComponent(component, this);
+
+		try
+		{
+			// Invoke the interface method on the component
+			method.invoke(behavior, new Object[] {});
+		}
+		catch (InvocationTargetException e)
+		{
+			// Honor redirect exception contract defined in IPageFactory
+			if (e.getTargetException() instanceof AbstractRestartResponseException ||
+				e.getTargetException() instanceof AuthorizationException ||
+				e.getTargetException() instanceof WicketRuntimeException)
+			{
+				throw (RuntimeException)e.getTargetException();
+			}
+			throw new WicketRuntimeException("Method " + method.getName() + " of " +
+				method.getDeclaringClass() + " targeted at behavior " + behavior +
+				" on component " + component + " threw an exception", e);
+		}
+		catch (Exception e)
+		{
+			throw new WicketRuntimeException("Method " + method.getName() + " of " +
+				method.getDeclaringClass() + " targeted at behavior " + behavior +
+				" on component " + component + " threw an exception", e);
+		}
+		finally
+		{
+			page.afterCallComponent(component, this);
+		}
+	}
+
+	/**
 	 * Creates a new request target for this request listener interface
 	 * 
 	 * @param page

Modified: wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/BookmarkableEncoderTest.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/BookmarkableEncoderTest.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/BookmarkableEncoderTest.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/BookmarkableEncoderTest.java Thu Sep 18 05:20:56 2008
@@ -133,6 +133,7 @@
 		RequestHandler handler = encoder.decode(getRequest(url));
 
 		assertTrue(handler instanceof ListenerInterfaceRequestHandler);
+		
 		ListenerInterfaceRequestHandler h = (ListenerInterfaceRequestHandler)handler;
 
 		IPage page = h.getPage();
@@ -140,6 +141,7 @@
 
 		assertEquals(ILinkListener.INTERFACE, h.getListenerInterface());
 		assertEquals("foo:bar", h.getComponent().getPath());
+		assertNull(h.getBehaviorIndex());
 	}
 
 	/**
@@ -169,6 +171,26 @@
 		assertEquals("b", p.getNamedParameter("a").toString());
 		assertEquals("c", p.getNamedParameter("b").toString());
 	}
+	
+	/**
+	 * 
+	 */
+	public void testDecode7()
+	{
+		Url url = Url.parse("wicket/bookmarkable/" + PAGE_CLASS_NAME + "?15-ILinkListener.4-foo-bar");
+		RequestHandler handler = encoder.decode(getRequest(url));
+
+		assertTrue(handler instanceof ListenerInterfaceRequestHandler);
+		
+		ListenerInterfaceRequestHandler h = (ListenerInterfaceRequestHandler)handler;
+
+		IPage page = h.getPage();
+		checkPage(page, 15, 0, null);
+
+		assertEquals(ILinkListener.INTERFACE, h.getListenerInterface());
+		assertEquals("foo:bar", h.getComponent().getPath());
+		assertEquals((Object)4, h.getBehaviorIndex());
+	}
 
 	/**
 	 * 
@@ -289,6 +311,33 @@
 	public void testEncode7()
 	{
 		MockPage page = new MockPage(15, 5, "abc");
+		page.getPageParameters().setIndexedParameter(0, "i1");
+		page.getPageParameters().setIndexedParameter(1, "i2");
+		page.getPageParameters().setNamedParameter("a", "b");
+		page.getPageParameters().setNamedParameter("b", "c");
+
+		// shouldn't make any difference for BookmarkableListenerInterfaceRequestHandler,
+		// as this explicitely says the url must be bookmarkable
+		page.setCreatedBookmarkable(false);
+
+		IComponent c = page.get("foo:bar");
+
+		RequestHandler handler = new BookmarkableListenerInterfaceRequestHandler(page, c,
+			ILinkListener.INTERFACE, 4);
+
+		Url url = encoder.encode(handler);
+
+		assertEquals("wicket/bookmarkable/" + PAGE_CLASS_NAME +
+			"/i1/i2?abc.15.5-ILinkListener.4-foo-bar&a=b&b=c", url.toString());
+	}
+
+	
+	/**
+	 * 
+	 */
+	public void testEncode8()
+	{
+		MockPage page = new MockPage(15, 5, "abc");
 		page.setBookmarkable(true);
 		page.setCreatedBookmarkable(true);
 		page.setPageStateless(true);

Modified: wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/PageInstanceEncoderTest.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/PageInstanceEncoderTest.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/PageInstanceEncoderTest.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/PageInstanceEncoderTest.java Thu Sep 18 05:20:56 2008
@@ -104,6 +104,7 @@
 		checkPage(h.getPage(), 4, 5, "abc"); 	
 		assertEquals(h.getComponent().getPath(), "a:b:c");
 		assertEquals(ILinkListener.INTERFACE, h.getListenerInterface());
+		assertNull(h.getBehaviorIndex());
 	}
 	
 	/**
@@ -131,6 +132,23 @@
 	/**
 	 * 
 	 */
+	public void testDecode7()
+	{
+		Url url = Url.parse("wicket/page?abc.4.5-ILinkListener.5-a-b-c");
+		
+		RequestHandler handler = encoder.decode(getRequest(url));
+		assertTrue(handler instanceof ListenerInterfaceRequestHandler);
+		
+		ListenerInterfaceRequestHandler h = (ListenerInterfaceRequestHandler) handler;
+		checkPage(h.getPage(), 4, 5, "abc"); 	
+		assertEquals(h.getComponent().getPath(), "a:b:c");
+		assertEquals(ILinkListener.INTERFACE, h.getListenerInterface());
+		assertEquals((Object)5, h.getBehaviorIndex());
+	}
+	
+	/**
+	 * 
+	 */
 	public void testEncode1()
 	{
 		MockPage page = new MockPage(15, 4, "pm1");
@@ -166,4 +184,19 @@
 		Url url = encoder.encode(handler);
 		assertEquals("wicket/page?15-ILinkListener-a-b-c", url.toString());
 	}
+	
+	/**
+	 * 
+	 */
+	public void testEncode4()
+	{
+		MockPage page = new MockPage(15, 0, null);
+		
+		IComponent c = page.get("a:b:c");
+		
+		RequestHandler handler = new ListenerInterfaceRequestHandler(page, c, ILinkListener.INTERFACE, 5);
+		
+		Url url = encoder.encode(handler);
+		assertEquals("wicket/page?15-ILinkListener.5-a-b-c", url.toString());
+	}	
 }

Modified: wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/info/ComponentInfoTest.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/info/ComponentInfoTest.java?rev=696647&r1=696646&r2=696647&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/info/ComponentInfoTest.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/test/java/org/apache/_wicket/request/encoder/info/ComponentInfoTest.java Thu Sep 18 05:20:56 2008
@@ -16,8 +16,6 @@
  */
 package org.apache._wicket.request.encoder.info;
 
-import org.apache._wicket.request.encoder.info.ComponentInfo;
-
 import junit.framework.TestCase;
 
 /**
@@ -44,6 +42,7 @@
 		ComponentInfo info = ComponentInfo.parse(s);
 		assertEquals("listener", info.getListenerInterface());
 		assertEquals("component:path", info.getComponentPath());
+		assertNull(info.getBehaviorIndex());
 		
 		assertEquals(s, info.toString());
 	}
@@ -55,10 +54,7 @@
 	{
 		String s = "-component-path";
 		ComponentInfo info = ComponentInfo.parse(s);
-		assertEquals(null, info.getListenerInterface());
-		assertEquals("component:path", info.getComponentPath());
-		
-		assertEquals(s, info.toString());
+		assertEquals(null, info);		
 	}
 	
 	/**
@@ -67,11 +63,8 @@
 	public void test3()
 	{
 		String s = "listener-";
-		ComponentInfo info = ComponentInfo.parse(s);
-		assertEquals("listener", info.getListenerInterface());
-		assertEquals(null, info.getComponentPath());
-		
-		assertEquals(s, info.toString());
+		ComponentInfo info = ComponentInfo.parse(s);		
+		assertEquals(null, info);
 	}
 	
 	/**
@@ -81,10 +74,7 @@
 	{
 		String s = "-";
 		ComponentInfo info = ComponentInfo.parse(s);
-		assertEquals(null, info.getListenerInterface());
-		assertEquals(null, info.getComponentPath());
-		
-		assertEquals(s, info.toString());
+		assertEquals(null, info);
 	}
 	
 	/**
@@ -105,6 +95,7 @@
 		ComponentInfo info = ComponentInfo.parse(s);
 		assertEquals("listener", info.getListenerInterface());
 		assertEquals("compo-nent:path", info.getComponentPath());
+		assertNull(info.getBehaviorIndex());
 		
 		assertEquals(s, info.toString());
 	}
@@ -118,6 +109,21 @@
 		ComponentInfo info = ComponentInfo.parse(s);
 		assertEquals("listener", info.getListenerInterface());
 		assertEquals("co-mpo--nent:path", info.getComponentPath());
+		assertNull(info.getBehaviorIndex());
+		
+		assertEquals(s, info.toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void test8()
+	{
+		String s = "listener.12-component-path";
+		ComponentInfo info = ComponentInfo.parse(s);
+		assertEquals("listener", info.getListenerInterface());
+		assertEquals("component:path", info.getComponentPath());
+		assertEquals((Object)12, info.getBehaviorIndex());
 		
 		assertEquals(s, info.toString());
 	}