wicket-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Vieujot <svieu...@apache.org>
Subject Re: Stateless page with an auto update section
Date Wed, 07 Sep 2011 19:06:06 GMT
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 <svieujot@apache.org>
> wrote:
> 
>         On Wed, 2011-09-07 at 10:19 -0700, Igor Vaynberg wrote: 
>         
>         > On Wed, Sep 7, 2011 at 10:11 AM, Sylvain Vieujot <svieujot@apache.org>
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 <svieujot@apache.org>
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: users-unsubscribe@wicket.apache.org
>         > > For additional commands, e-mail: users-help@wicket.apache.org
>         > >
>         > >
>         > 
>         > ---------------------------------------------------------------------
>         > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>         > For additional commands, e-mail: users-help@wicket.apache.org
>         > 
> 
> 
> 
> 
> 
> 
> 
> -- 
> 
> Martin Grigorov
> jWeekend
> Training, Consulting, Development
> http://jWeekend.com
> 
> 
> 

Mime
View raw message