Author: ivaynberg
Date: Tue Jun 16 20:25:01 2009
New Revision: 785373
URL: http://svn.apache.org/viewvc?rev=785373&view=rev
Log:
WICKET-1897 StatelessForm submitted to the wrong page
Issue: WICKET-1897
Added:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.html
(with props)
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.java
(with props)
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.html
(with props)
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.java
(with props)
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/StatelessFormTest.java
(with props)
Modified:
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/BookmarkableListenerInterfaceRequestTarget.java
Modified:
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/BookmarkableListenerInterfaceRequestTarget.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/BookmarkableListenerInterfaceRequestTarget.java?rev=785373&r1=785372&r2=785373&view=diff
==============================================================================
---
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/BookmarkableListenerInterfaceRequestTarget.java
(original)
+++
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/BookmarkableListenerInterfaceRequestTarget.java
Tue Jun 16 20:25:01 2009
@@ -1,196 +1,196 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.request.target.component;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.Page;
-import org.apache.wicket.PageParameters;
-import org.apache.wicket.RequestCycle;
-import org.apache.wicket.RequestListenerInterface;
-import org.apache.wicket.Session;
-import org.apache.wicket.WicketRuntimeException;
-import org.apache.wicket.protocol.http.PageExpiredException;
-import org.apache.wicket.protocol.http.request.WebRequestCodingStrategy;
-import org.apache.wicket.util.string.AppendingStringBuffer;
-import org.apache.wicket.util.string.Strings;
-
-/**
- * Request target for bookmarkable page links that also contain component path
and interface name.
- * This is used for stateless forms and stateless links.
- *
- * @author Matej Knopp
- */
-public class BookmarkableListenerInterfaceRequestTarget extends
BookmarkablePageRequestTarget
-{
- private final String componentPath;
- private final String interfaceName;
-
- /**
- * This constructor is called when a stateless link is clicked on but
the page wasn't found in
- * the session. Then this class will recreate the page and call the
interface method on the
- * component that is targeted with the component path.
- *
- * @param pageMapName
- * @param pageClass
- * @param pageParameters
- * @param componentPath
- * @param interfaceName
- * @param versionNumber
- */
- public BookmarkableListenerInterfaceRequestTarget(String pageMapName,
- Class<? extends Page> pageClass, PageParameters pageParameters,
String componentPath,
- String interfaceName, int versionNumber)
- {
- super(pageMapName, pageClass, pageParameters);
- this.componentPath = componentPath;
- this.interfaceName = interfaceName;
- }
-
- /**
- * This constructor is called for generating the urls
(RequestCycle.urlFor()) So it will alter
- * the PageParameters to include the 2 org.apache.wicket params
- * {...@link WebRequestCodingStrategy#BOOKMARKABLE_PAGE_PARAMETER_NAME}
and
- * {...@link WebRequestCodingStrategy#INTERFACE_PARAMETER_NAME}
- *
- * @param pageMapName
- * @param pageClass
- * @param pageParameters
- * @param component
- * @param listenerInterface
- */
- public BookmarkableListenerInterfaceRequestTarget(String pageMapName,
- Class<? extends Page> pageClass, PageParameters pageParameters,
Component component,
- RequestListenerInterface listenerInterface)
- {
- this(pageMapName, pageClass, pageParameters,
component.getPath(),
- listenerInterface.getName(),
component.getPage().getCurrentVersionNumber());
-
- int version = component.getPage().getCurrentVersionNumber();
- setPage(component.getPage());
-
- // add the wicket:interface param to the params.
- //
pagemap:(pageid:componenta:componentb:...):version:interface:behavior:urlDepth
- AppendingStringBuffer param = new AppendingStringBuffer(4 +
componentPath.length() +
- interfaceName.length());
- if (pageMapName != null)
- {
- param.append(pageMapName);
- }
- param.append(Component.PATH_SEPARATOR);
- param.append(getComponentPath());
- param.append(Component.PATH_SEPARATOR);
- if (version != 0)
- {
- param.append(version);
- }
- // Interface
- param.append(Component.PATH_SEPARATOR);
- param.append(getInterfaceName());
-
- // Behavior (none)
- param.append(Component.PATH_SEPARATOR);
-
- // URL depth (not required)
- param.append(Component.PATH_SEPARATOR);
-
-
pageParameters.put(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME,
param.toString());
- }
-
- @Override
- public void processEvents(RequestCycle requestCycle)
- {
- Page page = getPage();
- if (page == null)
- {
- page = Session.get().getPage(getPageMapName(),
componentPath, -1);
- if (page != null)
- {
- setPage(page);
- }
- else if (page == null)
- {
- page = getPage(requestCycle);
- }
- }
-
- if (page == null)
- {
- throw new PageExpiredException(
- "Request cannot be processed. The target page
does not exist anymore.");
- }
-
- final String pageRelativeComponentPath =
Strings.afterFirstPathComponent(componentPath,
- Component.PATH_SEPARATOR);
- Component component = page.get(pageRelativeComponentPath);
- if (component == null)
- {
- // this is quite a hack to get components in repeater
work.
- // But it still can fail if the repeater is a paging
one or on every render
- // it will generate new index for the items...
- page.prepareForRender(false);
- component = page.get(pageRelativeComponentPath);
- if (component == null)
- {
- throw new WicketRuntimeException(
- "unable to find component with path " +
- pageRelativeComponentPath +
- " on stateless page " +
- page +
- " it could be that the
component is inside a repeater make your component return false in
getStatelessHint()");
- }
- }
- RequestListenerInterface listenerInterface =
RequestListenerInterface.forName(interfaceName);
- if (listenerInterface == null)
- {
- throw new WicketRuntimeException("unable to find
listener interface " + interfaceName);
- }
- listenerInterface.invoke(page, component);
- }
-
- @Override
- public void respond(RequestCycle requestCycle)
- {
- Page page = getPage(requestCycle);
- // if the listener call wanted to redirect
- // then do that if the page is not stateless.
- if (requestCycle.isRedirect() && !page.isPageStateless())
- {
- requestCycle.redirectTo(page);
- }
- else
- {
- // else render the page directly
- page.renderPage();
- }
- }
-
- /**
- * @return The component path.
- */
- public String getComponentPath()
- {
- return componentPath;
- }
-
- /**
- * @return The interface name
- */
- public String getInterfaceName()
- {
- return interfaceName;
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.request.target.component;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.RequestListenerInterface;
+import org.apache.wicket.Session;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.protocol.http.PageExpiredException;
+import org.apache.wicket.protocol.http.request.WebRequestCodingStrategy;
+import org.apache.wicket.util.string.AppendingStringBuffer;
+import org.apache.wicket.util.string.Strings;
+
+/**
+ * Request target for bookmarkable page links that also contain component path
and interface name.
+ * This is used for stateless forms and stateless links.
+ *
+ * @author Matej Knopp
+ */
+public class BookmarkableListenerInterfaceRequestTarget extends
BookmarkablePageRequestTarget
+{
+ private final String componentPath;
+ private final String interfaceName;
+
+ /**
+ * This constructor is called when a stateless link is clicked on but
the page wasn't found in
+ * the session. Then this class will recreate the page and call the
interface method on the
+ * component that is targeted with the component path.
+ *
+ * @param pageMapName
+ * @param pageClass
+ * @param pageParameters
+ * @param componentPath
+ * @param interfaceName
+ * @param versionNumber
+ */
+ public BookmarkableListenerInterfaceRequestTarget(String pageMapName,
+ Class<? extends Page> pageClass, PageParameters pageParameters,
String componentPath,
+ String interfaceName, int versionNumber)
+ {
+ super(pageMapName, pageClass, pageParameters);
+ this.componentPath = componentPath;
+ this.interfaceName = interfaceName;
+ }
+
+ /**
+ * This constructor is called for generating the urls
(RequestCycle.urlFor()) So it will alter
+ * the PageParameters to include the 2 org.apache.wicket params
+ * {...@link WebRequestCodingStrategy#BOOKMARKABLE_PAGE_PARAMETER_NAME}
and
+ * {...@link WebRequestCodingStrategy#INTERFACE_PARAMETER_NAME}
+ *
+ * @param pageMapName
+ * @param pageClass
+ * @param pageParameters
+ * @param component
+ * @param listenerInterface
+ */
+ public BookmarkableListenerInterfaceRequestTarget(String pageMapName,
+ Class<? extends Page> pageClass, PageParameters pageParameters,
Component component,
+ RequestListenerInterface listenerInterface)
+ {
+ this(pageMapName, pageClass, pageParameters,
component.getPath(),
+ listenerInterface.getName(),
component.getPage().getCurrentVersionNumber());
+
+ int version = component.getPage().getCurrentVersionNumber();
+ setPage(component.getPage());
+
+ // add the wicket:interface param to the params.
+ //
pagemap:(pageid:componenta:componentb:...):version:interface:behavior:urlDepth
+ AppendingStringBuffer param = new AppendingStringBuffer(4 +
componentPath.length() +
+ interfaceName.length());
+ if (pageMapName != null)
+ {
+ param.append(pageMapName);
+ }
+ param.append(Component.PATH_SEPARATOR);
+ param.append(getComponentPath());
+ param.append(Component.PATH_SEPARATOR);
+ if (version != 0)
+ {
+ param.append(version);
+ }
+ // Interface
+ param.append(Component.PATH_SEPARATOR);
+ param.append(getInterfaceName());
+
+ // Behavior (none)
+ param.append(Component.PATH_SEPARATOR);
+
+ // URL depth (not required)
+ param.append(Component.PATH_SEPARATOR);
+
+
pageParameters.put(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME,
param.toString());
+ }
+
+ @Override
+ public void processEvents(RequestCycle requestCycle)
+ {
+ Page page = getPage();
+ if (page == null)
+ {
+ page = Session.get().getPage(getPageMapName(),
componentPath, -1);
+ if (page != null && page.getClass() == getPageClass())
+ {
+ setPage(page);
+ }
+ else
+ {
+ page = getPage(requestCycle);
+ }
+ }
+
+ if (page == null)
+ {
+ throw new PageExpiredException(
+ "Request cannot be processed. The target page
does not exist anymore.");
+ }
+
+ final String pageRelativeComponentPath =
Strings.afterFirstPathComponent(componentPath,
+ Component.PATH_SEPARATOR);
+ Component component = page.get(pageRelativeComponentPath);
+ if (component == null)
+ {
+ // this is quite a hack to get components in repeater
work.
+ // But it still can fail if the repeater is a paging
one or on every render
+ // it will generate new index for the items...
+ page.prepareForRender(false);
+ component = page.get(pageRelativeComponentPath);
+ if (component == null)
+ {
+ throw new WicketRuntimeException(
+ "unable to find component with path " +
+ pageRelativeComponentPath +
+ " on stateless page " +
+ page +
+ " it could be that the
component is inside a repeater make your component return false in
getStatelessHint()");
+ }
+ }
+ RequestListenerInterface listenerInterface =
RequestListenerInterface.forName(interfaceName);
+ if (listenerInterface == null)
+ {
+ throw new WicketRuntimeException("unable to find
listener interface " + interfaceName);
+ }
+ listenerInterface.invoke(page, component);
+ }
+
+ @Override
+ public void respond(RequestCycle requestCycle)
+ {
+ Page page = getPage(requestCycle);
+ // if the listener call wanted to redirect
+ // then do that if the page is not stateless.
+ if (requestCycle.isRedirect() && !page.isPageStateless())
+ {
+ requestCycle.redirectTo(page);
+ }
+ else
+ {
+ // else render the page directly
+ page.renderPage();
+ }
+ }
+
+ /**
+ * @return The component path.
+ */
+ public String getComponentPath()
+ {
+ return componentPath;
+ }
+
+ /**
+ * @return The interface name
+ */
+ public String getInterfaceName()
+ {
+ return interfaceName;
+ }
+}
Added:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.html
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.html?rev=785373&view=auto
==============================================================================
---
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.html
(added)
+++
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.html
Tue Jun 16 20:25:01 2009
@@ -0,0 +1,5 @@
+page 1<br>
+stateless form:<br>
+<form wicket:id="form">
+<input type="submit" value="submit">
+</form>
\ No newline at end of file
Propchange:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.html
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.java?rev=785373&view=auto
==============================================================================
---
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.java
(added)
+++
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.java
Tue Jun 16 20:25:01 2009
@@ -0,0 +1,29 @@
+/*
+ * 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.stateless.pages;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.form.StatelessForm;
+
+public class Page1 extends WebPage
+{
+
+ public Page1()
+ {
+ add(new StatelessForm("form"));
+ }
+}
Propchange:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page1.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.html
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.html?rev=785373&view=auto
==============================================================================
---
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.html
(added)
+++
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.html
Tue Jun 16 20:25:01 2009
@@ -0,0 +1,2 @@
+page 2<br>
+hi there
\ No newline at end of file
Propchange:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.html
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.java?rev=785373&view=auto
==============================================================================
---
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.java
(added)
+++
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.java
Tue Jun 16 20:25:01 2009
@@ -0,0 +1,27 @@
+/*
+ * 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.stateless.pages;
+import org.apache.wicket.markup.html.WebPage;
+
+
+public class Page2 extends WebPage
+{
+ public Page2()
+ {
+ setStatelessHint(false);
+ }
+}
Propchange:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/Page2.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/StatelessFormTest.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/StatelessFormTest.java?rev=785373&view=auto
==============================================================================
---
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/StatelessFormTest.java
(added)
+++
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/StatelessFormTest.java
Tue Jun 16 20:25:01 2009
@@ -0,0 +1,80 @@
+/*
+ * 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.stateless.pages;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.WicketTestCase;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.WebRequestCycle;
+import org.apache.wicket.util.tester.WicketTester;
+
+/**
+ * User: Anatoly Kupriyanov ([email protected]) Date: 12-Feb-2009 Time:
22:27:08 Bugfix for
+ * http://issues.apache.org/jira/browse/WICKET-1897
+ */
+public class StatelessFormTest extends WicketTestCase
+{
+ @Override
+ protected void setUp() throws Exception
+ {
+ tester = new WicketTester(new WebApplication()
+ {
+ @Override
+ protected void init()
+ {
+ super.init();
+ mountBookmarkablePage("page1", Page1.class);
+ mountBookmarkablePage("page2", Page2.class);
+ }
+
+ @Override
+ public Class<? extends Page> getHomePage()
+ {
+ return Page1.class;
+ }
+
+ @Override
+ protected void outputDevelopmentModeWarning()
+ {
+ // Do nothing.
+ }
+ });
+ }
+
+ public void testBug()
+ {
+ {
+ final WebRequestCycle cycle =
tester.setupRequestAndResponse(false);
+ tester.getServletRequest().setURL("page2");
+ tester.processRequestCycle(cycle);
+ tester.assertRenderedPage(Page2.class);
+ }
+ {
+ final WebRequestCycle cycle =
tester.setupRequestAndResponse(false);
+ tester.getServletRequest().setURL("page1");
+ tester.processRequestCycle(cycle);
+ tester.assertRenderedPage(Page1.class);
+ }
+ {
+ final WebRequestCycle cycle =
tester.setupRequestAndResponse(false);
+ tester.getServletRequest().setURL(
+
"page1/wicket:interface/:0:form::IFormSubmitListener::");
+ tester.processRequestCycle(cycle);
+ tester.assertRenderedPage(Page1.class);
+ }
+ }
+}
Propchange:
wicket/trunk/wicket/src/test/java/org/apache/wicket/stateless/pages/StatelessFormTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain