You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2010/08/16 21:07:42 UTC

svn commit: r986100 - in /wicket/trunk/wicket/src: main/java/org/apache/wicket/request/mapper/PackageMapper.java test/java/org/apache/wicket/request/mapper/PackageMapperTest.java

Author: mgrigorov
Date: Mon Aug 16 19:07:41 2010
New Revision: 986100

URL: http://svn.apache.org/viewvc?rev=986100&view=rev
Log:
WICKET-2989 Add IRequestMapper that can mount all pages in a package

Add a mapper that replaces org.apache.wicket.protocol.http.WebApplication.mount(String, PackageName) from Wicket 1.4


Added:
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/PackageMapper.java   (with props)
    wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/PackageMapperTest.java   (with props)

Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/PackageMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/PackageMapper.java?rev=986100&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/PackageMapper.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/PackageMapper.java Mon Aug 16 19:07:41 2010
@@ -0,0 +1,157 @@
+/*
+ * 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.request.mapper;
+
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.component.IRequestablePage;
+import org.apache.wicket.request.mapper.info.PageComponentInfo;
+import org.apache.wicket.request.mapper.parameter.IPageParametersEncoder;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
+import org.apache.wicket.util.lang.Checks;
+import org.apache.wicket.util.lang.PackageName;
+
+/**
+ * A request mapper that mounts all bookmarkable pages at a given package.
+ * 
+ * <pre>
+ *  Page Class - Render (BookmarkablePageRequestHandler)
+ *  /mountPath/MyPage
+ *  (will redirect to hybrid alternative if page is not stateless)
+ * 
+ *  Page Instance - Render Hybrid (RenderPageRequestHandler for pages that were created using bookmarkable URLs)
+ *  /mountPath/MyPage?2
+ * 
+ *  Page Instance - Bookmarkable Listener (BookmarkableListenerInterfaceRequestHandler)
+ *  /mountPath/MyPage?2-click-foo-bar-baz
+ *  /mountPath/MyPage?2-click.1-foo-bar-baz (1 is behavior index)
+ *  (these will redirect to hybrid if page is not stateless)
+ * </pre>
+ */
+public class PackageMapper extends AbstractBookmarkableMapper
+{
+	/** the path to mount the bookmarkable page classes on */
+	private final String mountPath;
+
+	/**
+	 * the name of the package for which all bookmarkable pages should be mounted
+	 */
+	private final PackageName packageName;
+
+	/** the encoder used to encode/decode the page parameters */
+	private final IPageParametersEncoder pageParametersEncoder;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param mountPath
+	 * @param packageName
+	 */
+	public PackageMapper(final String mountPath, final PackageName packageName)
+	{
+		this(mountPath, packageName, new PageParametersEncoder());
+	}
+
+	/**
+	 * Construct.
+	 * 
+	 * @param mountPath
+	 * @param packageName
+	 * @param pageParametersEncoder
+	 */
+	public PackageMapper(final String mountPath, final PackageName packageName,
+		final IPageParametersEncoder pageParametersEncoder)
+	{
+		Checks.argumentNotNull(mountPath, "mountPath");
+		Checks.argumentNotNull(packageName, "packageName");
+		Checks.argumentNotNull(pageParametersEncoder, "pageParametersEncoder");
+
+		this.mountPath = mountPath;
+		this.packageName = packageName;
+		this.pageParametersEncoder = pageParametersEncoder;
+	}
+
+	/**
+	 * @see org.apache.wicket.request.mapper.AbstractBookmarkableMapper#buildUrl(org.apache.wicket.request.mapper.AbstractBookmarkableMapper.UrlInfo)
+	 */
+	@Override
+	protected Url buildUrl(UrlInfo info)
+	{
+		Class<? extends IRequestablePage> pageClass = info.getPageClass();
+		if (pageClass.getName().startsWith(packageName.getName()))
+		{
+			Url url = new Url();
+			url.getSegments().add(mountPath);
+			url.getSegments().add(pageClass.getSimpleName());
+
+			encodePageComponentInfo(url, info.getPageComponentInfo());
+
+			return encodePageParameters(url, info.getPageParameters(), pageParametersEncoder);
+		}
+
+		return null;
+	}
+
+	/**
+	 * @see org.apache.wicket.request.mapper.AbstractBookmarkableMapper#parseRequest(org.apache.wicket.request.Request)
+	 */
+	@Override
+	protected UrlInfo parseRequest(Request request)
+	{
+		Url url = request.getUrl();
+		if (url.getSegments().size() >= 1 && urlStartsWith(url, mountPath))
+		{
+			// try to extract page and component information from URL
+			PageComponentInfo info = getPageComponentInfo(url);
+
+			// load the page class
+			String className = url.getSegments().get(1);
+			String fullyQualifiedClassName = packageName.getName() + '.' + className;
+			Class<? extends IRequestablePage> pageClass = getPageClass(fullyQualifiedClassName);
+
+			if (pageClass != null && IRequestablePage.class.isAssignableFrom(pageClass))
+			{
+				// extract the PageParameters from URL if there are any
+				PageParameters pageParameters = extractPageParameters(request, 2,
+					pageParametersEncoder);
+
+				return new UrlInfo(info, pageClass, pageParameters);
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @see org.apache.wicket.request.mapper.AbstractBookmarkableMapper#pageMustHaveBeenCreatedBookmarkable()
+	 */
+	@Override
+	protected boolean pageMustHaveBeenCreatedBookmarkable()
+	{
+		return true;
+	}
+
+	/**
+	 * @see org.apache.wicket.request.mapper.AbstractBookmarkableMapper#getCompatibilityScore(org.apache.wicket.request.Request)
+	 */
+	@Override
+	public int getCompatibilityScore(Request request)
+	{
+		// always return 0 here so that the mounts have higher priority
+		return 0;
+	}
+}

Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/PackageMapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/PackageMapperTest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/PackageMapperTest.java?rev=986100&view=auto
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/PackageMapperTest.java (added)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/PackageMapperTest.java Mon Aug 16 19:07:41 2010
@@ -0,0 +1,419 @@
+/*
+ * 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.request.mapper;
+
+import org.apache.wicket.MockPage;
+import org.apache.wicket.markup.html.link.ILinkListener;
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.component.IRequestableComponent;
+import org.apache.wicket.request.component.IRequestablePage;
+import org.apache.wicket.request.handler.BookmarkableListenerInterfaceRequestHandler;
+import org.apache.wicket.request.handler.BookmarkablePageRequestHandler;
+import org.apache.wicket.request.handler.IPageProvider;
+import org.apache.wicket.request.handler.IPageRequestHandler;
+import org.apache.wicket.request.handler.ListenerInterfaceRequestHandler;
+import org.apache.wicket.request.handler.PageAndComponentProvider;
+import org.apache.wicket.request.handler.PageProvider;
+import org.apache.wicket.request.handler.RenderPageRequestHandler;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.util.lang.PackageName;
+
+/**
+ * 
+ */
+public class PackageMapperTest extends AbstractMapperTest
+{
+
+	private static final String MOUNT_PATH = "mountPath";
+
+	/**
+	 * Construct.
+	 */
+	public PackageMapperTest()
+	{
+	}
+
+	private final PackageMapper encoder = new PackageMapper(MOUNT_PATH,
+		PackageName.forClass(MockPage.class))
+	{
+		@Override
+		protected IMapperContext getContext()
+		{
+			return context;
+		}
+	};
+
+	private static final String PAGE_CLASS_NAME = MockPage.class.getSimpleName();
+
+	/**
+	 * 
+	 */
+	public void testDecode1()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME);
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+		assertTrue(handler instanceof RenderPageRequestHandler);
+		IRequestablePage page = ((RenderPageRequestHandler)handler).getPage();
+		assertEquals(PAGE_CLASS_NAME, page.getClass().getSimpleName());
+		assertEquals(0, page.getPageParameters().getIndexedParamsCount());
+		assertTrue(page.getPageParameters().getNamedParameterKeys().isEmpty());
+	}
+
+	/**
+	 * 
+	 */
+	public void testDecode2()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME + "/indexed1?a=b&b=c");
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+		assertTrue(handler instanceof RenderPageRequestHandler);
+		IRequestablePage page = ((RenderPageRequestHandler)handler).getPage();
+		assertEquals(PAGE_CLASS_NAME, page.getClass().getSimpleName());
+
+		PageParameters p = page.getPageParameters();
+		assertEquals(1, p.getIndexedParamsCount());
+		assertEquals("indexed1", p.getIndexedParameter(0).toString());
+
+		assertEquals(2, p.getNamedParameterKeys().size());
+		assertEquals("b", p.getNamedParameter("a").toString());
+		assertEquals("c", p.getNamedParameter("b").toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testDecode3()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME + "?15");
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+		assertTrue(handler instanceof RenderPageRequestHandler);
+		IRequestablePage page = ((RenderPageRequestHandler)handler).getPage();
+		checkPage(page, 15);
+	}
+
+	/**
+	 * 
+	 */
+	public void testDecode4()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME + "/i1/i2?15&a=b&b=c");
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+		assertTrue(handler instanceof RenderPageRequestHandler);
+		IRequestablePage page = ((RenderPageRequestHandler)handler).getPage();
+		checkPage(page, 15);
+
+		PageParameters p = page.getPageParameters();
+		assertEquals(2, p.getIndexedParamsCount());
+		assertEquals("i1", p.getIndexedParameter(0).toString());
+		assertEquals("i2", p.getIndexedParameter(1).toString());
+
+		assertEquals(2, p.getNamedParameterKeys().size());
+		assertEquals("b", p.getNamedParameter("a").toString());
+		assertEquals("c", p.getNamedParameter("b").toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testDecode5()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME + "?15-ILinkListener-foo-bar");
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+		assertTrue(handler instanceof ListenerInterfaceRequestHandler);
+
+		ListenerInterfaceRequestHandler h = (ListenerInterfaceRequestHandler)handler;
+
+		IRequestablePage page = h.getPage();
+		checkPage(page, 15);
+
+		assertEquals(ILinkListener.INTERFACE, h.getListenerInterface());
+		assertEquals("foo:bar", h.getComponent().getPageRelativePath());
+		assertNull(h.getBehaviorIndex());
+	}
+
+	/**
+	 * 
+	 */
+	public void testDecode6()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME +
+			"/i1/i2?15-ILinkListener-foo-bar&a=b&b=c");
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+		assertTrue(handler instanceof ListenerInterfaceRequestHandler);
+		ListenerInterfaceRequestHandler h = (ListenerInterfaceRequestHandler)handler;
+
+		IRequestablePage page = h.getPage();
+		checkPage(page, 15);
+
+		assertEquals(ILinkListener.INTERFACE, h.getListenerInterface());
+		assertEquals("foo:bar", h.getComponent().getPageRelativePath());
+
+		PageParameters p = page.getPageParameters();
+		assertEquals(2, p.getIndexedParamsCount());
+		assertEquals("i1", p.getIndexedParameter(0).toString());
+		assertEquals("i2", p.getIndexedParameter(1).toString());
+
+		assertEquals(2, p.getNamedParameterKeys().size());
+		assertEquals("b", p.getNamedParameter("a").toString());
+		assertEquals("c", p.getNamedParameter("b").toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testDecode7()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME + "?15-ILinkListener.4-foo-bar");
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+		assertTrue(handler instanceof ListenerInterfaceRequestHandler);
+
+		ListenerInterfaceRequestHandler h = (ListenerInterfaceRequestHandler)handler;
+
+		IRequestablePage page = h.getPage();
+		checkPage(page, 15);
+
+		assertEquals(ILinkListener.INTERFACE, h.getListenerInterface());
+		assertEquals("foo:bar", h.getComponent().getPageRelativePath());
+		assertEquals((Object)4, h.getBehaviorIndex());
+	}
+
+	/**
+	 * 
+	 */
+	public void testDecode8()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME +
+			"/i1/i2?15-5.ILinkListener-foo-bar&a=b&b=c");
+
+		context.setNextPageRenderCount(5);
+
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+		assertTrue(handler instanceof ListenerInterfaceRequestHandler);
+		ListenerInterfaceRequestHandler h = (ListenerInterfaceRequestHandler)handler;
+
+		IRequestablePage page = h.getPage();
+		assertEquals(page.getRenderCount(), 5);
+	}
+
+	/**
+	 * 
+	 */
+	public void testDecode9()
+	{
+		Url url = Url.parse(MOUNT_PATH + "/" + PAGE_CLASS_NAME +
+			"/i1/i2?15-5.ILinkListener-foo-bar&a=b&b=c");
+
+		context.setNextPageRenderCount(6);
+
+		try
+		{
+			IRequestHandler handler = encoder.mapRequest(getRequest(url));
+
+			((IPageRequestHandler)handler).getPage();
+
+			// should never get here
+			assertFalse(true);
+		}
+		catch (StalePageException e)
+		{
+
+		}
+	}
+
+	/**
+	 * WICKET-2993
+	 */
+	public void testDecode10()
+	{
+		// use String.class but any other non-Page will do the job as well
+		Url url = Url.parse(MOUNT_PATH + "/" + String.class.getSimpleName());
+
+		IRequestHandler handler = encoder.mapRequest(getRequest(url));
+		assertNull("A non-page class should not create a request handler!", handler);
+	}
+
+	/**
+	 * 
+	 */
+	public void testEncode1()
+	{
+		PageProvider provider = new PageProvider(MockPage.class, new PageParameters());
+		provider.setPageSource(context);
+		IRequestHandler handler = new BookmarkablePageRequestHandler(provider);
+		Url url = encoder.mapHandler(handler);
+		assertEquals(MOUNT_PATH + "/" + PAGE_CLASS_NAME, url.toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testEncode2()
+	{
+		PageParameters parameters = new PageParameters();
+		parameters.setIndexedParameter(0, "i1");
+		parameters.setIndexedParameter(1, "i2");
+		parameters.setNamedParameter("a", "b");
+		parameters.setNamedParameter("b", "c");
+		PageProvider provider = new PageProvider(MockPage.class, parameters);
+		provider.setPageSource(context);
+		IRequestHandler handler = new BookmarkablePageRequestHandler(provider);
+		Url url = encoder.mapHandler(handler);
+		assertEquals(MOUNT_PATH + "/" + PAGE_CLASS_NAME + "/i1/i2?a=b&b=c", url.toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testEncode3()
+	{
+		PageParameters parameters = new PageParameters();
+		parameters.setIndexedParameter(0, "i1");
+		parameters.setIndexedParameter(1, "i2");
+		parameters.setNamedParameter("a", "b");
+		parameters.setNamedParameter("b", "c");
+
+		PageProvider provider = new PageProvider(MockPage.class, parameters);
+		provider.setPageSource(context);
+		IRequestHandler handler = new BookmarkablePageRequestHandler(provider);
+		Url url = encoder.mapHandler(handler);
+
+		assertEquals(MOUNT_PATH + "/" + PAGE_CLASS_NAME + "/i1/i2?a=b&b=c", url.toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testEncode4()
+	{
+		MockPage page = new MockPage(15);
+		page.getPageParameters().setIndexedParameter(0, "i1");
+		page.getPageParameters().setIndexedParameter(1, "i2");
+		page.getPageParameters().setNamedParameter("a", "b");
+		page.getPageParameters().setNamedParameter("b", "c");
+		page.setCreatedBookmarkable(true);
+
+		IPageProvider provider = new PageProvider(page);
+		IRequestHandler handler = new RenderPageRequestHandler(provider);
+		Url url = encoder.mapHandler(handler);
+
+		assertEquals(MOUNT_PATH + "/" + PAGE_CLASS_NAME + "/i1/i2?15&a=b&b=c", url.toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testEncode5()
+	{
+		MockPage page = new MockPage(15);
+		page.getPageParameters().setIndexedParameter(0, "i1");
+		page.getPageParameters().setIndexedParameter(1, "i2");
+		page.getPageParameters().setNamedParameter("a", "b");
+		page.getPageParameters().setNamedParameter("b", "c");
+
+		page.setCreatedBookmarkable(false);
+
+		IPageProvider provider = new PageProvider(page);
+		IRequestHandler handler = new RenderPageRequestHandler(provider);
+		Url url = encoder.mapHandler(handler);
+
+		// never allow bookmarkable render url for page that has not been created by bookmarkable
+		// URL
+
+		assertNull(url);
+	}
+
+	/**
+	 * 
+	 */
+	public void testEncode6()
+	{
+		MockPage page = new MockPage(15);
+		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);
+
+		IRequestableComponent c = page.get("foo:bar");
+
+		PageAndComponentProvider provider = new PageAndComponentProvider(page, c);
+		IRequestHandler handler = new BookmarkableListenerInterfaceRequestHandler(provider,
+			ILinkListener.INTERFACE);
+
+		Url url = encoder.mapHandler(handler);
+
+		assertEquals(MOUNT_PATH + "/" + PAGE_CLASS_NAME +
+			"/i1/i2?15-0.ILinkListener-foo-bar&a=b&b=c", url.toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testEncode7()
+	{
+		MockPage page = new MockPage(15);
+		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);
+
+		IRequestableComponent c = page.get("foo:bar");
+
+		PageAndComponentProvider provider = new PageAndComponentProvider(page, c);
+		IRequestHandler handler = new BookmarkableListenerInterfaceRequestHandler(provider,
+			ILinkListener.INTERFACE, 4);
+
+		Url url = encoder.mapHandler(handler);
+
+		assertEquals(MOUNT_PATH + "/" + PAGE_CLASS_NAME +
+			"/i1/i2?15-0.ILinkListener.4-foo-bar&a=b&b=c", url.toString());
+	}
+
+	/**
+	 * 
+	 */
+	public void testEncode8()
+	{
+		MockPage page = new MockPage(15);
+		page.setBookmarkable(true);
+		page.setCreatedBookmarkable(true);
+		page.setPageStateless(true);
+
+		IPageProvider provider = new PageProvider(page);
+		IRequestHandler handler = new RenderPageRequestHandler(provider);
+
+		Url url = encoder.mapHandler(handler);
+
+		assertEquals(MOUNT_PATH + "/" + PAGE_CLASS_NAME, url.toString());
+	}
+}

Propchange: wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/PackageMapperTest.java
------------------------------------------------------------------------------
    svn:eol-style = native