Internationalisation i18N avec GWT
- vendredi, août 5 2011
- Par littlewing
- Category Java EE
- Tags gwt, i18n, java, javaee, Planet-APRIL, Planet-Libre
- aucun commentaire
Me voila arrivé dans mon projet ou j'ai envie d'externaliser les chaînes de caractères pour pallier aux différents problèmes de locale qui peuvent être soit la locale utilisé dans les composants GWT, soit un quelconque problème d'enc@$ding dans les libellés.
Venant du monde JSF j'ai d'abord pensé qu'il fallait passer par des ressources bundle... que nenni !!!
Vous avez deux options ; faire tout à la main comme indiqué dans la documentation officielle utiliser l'outil de génération fourni en standard avec le compilateur GWT
J'exposerai dans ce billet deux types d'externalisation :
- l'externalisation des messages/constantes utilisés dans le code
- l'externalisation des messages contenus dans les fichiers ui.xml
Configuration préalable
Pour activer la prise en compte de l'internationalisation ou i18n pour les intimes, il faut d'abord ajouter la configuration dans le fichier module.gwt.xml
<inherits name="com.google.gwt.i18n.I18N" /> <extend-property name="locale" values="fr" /> <extend-property name="locale" values="en" />
On obtient donc le fichier suivant :
<?xml version="1.0" encoding="UTF-8"?> <module rename-to="admin"> <inherits name="com.google.gwt.user.User" /> <inherits name="com.google.gwt.logging.Logging" /> <inherits name="com.google.gwt.i18n.I18N" /> <inherits name='com.google.gwt.user.theme.chrome.Chrome' /> <inherits name="info.touret.winecellar.userinfo.UserInfo" /> <inherits name="info.touret.winecellar.dao.persistencecommon" /> <inherits name="com.googlecode.objectify.Objectify" /> <inherits name='com.google.gwt.activity.Activity' /> <inherits name="com.google.web.bindery.requestfactory.RequestFactory" /> <source path="client" /> <entry-point class="info.touret.winecellar.admin.client.Admin"></entry-point> <extend-property name="locale" values="fr" /> <extend-property name="locale" values="en" /> </module>
l'externalisation des messages/constantes utilisés dans le code
Les messages et constantes
l'API i18n de GWT embarque de nombreuses classes avec des responsabilités bien déterminées :
Constants
: des constantes externaliséesMessages
: les messages et phrases externalisées ( des paramètres sont possibles )ConstantsWithLookup
: équivalent àConstants
mais avec un comportement dynamique- Dictionary : Un dictionnaire embarqué dans la page hôte
Localizable
: Spécialise le comportement d'une classe en fonction d'une ressource donnéeDateTimeFormat
,NumberFormat
:Formattage
des des dates et nombres en fonction de la locale.
Il est également possible d'externaliser les messages contenus dans les page ***.ui.xml
.
Création des messages
Voici ce que j'ai fait avec l'API Messages
J'ai crée une interface AdminMessages
import com.google.gwt.i18n.client.LocalizableResource.DefaultLocale; import com.google.gwt.i18n.client.LocalizableResource.Generate; import com.google.gwt.i18n.client.Messages; @Generate( format = { "com.google.gwt.i18n.rebind.format.PropertiesFormat" }, fileName = "AdminMessages", locales = {"fr","en","default"}) @DefaultLocale("en") public interface AdminMessages extends Messages { @DefaultMessage("insert failed") @Key("insertko") public String insertko(); @DefaultMessage("insert is ok") @Key("insertok") public String insertok(); @DefaultMessage("The parameters are wrong") @Key("udpatefailwithparameters") public String udpatefailwithparameters(); @DefaultMessage("Update failed") @Key("udpatefail") public String updatefail(); }
J'ai indiqué au niveau de la classe que je souhaitai que le compilateur génère les fichiers properties
correspondants avec pour base le nom AdminMessages
. J'ai aussi spécifié les locales disponibles et celle par défaut.
Ensuite, pour chaque méthode, j'ai spécifié le message par défaut ainsi que la clé utilisée lors de la génération.
Dans mon module, j'accède aux messages de la manière suivante :
AdminMessages constants ; [...] constants= GWT.create(AdminMessages.class); [...] Window.alert(constants.insertok());
Génération des resourcebundle
GWT permet la génération des fichiers properties
avec les clés définies précédemment dans l'interface. Lors de la compilation, il faut ajouter le paramètre -extra pour la génération soit effective.
Si vous utilisez maven, la configuration de votre plugin devrait ressembler à quelque chose comme ça :
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>gwt-maven-plugin</artifactId> <version>2.3.0-1</version> <dependencies> <dependency> <groupId>com.google.gwt</groupId> <artifactId>gwt-user</artifactId> <version>${gwt.version}</version> </dependency> <dependency> <groupId>com.google.gwt</groupId> <artifactId>gwt-dev</artifactId> <version>${gwt.version}</version> </dependency> <dependency> <groupId>com.google.gwt</groupId> <artifactId>gwt-servlet</artifactId> <version>${gwt.version}</version> </dependency> </dependencies> <configuration> <appEngineVersion>${gae.version}</appEngineVersion> <logLevel>INFO</logLevel> <style>${gwt.style}</style> <runTarget>/Winecellar.html</runTarget> <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs> __<extraParam>true</extraParam>__ <server>com.google.appengine.tools.development.gwt.AppEngineLauncher</server> <copyWebapp>true</copyWebapp> <modules> <module>info.touret.winecellar.admin.Admin</module> <module>info.touret.winecellar.winecellar</module> </modules> <i18nMessagesBundle>info.touret.winecellar.admin.client.AdminMessages</i18nMessagesBundle> </configuration> <executions> <execution> <id>gwtcompile</id> <phase>prepare-package</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin>
J'obtiens donc les fichiers suivants dans le répertoire target/extra/
- AdminMessages_fr.properties
- AdminMessages_default.properties
- AdminMessages_en.properties
Avec un contenu ressemblant à ça :
# Generated from info.touret.winecellar.admin.client.AdminMessages # for locale en insertko=insert failed insertok=insert is ok udpatefail=Update failed udpatefailwithparameters=The parameters are wrong
Il ne vous reste plus qu'à copier les fichiers dans le répertoire src/main/resources/mon package de l'interface
Petit bémol sur la version 2.3 du toolkit de google, si vous mettez des apostrophes, il y aura une exception bloquante à l'execution
java.text.ParseException: Unterminated single quote ...
Le problème est connu coté google, à voir pour la suite ...
Internationalisation des fichiers ui.xml
Tout d'abord, je vous conseille de lire attentivement la documentation officielle , elle est bien faite
Voila ce que j'ai fait dans mon code
Pour paramétrer la génération :
à la racine de mon fichier ui.xml
<!DOCTYPE ui:UiBinder SYSTEM "dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' ui:generateFormat='com.google.gwt.i18n.rebind.format.PropertiesFormat' ui:generateKeys="com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator" ui:generateLocales="default,en,fr"
Pour la description du message
On ajoute les libellés avec la balise ui:msg
<g:header><ui:msg description="users title">Users </ui:msg></g:header>
Ensuite, a l'instar des messages, on lance la compilation gwt avec le paramètre -extra
. On obtient les fichiers présents avec pour nom le chemin absolu ( package inclus ) . Ex : info.touret.....AdminConsoleAdminConsoleUiBinderImplGenMessages_default.properties
. Il nous reste plus qu'à le copier dans le répertoire src/main/resources/ mon package du fichier ui.xml
Forcer l'application d'une locale
Contrairement à JSF/JSP , l'application de la locale n'est pas automatique suivant la locale envoyée par le navigateur . On peut forcer la locale en appliquant le paramètre locale dans l'url (ex. &locale=fr
). A voir si je mets une combobox de sélection , un filtre (API Servlet ) pour appliquer la locale directement ou si je gère ça dans le point d'entrée GWT.
Encoding
Attention à l'encoding des fichiers! Il faut impérativement que les fichiers soient encodés au format UTF-8.
Exemple et code source
Le code est disponible sur le référentiel google à cette adresse : code.google.com/p/my-wine-cellar/source/browse/
Bye Dropbox, Hello Ubuntu One
- mercredi, août 3 2011
- Par littlewing
- Category Ubuntu
- Tags one, Planet-APRIL, Planet-Libre, PUF, ubuntu
- 12 commentaires
Depuis quelques temps ,j'hésitai à quitter le service dropbox et passer sur ubuntu one. Le changement des conditions d'utilisation de ce premier m'a fait sauter le pas.
Ubuntu One existe depuis quelques temps sur mon os préféré. Il permet entre autres
- d'avoir un espace gratuit de stockage de 5Go ( au lieu de 2 sur dropbox )
- de synchroniser sur différents médiums ( ubuntu, android, bientôt windows )
- d'écouter de la musique stockée sur le cloud via une application android ( à l'instar de google music ou amazon )
- de synchroniser les contacts
Personnellement, je ne recherche que la première partie qui est le stockage et la synchronisation de fichiers. Par rapport à Dropbox, j'ai même gagné l'upload automatique des photos prises par mon téléphone android .
L'utilisation très simple et intégré par défaut dans l'interface utilisateur Ubuntu.
Ne souhaitant pas réinventer la roue, voici la procédure officielle d'installation sur Ubuntu Natty :
- La documentation officielle décrit la procédure d'installation
- et la procédure de gestion des fichiers
Pour ceux qui sont encore sous windows, canonical met à disposition la version beta du client windows ( à vos risques et périls ...)
Paramétrer votre blog dotclear pour une recherche opensearch
- jeudi, juillet 28 2011
- Par littlewing
- Category Logiciels Libres
- Tags dotclear, opensearch, Planet-APRIL, Planet-Libre
- 2 commentaires
Qu'est-ce qu'opensearch ?
Pour faire simple et pour ne pas me substituer à une documentation déjà présente et bien fournie, c'est ce qui vous permet d'avoir un moteur recherche présent dans firefox, et consorts
Un exemple :
Pour ajouter votre blog, c est assez simple
Créer un fichier dc_opensearch.xml avec le contenu suivant :
<?xml version="1.0" encoding="UTF-8"?> <OpenSearchDescription xmlns="a9.com/-/spec/opensearch/1.1/"> <ShortName>Qu'est-ce qu'on se fait ch...</ShortName> <Description>Rechercher sur le blog Qu'est-ce qu'on se fait ch...</Description> <Tags>alexandre touret</Tags> <Url type="text/html" template="blog.touret.info/blog/index.php/?q={searchTerms}"/> </OpenSearchDescription>
Modifiez les contenus des éléments selon les adresses de votre site.
Modifiez via l'éditeur de thème le fichier user_head.html
de votre thème et ajouter le contenu suivant :
<!-- # This template is included at the end of _head.html template --> <link rel="search" class="blog.touret.info/common-blog/dc_opensearch.xml" type="application/opensearchdescription+xml" title="blog.touret.info" />
Maintenant, le moteur de recherche apparaît dans votre navigateur, il ne vous reste plus qu'à l'ajouter!
Utilisation des services web exchange 2010 en java
- lundi, juillet 25 2011
- Par littlewing
- Category Java EE
- Tags exchange, jav