Thursday, August 13, 2009

Groovy Closure vs. javascript closure

Coming from a javascript and java background, i've learned to use the javascript closure to its full advantage, but when we used groovy (on grails) for our new system, I was surprise that the concept of closure in groovy is different.

The definition of closure in groovy (from groovy.codehaus.org) is that, a groovy Closure is like a "code block" or a method pointer. It is a piece of code that is defined and then executed at a later point. It has some special properties like implicit variables, support for currying and support for free variables (which we'll see later on). We'll ignore the nitty gritty details for now (see the formal definition if you want those) and look at some simple examples.

GROOVY CODE:

def myclosure = { println "hello world!" }

println "Executing the Closure:"
myclosure() //prints "hello world!"



The javascript closure is a functionality that marks a variable, that it will be use later. So even when it goes out of scope, the data is saved in the memory. Here's an example:



function SayHelloTo(name) {
var greeting = 'Hello ' + name;
var display = function() { alert(greeting); }
return display;
}

var greet = new SayHelloTo("Aidan Thor");
greet();




This is simply defining a method with a local variable called "greeting" and another method inside called display, then it returns that method.

When you instantiate "SayHelloTo", and execute it ( "greet()"), you would think that it will throw an error, because "greeting" is out of scope, but actually it will not throw an error, because the method created a closure (knowing that "greeting" will be called later).

Wednesday, July 29, 2009

MVP with GWT

MVP stands for Model View Presenter. It is a front end architecture that separates your model (data object) and the view via presenter.

A detailed description can be found in this link (http://www.martinfowler.com/eaaDev/uiArchs.html) written by Martin Fowler. The post is focused on why it's appropriate to use MVP than MVC in GWT project, and how to implement it.

It is tough to decide whether to use MVP or MVC, because both designs solve the problem. One good example that separates the two is that with MVC, it's always the controller's responsibility to handle keyboard and mouse events, while with MVP the GUI component itself initially handle the user's input, and delegate the interpretation of that input to the presenter. (Consider Struts or Spring MVC vs. Flex/Flash ).



A good friend of mine said that MVP is particularly interesting in the context of GWT when doing TDD (Test Driven Development) or just thorough testing all round. The reason is that testing widgets and widget interactions is generally slow because you need to create a UI environment (hosted mode or web mode usually) to run your tests in. By moving your application logic into the Presenter, you end up with code that can be tested fairly fast (with mock widgets). Since the widgets are simple there's less to go wrong in this harder/slower to test area.



In my opinion, the richer your client framework is (e.g. Flex/Flash, Silverlight ) the more you should favor MVP.

Here are the steps you need to do in building MVP compliant project.


1) Define a Page object. The page object represents a web page. You can even make it more granular by defining a Form object.



public class Page extends Composite implements PageView {
private presenter;

public Page() {
presenter = new PagePresenter(this);
TextArea ta = new TextArea();
ta.setCharacterWidth(80);
ta.setVisibleLines(50);
add(ta);

Button b = new Button("Comment", new ClickHandler() {
public void onClick(ClickEvent event) {
presenter.submitComment(ta.getValue());
}
});
add(b);

}
//This method is defined in PageView, and its being called
//by the presenter.
public void updateView(String text) {
Label commentLabel = new Label(text);
add(commentLabel);
}

}


Your page contains the presenter object, and it implements PageView.

2) Define your PageView interface. The PageView acts as a conduit between Page and the Presenter.


public interface PageView {

public void updateView(String text);

}


3) Define your Presenter object. The presenter is the class that contains all the business logic. It has reference to the services.


public class PagePresenter {

private PageView pageView;


public PagePresenter(PageView pageView ) {
this.pageView = pageView;
}

//You can use HasClickHandlers, Hastext or HasHTML, but I prefer just passing the
// data, if you dont need any other functionalities.
public void submitComment(String comment) {
if(comment != null) {
service.submitComment(comment);
//Do service calls here. When done, call
//pageView.updateView()
}
}
}

Sunday, May 31, 2009

what's on GWT2.0 ??

Here are a few things that I was able to capture about GWT 2.0 during google i/o 2009.

with GWT 2.0, they have added RunAsync functionality. RunAsync gives you the ability to split your javascript into chunks of files. Which allows you, not to load the entire JS from the start.

They have added ClientBundle functionality. ClientBundle includes ImageBundle, ResourceBundle and CssResource (The killer feature). ImageBundle combines individual images into a single image in multiple dimensions. Simply lining up images left-to-right to create an image strip is sufficient. This will make fewer HTTP round-trips. This is what the code looks like:


Interface MyBundle extends ClientBundle {
public static final MyBundle INSTANCE = GWT.create(MyBundle.class);

@Source(“smiley.gif”)
ImageResource smileyImage();

@Source(“frowny.png”)
ImageResource frownlyImage();

@Source(“app_config.xml”)
TextResource appConfig();

@Source(“wordlist.txt”)
ExternalTextResource wordlist();

@Source("my.css")
public CssResource css();

@Source("config.xml")
public TextResource initialConfiguration();

@Source("manual.pdf")
public DataResource ownersManual();
}

This is how you would use it:

Window.alert(MyResources.INSTANCE.css().getText());
Frame myFrame = new Frame(MyResources.INSTANCE.ownersManual().getURL());
TextResource configs = MyBundle.INSTANCE. InitialConfiguration();
String configXml = configs.getText();
Document doc = XMLParser.parse(configXml);


The CSSResource compiles CSS with an enhanced syntax. It defines and uses constants in CSS. E.g.

@define myBorder 8px;
@define myColor #FDD;
.error-border { border:myBorder solid:myColor; }

It also uses conditions for user agent, locale or anything.

/* Runtime evaluation in a static context */
@if (com.module.Foo.staticBooleanFunction()) {
... css rules ...
}

/* Compile-time evaluation */
@if {
... css rules ...
}
@if user.agent safari gecko1_8 { ... }
@if locale en { ... }

/* Negation is supported */
@if !user.agent ie6 opera { ... }


GWT 2.0 have updated sets of Panel that fix the Layout. The example given is the new and improve DockPanel. It doesn’t run javascript during resize. Constraints-based layout similar to Cocoa on OSX.

GWT2.0 have added option in the compiler is: -XdisableClassMetaData. Calling obj.getClass() or clazz.getName() forces class objects and their names to be generated into javascript. It has Size, speed and obscurity benefits.

GWT2.0 added options in the compiler is: -XdisableCastChecking. Nobody actually catches ClassCastException in app code. (I hope you are not doing this):


Void makeItQuak(Animal animal) {
Try {
((Quaker) animal).quak();
}catch(ClassCastException c ) {
Window.alert(“doesn’t quak!”);
}


The above example generates a call like this (compiled JS)

DynamicCast(animal, 2).quak();


But when the flag is turned on, you only get this:

animal.quak();

How does this help you? In real-world (and very large) google app:
-1% script size reduction
-10% speed improvement in performance-sensitive code.


GWT have added RPC blacklist. Tell the RPC subsystem to skip types that you know aren’t ever sent across the wire:

<extend-configuration-property name="”rpc.blacklist”" value="”com.example.client.WidgetList”">


-Added Client side stackTrace on some browsers.
Throwable#getStackTrace() actually does something sometimes )


-Added interfaces on JavaScript Overlay Types.

Wednesday, May 20, 2009

adding whitelist or blacklist option in maven GWT

If you are using Maven GWT plugin and find yourself lost in adding the whitelist or blacklist option in the configuration, do not worry, because it is not supported.

At first, I thought it's just another configuration tag, so i added:

<configuration>
<whitelist></whitelist>

But it didn't work. The solution is to add it in the runTarget tag. like this:

<properties>
<whitelist>" ^http[:][/][/]sample[.]net"</whitelist>
</properties>

<runtarget>com.sample.app/Sample.html -whitelist ${whitelist}</runtarget>


I hope this helps.

Monday, May 18, 2009

4 steps to add facebook connect (xfbml) to google web toolkit (GWT) app

Adding facebook connect (XFBML) to your Google web toolkit (GWT) application


This is a fast track tips on how to add facebook connect to your GWT based application.



Step 1: add a facebook application.
If you don't have the facebook application. Just login to facebook and search for the word "developer" in the search field of the menu bar.

http://screencast.com/t/43OHbcLl9

select developer and add/install it. Select "Set Up New Application" , select an application name, select agree then save changes.
The next page is the application configuration. take note of your API Key, because you will be using it. In the left menu bar, select "Connect".
in the connect URL, add your URL. (e.g. http://localhost:8888/com.sample.facebookApp/ ). localhost will work, because facebook connect will not
ping your server.



Step 2: adding the facebook connect library
open your .html file and add the facebook connect name space and the javscript library.


<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">

...

<body>
</body>
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript">

Facebook said that its faster to add the script tab below the closing body tag.




Step 3: add Cross Domain Communication Channel in your GWT app.

create a file called "xd_receiver.html" or download the file from http://www.somethingtoputhere.com/xd_receiver.htm and save it to the
public diretory of your google web toolkit app. You will reference this file later in your code.


Step 4: adding the code in your EntryPoint.


a) Add a static final String called FB_API_KEY and XD_RECEIVER_URL.


public static final String FB_API_KEY = "YOUR_KEY_FROM_FROM_YOUR_FACEBOOK_APP";
public static final String XD_RECEIVER_URL = "/xd_receiver.html";


b) build init method. This method initialize the facebook connect in your app. You should call this method in your onModuleLoad()


private static native String initFacebook(String apiKey, String xd_receiver_url)
/*-{
$wnd.FB_RequireFeatures(["XFBML"], function(){
$wnd.FB.Facebook.init(apiKey, xd_receiver_url);
});
}-*/;


c) Define the loginHandler. The login handler gets executed after a user login has login to facebook connect. This method should be called
in your onModuleLoad().


private native void defineFbLoginHandler() /*-{
var fbConn = this;
$wnd.facebookConnectLogin = function() {
//The "@com.sample.facebookApp.XfbmlPrototype" is the fully qualified name of your GWT app EntryPoint.
//The renderFriendsList is the method that will be executed after you login. (aka. login handler).

@com.sample.facebookApp.XfbmlPrototype::SESSION_KEY = $wnd.FB.Facebook.apiClient.get_session().session_key;
fbConn.@com.sample.facebookApp.XfbmlPrototype::onLoginHandler()();
}
}-*/;

public void onLoginHandler() {
Window.alert("Login is successful!!");
//You can start adding XFBML comments here, like welcome notes, friend selector, etc.
}


d) define a parseDomTree method. Since facebook XFBML is not standard, you need to execute a method for them to render.


private static native void parseDomTree() /*-{
$wnd.FB.XFBML.Host.parseDomTree();
}-*/;


e) define your login button.


private Widget makeFbLoginButton() {
String fblogin = "";
HTML html = new HTML(fblogin);
return html;
}


As you can see, in the onlogin we point it to "facebookConnectLogin()". This method is define in defineFbLoginHandler() method we created in step c.




To sum it all up, your onModuleLoad() method will look like this:


public void onModuleLoad() {
FlowPanel loginPanel = new FlowPanel();
RootPanel.get().add(loginPanel);

Widget fbLoginButton = makeFbLoginButton();
loginPanel.add(fbLoginButton);

initFacebook(FB_API_KEY, XD_RECEIVER_URL);
defineFbLoginHandler();
}


Take note that facebook widgets doesn't render in Google Hosted mode. I tried DeferredCommand but it doesn't work. Make sure to compile and test it in a
browser.

Here's the link to all the facebook connect tags that are available: http://wiki.developers.facebook.com/index.php/XFBML

These are the books that I recommend:
1) GWT in Practice
2) GWT in Action
3) Google Web Toolkit Applications (Paperback)

Monday, February 16, 2009

busy life

It's been a year since my last post. I've been very busy working on a project that involves GWT, Grails and Android. Part of it, is that I got so busy with my personal life too.

With regards to the technology I'm using, it seems to me that there are lots of documentations, tutorials in the internet available already. So it doesn't make sense for me to post some introduction on these technologies since they can easily be found.

Although, I will post some methodology and technique that I find interesting when I get a chance.