Using the session does not work, but using the RequestCycle works fine. Below is how I solved the problem, and it seems to work quite well for stateless pages.
Thank you for your help.
public class StatelessAjaxSelfUpdatingTimerBehavior extends
AjaxSelfUpdatingTimerBehavior {
private final static MetaDataKey<Integer> requestIdsSequenceMetaDataKey
= new MetaDataKey<Integer>() {
private static final long serialVersionUID = 1L;
};
static final String GENERATED_IDS_PREFIX = "SASUTB";
public StatelessAjaxSelfUpdatingTimerBehavior(Duration updateInterval)
{
super( updateInterval );
}
@Override
public boolean getStatelessHint(@SuppressWarnings( "unused" ) Component
component) {
return true;
}
private static int getRequestNextSequenceValue() {
Integer currentSequence =
RequestCycle.get().getMetaData( requestIdsSequenceMetaDataKey );
if( currentSequence == null )
currentSequence = 0;
else
currentSequence++;
RequestCycle.get().setMetaData( requestIdsSequenceMetaDataKey,
currentSequence );
return currentSequence;
}
@Override
protected void onBind() {
Object storedMarkupId = getComponent().getMarkupIdImpl();
if( storedMarkupId == null || storedMarkupId instanceof Integer
){
String markupIdPrefix = "id";
if(
!getComponent().getApplication().usesDeploymentConfig() ){
// in non-deployment mode we make the markup id
include component id
// so it is easier to debug
markupIdPrefix = getComponent().getId();
}
String markupIdPostfix = GENERATED_IDS_PREFIX +
Integer.toHexString( getRequestNextSequenceValue() ).toLowerCase();
String markupId = markupIdPrefix + markupIdPostfix;
getComponent().setMarkupId( markupId );
}
super.onBind();
}
}
On Wed, 2011-09-07 at 21:42 +0300, Martin Grigorov wrote:
> Session#nextSequenceValue() is public and non-final.
>
> You can override it in YourWebSession to do whatever fits for your
> needs.
>
>
> On Wed, Sep 7, 2011 at 9:35 PM, Sylvain Vieujot <[email protected]>
> wrote:
>
> On Wed, 2011-09-07 at 10:19 -0700, Igor Vaynberg wrote:
>
> > On Wed, Sep 7, 2011 at 10:11 AM, Sylvain Vieujot
> <[email protected]> wrote:
> > > I looked at this code, but it does not really help as it has to
> bind to an
> > > event, whilst I am trying to do an auto update component.
> > >
> > > I have 2 questions :
> > >
> > > 1) Why does the AbstractAjaxBehavior sets the getStatelessHint to
> false ?
> > > It seems to me that this "non stateless" hint could be set much
> lower in the
> > > classe hierarchy, but I must be missing something.
> >
> > because the behavior itself is stateful. it needs to generate a
> > callback url to a component, which means it needs a page id - which
> > means the page has to exist already - which means it cannot be
> > stateless. it works much the same way as a Link component.
>
> But if the page is stateless you should not need the page id,
> just the page class to create a new instance isn't it ? (that
> is if the page's components ids are stable - see 2 below)
>
>
>
>
> > > 2) The main problem I have is in the component's id generation.
> > > In Component.getMarkupId, line 1505, we have :
> > > final int generatedMarkupId = storedMarkupId instanceof
> Integer ?
> > > (Integer)storedMarkupId
> > > : getSession().nextSequenceValue();
> > > So on every request, the id changes because of the
> > > getSession().nextSequenceValue().
> > > If in the Behaviour's onBind method, the component's id is fixed,
> then I
> > > have no problem ... except this is not very clean programming!
> >
> > if you fix the id yourself you have no way to guarantee it is
> unique.
> > eg if this is a panel you can have two instances of the panel in the
> > page, etc. the id itself should not matter much as long as you
> repaint
> > the component so its markup id changes to the new value.
>
> I agree that fixing the id is not a great idea ;-)
> But if the id generation could be stable for stateless pages,
> it would be quite helpful.
> My behaviour needs to repaint a component on a stateless page
> (which in the concept is like a stateless version of the clock
> example
> http://www.wicket-library.com/wicket-examples/ajax/clock ).
>
> In the Component id generation, couldn't we replace
> getSession().nextSequenceValue() by a new
> RequestCycle.get().nextSequenceValue() ( like the
> Page.getAutoIndex(), but we can not use the Page.getAutoIndex
> here as the page is not yet accessible) ?
> The ids would then be fixed for 2 instances of the same
> stateless page ?
> The ids would be much more stable and we could then have
> stable callback urls, i.e. stateless behaviours.
>
> Would this work ?
>
>
> > -igor
> >
> >
> > >
> > > public class StatelessAjaxTimerBehavior extends
> > > AjaxSelfUpdatingTimerBehavior {
> > >
> > > public StatelessAjaxTimerBehavior(Duration updateInterval) {
> > > super( updateInterval );
> > > }
> > >
> > > @Override
> > > public boolean getStatelessHint(@SuppressWarnings( "unused" )
> Component
> > > component) {
> > > return true;
> > > }
> > >
> > > @Override
> > > protected void onBind() {
> > > getComponent().setMarkupId( "myForcedID" ); // FIXME: This works,
> but is not
> > > very clean ... to say the least
> > > super.onBind();
> > > }
> > > }
> > >
> > > Is there a recommended way to fix this ?
> > >
> > > Thank you,
> > >
> > > Sylvain.
> > >
> > > On Wed, 2011-09-07 at 08:34 -0700, Igor Vaynberg wrote:
> > >
> > > use something like this [1] as a base and build your own timer
> behavior
> > >
> > > [1]
> > >
> https://github.com/jolira/wicket-stateless/blob/master/stateless/src/main/java/com/google/code/joliratools/StatelessAjaxEventBehavior.java
> > >
> > > -igor
> > >
> > >
> > > On Wed, Sep 7, 2011 at 3:36 AM, Sylvain Vieujot
> <[email protected]> wrote:
> > >> Hello,
> > >>
> > >> I have a stateless page, and I would like to periodically
> refresh a
> > >> section
> > >> of this page.
> > >> If I do :
> > >>
> > >> add( new MyPanel( "header" )
> > >> .setOutputMarkupId( true )
> > >> .add( new AjaxSelfUpdatingTimerBehavior(
> Duration.minutes( 2 ) )
> > >> );
> > >>
> > >> The page becomes stateless.
> > >>
> > >> If in MyPanel, I have :
> > >> class MyPanel{
> > >> ...
> > >> @Override
> > >> public boolean getStatelessHint(@SuppressWarnings( "unused"
> )
> > >> Component
> > >> component) {
> > >> return true;
> > >> }
> > >> ...
> > >> }
> > >>
> > >> The update does not work as the expected component's HTML id
> does not
> > >> remain
> > >> constant :
> > >>
> > >> Wicket.Ajax: Wicket.Ajax.Call.processComponent: Component with id
> > >> [[header2]] was not found while trying to perform markup update.
> Make sure
> > >> you called component.setOutputMarkupId(
> > > true) on the component whose markup
> > >> you are trying to update. console.error('Wicket.Ajax: ' + msg);
> > >> I also tried to use .setVersioned( false ) on both the component
> and the
> > >> page, but without success.
> > >> Is there a way to do this ?
> > >>
> > >> Thank you,
> > >>
> > >> Sylvain.
> > >
> > >
> ---------------------------------------------------------------------
> > > 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]
> >
>
>
>
>
>
>
>
> --
>
> Martin Grigorov
> jWeekend
> Training, Consulting, Development
> http://jWeekend.com
>
>
>
signature.asc
Description: This is a digitally signed message part
