jueves, 18 de agosto de 2011

Primera aplicación usando GWTP

GWTP o GWT Platform es un framework que implementa el patrón MVP para simplificar el desarrollo de aplicaciones. Hace uso de GIN(Client) y Guice(Server) para implementar el patrón inyección de dependencia. La versión 0.6 dispone de un plugin para eclipse.


El ejemplo a continuación muestra un ejemplo básico sin usar el Plugin de GWTP para ver un ejemplo del uso del plugin puede ver este video.



Hello GWT


Ir al Menú de eclipse  File -> New -> Web Application Project




Luego eliminar los archivos GreetingService.java , GreetingServiceAsync.java, FieldVerifier.java y eliminar el código de ejemplo del entry point.

package com.hellogwtp.client;
package com.hellogwtp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;

public class HelloGWTP implements EntryPoint {
 
 public void onModuleLoad() {
  GWT.log("hello");
 }
}

El módulo

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='hellogwtp'>  
  <inherits name='com.google.gwt.user.User'/>
  <entry-point class='com.hellogwtp.client.HelloGWTP'/>
  <source path='client'/>
  <source path='shared'/>
</module>

El archivo html

<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="HelloGWTP.css">
    <title>Web Application Starter Project</title>    
    <script type="text/javascript" language="javascript" src="hellogwtp/hellogwtp.nocache.js"></script>
  </head>
  <body>
    <!-- OPTIONAL: include this if you want history support -->
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
  </body>
</html>

También dejar en blanco el archivo css.

El archivo web.xml debe tener el siguiente contenido

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  
  <!-- Servlets -->
  
  <!-- Default page to serve -->
  <welcome-file-list>
    <welcome-file>HelloGWTP.html</welcome-file>
  </welcome-file-list>

</web-app>

Luego ejecutar el proyecto para comprobar que todo esta bien.

Para poder utilizar el GWTP necesitamos descargar unas librerias.

aopalliance.jar
gin-1.5-post-gwt-2.2.jar
guice-3.0.jar
guice-assistedinject-3.0.jar
gwtp-all-0.6.jar
javax.inject-1.jar
validation-api-1.0.0.GA-sources.jar
validation-api-1.0.0.GA.jar

de la página de GIN descargamos gin-1.5.zip en su contenido estan:
aopalliance.jar
gin-1.5-post-gwt-2.2.jar
javax.inject.jar

Ahora vamos a la página de Guice y descargamos guice-3.0.zip y en su contenido estan:
guice-3.0.jar
guice-assistedinject-3.0.jar

Luego descargamos los jars validation validation-api-1.0.0.GA.jar y validation-api-1.0.0.GA-sources.jar
y por último vamos a la página de GWTP y descargamos gwtp-all-0.6.zip en su contenido esta
gwtp-all-0.6.jar

Todos estos 7 jars los copio al directorio war/WEB-INF/lib del proyecto y los selecciono click derecho Build Path->Add to Build Path.

Luego agrego el módulo de GWTP a nuestro archivo de modulo

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='hellogwtp'>  
  <inherits name='com.google.gwt.user.User'/>
  <inherits name='com.gwtplatform.mvp.Mvp' />
  <entry-point class='com.hellogwtp.client.HelloGWTP'/>
  <source path='client'/>
  <source path='shared'/>
</module>

dentro de client creo un paquete place y ahi estará la clase MyPlaceManager.java

package com.hellogwtp.client.place;

import com.google.gwt.event.shared.EventBus;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.proxy.PlaceManagerImpl;
import com.gwtplatform.mvp.client.proxy.TokenFormatter;

public class MyPlaceManager extends PlaceManagerImpl {

 @Inject
 public MyPlaceManager(EventBus eventBus, TokenFormatter tokenFormatter) {
  super(eventBus, tokenFormatter);
 }

 @Override
 public void revealDefaultPlace() {
   
 }

}

dentro client creo el paquete gin dentro estarán la clase MyModule.java y la interfaz MyGinjector.java

MyModule.java
package com.hellogwtp.client.gin;

import com.gwtplatform.mvp.client.gin.AbstractPresenterModule;
import com.gwtplatform.mvp.client.gin.DefaultModule;
import com.hellogwtp.client.place.MyPlaceManager;

public class MyModule extends AbstractPresenterModule {

 @Override
 protected void configure() {
  install(new DefaultModule(MyPlaceManager.class));
  
 }

}

MyGinjector.java

package com.hellogwtp.client.gin;

import com.google.gwt.event.shared.EventBus;
import com.google.gwt.inject.client.GinModules;
import com.google.gwt.inject.client.Ginjector;
import com.gwtplatform.mvp.client.proxy.PlaceManager;

@GinModules({ MyModule.class })
public interface MyGinjector extends Ginjector {
 PlaceManager getPlaceManager();
 EventBus getEventBus();
}

Ahora le indico a mi archivo de módulo la ubicación del Ginjector

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='hellogwtp'>  
  <inherits name='com.google.gwt.user.User'/>
  <inherits name='com.gwtplatform.mvp.Mvp' />
  <entry-point class='com.hellogwtp.client.HelloGWTP'/>
  <source path='client'/>
  <source path='shared'/>
  <define-configuration-property name="gin.ginjector" is-multi-valued="false" />
  <set-configuration-property name="gin.ginjector" value="com.hellogwtp.client.gin.MyGinjector" />
</module>

Luego modifico el archivo entry point HelloGWTP.java

package com.hellogwtp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.gwtplatform.mvp.client.DelayedBindRegistry;
import com.hellogwtp.client.gin.MyGinjector;

public class HelloGWTP implements EntryPoint {
 public final MyGinjector ginjector = GWT.create(MyGinjector.class);
 
 public void onModuleLoad() {
  DelayedBindRegistry.bind(ginjector);  
  ginjector.getPlaceManager().revealCurrentPlace();
 }
}

Hasta ahora ya se ha configurado el proyecto para usar el GWT Platform. Si ejecuta el proyecto no deben salir errores.
Dentro de client creo el paquete core para los Presentadores y las Vistas.

IndexPresenter.java

package com.hellogwtp.client.core;

import com.google.gwt.event.shared.EventBus;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealRootContentEvent;

public class IndexPresenter extends Presenter<IndexPresenter.MyView, IndexPresenter.MyProxy> { 

 @ProxyCodeSplit
 @NameToken("index")
 public interface MyProxy extends ProxyPlace<IndexPresenter> {}

 public interface MyView extends View {

 }
 
 @Inject
 public IndexPresenter(EventBus eventBus, MyView view, MyProxy proxy) {
  super(eventBus, view, proxy);
 }

 @Override
 protected void revealInParent() {
  RevealRootContentEvent.fire(this, this);
 }

}

Luego click derecho al paquete core New -> UiBinder y el nombre será IndexView

Modifico el archivo IndexView.java
package com.hellogwtp.client.core;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.ViewImpl;

public class IndexView extends ViewImpl implements IndexPresenter.MyView {

 private static Binder uiBinder = GWT.create(Binder.class);

 interface Binder extends UiBinder<Widget, IndexView> {}
 private final Widget widget;

 @Inject
 public IndexView() {
  widget = uiBinder.createAndBindUi(this);
 }
 
 @Override
 public Widget asWidget() {
  return widget;
 }

}

Agrego el saludo al archivo IndexView.ui.xml
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
 xmlns:g="urn:import:com.google.gwt.user.client.ui">
 <ui:style>
  
 </ui:style>
 <g:HTMLPanel>
 Hello GWTP
 </g:HTMLPanel>
</ui:UiBinder>

Ahora voy a enlazar el Presenter con su vista y Proxy

MyModule.java
public class MyModule extends AbstractPresenterModule {

 @Override
 protected void configure() {
  install(new DefaultModule(MyPlaceManager.class));
  bindPresenter(IndexPresenter.class, IndexPresenter.MyView.class, IndexView.class, IndexPresenter.MyProxy.class);
 }

}

Agrego el nuevo Presenter a la interfaz MyGinjector.java

@GinModules({ MyModule.class })
public interface MyGinjector extends Ginjector {
 PlaceManager getPlaceManager();
 EventBus getEventBus();
 AsyncProvider<IndexPresenter> getIndexPresenter();
}

Ahora debo indicarle a la clase MyPlaceManager.java el Place por defecto

public class MyPlaceManager extends PlaceManagerImpl {

 @Inject
 public MyPlaceManager(EventBus eventBus, TokenFormatter tokenFormatter) {
  super(eventBus, tokenFormatter);
 }

 @Override
 public void revealDefaultPlace() {
  revealPlace(new PlaceRequest("index"), false);
 }

}

Ejecuto el proyecto click derecho Run As -> Web Application

5 comentarios:

  1. Muchas Gracias por el tutorial, realmente esta muy bueno.

    Te puedo hacer una consulta, soy nuevo en GWT y hoy en un foro me dijeron que GWT estaba discontinuado, pero estuve buscando info sobre esto y no encuentro nada, vos sabes algo?

    Saludos, Gracias!

    ResponderEliminar
    Respuestas
    1. A la fecha google soporta al menos 5 plataformas diferentes Javascript, GWT, Closure, NaCl y Dart según este enlace
      http://www.igvita.com/2012/01/05/google-web-toolkit-gwt-closure-nacl-dart-js/
      No existe una forma correcta de desarrollar aplicaciones, la selección de una plataforma depende del contexto.
      Google también lanzó un lenguaje "GO" con el argumento de que el hardware ha evolucionado y los lenguajes de programación no.
      Dart es una propuesta al javascript y usa una VM(Virtual Machine o plugin) aunque navegadores como Firefox, Safari e Internet Explorer no tienen planes de dar soporte a "Dart VM". Dart al igual que GWT puede compilarse a Javascript. El éxito de alguna estas plataformas depende de la comunidad. GWT fue liberado el 2006 y es una plataforma madura a comparación de Dart además de una comunidad creciente.
      En este enlace adicional http://blog.oio.de/2011/12/08/future-of-gwt-and-gwt-2-5/ . Al final el autor dice: "GWT es en mi opinion el mejor framework para construir aplicaciones web para la web, la web como lo es hoy. La web puede cambiar - puede ser que Dart despegue y cambie la web. Pero esa es otra historia..."

      Eliminar
    2. Muchas Gracias, Juan!
      Te felicito por tu blog, sigue así!

      Saludos!

      Eliminar
  2. Great GWTP video tutorials http://www.youtube.com/playlist?list=PL29DDDC847F63AF82

    ResponderEliminar
  3. Que bien por tu articulo, bastante explicativo... sobre todo como en el caso personal que quiero migrar de GWT A GWTP !!!!!!

    ResponderEliminar