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]

Reply via email to