001package votorola.s.gwt.wic; // Copyright 2012, Michael Allan.  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE.
002
003import com.google.gwt.http.client.UrlBuilder;
004import com.google.gwt.user.client.Window;
005import java.util.*;
006import votorola.a.count.*;
007import votorola.g.lang.*;
008import votorola.g.web.gwt.*;
009import votorola.g.web.gwt.event.*;
010import votorola.s.gwt.stage.*;
011
012
013/** A controller that loads a new page when the poll changes on stage.
014  */
015class PollPager implements PropertyChangeHandler
016{
017
018
019    /** Creates the single instance of PollPager.
020      */
021    PollPager( final Stage stage ) // called by CountIn
022    {
023        pollName0 = stage.getPollName();
024        GWTX.i().bus().addHandlerToSource( PropertyChange.TYPE, /*source*/stage.prompter(),
025          PollPager.this ); // no need to unregister, registry does not outlive this handler
026    }
027
028
029
030    /** The single instance of PollPager.
031      */
032    private static PollPager instance;
033
034        {
035            if( instance != null ) throw new IllegalStateException();
036
037            instance = PollPager.this;
038        }
039
040
041
042   // ------------------------------------------------------------------------------------
043
044
045    /** The initial poll name.
046      */
047    String pollName0; // matching (it is assumed) query parameter 'p'
048
049
050
051    /** Returns true if the named parameter was set to the specified value, false if it
052      * had already been set.
053      */
054    static boolean setParameter( final String name, final String value, final UrlBuilder u )
055    {
056        final String oldValue = Window.Location.getParameter( name );
057        final boolean wasSet;
058        if( value == null )
059        {
060            if( null == oldValue ) wasSet = false;
061            else
062            {
063                u.removeParameter( name );
064                wasSet = true;
065            }
066        }
067        else
068        {
069            if( value.equals( oldValue )) wasSet = false;
070            else
071            {
072                u.setParameter( name, value );
073                wasSet = true;
074            }
075        }
076        return wasSet;
077    }
078
079
080
081   // - P r o p e r t y - C h a n g e - H a n d l e r ------------------------------------
082
083
084    public void onPropertyChange( final PropertyChange e )
085    {
086        // cf. PositionPager.onPropertyChange
087
088        final String propertyName = e.propertyName();
089        if( !propertyName.startsWith( "pollName" ) ) return;
090
091        final Stage stage = Stage.i();
092        final String pollName = stage.getPollName();
093        if( ObjectX.nullEquals( pollName, pollName0 ))
094        {
095            // no actual change.  Either event is from setPollName below (page load
096            // pending) or another change that was reverted before the event got here.  In
097            // either case, it is safe to suppress to lighten the burden
098         // stage.prompter().setSuppressed( true );
099         //// not actually safe, as an intermediate value may possibly have been read somewhere
100            return;
101        }
102
103        final UrlBuilder u = Window.Location.createUrlBuilder();
104        if( !setParameter( "p", Poll.U.toQuery(pollName), u ))
105        {
106            // parameters are already set correctly, so apparently pollName0 wasn't
107            assert false: "pollName0 to 'p'";
108            pollName0 = pollName; // ensure it's now correct
109            return;
110        }
111
112        stage.setPollName( pollName0 ); // back to original values, keep state clean in BFCache
113        stage.prompter().setSuppressed( true ); // suppress event, which is now redundant
114        Window.Location.assign( u.buildString() );
115    }
116
117
118}