insideIT.fr : le blog des architectes IT de SFEIR

Aller au contenu | Aller au menu | Aller à la recherche

vendredi 15 janvier 2010

Evénement : Conférence "Jump Camp 4 IT" jeudi 21 janvier à 19h

Jeudi prochain aura lieu le premier opus du Jump Camp 4 IT.

Alors Jump Camp 4 IT, c'est quoi ?

Jump Camp 4 IT est une mini conférence en soirée sur Paris mêlant présentations et ateliers de coding, destinés aux passionnés des technologies de l'information.
Ainsi, ce qui est intéressant dans ce format, c'est que cela vous permet de mettre un premier pied à l'étrier sur le framework présenté, et non pas juste d'écouter une présentation théorique. Il est donc conseillé de venir avec son ordinateur portable pour profiter pleinement des présentations ;)

Ah, et petit détail qui ravira tout le monde : c'est gratuit.

Le premier opus de la série aura lieu jeudi prochain, soit le 21 janvier, de 19h à 21h.
Au programme, 6 présentations/séances de coding live autour des dernières technologies/tendances web du moment :

  • Surprise... : une présentation/annonce surprise par Didier Girard
  • Atmosphere :  un framework permettant de faire des applications web asynchrones (Comet) à partir de simples POJO (https://atmosphere.dev.java.net)
  • HTML5 : découverte de html5 step by step
  • Robots Wave et le WadRobotFramework : un framework qui simplifie énormément la création de robots pour Google Wave (http://goo.gl/6pOC)
  • Sisyphe version GWT : une interface à refaire ? reprogrammer ? Non, utilisez dès maintenant sisyphe.
  •  gwt-mvc : Framework pour GWT permettant de structurer le code client en suivant le design pattern MVC (http://code.google.com/p/gwt-mvc/

Si vous souhaitez vous inscrire, connaître le lieu exact de la conférence, ou avoir plus de détails sur les présentations, c'est par ici.

lundi 23 novembre 2009

La conférence "Innovation WEB" fait son retour

Le 4 décembre 2008, l'association GET (Google EFREI Technologies) organisait en association avec SFEIR une conférence sur les technologies Google.

Fort de son succès, une deuxième édition est programmée pour le 11 décembre 2009.

Cette année, il sera question d'Android, de Google App Engine, de GWT, de Google Wave et des standards du WEB (HTML5, CSS3, SVG).

Les intervenants de cette année seront Ludovic Perrier, Didier Girard et Patrick Chanezon.

Les conférences se tiendront de 13h30 à 16h30 dans les locaux de l'EFREI.


A la fin de la conférence aura lieu un cocktail, ce dernier sera suivi d'un atelier de développement Android organisé en association avec le Paris GTUG.

Pour plus d'informations, rendez vous sur le site de l'association.

jeudi 1 octobre 2009

Accélérez vos applications GWT avec Google Chrome Frame

Il y a un peu plus d'une semaine, Google annonçait la sortie de Google Chrome Frame.
Vous en avez surement déjà  beaucoup entendu parler.

Pour rappel, il s'agit d'un plugin s'intégrant à Internet Explorer et permettant de bénéficier
du moteur de rendu de Google Chrome, lui même basé sur WebKit.

Chrome Frame ne vient pas complètement remplacer le moteur de rendu d'Internet Explorer, il ne prend la main que si l'utilisateur ou la page qu'il visite le demandent explicitement.



Si vous souhaitez spécifier que votre page doit être chargée par Chrome Frame, il vous suffit de rajouter la balise suivante :

<meta http-equiv="X-UA-Compatible" content="chrome=1">


Sur le plateau de développement où je suis actuellement en mission, nous développons des applications GWT. Il s'agit d'applications de gestion dont les traitements côté client peuvent parfois être assez importants. La fluidité sous Internet Explorer n'est donc souvent pas optimale quand on la compare à celle sous Firefox ou Chrome.

Malheureusement, comme dans de nombreuses entreprises, le navigateur installé sur les postes de nos utilisateurs est Internet Explorer et faire installer un second navigateur pour optimiser la consultation de nos applications n'est pas vraiment une possibilité.

A l'annonce de la mise à disposition de ce plugin, nous avons décidé de le tester sur nos applications et les résultats se sont montrés vraiment impressionnants. Les gains en termes de rapidité d'exécution et de fluidité sont tels que l'adoption a été quasiment immédiate par le client.
Certes, tout n'est pas rose, nous avons eu quelques petites surprises d'affichage et le plugin est encore très jeune mais globalement pour un effort vraiment minime, les gains en termes de performance sont au-delà de ce que n’importe quelle optimisation de notre application aurait pu donner.


Le site officiel de Google Chrome Frame
L'annonce sur le site de GWT
Chrome Frame et Google Wave

jeudi 13 août 2009

Utiliser des CSS avec Uibinder

Pour revenir sur un billet précédent, dans lequel un widget basique était conçu avec UiBuilder, nous avions pu constater la puissance de la technologie, mais le résultat n'était pas visuellement appétissant.

Voilà qui est maintenant réparé avec l'utilisation des CSS avec UiBinder pour donner une meilleure apparence aux widgets. Ce fut aussi l'occasion d'utiliser une autre fonctionalité à venir de GWT, le ClientBundle, qui permet à l'instar de l'ImageBundle de transmettre toutes ses ressources au client à travers une seule requête HTTP.


Feuille CSS et UiBinder

mercredi 12 août 2009

Prendre de l'avance sur GWT 2.0

Google Web Toolkit étant un projet open source, il est possible de suivre l'avancement du projet au jour le jour sur le dépôt svn officiel.

On peut donc voir les fonctionnalités promises pour la version 2.0 apparaitre peu à peu, et on a récemment constaté l'apparition dans le code d'UiBinder, qui permet de construire ses interfaces GWT avec des templates en XML au lieu du code Java habituel.

C'était donc l'occasion rêvée de prendre le temps de compiler une version snapshot et de tester à travers un exemple simple l'efficacité d'UiBinder.

Le résultat de ces expérimentations peut être trouvé ici :

Télécharger GWT r5926

Un exemple d'utilisation

On retiendra que la conception d'interfaces avec cette technologie est très agréable et offre une séparation bienvenue entre le visuel et le code métier. Tout n'est pas rose cependant, puisqu'on perd entre autres les possibilités liées au code java telles que les possibilités de refactoring, mais gageons qu'une fois que l'utilisation de cette technologie se démocratisera, de nombreux outils permettront de l'utiliser pour améliorer la productivité.

mercredi 8 avril 2009

Développez en Java vos applications Google App Engine :

Il y a à peu près un an, Google ouvrait l'App Engine aux développeurs, il n'était alors possible de déployer que des applications développées en Python.
Pour rappel, Google App Engine est une offre de Cloud Computing permettant aux développeurs d’héberger leurs applications Web sur les serveurs de Google. Les applications ainsi hébergées bénéficient de ce fait de la même capacité de montée en charge que les services Google tels que Gmail ou Google Finance.
Google n’est pas la seule entreprise positionnée sur ce secteur, bien que pas tout à fait similaires, Amazon et Microsoft ont eux aussi leurs offres avec respectivement AWS et Windows Azure.
Un des atouts de Google App Engine c’est que gratuitement un développeur peut déployer une application qui soit accédées à raison de 5 millions de pages vues par mois. Ce qui est somme toute une offre d’hébergement intéressante. Au-delà de ces quotas, il est possible d’acheter des ressources supplémentaires.
Depuis quelques mois, nous pouvions voir dans la roadmap de ce projet que le support d’autres langages était un des objectifs de Google. Aujourd'hui, c’est chose faite, Google ouvre son service à une nouvelle communauté et contrairement à leur poisson d’avril, ce n’est pas Fortran mais bien Java qui est désormais supporté.
Cette nouvelle devrait donc être accueillie avec un vif enthousiasme lorsque l’on sait que le support de Java a été l’une des premières évolutions suggérées par les développeurs lors de la sortie de la première version de l’App Engine.
La version Java ne déroge pas au qualificatif de « Simple d’utilisation » qui caractérisait la version Python. En effet, il n’y a pas de différence majeure dans l’approche qu’ont ses deux dernières. Un atout supplémentaire de la version Java et qui a son importance, c’est le fait qu’elle s’accompagne d’un plugin Eclipse. Il est ainsi possible de créer une application et de la déployer en quelques clics.
De plus, l’intégration avec GWT (Google Web Toolkit) est enfantine et proposée par défaut par le plugin.
L’environnement de développement App Engine Java supporte les versions Java 5 et Java 6, sachant que sur les serveurs distants c’est la 6 qui est supportée. Les pré-requis au développement et au déploiement d’applications sur la plate-forme sont relativement faibles : avoir installé Java et le SDK de l’App Engine. L’installation du plugin Eclipse est bien entendu un plus non négligeable.
L’administration des applications se fait via la même interface que pour les applications Python. Il est ainsi possible de voir la répartition de la charge dans le temps, les requêtes HTTP les plus récurrentes, le taux d’utilisation ramené aux quotas. Il est également possible de consulter les logs. Enfin, une page permet d’accéder aux données stockées dans le Datastore.
Etudions de plus près l’architecture d’un projet et l’utilisation des APIs

Passons à la pratique : 

Les applications Google App Engine doivent être structurées en respectant l’arborescence WAR, ainsi, si vous créez un projet via le plugin Eclipse, vous obtiendrez une structuration semblable à celle-ci :

Cette arborescence de projet ne présente pas de spécificité particulière, on notera la présence d’un fichier web.xml permettant d’assurer le mapping entre les URLs et les classes des Servlets.
Lorsque vous déployez une application sur Google App Engine, une association s’opère entre les fichiers que vous transférez sur les serveurs de Google et les applications que vous êtes en mesure d’administrer. Cette association est possible grâce à un identifiant que vous vous devez de retranscrire dans le fichier appengine-web.xml. Ce fichier est l’équivalent du fichier app.yaml de la version Python de l’App Engine.
Les Servlets sont tout à fait communes et ne différent pas de celles que l’on peut développer dans une application traditionnelle. La Servlet d’un HelloWorld pourrait donc se présenter ainsi :

package com.sfeir.demo;

import java.io.IOException;
import javax.servlet.http.*;

public class DemoServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        resp.setContentType("text/plain");
        resp.getWriter().println("Hello, world");
    }
}


Maintenant que nous savons qu’il n’est pas difficile de créer un projet, intéressons nous aux APIs spécifiques de Google App Engine.

Utiliser les APIs :

Authentification

Ajouter un système d’authentification des utilisateurs se fait tout aussi facilement qu’avec la version Python :

package com.sfeir.demo;

import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class DemoServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();

        if (user != null) {
            resp.setContentType("text/plain");
            resp.getWriter().println("Hello, " + user.getNickname());
        } else {
            resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
        }
    }
}


Ici, on utilise le UserService pour récupérer l’utilisateur actuellement connecté à l’application. S’il y a bel et bien un utilisateur authentifié, nous lui affichons un message de bienvenue et si ce n’est pas le cas, l’API nous permet de le rediriger vers une page de login. Lorsque vous travaillez en « local », le système d’authentification est émulé, il n’y a pas de vérification à proprement parler de l’existence des utilisateurs. Lorsque vous déployez votre application, le UserService se base sur les Google Accounts pour vérifier l’existence des utilisateurs.

Il est également possible de savoir si l’utilisateur actuellement authentifié est un administrateur de l’application et ainsi de lui donner accès ou non à certaines fonctionnalités.

Persistance


Attention, comme pour la version Python de Google App Engine, le stockage des données ne s’effectue pas dans une base de données relationnelle. Google dispose de son propre formalisme de stockage des données qui s’apparente à une Map multidimensionnelle partagée.
Le développeur dispose de trois solutions distinctes pour persister ses données, en effet, Google App Engine Java implémente JDO (Java Data Object), JPA (Java Persitance API) et met également à disposition une API de plus bas niveau (Datastore API).
Dans cette version de Google App Engine, Google pousse un Framework de persistance : DataNucleus. Sa configuration se fait très simplement (voir doc pour plus de détails)
Voici un exemple utilisant JDO, la définition des données à persister se fait par annotation.
Ci-dessous, l’objet Comment est défini comme pouvant être persisté, en le sauvant, les éléments annotés comme @Persistent feront parti de la sauvegarde.

package com.sfeir.demo;

import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.users.User;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Comment {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;

    @Persistent
    private User author;

    @Persistent
    private String content;

    @Persistent
    private Date date;

    public Comment(User author, String content, Date date) {
        this.author = author;
        this.content = content;
        this.date = date;
    }

}

Il est ensuite très simple de manipuler cet objet au travers de l’API. Ainsi, pour persister une instance de cet objet, on peut utiliser le PersistenceManager de la manière suivante :

Comment comment = new Comment(user.getNickName(), content, new Date()) ;
PersistenceManagerFactory pmfInstance =
        JDOHelper.getPersistenceManagerFactory("transactions-optional");
      PersistenceManager pm = pmfInstance.get().getPersistenceManager();
        try {
            pm.makePersistent(comment);
        } finally {
            pm.close();
        }



Avec ce PersistenceManager, il est tout aussi simple de récupérer un objet pm.getObjectById(…) ou encore de le supprimer pm.deletePersistent(…).
Au même titre qu’il était possible d’interroger la base au travers du GQL dans la version Python, il est ici possible d’utiliser un langage de requête proche de SQL pour récupérer des données, il s’agit de JDOQL.
On pourrait récupérer la liste de nos commentaires ainsi :

PersistenceManagerFactory pmfInstance =
        JDOHelper.getPersistenceManagerFactory("transactions-optional");

PersistenceManager pm = pmfInstance.get().getPersistenceManager();

String query = "select from " + Comment.class.getName();
List<Comment> comments = (List<Comment>) pm.newQuery(query).execute() ;


Gestion d'un cache mémoire


Afin de ne pas surcharger le Datastore avec des requêtes récurrentes, il peut être intéressant de stocker un certain nombre d’informations dans un cache mémoire. Cela peut se faire très simplement au travers de l’utilisation de la Memcache API.

cache = CacheManager.getInstance().getCacheFactory().createCache(Collections.emptyMap());
cache.put(‘‘cachedInteger’’, 25) ;
Integer cachedValue = (Integer) cache.get(‘‘cachedInteger’’);



Dans l’exemple ci-dessus, après avoir récupéré l’instance du cache mémoire, on y insère un entier à la clef « cachedInteger » au travers d’un put. Un simple get avec la clef nous permet de récupérer la donnée que nous avions mise en cache.
Le cache est utilisé pour cet exemple de manière très simpliste mais on pourrait imaginer l’utiliser pour retourner des informations ayant plus de valeur, comme le contenu RSS de l’application ou encore une page fréquemment requêtée.
Cette API de cache propose d’autres fonctionnalités intéressantes comme la possibilité de définir une période de validité pendant laquelle les données peuvent être considérées comme « fraiches ». Différentes politiques de gestion sont également applicables, ainsi il est possible de n’ajouter la donnée que si celle-ci est déjà présente ou réciproquement.

Envoi de mail


L'envoi de mail fait partie des fonctionnalités intégrées à Google App Engine et relativement simples à mettre en place au sein d'un projet.
Dans cette version Java, l'API implémente l'interface JavaMail, pour des raisons de sécurité, seules les adresses d’un administrateur de l’application ou celle de l’utilisateur couramment authentifié peuvent être spécifiées comme adresses de l’émetteur.
       

Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);

        String msgBody = "Contenu du mail";

        ...
        Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("admin@mondomaine.com"));
        msg.addRecipient(Message.RecipientType.TO,new InternetAddress("destinataire@sondomaine.com", "Destinataire"));
        msg.setSubject("Email envoyé par Google App Engine");
        msg.setText(msgBody);
        Transport.send(msg);


L’exemple ci-dessus montre l’envoi d’un mail basic, sachez qu’il est également possible d’ajouter des pièces jointes (voir types MIME autorisés) avec la contrainte toutefois que l’e-mail ne dépasse pas les 1mb.

Comme pour la version Python, il est également mis à la disposition des développeurs une API permettant d’interroger des hôtes distants (via l’API URL FETCH) et une autre permettant de manipuler des images.

Cette version de Google App Engine étant toute récente, il va être intéressant de suivre l’adhésion des développeurs de la communauté Java à ce service. D’une part, elle offre une grande facilité de développement et de ce fait un gain de temps dans l’élaboration d’applications, ce qui devrait en attirer plus d’un. D’autre part, tout comme pour la version Python un certain nombre de quotas et de restrictions sont à prendre en compte lors de l’utilisation de ce service, ce qui exclu certain types d’applications de cette offre d’hébergement.

Cette nouvelle version est également un beau coup de pousse donné à GWT, en effet le plugin Eclipse permet de créer en quelques clics une application GWT pour Google App Engine et devrait donc  amener davantage de développeurs à adopter ce Framework Web.

Google Guice sera peut être un autre des bénéficiaires de cette version Java, bien qu’il ne soit pas poussé outre mesure par Google pour être associé à Google App Engine, sa légèreté et sa simplicité d’utilisation devrait lui permettre de s’intégrer facilement aux applications déployées sur la plate-forme.

Quoi qu’il en soit c’est une nouveauté que nous nous devons de suivre.

Références :

Pour s'inscrire
L'annonce officielle
Le Coud Computing
Tout sur Google App Engine
DataNucleus
Découvrir GWT
En savoir plus sur GUICE
Amazon Web Services
Windows Azure

jeudi 19 février 2009

Intégration de Guice avec les RemoteServiceServlet de GWT

La dernière version snapshot de Guice intégre des fonctionnalités intéressantes pour les Servlets, notamment de nouveaux Builders qui viennent du projet warp-servlet et qui permettent de configurer des mappings de Servlet ou de Filter directement dans un module. Vous pouvez obtenir les sources de l’exemple décrit dans cet article ici.

Au lieu de définir nos RemoteServiceServlet dans le web.xml (ce qui est désormais le cas avec GWT 1.6), nous allons déclarer un GuiceServletContextListener et un GuiceFilter :


 1 <?xmlversion="1.0"encoding="UTF-8"?>
2 <web-app>
3
4
<!-- Default page to serve -->
5 <welcome-file-list>
6 <welcome-filecda.html</welcome-file>
7 </welcome-file-list>
8
9
<listener>
10 <listener-classcom.sfeir.server.CdaGuiceServletConfig
11 </listener-class>
12 </listener>
13
14
<filter>
15 <filter-nameguiceFilter</filter-name>
16 <filter-classcom.google.inject.servlet.GuiceFilter
17 </filter-class>
18 </filter>
19
20
<filter-mapping>
21 <filter-nameguiceFilter</filter-name>
22 <url-pattern/*</url-pattern>
23 </filter-mapping>
24
25
</web-app

GuiceServletContextListener crée une instance d’Injector avec la méthode getInjector(), nous pouvons alors définir notre module en redéfinissant cette méthode :


 1 public class CdaGuiceServletConfig extends GuiceServletContextListener
 2 {
 3     @Override
 4     protected Injector getInjector()
 5     {
 6         return Guice.createInjector(new ServletModule()
 7         {
 8             @Override
 9             protectedvoid configureServlets()
10             {
11                 serve("/cda/echo").with(EchoServiceImpl.class);
12                 serve("/cda/spreadsheet").with(SpreadSheetServiceImpl.class);
13 ...

Nous utilisons pour cela une classe anonyme qui hérite de ServletModule : les méthodes «serve» et «filter» de cette dernière nous permettent de faire l’équivalent de huit lignes de XML pour déclarer une Servlet ou un Filter en une seule ligne de Java.

«serve» fonctionne directement avec les RemoteServiceServlet de GWT (il faut néanmoins ajouter y l’annotation Singleton), par contre les scopes Session et Request de la classe ServletScopes ne peuvent pas être utilisés : nous allons devoir hériter de la classe RemoteServiceServlet pour y ajouter notre propre Scope Session et par la même occasion ajouter un champ «injector» qui contiendra l’objet Injector créé par notre classe CdaGuiceServletConfig.

Dans notre ServletModule, nous rajoutons un appel à «bind» qui associe l’interface SpreadsheetManager à une implémentation :


 1                 bind(SpreadsheetManager.class).
2 to(SpreadsheetManagerImpl.class);

Ainsi l’appel de getInstance de l’object Injector avec SpreadsheetManager.class en paramètre renverra une instance de SpreadsheetManagerImpl.


 1 @Singleton
2 public class SpreadSheetServiceImpl extends GuiceRPCServlet implements SpreadSheetService
3 {
4
5
@Override
6 public List<String> fetchSpreadsheetList()
7 {
8 SpreadsheetManager manager = injector.getInstance(SpreadsheetManager.class);
9 ...

Par défaut, l’Injector de Guice renvoie toujours une nouvelle instance. Nous pouvons également utiliser l’annotation Singleton ou dans le cas présent notre propre annotation GwtSessionScoped afin qu’une même instance soit réutilisée, par exemple le temps d’une session.


 1                 bindScope(GwtSessionScoped.class,
2 GuiceRPCServlet.SESSION);
3 bind(GoogleService.class).toProvider(
4 SpreadsheetServiceProvider.class).
5 in(GwtSessionScoped.class);

Ainsi les champs injectés de type GoogleService seront créés une première fois puis récupérés dans la session en cours. Ce mécanisme fonctionne quand l’Injector de Guice est appelé, il est donc exclu de l’utiliser sur des champs d’une RemoteServiceServlet.


 1 public class SpreadsheetManagerImpl implements SpreadsheetManager
2 {
3 @Inject
4 private GoogleService service;
5
6
@Inject
7 @Named("user")
8 private String username;
9 @Inject
10 @Named("pass")
11 private String password;
12
13
@Override
14 public void authenticate()
15 {
16 try
17 {
18 service.setUserCredentials(username,password);
19 } ...

L’annotation Named est utile pour injecter objets de même type sans avoir à créer de nouvelle annotation. La méthode statique «named» crée cette annotation pour l’utiliser dans les instructions de binding.


 1                 bindConstant().annotatedWith(named("user")).
2 to("cappelle.florent@gmail.com");
3 bindConstant().annotatedWith(named("pass")).
4 to("*************");

Finalement, Guice permet aussi d’ajouter des fonctions transverses à nos services en «bindant» un intercepteur sur un ensemble de méthodes :


 1                 bindInterceptor(subclassesOf(SpreadsheetManager.class),
2 returns(subclassesOf(List.class)),
3 new LoggingInterceptor());

Ici, LoggingInterceptor est appliqué aux classes qui héritent de SpreadsheetManager et plus particulièrement aux méthodes de ces classes dont le retour est de type List. Les classes d’interception doivent implémenter MethodInterceptor de l’API aopalliance.

Vous aurez sans doute deviné que LoggingInterceptor fait un log des appels de méthode, la sécurité et les transactions étant les autres exemples typiques d’utilisation des MethodInterceptor.

En conclusion, Google Guice constitue une alternative intéressante à Spring pour l’injection de dépendance. Dans certains cas, on pourra également utiliser les méthodes de la classe SpringIntegration afin de réutiliser une configuration XML existante.

Liens :

How to : Spring Security (ex Acegi) and GWT

As you know, Spring Security (previously Acegi) provides an easy and robust solution to secure web applications. Thereby, web developers do not have to deal with all that stuff in their source code, but just have to configure Spring Security to enable authentication and authorization for their application.

As it works pretty good with 'conventional' application, things go less cool with applications like GWT ones. This is mainly due to the asynchronous calls.

Lire la suite...

mercredi 11 février 2009

Editing Google Spreadsheets rows with Google Data API and GWT

In a previous article (here), we saw how to display Google Spreadsheets content with the Google Data API Java client and CellFeed objects.

This time, the proof of concept application shown below uses ListEntry objects to fetch our worksheets content, using header names (see (1) and (2) in the following screenshot) and unique identifiers (see (3)) instead of x and y positioning system.

You will find the source code at the bottom.

The following piece of code shows how to fetch every row entries in a worksheet into a HashMap which maps each row identifier to its ListEntry object:


  1         Map<String, ListEntry> listEntries =
2 new HashMap<String, ListEntry>();
3 List<WorksheetRow> rows = new ArrayList<WorksheetRow>();
4 try
5 {
6 ListFeed feed = sService.getFeed(new URL(sheetFeedURL),
7 ListFeed.class);
8 for (ListEntry entry : feed.getEntries())
9 {
10 WorksheetRow clonedRow = new WorksheetRow();
11 clonedRow.setTitle(entry.getTitle().getPlainText());
12 clonedRow.setId(entry.getId().substring(
13 entry.getId().lastIndexOf('/') + 1));
14 listEntries.put(clonedRow.getId(), entry);
15 CustomElementCollection elementColl =
16 entry.getCustomElements();
17 WorksheetRow.CustomElement rowElement =
18 new WorksheetRow.CustomElement();
19 for (String value : elementColl.getTags())
20 {
21 rowElement.put(value,
22 elementColl.getValue(value));
23 }
24 clonedRow.setElement(rowElement);
25 rows.add(clonedRow);
26 }
27 getSession().setAttribute("listEntries", listEntries);
28 } catch (MalformedURLException e) ...

Each ListEntry object has a list of «Tag» (column names) and a HashMap which maps each tag name to its value in the current entry. Note that each column name is automatically made unique.

To update a row with a modified WorkSheetRow object, we get its associated ListEntry object and set every value of the WorkSheetRow object with the «setValueLocal» method.


  1     public void updateWorkSheetRow(WorksheetRow row) throws AuthException
2 {
3 Map<String, ListEntry> listEntries = (Map<String, ListEntry>) getSession().getAttribute("listEntries");
6 ListEntry entry = listEntries.get(row.getId());
7 for (String tag : row.getElement().keySet())
8 {
9 entry.getCustomElements().setValueLocal(tag, row.getElement().get(tag));
10 try
11 {
12 entry.update();
13 } catch (IOException e)...

Then we simply have to call the modified entry update method.

Going further

Row editing in Spreadsheets API is not limited to the ListEntry class: Indeed, there is also a ListQuery class which enables advanced selection for your Worksheets.

Listing in reverse order:

In order to list the rows in reverse order, you just have to set the «reverse» property of a ListQuery object to «true» and pass this object to the SpreadsheetService object


  1     ListQuery query = new ListQuery(listFeedUrl);
2 query.setReverse(true);
3 ListFeed feed = service.query(query, ListFeed.class);
4 for (ListEntry entry : feed.getEntries())
5 { ...

Full-text search:

For full-text search, use the «setFullTextQuery» method. Note that you can pass several strings.


  1     ListQuery query = new ListQuery(listFeedUrl);
2 query.setFullTextQuery("Florent Tue");
3 ListFeed feed = service.query(query, ListFeed.class);
4 for (ListEntry entry : feed.getEntries())
5 { ...

Structured query:

Structured queries can filter the list by a particular value to a column name. You can also set the ordering of the listing with a column name.


  1     ListQuery query = new ListQuery(listFeedUrl);
2 query.setSpreadsheetQuery("name = 'Florent'");
3 query.setOrderBy("column:name");
4 ListFeed feed = service.query(query, ListFeed.class);
5 for (ListEntry entry : feed.getEntries())
6 { ...

Useful Links:

Article related downloads:

jeudi 11 décembre 2008

Roadmap GWT (1.6 et après)

Encore un post intéressant sur le blog de l'équipe GWT !
Cette fois, le sujet est le futur... Au programme de GWT 1.6 (prévu pour le premier trimestre 2009) :

* New compiled file deployment structure
* Migration from Tomcat to Jetty hosted mode server
* Uniform event handlers
* DatePicker, LazyPanel migrated in from incubator
* String performance improvements
* Compiler performance improvements

Et pour l'après 1.6 :

* Developer Guided Code splitting
* Analysis of compiled code, aka Story of your compile (SOYC)
* In-browser hosted mode, aka Out-of-process Hosted Mode (OOPHM)
* UI Binder
* Client Bundle
* RPC performance improvements

What's ahead for Google Web Toolkit

mercredi 10 décembre 2008

Google Visualization API pour GWT

La famille des APIs Google pour GWT s'agrandit avec la librairie Google Visualization pour GWT. L'annonce est encore chaude sur le blog de l'équipe GWT.

Le but de l'API Google Visualization est de permettre d'accéder à de multiples sources de données structurées pour les afficher, en choisissant parmi une large sélection de visualisations.

mercredi 3 décembre 2008

Release de SmartGWT

Sanjiv, le créateur de GWT-Ext vient de sortir la première release de SmartGWT. Sanjiv a réussi à sortir un wrapping de la librairie JavaScript SmartClient en à peine 4 mois !

SmartGWT reprend les principales fonctionnalités de GWT-Ext auxquelles s'ajoutent un databinding puissant, d'avantages de widgets (notamment le composant Calendar, un Google Agenda simplifié) et de meilleures performances d'affichage. Sanjiv a su prendre du recul par rapport à sa précédente expérience, et présente une librairie mieux adaptée au développement d'applications de gestion. Allez voir les sources, vous verrez que l'utilisation des composants graphiques et des datasources se fait de façon beaucoup plus simple qu'auparavant.

Utilisation d'une grille éditable à la volée

A cela s'ajoute une très grande réactivité de l'équipe : critiqués sur leurs styles un peu old school, ils sont déjà en train d'y remédier.

Quelques indicateurs :

  • GWT-Ext incite à passer sur SmartGWT : lien
  • Evolution du nombre de posts du google group GWT-Ext : lien

mardi 25 novembre 2008

Rejoignez nous le 4 décembre !

SFEIR et l'association G-EFREI Technologies organisent une grande conférence le jeudi 4 décembre 2008 à l'EFREI.

Au programme, des présentations et des ateliers traitant de RIA, Cloud Computing et mobilité.

Parmi les intervenants, Didier Girard parlera des RIA via une présentation de GWT, Christian Fauré de Cloud Computing et Jieren Wu de mobilité avec Android.

L'évènement est gratuit et ouvert à tous, reservez dès maintenant votre place en remplissant le formulaire ci-dessous.

Pour davantage d'informations et savoir comment vous rendre à cet évènement, c'est par ici.


vendredi 14 novembre 2008

Joda-Time pour GWT : Goda-Time

Pour les utilisateurs de GWT appréciant l'API Joda-Time, bonne nouvelle !

Goda-Time, a GWT port of Joda-Time, has just been forked from gwittir. Goda-Time is looking for volunteers.

Description du projet :

GWT port of Joda-Time

Originally found in the gwittir project. As of Nov 12th 2008 kebernet, the owner of gwittir, has been silent for 5 months. Goda-Time needed its own project anyway. I ripped Goda-Time out of the gwittir source tree and made it compile on its own.

Goda-Time still needs help with cleanup and unit tests. Goda-Time needs volunteers. Send a message to the group to indicate your interest.

En français :
Après une longue inactivité du projet Gwittir qui comprend une ébauche du port de l'API Joda-Time pour GWT, voici le projet Goda-Time qui reprend cette ébauche avec pour but de la compléter.
Ce projet est ouvert, toute participation est la bienvenue.

Goda-Time

mercredi 15 octobre 2008

Jetty or Tomcat for GWT 1.6 ?

Bruce Johnson (tech lead of the Google Web Toolkit ) :

The GWT team has started putting together a 1.6 roadmap, which we'll publish as soon as we have it nailed down. Two of the areas we want to work on for 1.6 are some improvements to hosted mode startup time and a friendlier output directory structure (something that looks more .war-like).

As part of this effort, we've all but decided to switch the hosted mode embedded HTTP server from Tomcat to Jetty. Would this break you? (And if so, how mad would you be if we did it anyway?)

Less than two months after the release of GWT 1.5, the GWT team is already asking the community for its opinion for GWT improvement for 1.6 roadmap. In this post, Bruce Johnson is asking the community if it would rather have Jetty or Tomcat as the hosted mode embedded HTTP. Unfortunately, I do not know Jetty enough to have an opinion. But if you know both Jetty and Tomcat, you should not hesitate to participate in this debate.

GWT et accessibilité

Google Web Toolkit Blog :

As described in our earlier article outlining ARIA support in GWT1.5, widgets now include basic support for W3C ARIA, an emerging set of Web standards that enable AJAX applications to work smoothly with screenreaders. But there is more to using an application than interacting with individual user interface widgets — overall usability is determined by the complete user experience.

We have improved the usability of Google Health for screenreader users by enhancing the built-in support available in GWT 1.5 via JavaScript. The resulting user experience enables users of screenreaders and self-voicing browsers to easily navigate the interface to obtain relevant auditory feedback.

Pour les personnes intéressées par la problématique d'accessibilité dans une application GWT, Google vient d’annoncer l’ajout de cette fonctionnalité dans Google Health. Pour rappel, Google Health est une application de gestion de dossiers médicaux états-uniens développée avec GWT.

mardi 14 octobre 2008

PureMVC Multicore for Java (compatible with GWT)

The first version of the PureMVC Multicore framework for Java which is compatible with GWT has been relased here under Creative Commons Attribution 3.0 license. For those who do not know MVC, you should look at Wikipedia. Then, if you want to know more about PureMVC, you should continue with the conceptual diagram and best practices. These documents demonstrate the Singleton version, they are a good introduction to PureMVC concepts.

lundi 29 septembre 2008

Google Developer Day Paris 2008 - Résumé de la journée

2888831206_678d2cdedf Le 18 septembre dernier, à l'ENSA (Ecole Nationale Supérieure d'Architecture), Google faisait étape à Paris pour son tour du monde 2008.

Cette journée avait pour ambition de présenter les technologies Google et de proposer aux développeurs français présents de participer à quelques séances pratiques de codage avec ses APIs et frameworks. Pour certains, c'était les premiers pas comme développeur d'App Engine ou de GWT et pour d'autres, l'objectif était déjà d'aller un peu plus loin et d'échanger avec d'autres présentateurs ou participants sur leur expérience dans ces technologies ou de voir comment les intégrer dans les développements de solutions diverses...

Après la traditionnelle file d'attente devant l'entrée du magnifique bâtiment de l'ENSA, l'évènement a commencé vers 10h00 par une présentation des thèmes de la journée: le standard d'interopérabilité de réseaux sociaux OpenSocial, la plateforme de développement pour téléphones mobiles Android, le framework de développement web GWT, le service d'hébergement d'applications web Google App Engine, et les outils de localisation géographiques basés sur Google Maps et Google Earth.

La présentation du programme de la journée à peine terminée, la foule des participants quittait le hall central pour prendre place dans les amphis et dans les salles équipées afin de suivre des présentations "magistrales" et des sessions de code.

Ces présentations ont été animées par des ingénieurs Google mais également par des acteurs du terrain, des ingénieurs d'entreprises qui mettent en œuvre ces technologies dans leur travail quotidien telles que Sfeir et Viadeo.

Pour ce qui est des " Sfeiriens ": Jieren Wu et Didier Girard ont pu faire découvrir Google Web Tookit lors d'une session de code. Bruno Guedes et Vincent Bostoen ont présenté Google App Engine.

Les thèmes abordés ont été très nombreux : mobilité avec Android et en démonstration une balle fluide et rebondissante; Cloud Computing où on a pu faire héberger un wiki développé bien sûr en Python pendant que dans une autre salle nos collègues Bruno Guedes et Vincent Bostoen montraient à quoi sert l'infrastructure App Engine et comment l'utiliser; RIA où le Directeur Technique de Sfeir Didier Girard a présenté GWT puis accompagné de notre collègue Jieren Wu ils ont aidé les développeurs à écrire une application GWT pendant que d'autres suivaient en amphi une présentation d'Ajax; navigateurs avec la plateforme Chrome et sa gestion innovante de processus; réseaux sociaux où Viadeo a fourni son expertise lors de la session de code dédiée principalement à OpenSocial, avec quelques touches des APIs de géolocalisation et d'intégration dans le Google App Engine; ... Beacoup de sujets intéressants donc mais on ne pouvait pas être partout à la fois!! Difficile pour les participants de faire un choix.

Tout au long de la journée, un espace de détente était accessible à tous. Une occasion de discuter des dernières APIs autour d'un BabyFoot ou encore d'argumenter sur GWT tout en jouant à la Wii. Pour les moins agités, une masseuse ainsi qu'une montagne d'oreillers étaient également à disposition.

La journée s'est terminée vers 21h00 autour d'un buffet, une occasion de discuter avec ceux qui créent les technologies mais également ceux qui les utilisent.

En définitive, ce fût une journée bien remplie, de laquelle chacun des participants est reparti avec un tee-shirt et une clé USB en forme de PLAYMOBIL. En attendant l'édition 2009 des Developer Days, n'hésitez pas à vous rendre sur http://code.google.com pour vous former aux technologies Google. Pour ceux qui veulent voir ou revoir les vidéos, rendez vous sur http://fr.youtube.com/view_play_list?p=22350CB6D86B7A2B.

mercredi 24 septembre 2008

Extension de la boîte à outil GWT

Google Web Toolkit Blog :

Following up on our earlier post, a release candidate of the Google Maps API Library for GWT is now available for download. This library provides a way to access the Google Maps API from a GWT project without having to write additional JavaScript code. The library gives you full control using the standard Maps components such as InfoWindows, Markers, MapTypes, and Geocoding. You can even use advanced features such as adding GWT widgets to the Map, creating custom overlays, custom map types, and other components.

In addition to maps, the Google API Libraries for GWT also provide libraries for Gears, Gadgets and the Google AJAX Search API. Please try out these release candidates and give us feedback, either through the issue tracker on code.google.com, or through the Google-Web-Toolkit or Google-Web-Toolkit-Contributors group.

C'est chaud bouillant !

Google vient d'annoncer la sortie de la release candidate de son API Google Maps pour GWT. Tout un programme qui ne se limite pas à l'accès des maps depuis GWT mais également à l'intégration de composants GWT dans les maps. Pour couronner le tout, cette librairie ne se limite pas seulement à Google Maps, mais vient également grignoter sur les plate-bandes de Gears, Gadgets et Google AJAX Search API.

Je me joins à l'équipe GWT pour vous inviter à tester cette librairie au plus vite !

mardi 2 septembre 2008

GWT in the AIR Milestone 1

Logo Adobe AIR Avec la sortie de Google Chrome, Didier Girard annonce sur onGWT : "le navigateur est la plateforme".

Pourtant la plateforme n'est pas encore morte. Par exemple, le projet GWT in the AIR vient d'annoncer la sortie de sa version Milestone 1. Pour rappel, l'objectif de ce projet est de permettre le développement d'application AIR, c'est à dire d'application desktop s'exécutant dans la runtime AIR d'Adobe, à partir de code GWT.

GWT in the Air rend l'API AIR d'Adobe disponible en GWT via JSNI. Ce projet fournit également des outils facilitant le développement d'application AIR en GWT dont des outils de test. Le point faible du projet est le manque de documentation bien que le chantier soit en cours. Pour le moment, il faut se référer au showcase et à la documentation AIR d'Adobe.




English version:

With Google Chrome release, Didier Girard announces on onGWT : "the browser is the platform".

But the platform is not dead yet. For instance, GWT in the AIR just released its Milestone 1 version. A quick reminder: the aim of this project is to allow the development of AIR applications, i.e. desktop applications running on top of the Adobe AIR runtime, from GWT code.

GWT in the AIR makes the Adobe AIR API available for GWT using JSNI. This project also provides tools to ease "GWT in Adobe AIR" development includint test tools. The weakness of this project is its lack of documentation but it seems to be progressing. For the moment, the showcase and Adobe AIR documentation should be your starting points.

- page 1 de 2