viernes, 20 de julio de 2012

Eclipse Java Code Templates for GWT related code automation

I often develop GWT libraries that port an existing javascript library like for example the raphael4gwt project that ports the javascript drawing library raphael to GWT / Java. I uses a lot of GWT Overlay types for dealing with native javascript objects from Java code.
GWT overlay types are not common java objects, in fact, at runtime, they "overlay" a native javascript object created outside GWT for example a DOM node. In my libraries I discovered that a good way to work with overlay types from java is like the following code.
Suppose I need to overlay a simple javascript object like the following in a java overlay type:
{
  color: "#ededed", 
  dashStyle: "none"
}
(this is an example taken from a real javascript library, YUI 3 - http://yuilibrary.com/yui/docs/api/classes/Circle.html#attr_stroke)
Now wuppose I want to create a GWT overlay type for this Stroke objects. In my experience I would like to define the overlay type, so I can create the same previous javascript object using the following java :
Stroke stroke1 = Stroke.create().
  color("#ededed").
  dashStyle("none");
The overlay type must be something like the following java class:
package org.sgx.yui4gwt.yui.graphic;

import com.google.gwt.core.client.JavaScriptObject;

/**GWT Overlay type for yui graphic stroke objects - 
 * http://yuilibrary.com/yui/docs/api/classes/Circle.html#attr_stroke
 * @author sg
 */
public class Stroke extends JavaScriptObject {

 protected Stroke() {}

 public static final String LINECAP_BUTT = "butt",
   LINECAP_SQUARE = "square", LINECAP_ROUND = "round";
 
 public static final String DASHSTYPE_NONE = "none",
   DASHSTYPE_TODO = "..."; 

 /** static constructor */
 public static final native Stroke create()/*-{
  return {}; 
 }-*/;
 
 /**
  * The color of the stroke.
  * 
  * @return
  */
 public native final String color() /*-{
  return this.color;
 }-*/;

 /**
  * The color of the stroke.
  * 
  * @param val
  * @return this - for setter chaining
  */
 public native final Stroke color(String val) /*-{
  this.color = val;
  return this;
 }-*/;

 /**
  * Number that indicates the width of the stroke.
  * 
  * @return
  */
 public native final double weight() /*-{
  return this.weight;
 }-*/;

 /**
  * Number that indicates the width of the stroke.
  * 
  * @param val
  * @return this - for setter chaining
  */
 public native final Stroke weight(double val) /*-{
  this.weight = val;
  return this;
 }-*/;

 /**
  * Number between 0 and 1 that indicates the opacity of the stroke. The
  * default value is 1.
  * 
  * @return
  */
 public native final double opacity() /*-{
  return this.opacity;
 }-*/;

 /**
  * 
  * @param val
  * @return this - for setter chaining
  */
 public native final Stroke opacity(double val) /*-{
  this.opacity = val;
  return this;
 }-*/;

 /**
  * 
  * @return
  */
 public native final String dashStyle() /*-{
  return this.dashStyle;
 }-*/;

 /**
  * 
  * @param val
  * @return this - for setter chaining
  */
 public native final Stroke dashStyle(String val) /*-{
  this.dashStyle = val; 
  return this; 
 }-*/;
}
And now the fun part. Writing more and more of this kind of overlay types I discovered that I can automate the work with eclipse java code templates. Just create an eclipse java code template going to Preferences->Java->Editor->Templates, and create a new template called "gwtOverlay1" with the following body:
/**
 * 
 * @return
 */
public native final ${attributeType} ${attributeName}() /*-{
 return this.${attributeName}; 
}-*/;
/**
 * 
 * @param val
 * @return this - for setter chaining
 */
public native final ${enclosing_type} ${attributeName}(${attributeType} val) /*-{
 this.${attributeName} = val; 
 return this; 
}-*/;
this way, when you need editing your overlay types in the eclipse java editor, to add another property to your overlay type, just use this template. type "gwt" and press ctrl+space. Choose "gwtOverlay1" and press enter. The template code will generated, and you can refactor the property type and property name.

yuigwt java code templates

In http://code.google.com/p/yuigwt/, where I work 100% with these kind of overlay types, I'm automatizing the Java definition of YUI attributes using getters/setters methods created with Java code templates. This is the template for those cases.
/**
 * 
 * @return
 */
public native final ${type} ${name}() /*-{
return this.get("${name}"); 
}-*/;

/**
 * 
 * @param val
 * @return this - for method chaining
 */
public native final ${enclosing_type} ${name}(${type} val) /*-{
this.set("${name}", val); 
return this; 
}-*/;

UIBinder @UIFactory

When writing YUIGWT with UIBinder (as documented in TODO LINK), if we reference a "YUIBinded" in another "YUIBinded" because "YUIBinded" required to pass a YUIContext as a constructor parameter, it is useful to autogenerate the @UIFactory method. This is a very personal note since I dot think anybody is working with this tech besides me. This is the template:

/**
 * Will be used for creating ${T} instances of this UIBinder widget. 
 * @return a new ${T}
 */
@UiFactory 
public ${T} make${T}() {
 return new ${T}(y); 
}

No hay comentarios: