-
-
Save dashorst/6308833 to your computer and use it in GitHub Desktop.
Please see https://github.com/dashorst/wicket-rfcs/blob/master/wicket-rfc-0001.txt for the RFC. | |
Please comment either inline in the github repository, or reply to the message | |
thread on the [email protected] mailing list. |
2.3 Custom type parameters
it is not enough to simply say you need a constructor that takes a String. we need a converter system. for example, we often pull ids out of PageParameters and load entities. we cannot have entities take a string parameter and then reload itself with data.
whether or not we can/should reuse the existing converter infrastructure we have should also be discussed.
// register all pages in the package and its child packages
mountPackage("com.example.web.pages");
that will basically require a package scan, so not sure why we are still discussing whether or not we need one in 3.3...
we should keep the existing PageParameters infrastructure unchanged.
- i do not want to migrate all the pages that use PageParameters when I upgrade
- in a few instances page parameters are dynamic and i do not want to/cannot list all possible ones in annotations
What if you have many pages that receive the same parameters, and those have to be converted to a TO? Or multiple-field objects (like, a Date could be created by three inputs, '_year', '_month', and '_day', with some common prefix).
With PageParameters, I could just have a static method that takes PageParameter and returns the object, and reuse it in every page. Not being allowed to do this would take a lot of control off our hands.
And even if this new parameter system implemented something like SpringMVC's annotated parameters (can take POJOs, inject parameters into their properties, etc.), I think it would be very complex and confusing (just like SpringMVC).
We need to show how this parameter binding works on the side where the URL is created inside Wicket not just one-way. With the RFC, only the parsing of the parameter on the receiving end is shown. With the RFC we would have to duplicate the rules by which the parameters are bound to URLs on the receiving AND the sending side.
With the existing scheme, we can delegate the creation of a link to a page in code in a typesafe way. Perhaps the RFC can be updated to show how this works with the new scheme.
Currently we can encapsulate this two-way in the page as follows:
MyPage.java
// A static LongParameter object knows how to convert from and to
// The name of the parameter in URL "ssn" is encapsulated in the instance
private static final LongParameter PARAMETER_ID = new LongParameter("ssn");
// Constructor
public MyPage(final PageParameters parameters) {
Long securityNumber = PARAMETER_SECUTRITY_NUMBER.getValue(parameters);
// parameter interface
public static PageParameters createParameters(final long securityNumber) {
final PageParameters parameters = new PageParameters();
PARAMETER_SECUTRITY_NUMBER.addToParameters(parameters, securityNumber);
return parameters;
}
Other page:
// Delegate the creation of page parameters to destination page
new BookmarkablePageLink("edit", MyPage.class, MyPage.createParameters(securityNumber)
Using annotations for brevity does not necessarily improve code quality if it does not encapsulate the formatting rules for these parameters.
There is nothing regarding the use of optional parameters. How should we handle this use case, should we use multiple constructors [1] or should we use a @DefaultValue
annotation [2] to stay on par with Jax-RS API ?
[1] :
@Path("/page/{req}/val/{opt}")
public class MyPage extends WebPage{
public MyPage(@PathParam("req") String req){
}
public MyPage(@PathParam("req") String req,
@PathParam("opt") String opt){
}
}
[2] :
@Path("/page/{req}/val/{opt}")
public class MyPage extends WebPage{
public MyPage(@PathParam("req") String req,
@DefaultValue("default") @PathParam("opt") String opt){
}
}
How many users have complained that the current way (using PageParameters) causes them troubles ?
What kind of troubles ?
Please provide a list of open tickets in JIRA which will be solved with this RFC.
7.1.3 setResponsePage(Class<?>, PageParameters) removed
What will be the new way to make a redirect with path and/or query parameters ?
org.apache.wicket.request.resource.IResource#respond
At the moment one could have:
- a stateless resource - the mounted resource reference create a new IResource for each request
- a stateful resource - the mounted reference reused the same resource
In both cases IResource#respond() receives IResource.Attributes with the current Request, Response and PageParameters.
Do you imagine how the new way will be applied here ?
Hi everybody!
I have to finish yet to read the complete rfc document. I agree that sometimes PageParameters can generate a little bit of confusion when we use them with page constructor or links. I also agree that the code for mounting pages/resources should be more neat and clear (too many IRequestMapper ??).
However I don't understand why we should get rid (or heavily modify) PageParameters. The funny thing (of course for me) is that PageParameters have been very helpful writing REST module for Wicket, which basically offers the same features (and the same approach) of JAX-RS.
REST module for Wicket: https://github.com/wicketstuff/core/tree/master/jdk-1.6-parent/wicketstuff-restannotations-parent
I find it very clean and extremely easy to deal with PageParameters. They allow developers to instantiate pages with completely different sets of parameters. To formalise the conversion between PageParameters and sets of values (not just IModel) one can use two-way converters within the target page. That achieves 100% type safety:
setResponsPage(MyPage.class, MyPage.createParameters(parameter1, parameter2)
The proposed solution must show how to achieve type safety.
varargs or builder that add arbitrary parameters cannot be used to provide type safety (which comes with code completion in IDEs). Here is why: Wrap a parameter builder in a type safe converter. The parameter builder or varargs object - what are they? Just another way to represent name value pairs - which is what PageParameters are - except they are broken because the names are missing.
So one cannot build the type safety even with a converter.
The annotation approach is good for web services where the consumer is outside the system, and a complete tool chain exists to generate the annotations and wsdl which provides the type safety at the other end. Do we want to provide this?
Perhaps behind the annotations should be be real classes that provide the type safety . Something like jsr303 bean validation.
This is a generic problem of two-way mapping between name-value pairs and and arbitrary objects. Why is Wicket trying to solve this? Given the maturity of the Java ecosystem and the basic nature of the problem I would guess that either 1) we can use an existing solution and plug it in, or 2) this problem does not have a generic solution.
I guess it is 2) because of validation constraints.
I would prefer if Wicket keeps PageParameters and provides PageParameter converters to support type safety. Developers just code them anyway so we are not asking for them. They would be great for beginners though.
if we were to implement 2.2 (field injection) this would have to be done from the Component's constructor, so we would spread creation and initialization of parameters across two places: component and page factory - this sucks. also, it is rarely these things are useful as fields because we dont usually want them serialized. most of the time we pull a value, wrap it in an LDM and store that as a field.