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/03/01 01:01:58 UTC
svn commit: r917331 [1/2] - in /wicket/trunk/wicket/src:
main/java/org/apache/wicket/ main/java/org/apache/wicket/ng/
main/java/org/apache/wicket/ng/mock/
main/java/org/apache/wicket/ng/request/mapper/
main/java/org/apache/wicket/protocol/http/ main/ja...
Author: ivaynberg
Date: Mon Mar 1 00:01:57 2010
New Revision: 917331
URL: http://svn.apache.org/viewvc?rev=917331&view=rev
Log:
text fixes and ../ handling inside resource paths
Added:
wicket/trunk/wicket/src/main/java/org/apache/wicket/IPageManagerProvider.java (contents, props changed)
- copied, changed from r917266, wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/TestExpirePage.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletRequest.java (with props)
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletResponse.java (with props)
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpSession.java (with props)
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockServletContext.java (with props)
Modified:
wicket/trunk/wicket/src/main/java/org/apache/wicket/Application.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/DefaultExceptionMapper.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockApplication.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockPageManager.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockWebResponse.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/RequestUtils.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/Settings.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/util/cookies/CookieUtils.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/util/crypt/KeyInSessionSunJceCryptFactory.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/ParentResourceEscapePathTest.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/link/submitLink/FormPage.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/resolver/TestHomePage.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/TestExpirePage.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/WebResponseExceptionsTest.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/StatelessComponentPageWithParams.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/util/cookies/CookieUtilsTest.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/util/tester/WicketTesterTest.java
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/Application.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/Application.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/Application.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/Application.java Mon Mar 1 00:01:57 2010
@@ -85,6 +85,7 @@
import org.apache.wicket.settings.ISecuritySettings;
import org.apache.wicket.settings.ISessionSettings;
import org.apache.wicket.settings.Settings;
+import org.apache.wicket.util.IProvider;
import org.apache.wicket.util.convert.ConverterLocator;
import org.apache.wicket.util.lang.Checks;
import org.apache.wicket.util.lang.Objects;
@@ -192,7 +193,7 @@
private IRequestLogger requestLogger;
/** The session facade. */
- private ISessionStore sessionStore;
+ private volatile ISessionStore sessionStore;
/** Settings for this application. */
private Settings settings;
@@ -206,6 +207,9 @@
/** request cycle provider */
private IRequestCycleProvider requestCycleProvider;
+ /** session store provider */
+ private IProvider<ISessionStore> sessionStoreProvider;
+
/**
* Checks if the <code>Application</code> threadlocal is set in this thread
*
@@ -609,6 +613,17 @@
*/
public final ISessionStore getSessionStore()
{
+ if (sessionStore == null)
+ {
+ synchronized (this)
+ {
+ if (sessionStore == null)
+ {
+ sessionStore = sessionStoreProvider.get();
+ sessionStore.registerUnboundListener(this);
+ }
+ }
+ }
return sessionStore;
}
@@ -907,11 +922,9 @@
String applicationKey = getApplicationKey();
applicationKeyToApplication.put(applicationKey, this);
- sessionStore = newSessionStore();
- sessionStore.registerUnboundListener(this);
converterLocator = newConverterLocator();
- pageManager = newPageManager(getPageManagerContext());
+ setPageManagerProvider(new DefaultPageManagerProvider());
resourceReferenceRegistry = newResourceReferenceRegistry();
sharedResources = newSharedResources(resourceReferenceRegistry);
@@ -923,6 +936,17 @@
requestCycleProvider = new DefaultRequestCycleProvider();
}
+
+ public final IProvider<ISessionStore> getSessionStoreProvider()
+ {
+ return sessionStoreProvider;
+ }
+
+ public final void setSessionStoreProvider(IProvider<ISessionStore> sessionStoreProvider)
+ {
+ this.sessionStoreProvider = sessionStoreProvider;
+ }
+
/**
* Creates and returns a new instance of {@link IConverterLocator}.
*
@@ -945,14 +969,6 @@
}
/**
- * Creates a new session facade. Is called once per application, and is typically not something
- * clients reimplement.
- *
- * @return The session facade
- */
- protected abstract ISessionStore newSessionStore();
-
- /**
* Notifies the registered component instantiation listeners of the construction of the provided
* component
*
@@ -1210,16 +1226,19 @@
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- protected IPageManager newPageManager(IPageManagerContext context)
+ private volatile IPageManager pageManager;
+ private IPageManagerProvider pageManagerProvider;
+
+
+ public final IPageManagerProvider getPageManagerProvider()
{
- int cacheSize = 40;
- int fileChannelPoolCapacity = 50;
- IDataStore dataStore = new DiskDataStore(getName(), 1000000, fileChannelPoolCapacity);
- IPageStore pageStore = new DefaultPageStore(getName(), dataStore, cacheSize);
- return new PersistentPageManager(getName(), pageStore, context);
+ return pageManagerProvider;
}
- private IPageManager pageManager;
+ public final void setPageManagerProvider(IPageManagerProvider pageManagerProvider)
+ {
+ this.pageManagerProvider = pageManagerProvider;
+ }
/**
* Context for PageManager to interact with rest of Wicket
@@ -1230,8 +1249,18 @@
*
* @return the page manager
*/
- public IPageManager getPageManager()
+ public final IPageManager getPageManager()
{
+ if (pageManager == null)
+ {
+ synchronized (this)
+ {
+ if (pageManager == null)
+ {
+ pageManager = pageManagerProvider.get(getPageManagerContext());
+ }
+ }
+ }
return pageManager;
}
@@ -1470,6 +1499,16 @@
throw new IllegalStateException(
"An instance of IPageRendererProvider has not yet been set on this Application. @see Application#setPageRendererProvider");
}
+ if (getSessionStoreProvider() == null)
+ {
+ throw new IllegalStateException(
+ "An instance of ISessionStoreProvider has not yet been set on this Application. @see Application#setSessionStoreProvider");
+ }
+ if (getPageManagerProvider() == null)
+ {
+ throw new IllegalStateException(
+ "An instance of IPageManagerProvider has not yet been set on this Application. @see Application#setPageManagerProvider");
+ }
}
/**
@@ -1507,4 +1546,19 @@
{
return URLConnection.getFileNameMap().getContentTypeFor(fileName);
}
+
+ private class DefaultPageManagerProvider implements IPageManagerProvider
+ {
+
+ public IPageManager get(IPageManagerContext context)
+ {
+ int cacheSize = 40;
+ int fileChannelPoolCapacity = 50;
+ IDataStore dataStore = new DiskDataStore(getName(), 1000000, fileChannelPoolCapacity);
+ IPageStore pageStore = new DefaultPageStore(getName(), dataStore, cacheSize);
+ return new PersistentPageManager(getName(), pageStore, context);
+
+ }
+
+ }
}
Copied: wicket/trunk/wicket/src/main/java/org/apache/wicket/IPageManagerProvider.java (from r917266, wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/TestExpirePage.java)
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/IPageManagerProvider.java?p2=wicket/trunk/wicket/src/main/java/org/apache/wicket/IPageManagerProvider.java&p1=wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/TestExpirePage.java&r1=917266&r2=917331&rev=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/protocol/http/TestExpirePage.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/IPageManagerProvider.java Mon Mar 1 00:01:57 2010
@@ -1,48 +1,25 @@
-/*
- * 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.protocol.http;
-
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.markup.html.WebPage;
-
-/**
- * Test page for session expiry (/ page not found).
- */
-public class TestExpirePage extends WebPage
-{
- private static final long serialVersionUID = 1L;
-
- /**
- * Construct.
- */
- public TestExpirePage()
- {
-
- add(new AjaxLink("link")
- {
- private static final long serialVersionUID = 1L;
-
- @Override
- public void onClick(AjaxRequestTarget target)
- {
- target.addComponent(this);
- }
- });
- }
-
-}
+/*
+ * 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.pageStore.IPageManager;
+import org.apache.wicket.pageStore.IPageManagerContext;
+
+public interface IPageManagerProvider
+{
+ IPageManager get(IPageManagerContext context);
+}
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/IPageManagerProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/IPageManagerProvider.java
------------------------------------------------------------------------------
svn:executable = *
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/IPageManagerProvider.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/DefaultExceptionMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/DefaultExceptionMapper.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/DefaultExceptionMapper.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/DefaultExceptionMapper.java Mon Mar 1 00:01:57 2010
@@ -22,6 +22,7 @@
import org.apache.wicket.ng.request.handler.PageProvider;
import org.apache.wicket.ng.request.handler.impl.RenderPageRequestHandler;
import org.apache.wicket.ng.request.mapper.StalePageException;
+import org.apache.wicket.protocol.http.PageExpiredException;
public class DefaultExceptionMapper implements IExceptionMapper
{
@@ -33,6 +34,12 @@
// If the page was stale, just rerender it
return new RenderPageRequestHandler(new PageProvider(((StalePageException)e).getPage()));
}
+ else if (e instanceof PageExpiredException)
+ {
+ return new RenderPageRequestHandler(new PageProvider(Application.get()
+ .getApplicationSettings()
+ .getPageExpiredErrorPage()));
+ }
else
{
return new RenderPageRequestHandler(new PageProvider(Application.get()
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockApplication.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockApplication.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockApplication.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockApplication.java Mon Mar 1 00:01:57 2010
@@ -16,12 +16,14 @@
*/
package org.apache.wicket.ng.mock;
+import org.apache.wicket.IPageManagerProvider;
import org.apache.wicket.Page;
import org.apache.wicket.Session;
import org.apache.wicket.pageStore.IPageManager;
import org.apache.wicket.pageStore.IPageManagerContext;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.session.ISessionStore;
+import org.apache.wicket.util.IProvider;
public class MockApplication extends WebApplication
{
@@ -43,29 +45,43 @@
}
- @Override
- protected IPageManager newPageManager(IPageManagerContext context)
+ public Session getSession()
{
- return new MockPageManager(context);
+ return getSessionStore().lookup(null);
}
- /**
- * @see org.apache.wicket.ng.protocol.http.WebApplication#newSessionStore()
- */
@Override
- public ISessionStore newSessionStore()
+ public final String getInitParameter(String key)
{
- return new MockSessionStore();
+ return null;
}
- public Session getSession()
+ @Override
+ protected void internalInit()
{
- return getSessionStore().lookup(null);
+ super.internalInit();
+ setSessionStoreProvider(new MockSessionStoreProvider());
+ setPageManagerProvider(new MockPageManagerProvider());
}
- @Override
- public final String getInitParameter(String key)
+ private static class MockSessionStoreProvider implements IProvider<ISessionStore>
{
- return null;
+
+ public ISessionStore get()
+ {
+ return new MockSessionStore();
+ }
+
}
+ private static class MockPageManagerProvider implements IPageManagerProvider
+ {
+
+ public IPageManager get(IPageManagerContext context)
+ {
+ return new MockPageManager(context);
+ }
+
+
+ }
+
}
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockPageManager.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockPageManager.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockPageManager.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockPageManager.java Mon Mar 1 00:01:57 2010
@@ -56,10 +56,12 @@
public void newSessionCreated()
{
+ pages.clear();
}
public void sessionExpired(String sessionId)
{
+ pages.clear();
}
public void setContext(IPageManagerContext context)
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockWebResponse.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockWebResponse.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockWebResponse.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/mock/MockWebResponse.java Mon Mar 1 00:01:57 2010
@@ -273,7 +273,14 @@
}
else
{
- return binaryResponse.toByteArray();
+ byte[] bytes = binaryResponse.toByteArray();
+ if (getContentLength() != null)
+ {
+ byte[] trimmed = new byte[getContentLength().intValue()];
+ System.arraycopy(bytes, 0, trimmed, 0, getContentLength().intValue());
+ return trimmed;
+ }
+ return bytes;
}
}
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java Mon Mar 1 00:01:57 2010
@@ -16,6 +16,7 @@
*/
package org.apache.wicket.ng.request.mapper;
+import org.apache.wicket.Application;
import org.apache.wicket.IRequestHandler;
import org.apache.wicket.Request;
import org.apache.wicket.ng.request.Url;
@@ -69,6 +70,16 @@
public IRequestHandler mapRequest(Request request)
{
Url url = request.getUrl();
+
+ for (int i = 0; i < url.getSegments().size(); i++)
+ {
+ if (url.getSegments().get(i).equals(
+ Application.get().getResourceSettings().getParentFolderPlaceholder()))
+ {
+ url.getSegments().set(i, "..");
+ }
+ }
+
if (url.getSegments().size() >= 4 &&
urlStartsWith(url, getContext().getNamespace(), getContext().getResourceIdentifier()))
{
@@ -142,6 +153,19 @@
parameters.clearIndexedParameters();
url = encodePageParameters(url, parameters, pageParametersEncoder);
}
+
+ final CharSequence placeholder = Application.get()
+ .getResourceSettings()
+ .getParentFolderPlaceholder();
+
+ for (int i = 0; i < url.getSegments().size(); i++)
+ {
+ if ("..".equals(url.getSegments().get(i)))
+ {
+ url.getSegments().set(i, placeholder.toString());
+ }
+ }
+
return url;
}
return null;
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/RequestUtils.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/RequestUtils.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/RequestUtils.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/RequestUtils.java Mon Mar 1 00:01:57 2010
@@ -135,7 +135,7 @@
* @param path
* @return path string with double dots removed
*/
- static String removeDoubleDots(String path)
+ public static String removeDoubleDots(String path)
{
List<String> newcomponents = new ArrayList<String>(Arrays.asList(path.split("/")));
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java Mon Mar 1 00:01:57 2010
@@ -46,6 +46,7 @@
import org.apache.wicket.ng.resource.ResourceReference;
import org.apache.wicket.session.HttpSessionStore;
import org.apache.wicket.session.ISessionStore;
+import org.apache.wicket.util.IProvider;
import org.apache.wicket.util.collections.MostRecentlyUsedMap;
import org.apache.wicket.util.file.FileCleaner;
import org.apache.wicket.util.file.IResourceFinder;
@@ -440,7 +441,7 @@
}
setPageRendererProvider(new WebPageRendererProvider());
-
+ setSessionStoreProvider(new WebSessionStoreProvider());
// Configure the app.
configure();
}
@@ -510,16 +511,6 @@
}
/**
- * @see org.apache.wicket.Application#newSessionStore()
- */
- @Override
- protected ISessionStore newSessionStore()
- {
- return new HttpSessionStore();
- }
-
-
- /**
* Creates a new ajax request target used to control ajax responses
*
* @param page
@@ -671,6 +662,15 @@
{
return new WebPageRenderer(handler);
}
+ }
+
+ private static class WebSessionStoreProvider implements IProvider<ISessionStore>
+ {
+
+ public ISessionStore get()
+ {
+ return new HttpSessionStore();
+ }
}
}
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java?rev=917331&r1=917330&r2=917331&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java Mon Mar 1 00:01:57 2010
@@ -366,9 +366,16 @@
foundUrlPattern = n.getTextContent();
}
}
+
+ if (foundFilterName != null)
+ {
+ foundFilterName = foundFilterName.trim();
+ }
+
+
if (filterName.equals(foundFilterName))
{
- return foundUrlPattern;
+ return (foundUrlPattern != null) ? foundUrlPattern.trim() : null;
}
else
{
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletRequest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletRequest.java?rev=917331&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletRequest.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletRequest.java Mon Mar 1 00:01:57 2010
@@ -0,0 +1,1505 @@
+/*
+ * 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.protocol.http.mock;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.protocol.http.RequestUtils;
+import org.apache.wicket.protocol.http.WicketURLDecoder;
+import org.apache.wicket.protocol.http.WicketURLEncoder;
+import org.apache.wicket.util.file.File;
+import org.apache.wicket.util.io.IOUtils;
+import org.apache.wicket.util.upload.FileUploadBase;
+import org.apache.wicket.util.value.ValueMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Mock servlet request. Implements all of the methods from the standard HttpServletRequest class
+ * plus helper methods to aid setting up a request.
+ *
+ * @author Chris Turner
+ */
+public class MockHttpServletRequest implements HttpServletRequest
+{
+ /**
+ * A holder class for an uploaded file.
+ *
+ * @author Frank Bille (billen)
+ */
+ private class UploadedFile
+ {
+ private String fieldName;
+ private File file;
+ private String contentType;
+
+ /**
+ * Construct.
+ *
+ * @param fieldName
+ * @param file
+ * @param contentType
+ */
+ public UploadedFile(String fieldName, File file, String contentType)
+ {
+ this.fieldName = fieldName;
+ this.file = file;
+ this.contentType = contentType;
+ }
+
+ /**
+ * @return The content type of the file. Mime type.
+ */
+ public String getContentType()
+ {
+ return contentType;
+ }
+
+ /**
+ * @param contentType
+ * The content type.
+ */
+ public void setContentType(String contentType)
+ {
+ this.contentType = contentType;
+ }
+
+ /**
+ * @return The field name.
+ */
+ public String getFieldName()
+ {
+ return fieldName;
+ }
+
+ /**
+ * @param fieldName
+ */
+ public void setFieldName(String fieldName)
+ {
+ this.fieldName = fieldName;
+ }
+
+ /**
+ * @return The uploaded file.
+ */
+ public File getFile()
+ {
+ return file;
+ }
+
+ /**
+ * @param file
+ */
+ public void setFile(File file)
+ {
+ this.file = file;
+ }
+ }
+
+ /** Logging object */
+ private static final Logger log = LoggerFactory.getLogger(MockHttpServletRequest.class);
+
+ /** The application */
+ private final Application application;
+
+ private final ValueMap attributes = new ValueMap();
+
+ private String authType;
+
+ private String characterEncoding;
+
+ private final ServletContext context;
+
+ private final List<Cookie> cookies = new ArrayList<Cookie>();
+
+ private final ValueMap headers = new ValueMap();
+
+ private String method;
+
+ private final ValueMap parameters = new ValueMap();
+
+ private String path;
+
+ private final HttpSession session;
+
+ private String url;
+
+ private Map<String, UploadedFile> uploadedFiles;
+
+ private boolean useMultiPartContentType;
+
+ /**
+ * Create the request using the supplied session object. Note that in order for temporary
+ * sessions to work, the supplied session must be an instance of {@link MockHttpSession}
+ *
+ * @param application
+ * The application that this request is for
+ * @param session
+ * The session object
+ * @param context
+ * The current servlet context
+ */
+ public MockHttpServletRequest(final Application application, final HttpSession session,
+ final ServletContext context)
+ {
+ this.application = application;
+ this.session = session;
+ this.context = context;
+ initialize();
+ }
+
+ /**
+ * Add a new cookie.
+ *
+ * @param cookie
+ * The cookie
+ */
+ public void addCookie(final Cookie cookie)
+ {
+ cookies.add(cookie);
+ }
+
+ public void addCookies(Iterable<Cookie> cookies)
+ {
+ for (Cookie cookie : cookies)
+ {
+ addCookie(cookie);
+ }
+ }
+
+
+ /**
+ * Add an uploaded file to the request. Use this to simulate a file that has been uploaded to a
+ * field.
+ *
+ * @param fieldName
+ * The fieldname of the upload field.
+ * @param file
+ * The file to upload.
+ * @param contentType
+ * The content type of the file. Must be a correct mimetype.
+ */
+ public void addFile(String fieldName, File file, String contentType)
+ {
+ if (file == null)
+ {
+ throw new IllegalArgumentException("File must not be null");
+ }
+
+ if (file.exists() == false)
+ {
+ throw new IllegalArgumentException(
+ "File does not exists. You must provide an existing file: " +
+ file.getAbsolutePath());
+ }
+
+ if (file.isFile() == false)
+ {
+ throw new IllegalArgumentException(
+ "You can only add a File, which is not a directory. Only files can be uploaded.");
+ }
+
+ if (uploadedFiles == null)
+ {
+ uploadedFiles = new HashMap<String, UploadedFile>();
+ }
+
+ UploadedFile uf = new UploadedFile(fieldName, file, contentType);
+
+ uploadedFiles.put(fieldName, uf);
+ }
+
+ /**
+ * Add a header to the request.
+ *
+ * @param name
+ * The name of the header to add
+ * @param value
+ * The value
+ */
+ public void addHeader(String name, String value)
+ {
+ @SuppressWarnings("unchecked")
+ List<String> list = (List<String>)headers.get(name);
+ if (list == null)
+ {
+ list = new ArrayList<String>(1);
+ headers.put(name, list);
+ }
+ list.add(value);
+ }
+
+ /**
+ * @param name
+ * @param date
+ */
+ public void addDateHeader(String name, long date)
+ {
+ DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
+ String dateString = df.format(new Date(date));
+ addHeader(name, dateString);
+ }
+
+ /**
+ * Get an attribute.
+ *
+ * @param name
+ * The attribute name
+ * @return The value, or null
+ */
+ public Object getAttribute(final String name)
+ {
+ return attributes.get(name);
+ }
+
+ /**
+ * Get the names of all of the values.
+ *
+ * @return The names
+ */
+ public Enumeration<String> getAttributeNames()
+ {
+ return Collections.enumeration(attributes.keySet());
+ }
+
+ // HttpServletRequest methods
+
+ /**
+ * Get the auth type.
+ *
+ * @return The auth type
+ */
+ public String getAuthType()
+ {
+ return authType;
+ }
+
+ /**
+ * Get the current character encoding.
+ *
+ * @return The character encoding
+ */
+ public String getCharacterEncoding()
+ {
+ return characterEncoding;
+ }
+
+ /**
+ * true will force Request generate multiPart ContentType and ContentLength
+ *
+ * @param useMultiPartContentType
+ */
+ public void setUseMultiPartContentType(boolean useMultiPartContentType)
+ {
+ this.useMultiPartContentType = useMultiPartContentType;
+ }
+
+
+ /**
+ * Return the length of the content. This is always -1 except if useMultiPartContentType set as
+ * true. Then the length will be the length of the generated request.
+ *
+ * @return -1 if useMultiPartContentType is false. Else the length of the generated request.
+ */
+ public int getContentLength()
+ {
+ if (useMultiPartContentType)
+ {
+ byte[] request = buildRequest();
+ return request.length;
+ }
+
+ return -1;
+ }
+
+ /**
+ * If useMultiPartContentType set as true return the correct content-type.
+ *
+ * @return The correct multipart content-type if useMultiPartContentType is true. Else null.
+ */
+ public String getContentType()
+ {
+ if (useMultiPartContentType)
+ {
+ return FileUploadBase.MULTIPART_FORM_DATA + "; boundary=abcdefgABCDEFG";
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the context path. For this mock implementation the name of the application is always
+ * returned.
+ *
+ * @return The context path
+ */
+ public String getContextPath()
+ {
+ return "/" + application.getName();
+ }
+
+ /**
+ * Get all of the cookies for this request.
+ *
+ * @return The cookies
+ */
+ public Cookie[] getCookies()
+ {
+ if (cookies.size() == 0)
+ {
+ return null;
+ }
+ Cookie[] result = new Cookie[cookies.size()];
+ return cookies.toArray(result);
+ }
+
+ /**
+ * Get the given header as a date.
+ *
+ * @param name
+ * The header name
+ * @return The date, or -1 if header not found
+ * @throws IllegalArgumentException
+ * If the header cannot be converted
+ */
+ public long getDateHeader(final String name) throws IllegalArgumentException
+ {
+ String value = getHeader(name);
+ if (value == null)
+ {
+ return -1;
+ }
+
+ DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
+ try
+ {
+ return df.parse(value).getTime();
+ }
+ catch (ParseException e)
+ {
+ throw new IllegalArgumentException("Can't convert header to date " + name + ": " +
+ value);
+ }
+ }
+
+ /**
+ * Get the given header value.
+ *
+ * @param name
+ * The header name
+ * @return The header value or null
+ */
+ public String getHeader(final String name)
+ {
+ @SuppressWarnings("unchecked")
+ final List<String> l = (List<String>)headers.get(name);
+ if (l == null || l.size() < 1)
+ {
+ return null;
+ }
+ else
+ {
+ return l.get(0);
+ }
+ }
+
+ /**
+ * Get the names of all of the headers.
+ *
+ * @return The header names
+ */
+ public Enumeration<String> getHeaderNames()
+ {
+ return Collections.enumeration(headers.keySet());
+ }
+
+ /**
+ * Get enumeration of all header values with the given name.
+ *
+ * @param name
+ * The name
+ * @return The header values
+ */
+ public Enumeration<String> getHeaders(final String name)
+ {
+ @SuppressWarnings("unchecked")
+ List<String> list = (List<String>)headers.get(name);
+ if (list == null)
+ {
+ list = new ArrayList<String>();
+ }
+ return Collections.enumeration(list);
+ }
+
+ /**
+ * Returns an input stream if there has been added some uploaded files. Use
+ * {@link #addFile(String, File, String)} to add some uploaded files.
+ *
+ * @return The input stream
+ * @throws IOException
+ * If an I/O related problem occurs
+ */
+ public ServletInputStream getInputStream() throws IOException
+ {
+ byte[] request = buildRequest();
+
+ // Ok lets make an input stream to return
+ final ByteArrayInputStream bais = new ByteArrayInputStream(request);
+
+ return new ServletInputStream()
+ {
+ @Override
+ public int read()
+ {
+ return bais.read();
+ }
+ };
+ }
+
+ /**
+ * Get the given header as an int.
+ *
+ * @param name
+ * The header name
+ * @return The header value or -1 if header not found
+ * @throws NumberFormatException
+ * If the header is not formatted correctly
+ */
+ public int getIntHeader(final String name)
+ {
+ String value = getHeader(name);
+ if (value == null)
+ {
+ return -1;
+ }
+ return Integer.valueOf(value).intValue();
+ }
+
+ /**
+ * Get the locale of the request. Attempts to decode the Accept-Language header and if not found
+ * returns the default locale of the JVM.
+ *
+ * @return The locale
+ */
+ public Locale getLocale()
+ {
+ return getLocales().nextElement();
+ }
+
+ /**
+ *
+ * @param value
+ * @return locale
+ */
+ private Locale getLocale(final String value)
+ {
+ final String[] bits = value.split("-");
+ if (bits.length < 1)
+ {
+ return null;
+ }
+
+ final String language = bits[0].toLowerCase();
+ if (bits.length > 1)
+ {
+ final String country = bits[1].toUpperCase();
+ return new Locale(language, country);
+ }
+ else
+ {
+ return new Locale(language);
+ }
+ }
+
+ /**
+ * Return all the accepted locales. This implementation always returns just one.
+ *
+ * @return The locales
+ */
+ public Enumeration<Locale> getLocales()
+ {
+ List<Locale> list = new ArrayList<Locale>();
+ final String header = getHeader("Accept-Language");
+ if (header != null)
+ {
+ final String[] locales = header.split(",");
+ for (String value : locales)
+ {
+ Locale locale = getLocale(value);
+ if (locale != null)
+ {
+ list.add(locale);
+ }
+ }
+ }
+
+ if (list.size() == 0)
+ {
+ list.add(Locale.getDefault());
+ }
+
+ return Collections.enumeration(list);
+ }
+
+ /**
+ * Get the method.
+ *
+ * @return The method
+ */
+ public String getMethod()
+ {
+ return method;
+ }
+
+ /**
+ * Get the request parameter with the given name.
+ *
+ * @param name
+ * The parameter name
+ * @return The parameter value, or null
+ */
+ public String getParameter(final String name)
+ {
+ return parameters.getString(name);
+ }
+
+ /**
+ * Get the map of all of the parameters.
+ *
+ * @return The parameters
+ */
+ public Map<String, Object> getParameterMap()
+ {
+ return parameters;
+ }
+
+ /**
+ * Get the names of all of the parameters.
+ *
+ * @return The parameter names
+ */
+ public Enumeration<String> getParameterNames()
+ {
+ return Collections.enumeration(parameters.keySet());
+ }
+
+ /**
+ * Get the values for the given parameter.
+ *
+ * @param name
+ * The name of the parameter
+ * @return The return values
+ */
+ public String[] getParameterValues(final String name)
+ {
+ Object value = parameters.get(name);
+ if (value == null)
+ {
+ return new String[0];
+ }
+
+ if (value instanceof String[])
+ {
+ return (String[])value;
+ }
+ else
+ {
+ String[] result = new String[1];
+ result[0] = value.toString();
+ return result;
+ }
+ }
+
+ /**
+ * Get the path info.
+ *
+ * @return The path info
+ */
+ public String getPathInfo()
+ {
+ return path;
+ }
+
+ /**
+ * Always returns null.
+ *
+ * @return null
+ */
+ public String getPathTranslated()
+ {
+ return null;
+ }
+
+ /**
+ * Get the protocol.
+ *
+ * @return Always HTTP/1.1
+ */
+ public String getProtocol()
+ {
+ return "HTTP/1.1";
+ }
+
+ /**
+ * Get the query string part of the request.
+ *
+ * @return The query string
+ */
+ public String getQueryString()
+ {
+ if (parameters.size() == 0)
+ {
+ return null;
+ }
+ else
+ {
+ final StringBuffer buf = new StringBuffer();
+ for (Iterator<String> iterator = parameters.keySet().iterator(); iterator.hasNext();)
+ {
+ final String name = iterator.next();
+ final String value = parameters.getString(name);
+ if (name != null)
+ {
+ buf.append(WicketURLEncoder.QUERY_INSTANCE.encode(name));
+ }
+ buf.append('=');
+ if (value != null)
+ {
+ buf.append(WicketURLEncoder.QUERY_INSTANCE.encode(value));
+ }
+ if (iterator.hasNext())
+ {
+ buf.append('&');
+ }
+ }
+ return buf.toString();
+ }
+ }
+
+ /**
+ * This feature is not implemented at this time as we are not supporting binary servlet input.
+ * This functionality may be added in the future.
+ *
+ * @return The reader
+ * @throws IOException
+ * If an I/O related problem occurs
+ */
+ public BufferedReader getReader() throws IOException
+ {
+ return new BufferedReader(new CharArrayReader(new char[0]));
+ }
+
+ /**
+ * Deprecated method - should not be used.
+ *
+ * @param name
+ * The name
+ * @return The path
+ * @deprecated Use ServletContext.getRealPath(String) instead.
+ */
+ @Deprecated
+ public String getRealPath(String name)
+ {
+ return context.getRealPath(name);
+ }
+
+ /**
+ * Get the remote address of the client.
+ *
+ * @return Always 127.0.0.1
+ */
+ public String getRemoteAddr()
+ {
+ return "127.0.0.1";
+ }
+
+ /**
+ * Get the remote host.
+ *
+ * @return Always localhost
+ */
+ public String getRemoteHost()
+ {
+ return "localhost";
+ }
+
+ /**
+ * Get the name of the remote user from the REMOTE_USER header.
+ *
+ * @return The name of the remote user
+ */
+ public String getRemoteUser()
+ {
+ return getHeader("REMOTE_USER");
+ }
+
+ /**
+ * Return a dummy dispatcher that just records that dispatch has occurred without actually doing
+ * anything.
+ *
+ * @param name
+ * The name to dispatch to
+ * @return The dispatcher
+ */
+ public RequestDispatcher getRequestDispatcher(String name)
+ {
+ return context.getRequestDispatcher(name);
+ }
+
+ /**
+ * Get the requested session id. Always returns the id of the current session.
+ *
+ * @return The session id
+ */
+ public String getRequestedSessionId()
+ {
+ if (session instanceof MockHttpSession && ((MockHttpSession)session).isTemporary())
+ {
+ return null;
+ }
+ return session.getId();
+ }
+
+ /**
+ * Returns context path and servlet path concatenated, typically
+ * /applicationClassName/applicationClassName
+ *
+ * @return The path value
+ * @see javax.servlet.http.HttpServletRequest#getRequestURI()
+ */
+ public String getRequestURI()
+ {
+ if (url == null)
+ {
+ return getContextPath() + getServletPath();
+ }
+ else
+ {
+ int index = url.indexOf("?");
+ if (index != -1)
+ {
+ return url.substring(0, index);
+ }
+ }
+ return url;
+ }
+
+ /**
+ * Try to build a rough URL.
+ *
+ * @return The url
+ */
+ public StringBuffer getRequestURL()
+ {
+ final StringBuffer buf = new StringBuffer();
+ buf.append("http://localhost");
+ buf.append(getContextPath());
+ if (getPathInfo() != null)
+ {
+ buf.append(getPathInfo());
+ }
+
+ final String query = getQueryString();
+ if (query != null)
+ {
+ buf.append('?');
+ buf.append(query);
+ }
+ return buf;
+ }
+
+ /**
+ * Get the scheme.
+ *
+ * @return Always http
+ */
+ public String getScheme()
+ {
+ return "http";
+ }
+
+ /**
+ * Get the server name.
+ *
+ * @return Always localhost
+ */
+ public String getServerName()
+ {
+ return "localhost";
+ }
+
+ /**
+ * Get the server port.
+ *
+ * @return Always 80
+ */
+ public int getServerPort()
+ {
+ return 80;
+ }
+
+ /**
+ * The servlet path may either be the application name or /. For test purposes we always return
+ * the servlet name.
+ *
+ * @return The servlet path
+ */
+ public String getServletPath()
+ {
+ return getContextPath();
+ }
+
+ /**
+ * Get the sessions.
+ *
+ * @return The session
+ */
+ public HttpSession getSession()
+ {
+ if (session instanceof MockHttpSession && ((MockHttpSession)session).isTemporary())
+ {
+ return null;
+ }
+ return session;
+ }
+
+ /**
+ * Get the session.
+ *
+ * @param b
+ * Ignored, there is always a session
+ * @return The session
+ */
+ public HttpSession getSession(boolean b)
+ {
+ if (b && session instanceof MockHttpSession)
+ {
+ ((MockHttpSession)session).setTemporary(false);
+ }
+ return getSession();
+ }
+
+ /**
+ * Get the user principal.
+ *
+ * @return A user principal
+ */
+ public Principal getUserPrincipal()
+ {
+ final String user = getRemoteUser();
+ if (user == null)
+ {
+ return null;
+ }
+ else
+ {
+ return new Principal()
+ {
+ public String getName()
+ {
+ return user;
+ }
+ };
+ }
+ }
+
+ /**
+ * @return True if there has been added files to this request using
+ * {@link #addFile(String, File, String)}
+ */
+ public boolean hasUploadedFiles()
+ {
+ return uploadedFiles != null;
+ }
+
+ /**
+ * Reset the request back to a default state.
+ */
+ public void initialize()
+ {
+ authType = null;
+ method = "post";
+ cookies.clear();
+ setDefaultHeaders();
+ path = null;
+ url = null;
+ characterEncoding = "UTF-8";
+ parameters.clear();
+ attributes.clear();
+ }
+
+ /**
+ * Check whether session id is from a cookie. Always returns true.
+ *
+ * @return Always true
+ */
+ public boolean isRequestedSessionIdFromCookie()
+ {
+ return true;
+ }
+
+ /**
+ * Check whether session id is from a url rewrite. Always returns false.
+ *
+ * @return Always false
+ */
+ public boolean isRequestedSessionIdFromUrl()
+ {
+ return false;
+ }
+
+ /**
+ * Check whether session id is from a url rewrite. Always returns false.
+ *
+ * @return Always false
+ */
+ public boolean isRequestedSessionIdFromURL()
+ {
+ return false;
+ }
+
+ /**
+ * Check whether the session id is valid.
+ *
+ * @return Always true
+ */
+ public boolean isRequestedSessionIdValid()
+ {
+ return true;
+ }
+
+ /**
+ * Always returns false.
+ *
+ * @return Always false
+ */
+ public boolean isSecure()
+ {
+ return false;
+ }
+
+ /**
+ * NOT IMPLEMENTED.
+ *
+ * @param name
+ * The role name
+ * @return Always false
+ */
+ public boolean isUserInRole(String name)
+ {
+ return false;
+ }
+
+ /**
+ * Remove the given attribute.
+ *
+ * @param name
+ * The name of the attribute
+ */
+ public void removeAttribute(final String name)
+ {
+ attributes.remove(name);
+ }
+
+ /**
+ * Set the given attribute.
+ *
+ * @param name
+ * The attribute name
+ * @param o
+ * The value to set
+ */
+ public void setAttribute(final String name, final Object o)
+ {
+ attributes.put(name, o);
+ }
+
+ /**
+ * Set the auth type.
+ *
+ * @param authType
+ * The auth type
+ */
+ public void setAuthType(final String authType)
+ {
+ this.authType = authType;
+ }
+
+ /**
+ * Set the character encoding.
+ *
+ * @param encoding
+ * The character encoding
+ * @throws UnsupportedEncodingException
+ * If encoding not supported
+ */
+ public void setCharacterEncoding(final String encoding) throws UnsupportedEncodingException
+ {
+ characterEncoding = encoding;
+ }
+
+ /**
+ * Set the cookies.
+ *
+ * @param theCookies
+ * The cookies
+ */
+ public void setCookies(final Cookie[] theCookies)
+ {
+ cookies.clear();
+ for (int i = 0; i < theCookies.length; i++)
+ {
+ cookies.add(theCookies[i]);
+ }
+ }
+
+ /**
+ * Set the method.
+ *
+ * @param method
+ * The method
+ */
+ public void setMethod(final String method)
+ {
+ this.method = method;
+ }
+
+ /**
+ * Set a parameter.
+ *
+ * @param name
+ * The name
+ * @param value
+ * The value
+ */
+ public void setParameter(final String name, final String value)
+ {
+ parameters.put(name, value);
+ }
+
+ /**
+ * Sets a map of parameters.
+ *
+ * @param parameters
+ * the parameters to set
+ */
+ public void setParameters(final Map<String, String[]> parameters)
+ {
+ this.parameters.putAll(parameters);
+ }
+
+ /**
+ * Set the path that this request is supposed to be serving. The path is relative to the web
+ * application root and should start with a / character
+ *
+ * @param path
+ */
+ public void setPath(final String path)
+ {
+ this.path = WicketURLDecoder.PATH_INSTANCE.decode(path);
+ }
+
+ /**
+ * Set the complete url for this request. The url will be analyzed.
+ *
+ * @param url
+ */
+ public void setURL(String url)
+ {
+ if (url.startsWith("http://"))
+ {
+ int index = url.indexOf("/", 7);
+ url = url.substring(index);
+ }
+ if (!url.startsWith("/"))
+ {
+ url = getContextPath() + getServletPath() + "/" + url;
+ }
+ this.url = url;
+ if (url.startsWith(getContextPath()))
+ {
+ url = url.substring(getContextPath().length());
+ }
+ if (url.startsWith(getServletPath()))
+ {
+ url = url.substring(getServletPath().length());
+ }
+
+ int index = url.indexOf("?");
+ if (index == -1)
+ {
+ setPath(url);
+ }
+ else
+ {
+ setPath(url.substring(0, index));
+
+ String queryString = url.substring(index + 1);
+ Map<String, String[]> params = new HashMap<String, String[]>();
+ RequestUtils.decodeUrlParameters(queryString, params);
+ parameters.putAll(params);
+ }
+ }
+
+// /**
+// * Initialize the request parameters to point to the given bookmarkable page.
+// *
+// * @param page
+// * The page to point to
+// * @param params
+// * Additional parameters
+// */
+// public void setRequestToBookmarkablePage(final Page page, final Map<String, Object> params)
+// {
+// parameters.putAll(params);
+// parameters.put(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME, page.getClass()
+// .getName());
+// }
+//
+// /**
+// * Initialize the request parameters to point to the given component.
+// *
+// * @param component
+// * The component
+// */
+// public void setRequestToComponent(final Component component)
+// {
+// final IPageMap pageMap = component.getPage().getPageMap();
+// final String pageMapName = pageMap.isDefault() ? "" : pageMap.getName();
+// if (component instanceof BookmarkablePageLink)
+// {
+// final Class<? extends Page> clazz = ((BookmarkablePageLink<?>)component).getPageClass();
+// parameters.put(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME, pageMapName +
+// ':' + clazz.getName());
+// }
+// else
+// {
+// int version = component.getPage().getCurrentVersionNumber();
+// Class<?> clazz = null;
+// if (component instanceof IRedirectListener)
+// {
+// clazz = IRedirectListener.class;
+// }
+// else if (component instanceof IResourceListener)
+// {
+// clazz = IResourceListener.class;
+// }
+// else if (component instanceof IFormSubmitListener)
+// {
+// clazz = IFormSubmitListener.class;
+// }
+// else if (component instanceof ILinkListener)
+// {
+// clazz = ILinkListener.class;
+// }
+// else if (component instanceof IOnChangeListener)
+// {
+// clazz = IOnChangeListener.class;
+// }
+// else
+// {
+// throw new IllegalArgumentException(
+// "The component class doesn't seem to implement any of the known *Listener interfaces: " +
+// component.getClass());
+// }
+//
+// // manually create the url using default strategy and format
+// parameters.put(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME, pageMapName + ':' +
+// component.getPath() + ':' + (version == 0 ? "" : "" + version) + ':' +
+// Classes.simpleName(clazz) + "::");
+//
+// // see if we can replace our manual listener url with a properly generated one...
+//
+// try
+// {
+// RequestListenerInterface rli = (RequestListenerInterface)clazz.getField("INTERFACE")
+// .get(clazz);
+//
+// String auto = component.getRequestCycle().urlFor(component, rli).toString();
+//
+// // check for crypted strategy
+// if (auto.startsWith("?x="))
+// {
+// auto = auto.substring(3);
+// parameters.put("x", auto);
+// parameters.remove(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME);
+// }
+// else
+// {
+// int idx = auto.indexOf(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME);
+// if (idx >= 0)
+// {
+// auto = auto.substring(idx +
+// WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME.length() + 1);
+// }
+// else
+// {
+// idx = auto.indexOf("&");
+// if (idx >= 0)
+// {
+// auto = auto.substring(0, idx);
+// }
+// }
+// parameters.put(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME, auto);
+// }
+// }
+// catch (Exception e)
+// {
+// // noop
+// }
+//
+// if (component.isStateless() && component.getPage().isBookmarkable())
+// {
+// parameters.put(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME,
+// pageMapName + ':' + component.getPage().getClass().getName());
+// }
+// }
+// }
+
+// /**
+// * Initialize the request parameters to point to the given form component. The additional map
+// * should contain mappings between individual components that appear in the form and the string
+// * value that should be submitted for each of these components.
+// *
+// * @param form
+// * The for to send the request to
+// * @param values
+// * The values for each of the form components
+// */
+// public void setRequestToFormComponent(final Form<?> form, final Map<String, Object> values)
+// {
+// setRequestToComponent(form);
+//
+// final Map<String, Object> valuesApplied = new HashMap<String, Object>();
+// form.visitChildren(FormComponent.class, new Component.IVisitor<FormComponent<?>>()
+// {
+// public Object component(final FormComponent<?> component)
+// {
+// String value = (String)values.get(component);
+// if (value != null)
+// {
+// parameters.put(component.getInputName(), values.get(component));
+// valuesApplied.put(component.getId(), component);
+// }
+// return CONTINUE_TRAVERSAL;
+// }
+// });
+//
+// if (values.size() != valuesApplied.size())
+// {
+// Map<String, Object> diff = new HashMap<String, Object>();
+// diff.putAll(values);
+//
+// Iterator<String> iter = valuesApplied.keySet().iterator();
+// while (iter.hasNext())
+// {
+// diff.remove(iter.next());
+// }
+//
+// log.error("Parameter mismatch: didn't find all components referenced in parameter 'values': " +
+// diff.keySet());
+// }
+// }
+
+ /**
+ * Initialize the request parameters from the given redirect string that redirects back to a
+ * particular component for display.
+ *
+ * @param redirect
+ * The redirect string to display from
+ */
+ public void setRequestToRedirectString(final String redirect)
+ {
+ parameters.clear();
+
+ int queryStringPos = redirect.indexOf('?');
+
+ // Decode the parameters
+ if (queryStringPos != -1)
+ {
+ final String queryString = redirect.substring(queryStringPos + 1);
+ RequestUtils.decodeParameters(queryString, parameters);
+ }
+
+ // We need to absolutize the redirect URL as we are not as smart as a web-browser
+ // (WICKET-702)
+ url = redirect;
+ if ((url.length() == 0) || (url.charAt(0) != '/'))
+ {
+ url = getContextPath() + getServletPath() + "/" + redirect;
+ }
+
+ // Remove occurrences of ".." from the path
+ url = RequestUtils.removeDoubleDots(url);
+ log.info("Redirecting to " + url);
+ }
+
+ /**
+ * Helper method to create some default headers for the request
+ */
+ private void setDefaultHeaders()
+ {
+ headers.clear();
+ addHeader("Accept", "text/xml,application/xml,application/xhtml+xml,"
+ + "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
+ addHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
+ Locale l = Locale.getDefault();
+ addHeader("Accept-Language", l.getLanguage().toLowerCase() + "-" +
+ l.getCountry().toLowerCase() + "," + l.getLanguage().toLowerCase() + ";q=0.5");
+ addHeader("User-Agent",
+ "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040707 Firefox/0.9.2");
+ }
+
+ private static final String crlf = "\r\n";
+ private static final String boundary = "--abcdefgABCDEFG";
+
+ private void newAttachment(OutputStream out) throws IOException
+ {
+ out.write(boundary.getBytes());
+ out.write(crlf.getBytes());
+ out.write("Content-Disposition: form-data".getBytes());
+ }
+
+ /**
+ * Build the request based on the uploaded files and the parameters.
+ *
+ * @return The request as a string.
+ */
+ private byte[] buildRequest()
+ {
+ try
+ {
+ // Build up the input stream based on the files and parameters
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ // Add parameters
+ for (Iterator<String> iterator = parameters.keySet().iterator(); iterator.hasNext();)
+ {
+ final String name = iterator.next();
+ newAttachment(out);
+ out.write("; name=\"".getBytes());
+ out.write(name.getBytes());
+ out.write("\"".getBytes());
+ out.write(crlf.getBytes());
+ out.write(crlf.getBytes());
+ out.write(parameters.get(name).toString().getBytes());
+ out.write(crlf.getBytes());
+ }
+
+ // Add files
+ if (uploadedFiles != null)
+ {
+ for (Iterator<String> iterator = uploadedFiles.keySet().iterator(); iterator.hasNext();)
+ {
+ String fieldName = iterator.next();
+
+ UploadedFile uf = uploadedFiles.get(fieldName);
+
+ newAttachment(out);
+ out.write("; name=\"".getBytes());
+ out.write(fieldName.getBytes());
+ out.write("\"; filename=\"".getBytes());
+ out.write(uf.getFile().getName().getBytes());
+ out.write("\"".getBytes());
+ out.write(crlf.getBytes());
+ out.write("Content-Type: ".getBytes());
+ out.write(uf.getContentType().getBytes());
+ out.write(crlf.getBytes());
+ out.write(crlf.getBytes());
+
+ // Load the file and put it into the the inputstream
+ FileInputStream fis = new FileInputStream(uf.getFile());
+ IOUtils.copy(fis, out);
+ fis.close();
+ out.write(crlf.getBytes());
+ }
+ }
+
+ out.write(boundary.getBytes());
+ out.write("--".getBytes());
+ out.write(crlf.getBytes());
+ return out.toByteArray();
+ }
+ catch (IOException e)
+ {
+ // NOTE: IllegalStateException(Throwable) only exists since Java 1.5
+ throw new WicketRuntimeException(e);
+ }
+ }
+
+ /**
+ * @return local address
+ */
+ public String getLocalAddr()
+ {
+ return "127.0.0.1";
+ }
+
+ /**
+ * @return local host name
+ */
+ public String getLocalName()
+ {
+ return "127.0.0.1";
+ }
+
+ /**
+ * @return local port
+ */
+ public int getLocalPort()
+ {
+ return 80;
+ }
+
+ /**
+ * @return remote port
+ */
+ public int getRemotePort()
+ {
+ return 80;
+ }
+}
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletRequest.java
------------------------------------------------------------------------------
svn:executable = *
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletResponse.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletResponse.java?rev=917331&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletResponse.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletResponse.java Mon Mar 1 00:01:57 2010
@@ -0,0 +1,820 @@
+/*
+ * 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.protocol.http.mock;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TimeZone;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.wicket.protocol.http.RequestUtils;
+import org.apache.wicket.util.value.ValueMap;
+
+
+/**
+ * Mock servlet response. Implements all of the methods from the standard HttpServletResponse class
+ * plus helper methods to aid viewing the generated response.
+ *
+ * @author Chris Turner
+ */
+public class MockHttpServletResponse implements HttpServletResponse
+{
+ private static final int MODE_BINARY = 1;
+
+ private static final int MODE_NONE = 0;
+
+ private static final int MODE_TEXT = 2;
+
+ private ByteArrayOutputStream byteStream;
+
+ private String characterEncoding = "UTF-8";
+
+ private int code = HttpServletResponse.SC_OK;
+
+ private final List<Cookie> cookies = new ArrayList<Cookie>();
+
+ private String errorMessage = null;
+
+ private final ValueMap headers = new ValueMap();
+
+ private Locale locale = null;
+
+ private int mode = MODE_NONE;
+
+ private PrintWriter printWriter;
+
+ private String redirectLocation = null;
+
+ private ServletOutputStream servletStream;
+
+ private int status = HttpServletResponse.SC_OK;
+
+ private StringWriter stringWriter;
+
+ private final MockHttpServletRequest servletRequest;
+
+ /**
+ * Create the response object.
+ *
+ * @param servletRequest
+ */
+ public MockHttpServletResponse(MockHttpServletRequest servletRequest)
+ {
+ this.servletRequest = servletRequest;
+ initialize();
+ }
+
+ /**
+ * Add a cookie to the response.
+ *
+ * @param cookie
+ * The cookie to add
+ */
+ public void addCookie(final Cookie cookie)
+ {
+ // remove any potential duplicates
+ cookies.remove(cookie);
+ cookies.add(cookie);
+ }
+
+ /**
+ * Add a date header.
+ *
+ * @param name
+ * The header value
+ * @param l
+ * The long value
+ */
+ public void addDateHeader(String name, long l)
+ {
+ DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
+ addHeader(name, df.format(new Date(l)));
+ }
+
+ /**
+ * Add the given header value, including an additional entry if one already exists.
+ *
+ * @param name
+ * The name for the header
+ * @param value
+ * The value for the header
+ */
+ @SuppressWarnings("unchecked")
+ public void addHeader(final String name, final String value)
+ {
+ List<String> list = (List<String>)headers.get(name);
+ if (list == null)
+ {
+ list = new ArrayList<String>(1);
+ headers.put(name, list);
+ }
+ list.add(value);
+ }
+
+ /**
+ * Add an int header value.
+ *
+ * @param name
+ * The header name
+ * @param i
+ * The value
+ */
+ public void addIntHeader(final String name, final int i)
+ {
+ addHeader(name, "" + i);
+ }
+
+ /**
+ * Check if the response contains the given header name.
+ *
+ * @param name
+ * The name to check
+ * @return Whether header in response or not
+ */
+ public boolean containsHeader(final String name)
+ {
+ return headers.containsKey(name);
+ }
+
+ /**
+ * Encode the redirectLocation URL. Does no changes as this test implementation uses cookie
+ * based url tracking.
+ *
+ * @param url
+ * The url to encode
+ * @return The encoded url
+ */
+ public String encodeRedirectUrl(final String url)
+ {
+ return url;
+ }
+
+ /**
+ * Encode the redirectLocation URL. Does no changes as this test implementation uses cookie
+ * based url tracking.
+ *
+ * @param url
+ * The url to encode
+ * @return The encoded url
+ */
+ public String encodeRedirectURL(final String url)
+ {
+ return url;
+ }
+
+ /**
+ * Encode the URL. Does no changes as this test implementation uses cookie based url tracking.
+ *
+ * @param url
+ * The url to encode
+ * @return The encoded url
+ */
+ public String encodeUrl(final String url)
+ {
+ return url;
+ }
+
+ /**
+ * Encode the URL. Does no changes as this test implementation uses cookie based url tracking.
+ *
+ * @param url
+ * The url to encode
+ * @return The encoded url
+ */
+ public String encodeURL(final String url)
+ {
+ return url;
+ }
+
+ /**
+ * Flush the buffer.
+ *
+ * @throws IOException
+ */
+ public void flushBuffer() throws IOException
+ {
+ }
+
+ /**
+ * Get the binary content that was written to the servlet stream.
+ *
+ * @return The binary content
+ */
+ public byte[] getBinaryContent()
+ {
+ return byteStream.toByteArray();
+ }
+
+ /**
+ * Return the current buffer size
+ *
+ * @return The buffer size
+ */
+ public int getBufferSize()
+ {
+ if (mode == MODE_NONE)
+ {
+ return 0;
+ }
+ else if (mode == MODE_BINARY)
+ {
+ return byteStream.size();
+ }
+ else
+ {
+ return stringWriter.getBuffer().length();
+ }
+ }
+
+ /**
+ * Get the character encoding of the response.
+ *
+ * @return The character encoding
+ */
+ public String getCharacterEncoding()
+ {
+ return characterEncoding;
+ }
+
+ /**
+ * Get the response code for this request.
+ *
+ * @return The response code
+ */
+ public int getCode()
+ {
+ return code;
+ }
+
+ /**
+ * Get all of the cookies that have been added to the response.
+ *
+ * @return The collection of cookies
+ */
+ public Collection<Cookie> getCookies()
+ {
+ return cookies;
+ }
+
+ /**
+ * Get the text document that was written as part of this response.
+ *
+ * @return The document
+ */
+ public String getDocument()
+ {
+ if (mode == MODE_BINARY)
+ {
+ return new String(byteStream.toByteArray());
+ }
+ else
+ {
+ return stringWriter.getBuffer().toString();
+ }
+ }
+
+ /**
+ * Get the error message.
+ *
+ * @return The error message, or null if no message
+ */
+ public String getErrorMessage()
+ {
+ return errorMessage;
+ }
+
+ /**
+ * Return the value of the given named header.
+ *
+ * @param name
+ * The header name
+ * @return The value, or null
+ */
+ @SuppressWarnings("unchecked")
+ public String getHeader(final String name)
+ {
+ List<String> l = (List<String>)headers.get(name);
+ if (l == null || l.size() < 1)
+ {
+ return null;
+ }
+ else
+ {
+ return l.get(0);
+ }
+ }
+
+ /**
+ * Get the names of all of the headers.
+ *
+ * @return The header names
+ */
+ public Set<String> getHeaderNames()
+ {
+ return headers.keySet();
+ }
+
+ /**
+ * Get the encoded locale
+ *
+ * @return The locale
+ */
+ public Locale getLocale()
+ {
+ return locale;
+ }
+
+ /**
+ * Get the output stream for writing binary data from the servlet.
+ *
+ * @return The binary output stream.
+ */
+ public ServletOutputStream getOutputStream()
+ {
+ if (mode == MODE_TEXT)
+ {
+ throw new IllegalArgumentException("Can't write binary after already selecting text");
+ }
+ mode = MODE_BINARY;
+ return servletStream;
+ }
+
+ /**
+ * Get the location that was redirected to.
+ *
+ * @return The redirect location, or null if not a redirect
+ */
+ public String getRedirectLocation()
+ {
+ return redirectLocation;
+ }
+
+ /**
+ * Get the status code.
+ *
+ * @return The status code
+ */
+ public int getStatus()
+ {
+ return status;
+ }
+
+ /**
+ * Get the print writer for writing text output for this response.
+ *
+ * @return The writer
+ * @throws IOException
+ * Not used
+ */
+ public PrintWriter getWriter() throws IOException
+ {
+ if (mode == MODE_BINARY)
+ {
+ throw new IllegalArgumentException("Can't write text after already selecting binary");
+ }
+ mode = MODE_TEXT;
+ return printWriter;
+ }
+
+ /**
+ * Reset the response ready for reuse.
+ */
+ public void initialize()
+ {
+ cookies.clear();
+ headers.clear();
+ code = HttpServletResponse.SC_OK;
+ errorMessage = null;
+ redirectLocation = null;
+ status = HttpServletResponse.SC_OK;
+ characterEncoding = "UTF-8";
+ locale = null;
+
+ byteStream = new ByteArrayOutputStream();
+ servletStream = new ServletOutputStream()
+ {
+ @Override
+ public void write(int b)
+ {
+ byteStream.write(b);
+ }
+ };
+ stringWriter = new StringWriter();
+ printWriter = new PrintWriter(stringWriter)
+ {
+ @Override
+ public void close()
+ {
+ // Do nothing
+ }
+
+ @Override
+ public void flush()
+ {
+ // Do nothing
+ }
+ };
+ mode = MODE_NONE;
+ }
+
+ /**
+ * Always returns false.
+ *
+ * @return Always false
+ */
+ public boolean isCommitted()
+ {
+ return false;
+ }
+
+ /**
+ * Return whether the servlet returned an error code or not.
+ *
+ * @return Whether an error occurred or not
+ */
+ public boolean isError()
+ {
+ return (code != HttpServletResponse.SC_OK);
+ }
+
+ /**
+ * Check whether the response was redirected or not.
+ *
+ * @return Whether the state was redirected or not
+ */
+ public boolean isRedirect()
+ {
+ return (redirectLocation != null);
+ }
+
+ /**
+ * Delegate to initialize method.
+ */
+ public void reset()
+ {
+ initialize();
+ }
+
+ /**
+ * Clears the buffer.
+ */
+ public void resetBuffer()
+ {
+ if (mode == MODE_BINARY)
+ {
+ byteStream.reset();
+ }
+ else if (mode == MODE_TEXT)
+ {
+ stringWriter.getBuffer().delete(0, stringWriter.getBuffer().length());
+ }
+ }
+
+ /**
+ * Send an error code. This implementation just sets the internal error state information.
+ *
+ * @param code
+ * The code
+ * @throws IOException
+ * Not used
+ */
+ public void sendError(final int code) throws IOException
+ {
+ this.code = code;
+ errorMessage = null;
+ }
+
+ /**
+ * Send an error code. This implementation just sets the internal error state information.
+ *
+ * @param code
+ * The error code
+ * @param msg
+ * The error message
+ * @throws IOException
+ * Not used
+ */
+ public void sendError(final int code, final String msg) throws IOException
+ {
+ this.code = code;
+ errorMessage = msg;
+ }
+
+ /**
+ * @return url
+ * @see org.apache.wicket.Request#getURL()
+ */
+ private String getURL()
+ {
+ /*
+ * Servlet 2.3 specification :
+ *
+ * Servlet Path: The path section that directly corresponds to the mapping which activated
+ * this request. This path starts with a "/" character except in the case where the request
+ * is matched with the "/*" pattern, in which case it is the empty string.
+ *
+ * PathInfo: The part of the request path that is not part of the Context Path or the
+ * Servlet Path. It is either null if there is no extra path, or is a string with a leading
+ * "/".
+ */
+ String url = servletRequest.getServletPath();
+ final String pathInfo = servletRequest.getPathInfo();
+
+ if (pathInfo != null)
+ {
+ url += pathInfo;
+ }
+
+ final String queryString = servletRequest.getQueryString();
+
+ if (queryString != null)
+ {
+ url += ("?" + queryString);
+ }
+
+ // If url is non-empty it will start with '/', which we should lose
+ if (url.length() > 0 && url.charAt(0) == '/')
+ {
+ // Remove leading '/'
+ url = url.substring(1);
+ }
+ return url;
+ }
+
+ /**
+ * Indicate sending of a redirectLocation to a particular named resource. This implementation
+ * just keeps hold of the redirectLocation info and makes it available for query.
+ *
+ * @param location
+ * The location to redirectLocation to
+ * @throws IOException
+ * Not used
+ */
+ public void sendRedirect(String location) throws IOException
+ {
+ // If the location starts with ../
+ if (location.startsWith("../"))
+ {
+ // Test if the current url has a / in it. (a mount)
+ String url = getURL();
+ int index = url.lastIndexOf("/");
+ if (index != -1)
+ {
+ // Then we have to recalculate what the real redirect is for the next request
+ // which is just getContext() + getServletPath() + "/" + location;
+ url = url.substring(0, index + 1) + location;
+ url = RequestUtils.removeDoubleDots(url);
+
+ // stril the servlet path again from it.
+ index = url.indexOf("/");
+ location = url.substring(index + 1);
+ }
+ }
+ redirectLocation = location;
+ }
+
+ /**
+ * Method ignored.
+ *
+ * @param size
+ * The size
+ */
+ public void setBufferSize(final int size)
+ {
+ }
+
+ /**
+ * Set the character encoding.
+ *
+ * @param characterEncoding
+ * The character encoding
+ */
+ public void setCharacterEncoding(final String characterEncoding)
+ {
+ this.characterEncoding = characterEncoding;
+ }
+
+ /**
+ * Set the content length.
+ *
+ * @param length
+ * The length
+ */
+ public void setContentLength(final int length)
+ {
+ setIntHeader("Content-Length", length);
+ }
+
+ /**
+ * Set the content type.
+ *
+ * @param type
+ * The content type
+ */
+ public void setContentType(final String type)
+ {
+ setHeader("Content-Type", type);
+ }
+
+ /**
+ * @return value of content-type header
+ */
+ public String getContentType()
+ {
+ return getHeader("Content-Type");
+ }
+
+ /**
+ * Set a date header.
+ *
+ * @param name
+ * The header name
+ * @param l
+ * The long value
+ */
+ public void setDateHeader(final String name, final long l)
+ {
+ setHeader(name, formatDate(l));
+ }
+
+ /**
+ * @param l
+ * @return formatted date
+ */
+ public static String formatDate(long l)
+ {
+ StringBuffer _dateBuffer = new StringBuffer(32);
+ Calendar _calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+ _calendar.setTimeInMillis(l);
+ formatDate(_dateBuffer, _calendar, false);
+ return _dateBuffer.toString();
+ }
+
+ /* BEGIN: This code comes from Jetty 6.1.1 */
+ private static String[] DAYS = { "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+ private static String[] MONTHS = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
+ "Sep", "Oct", "Nov", "Dec", "Jan" };
+
+ /**
+ * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" or "EEE, dd-MMM-yy HH:mm:ss 'GMT'"for
+ * cookies
+ *
+ * @param buf
+ * @param calendar
+ * @param cookie
+ */
+ public static void formatDate(StringBuffer buf, Calendar calendar, boolean cookie)
+ {
+ // "EEE, dd MMM yyyy HH:mm:ss 'GMT'"
+ // "EEE, dd-MMM-yy HH:mm:ss 'GMT'", cookie
+
+ int day_of_week = calendar.get(Calendar.DAY_OF_WEEK);
+ int day_of_month = calendar.get(Calendar.DAY_OF_MONTH);
+ int month = calendar.get(Calendar.MONTH);
+ int year = calendar.get(Calendar.YEAR);
+ int century = year / 100;
+ year = year % 100;
+
+ int epoch = (int)((calendar.getTimeInMillis() / 1000) % (60 * 60 * 24));
+ int seconds = epoch % 60;
+ epoch = epoch / 60;
+ int minutes = epoch % 60;
+ int hours = epoch / 60;
+
+ buf.append(DAYS[day_of_week]);
+ buf.append(',');
+ buf.append(' ');
+ append2digits(buf, day_of_month);
+
+ if (cookie)
+ {
+ buf.append('-');
+ buf.append(MONTHS[month]);
+ buf.append('-');
+ append2digits(buf, year);
+ }
+ else
+ {
+ buf.append(' ');
+ buf.append(MONTHS[month]);
+ buf.append(' ');
+ append2digits(buf, century);
+ append2digits(buf, year);
+ }
+ buf.append(' ');
+ append2digits(buf, hours);
+ buf.append(':');
+ append2digits(buf, minutes);
+ buf.append(':');
+ append2digits(buf, seconds);
+ buf.append(" GMT");
+ }
+
+ /**
+ * @param buf
+ * @param i
+ */
+ public static void append2digits(StringBuffer buf, int i)
+ {
+ if (i < 100)
+ {
+ buf.append((char)(i / 10 + '0'));
+ buf.append((char)(i % 10 + '0'));
+ }
+ }
+
+ /* END: This code comes from Jetty 6.1.1 */
+
+ /**
+ * Set the given header value.
+ *
+ * @param name
+ * The name for the header
+ * @param value
+ * The value for the header
+ */
+ public void setHeader(final String name, final String value)
+ {
+ List<String> l = new ArrayList<String>(1);
+ l.add(value);
+ headers.put(name, l);
+ }
+
+ /**
+ * Set an int header value.
+ *
+ * @param name
+ * The header name
+ * @param i
+ * The value
+ */
+ public void setIntHeader(final String name, final int i)
+ {
+ setHeader(name, "" + i);
+ }
+
+ /**
+ * Set the locale in the response header.
+ *
+ * @param locale
+ * The locale
+ */
+ public void setLocale(final Locale locale)
+ {
+ this.locale = locale;
+ }
+
+ /**
+ * Set the status for this response.
+ *
+ * @param status
+ * The status
+ */
+ public void setStatus(final int status)
+ {
+ this.status = status;
+ }
+
+ /**
+ * Set the status for this response.
+ *
+ * @param status
+ * The status
+ * @param msg
+ * The message
+ * @deprecated
+ */
+ @Deprecated
+ public void setStatus(final int status, final String msg)
+ {
+ setStatus(status);
+ }
+}
\ No newline at end of file
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpServletResponse.java
------------------------------------------------------------------------------
svn:executable = *
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpSession.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpSession.java?rev=917331&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpSession.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpSession.java Mon Mar 1 00:01:57 2010
@@ -0,0 +1,282 @@
+/*
+ * 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.protocol.http.mock;
+
+import java.io.Serializable;
+import java.rmi.server.UID;
+import java.util.Collections;
+import java.util.Enumeration;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+
+import org.apache.wicket.util.value.ValueMap;
+
+
+/**
+ * Mock implementation of the <code>WebSession</code> interface for use by the test harnesses.
+ *
+ * @author Chris Turner
+ */
+public class MockHttpSession implements HttpSession, Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ private final ValueMap attributes = new ValueMap();
+
+ private final ServletContext context;
+
+ private final long creationTime = System.currentTimeMillis();
+
+ private final String id = (new UID()).toString().replace(':', '_').replace('-', '_');
+
+ private long lastAccessedTime = 0;
+
+ private boolean temporary = true;
+
+ /**
+ * Create the session.
+ *
+ * @param context
+ */
+ public MockHttpSession(final ServletContext context)
+ {
+ this.context = context;
+ }
+
+ /**
+ * Get the attribute with the given name.
+ *
+ * @param name
+ * The attribute name
+ * @return The value or null
+ */
+ public Object getAttribute(final String name)
+ {
+ return attributes.get(name);
+ }
+
+ /**
+ * Get the names of the attributes in the session.
+ *
+ * @return The attribute names
+ */
+ public Enumeration<String> getAttributeNames()
+ {
+ return Collections.enumeration(attributes.keySet());
+
+ }
+
+ /**
+ * Get the creation time of the session.
+ *
+ * @return The creation time
+ */
+ public long getCreationTime()
+ {
+ return creationTime;
+ }
+
+ /**
+ * Return the id of this session.
+ *
+ * @return The id
+ */
+ public String getId()
+ {
+ return id;
+ }
+
+ /**
+ * Get the time the session was last accessed.
+ *
+ * @return The last accessed time
+ */
+ public long getLastAccessedTime()
+ {
+ return lastAccessedTime;
+ }
+
+ /**
+ * NOT USED. Sessions never expire in the test harness.
+ *
+ * @return Always returns 0
+ */
+ public int getMaxInactiveInterval()
+ {
+ return 0;
+ }
+
+ /**
+ * Return the servlet context for the session.
+ *
+ * @return The servlet context
+ */
+ public ServletContext getServletContext()
+ {
+ return context;
+ }
+
+ /**
+ * NOT USED.
+ *
+ * @return Always null
+ * @deprecated
+ */
+ @Deprecated
+ public javax.servlet.http.HttpSessionContext getSessionContext()
+ {
+ return null;
+ }
+
+ /**
+ * Get the value for the given name.
+ *
+ * @param name
+ * The name
+ * @return The value or null
+ * @deprecated use getAttribute(String) instead
+ */
+ @Deprecated
+ public Object getValue(final String name)
+ {
+ return getAttribute(name);
+ }
+
+ /**
+ * Get the names of the values in the session.
+ *
+ * @return The names of the attributes
+ * @deprecated use getAttributeNames() instead
+ */
+ @Deprecated
+ public String[] getValueNames()
+ {
+ String[] result = new String[attributes.size()];
+ return attributes.keySet().toArray(result);
+ }
+
+ /**
+ * Invalidate the session.
+ */
+ public void invalidate()
+ {
+ attributes.clear();
+ }
+
+ /**
+ * Check if the session is new.
+ *
+ * @return Always false
+ */
+ public boolean isNew()
+ {
+ return false;
+ }
+
+ /**
+ * Set a value.
+ *
+ * @param name
+ * The name of the value
+ * @param o
+ * The value
+ * @deprecated Use setAttribute(String, Object) instead
+ */
+ @Deprecated
+ public void putValue(final String name, final Object o)
+ {
+ setAttribute(name, o);
+ }
+
+ /**
+ * Remove an attribute.
+ *
+ * @param name
+ * The name of the attribute
+ */
+ public void removeAttribute(final String name)
+ {
+ attributes.remove(name);
+ }
+
+ /**
+ * Remove a value.
+ *
+ * @param name
+ * The name of the value
+ * @deprecated Use removeAttribute(String) instead
+ */
+ @Deprecated
+ public void removeValue(String name)
+ {
+ removeAttribute(name);
+ }
+
+ /**
+ * Set an attribute.
+ *
+ * @param name
+ * The name of the attribute to set
+ * @param o
+ * The value to set
+ */
+ public void setAttribute(final String name, final Object o)
+ {
+ attributes.put(name, o);
+ }
+
+ /**
+ * NOT USED. Sessions never expire in the test harness.
+ *
+ * @param i
+ * The value
+ */
+ public void setMaxInactiveInterval(final int i)
+ {
+ }
+
+ /**
+ * Set the last accessed time for the session.
+ */
+ public void timestamp()
+ {
+ lastAccessedTime = System.currentTimeMillis();
+ }
+
+ /**
+ * Indicates the state of the session. Temporary or persisted.
+ *
+ * @return true if this is a temporary session, false otherwise
+ */
+ public final boolean isTemporary()
+ {
+ return temporary;
+ }
+
+ /**
+ * Changes the state of this session. Temporary or persisted. Uppon creation all sessions are
+ * temporary.
+ *
+ * @param temporary
+ * trur, for a temporary session, false for a persisted session
+ */
+ public final void setTemporary(boolean temporary)
+ {
+ this.temporary = temporary;
+ }
+}
\ No newline at end of file
Propchange: wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/mock/MockHttpSession.java
------------------------------------------------------------------------------
svn:executable = *