jeudi 10 décembre 2009

Intégration de l’API Zoho Report dans Spring

Zoho Report permet de réaliser facilement en ligne des rapports et graphiques efficaces.
Une API REST est disponible pour soumettre ou récupérer des données dans ou depuis Zoho Report. Ce format n’est pas le plus adapté pour manipuler un nombre important de données organisées au sein d’une base de données. Zoho CloudSQL permet d’effectuer ces manipulations par requête SQL. Un driver JDBC vient compléter le tout pour offrir une véritable connectivité à cette base de donnée “on the cloud”.
Cependant, CloudSQL et donc le driver JDBC ne permettent, pour l’instant, que de la récupération de données (SELECT).
Pour utiliser complètement les possibilités de Zoho Report, le mieux est donc d’utiliser les librairies clientes disponibles (Java, Python et Google App Engine).
Pour Java, pour utiliser la librairie, il faut :
  • télécharger la librairie sur cette page
  • avoir un compte Zoho (LOGINNAME,PASSWORD)
  • demander une clé API (APIKEY)
  • une base de donnée crée (DATABASENAME) avec au mois une table (TABLENAME)
ReportClient rc = new ReportClient(APIKEY);
rc.login(LOGINNAME,PASSWORD);
String uri = getURI(LOGINNAME,DATABASENAME,TABLENAME);
rc.addRow(uri, new HashMap(), null);
Le but ici est d’utiliser Spring pour simplifier la gestion du client et de ses constantes de configuration (APIKEY, LOGINNAME, PASSWORD et DATABASENAME) :
ZohoReportClientWrapper rc = (ZohoReportClientWrapper) ctx.getBean("zohoClient");
rc.login();
rc.addRow("sampleTable", new HashMap());
Avec comme fichier de configuration Spring :

<bean id="zohoConfig" class="ZohoConfig">
<property name="apiKey" value="yourAPIKey"/>
<property name="databaseName" value="yourDBName"/>
<property name="loginName" value="yourZohoLogin"/>
<property name="password" value="yourZohoPasswd"/> 
</bean>

<bean id="zohoClient" class="ZohoReportClientWrapper" init-method="init">
<property name="config" ref="zohoConfig"/> 
</bean>
Pour cela, j’ai crée un projet Google : spring-zohoreport

mercredi 21 octobre 2009

Google App Engine (GAE) : création d'un environnement de développement

Installation et configuration pas à pas d'un environnement de développement java pour Google App Engine.

Installation du SDK Java

Google App Engine supporte Java 5 et Java 6. Cependant, l'application tournera sous Java 6 dans App Engine. Il est donc naturellement préférable que l'environnement de développement soit configuré en Java 6.


Tips : localisation des SDKs sur le disque
Créer un dossier "SDKs" sur votre disque dur. Par exemple, sous Windows, je l'ai créer sous C:\SDKs.
Créer une variable d'environnement pour ce dossier (SDKS_HOME).
C'est dans ce répertoire SDKS_HOME que vous pourrez installer les différentes versions de SDK.
Par exemple sous Windows, pour créer des variables d'environnement il faut soit aller dans Panneau de Configuration -> Système ou clique droit sur le bureau dans Poste De Travail -> Propriétés.
Cliquer alors sur l'onglet Avancé puis sur le bouton Variables d'environnement.
Entrer les variables suivantes dans Variables Systèmes :
SDKS_HOME = C:\SDKs
JAVA_HOME = %SDKS_HOME%\jdk1.6.0_16
Rajouter %JAVA_HOME%\bin à la variable PATH
Tout ceci permet de "switcher" rapidement de version de Java,
simplement en modifiant la variable JAVA_HOME.

Télécharger et installer le Java SE Development Kit (JDK). Pour vérifier l'installation, vérifier le numéro de version retourné par ces lignes de commande.
java -version
javac -version

Installation d'Eclipse et du Plugin Google

Un plugin Google pour Eclipse est disponible. Celui-ci est disponible pour les versions Eclipse 3.3 (Europa), Eclipse 3.4 (Ganymede) and Eclipse 3.5 (Galileo). Le dernière version Eclipse à l'écriture de ce post est la version 3.5 (Galileo).
Télécharger et installer Eclipse 3.5 (Galileo) Il est préférable de choisir le package Eclipse IDE for Java EE Developers pour profiter aussi du plugin Web Tools Platform (WTP).

Lancer Eclipse pour installer le Plugin Google par le Software Update d'Eclipse.
  1. Selectionner Help -> Install New Software
  2. Dans la zone de texte Work with taper http://dl.google.com/eclipse/plugin/3.5
  3. Cliquer sur le bouton Add puis sur OK dans la zone de dialogue.
  4. Cocher les composants "Google Plugin for Eclipse 3.5" et "Google App Engine Java SDK"("Google Web Toolkit SDK" pourra être installer plus tard si nécessaire).
  5. Une fois l'installation terminée Eclipse doit être redémarré.
Voilà, il faut maintenant se lancer en créant son premier projet.

mercredi 27 mai 2009

Traitement asynchrone avec une api REST

Une des critiques faite sur REST est le fait de son attachement au protocole HTTP. Ce protocole est "déconnecté" : il est impossible de reprendre une connexion précédente. Cela pose un problème dans le cadre de longs traitements asynchrones et de notifications.

Une possibilité pour palier à cette faiblesse est de considérer elle aussi cette transaction comme une ressource. Cette ressource est retournée immédiatement au client suite au premier appel. Ensuite, le client pourra récupérer l'état de cette transaction. Par exemple, supposons que nous souhaitons lancer un batch "batch1" de manière asynchrone :

GET /batchs/batch1 HTTP/1.1
Host: xyz.com
Content-Type: application/xml; charset=utf-8


HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
Location: /transactions/1234
http://xyz.com/transactions/1234


La réponse est immédiatement renvoyée et contient l'URI de la transaction utilisée. Le client peut consulter cette ressource pour connaitre le status de son traitement en cours.

GET /transactions/1234 HTTP/1.1
Host: xyz.com
Content-Type: application/xml; charset=utf-8


HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
Content-Length: nnn

batch1
In Progress

vendredi 6 février 2009

Internationalisation (i18n) en Javascript


Difficile de gérer le multilinguisme (i18n) en Javascript ! Et pourtant, on est souvent tenté de rapidement écrire dans son code des messages destinés à l'utilisateur. La gestion a posteriori de plusieurs langues devient alors un casse tête. Mieux vaut anticipé et externaliser ses libellés.
var labels_fr =  {
'hello' : 'Bonjour {0}, tu as {1} ans',
'quit' : 'Quitter ?'
}
var labels_en =  {
'hello' : 'Hello {0}, you are {1}',
'quit' : 'Quit ?'
}

La classe ci-dessous permet d'obtenir simplement le libellé souhaité en fonction de la langue :
var i18n = new I18n();
i18n.load(labels_fr);
i18n.translate('hello','JC', '33');

Plus propre, non ?
La classe en question (UPDATE 18/10/2010 : prise en compte de plusieurs patterns) :
/**
* I18n est une classe permettant d'obtenir un libellé
* caractérisé par une clé dans une map contenant un
* ensemble de libellés traduits dans la langue choisie
* @constructor
*/
var I18n = function(){}

/**
* Charge la map de clés/libellés
* @param {Object}  translations Les clés/libellés traduits
* @constructor
*/
I18n.prototype.load = function(translations) {
this._translations = translations;
}

/**
* Remplace les nombres entre accolades ({0}) par les
* chaînes de caractères passées en paramètre
* exemple  : _format('Hello {0} ! ', 'guy') => Hello guy !
* @param {String}  format La chaîne de caractère à formater
*/
I18n.prototype._format = function(format) {
var args = arguments[1];
return format.replace(/\{(\d+)\}/g, function(m, i){
return args[i];
});
}

/**
*  Retrouve le libellé correspondant à la clé passée en paramètre
* et le formate en fonction des paramètres supplémentaires
* exemple  : translate('hello', 'guy') => Hello guy !
* @param {String}  key La clé à traduire
*/
I18n.prototype.translate = function(key) {
if (typeof(this._translations)!='undefined' && this._translations[key]) {
return this._format(this._translations[key],Array.prototype.slice.call(arguments,1));
}
return key;
}