You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2010/10/14 08:06:38 UTC

svn commit: r1022384 - in /wicket/trunk: wicket-examples/src/main/java/org/apache/wicket/examples/requestmapper/ wicket-request/src/main/java/org/apache/wicket/request/ wicket-request/src/main/java/org/apache/wicket/request/http/ wicket-request/src/mai...

Author: ivaynberg
Date: Thu Oct 14 06:06:37 2010
New Revision: 1022384

URL: http://svn.apache.org/viewvc?rev=1022384&view=rev
Log:

Issue: WICKET-3086

Added:
    wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/lang/Checks.java   (with props)
Modified:
    wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/requestmapper/LocaleFirstMapper.java
    wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Request.java
    wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Url.java
    wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/http/WebRequest.java
    wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
    wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java
    wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/ParentPathReferenceRewriter.java
    wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/mount/MountMapper.java
    wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/Strings.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
    wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/form/Form.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockWebRequest.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequest.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebRequest.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/handler/RenderPageRequestHandler.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/CryptoMapper.java
    wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/AbstractMapperTest.java
    wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java

Modified: wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/requestmapper/LocaleFirstMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/requestmapper/LocaleFirstMapper.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/requestmapper/LocaleFirstMapper.java (original)
+++ wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/requestmapper/LocaleFirstMapper.java Thu Oct 14 06:06:37 2010
@@ -77,7 +77,7 @@ public class LocaleFirstMapper extends A
 				url.getSegments().remove(0);
 
 				// create a request based on the new url
-				request = request.requestWithUrl(url);
+				request = request.cloneWithUrl(url);
 			}
 		}
 

Modified: wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Request.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Request.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Request.java (original)
+++ wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Request.java Thu Oct 14 06:06:37 2010
@@ -38,7 +38,22 @@ public abstract class Request
 	public abstract Url getUrl();
 
 	/**
-	 * In case this request has been created using {@link #requestWithUrl(Url)}, this method should
+	 * Returns the base URL relative to which this request should be processed.
+	 * 
+	 * If the current requested url is:
+	 * 
+	 * <pre>
+	 * /con/text/fil/ter/wicket/page?1&foo=bar
+	 * </pre>
+	 * 
+	 * the relative url is: </pre> wicket/page </pre>
+	 * 
+	 * @return ajax base url
+	 */
+	public abstract Url getBaseUrl();
+
+	/**
+	 * In case this request has been created using {@link #cloneWithUrl(Url)}, this method should
 	 * return the original URL.
 	 * 
 	 * @return original URL
@@ -86,7 +101,7 @@ public abstract class Request
 	 *            Url instance
 	 * @return request with specified URL.
 	 */
-	public Request requestWithUrl(final Url url)
+	public Request cloneWithUrl(final Url url)
 	{
 		return new Request()
 		{
@@ -119,6 +134,12 @@ public abstract class Request
 			{
 				return Request.this.getCharset();
 			}
+
+			@Override
+			public Url getBaseUrl()
+			{
+				return getUrl();
+			}
 		};
 	}
 

Modified: wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Url.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Url.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Url.java (original)
+++ wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/Url.java Thu Oct 14 06:06:37 2010
@@ -257,6 +257,18 @@ public final class Url implements Serial
 		setCharset(charset);
 	}
 
+	public void resolveRelativeTo(Url base)
+	{
+		Url url = new Url(base);
+
+		while (!getSegments().isEmpty() && "..".equals(getSegments().get(0)))
+		{
+			removeLeadingSegments(0);
+			url.getSegments().remove(url.getSegments().size() - 1);
+		}
+		getSegments().addAll(url.getSegments());
+	}
+
 	/**
 	 * Returns segments of the URL. Segments form the part before query string.
 	 * 
@@ -701,4 +713,54 @@ public final class Url implements Serial
 			return result.toString();
 		}
 	}
+
+	/**
+	 * Makes this url the result of resolving the {@code relative} url against this url.
+	 * <p>
+	 * Segments will be properly resolved, handling any {@code ..} references, while the query
+	 * parameters will be completely replaced with {@code relative}'s query parameters.
+	 * </p>
+	 * <p>
+	 * For example:
+	 * 
+	 * <pre>
+	 * wicket/page/render?foo=bar
+	 * </pre>
+	 * 
+	 * resolved with
+	 * 
+	 * <pre>
+	 * ../component/render?a=b
+	 * </pre>
+	 * 
+	 * will become
+	 * 
+	 * <pre>
+	 * wicket/component/render?a=b
+	 * </pre>
+	 * 
+	 * </p>
+	 * 
+	 * @param relative
+	 *            relative url
+	 */
+	public void resolveRelative(Url relative)
+	{
+		// strip the first non-folder segment
+		getSegments().remove(getSegments().size() - 1);
+
+		// process any ../ segments in the relative url
+		while (!relative.getSegments().isEmpty() && "".equals(relative.getSegments().get(0)))
+		{
+			relative.getSegments().remove(0);
+			getSegments().remove(getSegments().size() - 1);
+		}
+
+		// append the remaining relative segments
+		getSegments().addAll(relative.getSegments());
+
+		// replace query params with the ones from relative
+		parameters.clear();
+		parameters.addAll(relative.getQueryParameters());
+	}
 }

Modified: wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/http/WebRequest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/http/WebRequest.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/http/WebRequest.java (original)
+++ wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/http/WebRequest.java Thu Oct 14 06:06:37 2010
@@ -33,9 +33,19 @@ import org.apache.wicket.util.string.Str
  * Base class for request that provides additional web-related information.
  * 
  * @author Matej Knopp
+ * @author Igor Vaynberg
  */
 public abstract class WebRequest extends Request
 {
+	/** marker for Ajax requests */
+	protected static final String PARAM_AJAX = "wicket-ajax";
+	/** marker for Ajax requests */
+	protected static final String HEADER_AJAX = "Wicket-Ajax";
+	/** marker for Ajax-relative url */
+	protected static final String PARAM_AJAX_BASE_URL = "wicket-ajax-baseurl";
+	/** marker for Ajax-relative url */
+	protected static final String HEADER_AJAX_BASE_URL = "Wicket-Ajax-BaseURL";
+
 	/**
 	 * @return request cookies
 	 */
@@ -101,15 +111,11 @@ public abstract class WebRequest extends
 		}
 	}
 
-	/**
-	 * Marker parameter for AjaxRequest.
-	 */
-	private static final String PARAM_AJAX = "wicket:ajax";
-	private static final String HEADER_AJAX = "Wicket-Ajax";
 
 	/**
-	 * Returns whether this request is an Ajax request. This implementation only checks for value of
-	 * wicket:ajax url parameter. Subclasses can use other approach.
+	 * Returns whether this request is an Ajax request. This implementation checks for values of
+	 * {@value #PARAM_AJAX} url parameter or the {@value #HEADER_AJAX} header. Subclasses can use
+	 * other approaches.
 	 * 
 	 * @return <code>true</code> if this request is an ajax request, <code>false</code> otherwise.
 	 */
@@ -127,7 +133,7 @@ public abstract class WebRequest extends
 	 * @return request with specified URL.
 	 */
 	@Override
-	public WebRequest requestWithUrl(final Url url)
+	public WebRequest cloneWithUrl(final Url url)
 	{
 		return new WebRequest()
 		{
@@ -178,6 +184,12 @@ public abstract class WebRequest extends
 			{
 				return WebRequest.this.getCharset();
 			}
+
+			@Override
+			public Url getBaseUrl()
+			{
+				return WebRequest.this.getBaseUrl();
+			}
 		};
 	}
 

Modified: wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java (original)
+++ wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java Thu Oct 14 06:06:37 2010
@@ -118,7 +118,7 @@ public abstract class AbstractMapper
 			removeMetaParameter(urlCopy);
 		}
 
-		PageParameters decoded = encoder.decodePageParameters(request.requestWithUrl(urlCopy));
+		PageParameters decoded = encoder.decodePageParameters(request.cloneWithUrl(urlCopy));
 		return decoded;
 	}
 

Modified: wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java (original)
+++ wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java Thu Oct 14 06:06:37 2010
@@ -118,7 +118,8 @@ public class CompoundRequestMapper imple
 
 		for (IRequestMapper encoder : mappers)
 		{
-			list.add(new EncoderWithSegmentsCount(encoder, encoder.getCompatibilityScore(request)));
+			int score = encoder.getCompatibilityScore(request);
+			list.add(new EncoderWithSegmentsCount(encoder, score));
 		}
 
 		Collections.sort(list);

Modified: wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/ParentPathReferenceRewriter.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/ParentPathReferenceRewriter.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/ParentPathReferenceRewriter.java (original)
+++ wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/ParentPathReferenceRewriter.java Thu Oct 14 06:06:37 2010
@@ -79,7 +79,7 @@ public class ParentPathReferenceRewriter
 			}
 		}
 
-		return chain.mapRequest(request.requestWithUrl(url));
+		return chain.mapRequest(request.cloneWithUrl(url));
 	}
 
 	/**

Modified: wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/mount/MountMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/mount/MountMapper.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/mount/MountMapper.java (original)
+++ wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/mount/MountMapper.java Thu Oct 14 06:06:37 2010
@@ -103,7 +103,7 @@ public class MountMapper extends Abstrac
 	{
 		Url dismountedUrl = new Url(request.getUrl());
 		dismountedUrl.removeLeadingSegments(mountSegments.length);
-		return request.requestWithUrl(dismountedUrl);
+		return request.cloneWithUrl(dismountedUrl);
 	}
 
 	/**

Added: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/lang/Checks.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/lang/Checks.java?rev=1022384&view=auto
==============================================================================
--- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/lang/Checks.java (added)
+++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/lang/Checks.java Thu Oct 14 06:06:37 2010
@@ -0,0 +1,117 @@
+/*
+ * 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.util.lang;
+
+import org.apache.wicket.util.string.Strings;
+
+/**
+ * 
+ */
+public class Checks
+{
+	/**
+	 * Checks value is not null
+	 * 
+	 * @param argument
+	 * @param name
+	 * @throws IllegalStateException
+	 */
+	public static void notNull(final Object argument, final String message)
+	{
+		if (argument == null)
+		{
+			throw new IllegalStateException(message);
+		}
+	}
+
+	/**
+	 * Checks argument is not empty (not null and has a non-whitespace character)
+	 * 
+	 * @param argument
+	 * @param name
+	 * @throws IllegalStateException
+	 */
+	public static void notEmpty(final String argument, final String message)
+	{
+		if (Strings.isEmpty(argument))
+		{
+			throw new IllegalStateException(message);
+		}
+	}
+
+	/**
+	 * Checks if argument is within a range
+	 * 
+	 * @param <T>
+	 * @param min
+	 * @param max
+	 * @param value
+	 * @param name
+	 * @throws IllegalStateException
+	 */
+	public static <T extends Comparable<T>> void withinRange(T min, T max, T value, String message)
+	{
+		notNull(min, message);
+		notNull(max, message);
+		if (value.compareTo(min) < 0 || value.compareTo(max) > 0)
+		{
+			throw new IllegalStateException(message);
+		}
+
+		return;
+	}
+
+	/**
+	 * Checks value is not null
+	 * 
+	 * @param argument
+	 * @param name
+	 * @throws IllegalStateException
+	 */
+	public static void notNullShort(final Object argument, final String name)
+	{
+		notNull(argument, name + " may not be null.");
+	}
+
+	/**
+	 * Checks argument is not empty (not null and has a non-whitespace character)
+	 * 
+	 * @param argument
+	 * @param name
+	 * @throws IllegalStateException
+	 */
+	public static void notEmptyShort(final String argument, final String name)
+	{
+		notEmpty(argument, name + " may not be null or empty string.");
+	}
+
+	/**
+	 * Checks if argument is within a range
+	 * 
+	 * @param <T>
+	 * @param min
+	 * @param max
+	 * @param value
+	 * @param name
+	 * @throws IllegalStateException
+	 */
+	public static <T extends Comparable<T>> void withinRangeShort(T min, T max, T value, String name)
+	{
+		withinRange(min, max, value,
+			String.format("%s must have a value within [%s,%s], but was %s", name, min, max, value));
+	}
+}

Propchange: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/lang/Checks.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/Strings.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/Strings.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/Strings.java (original)
+++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/string/Strings.java Thu Oct 14 06:06:37 2010
@@ -639,21 +639,26 @@ public final class Strings
 			}
 			for (int i = 1; i < fragments.length; i++)
 			{
-				if ((fragments[i - 1] != null) || (fragments[i] != null))
+				String fragment = fragments[i];
+				if ((fragments[i - 1] != null) || (fragment != null))
 				{
 					boolean lhsClosed = fragments[i - 1].endsWith(separator);
-					boolean rhsClosed = fragments[i].startsWith(separator);
+					boolean rhsClosed = fragment.startsWith(separator);
 					if (lhsClosed && rhsClosed)
 					{
-						buff.append(fragments[i].substring(1));
+						buff.append(fragment.substring(1));
 					}
 					else if (!lhsClosed && !rhsClosed)
 					{
-						buff.append(separator).append(fragments[i]);
+						if (!Strings.isEmpty(fragment))
+						{
+							buff.append(separator);
+						}
+						buff.append(fragment);
 					}
 					else
 					{
-						buff.append(fragments[i]);
+						buff.append(fragment);
 					}
 				}
 			}

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java Thu Oct 14 06:06:37 2010
@@ -23,9 +23,7 @@ import org.apache.wicket.behavior.Abstra
 import org.apache.wicket.markup.html.IHeaderResponse;
 import org.apache.wicket.markup.html.WicketEventReference;
 import org.apache.wicket.protocol.http.WebApplication;
-import org.apache.wicket.request.Url;
 import org.apache.wicket.request.cycle.RequestCycle;
-import org.apache.wicket.request.http.WebRequest;
 import org.apache.wicket.request.resource.JavascriptResourceReference;
 import org.apache.wicket.request.resource.PackageResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
@@ -295,14 +293,7 @@ public abstract class AbstractDefaultAja
 		RequestCycle requestCycle = RequestCycle.get();
 		requestCycle.scheduleRequestHandlerAfterCurrent(target);
 
-		Url oldBaseURL = requestCycle.getUrlRenderer().getBaseUrl();
-		WebRequest request = (WebRequest)requestCycle.getRequest();
-		Url baseURL = Url.parse(request.getHeader("Wicket-Ajax-BaseURL"), request.getCharset());
-		requestCycle.getUrlRenderer().setBaseUrl(baseURL);
-
 		respond(target);
-
-		requestCycle.getUrlRenderer().setBaseUrl(oldBaseURL);
 	}
 
 	/**

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java Thu Oct 14 06:06:37 2010
@@ -32,7 +32,6 @@ import org.apache.wicket.Application;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.Page;
-import org.apache.wicket.ajax.AjaxRequestTarget.IListener;
 import org.apache.wicket.behavior.IBehavior;
 import org.apache.wicket.markup.html.IHeaderResponse;
 import org.apache.wicket.markup.html.internal.HeaderResponse;
@@ -42,7 +41,6 @@ import org.apache.wicket.markup.repeater
 import org.apache.wicket.request.IRequestCycle;
 import org.apache.wicket.request.IRequestHandler;
 import org.apache.wicket.request.Response;
-import org.apache.wicket.request.Url;
 import org.apache.wicket.request.component.IRequestablePage;
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.handler.IPageRequestHandler;
@@ -574,19 +572,13 @@ public class AjaxRequestTarget implement
 		try
 		{
 			RequestCycle rc = (RequestCycle)requestCycle;
-			Url oldBaseURL = rc.getUrlRenderer().getBaseUrl();
-			WebRequest request = (WebRequest)requestCycle.getRequest();
-			Url baseURL = Url.parse(request.getHeader("Wicket-Ajax-BaseURL"), request.getCharset());
-
-			rc.getUrlRenderer().setBaseUrl(baseURL);
 
 			final WebResponse response = (WebResponse)requestCycle.getResponse();
 
 			if (markupIdToComponent.values().contains(page))
 			{
 				// the page itself has been added to the request target, we simply issue a redirect
-// back
-// to the page
+				// back to the page
 				IRequestHandler handler = new RenderPageRequestHandler(new PageProvider(page));
 				final String url = rc.urlFor(handler).toString();
 				response.sendRedirect(url);
@@ -646,8 +638,6 @@ public class AjaxRequestTarget implement
 			}
 
 			response.write("</ajax-response>");
-
-			rc.getUrlRenderer().setBaseUrl(oldBaseURL);
 		}
 		finally
 		{

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js Thu Oct 14 06:06:37 2010
@@ -1151,7 +1151,7 @@ Wicket.Ajax.Call.prototype = {
 		
 		// reconfigure the form
 		form.target=iframe.name;
-		form.action=this.request.url + "&wicket:ajax=true";
+		form.action=this.request.url + "&wicket-ajax=true&wicket-ajax-baseurl=" + Wicket.Form.encode(Wicket.Ajax.baseUrl);
 		form.method="post";
 		form.enctype="multipart/form-data";
 		form.encoding="multipart/form-data";

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/form/Form.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/form/Form.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/form/Form.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/form/Form.java Thu Oct 14 06:06:37 2010
@@ -37,10 +37,13 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
 import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.IRequestMapper;
 import org.apache.wicket.request.IRequestParameters;
+import org.apache.wicket.request.Request;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.Url;
 import org.apache.wicket.request.UrlDecoder;
+import org.apache.wicket.request.UrlRenderer;
 import org.apache.wicket.request.http.WebRequest;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.settings.IApplicationSettings;
@@ -590,6 +593,18 @@ public class Form<T> extends WebMarkupCo
 	 */
 	public final CharSequence getJsForInterfaceUrl(CharSequence url)
 	{
+		/*
+		 * since the passed in url is handled when the current url is form's action url and not the
+		 * current request's url we rerender the passed in url to be relative to the form's action
+		 * url
+		 */
+		UrlRenderer renderer = getRequestCycle().getUrlRenderer();
+		Url oldBase = renderer.getBaseUrl();
+		Url action = Url.parse(getActionUrl().toString());
+		renderer.setBaseUrl(action);
+		url = renderer.renderUrl(Url.parse(url.toString()));
+		renderer.setBaseUrl(oldBase);
+
 		Form<?> root = getRootForm();
 		return new AppendingStringBuffer("document.getElementById('").append(
 			root.getHiddenFieldId())
@@ -1059,9 +1074,16 @@ public class Form<T> extends WebMarkupCo
 	 */
 	private void dispatchEvent(final Page page, final String url)
 	{
-		Url parsed = Url.parse(url, getRequest().getCharset());
-		IRequestHandler handler = getApplication().getRootRequestMapper().mapRequest(
-			getRequest().requestWithUrl(parsed));
+		// the current requst's url is most likely wicket/page?x-y.IFormSubmitListener-path-to-form
+		// while the passed in url is most likely page?x.y.IOnChangeListener-path-to-component
+		// we transform the passed in url into wicket/page?x-y.IOnChangeListener-path-to-component
+		// so the system mapper can interpret it
+		Url resolved = new Url(getRequest().getUrl());
+		resolved.resolveRelative(Url.parse(url));
+
+		IRequestMapper mapper = getApplication().getRootRequestMapper();
+		Request request = getRequest().cloneWithUrl(resolved);
+		IRequestHandler handler = mapper.mapRequest(request);
 
 		if (handler != null)
 		{
@@ -1510,7 +1532,7 @@ public class Form<T> extends WebMarkupCo
 		{
 			String method = getMethod().toLowerCase();
 			tag.put("method", method);
-			String url = urlFor(IFormSubmitListener.INTERFACE).toString();
+			String url = getActionUrl().toString();
 			if (encodeUrlInHiddenFields())
 			{
 				int i = url.indexOf('?');
@@ -1552,6 +1574,16 @@ public class Form<T> extends WebMarkupCo
 	}
 
 	/**
+	 * Generates the action url for the form
+	 * 
+	 * @return action url
+	 */
+	protected CharSequence getActionUrl()
+	{
+		return urlFor(IFormSubmitListener.INTERFACE);
+	}
+
+	/**
 	 * @see org.apache.wicket.Component#renderPlaceholderTag(org.apache.wicket.markup.ComponentTag,
 	 *      org.apache.wicket.request.Response)
 	 */
@@ -1614,7 +1646,7 @@ public class Form<T> extends WebMarkupCo
 			// and have to write the url parameters as hidden fields
 			if (encodeUrlInHiddenFields())
 			{
-				String url = urlFor(IFormSubmitListener.INTERFACE).toString();
+				String url = getActionUrl().toString();
 				int i = url.indexOf('?');
 				String[] params = ((i > -1) ? url.substring(i + 1) : url).split("&");
 

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockWebRequest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockWebRequest.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockWebRequest.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockWebRequest.java Thu Oct 14 06:06:37 2010
@@ -28,6 +28,7 @@ import javax.servlet.http.Cookie;
 
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.request.Url;
+import org.apache.wicket.request.Url.QueryParameter;
 import org.apache.wicket.request.http.WebRequest;
 
 /**
@@ -64,7 +65,7 @@ public class MockWebRequest extends WebR
 	}
 
 	@Override
-	public MockWebRequest requestWithUrl(Url url)
+	public MockWebRequest cloneWithUrl(Url url)
 	{
 		return new MockWebRequest(url, cookies, headers, postRequestParameters, locale);
 	}
@@ -249,4 +250,10 @@ public class MockWebRequest extends WebR
 	{
 		return Charset.forName("UTF-8");
 	}
+
+	@Override
+	public Url getBaseUrl()
+	{
+		return new Url(url.getSegments(), Collections.<QueryParameter> emptyList());
+	}
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequest.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequest.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequest.java Thu Oct 14 06:06:37 2010
@@ -60,7 +60,7 @@ public abstract class MultipartServletWe
 	}
 
 	@Override
-	public ServletWebRequest requestWithUrl(Url url)
+	public ServletWebRequest cloneWithUrl(Url url)
 	{
 		return new MultipartServletWebRequest(getHttpServletRequest(), getFilterPrefix(), url)
 		{

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebRequest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebRequest.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebRequest.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebRequest.java Thu Oct 14 06:06:37 2010
@@ -42,6 +42,7 @@ import org.apache.wicket.request.http.We
 import org.apache.wicket.util.io.Streams;
 import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Bytes;
+import org.apache.wicket.util.lang.Checks;
 import org.apache.wicket.util.string.PrependingStringBuffer;
 import org.apache.wicket.util.string.StringValue;
 import org.apache.wicket.util.string.Strings;
@@ -104,7 +105,54 @@ public class ServletWebRequest extends W
 		}
 	}
 
-	private Url getUrl(HttpServletRequest request, String filterPrefix)
+	/**
+	 * Returns base url without context or filter mapping.
+	 * 
+	 * Example: if current url is
+	 * 
+	 * <pre>
+	 * http://localhost:8080/context/filter/mapping/wicket/bookmarkable/com.foo.Page?1&id=2
+	 * </pre>
+	 * 
+	 * the base url is wicket/bookmarkable/com.foo.Page
+	 * 
+	 * <pre>
+	 * wicket / bookmarkab
+	 * @see org.apache.wicket.request.Request#getBaseUrl()
+	 */
+	@Override
+	public Url getBaseUrl()
+	{
+		if (!isAjax())
+		{
+			return Url.parse(getBaseUrl(httpServletRequest, filterPrefix).toString(), getCharset());
+		}
+		else
+		{
+			String base = null;
+
+			base = getHeader(HEADER_AJAX_BASE_URL);
+
+			if (base == null)
+			{
+				base = getRequestParameters().getParameterValue(PARAM_AJAX_BASE_URL).toString(null);
+			}
+
+			Checks.notNull(base, "Current ajax request is missing the base url header or parameter");
+
+			return Url.parse(base, getCharset());
+		}
+
+	}
+
+	/**
+	 * Builds base url for this request
+	 * 
+	 * @param request
+	 * @param filterPrefix
+	 * @return
+	 */
+	private StringBuilder getBaseUrl(HttpServletRequest request, String filterPrefix)
 	{
 		if (filterPrefix.length() > 0 && !filterPrefix.endsWith("/"))
 		{
@@ -116,6 +164,13 @@ public class ServletWebRequest extends W
 		final int start = request.getContextPath().length() + filterPrefix.length() + 1;
 		url.append(uri.substring(start));
 
+		return url;
+	}
+
+	private Url getUrl(HttpServletRequest request, String filterPrefix)
+	{
+		StringBuilder url = getBaseUrl(request, filterPrefix);
+
 		String query = request.getQueryString();
 		if (!Strings.isEmpty(query))
 		{
@@ -123,7 +178,7 @@ public class ServletWebRequest extends W
 			url.append(query);
 		}
 
-		return Url.parse(Strings.stripJSessionId(url.toString()), getCharset());
+		return Url.parse(url.toString(), getCharset());
 	}
 
 
@@ -311,7 +366,7 @@ public class ServletWebRequest extends W
 	}
 
 	@Override
-	public ServletWebRequest requestWithUrl(Url url)
+	public ServletWebRequest cloneWithUrl(Url url)
 	{
 		return new ServletWebRequest(httpServletRequest, filterPrefix, url)
 		{
@@ -372,4 +427,5 @@ public class ServletWebRequest extends W
 		return RequestUtils.getCharset(httpServletRequest);
 	}
 
+
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java Thu Oct 14 06:06:37 2010
@@ -28,6 +28,7 @@ import org.apache.wicket.protocol.http.R
 import org.apache.wicket.request.Url;
 import org.apache.wicket.request.http.WebResponse;
 import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.string.Strings;
 
 /**
  * WebResponse that wraps a {@link ServletWebResponse}.
@@ -215,25 +216,13 @@ public class ServletWebResponse extends 
 
 			final Url current;
 
-			if (webRequest.isAjax())
-			{
-				String ajaxBaseUrl = httpServletRequest.getHeader("Wicket-Ajax-BaseURL");
-
-				if (ajaxBaseUrl == null)
-					throw new IllegalStateException(
-						"current ajax request is missing the base url header");
-
-				current = Url.parse('/' + ajaxBaseUrl, charset);
-			}
-			else
-			{
-				current = Url.parse(httpServletRequest.getRequestURI(), charset);
-			}
+			current = webRequest.getBaseUrl();
 
 			Url append = Url.parse(url, charset);
 			current.concatSegments(append.getSegments());
 			Url result = new Url(current.getSegments(), append.getQueryParameters());
-			return getAbsolutePrefix() + result.toString();
+			return Strings.join("/", getAbsolutePrefix(), httpServletRequest.getContextPath(),
+				webRequest.getFilterPrefix(), result.toString());
 		}
 	}
 

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java Thu Oct 14 06:06:37 2010
@@ -154,7 +154,7 @@ public class RequestCycle extends Reques
 	protected UrlRenderer newUrlRenderer()
 	{
 		// All URLs will be rendered relative to current request (can be overriden afterwards)
-		return new UrlRenderer(getRequest().getUrl());
+		return new UrlRenderer(getRequest().getBaseUrl());
 	}
 
 	/**

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/handler/RenderPageRequestHandler.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/handler/RenderPageRequestHandler.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/handler/RenderPageRequestHandler.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/handler/RenderPageRequestHandler.java Thu Oct 14 06:06:37 2010
@@ -21,6 +21,7 @@ import org.apache.wicket.request.IReques
 import org.apache.wicket.request.IRequestHandler;
 import org.apache.wicket.request.component.IRequestablePage;
 import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.handler.render.PageRenderer;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.util.lang.Args;
 
@@ -144,6 +145,7 @@ public class RenderPageRequestHandler im
 	 */
 	public void respond(IRequestCycle requestCycle)
 	{
-		Application.get().getPageRendererProvider().get(this).respond((RequestCycle)requestCycle);
+		PageRenderer renderer = Application.get().getPageRendererProvider().get(this);
+		renderer.respond((RequestCycle)requestCycle);
 	}
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/CryptoMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/CryptoMapper.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/CryptoMapper.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/CryptoMapper.java Thu Oct 14 06:06:37 2010
@@ -73,7 +73,7 @@ public class CryptoMapper implements IRe
 			return null;
 		}
 
-		return wrappedMapper.mapRequest(request.requestWithUrl(url));
+		return wrappedMapper.mapRequest(request.cloneWithUrl(url));
 	}
 
 	private ICrypt getCrypt()

Modified: wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/AbstractMapperTest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/AbstractMapperTest.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/AbstractMapperTest.java (original)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/AbstractMapperTest.java Thu Oct 14 06:06:37 2010
@@ -69,6 +69,12 @@ public abstract class AbstractMapperTest
 			{
 				return Charset.forName("UTF-8");
 			}
+
+			@Override
+			public Url getBaseUrl()
+			{
+				return url;
+			}
 		};
 	}
 

Modified: wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java?rev=1022384&r1=1022383&r2=1022384&view=diff
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java (original)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java Thu Oct 14 06:06:37 2010
@@ -58,6 +58,12 @@ public class ResourceMapperTest extends 
 			{
 				return CHARSET;
 			}
+
+			@Override
+			public Url getBaseUrl()
+			{
+				return getUrl();
+			}
 		};
 	}
 
@@ -146,7 +152,7 @@ public class ResourceMapperTest extends 
 
 		public void respond(Attributes attributes)
 		{
-			this.pageParameters = attributes.getParameters();
+			pageParameters = attributes.getParameters();
 		}
 	}
 }