I was trying out few options, but subclassing
is the simplest.
When subclassing generic data is preserved,
and prop: binding can resolve to actual return type of a method.
generic data is preserved for:
- fields : List<String> strings;
- methods List<Strings> getNames(List<User> users)
- subclasses : class UserEdit extends GenericEdit<User, Long>
tapestry currently only handles the third case, and only for getters,
when for example:
class GenericEdit<T, T_ID>{
public T getEntity(){...}
}
Davor Hrg
On Jan 30, 2008 11:38 AM, Geoff Callender
<[EMAIL PROTECTED]> wrote:
> Good point, Davor. The way I've used flash persistence it could just
> as well have been session persistence. The effect would be identical.
>
> * Perhaps what we really need is @Persist("redirection")?!?!?!
>
> It's a serious suggestion. After all, what we're aiming for is
> persistence during a redirection and only during a redirection. We
> don't want persistence after arriving from PageLink or browser Reload/
> Refresh because it causes anomalies (and that's why Mk VI uses
> cleanupRender()). Even better, redirection-persistence could be keyed
> by a temporary conversation id behind the scenes.
>
> What does everyone think?
>
> * Mk VI might be unacceptable in clustered environments, because it
> uses server-side persistence, requiring session replication traffic.
> In that situation I guess the options are either the Mk V solution or
> some sort of client-side persistence - hidden fields,
> @Persist("client"). or something new.
>
> As for your generic editing, I like it. It's exactly where I wanted
> to take this once we have the possible solutions codified. Perhaps an
> @EditPage annotation rather than a superclass would be even nicer?
>
> Cheers,
>
> Geoff
>
>
> On 30/01/2008, at 1:15 AM, Davor Hrg wrote:
>
> > cleanupRender is not a fix for flash persistence, it's more like
> > replacement for it.
> > flash persistence is made for the same reason (only persisting until
> > next request)
> >
> > you can take your example even further and make it generic
> > thus allowing actual edit page to be as simple as:
> >
> > public class EditCompany extends EntityEditPage<Company, Long>{
> >
> > @Override
> > protected Object getNextPage() {
> > return ListCompany.class;
> > }
> >
> > }
> >
> >
> > the generic edit page I'm working on
> > gets entity class like this:
> >
> > @SuppressWarnings("unchecked")
> > public AbstractEntityEdit() {
> > Type genericSuperclassType = getClass().getGenericSuperclass();
> > if((genericSuperclassType instanceof ParameterizedType)){
> > ParameterizedType genericSuperclass = (ParameterizedType)
> > genericSuperclassType;
> > if(genericSuperclass.getActualTypeArguments()[0]
> > instanceof Class){
> > this.persistentClass = (Class<T>)
> > genericSuperclass.getActualTypeArguments()[0];
> > this.idClass = (Class<T_ID>)
> > genericSuperclass.getActualTypeArguments()[1];
> > }
> > }
> > }
> >
> > uses Session to load entity when needed,
> > persists only entityId as string
> > uses TypeCoercer to convert string to "idClass" before calling
> > session.get()
> >
> > resets the form if cancel button is pressed or entityId changes
> >
> > Davor Hrg
> >
> >
> > On Jan 29, 2008 2:48 PM, Geoff Callender
> > <[EMAIL PROTECTED]> wrote:
> >> Thanks for all the comments. They've been invaluable. Below is the
> >> result, Mark Vi.
> >>
> >> Kalle, I'm using T5.0.9, but I think 5.0.7 would behave similarly.
> >> Yes, I'm trying frantically to keep up with the releases!
> >>
> >> As Davor pointed out, if validation has failed then getting the
> >> entity
> >> again doesn't overwrite the form in recent releases. I believe,
> >> however, that this only works if you keep everything that can fail in
> >> the onValidate... methods, eg. changePerson is called in
> >> onValidateFromForm instead of in onSuccess for this very reason.
> >>
> >> As Martin pointed out, I can avoid getting the entity every time in
> >> onActivate if I use @Persist("flash"), test for null entity in
> >> onActivate, and nullify "flash" fields in cleanupRender, ie. right
> >> before the page is displayed. The reason for the last bit is that
> >> sometimes there's only one onActivate before a page is displayed, so
> >> an attempt to refresh the page won't work because the entity is still
> >> in flash-persistence. A second attempt would work, which is very
> >> disconcerting.
> >>
> >> Davor, I like Martin's cleanupRender effect, so I don't think the
> >> "new
> >> window" problems you describe occur, and therefore I don't think I
> >> need the @Meta form annotation. Have I missed a corner-case here?
> >>
> >> If you're using BeanEditForm, just replace "Form" with
> >> "BeanEditForm".
> >>
> >> private Long _personId;
> >>
> >> @Persist("flash")
> >> private Person _person;
> >>
> >> @Component(id = "form")
> >> private Form _form;
> >>
> >> @InjectPage
> >> private NextPage _nextPage;
> >>
> >> void onActivate(Long id) throws Exception {
> >> _personId = id;
> >> if (_person == null) {
> >> _person =
> >> getPersonService().findPerson(_personId);
> >> }
> >> }
> >>
> >> Long onPassivate() {
> >> return _personId;
> >> }
> >>
> >> void onValidateFromForm() {
> >> if (...a bit of validation logic detects an
> >> error...) {
> >> _form.recordError(...);
> >> return;
> >> }
> >> // todo: move this next block back to onSuccess()
> >> once TAPESTRY-1972
> >> has been resolved.
> >> try {
> >> getPersonService().changePerson(_person);
> >> }
> >> catch (Exception e) {
> >>
> >> _form.recordError(ExceptionUtil.getRootCause(e));
> >> }
> >> }
> >>
> >> Object onSuccess() {
> >> _nextPage.onActivate(_personId);
> >> return _nextPage;
> >> }
> >>
> >> void cleanupRender() {
> >> _form.clearErrors();
> >> // Clear the flash-persisted fields to prevent
> >> anomalies in
> >> onActivate when we hit refresh on page or browser button
> >> _person = null;
> >> }
> >>
> >> and of course the hidden version field stuff still applies (it
> >> ensures
> >> optimistic locking works, preventing us saving changes to a Person
> >> that has since been updated or deleted by someone else or by us in
> >> another of our windows or tabs):
> >>
> >> <t:hidden t:id="version" value="person.version"/>
> >>
> >> or if you're using BeanEditForm:
> >>
> >> <t:beaneditform t:id="form" object="person"
> >> submitLabel="Save">
> >> <t:parameter name="version">
> >> <t:hidden t:id="version"
> >> value="person.version"/>
> >> </t:parameter>
> >> </t:beaneditform>
> >>
> >> Any more thoughts?
> >>
> >> Geoff
> >>
> >>
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]