Tuesday, May 17, 2011

Sharing Counter alternative: Pull Queues on App Engine

At Google I/O this year I learned about Pull Queues, now available on App Engine. During the session it occurred to me that this might be an alternative method to gathering counter statistics without using a sharding counter. Just send your stats to a Pull Queue and let another periodic task aggregate and store the data where it belongs.

Clearly the appropriateness of this depends on your application, but it seems to me that statistics gathering would be suitable.

Okay, so I’ll have to try it out, see how it works, and post some code!

Wednesday, May 4, 2011

Adventures in Tristate Checkboxes, Closure, and GWT

For the last week I have been trying to find or create an HTML widget similar to the GMail ‘labels’ menu button, e.g., like this:

gmail-tristate-menu-button(Hey, I found something useful for the contents of my spam folder… to make this screenshot!) 


Today I have succeeded with a simple drop-down menu button containing a list of tristate checkboxes. I used (and hacked) the closure library to achieve this. Below is a screen shot of my drop-down menu button from my working demo.


I compiled these button widgets into a standalone javascript file, which gives some very rich functionality with a pretty small “surface area” API. You just pass in the id of a div tag where you want the menu button, a list of group names, and a callback function to receive changes. The source for the demo menu button is very straightforward. You could copy that buttonlib.x.js file and those css files, and be off and running.

    <script src="buttonlib.x.js"></script>
    <link rel="stylesheet" href="../closure-library/closure/goog/css/common.css"> 
    <link rel="stylesheet" href="../closure-library/closure/goog/css/custombutton.css"> 
    <link rel="stylesheet" href="../closure-library/closure/goog/css/menu.css"> 
    <link rel="stylesheet" href="../closure-library/closure/goog/css/menubutton.css">
    <link rel="stylesheet" href="../closure-library/closure/goog/css/tristatemenuitem.css">
    <div style="font-size: 11px;"> 
          <div id="btn1" class="goog-custom-button goog-custom-button-collapse-right">
            <div style="padding: 0px 5px;">delete Freds</div>
        </div><div id="btn2" class="goog-custom-button goog-custom-button-collapse-left goog-custom-button-collapse-right">
            <div style="padding: 0px 5px;">set Freds to mixed</div>
        </div><div id="btn3" class="goog-custom-button goog-custom-button-collapse-left goog-custom-button-collapse-right">
            <div style="padding: 0px 5px;">set Pennys to checked</div>
        </div><div id="btn4" class="goog-custom-button goog-custom-button-collapse-left">
            <div style="padding: 0px 5px;">add Daves</div>
    <div id="btnGroups" style="font-size: 11px; font-family: Arial;"></div>
    <div style="margin-top:500px;"></div>
    <a href="http://www.youtube.com/watch?v=_LrlMoIzSjw" style="font-size: 11px;">the Daves I know</a>
    <script type="text/javascript">
        var mb1 = buttonlib.groupsMenuButtonCreate('btnGroups', 'Add to Groups...', function(groupKey, groupName, isChecked) {
            alert("groupKey="+groupKey+", groupName=" + groupName + ", isChecked=" + isChecked);
        buttonlib.groupsMenuButtonAddItem(mb1, '14', 'Freds', true);
        buttonlib.groupsMenuButtonAddItem(mb1, '21', 'Gails', false);
        buttonlib.groupsMenuButtonAddItem(mb1, '32', 'Harrys', null);
        buttonlib.groupsMenuButtonAddItem(mb1, '47', 'Alices', false);
        buttonlib.groupsMenuButtonAddItem(mb1, '23', 'Pennys', null);
        buttonlib.groupsMenuButtonAddItem(mb1, '12', 'Toms', false);
        buttonlib.buttonBarDecorate('btn1', function() { buttonlib.groupsMenuButtonRemoveItem(mb1, '14'); }); /*freds*/
        buttonlib.buttonBarDecorate('btn2', function() { buttonlib.groupsMenuButtonUpdateItem(mb1, '14', null); }); /*freds*/
        buttonlib.buttonBarDecorate('btn3', function() { buttonlib.groupsMenuButtonUpdateItem(mb1, '23', true); }); /*pennys*/
        buttonlib.buttonBarDecorate('btn4', function() { buttonlib.groupsMenuButtonAddItem(mb1, '41', 'Daves', false); });


If you want to have a look at the original source code, load this non-compiled version of the demo and view its sources – here you’ll find the javascript is “uncompiled” and still readable. The drop-down menu button code utilizes the goog.ui.TriStateMenuItem class, which did NOT behave as desired. I ended up modifying goog/ui/tristatemenuitem.js and goog/ui/component.js to get the behavior I wanted. (I also edited goog/css/tristatemenuitem.css just to make the menu highlight color consistent with the normal menu ui.)

If I were more experienced with javascript, I would have made my own version of TriStateMenuItem and not touched google’s code. But my initial attempt at this failed, and I don’t have infinite time, so a-hacking I went. For the record, here’s the patch file for the changes I made to three source files in closure.  (If you dig in there, you’ll find the HALFCHECK state I added to component.js – this topic deserves a post of its own, if anyone wishes to discuss it.)

With respect to my earlier post seeking a “native” tri-state checkbox, I am happy to compromise with this solution. The images used to depict the checked and half-checked states do not appear to “belong” to any particular OS/platform, and I think the user is willing to accept their appearance as being “oh, I *am* in a browser…”. To nitpick, I wish these images had an actual “box” for the checkbox. When nothing is checked in the list, everything is blank and there is no visual cue that you might want to click on something. Clearly the screenshot of the GMail interface agrees with this, since they put actual boxes around their checkmarks.

I will now apply this closure widget in my GWT app using JSNI glue per my previous post.

Sunday, May 1, 2011

Mixing Google Closure with GWT

I’ve been happily using GWT for some time now, but I’ve wanted some widgets (just three**) that didn’t exist in GWT out of the box. While searching for widgets to fit my UI needs, I decided to try to mix the use Google’s Closure Library inside my GWT app. I’ve had some success and wanted to share how I got the two to work together.

**Namely I’ve needed tri-state checkboxes, a button with a dropdown menu (like the labels drop-down button in GMail), and I’ve also desired the look of buttons in a row (like the button bar in GMail that contains: Archive|Spam|Delete ).


The outline version of how to do this is:

  1. Write a static html page (non GWT) that isolates the desired closure widgets onto a page by themselves.
  2. Compile the closure javascript into a standalone .js file.
  3. Copy the standalone .js file and the some closure CSS files into your GWT project.
  4. Copy the static html bits into your uibinder xml file.
  5. Use JSNI to glue the Closure and GWT worlds.


1. Isolate the closure widgets you want.

You should follow the Closure Getting Started page to download the closure library, and to setup a simple static html page containing the Closure widgets you want to use. I wanted to use a CustomButton “button bar”, like the [Left|Center|Right] buttons shown in this demo page. (You can browse all the closure demos – click the Demos tab on the right side of this page.)

I already had a local apache httpd server running, so I just checked out the closure library directly into my apache document root, and created another directory called buttonbar where I could create my work.

cd /website/docroot
svn checkout http://closure-library.googlecode.com/svn/trunk/ closure-library
mkdir buttonbar


In the buttonbar directory I created a buttonbar.html file and buttonbar.js file. With Closure, I had a choice of “decorating” existing div tags, or generating all the items programmatically. I opted to “decorate” because this allowed me to still layout my page in a declarative style, i.e. supply my button names in the HTML, etc. This is also a good match with how I’ve already been using UIBinder in GWT to keep layout as declarative as possible. These two files looked like this:

    <script src="../closure-library/closure/goog/base.js"></script>
    <script src="buttonbar.js"></script>
    <link rel="stylesheet" href="../closure-library/closure/goog/css/common.css">
    <link rel="stylesheet" href="../closure-library/closure/goog/css/custombutton.css">
    <div style="font-size: 11px;">
        <div id="btn1" class="goog-custom-button goog-custom-button-collapse-right">
            <div style="padding: 0px 5px;">Dodge</div>
        </div><div id="btn2" class="goog-custom-button goog-custom-button-collapse-left goog-custom-button-collapse-right">
            <div style="padding: 0px 5px;">Parry</div>
        </div><div id="btn3" class="goog-custom-button goog-custom-button-collapse-left">
            <div style="padding: 0px 5px;">Spin</div>
    <script type="text/javascript">
        buttonbar.setup('btn1', function() {alert("Dodge")} );
        buttonbar.setup('btn2', function() {alert("Parry")} );
        buttonbar.setup('btn3', function() {alert("Spin")} );


 * onClickCallback will be passed an ActionEvent when the button is clicked.
 *   http://closure-library.googlecode.com/svn/docs/class_goog_events_ActionEvent.html
buttonbar.setup = function(name, onClickCallback) {
    var button = goog.ui.decorate(goog.dom.getElement(name));
    button.setDispatchTransitionEvents(goog.ui.Component.State.ACTION, true);
    goog.events.listen(button, goog.ui.Component.EventType.ACTION, onClickCallback);
goog.exportSymbol('buttonbar.setup', buttonbar.setup);


With respect to the event filtering in the above code, know that Closure does their own (browser-independent) implementation of events. You will simply have to read about Closure Events to decide the appropriate way you should handle them for your application. In my code above, I specifically only want events when a button is clicked, which is why you only see goog.ui.Component.State.ACTION and goog.ui.Component.EventType.ACTION. You will need to examine your application needs with respect to the event handing you specify here.

Finally, loading the html page in a browser yields a lovely button bar:


(Note: if you are loading the html page with a file:/// url, and you are using Chrome, you will have to set the security parameter --allow-file-access-from-files as an argument to Chrome upon startup.)

It is this dividing point between the html file and the js file where you must consider what code goes into the .js file, and what function(s) you will expose to the outside html world to call. You need to think about how your GWT app is going to interact with the closure widget and be sure to expose a function that allows to you stitch these two worlds together. In this case, I only need a callback to be called when a button is clicked. And I also want to keep the button declarations in the html side, and just have the javascript side “decorate” these elements. Therefore the only other argument is the ‘name’, which is the id of the div element that represents a button.

For your application, other closure widgets (or even multiple widgets combined ) will likely require exposing multiple setup functions.


2. Compile the javascript into a “standalone” script.

To compile, you use the Closure Builder. Using the Closure compiler will eliminate all the unused code, and given the right flags, it will reduce the code into a single compact javascript file.

The compiler itself is written in Java, and you have to download the latest compiler jar file separately. Unzip this archive and copy compiler.jar to the same directory that contains your closure-library directory that you checked out earlier.

cd /website/docroot
wget http://closure-compiler.googlecode.com/files/compiler-latest.zip
unzip compiler-latest.zip compiler.jar


Run the compiler over the buttonbar.js file (requires python):

cd /website/docroot

closure-library/closure/bin/build/closurebuilder.py \
  --root=closure-library/ \
  --root=buttonbar/ \
  --namespace="buttonbar.setup" \
  --output_mode=compiled \
  --compiler_jar=compiler.jar \
  --compiler_flags="--compilation_level=ADVANCED_OPTIMIZATIONS" \
  > buttonbar/buttonbar.x.js


It’s the compiler_flags option above that shrinks the output code into a nice single little file.

Now you can edit the <head> of your original html file, loading only your new single javascript file":

    <script src="buttonbar.x.js"></script>
    <link rel="stylesheet" href="../closure-library/closure/goog/css/common.css">
    <link rel="stylesheet" href="../closure-library/closure/goog/css/custombutton.css">


Again, loading the html page in a browser should yield:



3. Copy the standalone .js file .css files into your GWT project

At this point we depend only upon a single javascript file buttonbar.x.js, and two css files common.css and custombutton.css. Copy all three to appropriate subdirectories of the “war” directory in your GWT  project. In your html (or jsp, or whatever) be sure to load all three of these resources. E.g., your <head> should now also contain these three items:


<script src="/path/to/js/buttonbar.x.js"></script>

    <link rel="stylesheet" href="/path/to/css/common.css">
    <link rel="stylesheet" href="/path/to/css/custombutton.css">


4. Copy the static html bits into your UIBinder file, e.g. MyPage.ui.xml :

    <div style="font-size: 11px;">
        <div id="btn1" class="goog-custom-button goog-custom-button-collapse-right">
            <div style="padding: 0px 5px;">Dodge</div>
        </div><div id="btn2" class="goog-custom-button goog-custom-button-collapse-left goog-custom-button-collapse-right">
            <div style="padding: 0px 5px;">Parry</div>
        </div><div id="btn3" class="goog-custom-button goog-custom-button-collapse-left">
            <div style="padding: 0px 5px;">Spin</div>

(Note: the above .ui.xml file actually contains many more GWT widgets; just this bit of html is shown cut and paste into an HTMLPanel)


5. Use JSNI to glue the Closure and GWT worlds.

In our GWT code, we must setup our closure widgets. This requires the presence of two things: 1) the buttonbar.x.js script must be loaded, 2) the html that declares the widgets must be loaded. Some reading about GWT widgets reveals that we can override the onLoad() method which will be called after both of those items are ready.

Earlier, in our simple html file, we made a javascript call to buttonbar.setup() for each button. In GWT, we will wrap the same call using JSNI and use the $wnd prefix to access the global space where we will find our setup function. Look for the setup in the onLoad() method.

public class MyPage extends Composite {
    interface MyPageUiBinder extends UiBinder<Widget, MyPage> {}
    private static MyPageUiBinder uiBinder = GWT.create(MyPageUiBinder.class);
    public MyPage() {
        // etc...
    protected void onLoad() {
    private static native void setupGoogButtons(MyPage widget) /*-{
        $wnd.buttonbar.setup('btn1', function() { widget.@com.your.namespace.client.MyPage::btnDodgeClick()() });
        $wnd.buttonbar.setup('btn2', function() { widget.@com.your.namespace.client.MyPage::btnParryClick()() });
        $wnd.buttonbar.setup('btn3', function() { widget.@com.your.namespace.client.MyPage::btnSpinClick()() });
    public void btnDodgeClick() {
        GWT.log("btn dodge click");
    public void btnParryClick() {
        GWT.log("btn parry click");
    public void btnSpinClick() {
        GWT.log("btn spin click");


That’s it. Granted the above example just logs the button clicks. But it does demonstrate the use of closure widgets in a GWT app.



I have two thoughts after achieving this task:

1) I do not have a “clean” development environment to easily iterate development. Normally GWT work is completely self-contained in eclipse. But with closure, I need python (plus java) to compile, and I was using an existing apache server to test my html/javascript, and just using vi to edit files. Figuring out how I could integrate all this activity into my “normal” eclipse world does not seem worth the effort for a one-off use of closure widgets. I am just documenting how I did things so I may maintain it or repeat it in the future. But it is not a push-one-button “make all” solution.

2) One could wrap each individual closure library widget into a self standing GWT widget and be done with the “dirty work” for good. But that would defeat closure’s ability of reducing unnecessary code. Instead you have consider the whole content of a particular page load, and all the possible closure widgets you will need while on that GWT page. You need to consider your interface and export javascript functions for all of those widgets and compile them such that you GWT page will still only need to load one closure js file. This presents more “dirty work” for each GWT page that needs closure widgets, and will make me curse my disjointed development environment. But the end result is worthwhile, so the incongruent nature of it all will be okay by me.