<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
xmlns:media="http://search.yahoo.com/mrss/"
> <channel><title>Blog Xebia France &#187; RIA</title> <atom:link href="http://blog.xebia.fr/category/ria/feed/" rel="self" type="application/rss+xml" /><link>http://blog.xebia.fr</link> <description>J2EE, Agilité et SOA</description> <lastBuildDate>Wed, 08 Feb 2012 09:23:16 +0000</lastBuildDate> <language>fr</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=</generator> <copyright>CC BY-NC-ND 2.0 http://creativecommons.org/licenses/by-nc-nd/2.0/fr/</copyright> <managingEditor>blog-france@xebia.com (Xebia France)</managingEditor> <webMaster>blog-france@xebia.com (Xebia France)</webMaster> <ttl>1440</ttl> <image> <url>http://blog.xebia.fr/videos/xebia-podcast.png</url><title>Blog Xebia France</title><link>http://blog.xebia.fr</link> <width>144</width> <height>144</height> </image> <itunes:new-feed-url>http://blog.xebia.fr/feed/podcast/</itunes:new-feed-url> <itunes:subtitle>Les podcasts de Xebia France vous permettent de suivre l&#039;actualité autour de Java, de l&#039;agilité, des technologies Web et bien d&#039;autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agi[...]</itunes:subtitle> <itunes:summary>Les podcasts de Xebia France vous permettent de suivre l&#039;actualité autour de Java, de l&#039;agilité, des technologies Web et bien d&#039;autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agile.</itunes:summary> <itunes:keywords>Xebia, Java, JEE, SOA, Agile, Méthodes, Agiles</itunes:keywords> <itunes:category text="Technology" /> <itunes:category text="Technology"> <itunes:category text="Software How-To" /> </itunes:category> <itunes:category text="Technology"> <itunes:category text="Tech News" /> </itunes:category> <itunes:author>Xebia France</itunes:author> <itunes:owner> <itunes:name>Xebia France</itunes:name> <itunes:email>blog-france@xebia.com</itunes:email> </itunes:owner> <itunes:block>no</itunes:block> <itunes:explicit>no</itunes:explicit> <itunes:image href="http://blog.xebia.fr/videos/xebia-podcast.png" /> <item><title>Composant Scroll Avec jQuery</title><link>http://blog.xebia.fr/2011/11/30/composant-scroll-avec-jquery/</link> <comments>http://blog.xebia.fr/2011/11/30/composant-scroll-avec-jquery/#comments</comments> <pubDate>Wed, 30 Nov 2011 07:21:47 +0000</pubDate> <dc:creator>Amin Fathallah</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[jQuery]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=9587</guid> <description><![CDATA[Dernièrement, j’ai participé au développement d&#8217;un Framework de composants visuels en HTML, jQuery et Java. Parmi ces composants, nous avons mis en place une grille de données évoluée avec des fonctionnalités étendues (Support du drag and drop, rafraichissement partiel de la page, &#8230;). Ce composant est intégré dans une application web utilisée la majorité de [...]]]></description> <content:encoded><![CDATA[<p>Dernièrement, j’ai participé au développement d&#8217;un Framework de composants visuels en HTML, <a
href="http://jquery.com/" rel="nofollow">jQuery</a> et Java. Parmi ces composants, nous avons mis en place une grille de données évoluée avec des fonctionnalités étendues (Support du drag and drop, rafraichissement partiel de la page, &#8230;). Ce composant est intégré dans une application web utilisée la majorité de temps depuis un terminal tactile. Pour naviguer à travers les données, la grille de données utilisait un contrôle de pagination classique dans le style ci-dessous :</p><p><span
style="display: block; text-align: center"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/11/pagination-classique.png" style="border: 0px solid black" /></span></p><p>Ce type de pagination contraint l&#8217;utilisateur à effectuer plusieurs clics pour avancer à travers les données paginées, et atteindre sa page cible. Pour améliorer ce comportement, un ergonome et moi avons proposé une nouvelle stratégie de pagination permettant d’atteindre la page souhaitée avec un minimum de clics, tout en gardant un comportement proche d’une pagination classique (pagination des pages). Le résultat de notre travail est un contrôle scroll permettant de paginer à travers les données en utilisant la fonctionnalité drag-and-drop.</p><p>L’expérience tactile des utilisateurs et la résolution fixe du terminal nous imposait certaines règles à respecter pour une interaction facile et aisée avec l’application :</p><ul><li>La barre de scroll doit avoir une taille fixe (56 pixels dans mon exemple) pour mieux interagir avec les doigts des utilisateurs.</li><li>Le contrôle scroll (boutons de navigation+espace de scrolling) doit avoir une hauteur fixe selon le nombre de lignes par page et la résolution du terminal. (L’affichage du scroll navigateur est banni)</li></ul><p>Une fois le travail réalisé, j&#8217;ai trouvé intéressante l’idée de partager cette expérience de code avec des personnes sensibles à l&#8217;ergonomie et à l&#8217;utilisabilité des interfaces web.</p><h3><a
name="DRAFT-ComposantScrollAvecjQuery-LeDesign"></a>Le Design</h3><p>Le contrôle Scroll est sensible aux évènements suivants : click, drag-and-drop, et mouse-wheel. Il est composé essentiellement des éléments suivants :</p><ul><li>Deux boutons de navigation pour avancer et reculer d&#8217;une page.</li><li>Un espace de scrolling.</li><li>Une barre de scroll pour changer de page.</li></ul><p>Les boutons de navigation sont des boutons cliquables qui par souci de design ont la même hauteur qu&#8217;une ligne de données. L&#8217;espace de scrolling est défini sur la base de nombre de lignes maximum par page. La barre de scroll est un bloc graphique draggable dans l&#8217;espace de scrolling. La taille de ce bloc dépend du nombre total de pages remontées par le serveur et de la contrainte de taille des doigts des utilisateurs de l&#8217;application.</p><p>Les évènements click et mouse-wheel sont branchés sur l&#8217;espace scrolling pour permettre une meilleure expérience utilisateur. L&#8217;évènement drag-and-drop est branché sur la barre de scroll pour naviguer à travers les données en utilisant cette partie du composant.</p><p>La barre de scroll peut avoir une taille dynamique seulement si le nombre total de pages est inférieur à 6 (valeur définie dans mon exemple et correspondant à la résolution maximale utilisée par mon application, vous pouvez redéfinir cette valeur selon vos spécifications). Dans ce cas la taille de la barre de scroll est générée par une formule de calcul et dépend de la taille de l&#8217;espace de scrolling et du nombre de pages.</p><p><span
style="display: block; text-align: center"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/11/2-pages.png" style="border: 0px solid black" /></span></p><p>Si le nombre total de pages est supérieur ou égal à 6, la barre de scroll générée par la formule de calcul devient trop petite pour les doigts de l&#8217;utilisateur. J&#8217;utilise alors une formule de calcul pour générer une barre de scroll à taille fixe quelque soit le nombre de page.</p><p><span
style="display: block; text-align: center"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/11/page-173.png" style="border: 0px solid black" /></span></p><h3><a
name="DRAFT-ComposantScrollAvecjQuery-LastructureHTML"></a>La structure HTML</h3><p>Pour une meilleure intégration avec les styles CSS, la structure HTML du composant scroll est basée essentiellement sur des balises DIV. Les identifiants avec marqueurs sont nécessaires pour intégrer plusieurs instances du composant scroll dans la même page. Les classes CSS définissent les styles, et le positionnement des éléments dans la page.</p><pre class="brush: xml; gutter: true; title: ; notranslate">
&lt;!--Le composant scroll--&gt;
&lt;div id=&quot;scrollComponent#{marker}&quot; class=&quot;scrollComponent&quot;&gt;
       &lt;!--Bouton de navigation (Reculer d’une page)--&gt;
       &lt;div id=&quot;scrollUpButton#{marker}&quot; class=&quot;scrollUpButton&quot;&gt;&lt;/div&gt;
       &lt;!--Espace de scrolling--&gt;
       &lt;div id=&quot;scrollBarContainer#{marker}&quot; class=&quot;scrollBarContainer&quot;&gt;
            &lt;!--Barre de scroll--&gt;
            &lt;div id=&quot;scrollBar#{marker}&quot; class=&quot;scrollBar&quot;&gt;
                 &lt;label id=&quot;pageNumberLabel#{marker}&quot; class=&quot;pageNumberLabel&quot;&gt;&lt;/label&gt;
            &lt;/div&gt;
       &lt;/div&gt;
       &lt;!--Bouton de navigation (Avancer d’une page)--&gt;
       &lt;div id=&quot;scrollBottomButton#{marker}&quot; class=&quot;scrollBottomButton&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
</pre><h3><a
name="DRAFT-ComposantScrollAvecjQuery-LesstylesCSS"></a>Les styles CSS</h3><p>Les styles CSS permettent de donner l’aspect visuel du composant Scroll. Le JavaScript est nécessaire pour calculer les dimensions, positionner et afficher les différentes briques du composant scroll en fonction du nombre des pages et des paramètres avancés par l&#8217;application.</p><h4><a
name="DRAFT-ComposantScrollAvecjQuery-Lecomposantscroll"></a>Le composant scroll</h4><p>Le style appliqué permet de définir la largeur du composant scroll. Il définit également l’image de fond,  et les images des boutons de navigation dans les données et leurs positions.</p><pre class="brush: css; gutter: true; title: ; notranslate">
.scrollComponent {
 width:46px;
 background-image: url(&quot;./images/scrollup.png&quot;), url(&quot;./images/scrolldown.png&quot;), url(&quot;./images/contenu.png&quot;);
 background-repeat: no-repeat, no-repeat, repeat-y;
 background-position: center top, center bottom, center top;
}
</pre><h4><a
name="DRAFT-ComposantScrollAvecjQuery-L%27espacedescrolling"></a>L&#8217;espace de scrolling</h4><p>Le style appliqué permet de définir la largeur de l’espace de scrolling. La hauteur est calculée en fonction du nombre des lignes maximum à afficher par page.</p><pre class="brush: css; gutter: true; title: ; notranslate">
.scrollBarContainer {
        width:46px;
}
</pre><h4><a
name="DRAFT-ComposantScrollAvecjQuery-Labarredescroll"></a>La barre de scroll</h4><p>La classe CSS <em>scrollBar</em> permet de définir la largeur de la barre du scroll, son positionnement, ses bordures, et son image de fond. La taille de la barre de scroll est calculée selon le nombre de pages. La classe CSS <em>pageNumberLabel</em> permet de définir le positionnement, les propriétés de la police des caractères, et la largeur du libellé utilisé pour l&#8217;affichage de la page en cours.</p><pre class="brush: css; gutter: true; title: ; notranslate">
.scrollBar {
 position:absolute;
 width:39px;
 margin-left:4px;
 -webkit-border-radius:150px;
 -moz-border-radius:150px;
 -o-border-radius:150px;
 border-radius:150px;
 background-image:url(&quot;./images/texture.png&quot;);
}
.pageNumberLabel {
 position:absolute;
 top:40%;
 width:37px;
 font-family:Trebuchet MS,Arial,Helvetica,Jamrul,sans-serif;
 font-size:9px;
 color: #FFFFFF;
 font-weight: bold;
 text-align: center;
}
</pre><h4><a
name="DRAFT-ComposantScrollAvecjQuery-Lesboutonsdenavigation"></a>Les boutons de navigation</h4><p>Le style appliqué sur les boutons de navigation permet de définir le type de curseur en survolant ces briques.</p><pre class="brush: css; gutter: true; title: ; notranslate">
.scrollUpButton {
 cursor: pointer;
}
.scrollBottomButton {
 cursor: pointer;
}
</pre><h3><a
name="DRAFT-ComposantScrollAvecjQuery-LescriptJavaScript"></a>Le script JavaScript</h3><p>Le script ci-dessous, permet de définir les propriétés du composant scroll, et de brancher les événements click, drag-and-drop et mouse-wheel sur les différentes briques du composant scroll.</p><h4><a
name="DRAFT-ComposantScrollAvecjQuery-Initilisationducomposantscroll"></a>Initilisation du composant scroll</h4><p>En premier lieu, le script doit définir les dimensions des différentes briques du composant scroll ainsi que leur positionnement. Pour cela, nous avons utilisé la fonction <a
href="http://jquery.developpeur-web2.com/documentation/css/css.php" rel="nofollow">css</a> de <a
href="http://jquery.com/" rel="nofollow">jQuery</a> pour accéder et modifier les propriétés des différents styles.</p><p>Nous commençons par initialiser la taille de la barre de scroll et la sensibilité de déplacement dans l&#8217;espace de scrolling. Ces propriétés sont définies suivant le nombre total de pages et le nombre maximum de lignes à afficher par page.</p><p>Si le nombre de pages est inférieur à 6 :</p><pre class="brush: jscript; gutter: true; title: ; notranslate">
// Hauteur dynamique de la barre de scroll selon le nombre de pages (1)
scrollBarHeight = ((maxRowsPerPage-2) * rowHeight) / totalPages;
// 2 correspond aux boutons de navigation qui sont font partie de l'espace de données.
// Sensibilité de déplacement de la barre de scroll (2)
sensibility = ((maxRowsPerPage-2) * rowHeight) / totalPages;
</pre><p>Si le nombre de pages est supérieur ou égal à 6 :</p><pre class="brush: jscript; gutter: true; title: ; notranslate">
// Hauteur fixe du composant scrollBar (1)
scrollBarHeight = ((maxRowsPerPage - 2) * rowHeight) / 6;
var oldsensibility = ((((maxRowsPerPage-2)  * rowHeight) / totalPages) - (scrollBarHeight / totalPages));
var diff = (((rowHeight * maxRowsPerPage) - (rowHeight+scrollBarHeight)) -
           (rowHeight + (oldsensibility * (totalPages - 1))) ) / (totalPages - 1);
// Sensibilité de déplacement du composant scrollbar (2)
sensibility = oldsensibility + diff;
</pre><p>Le positionnement de la barre de scroll, et les dimensions des autres briques du composant scroll sont définies par la suite.</p><pre class="brush: jscript; gutter: true; title: ; notranslate">
// Positionnement du scrollbar selon la page courante (3)
scrollBarBottom = parseFloat(scrollUpButton.position().top)+rowHeight;
var initialScrollBarTop = scrollBarBottom + ((currentPage * sensibility) - sensibility);
scrollBar.css('top',initialScrollBarTop+'px');
// Définition de la taille du composant scroll (4)
scrollComponent.css('height', maxRowsPerPage * rowHeight+'px');
// Définition de la taille d'espace de scrolling (5)
scrollBarContainer.css('height', (maxRowsPerPage - 2) * rowHeight+'px');
// Définition de la taille des boutons de navigation (6)
scrollUpButton.css('height',rowHeight+'px');
scrollBottomButton.css('height',rowHeight+'px');
// Définition de la taille de la barre de scroll
scrollBar.css('height',scrollBarHeight+'px');
// Numéro de page courante (7)
pageNumberLabel.html(currentPage + '/' + totalPages);
</pre><h4><a
name="DRAFT-ComposantScrollAvecjQuery-%C3%89v%C3%A8nementsclicksurlesboutonsdenavigation"></a>Évènements click sur les boutons de navigation</h4><p>Nous utilisons l&#8217;évènement <a
href="http://api.jquery.com/click/" rel="nofollow">click</a> de l&#8217;API <a
href="http://api.jquery.com/" rel="nofollow">jQuery</a> pour utiliser les boutons de navigation.</p><pre class="brush: jscript; gutter: true; title: ; notranslate">
// Reculer d'une page
scrollUpButton.click(function() {
    previousPage();
});
// Avancer d'une page
scrollBottomButton.click(function() {
    nextPage();
});
// Avancer d'une page
function nextPage() {
    if (currentPage == totalPages) return false;
    currentPage = currentPage + 1;
    changePage();
}
// Reculer d'une page
function previousPage() {
   if (currentPage == 1) return false;
   currentPage = currentPage - 1;
   changePage();
}
// Changer les propriétés de la barre de scroll
function changePage() {
    // Nouvelle position selon la page en cours
    var newTop = scrollBarBottom + ((sensibility * currentPage) - (sensibility));
    scrollBar.css('top',newTop+'px');
    // Mise à jour du numéro de la page
    pageNumberLabel.html(currentPage + '/' + totalPages);
}
</pre><h4><a
name="DRAFT-ComposantScrollAvecjQuery-%C3%89v%C3%A8nementdraganddropsurlabarredescroll"></a>Évènement drag-and-drop sur la barre de scroll</h4><p>Pour donner la vie à notre barre de scroll, nous utilisons la fonction <a
href="http://jqueryui.com/demos/draggable/" rel="nofollow">draggable</a> de l&#8217;API <a
href="http://jqueryui.com/" rel="nofollow">jQuery UI</a>.</p><pre class="brush: jscript; gutter: true; title: ; notranslate">
// Evènement DragAndDrop sur le scrollbar
scrollBar.draggable({ axis:'y', opacity: 0.70, currentPage: 'pointer', containment: &quot;#scrollBarContainer&quot;+componentId,
    stop: function(event, ui) {
        // Changer les propriétés de la barre de scroll
        changePage();
        // Charger la page en cours
        loadPage();
    },
   drag: function(event, ui) {
        // Définir la page en cours selon la position de la barre de scroll dans l'espace de scrolling
        var p = scrollBar.position();
        var scrollBarPosition =  parseFloat(p.top+sensibility);
        currentPage = Math.round((scrollBarPosition - scrollBarTop) / sensibility);
        pageNumberLabel.html(currentPage + '/'+ totalPages);
   }
});
</pre><h4><a
name="DRAFT-ComposantScrollAvecjQuery-%C3%89v%C3%A8nementmousewheelsurl%27espacedescrolling"></a>Évènement mouse-wheel sur l&#8217;espace de scrolling</h4><p>Pour gérer la souris molette ou le mouse-wheel, nous utilisons le plugin <a
href="https://github.com/brandonaaron/jquery-mousewheel/" rel="nofollow">mousewheel</a> de l&#8217;API <a
href="http://api.jquery.com/" rel="nofollow">jQuery</a>. Pour des performances optimales, nous attendons un laps de temps après l&#8217;arrêt pour charger la dernière page sélectionnée. Toutefois, la barre de scroll change de position pour une meilleure interaction avec l&#8217;utilisateur.</p><pre class="brush: jscript; gutter: true; title: ; notranslate">
// Evènement molette souris sur le composant scroll
scrollComponent.bind('mousewheel', function(event, delta) {
    var direction = delta &gt; 0 ? 'Up' : 'Down';
    if (direction =='Up') {
        previousPage();
    }
    else if  (direction =='Down') {
        nextPage();
    }
    clearTimeout(jQuery.data(this, 'timer'));
    jQuery.data(this, 'timer', setTimeout(function() {
        loadPage();
    }, 250));
});
// Charger la page en cours
function loadPage() {
    if (alreadyLoadedPage != currentPage) {
        alreadyLoadedPage = currentPage;
        // Appel asynchrone pour charger les données ...
    }
}
</pre><h3><a
name="DRAFT-ComposantScrollAvecjQuery-Exempled%27utilisation"></a>Exemple d&#8217;utilisation</h3><p>La fonction <a
href="http://jquery.developpeur-web2.com/documentation/evenements/ready.php" rel="nofollow">Ready</a> de <a
href="http://www.jquery.com" rel="nofollow">jQuery</a> est utilisé pour activer le composant et définir ses propriétés une fois le document DOM est entièrement chargé.</p><pre class="brush: jscript; gutter: true; title: ; notranslate">
jQuery(document).ready(initialiseScroll);
function initialiseScroll() {
      var scrollComponent = scrollComponentFunction({
                                             componentId: 'test1',
                                             currentPage : 1,
                                             totalPages: 5,
                                             maxRows: 10
                            });
}
</pre><h3><a
name="DRAFT-ComposantScrollAvecjQuery-Quelquesexemplesducomposantscroll"></a>Quelques exemples du composant scroll</h3><p><iframe
src="http://blog.xebia.fr/wp-content/uploads/2011/11/scrollComponent1.html" style="border: 0px black solid;" width="100%" height="550"><p>Your browser does not support iframes.</p><p> </iframe></p><h3><a
name="DRAFT-ComposantScrollAvecjQuery-Conclusion"></a>Conclusion</h3><p>Le projet de création de notre Framework UI vient en remplacement du Framework <a
href="http://www.jboss.org/richfaces" rel="nofollow">RichFaces</a> qui constituait un frein à l&#8217;évolution de notre application à tous les niveaux : (développements, intégration avec d&#8217;autres technologies, tests IHM, performances des pages générées, évolutivité des composants de base &#8230;). En combinant quelques technologies et Frameworks de base (HTML, CSS, <a
href="http://jquery.com/" rel="nofollow">jQuery</a>, <a
href="http://jqueryui.com/" rel="nofollow">jQuery UI</a>, Java, &#8230;), nous avons réussi à créer des composants UI légers, performants et facilement intégrables &#8230; Utiliser des technologies de base pour développer notre propre Framework s&#8217;est avéré un pari gagnant. Toutefois, créer son propre Framework est un travail laborieux et couteux dans le temps mais les résultats sont plus que satisfaisants. Utiliser des technologies de base ou partir sur des Frameworks comme <a
href="http://code.google.com/intl/fr/webtoolkit/" rel="nofollow">GWT</a>, <a
href="http://www.jboss.org/richfaces" rel="nofollow">RichFaces</a> &#8230; ? C&#8217;est un sujet auquel nous essayerons de répondre dans d&#8217;autres articles.</p><p><b>Ressources :</b></p><ul><li><a
href="http://xebia-france.googlecode.com/svn/trunk/scrollComponent/" rel="nofollow">Code source du projet</a></li></ul><div
class="shr-publisher-9587"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2011%2F11%2F30%2Fcomposant-scroll-avec-jquery%2F' data-shr_title='Composant+Scroll+Avec+jQuery'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2011%2F11%2F30%2Fcomposant-scroll-avec-jquery%2F' data-shr_title='Composant+Scroll+Avec+jQuery'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/11/30/composant-scroll-avec-jquery/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>Devoxx &#8211; HTML5 à l&#8217;honneur</title><link>http://blog.xebia.fr/2011/11/17/devoxx-html5-a-lhonneur/</link> <comments>http://blog.xebia.fr/2011/11/17/devoxx-html5-a-lhonneur/#comments</comments> <pubDate>Thu, 17 Nov 2011 08:45:20 +0000</pubDate> <dc:creator>François Marot</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[Devoxx]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[Web]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=9213</guid> <description><![CDATA[HTML 5 est définitivement à l&#8217;honneur de ce Devoxx 2011. Pour preuve les salles de 3 conférences dédiées au sujet étaient pleines. Nous vous avons déjà parlé de &#171;&#160;Devoxx &#8211; Les nouvelles applications HTML 5 et DART&#160;&#187; et nous allons maintenant évoquer les 2 autres sessions que nous avons vues: Working Off the Grid: HTML5 [...]]]></description> <content:encoded><![CDATA[<p><span
style="float: right"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/11/html5.jpg" style="border: 0px solid black; padding: 20px;" /></span><br
/> HTML 5 est définitivement à l&#8217;honneur de ce Devoxx 2011. Pour preuve les salles de 3 conférences dédiées au sujet étaient pleines. Nous vous avons déjà parlé de &laquo;&nbsp;<a
href="http://blog.xebia.fr/2011/11/17/devoxx-les-nouvelles-applications-html-5-et-dart/" rel="nofollow">Devoxx &#8211; Les nouvelles applications HTML 5 et DART</a>&nbsp;&raquo; et nous allons maintenant évoquer les 2 autres sessions que nous avons vues:</p><ul><li><a
href="http://www.devoxx.com/display/DV11/Working+Off+the+Grid++HTML5+Offline" rel="nofollow">Working Off the Grid: HTML5 Offline</a></li><li><a
href="http://www.devoxx.com/display/DV11/Bleeding+Edge+HTML5" rel="nofollow">Bleeding Edge HTML5</a></li></ul><p>Elles ont toutes été réalisées par des personnes de Google, preuve de l&#8217;implication de la compagnie dans le futur du HTML.</p><p>Il y avait aussi un sujet &laquo;&nbsp;Intro to HTML5 Game Programming &#8211; WebGL Edition&nbsp;&raquo; mais auquel aucun Xebian n&#8217;a pu assister: il faut bien faire un choix lorsque plusieurs sessions intéressantes sont en parallèle !</p><h3><a
name="Devoxx-HTML5%C3%A0l%27honneur-WorkingOfftheGrid%3AHTML5Offline"></a>Working Off the Grid: HTML5 Offline</h3><p><a
href="https://twitter.com/#!/sw12" rel="nofollow">Sam Dutton</a> de Google nous <a
href="http://www.samdutton.com/offlinePresentation/#1" rel="nofollow">a présenté</a> les différentes solutions de stockage hors ligne. Les problématiques adressées par ces technologies sont multiples:</p><ul><li>Problèmes de bande passante.</li><li>Connexions peu stables.</li><li>Amélioration des performances des applications web.</li><li>Diminution de la consommation de ressources sur le serveur.</li><li>Amélioration générale de l’expérience utilisateur.</li></ul><p>Auparavant, nous ne disposions que de méthodes peu satisfaisantes: cookies, flash&#8230;</p><p>Maintenant, des solutions plus adaptées sont à notre disposition:</p><ul><li>Web Storage (localStorage/sessionStorage): permet de stocker de façon simple des paires clef/valeur.</li><li>IndexedDB/WebSQL: stockage de structures plus complexes et support des transactions (utile si plusieurs onglets ou sessions ouverts simultanément).</li><li><a
href="http://www.html5rocks.com/en/tutorials/appcache/beginner/" rel="nofollow">AppCache</a>: l&#8217;utilisation d&#8217;un fichier manifeste permet de déclarer des ressources (images, CSS&#8230;) à mettre en cache.</li></ul><p>Bref, les possibilités s&#8217;annoncent énormes mais des problématiques fondamentales demeurent: quid de la compatibilité entre navigateurs ? Tous ne supportent pas toutes les APIs et cela peut augurer de belles galères. C&#8217;est malheureusement un aspect sur lequel la présentation n&#8217;a pas du tout insisté.</p><p>Pour plus de renseignements sur les possibilités de stockages hors ligne, le site html5Rocks en offre <a
href="http://www.html5rocks.com/en/tutorials/offline/whats-offline/" rel="nofollow">un vaste aperçu</a>.</p><h3><a
name="Devoxx-HTML5%C3%A0l%27honneur-BleedingEdgeHTML5"></a>Bleeding Edge HTML5</h3><p>Paul Kinlan (dont voici <a
href="http://paul.kinlan.me/" rel="nofollow">le blog</a>) a effectué une présentation assez généraliste sur nombre de nouveautés apportées par HTML 5. Les slides sont <a
href="http://bleedinghtml5.appspot.com" rel="nofollow">en ligne</a> et voici les points marquants:</p><p><span
style="display: block; text-align: center"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/11/Paul-Kinlan.jpg" style="border: 0px solid black" /></span></p><ul><li>Début en douceur avec <a
href="http://www.w3schools.com/html5/tag_mark.asp" rel="nofollow">la nouvelle balise</a> &lt;mark /&gt; qui s&#8217;utilise pour mettre en avant, de façon sémantique, une partie de texte. Bon, ce n&#8217;est pas cela qui changera la face du web ﻿!</li><li>Les champs susceptibles d’être remplis par la voix, les <a
href="http://www.sitepoint.com/html5-speech-input-fields/" rel="nofollow">speech input</a>, sont aussi une nouveauté: un attribut x-webkit-speech, pour l&#8217;instant disponible seulement sur Chrome, permet d&#8217;offrir la possibilité de saisir du texte avec un micro. On peut se demander pourquoi laisser au développeur le choix d&#8217;activer ou non cette possibilité: il serait peut être plus simple de laisser le choix au niveau du navigateur, ce qui permettrait à tous les champs texte de bénéficier de cette fonctionnalité.</li><li>On passe ensuite à des nouveautés plus impressionnantes concernant les animations. On en profitera pour remarquer que Google a en ce moment un intérêt certain pour les jeux videos: que ce soit avec Angry Birds dans Chrome ou le nouveau framework avec lequel il a été réalisé, <a
href="http://playn-2011.appspot.com/slides/index.html" rel="nofollow">PlayN</a>, Google a envie de réussir dans ce domaine. Pour revenir aux animations, donc, au lieu de coder en dur un timeout définissant le framerate à une valeur fixe, les navigateurs proposent maintenant la notion de &laquo;&nbsp;<a
href="http://www.html5rocks.com/en/tutorials/speed/html5/#toc-request-ani-frame" rel="nofollow">RequestAnimationFrame</a>&nbsp;&raquo; qui appelle un callback définit par l&#8217;utilisateur quand le navigateur le juge utile. Ainsi le CPU ne travaillera pas pour rien: d&#8217;une part, pas besoin de calculer 100 images secondes si le rafraichissement de l&#8217;écran est de 60Hz, et d&#8217;autre part le callback ne sera pas appelé si l&#8217;onglet de l&#8217;animation n&#8217;est pas l&#8217;onglet actif. Cette fonctionnalité fait aussi partie de la &laquo;&nbsp;<a
href="http://updates.html5rocks.com/2011/06/Page-Visibility-API-Have-I-got-your-attention" rel="nofollow">page visibility API</a>&laquo;&nbsp;: les vidéos ou sons pourront être mis en pause lors du changement d&#8217;onglet.</li><li>Les &laquo;&nbsp;<a
href="http://bleedinghtml5.appspot.com/#8" rel="nofollow">prerendered pages</a>&nbsp;&raquo; sont des pages liées à d&#8217;autres par un lien spécial permettant leur chargement en arrière plan pour un rendu immédiat lors du clic sur le lien. On peut imaginer Google utiliser ce type de liens pour précharger les 2 ou 3 premiers résultats affichés lors d&#8217;une recherche. Par contre, on voit mal comment ce type de liens pourra se passer d&#8217;augmenter virtuellement le traffic des sites même s&#8217;ils n&#8217;ont pas été visités réellement par des utilisateurs.</li><li>Un attribut &laquo;&nbsp;online&nbsp;&raquo; de l&#8217;objet js navigator permet maintenant de connaitre l&#8217;état de l&#8217;ordinateur, connecté ou non à un réseau. Un callback permet d’être notifié sur un changement d&#8217;état (connexion/déconnexion).</li><li>Après le succès qu&#8217;on leur connait dans Android, les &laquo;&nbsp;intents&nbsp;&raquo; débarquent sur le web. On pourra grâce à eux partager du contenu entre plusieurs sites. Il suffira que les sites fournisseurs se déclarent au navigateur pour que l&#8217;on puisse les sélectionner comme tel et, par exemple, importer directement des photos en provenance de Picasa lors de la rédaction de son mail sur gmail.com. Plus de détails dans <a
href="http://bleedinghtml5.appspot.com/#19" rel="nofollow">les slides</a>.</li><li>Le projet <a
href="http://www.webrtc.org/" rel="nofollow">WebRTC</a> a pour but de donner la possibilité de réaliser des chats vidéos sans flash, directement avec les API javascript fournies par le navigateur. Le but avoué est de casser le paradigme de la numérotation en permettant des communications instantanées en un clic. Mais du coté software, cela suppose bien sûr des notions de:<ul><li>Capture/rendu de flux audios/vidéos.</li><li>Énumération des périphériques matériels de capture.</li></ul></li><li>Pour finir, nous avons eu droit à une démonstration plutôt impressionnante de génération dynamique de sons, en temps réel et en javascript. Des filtres successifs peuvent être appliqués pour déformer le son original.</li></ul><p>Dès demain, de nouvelles présentations sur HTML5 devraient avoir lieu, notamment en relation avec JavaFX et Play!/Scala. Il n&#8217;y a pas de mystère, HTML5 gagne ces temps-ci une crédibilité énorme, avec notamment les soutiens récents de Microsoft et Adobe, qui incitent nombre d&#8217;entre nous à s&#8217;intéresser de près au projet qui est en perpétuelle évolution.</p><div
class="shr-publisher-9213"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2011%2F11%2F17%2Fdevoxx-html5-a-lhonneur%2F' data-shr_title='Devoxx+-+HTML5+%C3%A0+l%27honneur'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2011%2F11%2F17%2Fdevoxx-html5-a-lhonneur%2F' data-shr_title='Devoxx+-+HTML5+%C3%A0+l%27honneur'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/11/17/devoxx-html5-a-lhonneur/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Devoxx &#8211; Les nouvelles applications HTML 5 et DART</title><link>http://blog.xebia.fr/2011/11/17/devoxx-les-nouvelles-applications-html-5-et-dart/</link> <comments>http://blog.xebia.fr/2011/11/17/devoxx-les-nouvelles-applications-html-5-et-dart/#comments</comments> <pubDate>Thu, 17 Nov 2011 06:19:18 +0000</pubDate> <dc:creator>Nicolas Jozwiak</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[Dart]]></category> <category><![CDATA[Devoxx]]></category> <category><![CDATA[HTML 5]]></category> <category><![CDATA[JavaScript]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=9205</guid> <description><![CDATA[HTML 5 est sans conteste un des sujets phare de ce Devoxx 2011. Pour preuve la salle est bien remplie. Lors de cette présentation David Chandler commence par nous  montrer comment HTML 5 peut nous aider à simplifier la conception et l’utilisation des applications Web. Il nous rappelle également que les versions récentes des navigateurs [...]]]></description> <content:encoded><![CDATA[<p><span
style="float: left;"><img
style="border: 0px solid black; margin: 1em 1em 1em 1em;" src="http://blog.xebia.fr/wp-content/uploads/2011/11/dart_scene.jpeg" alt="" width="400" /></span><br
/> HTML 5 est sans conteste un des sujets phare de ce Devoxx 2011. Pour preuve la salle est bien remplie. Lors de cette présentation David Chandler commence par nous  montrer comment HTML 5 peut nous aider à simplifier la conception et l’utilisation des applications Web. Il nous rappelle également que les versions récentes des navigateurs prennent en charge le HTML 5, mis à part Internet Explorer (étonnant non ?)</p><p>&nbsp;<br
/> <br
/>&nbsp;<br
/> <br
/>&nbsp;<br
/> <br
/>&nbsp;<br
/> <br
/>&nbsp;</p><p><span
style="float: right;"><img
style="border: 0px solid black; margin: 1em 1em 1em 1em;" src="http://blog.xebia.fr/wp-content/uploads/2011/11/html5.jpg" alt="" width="320" height="250" /></span></p><p>David commence par poser la question suivante : comment créer une application Web avec le comportement d’une application desktop ? La réponse réside dans de petites démonstrations des possibilités d’HTML 5 :</p><ul><li>Sauvegarde de fichiers du navigateur vers le filesystem et inversement.</li><li>Sauvegarde des données saisies localement</li><li>Détection des déconnexions et reconnexions automatique.</li></ul><p>Assez bluffantes, ces fonctionnalités se mettent en place en seulement quelques lignes !</p><p>David poursuit avec le CSS3 et nous parle des possibilités de transitions et d’animations. Pour les fans de jeux, la version Web d’<a
href="http://chrome.angrybirds.com/" rel="nofollow">Angry Birds</a> est basée sur CSS3 et lorsque nous voyons le résultat, nous ne pouvons qu’être admiratifs.</p><p>Vient ensuite une discussion autour de la conception des applications. David nous explique que les frameworks MVC (Backbone, ExtJS, etc) nous impose une limitation de par leur structure.</p><p>Une première solution réside dans l’utilisation du triplet HTML, javascript et CSS, mais cette dernière pose un certain nombre de problèmes :</p><ul><li>Manque de performances.</li><li>Difficulté de debugging.</li><li>Pas de typage fort, rendant le développement d’outils difficile.</li></ul><p>La seconde solution est l’utilisation du framework GWT. Le principe est de coder du Java qui est automatiquement « traduit » en javascript. Ce dernier permet d’adresser les problèmes précédemment cités, mais GWT reste difficile à maîtriser et peut se révéler lourd à mettre en place.</p><p><span
style="float: left;"><img
style="border: 0px solid black; margin: 1em 1em 1em 1em;" src="http://blog.xebia.fr/wp-content/uploads/2011/11/dart-logo.png" alt="" height="100" /></span><br
/> David nous présente alors DART. Ce dernier est né de la volonté d’avoir un langage de scripting plus léger tout en utilisant la structure d’un langage orienté objet. Dart est un langage construit pour plaire à la fois aux personnes fluides en Java ou en JavaScript. La courbe d&#8217;apprentissage devrait être particulièrement courte pour ces deux populations. Aujourd&#8217;hui Dart est un langage qu&#8217;il faut &laquo;&nbsp;compiler&nbsp;&raquo; pour produire du javascript, dans la même veine que <a
href="http://jashkenas.github.com/coffee-script/" rel="nofollow">coffeescript</a>.</p><p>Voici un exemple de code en DART :</p><pre class="brush: java; gutter: true; title: ; notranslate">
interface Shape {
  num perimeter();
}
class Rectangle implements Shape {
  final num height, width;
  Rectangle(num this.height, num this.width);  // Compact constructor syntax.
  num perimeter() =&gt; 2*height + 2*width;       // Short function syntax.
}
class Square extends Rectangle {
  Square(num size) : super(size, size);
}
</pre><p>Nous retrouvons ainsi les notions de classes, interfaces et méthodes entre autres.</p><p>Concernant l’outillage, nous avons à disposition Dart VM, dartc (compilateur javascript écrit en java), frog (compilateur javascript écrit en Dart, qui fait figure de futur compilateur) et le dartboard. Un début d&#8217;IDE Dart (appelé <a
href="http://www.dartlang.org/docs/getting-started/editor/index-macos.html" rel="nofollow">Dart Editor</a>) existe également pour Eclipse. Tous ces éléments peuvent être retrouvés sur le site du <a
href="http://dartlang.org" rel="nofollow">langage</a>. Il est à noter que Dart est encore en version alpha, et que des changements dans le langage vont encore intervenir. Il n&#8217;existe pas non plus de binaire disponible en téléchargement pour toutes les plateformes, mais nous sommes invités à télécharger les <a
href="http://dart.googlecode.com" rel="nofollow">sources</a> et à construire les différents outils (VM, compilateur etc..)</p><p>David termine sa présentation en nous expliquant qu’il reste encore du travail sur ce langage, mais que Google travaille d’arrache pied pour nous donner la possibilité de développer du javascript avec une syntaxe allégée. Notamment ils discutent avec l&#8217;équipe en charge de Google Chrome pour une intégration native de Dart dans le navigateur, poussant pour que demain, les navigateurs du marchés embarquent une vm dart, comme ils embarquent aujourd&#8217;hui une vm javascript.</p><p>Nul doute que l’évolution de ce langage est à surveiller et que ce dernier fera parler de lui dans les mois à venir.</p><p>Les slides de cette présentation sont <a
href="http://www.dartlang.org/slides/2011/11/devoxx/index.html#1" rel="nofollow">disponibles</a>, en html5 bien sur.</p><div
class="shr-publisher-9205"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2011%2F11%2F17%2Fdevoxx-les-nouvelles-applications-html-5-et-dart%2F' data-shr_title='Devoxx+-+Les+nouvelles+applications+HTML+5+et+DART'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2011%2F11%2F17%2Fdevoxx-les-nouvelles-applications-html-5-et-dart%2F' data-shr_title='Devoxx+-+Les+nouvelles+applications+HTML+5+et+DART'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/11/17/devoxx-les-nouvelles-applications-html-5-et-dart/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Application hors-ligne HTML5 le JavaScript</title><link>http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/</link> <comments>http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#comments</comments> <pubDate>Fri, 17 Dec 2010 20:05:58 +0000</pubDate> <dc:creator>Séven Le Mesle</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Ajax]]></category> <category><![CDATA[cache]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JSon]]></category> <category><![CDATA[PrototypeJs]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=6208</guid> <description><![CDATA[Dans l&#8217;article précédent, nous avons rendu une interface HTML disponible hors-ligne via l&#8217;utilisation du fichier manifest de cache. L&#8217;interface était totalement statique, ne supportait que la consultation en lecture seule et la gestion du contenu dynamique reposait sur les différents versions du manifest ; les nouvelles API JavaScript vont nous aider à résoudre ces problèmes. [...]]]></description> <content:encoded><![CDATA[<p>Dans <a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/">l&#8217;article précédent</a>, nous avons rendu une interface HTML disponible hors-ligne via l&#8217;utilisation du fichier manifest de cache. L&#8217;interface était totalement statique, ne supportait que la consultation en lecture seule et la gestion du contenu dynamique reposait sur les différents versions du manifest ; les nouvelles API JavaScript vont nous aider à résoudre ces problèmes.<br
/> Avec le localStorage et l&#8217;état window.onLine, nous pourrons stocker le contenu dynamique et différencier les traitements JavaScript selon le mode (dé)connecté.</p><h3> Sommaire</h3><ul><li><a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#Surveillerltatdelaconnexion">Surveiller l&#8217;état de la connexion</a></li><li><a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#Grerlecontenudynamique">Gérer le contenu dynamique</li><li
style="list-style: none;"><ul><li><a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#Attentionauxliensetlapaginatio">Attention aux liens et à la pagination</a></li><li> <a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#PassezauJSON">Passez au JSON</a></li></ul></li><li> <a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#Lemodehorsligne">Le mode hors ligne</a></li><li
style="list-style: none;"><ul><li> <a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#GestionderreurAjax">Gestion d&#8217;erreur Ajax</a></li><li> <a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#Stratgiedestockage">Stratégie de stockage</a></li><li> <a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#Gestiondesformulaires">Gestion des formulaires</a></li></ul></li><li> <a
href="http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/#Conclusion">Conclusion</a></li></ul><p>Cet article s&#8217;appuie sur la librairie PrototypeJS pour la majorité des exemples de code JavaScript.</p><h3><a
name="Surveillerltatdelaconnexion"></a>Surveiller l&#8217;état de la connexion</h3><p>La première étape est d&#8217;afficher un bloc indiquant à l&#8217;utilisateur l&#8217;état de la connexion. Le bloc affiche online ou offline en fonction du mode actif (connecté / déconnecté).</p><p>Il faut tout d&#8217;abord créer le bloc HTML dont nous avons besoin :</p><pre class="brush: xml; title: ; notranslate">
&lt;div id=&quot;line-status&quot; class=&quot;online&quot;&gt;
Online
&lt;/div&gt;
</pre><p>Un bloc div contient le libellé associé au statut. Nous avons positionné un id sur l&#8217;élément pour le manipuler facilement en JavaScript et la classe CSS nous servira à changer la couleur de fond : rouge pour connecté et vert pour déconnecté. Nous pouvons maintenant modifier le texte et la classe du bloc en fonction de l&#8217;objet <code>navigator.onLine</code>.</p><pre class="brush: jscript; title: ; notranslate">
setInterval(function () {
var status = document.getElementById('line-status');
  	status.className = navigator.onLine ? 'online' : 'offline';
  	status.innerHTML = navigator.onLine ? 'Online' : 'Offline';
}, 250);
</pre><p>Le texte et la classe du bloc <code>#line-status</code> seront mis à jour toutes les 250ms en fonction de la valeur de l&#8217;objet <code>navigator.onLine</code>. Vous pouvez tester ce code en coupant la connexion wifi/3G de votre ordinateur/téléphone (avec firefox, cliquer sur Travailler Hors Connexion). Une exécution toutes les 250ms a tendance à être consommatrice en ressources ; utilisons plutôt les événements associés à cet état fournis par HTML5.</p><pre class="brush: jscript; title: ; notranslate">
window.addEventListener('online', function(){
  var status = document.getElementById('line-status');
  status.className = 'online';
  status.innerHTML = 'Online';
}, false);
window.addEventListener('offline', function(){
  var status = document.getElementById('line-status');
  status.className = 'offline';
  status.innerHTML = 'Offline';
}, false);
</pre><p>Notez que l&#8217;événement est levé sur l&#8217;objet window et non sur l&#8217;objet navigator. Avec ce code, la mise à jour du bloc est réalisée à chaque fois que le navigateur change d&#8217;état de connexion. Dans cette version, nous reposons entièrement sur le fonctionnement du navigateur pour différencier le mode connecté du mode déconnecté. Si cela fonctionne sur Webphone, sur ordinateur portable la coupure de la connexion réseau ne change pas l&#8217;état du navigateur. Seul le passage en mode hors connexion permet de lancer l&#8217;événement offline. Le navigateur restera online si les requêtes partent en timeout ou finissent en &#8216;host not found&#8217; par exemple.<br
/> Pour affiner la gestion du mode hors ligne en JavaScript, nous allons maintenir l&#8217;état de la connexion dans un objet qui réagira aux événements du navigateur et fournira la possibilité de changer directement l&#8217;état de la connexion.</p><pre class="brush: jscript; title: ; notranslate">
Utils.LinkClass = Class.create({
	// Constructeur
	initialize: function (elem, config){
		// Par défaut nous utilisons la valeur du navigateur
		this.online = navigator.onLine;
		// Récupérer la div par son id
		this.elem = $(elem);
		// Ecouter les évènements online/offline sur l'objet
		this.evtOnLine = this.updateTagOnline.bindAsEventListener(this);
		this.evtOffLine = this.updateTagOffline.bindAsEventListener(this);
		Event.observe(window, 'online', this.evtOnLine);
		Event.observe(window, 'offline', this.evtOffLine);
		// Rendre les classes CSS et les libellés paramétrables
		this.config = Object.extend({
offlineText:'Offline',
onlineText:'Online',
 onlineClass:'online',
offlineClass:'offline' }, config || { });
		this.updateTag(this.online);
	},
	// change l'état et met à jour la div si l'état fourni est différent de celui de l'objet
	setLineState: function (online){
		if(online != this.online){
			this.updateTag(online);
		}
	},
	// Met à jour l'état et la div sur évènement online
	updateTagOnline: function (evt){
		this.updateTag(true);
	},
	// Met à jour l'état et la div sur évènement offline
	updateTagOffline: function (evt){
		this.updateTag(false);
	},
	// Met à jour l'état et la div avec le booléen fourni
	updateTag: function (online) {
		this.online = online;
		if (online) {
			this.elem.addClassName(this.config.onlineClass );
  			this.elem.update(this.config.onlineText);
  			this.elem.removeClasseName(this.config.offlineClass);
  		} else {
  			this.elem.addClassName(this.config.offlineClass);
  			this.elem.update(this.config.offlineText);
  			this.elem.removeClasseName(this.config.onlineClass);
  		}
	}
});
// Instancier Utils.Link lorsque la page est chargée
Event.observe (window, 'load', function (){
	Utils.link = new Utils.LinkClass('line-status');
});
</pre><p>Dans le cas où l&#8217;état de la connexion est mis à jour directement sans émettre un événement du navigateur, vous pouvez lancer un service de ping http qui ira vérifier à intervalles réguliers la disponibilité du serveur et mettra à jour l&#8217;état de la connexion.</p><pre class="brush: jscript; title: ; notranslate">
Utils.PingServiceClass  = Class.create({
	initialize: function (config){
		this.timer = null;
                  // Configuration par défaut de la fréquence de ping en ms
		this.config = Object.extend({
			pingInterval: 20000,
			startDelay: 1000,
			url: null,  // Url ciblée par le ping Ajax
			onUplink: function(){}}, // fonction invoquée quand le ping réussi
                      config || {});
		this.url = this.config.url;
	},
        // méthode de ping
	ping: function(){
		if (this.timer != null){
			new Ajax.Request(this.url, {
				  method: 'get',
				  onSuccess: function(transport) {
					if (transport.status &lt; 300 &amp;&amp; transport.status &gt;= 200){
						this.timer = null;
                                                  // appel du callback si le ping AJAX a réussi
						this.config.onUplink();
					} else if (this.timer != null){
                                                  // Planification du prochain ping en cas d'erreur
						this.timer = setTimeout(this.ping.bind(this), this.config.pingInterval);
					}
				  },
                                     // Planification du prochain ping en cas d'erreur
				  onFailure: function(){
					if(this.timer != null) {
						this.timer = setTimeout(this.ping.bind(this), this.config.pingInterval);
					}
				  }
				});
		}
	},
          // Lancement du service de ping
	start: function(){
		if (this.timer == null){
			this.timer = setTimeout(this.ping.bind(this), this.config.startDelay);
		}
	},
	  // Arret forcé du ping
	stop: function(){
		if (this.timer != null){
			clearTimeout(this.timer);
			this.timer = null;
		}
	}
});
</pre><p>La classe PingServiceClass utilise la fonction <code>setTimeout</code> pour assurer une exécution régulière et asynchrone. À chaque timeout, elle lance une requête Ajax sur l&#8217;URL fournie en configuration. Le ping se lance par un appel à <code>start()</code> et peut être arrêté par un appel à <code>stop()</code>. Il faut aussi modifier la classe <code>Utils.LinkClass</code> pour qu&#8217;elle utilise un <code>PingService</code> lorsqu&#8217;un script forcera le passage hors-ligne(<code>Utils.link.setLineState(false);</code>).</p><pre class="brush: java; title: ; notranslate">
//...
        initialize: function(config){
          //...
          	if (this.config.ping){ // Instanciation du PingService si la configuration l'autorise
		  this.ping = new Utils.PingServiceClass({
			url: this.config.url,
			onUplink: this.updateTagOnline.bind(this) // Passer Online quand le ping réussi
			});
		}
           },
//...
	setLineState: function (online){
		if(online != this.online){
			this.updateTag(online);
			if (!online &amp;&amp; this.config.ping){ // Lancement du Ping HTTP sur passage forcé en mode hors-ligne
				this.ping.start();
			}
		}
	},
	updateTagOnline: function (evt){
		this.updateTag(true);
		  // Arret du Ping HTTP si le navigateur passe en ligne
                if(this.config.ping){
		  this.ping.stop();
                }
	},
//...
Event.observe (window, 'load', function (){ // Ajoute l'url de ping en configuration
	Utils.link = new Utils.LinkClass('line-status',{url:'/ping.html'});
});
</pre><p>Nous avons maintenant un moyen de notifier l&#8217;utilisateur et de savoir à tout moment si l&#8217;application est en ligne ou non. Le service ping sera utilisé seulement sur les navigateurs ne supportant pas ou mal les événements &#8216;online&#8217; et &#8216;offline&#8217;.  Notez que le ping est exécuté sur l&#8217;URL &#8216;/ping.html&#8217; qui fournit une simple page html statique hors du manifest.</p><h3><a
name="Grerlecontenudynamique"></a>Gérer le contenu dynamique</h3><p>La première étape, en partant d&#8217;une application existante, consiste à ajaxifier son contenu dynamique. Pour reprendre le cas du blog, la page d&#8217;accueil liste les en-têtes des articles les plus récents. La première solution consiste à récupérer le bloc HTML listant les articles en Ajax et à l&#8217;injecter dans la page. Attention pour les moteurs de recherches et pour des questions d&#8217;accessibilité, la page doit toujours être servie avec l&#8217;intégralité de son contenu.<br
/> Dans le cas d&#8217;une page liée au fichier manifest, le problème est de savoir quand mettre à jour la liste. La page étant affichée à partir du cache, son contenu ne changera qu&#8217;avec le fichier manifest. Le plus simple est de récupérer le bloc HTML systématiquement au chargement de la page, puis de planifier des mises à jour à intervalles réguliers pour garantir la fraîcheur de l&#8217;information.</p><pre class="brush: java; title: ; notranslate">
new Ajax.PeriodicalUpdater('blocElementId', '/articles', {frequency: 30, decay: 2});
</pre><p>L&#8217;exemple ci-dessus crée un PeriodicalUpdater qui rechargera les articles toutes les 30s. Si le contenu ne change pas, la prochaine exécution sera planifiée avec un timeout de 30&#215;2 secondes en doublant le <code>decay</code> après chaque passage.</p><p>Afin d&#8217;améliorer l&#8217;expérience utilisateur, pensez à cacher le contenu par css au chargement initial ; le JavaScript l&#8217;affichera évitant à l&#8217;utilisateur la vue de contenu obsolète à chaque affichage de la page. Pensez aussi à mettre une animation d&#8217;attente ou une barre de chargement si vous êtes courageux. Pour la touche finale, vous pourrez ajouter un effet pour faire apparaître la liste des articles.</p><h4><a
name="Attentionauxliensetlapaginatio"></a>Attention aux liens et à la pagination</h4><p>Dans le cadre d&#8217;un blog, la page d&#8217;accueil liste les articles les plus récents avec pour chaque article, un lien vers l&#8217;article complet et son pitch. Sans oublier les boutons de navigation pour consulter des articles plus anciens. Tous ces liens doivent aussi être traités en JavaScript.<br
/> Le script devra prendre soin d&#8217;intercepter les événements &#8216;click&#8217; sur les liens d&#8217;articles et de pagination pour permettre l&#8217;exécution en Ajax de la requête et la mise à jour de l&#8217;interface.<br
/> A l&#8217;aide d&#8217;un sélecteur CSS, nous allons retrouver les liens et observer les événements <code>click</code> en exécutant la fonction d&#8217;affichage de l&#8217;article ou de la liste.</p><pre class="brush: jscript; title: ; notranslate">
// Utilise l'URL du lien d'article pour afficher ce dernier
Blog.displayArticle = function (evt){
	var url = evt.element().href;
	// ... Update Ajax de #uiBody
};
// Intercepter le click sur un article et afficher ce dernier
$$('#uiBody a.article').each(
function (item){
		item.observe('click', Blog.displayArticle);
});
</pre><h4><a
name="PassezauJSON"></a>Passez au JSON</h4><p>Pour offrir plus de flexibilité au script, je vous recommande de passer d&#8217;un échange Ajax en HTML brut à une donnée formatée en JSON. Nous pourrons communiquer des informations au script, comme le jeton de version, sans impacter le HTML. Le formatage des articles en JSON pourra contenir la vue HTML de pré-visualisation pour la page d&#8217;accueil et le HTML complet de l&#8217;article. L&#8217;utilisation du code HTML dans l&#8217;objet JSON évite la création chronophage des éléments HTML par le script.<br
/> Dans le cas de la liste d&#8217;articles, vous allez devoir gérer la pagination de la liste à la main. Dans l&#8217;objet JSON remonté par le serveur, pensez à intégrer les informations nécessaires à la pagination (nombre d&#8217;éléments total de la liste, numéro de la page, nombre d&#8217;éléments par page). La génération des boutons de navigation peut par exemple reposer sur le plugin JQuery pagination (<a
href="http://plugins.jquery.com/project/pagination" title="httppluginsjquerycomprojectpagination" >http://plugins.jquery.com/project/pagination</a>).<br
/> Le format JSON nous servira aussi au stockage des données côté navigateur. Le <code>localStorage</code> que nous allons utiliser ne supporte que des valeurs de type chaîne de caractères. Les objets y seront donc persistés en chaînes JSON, de manière à maintenir la structure objet sans surcoût de mapping.<br
/> <strong>Attention</strong> à l&#8217;injection de code dans vos objets JSON, pensez à toujours passer par une librairie JavaScript comme PrototypeJS ou JQuery pour évaluer l&#8217;arbre JSON. Elles se chargeront pour vous de faire les contrôles de syntaxe nécessaires ainsi que la conversion automatique du contenu JSON des réponses AJAX.</p><h3><a
name="Lemodehorsligne"></a>Le mode hors ligne</h3><p>Que se passe-t-il lorsque le navigateur est hors ligne ? En l&#8217;état actuel des choses, la page reste vide ou affiche un contenu obsolète issu du premier chargement. Dans certain cas, le bloc de notification restera même désespérément &#8216;online&#8217;.</p><h4><a
name="GestionderreurAjax"></a>Gestion d&#8217;erreur Ajax</h4><p>Le script doit traiter les erreurs AJAX, et mettre à jour le bloc de notification en cas d&#8217;indisponibilité du serveur. Pensez à positionner un timeout sur vos requêtes pour limiter le temps de chargement et détecter les erreurs réseau.  Attention aussi aux redirections HTTP, les requêtes Ajax les suivent si elles sont sur le même domaine. La requête pourra être réussie et contenir la page de login vers laquelle vous aurez été redirigé si vous n&#8217;avez plus de session.<br
/> En cas de problème réseau, mettez à jour le bloc de notification <code>Utils.link.setLineState(false);</code> et exécutez le traitement hors-ligne reposant sur les données stockées dans le navigateur.  Si vous n&#8217;utilisez pas le ping HTTP, pensez aussi à mettre à jour le bloc de notification lorsqu&#8217;une requête Ajax réussit pour éviter la notification hors-ligne éternelle.</p><h4><a
name="Stratgiedestockage"></a>Stratégie de stockage</h4><p>Bien sûr HTML5 fournit différents supports de persistance dans le navigateur allant de la base de données SQL au stockage dans des tables clé-valeur en passant par les tables clé-valeur indexées. Aujourd&#8217;hui seul le stockage de type clé-valeur (<code>localStorage</code>, <code>sessionStorage</code>) est supporté par tous les navigateurs. Les autres API sont intéressantes et pourront faire l&#8217;objet d&#8217;études futures mais pour cet article, je me suis contenté d&#8217;utiliser le <code>localStorage</code> directement disponible sur tous les navigateurs.</p><p>Attention, le <code>localStorage</code> ne convient pas à la persistance d&#8217;une grande quantité de tuples. Ne comptez pas non plus fournir des fonctionnalités de recherche hors-ligne. L&#8217;API du <code>localStorage</code> permet simplement de lister les clés, de récupérer la chaîne associée à une clé et d&#8217;associer une chaîne à une clé. Nous pourrons aussi supprimer une clé et sa valeur de la table ou vider l&#8217;intégralité de la table. C&#8217;est le script qui va devoir combler les manques de l&#8217;API en maintenant ses propres index.</p><p>Choisissons maintenant le support que nous allons fournir:</p><ul><li>Proxy cache &#8211; Le script stocke le résultat des requêtes AJAX dans le localStorage et utilise les objets JSON stockés si le serveur est indisponible. Ce type de stockage est adapté aux contenus liés (tag cloud, articles les plus lus, &#8230;) évoluant peu, mais il trouvera vite ses limites dans la gestion du contenu principal pour la pagination notamment. La taille du localStorage va grandir à chaque nouvel article et les articles n&#8217;ayant pas été visités ne seront pas disponibles hors-ligne.</li><li>Synchronisation automatique &#8211; Stockage d&#8217;un nombre restreint d&#8217;articles en fonction de la date de publication par exemple. Le navigateur doit synchroniser les n articles les plus récents lorsqu&#8217;il est en ligne. En mode hors-ligne, le navigateur ne listera que les articles disponibles dans le localStorage. Le script sera un peu plus compliqué à réaliser mais la taille de la base locale sera fixe et la pagination inutile. La synchronisation automatique est sans doute le meilleur choix dans le cas du blog en lecture seule.</li><li>Synchronisation manuelle &#8211; Stockage manuel des articles à positionner dans le cache. L&#8217;utilisateur choisi lui même d&#8217;ajouter les articles dans le localStorage à l&#8217;aide d&#8217;un bouton radio par exemple. Pour chaque article listé, le script indique si il est disponible hors ligne. Lorsque le serveur est indisponible, le navigateur n&#8217;affichera que les articles persistés dans le localStorage. Là encore, le script sera plus compliqué car cela ajoute plusieurs traitements d&#8217;évenements. Il faudra limiter le nombre d&#8217;articles persistants pour éviter les scripts trop longs et trop consommateurs en mémoire. La synchronisation manuelle est la plus efficace et la mieux sécurisée pour autoriser l&#8217;édition des articles hors-ligne.</li></ul><p>Vous l&#8217;aurez compris, c&#8217;est la synchronisation automatique que nous allons retenir pour assurer l&#8217;accès au blog hors-ligne et en lecture seule.</p><p>Nous voulons lister des articles pour pouvoir afficher une introduction dans la liste des articles et le contenu intégral dans la page d&#8217;article. Nous allons donc créer une vue logique servie par un DAO article qui se chargera de persister les articles, et de les lister. Le DAO pourra par exemple, maintenir la liste des identifiants d&#8217;article dans un tableau stocké avec la clé <code>article.index</code>. Cette liste sera triée par ordre de date de publication décroissante pour éviter d&#8217;avoir à réaliser des tris couteux en JavaScript.<br
/> Chaque article sera stocké avec une clé de type <code>article.id</code> en remplaçant <code>id</code> par l&#8217;identifiant de l&#8217;article. Pour limiter le temps de traitement l&#8217;introduction et le contenu serront stockés séparément. Cela évite le chargement des articles complets pour toute les pages affichant une liste d&#8217;articles (pagination, tri, recherche, &#8230;). La clé <code>article.index</code> contiendra en plus des identifiants les introductions de chaque article.</p><pre class="brush: jscript; title: ; notranslate">
var Article = {};
Article.DAOLocalStorageClass = Class.create( {
	initialize: function(){
		var articles = window.localStorage.getItem(&quot;article.index&quot;);
		if (articles != null &amp;&amp; articles.isJSON()){
			this.articles= articles.evalJSON();
		}else {
			this.articles = [];
		}
	},
	getArticleList: function(){
		return this.articles;
	},
	getArticle: function(id){
		var article = window.localStorage.getItem(&quot;article.&quot;+id);
		if (article != null &amp;&amp; article.isJSON()){
			return article.evalJSON();
		}
		return null;
	},
	setArticleList: function(list){
		if (list != null){
			window.localStorage.setItem(&quot;article.index&quot;, list.toJSON());
			this.articles = list;
		}
		else {
			this.articles = [];
		}
	},
	setArticle: function (article){
		if (article != null){
			window.localStorage.setItem(&quot;article.&quot;+article.id, article.toJSON());
		}
	},
	removeArticle: function(id){
		window.localStorage.removeItem(&quot;article.&quot;+id);
	},
	clear: function(){
		this.articles.each(function (item){
			window.localStorage.removeItem('article.'+item.id);
		});
		window.localStorage.removeItem('article.index');
		this.articles =[];
	}
});
Article.DAO = new Article.DAOLocalStorageClass();
</pre><p>Avec ce DAO nous sommes capables de gérer une petite liste d&#8217;articles persistés dans le navigateur. Si le navigateur implémente le <code>localStorage</code> et autorise le site à l&#8217;utiliser, notre DAO fonctionnera sans problème. Mais le DAO ne supporte pas de dégradation en cas d&#8217;indisponibilité du <code>localStorage</code>. La solution retenue est d&#8217;utiliser un bouchon à la place du <code>localStorage</code> dans ce cas.</p><pre class="brush: jscript; title: ; notranslate">
initialize: function(){
	this.enabled = false;
		this.storage = this.getStorage();
 		// ...
},
	getStorage: function(){
		if(window.localStorage){
			this.enabled = true;
			return window.localStorage;
		}else {
			return {
					setItem: function (){},
					getItem: function (){ return null;},
					removeItem: function () {}
			};
		}
	},
</pre><p>La méthode <code>getStorage()</code> fournit un bouchon et positionne la propriété <code>this.enabled</code> à <code>true</code> si le navigateur supporte bien le <code>localStorage</code>. Le reste du DAO doit être modifié pour utiliser <code>this.localStorage</code> au lieu de <code>window.localStorage</code>.</p><p>Passons maintenant à la récupération des données à persister. Nous allons développer un service de synchronisation des articles les plus récents pour renseigner notre base d&#8217;articles locale.</p><pre class="brush: jscript; title: ; notranslate">
		new Ajax.Request('sync', {
			  method: 'get',
			  onSuccess: function(transport) {
				if (transport.responseJSON != null){
Article.DAO.clear();				Article.DAO.setArticleList(transport.responseJSON.articles);
					transport.responseJSON.articles.each(function (pitch){
						new Ajax.Request('/article/'+pitch.id, {
							onSuccess: function(transport) {
								if (transport.responseJSON != null){
									Article.DAO.setArticle(transport.responseJSON);
								}
						  	}
						});
					});
				}
			  }
			  }
			});
</pre><p>Le code ci-dessus invoque un web service JSON qui lui retourne la liste des articles les plus récents avec les pitchs à la manière du service listant les articles. La base locale est d&#8217;abord vidée intégralement, puis la liste est persistée. Pour chaque article listé, une requête Ajax est lancée pour en récupérer le contenu et le stocker. Bien que la méthode soit assez consommatrice en ressources, elle a le mérite de fonctionner. Une bonne amélioration à réaliser serait de ne récupérer que les nouveaux articles tout en évitant de vider la base à chaque synchronisation.<br
/> Une fois la liste récupérée, il faut supprimer de la base les articles qui ne sont plus listés et télécharger tous les nouveaux ainsi que ceux nécessitants une mise à jour (date ou version différente).<br
/> N&#8217;oublions pas la règle d&#8217;or de la notification utilisateur. Nous devons montrer à l&#8217;utilisateur l&#8217;état de la synchronisation. Il suffit de stocker dans un contexte un booléen à true si la synchronisation est en cours et un compteur des requêtes Ajax lancées et non terminées. Lorsque la derniere requête se terminera elle décrémentera le compteur à zéro, passera le booléen à false et pourra alors notifier l&#8217;utilisateur. Pour le contrôle d&#8217;erreur on ajoutera un champs error initialement vide dans le contexte qui sera renseigné en cas d&#8217;erreur Ajax.</p><pre class="brush: jscript; title: ; notranslate">
var syncCtx = { running: false, requestCount: 0, error: null};
</pre><p>Il faut lancer la synchronisation au chargement de la page et à chaque fois que le navigateur passe en ligne. En principe pour un blog cela devrait suffire car les utilisateurs ne restent pas connectés très longtemps et le contenu change peu. Dans un site où le contenu évolue rapidement, pensez à exécuter la synchronisation à intervalle régulier. Attention, il est inutile de lancer ce nouveau service si <code>!Article.DAO.enabled</code>, puisqu&#8217;aucun article ne sera persisté dans ce cas.</p><p>Les fonctions d&#8217;affichage précédemment créées doivent-être modifiées pour utiliser le DAO lorsque le navigateur est hors-ligne. Comme vous avez pu le constater de nombreux cas d&#8217;erreur sont envisageables : veillez à afficher un contenu alternatif en cas d&#8217;indisponibilité des données.</p><h4><a
name="Gestiondesformulaires"></a>Gestion des formulaires</h4><p>Les requetes POST sont toujours envoyées sur le serveur sans tenir compte du cache manifest. Lors d&#8217;un POST redirect le navigateur pourra afficher la page depuis le cache. Si la réponse du POST contient la page elle sera affichée telle quelle par le navigateur. Seules les requêtes de type GET sont élligibles au cache. Quand le navigateur est hors-ligne, les formulaires utilisant la méthode POST vont afficher le message d&#8217;erreur HTTP habituel. Si toutefois vous utilisez la méthode GET, le manifest pourra être utilisé pour fournir une version hors-ligne de la page. Pour permettre l&#8217;utilisation d&#8217;un formulaire hors-ligne nous allons le soumettre via une requête AJAX en captant l&#8217;évènement &#8216;submit&#8217; du formulaire.  Le handler sérialisera les données du formulaire dans un objet JSON ou directement dans la requête AJAX à soumettre sous forme de POST HTTP au serveur.</p><pre class="brush: jscript; title: ; notranslate">
	// Ecouter le submit du formulaire
$('form').observe('submit', function (evt){
// Soumettre le formulaire en AJAX
			$('form').request({
				method: 'post',
onComplete: function () {
	// Affiche alerte 'Post Submitted'
	alert('Post submitted !');
}});
// Stopper l'évènement submit pour que le navigateur ne le traite pas
evt.stop();
});
</pre><p>Ajoutons un peu de traitement pour les cas d&#8217;erreur (indisponibilité du serveur, authentification requise) et le mode hors-ligne.  Dans les deux cas, le principe sera d&#8217;enregistrer la modification dans le <code>localStorage</code> sous la forme d&#8217;un évènement qui pourra être synchronisé lorsque la connexion le permettra.</p><pre class="brush: jscript; title: ; notranslate">
addEvent: function (evt){
	this.events.push(evt);
	this.storage.setItem('events', this.events.toJSON());
},
getEvents: function (){
	return this.events;
},
clearEvents: function(){
	this.events = [];
	this.storage.removeItem('events');
}
</pre><p>Sur POST d&#8217;un nouveau commentaire, l&#8217;évènement est enregistré dans la base locale.</p><pre class="brush: jscript; title: ; notranslate">
Article.DAO.addEvent({ type: 'comment', comment: $('form').serialize(true)});
</pre><p>Pour indiquer à l&#8217;utilisateur que le commentaire est bien pris en compte, pensez à vider les champs du formulaire et à afficher un message d&#8217;information par exemple. Ajoutez aussi un élément à l&#8217;interface pour indiquer à l&#8217;utilisateur qu&#8217;il y a des données à synchroniser avec le serveur. Cela pourra être un bouton ou un lien qui permettra de soumettre au serveur les modifications réalisées hors-ligne ou hors session.  Dans le cas des commentaires, il est possible de prévoir une synchronisation automatique quand le navigateur passe en ligne et au chargement de la page. En revanche cette pratique est fortement déconseillée pour des évènements concernant des articles modifiés.<br
/> Vous l&#8217;aurez compris tous les évènements qui nécessitent une authentification de l&#8217;utilisateur doivent être synchronisés manuellement à la demande de ce dernier. Prévoyez une interface d&#8217;administration permettant de lister, éditer et supprimer les évènements à synchroniser.</p><h3><a
name="Conclusion"></a>Conclusion</h3><p>Avec l&#8217;utilisation conjointe du <code>localStorage</code> et du MANIFEST, nous pouvons fournir une application qui fonctionnera hors ligne.  Les étapes que nous avons suivies prises séparément sont assez simples. Mais les impacts sont nombreux et plusieurs refactoring seront nécessaires sur le serveur. Le passage au mode hors ligne ne se fera pas sans mal. L&#8217;API <code>localStorage</code> n&#8217;est pas destinée à stocker et manipuler un grand nombre d&#8217;objets. Elle ne sera d&#8217;aucun secours pour la recherche, et le tri des listes par exemple. En bref les limitations du <code>localStorage</code> compliquent fortement les développements. Pour créer une application hors-ligne capable de gérer un grand nombre de données et affichant des fonctionnalités égales à des applications de bureau, vous devrez passer par l&#8217;utilisation d&#8217;un autre mode de stockage comme l&#8217;API <a
href="http://www.w3.org/TR/webdatabase/" title="WebSqlDatabase" >WebSqlDatabase</a> pour travailler en SQL ou bien l&#8217;API <a
href="http://www.w3.org/TR/IndexedDB/" title="WebIndexedDatabase" >WebIndexedDatabase</a> qui répondent à ces besoins. Notez tout de même que WebSQLDatabase n&#8217;est supportée ni par IE, ni par Firefox. L&#8217;API IndexedDB n&#8217;est de son côté supportée que par Firefox et Chrome. Pour un support tout navigateur vous devrez passer par l&#8217;utilisation des API fournies par <a
href="http://gears.google.com/" title="Google Gears" >Google Gears</a>. L&#8217;inconvénient étant que Gears n&#8217;implémente pas les API du standard en cours d&#8217;écriture HTML5. À terme, l&#8217;extension risque même de disparaître au profit des implémentations natives des navigateurs HTML5.</p><div
class="shr-publisher-6208"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F12%2F17%2Fapplication-hors-ligne-html5-le-javascript%2F' data-shr_title='Application+hors-ligne+HTML5+le+JavaScript'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F12%2F17%2Fapplication-hors-ligne-html5-le-javascript%2F' data-shr_title='Application+hors-ligne+HTML5+le+JavaScript'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/12/17/application-hors-ligne-html5-le-javascript/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Application hors-ligne avec HTML5 &#8211; le manifest</title><link>http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/</link> <comments>http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#comments</comments> <pubDate>Thu, 02 Dec 2010 21:53:06 +0000</pubDate> <dc:creator>Séven Le Mesle</dc:creator> <category><![CDATA[Non classé]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[cache]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[manifest]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=6054</guid> <description><![CDATA[Dans le train, l&#8217;avion, plus généralement en déplacement, combien se retrouvent perdus sans la précieuse connexion à internet ? Rappelez vous la dernière fois que vous avez voulu consulter un article ou une documentation en ligne. Prenons le cas d&#8217;un blog : vous voulez pouvoir le lire en déplacement, voire même pouvoir éditer vos articles [...]]]></description> <content:encoded><![CDATA[<p>Dans le train, l&#8217;avion, plus généralement en déplacement, combien se retrouvent perdus sans la précieuse connexion à internet ? Rappelez vous la dernière fois que vous avez voulu consulter un article ou une documentation en ligne. Prenons le cas d&#8217;un blog : vous voulez pouvoir le lire en déplacement, voire même pouvoir éditer vos articles en cours de rédaction. Avec le manifest de cache HTML5, il est possible de rendre disponible hors-ligne les interfaces web. Dans cet article, nous étudierons la mise en pratique d&#8217;un manifest de cache appliquée à un blog.</p><h3> Sommaire</h3><ul><li><a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#Principedefonctionnement">Principe de fonctionnement</a></li><li><a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#Ecrirelemanifestducache">Écrire le manifest du cache</a></li><li><a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#Integererlemanifestalapplication">Intégrer le manifest à l&#8217;application</a></li><li><a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#Gererlamiseajourducache">Gérer la mise à jour du cache</a></li><li><a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#GererlecacheenJavaScript">Gérer le cache en JavaScript</a></li><li><a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#Allerplusloinaveclemanifest">Aller plus loin avec le manifest</a></li><li><a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#Notesdesecurite">Notes de sécurité</a></li><li><a
href="http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/#Conclusion">Conclusion</a></li></ul><h3><a
name="Principedefonctionnement"></a>Principe de fonctionnement</h3><p>Une page HTML intègre une référence vers un fichier manifest. Celui-ci liste les URL des ressources à mettre dans le cache. Quand le navigateur charge la page pour la première fois, il va télécharger toutes les URL du manifest et les stocke dans le cache. Tous les chargements suivants se feront directement à partir du cache sans passer par le serveur.</p><p>En parallèle, le navigateur va vérifier la version de son fichier manifest auprès du serveur. En cas de mise à jour, le navigateur va télécharger l&#8217;intégralité des ressources dans un nouveau cache, qui sera utilisé pour tous les chargements suivants.</p><p>Que le navigateur soit en ligne ou hors-ligne, il n&#8217;y a plus aucun impact sur l&#8217;affichage de la page qui vient directement du cache.<br
/> Maintenant que vous connaissez le principe de fonctionnement passons à la première étape.</p><h3><a
name="Ecrirelemanifestducache"></a>Écrire le manifest du cache</h3><p>Il s&#8217;agit d&#8217;un fichier texte encodé en UTF-8 qui contient une liste d&#8217;URLs réparties en trois sections :</p><ul><li>CACHE : C&#8217;est la section par défaut, elle contient les URLs que le navigateur doit impérativement mettre en cache.</li><li>NETWORK : Liste les URLs qui doivent toujours être consultées sur le serveur. Ce sera par exemple le cas des ressources AJAX et des ressources externes (publicité, &#8230;).</li><li>FALLBACK :  Cette section permet d&#8217;associer des préfixes d&#8217;URL à des ressources alternatives utilisées en cas d&#8217;indisponibilité.</li></ul><p>Passons maintenant à la pratique : la première chose à faire est de créer notre cache manifest.</p><pre class="brush: java; title: ; notranslate">
CACHE MANIFEST
# Version 1 25/09/2010
images/img01.gif
images/img02.gif
images/img03.gif
styles/default.css
lib/demo.js
demo.html
offline.html
NETWORK:
/online.html
FALLBACK:
/online  offline.html
</pre><p>Le navigateur doit donc conserver en cache les ressources statiques du site (images, css, javascript), ainsi que la page demo.html.<br
/> La page online.html sera toujours consultée sur le serveur. En cas d&#8217;indisponibilité, le navigateur affichera la page offline.html à la place du service en ligne.</p><p>Par défaut, seules les ressources listées dans le cache explicite sont disponibles. Par exemple : si vous oubliez de lister une image, celle-ci ne sera pas affichée dans la page. Il faut donc lister toutes les ressources, ou bien ajouter le joker &#8216;*&#8217; dans la section NETWORK afin de permettre le téléchargement des ressources manquantes. Les ressources listées dans la section CACHE sont toujours prioritaires sur les autres. De ce fait, le joker n&#8217;a aucune incidence sur la mise en cache, il permet seulement d&#8217;accéder à d&#8217;autres ressources, y compris sur des domaines différents.</p><h3><a
name="Integererlemanifestalapplication"></a>Intégrer le manifest à l&#8217;application</h3><p>Pour activer le cache, il reste maintenant à ajouter le fichier dans l&#8217;application web et à référencer son URL dans l&#8217;attribut <code>manifest='cache-manifest.mf'</code> en s&#8217;assurant qu&#8217;il est encodé en UTF-8 et que le serveur lui donnera bien le type mime &#8216;text/cache-manifest&#8217;.</p><p>web.xml:</p><pre class="brush: xml; title: ; notranslate">
&lt;mime-mapping&gt;
    &lt;extension&gt;mf&lt;/extension&gt;
    &lt;mime-type&gt;text/cache-manifest&lt;/mime-type&gt;
&lt;/mime-mapping&gt;
</pre><p>Pages HTML:</p><pre class="brush: xml; title: ; notranslate">
&lt;html manifest=&quot;cache-manifest.mf&quot;&gt;
...
</pre><p>Au premier chargement d&#8217;une page, le navigateur va construire son cache en téléchargeant toutes les ressources listées dans le manifest et afficher la page. Après quoi, le navigateur affichera toujours cette page à partir du cache.<br
/> Notez bien que toute page référençant le manifest est ajoutée dans le cache explicite associé à ce dernier. Dans le cas de la page <code>online.html</code>, il ne faut donc surtout pas y référencer le fichier manifest.</p><p>Nous avons maintenant une première démonstration fonctionnelle que l&#8217;on peut qualifier de preuve de concept. Nous souhaitons modifier la page <code>demo.html</code> pour y ajouter un peu de contenu. Malheureusement, vous l&#8217;aurez compris, la modification du fichier html sur le serveur n&#8217;a aucun effet immédiat.</p><h3><a
name="Gererlamiseajourducache"></a>Gérer la mise à jour du cache</h3><p>Souvenez vous, le navigateur vérifie toujours la version du fichier manifest au chargement des pages du cache. Si le manifest n&#8217;est plus à jour, le navigateur va le récupérer et va télécharger l&#8217;ensemble des ressources dans une nouvelle version du cache en tache de fond. Au prochain chargement de la page, le navigateur utilisera le cache le plus à jour et vous pourrez constater la prise en compte de vos modifications.</p><p>Attention, les ressources du manifest sont téléchargées en outrepassant les directives de cache HTTP. A contrario, le fichier manifest est géré dans un cache standard du navigateur, ce qui signifie qu&#8217;il respecte les standards de mise en cache. Si le serveur est configuré pour forcer la mise en cache pendant trois semaines du fichier manifest, il vous faudra attendre autant de temps avant de pouvoir voir la moindre modification de votre interface.</p><p>En développement, l&#8217;interface change régulièrement, il donc est impératif d&#8217;interdire la mise en cache du fichier à l&#8217;aide du header HTTP <code>Cache-Control</code>. Pour la production, les directives de cache peuvent-être plus agressives (24h par exemple) car l&#8217;interface évolue moins vite. Les en-têtes HTTP peuvent-être positionnées à l&#8217;aide d&#8217;un filtre sur l&#8217;URL du manifest ou d&#8217;une Servlet générant le manifest.</p><p>A chaque modification du fichier manifest détectée par le navigateur, celui-ci re-télécharge l&#8217;intégralité du cache. Pour garantir la mise à jour du cache à chaque nouvelle version de l&#8217;application, il faut donc modifier le fichier manifest. C&#8217;est le rôle du commentaire <code># version 1 25/09/2010</code> qui changera à chaque livraison ou déploiement de l&#8217;application.</p><p>Le site est donc consultable hors-ligne et nous sommes capables de forcer la mise à jour du cache. L&#8217;utilisateur pourra continuer à consulter le site et verra une page d&#8217;erreur appropriée s&#8217;il tente d&#8217;accéder à des services indisponibles.  Pour un site statique c&#8217;est très bien mais quand on parle d&#8217;application, on pense à quelque chose de dynamique.</p><h3><a
name="GererlecacheenJavaScript"></a>Gérer le cache en JavaScript</h3><p>Pour un blog dont le contenu évolue lentement, il est envisageable de s&#8217;assurer que la version du manifest soit changée à chaque nouvel article. Le manifest devient alors un service généré par l&#8217;application qui change le commentaire de version à chaque nouvel article.<br
/> Malheureusement, l&#8217;utilisateur ne pourra voir le nouvel article qu&#8217;à son deuxième passage sur le site, une fois que le cache aura été mis à jour. Un début de solution est d&#8217;utiliser l&#8217;API JavaScript pour recharger automatiquement la page lorsque le nouveau cache est prêt.</p><p>L&#8217;objet <code>window.applicationCache</code> va nous permettre de :</p><ul><li>Suivre l&#8217;activité et l&#8217;état du cache associé au document courant.</li><li>Lancer le téléchargement de la nouvelle version du cache si le manifest a changé.</li><li>Activer la nouvelle version du cache pour que les prochains chargements l&#8217;utilisent.</li></ul><pre class="brush: xml; title: ; notranslate">
&lt;script&gt;
// Activer le nouveau cache quand il est disponible et recharger la page
window.applicationCache.addEventListener('updateready', function (){
  	window.applicationCache.swapCache();
  	alert('mise a jour du cache');
  	window.location.reload();
}, false);
// Notifier les erreurs
window.applicationCache.addEventListener('error', function (evt){
	alert('Erreur du cache : ' + evt);
}, false);
// Vérification de la version du manifest
window.applicationCache.addEventListener('checking', function (evt){
	alert('Vérification du cache : ' + evt);
}, false);
// Télécharger le nouveau cache quand le manifest a changé
window.applicationCache.addEventListener('obsolete', function (evt){
	alert('Le cache est obsolète : ' + evt);
	window.applicationCache.update();
}, false);
// Le manifest n'a pas changé
window.applicationCache.addEventListener('noupdate', function (evt){
	alert('Pas de mise à jour du cache : ' + evt);
}, false);
&lt;/script&gt;
</pre><p>Ce code rechargera automatiquement la page du navigateur lorsque le cache aura été mis à jour. Le lecteur du blog peut maintenant voir rapidement le nouvel article ou tout du moins son introduction. Pour pouvoir lire l&#8217;article hors-ligne, il faudra qu&#8217;il pense à afficher la page au moins une fois pour la mettre en cache.</p><h3><a
name="Allerplusloinaveclemanifest"></a>Aller plus loin avec le manifest</h3><p>La solution peut être de créer un service générant le manifest en changeant, d&#8217;une part, de version à chaque nouvel article publié et, d&#8217;autre part, en listant les URLs des derniers articles dans le cache explicite. Le chargement prendra plus de temps mais le lecteur pourra consulter l&#8217;article hors-ligne sans plus d&#8217;effort.</p><p>Attention, les pages implicites qui déclarent le manifest sans être listées dans ce dernier y sont ajoutées et seront téléchargées elles aussi lors de la mise à jour du cache.<br
/> Soyez prudent quand vous activez le manifest et ne multipliez pas les pages. Dans le cas du blog par exemple les pages affichant les articles ne doivent pas utiliser le manifest. Le lecteur ne souhaite certainement pas télécharger l&#8217;ensemble des articles qu&#8217;il a déjà lu à chaque nouvel article.</p><p>Cette solution minimaliste peut convenir à certains, mais elle n&#8217;est pas applicable pour un site dont le contenu change beaucoup ou pour un site à fort trafic tant l&#8217;utilisation du cache est mauvaise.</p><p>Pour optimiser l&#8217;utilisation du cache, il faut le considérer comme la vue statique de l&#8217;application qui évoluera au gré des changements d&#8217;interface et non au gré du contenu. Le contenu dynamique devra être servi par des requêtes asynchrones. Pour la mise en cache et le fonctionnement il faudra utiliser les nouvelles API JavaSript : <code>LocalStorage</code> et <code>document.onLine</code>. De cette manière, le manifest redeviendra un fichier statique évoluant au gré des versions de l&#8217;application.</p><p>Pour garantir l&#8217;indexation du contenu par les moteurs de recherche et assurer la compatibilité avec d&#8217;anciens navigateurs, prévoyez toujours un mode dégradé sans manifest ni contenu asynchrone.</p><h3><a
name="Notesdesecurite"></a>Notes de sécurité</h3><p>Notez que le cache est maintenu par nom de domaine. Il n&#8217;existe qu&#8217;une seule instance du même manifest pour un serveur. Pour les serveurs hébergeant plusieurs applications, l&#8217;utilisation d&#8217;hôte virtuel est plus que conseillée.</p><p>Le cache ne doit jamais contenir de données confidentielles. Les pages de login et tous services de sécurité doivent être exclus du cache. Ne les listez jamais dans le manifest sauf pour les exclure et surtout n&#8217;intégrez pas le manifest dans ces pages.</p><p>Informez l&#8217;utilisateur sur les dangers de ce service et surtout laissez le choisir d&#8217;activer ou non le fonctionnement hors ligne.  En effet si le navigateur lui-même n&#8217;est pas protégé, toute personne y ayant accès pourra consulter le cache. Pour limiter le problème vous pouvez activer le service en stockant un cookie sur le navigateur si l&#8217;utilisateur active le mode hors ligne. Ainsi le lecteur devra répéter l&#8217;opération pour tous les navigateurs sur lesquels il souhaite consulter le site.</p><p>En dehors de ces règles de sécurité basiques, toutes les règles de sécurité inhérentes aux sites web s&#8217;appliquent.</p><h3><a
name="Conclusion"></a>Conclusion</h3><p>Dans ce premier article, nous avons posé la première pierre d&#8217;une application hors-ligne, en intégrant un fichier manifest pour mettre en cache son interface et ses ressources statiques. Dans le prochain article, nous verrons comment utiliser les nouvelles API JavaScript pour permettre de lire et d&#8217;éditer du contenu hors-ligne.</p><p>Les points importants du manifest :</p><ul><li>Versionnez le manifest avec un commentaire</li><li>Désactivez ou maitrisez les directives de cache HTTP</li><li>Minimisez le nombre de pages référençant le manifest</li><li>Stockez uniquement les ressources statiques du site</li></ul><div
class="shr-publisher-6054"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F12%2F02%2Fapplication-hors-ligne-avec-html5-le-manifest%2F' data-shr_title='Application+hors-ligne+avec+HTML5+-+le+manifest'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F12%2F02%2Fapplication-hors-ligne-avec-html5-le-manifest%2F' data-shr_title='Application+hors-ligne+avec+HTML5+-+le+manifest'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-le-manifest/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Devoxx &#8211; Les nouveautés de la plateforme Flash</title><link>http://blog.xebia.fr/2010/11/23/devoxx-les-nouveautes-de-la-plateforme-flash/</link> <comments>http://blog.xebia.fr/2010/11/23/devoxx-les-nouveautes-de-la-plateforme-flash/#comments</comments> <pubDate>Tue, 23 Nov 2010 11:40:45 +0000</pubDate> <dc:creator>Ellène Dijoux</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[Adobe]]></category> <category><![CDATA[AIR]]></category> <category><![CDATA[Devoxx]]></category> <category><![CDATA[Flash]]></category> <category><![CDATA[Flash Catalyst]]></category> <category><![CDATA[Flex Hero]]></category> <category><![CDATA[LiveCycle]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=5997</guid> <description><![CDATA[A l&#8217;origine Michaël Chaize évangéliste de la plateforme Flash devait présenter cette session seul. Mais finalement il a obtenu le renfort de James Ward évangéliste Flex qui y a ajouté son expérience sur Flex et la plateforme Flash. &#160; &#160; &#160; L&#8217;avantage du Flash L&#8217;avantage du Flash est la possibilité de développer des applications plus [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://blog.xebia.fr/wp-content/uploads/2010/11/adobe.jpg" border="0" alt="" style="margin: 1em 1em 1em 1em; float: right;" /><br
/> A l&#8217;origine <a
href="http://www.riagora.com/" title="Michaël Chaize" >Michaël Chaize</a> évangéliste de la plateforme Flash devait présenter cette session seul. Mais finalement il a obtenu le renfort de <a
href="http://www.jamesward.com/" title="James Ward" >James Ward</a> évangéliste Flex qui y a ajouté son expérience sur Flex et la plateforme Flash.</p><p>&nbsp;<br
/> &nbsp;<br
/> &nbsp;</p><h3><a
name="LavantageduFlash"></a>L&#8217;avantage du Flash</h3><p>L&#8217;avantage du Flash est la possibilité de développer des applications plus intuitives, efficaces et faciles à utiliser. Michael nous présente une application pour la finance réalisée pour une grande banque française. Le backend est resté le même, seul le client a été modifié pour être remplacé par du Flex. Une amélioration de la productivité des utilisateurs a pu être constatée. En effet, les données étaient plus facilement lisibles et exploitables par les utilisateurs qui prenaient donc des décisions plus rapidement.<br
/> Michael met en avant la productivité par le design. L&#8217;avantage de Flex est la facilité avec laquelle on peut réaliser des applications. Elle est productive pour le développeur et pour l&#8217;utilisateur.</p><h3><a
name="LesnouveautsdelaplateformeFlas"></a>Les nouveautés de la plateforme Flash</h3><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/11/platform_overview.png" border="0" alt="" /></div><p>Tout d&#8217;abord Adobe a intégré dans sa plateforme le support d&#8217;HTML5 pour que ses outils, tels que Dreamweaver et Illustrator par exemple, le supportent .<br
/> La <a
href="http://www.adobe.com/fr/flashplatform/" title="plateforme Flash" >plateforme Flash</a> est un panel complet de solutions permettant de réaliser des applications riches sur tous les supports qui vont du mobile à l&#8217;ordinateur, en passant par la télé. Cette plateforme fournit tous les outils indispensables au développement d&#8217;applications, vidéos et autres. Les applications sont natives pour tous les supports. Adobe et d&#8217;autres partenaires ont d&#8217;ailleurs créé le projet open-screen qui a pour but de travailler ensemble à l&#8217;élaboration d&#8217;un environnement consistant pour la navigation web et le lancement d&#8217;application sur n&#8217;importe quel écran. Ce projet exploite les avantages de Flash Player et d&#8217;Adobe Air.</p><h3><a
name="FlashPlayer"></a>Flash Player 10.1</h3><p>Le taux de pénétration de Flash Player 10.1 est actuellement supérieur à 70%.<br
/> Les nouvelles fonctionnalités permettent maintenant d&#8217;exploiter les avantages des mobiles :</p><ul><li>le multi-touch et les gestures,</li><li>l&#8217;acceléromètre,</li><li>la gestion de l&#8217;orientation de l&#8217;écran,</li><li>les champs textes pour mobile &#8230;</li></ul><p>La performance a également été améliorée sur l&#8217;audio, la vidéo, la gestion des ressources en général pour économiser de la batterie (surtout pour les mobiles). Une nouvelle API vidéo a été développée pour réduire la charge sur le processeur comme certains ont pu le constater sur Mac OS. Elle utilise plutôt les ressources de la carte graphique pour fonctionner. L&#8217;utilisation de la mémoire a été optimisée. Pour tester ces nouvelles fonctionnalités, vous pouvez télécharger <a
href="http://www.adobeursurvey.com/devnet/flex/tourdeflex.html" title="l'application de démonstration TourDeFlex" >l&#8217;application de démonstration TourDeFlex</a> et tester la partie <a
href="http://www.adobe.com/products/flashplayer/features/" title="Flash Player APIs" >Flash Player APIs</a>. Le multi-touch est assez bluffant si vous avez un trackpad adapté <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .</p><h3><a
name="ApplicationspourMobile"></a>Applications pour Mobile</h3><p>Pour développer des applications pour mobile, vous pouvez utiliser <a
href="http://www.adobe.com/fr/products/creativesuite/devicecentral/" title="Device Central CS5" >Device Central CS5</a>. Il fait partie de la Creative Suite et fournit toutes les configurations des smartphones, telles que la mémoire, le processeur &#8230; Ces dernières sont mises à jour dynamiquement. Vous trouverez une démonstration de ce que l&#8217;on peut réaliser en terme d&#8217;application mobile <a
href="http://www.riagora.com/2010/04/air-and-the-accelerometer/" title="sur le blog de Michael Chaize" >sur le blog de Michael Chaize</a> où il présente un Doodle Jump développé avec Air et qu&#8217;il a pu déployer sur son Android en version 2.2 (Froyo).</p><h3><a
name="AIR"></a>AIR 2</h3><p>Air est une application desktop, ce qui signifie qu&#8217;il exploite les ressources de l&#8217;ordinateur. Maintenant le déploiement est possible sur Android, et pour plus d&#8217;informations je vous renvoie vers <a
href="http://blog.xebia.fr/2010/11/22/devoxx-deployer-vos-applications-air-sur-android/" title="cet article" >cet article</a>.  Autre nouvelles fonctionnalités avec AIR :</p><ul><li>ouverture des fichiers avec l&#8217;application par défaut définie par l&#8217;OS,</li><li>détection de l&#8217;OS avec l&#8217;objet Capabilities.os,</li><li>exécution possible de commandes grâce à NativeProcess.</li></ul><h3><a
name="QuoideneufsurFlexHero"></a>Quoi de neuf sur Flex Hero ?</h3><p>Flex Hero est le petit nom de la release majeure 4.1 de Flex. Dans cette nouvelle version, de nouveaux composants spark sont disponibles :</p><ul><li>une datagrid spark avec :<ul><li>gestion des déplacements avec les touches,</li><li>une skin class (apparence) plus simple à personnaliser que celui de Halo</li><li>et un chargement des données dynamique au moment du scroll. Ce qui rend le chargement plus rapide grâce à la pagination.</li></ul></li><li>un formulaire spark,</li><li>des formatters spark avec gestion de l&#8217;internationalisation,</li><li>un MobileApplication pour gérer les applications mobiles,</li><li>une API pour la navigation dans les vues,</li><li>ActionBar,</li><li>MobileItemRenderer pour les rendus de liste spécifique aux applications mobiles,</li><li>gestion de la géolocalisation,</li><li>gestion de l&#8217;orientation,</li><li>génération de l&#8217;application sous forme de package Android (APK).</li></ul><h3><a
name="FlashCatalyst"></a>Flash Catalyst</h3><p>La sortie en release preview de Flash Builder &laquo;&nbsp;Burrito&nbsp;&raquo; s&#8217;accompagne aussi de celle de Flash Catalyst &laquo;&nbsp;Panini&nbsp;&raquo;. Celui-ci a été revu pour faciliter la collaboration entre le développeur et le designer. Précédemment, le problème était que le designer ne pouvait pas retravailler sur ce qu&#8217;avait réalisé le développeur. Avec cette nouvelle version de Flash Catalyst, c&#8217;est maintenant possible.</p><h3><a
name="LiveCycleCollaborationService"></a>LiveCycle Collaboration Service</h3><p>Le LiveCycle Collaboration est une solution hébergée par Adobe pour proposer aux développeurs de réaliser des applications Flex collaboratives. Ils ont à leur disposition des composants : tableau blanc pour les dessins, gestion de la webcam &#8230; pour réaliser des applications où il est possible aux utilisateurs d&#8217;échanger des informations. Michaël nous a d&#8217;ailleurs invité à accéder à une des applications qu&#8217;il a réalisé. C&#8217;était très intéressant de voir sur le grand écran de la salle une dizaine de webcams afficher le visage de quelques participants curieux.</p><p><em>Crédit photo : les images proviennent du site d&#8217;Adobe et de</em> <em><a
href="http://picasaweb.google.com/JavaPolis.com/Devoxx2010#" title="lalbum Picasa de Stephan Jaansen" ><em>l&#8217;album Picasa de Stephan Jaansen</em></a></em> <em>pour Devoxx 2010</em></p><div
class="shr-publisher-5997"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F11%2F23%2Fdevoxx-les-nouveautes-de-la-plateforme-flash%2F' data-shr_title='Devoxx+-+Les+nouveaut%C3%A9s+de+la+plateforme+Flash'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F11%2F23%2Fdevoxx-les-nouveautes-de-la-plateforme-flash%2F' data-shr_title='Devoxx+-+Les+nouveaut%C3%A9s+de+la+plateforme+Flash'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/11/23/devoxx-les-nouveautes-de-la-plateforme-flash/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Flash Catalyst, Flash Builder l&#8217;avis de Xebia ! (suite)</title><link>http://blog.xebia.fr/2010/05/13/flash-catalyst-flash-builder-lavis-de-xebia-suite/</link> <comments>http://blog.xebia.fr/2010/05/13/flash-catalyst-flash-builder-lavis-de-xebia-suite/#comments</comments> <pubDate>Thu, 13 May 2010 08:18:31 +0000</pubDate> <dc:creator>Ellène Dijoux</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Flash Catalyst]]></category> <category><![CDATA[FlashBuilder]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=4654</guid> <description><![CDATA[Après avoir réalisé le projet sous Catalyst comme présenté dans le précédent billet, nous voici prêt à passer aux choses sérieuses : le développement de l&#8217;application. Récupération du projet Flash Catalyst Commençons donc par récupérer ce que notre designer a réalisé. Ce dernier nous génère grâce à Flash Catalyst un fichier fxp. Pour le récupérer [...]]]></description> <content:encoded><![CDATA[<p>Après avoir réalisé le projet sous Catalyst comme présenté dans <a
href="http://blog.xebia.fr/2010/04/07/flash-catalyst-flash-builder-lavis-de-xebia/" title="le prcdent billet" >le précédent billet</a>, nous voici prêt à passer aux choses sérieuses : le développement de l&#8217;application.</p><h3><a
name="RcuprationduprojetFlashCatalys"></a>Récupération du projet Flash Catalyst</h3><p>Commençons donc par récupérer ce que notre designer a réalisé. Ce dernier nous génère grâce à Flash Catalyst un fichier <code>fxp</code>. Pour le récupérer dans Flash Builder, il suffit d&#8217;aller dans <code>Fichier > Importer un projet Flex (FXP)</code> et de sélectionner le fichier à importer.</p><p>Une fois cette importation terminée, le projet apparaît comme un projet Flex classique dans Flash Builder. Il contient la librairie de Flash Catalyst. Le projet compile et s&#8217;exécute à merveille. Inspectons maintenant le code généré par Flash Catalyst.</p><h4><a
name="LapartiedesigndeFlashBuilder"></a>La partie design de Flash Builder</h4><p>Ouvrons l&#8217;application principale, c&#8217;est-à-dire le <code>Main.mxml</code> dans Flash Builder et intéressons nous à la partie Design (Conception si vous avez comme moi la version française) :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/05/etape6.png" border="0" alt="" width="650" /></div><p>Dans cette vue il est maintenant possible de visualiser les différents états possibles d&#8217;un composant.</p><h4><a
name="LalibrairieSparkdeFlex"></a>La librairie Spark de Flex 4</h4><p>Observons ensuite le composant bouton <code>Button1</code>, le code généré donne ceci :</p><pre class="brush: java; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:Skin xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot; xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot; xmlns:d=&quot;http://ns.adobe.com/fxg/2008/dt&quot;&gt;
	&lt;fx:Metadata&gt;[HostComponent(&quot;spark.components.Button&quot;)]&lt;/fx:Metadata&gt;
	&lt;s:states&gt;
		&lt;s:State name=&quot;up&quot;/&gt;
		&lt;s:State name=&quot;over&quot;/&gt;
		&lt;s:State name=&quot;down&quot;/&gt;
		&lt;s:State name=&quot;disabled&quot;/&gt;
	&lt;/s:states&gt;
	&lt;s:BitmapImage source=&quot;@Embed('/assets/images/xke_ui/telephone over.png')&quot; d:userLabel=&quot;over&quot; x=&quot;0&quot; y=&quot;0&quot; id=&quot;bitmapimage1&quot; visible.down=&quot;false&quot; visible.up=&quot;false&quot;/&gt;
	&lt;s:RichText color=&quot;0x000000&quot; fontFamily=&quot;Arial&quot; fontSize=&quot;18&quot; kerning=&quot;off&quot; lineHeight=&quot;27&quot; textAlpha=&quot;0.9&quot; d:userLabel=&quot;label&quot; whiteSpaceCollapse=&quot;preserve&quot; x=&quot;16&quot; y=&quot;4&quot; id=&quot;labelDisplay&quot; text=&quot;(Label)&quot;&gt;
	&lt;/s:RichText&gt;
	&lt;s:transitions&gt;
		&lt;s:Transition fromState=&quot;up&quot; toState=&quot;over&quot; autoReverse=&quot;true&quot;&gt;
			&lt;s:Parallel&gt;
				&lt;s:Parallel target=&quot;{bitmapimage1}&quot;&gt;
					&lt;s:Fade duration=&quot;0&quot;/&gt;
				&lt;/s:Parallel&gt;
			&lt;/s:Parallel&gt;
		&lt;/s:Transition&gt;
	&lt;/s:transitions&gt;
&lt;/s:Skin&gt;
</pre><p>Ce composant utilise Flex 4 et notamment la nouvelle librairie spark qui permet de réaliser des composants plus «customisables». C&#8217;est grâce à cette librairie que l&#8217;on peut faire collaborer designer et développeur. Comme vous pouvez le voir ici, le code MXML est vraiment différent de ce que l&#8217;on a pu voir jusqu&#8217;à maintenant avec Flex 3.<br
/> On peut retrouver toutes les informations données dans Catalyst telles que :</p><ul><li>le fait que le composant soit un bouton <code>&lt;fx:Metadata&gt;<a
href="HostComponent("spark.components.Button")" title="HostComponent("spark.components.Button")" >HostComponent("spark.components.Button")</a>&lt;/fx:Metadata&gt;</code>,</li><li>les différents états des boutons (<code>up</code>, <code>down</code>, <code>over</code>, <code>disabled</code>),</li><li>et l&#8217;apparence du bouton en lui même.</li></ul><p>Pour plus d&#8217;informations, vous pouvez consulter <a
href="http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/" title="cet article" >cet article</a> sur les nouveautés de Flex 4.</p><h3><a
name="IntgrationaubackendJava"></a>Intégration au backend Java</h3><h4><a
name="LintrospectiondesservicesavecF"></a>L&#8217;introspection des services avec Flash Builder</h4><p>Passons maintenant à l&#8217;intégration avec un <em>backend</em> Java: nous allons pour cela utiliser Flash Builder 4. Une des grandes nouveautés de cet IDE est la possibilité de réaliser l&#8217;introspection des différents services exposés côté Serveur. Il peut s&#8217;agir de services Java avec LCDS (LiveCycle Data Service ES) ou BlazeDS, ou encore de services PHP avec AmfPHP par exemple.</p><p>Le service sur lequel nous allons travailler côté Java est un simple war contenant un POJO TravelService renvoyant une liste fixe d&#8217;objets <code>Travel</code>.</p><p>Nous allons utiliser la fonctionnalité d&#8217;introspection que fournit Flash Builder 4. Pour ce faire, commençons par configurer le <code>web.xml</code> pour le développement en ajoutant la servlet permettant de réaliser l&#8217;introspection des classes Java par Flash Builder. Pour réaliser cette configuration, je me suis basée sur <a
href="http://sujitreddyg.wordpress.com/2009/10/06/building-flex-application-for-lcds-data-management-services-using-flash-builder-4/" title="cet article" >cet article</a> qui fournit toutes les librairies nécessaires.</p><pre class="brush: java; title: ; notranslate">
&lt;servlet&gt;
        &lt;servlet-name&gt;RDSDispatchServlet&lt;/servlet-name&gt;
		&lt;display-name&gt;RDSDispatchServlet&lt;/display-name&gt;
        &lt;servlet-class&gt;flex.rds.server.servlet.FrontEndServlet&lt;/servlet-class&gt;
        &lt;init-param&gt;
			&lt;param-name&gt;messageBrokerId&lt;/param-name&gt;
			&lt;param-value&gt;_messageBroker&lt;/param-value&gt;
		&lt;/init-param&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;useAppserverSecurity&lt;/param-name&gt;
			&lt;param-value&gt;false&lt;/param-value&gt;
		&lt;/init-param&gt;
        &lt;load-on-startup&gt;10&lt;/load-on-startup&gt;
    &lt;/servlet&gt;
    &lt;servlet-mapping id=&quot;RDS_DISPATCH_MAPPING&quot;&gt;
        &lt;servlet-name&gt;RDSDispatchServlet&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/CFIDE/main/ide.cfm&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
</pre><p>Cela permettra à Flash Builder de réaliser l&#8217;introspection des classes côté Java. La propriété <code>useAppserverSecurity</code> est à <code>false</code> durant la période de développement pour faciliter l&#8217;accès aux données.</p><p>Pour l&#8217;exposition des services, nous utilisons Spring BlazeDS configuré par annotation de la façon suivante.</p><pre class="brush: java; title: ; notranslate">
@Service(&quot;travelService&quot;)
@RemotingDestination(channels={&quot;my-amf&quot;})
public class TravelService {
</pre><p>Le channel est défini de façon classique dans un fichier de configuration services-config.xml dont voici un extrait :<br
/> Définition du channel :</p><pre class="brush: java; title: ; notranslate">
&lt;channel-definition id=&quot;my-amf&quot; class=&quot;mx.messaging.channels.AMFChannel&quot;&gt;
            &lt;endpoint url=&quot;http://{server.name}:{server.port}/{context.root}/messagebroker/amf&quot; class=&quot;flex.messaging.endpoints.AMFEndpoint&quot;/&gt;
        &lt;/channel-definition&gt;
</pre><p>Configuration du channel par défaut :</p><pre class="brush: java; title: ; notranslate">
&lt;services&gt;
	&lt;default-channels&gt;
             &lt;channel ref=&quot;my-amf&quot;/&gt;
     &lt;/default-channels&gt;
&lt;/services&gt;
</pre><p>Lançons maintenant notre serveur Tomcat côté Java pour y déployer notre war.</p><p>Côté Flash Builder, faites un clic droit sur votre projet puis sélectionnez <code>Propriétés > Serveur Flex</code>. Donnez le type de serveurs d&#8217;application J2EE et sélectionnez BlazeDS.</p><p>Le dossier de sortie permet à Flash Builder de pouvoir déployer l&#8217;application Flex sur le serveur d&#8217;application.</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/05/etape1.png" border="0" alt="" /></div><p>Après avoir validé la configuration, nous allons maintenant pouvoir visualiser les services disponibles pour cette application.</p><p>Allez dans le menu Données > Connexion à BlazeDS. Une authentification est demandée mais pour notre application aucun mot de passe n&#8217;est nécessaire. Sélectionnez donc &laquo;&nbsp;Aucun mot de passe requis&nbsp;&raquo;, puis Ok.</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/05/etape2.png" border="0" alt="" /></div><p>Une fois validé, vous pourrez visualiser les services disponibles côté Java exposés par BlazeDS :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/05/etape3.png" border="0" alt="" width="650" /></div><p>A ce stade vous pouvez sélectionner le service et l&#8217;associer à votre projet.</p><h4><a
name="TestersonserviceavecFlashBuild"></a>Tester son service avec Flash Builder</h4><p>En cliquant droit sur votre service, vous pouvez réaliser des opérations de test. Le test permet d&#8217;afficher les valeurs de retour de vos méthodes. Par exemple pour la méthode <code>loadAll</code> proposée par <code>TravelService</code>, nous pouvons voir les valeurs que retourne notre service.</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/05/etape4.png" border="0" alt="" /></div><h4><a
name="AssocierleservicelIHM"></a>Associer le service à l&#8217;IHM</h4><p>Le but étant de montrer ce que Flash Builder est capable de faire, nous allons utiliser tout ce qu&#8217;il nous propose en évitant le plus possible de coder.</p><p>Commençons par aller dans la vue design du <code>Main.mxml</code>, dans l&#8217;état voyages, sélectionnez la liste contenant les éléments San Francisco, cliquez droit sur le composant et sélectionnez <code>Lier aux données</code>.</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/05/etape8.png" border="0" alt="" /></div><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/05/etape5.png" border="0" alt="" /></div><p>Flash Builder propose les services précédemment configurés pour notre projet. Sélectionnez le champs de liaison aux données (dans notre cas destination) puis validez. Flash Builder va supprimer la liste de San Francisco pour la remplacer par le service sélectionné.<br
/> Maintenant en allant sur <a
href="http://localhost:8080/FlexProjectXke/" title="http://localhost:8080/FlexProjectXke/" >http://localhost:8080/FlexProjectXke/</a>, nous pouvons voir notre liste. Mais n&#8217;étant pas correctement configurée, les éléments apparaissent ainsi <a
href="object Travel" title="object Travel" >object Travel</a>. Nous allons donc faire quelques réajustements pour que l&#8217;affichage se fasse correctement.</p><p>A vrai dire, la définition de la destination ne fonctionne pas ici car la liste n&#8217;utilise pas le <code>labelField</code> mais fait appel à des composants « custom ».<br
/> Mais où doit être effectuée cette modification ? Commençons par repérer où se trouve la liste des données dans le Main.mxml :</p><pre class="brush: java; title: ; notranslate">
&lt;fx:DesignLayer d:userLabel=&quot;voyages page&quot; visible.operateurs=&quot;false&quot; id=&quot;designlayer3&quot; visible.xke=&quot;false&quot;&gt;
		&lt;s:BitmapImage source=&quot;@Embed('/assets/images/xke_ui/Objet dynamique vectoriel_1.png')&quot; d:userLabel=&quot;Objet dynamique vectoriel_1&quot; x=&quot;486&quot; y=&quot;140&quot;/&gt;
		&lt;s:BitmapImage source=&quot;@Embed('/assets/images/xke_ui/Objet dynamique vectoriel_2.png')&quot; d:userLabel=&quot;Objet dynamique vectoriel_2&quot; x=&quot;179&quot; y=&quot;140&quot;/&gt;
		&lt;s:VScrollBar skinClass=&quot;components.Objetdynamiquev_VerticalScrollbar&quot; fixedThumbSize=&quot;true&quot; x=&quot;433&quot; y=&quot;155&quot; includeIn=&quot;operateurs,xke&quot;/&gt;
		&lt;s:List skinClass=&quot;components.DataList1&quot; x=&quot;181&quot; y=&quot;155&quot; id=&quot;list&quot; creationComplete=&quot;list_creationCompleteHandler(event)&quot;  dataProvider=&quot;{loadAllResult.lastResult}&quot; labelField=&quot;destination&quot;&gt;
		&lt;/s:List&gt;
	&lt;/fx:DesignLayer&gt;
</pre><p>La liste fait appel au composant <code>DataList1</code>, regardons ce qu&#8217;il contient :</p><pre class="brush: java; title: ; notranslate">
&lt;s:DataGroup itemRenderer=&quot;components.RepeatedItem1&quot; x=&quot;0&quot; id=&quot;dataGroup&quot; width=&quot;253&quot; height=&quot;69&quot; clipAndEnableScrolling=&quot;true&quot; height.normal=&quot;332&quot; y=&quot;1&quot;&gt;
		&lt;s:layout&gt;
			&lt;s:VerticalLayout horizontalAlign.normal=&quot;left&quot; gap.normal=&quot;2&quot;/&gt;
		&lt;/s:layout&gt;
	&lt;/s:DataGroup&gt;
</pre><p>L&#8217;itemRenderer <code>RepeatedItem1</code> dans <code>DataGroup</code> fournit le rendu de chaque élément affiché dans la liste. C&#8217;est exactement à lui que l&#8217;on va s&#8217;intéresser pour personnaliser l&#8217;affichage des données.</p><pre class="brush: java; title: ; notranslate">
&lt;s:ItemRenderer xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot; xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot; xmlns:d=&quot;http://ns.adobe.com/fxg/2008/dt&quot; xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot;&gt;
	&lt;s:states&gt;
		&lt;s:State name=&quot;normal&quot;/&gt;
		&lt;s:State name=&quot;hovered&quot;/&gt;
		&lt;s:State name=&quot;selected&quot;/&gt;
	&lt;/s:states&gt;
	&lt;mx:Image source=&quot;{data.image1}&quot; d:userLabel=&quot;Objet dynamique vectoriel&quot; x=&quot;0&quot; y=&quot;0&quot; maintainAspectRatio=&quot;false&quot;/&gt;
	&lt;s:RichText color=&quot;0x000000&quot; color=&quot;0xFFFFFF&quot; fontFamily=&quot;Arial&quot; fontSize=&quot;18&quot; kerning=&quot;off&quot; lineHeight=&quot;27&quot; d:userLabel=&quot;San Francisco&quot; whiteSpaceCollapse=&quot;preserve&quot; x=&quot;10&quot; y=&quot;5&quot; text=&quot;{data.destination}&quot;&gt;
	&lt;/s:RichText&gt;
&lt;/s:ItemRenderer&gt;
</pre><p>Maintenant ajoutons l&#8217;image dans le <code>Main.mxml</code>, pour qu&#8217;elle soit affichée lorsqu&#8217;on sélectionne un pays.</p><pre class="brush: java; title: ; notranslate">
&lt;mx:Image includeIn=&quot;voyages&quot; x=&quot;495&quot; y=&quot;155&quot; width=&quot;282&quot; height=&quot;335&quot; source=&quot;{list.selectedItem.photo}&quot;/&gt;
</pre><p>Et voilà le résultat :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/05/etape7.png" border="0" alt="" width="650" /></div><h3><a
name="Conclusion"></a>Conclusion</h3><p>L&#8217;intégration dans Flash Builder de la maquette réalisée par Flash Catalyst ne fût pas aussi simple que prévue et il a fallu chercher et modifier un peu le code. Rien de très important certes, mais sur des maquettes plus complexes cela peut devenir plus compliqué. Comment en sommes nous arrivés là ? La création de l&#8217;élément répété a été faite par rapport à un texte sur fond d&#8217;image (noir si non sélectionné et gris sinon). Le problème est que la liste de données transportait initialement le chemin vers cette image, chose que le designer n&#8217;aurait pas dû faire si il s&#8217;était concerté avec le développeur. Une très bonne communication est nécessaire entre les deux mondes pour que le développeur ait un projet facilement exploitable et intégrable. A mon avis, le designer doit être sensibilisé à la qualité du code que Flash Catalyst pourrait générer en arrière plan. Sinon, le travail d&#8217;intégration au <em>backend</em> risque d&#8217;être laborieux.<br
/> Un autre inconvénient de Flash Catalyst concerne le code Flex généré: un peu lourd comparé à ce que le développeur aurait pu réaliser lui même, il fournit pas mal d&#8217;images  pour obtenir le rendu de départ, rendant le code moins compréhensible au premier abord.<br
/> Enfin Flash Builder 4 apporte beaucoup d&#8217;amélioration au développement d&#8217;application. L&#8217;auto-complétion y est améliorée. Et la récupération des services via Flash Builder permet d&#8217;éviter toute duplication des classes côté Flex, il s&#8217;occupe de gérer l&#8217;appel des services. Un gros point négatif à rayer de votre liste d&#8217;inconvénients vous empêchant de débuter un projet Flex/Java. Un outil à tester sans hésiter !</p><div
class="shr-publisher-4654"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F05%2F13%2Fflash-catalyst-flash-builder-lavis-de-xebia-suite%2F' data-shr_title='Flash+Catalyst%2C+Flash+Builder+l%27avis+de+Xebia+%21+%28suite%29'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F05%2F13%2Fflash-catalyst-flash-builder-lavis-de-xebia-suite%2F' data-shr_title='Flash+Catalyst%2C+Flash+Builder+l%27avis+de+Xebia+%21+%28suite%29'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/05/13/flash-catalyst-flash-builder-lavis-de-xebia-suite/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Flash Catalyst, Flash Builder, l&#8217;avis de Xebia !</title><link>http://blog.xebia.fr/2010/04/07/flash-catalyst-flash-builder-lavis-de-xebia/</link> <comments>http://blog.xebia.fr/2010/04/07/flash-catalyst-flash-builder-lavis-de-xebia/#comments</comments> <pubDate>Wed, 07 Apr 2010 05:41:05 +0000</pubDate> <dc:creator>Nicolas Jozwiak</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Flash]]></category> <category><![CDATA[Flash Builder]]></category> <category><![CDATA[Flash Catalyst]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=4320</guid> <description><![CDATA[Lors du XKE de Février, nous avons eu l&#8217;occasion de tester les outils Flash Catalyst et Builder en version beta. Pour ce faire, nous avons décidé de faire un projet et de présenter les facilités et les difficultés que nous avons rencontrées. Concernant le projet, ce dernier est simple : mettre en place une application [...]]]></description> <content:encoded><![CDATA[<p>Lors du XKE de Février, nous avons eu l&#8217;occasion de tester les outils Flash Catalyst et Builder en version beta. Pour ce faire, nous avons décidé de faire un projet et de présenter les facilités et les difficultés que nous avons rencontrées.<br
/> Concernant le projet, ce dernier est simple : mettre en place une application permettant de lister des voyages, et à partir d&#8217;une image Photoshop, nous allons définir les états/transitions dans Flash Catalyst, et brancher un backend Java avec Flash Builder. Cette série d&#8217;articles reprendra ces points avec nos analyses et critiques.<br
/> Avant toute chose, nous allons commencer par nous excuser auprès des designers/graphistes : n&#8217;étant pas notre coeur de métier, le design et l&#8217;ergonomie de l&#8217;application pourra peut être heurter la sensibilité de certains de nos lecteurs.</p><h3><a
name="MiseenplacedelimagePhotoshopIl"></a>Mise en place de l&#8217;image Photoshop/Illustrator</h3><p>N&#8217;ayant que très peu de connaissance de l&#8217;univers Photoshop, cette tâche s&#8217;est avérée au début périlleuse&#8230; Néanmoins, les différents tutoriaux d&#8217;Adobe permettent d&#8217;acquérir suffisamment de connaissances pour mettre en place une image, dont voici le résultat:</p><div
align="center"> <a
href="http://blog.xebia.fr/wp-content/uploads/2010/04/Img1.jpg"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img1-300x225.jpg" alt="Img1" title="Img1" width="300" height="225" class="alignnone size-medium wp-image-4322" /></a></div><p>Assez basique, le premier écran listera les voyages, et lorsque l&#8217;utilisateur cliquera sur l&#8217;un d&#8217;eux, une image s&#8217;affichera dans le panel de droite. C&#8217;est dans cet écran que sera branché notre backend Java. Le menu sera simplement utilisé afin de montrer la mise en place des états/transitions avec Catalyst. Ainsi, les autres rubriques du menu afficheront respectivement une carte, et un descriptif.</p><p>Voici notre arborescence de l&#8217;image Photoshop créée:</p><div
align="center"> <a
href="http://blog.xebia.fr/wp-content/uploads/2010/04/Img2.jpg"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img2-135x300.jpg" alt="Img2" title="Img2" width="135" height="300" class="alignnone size-medium wp-image-4323" /></a></div><p>Le principe est simple: l&#8217;image est découpée en calque, et ces derniers sont regroupés par fonctionnalités/pages. Ainsi nous retrouvons notre menu (navigation) avec les types d&#8217;effets que nous voudrons voir lorsque la souris de l&#8217;utilisateur passera sur le texte (ici une image violette), et les différentes pages avec leurs contenus.<br
/> Cette organisation est très importante, car par la suite nous l&#8217;utiliserons afin de mettre en place les transitions entre pages et créer nos composants.</p><h3><a
name="FlashCatalyst"></a>Flash Catalyst</h3><p>Une fois l&#8217;image importée dans Catalyst, nous constatons que la structure de Photoshop est bien présente et qu&#8217;un état a été créé.</p><div
align="center"> <a
href="http://blog.xebia.fr/wp-content/uploads/2010/04/Img3.jpg"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img3-300x108.jpg" alt="Img3" title="Img3" width="300" height="108" class="alignnone size-medium wp-image-4324" /></a></div><p>Nous allons commencer par créer les transitions entre les différents écrans:</p><ul><li>Sélectionnez le premier état en haut à gauche et renommez le en voyages.</li><li>Sélectionnez pour cet état la page que vous voudrez afficher dans la fenêtre <code>Layers</code> en haut à droite (en l&#8217;occurrence voyages page)</li><li>Créez deux autres états (<code>Duplicate State</code> en haut à gauche)</li><li>Répétez l&#8217;étape 2 pour les pages opérateurs et XKE.</li></ul><p>Animons cette page en créant les boutons:</p><ul><li>Revenez sur l&#8217;état «voyages».</li><li>Sélectionnez le texte «Voyages» ainsi que le fond violet.</li><li>La fenêtre <code>Convert to Artwork</code> apparaît, sélectionnez <code>Button</code>.</li><li>Re cliquez sur le texte Voyages et cochez <code>Label</code> dans la fenêtre qui est apparue.</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img4.jpg" border="0" alt="" /></div><ul><li>Dans la fenêtre <code>Layers</code> (en haut à droite), renommez Voyages en <code>Label</code> et voyages over en over (ce sera un composant générique pour les autres boutons du menu).</li><li>Revenez sur la racine de votre projet (nom du projet) et renommez le composant <code>Button</code> en voyages_button par exemple (fenêtre en haut à droite).</li><li>Ajoutez le label Voyages dans les propriétés du composant, et décochez <code>Enabled</code>.</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img5.jpg" border="0" alt="" /></div><ul><li>Sélectionnez le label de «Voyages» et modifier la couleur en noir (dans la fenêtre <code>Properties</code> en bas à droite)</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img6.jpg" border="0" alt="" /></div><ul><li>Copier coller deux fois le composant voyage_button dans la fenêtre <code>Layers</code> (en haut à droite). Ce seront les boutons Opérateurs et XKE.</li><li>Supprimez les composants du layer navigation importés de l&#8217;image Photoshop</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img7.jpg" border="0" alt="" /></div><ul><li>Tout comme «Voyages», modifiez les labels pour Opérateurs et XKE (par contre laissez la propriété <code>Enabled</code> cochée).</li><li>Vous devez réaligner les boutons les uns en dessous des autres, car en créant ces composants, Catalyst les a superposés.</li><li>Sur chaque bouton, faire clique droit => <code>Share to State</code> => <code>All States</code>.</li><li>Allez dans les états Opérateurs et xke: alignez les boutons et vérifier la couleur des labels.</li><li>Attention, pour ces états vérifiez également que pour le bouton Voyages, la propriété <code>Enabled</code> est bien cochée.</li><li>Cliquez sur le bouton Voyages, la fenêtre suivante s&#8217;ouvre</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img8.jpg" border="0" alt="" /></div><ul><li>Dans <code>Up</code> et <code>Down</code>, désélectionnez voyages over dans la fenêtre <code>layers</code>.</li></ul><div
align="center"> <a
href="http://blog.xebia.fr/wp-content/uploads/2010/04/Img9.jpg"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img9-300x26.jpg" alt="Img9" title="Img9" width="300" height="26" class="alignnone size-medium wp-image-4330"/></a></div><ul><li>Cliquez sur le bouton «Voyages» et dans le panneau Interactions (sur la droite), sélectionnez <code>Add Interaction</code>.</li><li>Dans la liste déroulante <code>Choose state</code>, sélectionnez voyages.</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img10.jpg" border="0" alt="" /></div><ul><li>Répétez ces opérations pour les boutons Opérateurs et XKE.</li><li>Allez dans <code>File</code> => <code>Run Project</code> pour tester la navigation.</li></ul><p>Passons à la création de la scrollBar verticale ainsi que de son association avec une liste déroulante :</p><ul><li>Sélectionnez les éléments graphiques qui vont composer la scrollBar.</li><li>Une fenêtre est apparue (<code>Convert to Artwork</code>), sélectionnez <code>Vertical scrollBar</code> dans la liste. Ne tenez pas compte du message Component Issues.</li><li>Cliquez sur <code>Edit Parts</code>, et associez les éléments graphiques aux éléments de la scrollBar.</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img11.jpg" border="0" alt="" /></div><ul><li>Un fois le composant terminé, cliquez sur la racine du projet (nom de votre projet) en haut à gauche.</li><li>Sélectionnez le fond gris clair avec le texte San Francisco et dans la fenêtre <code>Convert Artwork</code>, sélectionnez <code>Data List</code>.</li><li>Cliquez sur <code>Edit Parts</code>, et associez le fond gris ainsi que le texte San Francisco à <code>Repeated Item</code>.</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img12.jpg" border="0" alt="" /></div><ul><li>Ajustez la taille de la <code>Data List</code> à celle de la scrollBar.</li><li>Dans la fenêtre du bas, cliquez sur l&#8217;onglet <code>Design-Time Data</code>.</li><li>Ajouter des données en cliquant sur <code>Add Row</code>.</li></ul><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/Img13.jpg" border="0" alt="" /></div><ul><li>Couper la scrollBar, double cliquez sur la <code>Data List</code> et coller la scrollBar dedans (l&#8217;association avec la liste est effectuée à ce moment).</li><li>Allez dans <code>File</code> => <code>Run Project</code> pour tester l&#8217;application.</li></ul><h3><a
name="Analyses"></a>Analyses</h3><p>A travers la mise en place de cette première partie, nous pouvons effectuer les constats suivants:</p><ul><li>La maîtrise des outils Photoshop et Illustrator est indispensable : créer ses composants graphiques, appliquer des effets nécessitent un travail non négligeable.</li><li>Pour un développeur n&#8217;ayant pas de connaissances graphiques, la courbe d&#8217;apprentissage peut être assez longue.</li><li>Lors de la mise en place de l&#8217;image, il faut anticiper les transitions et effets car l&#8217;arborescence des composants est importante pour Catalyst.</li><li>L&#8217;outil Catalyst possède de bonnes interactions avec Photoshop et Illustrator:</li><ul><li>l&#8217;import d&#8217;images Photoshop est bien reconnu</li><li>possibilité de modifier et d&#8217;améliorer ses composants à partir de Catalyst dans Illustrator.</li></ul><li>Catalyst permet de créer des états, transitions assez rapidement et facilement</li><li>La création de certains composants n&#8217;est pas forcément très intuitive : création d&#8217;un composant Button et suppression des «boutons» créés dans Photoshop&#8230;</li></ul><p>Vous pouvez télécharger l&#8217;image et le projet Catalyst sur le <a
href="http://code.google.com/p/xebia-france/source/browse/#svn/trunk/flex" title="SVN de Xebia France" >SVN de Xebia France</a></p><div
class="shr-publisher-4320"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F04%2F07%2Fflash-catalyst-flash-builder-lavis-de-xebia%2F' data-shr_title='Flash+Catalyst%2C+Flash+Builder%2C+l%27avis+de+Xebia+%21'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F04%2F07%2Fflash-catalyst-flash-builder-lavis-de-xebia%2F' data-shr_title='Flash+Catalyst%2C+Flash+Builder%2C+l%27avis+de+Xebia+%21'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/04/07/flash-catalyst-flash-builder-lavis-de-xebia/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>HTML5 &#8211; Les API JavaScript</title><link>http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/</link> <comments>http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#comments</comments> <pubDate>Thu, 18 Mar 2010 09:32:05 +0000</pubDate> <dc:creator>Séven Le Mesle</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Apple]]></category> <category><![CDATA[Chrome]]></category> <category><![CDATA[Firefox]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Mozilla]]></category> <category><![CDATA[Safari]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=4225</guid> <description><![CDATA[C&#8217;est le moment de passer à la deuxième partie de cette série sur HTML5, avec en ligne de mire les nouveautés côté JavaScript. La spécification a pris le parti de mettre JavaScript en avant, avec des API standards qui pourront être implémentées dans tous les navigateurs. L&#8217;un des buts de la spécification est de faire [...]]]></description> <content:encoded><![CDATA[<p>C&#8217;est le moment de passer à la deuxième partie de cette série sur HTML5, avec en ligne de mire les nouveautés côté JavaScript. La spécification a pris le parti de mettre JavaScript en avant, avec des API standards qui pourront être implémentées dans tous les navigateurs. L&#8217;un des buts de la spécification est de faire monter HTML et JavaScript à un niveau de finition et de performance égalant les applications de bureau. Côté performance, il y a le parallélisme et quelques fonctions natives qui viendront remplacer des fonctions déjà implémentées par les frameworks JavaScript. Mais HTML5 fait aussi écho à l&#8217;explosion du Web mobile avec la géolocalisation et les applications hors ligne pour ceux qui ne sont pas connectés en permanence.</p><h3> Sommaire</h3><ul><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#SlecteursCSS">Sélecteurs CSS</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#Timers">Timers</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#WorkersetMessaging">Workers et Messaging</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#WebStorage">Web Storage</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#OfflineWebApplication">Offline Web Application</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#Geolocation">Geolocation</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#WebSocket">WebSocket</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#WebSQLDatabase">Web SQL Database</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#Dragndrop">Drag&#8217;n'drop</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#ContentEditable">ContentEditable</a></li><li><a
href="http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/#Conclusion">Conclusion</a></li></ul><h3><a
name="SlecteursCSS"></a>Sélecteurs CSS</h3><p>Habituellement utilisés pour appliquer des styles aux éléments HTML, les sélecteurs sont aussi utilisés en JavaScript pour retrouver facilement un ou plusieurs éléments. <code>#loginForm fieldset</code> permet de récupérer le ou les <code>fieldset</code> contenu dans l&#8217;élément dont l&#8217;<code>id</code> est <code>loginForm</code>. Tous les frameworks JavaScripts proposent leurs propre implémentation des sélecteurs CSS. Mais vous pouvez dès aujourd&#8217;hui migrer vers <code>document.querySelector()</code> qui fonctionne nativement sur tous les navigateurs récents  et supporte la norme CSS3.</p><p><code>document.querySelector()</code> retourne le premier élément trouvé correspondant au sélecteur, et <code>document.querySelectorAll()</code> va nous retourner la collection complète. Le gros avantage est la rapidité d&#8217;exécution fournie par le navigateur qui bat à plate couture tous les équivalents en framework JS.</p><div
align="center"><a
href="http://blog.xebia.fr/wp-content/uploads/2010/03/CaptureSlickSpeed.png"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/03/CaptureSlickSpeed.png" alt="CaptureSlickSpeed" title="CaptureSlickSpeed" width="600" height="590" class="aligncenter size-full wp-image-4230" /></a></div><p>Constatez par vous même en lançant <a
href="http://www2.webkit.org/perf/slickspeed" title="Slick Speed" >Slick Speed</a> dans votre navigateur.</p><p><a
href="http://www.w3.org/TR/selectors-api/">http://www.w3.org/TR/selectors-api</a></p><h3><a
name="Timers"></a>Timers</h3><p>Comme leur nom l&#8217;indique, les Timers permettent de planifier dans le temps des exécutions de callbacks avec ou sans répétition. La fonctionnalité n&#8217;est pas franchement nouvelle, mais elle trouve bonne place dans la recommandation du W3C. L&#8217;API propose deux fonctions pour créer les timers:</p><ul><li><code>setTimeout(handler, ms, [args ...])</code> &#8211; Enregistre un <code>handler</code> pour être exécuté dans <code>ms</code> millisecondes en lui passant les arguments <code>args</code>.</li><li><code>setInterval(handler, ms, [args ...])</code> &#8211; Enregistre un <code>handler</code> pour être exécuté toutes les <code>ms</code> millisecondes.</li></ul><p>Toutes deux retournent un pointeur qui pourra être utilisé plus tard pour supprimer le timer à l&#8217;aide de <code>clearTimeout()</code> et <code>clearInterval()</code>. Les timers sont assez pratiques pour rafraîchir le contenu de la page sans la recharger totalement. Ils sont maintenant aussi beaucoup utilisés pour animer le <code>canvas</code>. L&#8217;API intégrée depuis longtemps par les frameworks JavaScript est supportée par tous les navigateurs d&#8217;aujourd&#8217;hui et d&#8217;hier.</p><p><a
href="http://dev.w3.org/html5/spec-author-view/timers.html">http://dev.w3.org/html5/spec-author-view/timers.html</a></p><h3><a
name="WorkersetMessaging"></a>Workers et Messaging</h3><p>Les Workers sont des tâches de fond qui vont s&#8217;exécuter en parallèle du programme JavaScript principal. Pour assurer la sécurité, ils tournent dans un environnement totalement séparé de la page et n&#8217;ont aucun accès direct sur cette dernière. C&#8217;est via la nouvelle API de Messaging que les workers vont pouvoir communiquer avec le programme principal. Chacun des threads peut envoyer un message via la méthode <code>postMessage(...)</code> et le recevoir en enregistrant un handler pour l&#8217;évènement <code>onMessage</code>.</p><p>Créons, d&#8217;abord, un nouveau <code>Worker</code> en lui fournissant l&#8217;url du script à exécuter :</p><pre class="brush: jscript; title: ; notranslate">
var w = new Worker('prime.js');
// Ecrire le nombre premier trouvé dans la page sur message du worker
w.onMessage  = function (evt){
    document.getElementById('prime').textContent = event.data;
};
// Lancer le worker
document.getElementById('startTimerButton').onClick = function (evt) {
   w.postMessage('start');
}
// Stoper le worker
document.getElementById('stopTimerButton').onClick = function (evt) {
   w.postMessage('stop');
}
</pre><p>Voyons maintenant le code du <code>Worker</code> :</p><pre class="brush: jscript; title: ; notranslate">
var running = false;
var timer;
var n = 1;
// Traiter le message de la page
onmessage = function (event) {
  if (event.data == 'start' &amp;&amp; !running) {
    running = true;
    n = 1;
    timer = setInterval(run, 50);
  } else if (event.data == 'stop' &amp;&amp; running) {
    running = false;
    clearInterval(timer);
  }
};
// Rechercher un nombre premier
function run() {
  var isAPrime = false;
  while (!isAPrime) {
    isAPrime = true;
    n += 1;
    for (var i = 2; i &lt;= Math.sqrt(n); i += 1){
      if (n % i == 0){
        isAPrime = false;
        break;
      }
    }
  }
  // found a prime!
  postMessage(n);
}
</pre><p>Le code est assez simple. Sur message <code>'start'</code> de la page, il créé un Timer qui exécutera la fonction <code>run</code> toutes les 50ms. Si le message reçu est <code>'stop'</code>, il coupe le Timer ce qui arrêtera la recherche au prochain nombre premier trouvé.<br
/> Attention, le message contenu dans <code>event.data</code> ne peut contenir que du texte. Pour supporter des messages plus complexes, il faudra passer par des chaînes JSON.</p><p>Les Workers peuvent créer d&#8217;autres Workers sans limite, et importer d&#8217;autres scripts via la fonction <code>importScript(url)</code>. Les traitements lourds ne sont plus réservés aux applications de bureaux. L&#8217;API est supportée par Chrome, Safari, et Firefox. Il faut encore reposer sur Gears pour pouvoir en bénéficier sur IE et Opéra a planifié l&#8217;API pour sa prochaine version.</p><p>L&#8217;API de Messaging est aussi utilisée pour d&#8217;autres fonctionnalités comme la communication entre la page et son iFrame quelque soit le domaine d&#8217;origine. La page enregistre un handler <code>window.onMessage</code> et peut appeler le <code>postMessage()</code> pour communiquer. Ainsi, même deux <code>iframe</code> de la même page peuvent communiquer entre elles. Vous pouvez tester cette <a
href="http://achau.appspot.com/demo/html5/crossdoc/index.html" title="dmonstration" >démonstration</a> pour avoir un aperçu de la communication cross-domain. Cette API est disponible pour tous, à partir d&#8217;IE 8 <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .</p><p><a
href="http://dev.w3.org/html5/workers/">http://dev.w3.org/html5/workers</a></p><h3><a
name="WebStorage"></a>Web Storage</h3><p>Cette nouvelle API fournit deux types de stockage de données dans le navigateur :</p><ul><li>Le <code>sessionStorage</code> est une base JSON partagée, pour la durée de la session, entre toutes les pages d&#8217;une même fenêtre.</li><li>Le <code>localStorage</code> stocke aussi des objets JSON, maintenus localement d&#8217;une session à l&#8217;autre et partagés pour toutes les pages d&#8217;une même origine.</li></ul><p>Ces deux nouveaux objets implémentent l&#8217;interface <code>Storage</code> qui fournit les méthodes :</p><ul><li><code>getItem(key)</code>, <code>setItem(key)</code>, <code>removeItem(key)</code>, permettent de gérer les objets du tableau.</li><li><code>key(index)</code> et <code>length</code> fournissent la longueur du tableau et la clé de l&#8217;objet stocké à un certain indice.</li><li><code>clear()</code> vide entièrement le tableau.</li></ul><p>Mais vous pouvez aussi bien les utiliser comme de simples objets JavaScript :</p><pre class="brush: jscript; title: ; notranslate">
if (!localStorage.drafts){
  localStorage.drafts = [];
}else {
  // Afficher les drafts stockés
}
</pre><p>Dans une application disponible hors ligne, les modifications pourront être enregistrées dans le <code>localStorage</code>, pour être synchronisées plus tard quand le navigateur repassera en ligne. En REST, l&#8217;état pourra être stocké du côté navigateur dans le <code>sessionStorage</code>. Un autre exemple d&#8217;utilisation peut être l&#8217;enregistrement des préférences utilisateur thème et personnalisation. Déjà disponible dans Firefox, Chrome, Safari et IE 8, le WebStorage sera supporté partout à la sortie d&#8217;Opera 10.50.</p><p><a
href="http://dev.w3.org/html5/webstorage/">http://dev.w3.org/html5/webstorage</a></p><h3><a
name="OfflineWebApplication"></a>Offline Web Application</h3><p>L&#8217;idée est de fournir des applications qui peuvent fonctionner sans connexion à internet. La solution repose sur une gestion fine de la mise en cache des ressources et la mise à disposition d&#8217;un événement notifiant le changement d&#8217;état de la connexion <code>online</code>/<code>offline</code>. On pourra aussi utiliser WebStorage pour enregistrer, hors ligne, les nouveaux mails à envoyer plus tard quand la connexion sera de nouveau disponible.</p><p>La gestion du cache se fait via un fichier <code>MANIFEST</code> qui liste les règles de mises en cache.</p><pre class="brush: java; title: ; notranslate">
CACHE MANIFEST
index.html
style/default.css
images/logo.png
images/backgound.png
NETWORK:
server.cgi
FALLBACK:
online/images offline/images
</pre><p>Le fichier manifest contient plusieurs sections :</p><ul><li><code>CACHE</code> liste les url des fichiers à conserver dans le cache, c&#8217;est la section par défaut.</li><li><code>NETWORK</code> permet de lister les urls qui ne doivent pas être conservées dans le cache.</li><li><code>FALLBACK</code> liste des pairs d&#8217;urls. Si la première ne répond pas la seconde sera utilisée.</li></ul><p>Pour le déclarer, il suffit ensuite de l&#8217;ajouter dans la balise <code>html</code> des pages.</p><pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE HTML&gt;
&lt;html manifest=&quot;demo.manifest&quot;&gt;
</pre><p>Attention, le fichier demo.manifest doit être servi avec le type mime <code>text/cache-manifest</code>, pour garantir son traitement par le navigateur. Au premier accès à la page, le navigateur va télécharger et stocker les ressources dans le cache, éventuellement en notifiant l&#8217;utilisateur. Au prochain accès, le navigateur vérifiera la version du fichier manifest sur le serveur, et téléchargera la mise à jour, ou affichera directement la page du cache.</p><p>Les scripts peuvent suivre le chargement et forcer le passage d&#8217;une version du cache à une autre.</p><pre class="brush: jscript; title: ; notranslate">
var cache = window.applicationCache;
// Mise à jour du cache
cache.update();
// Passage au nouveau cache et invalidation de l'ancien sur updateReady
cache.swapCache();
</pre><p>L&#8217;objet <code>ApplicationCache</code> fournit en plus des deux méthodes, un status indiquant son état en cours et quelques événements permettant de suivre les changements d&#8217;état du cache.</p><p>Nous avons donc, de quoi conserver les pages d&#8217;une application pour pouvoir les afficher hors ligne, avec une solution pour fournir un contenu alternatif lorsque le navigateur n&#8217;est pas connecté. Bien sûr, il faut aussi prévoir un traitement alternatif en JavaScript lorsque le navigateur est hors ligne. L&#8217;objet <code>window</code> hérite donc d&#8217;une propriété booléenne <code>online</code>, accompagnée des événements <code>online</code> et <code>offline</code>.</p><p>Les applications hors ligne sont utilisables, dès aujourd&#8217;hui, sur Safari, Firefox, Chrome et Internet Explorer via gears. Attention tout de même, l&#8217;implémentation fournie par gears diffère un peu de la spécification.</p><p><a
href="http://www.w3.org/TR/html5/offline.html">http://www.w3.org/TR/html5/offline.html</a></p><h3><a
name="Geolocation"></a>Geolocation</h3><p>La Géo-localisation, ou Geolocation en anglais est une nouvelle API qui permet de récupérer auprès de l&#8217;objet <code>navigator</code>, les coordonnées complètes de l&#8217;utilisateur (longitude, latitude, et altitude). C&#8217;est comme ça que fonctionne le bouton &laquo;&nbsp;Where am I&nbsp;&raquo; de google maps sur l&#8217;iPhone par exemple. La spécification va un peu plus loin en permettant de faire un suivi de la position courante, de connaitre la vitesse et de retrouver la dernière position connue en cas d&#8217;indisponibilité.</p><p>Voici, un petit exemple issu de la spécification :</p><pre class="brush: jscript; title: ; notranslate">
 function showMap(position) {
      // Show a map centered at (position.coords.latitude, position.coords.longitude).
 }
    // One-shot position request.
 navigator.geolocation.getCurrentPosition(showMap);
</pre><p>Pour plus de détail sur l&#8217;API proprement dite, je vous invite à lire la <a
href="http://dev.w3.org/geo/api/spec-source.html" title="spcification" >spécification</a> qui montre des exemples de code facilement compréhensibles. Bien qu&#8217;expérimentale dans Internet Explorer, la fonctionnalité est disponible dans tous les navigateurs récents. Là encore, attention, Chrome vient d&#8217;intégrer l&#8217;implémentation HTML5 de la géo-localisation qui remplace celle de Gears. Si le système fonctionne très bien sur les mobiles grâce au GPS et au triangulation GSM, il s&#8217;avère assez hasardeux dès qu&#8217;il repose sur la géolocalisation par adresse IP.</p><p><a
href="http://dev.w3.org/geo/api/spec-source.html">http://dev.w3.org/geo/api/spec-source.html</a></p><h3><a
name="WebSocket"></a>WebSocket</h3><p>Avec les <code>server-event</code>, les WebSockets permettent d&#8217;établir une communication bi-directionnelle asynchrone entre le navigateur et le serveur, l&#8217;idée est de supporter le push server. En fournissant une API native qui ne nécessite pas de &laquo;&nbsp;bidouille&nbsp;&raquo; à base de requêtes Ajax ou d&#8217;<code>iframe</code> pour gérer les notifications du serveur. Les <code>WebSocket</code> tentent donc de fournir un cadre standard pour les applications <a
href="http://en.wikipedia.org/wiki/Comet_(programming)" title="Comet" >Comet</a>.</p><p>Les WebSocket fournissent deux méthodes :</p><ul><li><code>send( data_string)</code> pour envoyer un message au serveur.</li><li><code>close()</code> pour fermer la socket.</li></ul><p>Les messages envoyés par le serveur sont notifiés par l&#8217;événement <code>onmessage</code> contenant le message du serveur sous forme de chaîne. Les événements <code>onerror</code>, <code>onopen</code> et <code>onclose</code> permettent de suivre en temps réel l&#8217;état de la connexion. Côté protocole, la spécification est développée conjointement avec un draft déposé par Google à l&#8217;IETF. Le <a
href="http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75" title="protocole WebSocket" >protocole WebSocket</a> imaginé par <a
href="http://en.wikipedia.org/wiki/Ian_Hickson" title="Ian Hickson" >Ian Hickson</a> permet de valider l&#8217;origine des messages pour la sécurité et évite les lourdeurs de HTTP. Il est donc compatible avec le modèle de sécurité standard des navigateurs, et autorise même l&#8217;utilisation de proxy. Le protocole WebSocket est à considérer comme un protocole de transport qui va pouvoir être utilisé, pour encapsuler d&#8217;autres protocoles. Nous connaissons déjà l&#8217;exemple de Jabber qui est utilisé par Google Talk, mais il devient aussi possible de transporter des messages JMS ou AMQP. Ce type de connexion a des chances de venir concurrencer sérieusement les solutions fournies par Flash.</p><p>Par contre, la spécification est encore jeune et ne bénéficie pas pour le moment d&#8217;un large support parmi les navigateurs. Seul Chrome a terminé son implémentation depuis quelques semaines, Safari devrait suivre bientôt. A priori du côté de Firefox, le travail est déjà bien avancé puisque le bug est en cours de traitement depuis près d&#8217;un an. Il y a fort à parier que la prochaine version majeure du renard brûlant supportera les WebSockets. Pour ce qui est d&#8217;Opera et d&#8217;Internet Explorer aujourd&#8217;hui rien n&#8217;est fait mais je ne sais pas ce que l&#8217;avenir nous réserve.</p><p>Outre le navigateur, les WebSockets posent aussi un problème d&#8217;infrastructure puisqu&#8217;il ne s&#8217;agit plus de fournir seulement un serveur HTTP mais en plus un serveur web socket. Il existe déjà quelques solutions serveur telles que <a
href="http://kaazing.com/download" title="Kaazing gateway" >Kaazing gateway</a> et <a
href="http://jetty.codehaus.org/jetty/" title="Jetty" >Jetty</a> qui supportent des <code>WebSocketServlet</code>. Mais l&#8217;offre est encore très réduite et expérimentale, il faudra attendre encore quelque temps avant de pouvoir bénéficier de serveurs web socket éprouvés.</p><p><a
href="http://dev.w3.org/html5/websockets/" title="httpdevw3orghtml5websockets" >http://dev.w3.org/html5/websockets/</a></p><h3><a
name="WebSQLDatabase"></a>Web SQL Database</h3><p>Apple et Google ont décidé d&#8217;aller plus loin que le simple stockage NoSQL du navigateur en proposant une véritable base de données SQL embarquée dans le navigateur. Une fois de plus, c&#8217;est l&#8217;évangéliste HTML5 Ian Hickson qui rédige la spécification pour le W3C. Web SQL Database fonctionne de la même façon que le <code>localStorage</code> à la différence près qu&#8217;il s&#8217;agit bel et bien d&#8217;une base SQL stockée elle aussi par origine (nom de domaine racine). Comme d&#8217;habitude en JavaScript, l&#8217;API fonctionne en asynchrone grâce à l&#8217;utilisation de fonction callback. Elle permet d&#8217;ouvrir ou de créer une base avec un numéro de version pour gérer les évolutions du modèle. Une fois la base ouverte, il est possible d&#8217;exécuter des requêtes SQL avec paramètres au sein d&#8217;une transaction. La fonction de callback reçoit l&#8217;objet <code>SQLResultSet</code> qui contient les données lues en base ou les informations liées à l&#8217;insertion où la mise à jour des tuples en base de données.</p><pre class="brush: jscript; title: ; notranslate">
// ouverture de la base  et création si besoin
window.openDatabase('documents', '1.0', 'Offline document storage', 5*1024*1024, function (db) {
    db.changeVersion('', '1.0', function (t) {
      t.executeSql('CREATE TABLE docids (id, name)');
    }, error);
});
var span = document.getElementById('docCountSpan');
// Lecture du nombre de document en base
db.readTransaction(function (t) {
    t.executeSql('SELECT COUNT(*) AS c FROM docids', [], function (t, r) {
      span.textContent = r.rows[0].c;
    }, function (t, e) {
      // couldn't read database
      span.textContent = '(unknown: ' + e.message + ')';
    });
  });
</pre><p>Il existe maintenant aussi des méthodes synchrones pour accéder à la base qui peuvent être utilisées sans risque dans un <code>Worker</code>. Si les appels sont réalisés directement dans la page, utilisez toujours les méthodes asynchrones pour éviter les effets de bords type navigateur figé toujours désagréables.</p><p>Cette spécification, bien que prometteuse, n&#8217;est pas considérée comme stable. Le problème vient du langage SQL soutenu par la spécification qui n&#8217;est pour le moment qu&#8217;une redirection vers la documentation SQLite. L&#8217;API est donc figée en attente d&#8217;un navigateur qui utilisera un autre backend de base de données. Pour l&#8217;instant, tout le monde utilise SQLite, que ce soit avec Gears pour Firefox et Internet Explorer ou en natif dans Chrome, Opera et Safari.</p><p><a
href="http://dev.w3.org/html5/webdatabase/">http://dev.w3.org/html5/webdatabase/</a></p><h3><a
name="Dragndrop"></a>Drag&#8217;n'drop</h3><p>L&#8217;API cette fois vient d&#8217;Internet Explorer puisqu&#8217;elle existe depuis IE 6. Elle permet de définir un élément pour recevoir les objets déposés par l&#8217;utilisateur via l&#8217;événement <code>ondrop</code>, et de suivre l&#8217;objet glissé par l&#8217;utilisateur sur la page où le receveur d&#8217;objet déposé via six événements (<code>dragstart</code>, <code>drag</code>, <code>dragend</code>, <code>dragenter</code>, <code>dragover</code>, <code>dragleave</code>). L&#8217;idée offre des perspectives sympathiques:</p><ul><li>Gérer l&#8217;upload de fichier par glisser-déposer.</li><li>Récupérer proprement le texte glissé.</li><li>Supporter nativement le drag and drop des éléments de la page.</li></ul><p>C&#8217;est sur ce dernier point que la spécification apporte une réelle nouveauté avec l&#8217;attribut <code>dragable</code> qui peut-être positionné directement sur les balises de la page. Malheureusement seul Firefox supporte ce nouvel attribut. Pour le reste, les auteurs se sont contentés de recopier l&#8217;API Microsoft comme l&#8217;ont fait tous les navigateurs. Seul Opera résiste encore à cette API lourdement critiqué à travers la blogo-sphère. Il y a d&#8217;abord trop d&#8217;événements impliqués dans le simple glissé-déposé, mais ils sont en plus dépendants les uns des autres. Par exemple, pour espérer recevoir <code>ondrop</code> sur un élément HTML, il faudra recevoir et annuler l&#8217;événement <code>dragover</code>.</p><p><a
href="http://dev.w3.org/html5/spec-author-view/dnd.html">http://dev.w3.org/html5/spec-author-view/dnd.html</a></p><h3><a
name="ContentEditable"></a>ContentEditable</h3><p>Pour cette dernière étape de notre tour d&#8217;horizon des API JavaScript, j&#8217;ai décidé de vous parler de l&#8217;attribut <code>contenteditable</code>. Cet attribut active l&#8217;édition en ligne du contenu de l&#8217;élément. Il s&#8217;agit d&#8217;un éditeur WYSIWYG basique qui permet donc d&#8217;éditer directement le contenu de la page. Plus besoin de remplacer à la volée le texte par un <code>input</code> ou une <code>textarea</code>, il suffit de positionner l&#8217;attribut <code>contenteditable</code> sur la balise voulue. C&#8217;est ensuite au tour de l&#8217;attribut <code>designmode</code> de rentrer en jeu : placé à <code>on</code> le contenu de l&#8217;élément devient éditable. Toutes les modifications apportées par l&#8217;utilisateur pourront être traitées à la fin de l&#8217;édition.<br
/> Le tout est servi avec une API permettant d&#8217;autoriser et d&#8217;exécuter des <code>command</code> sur le texte en cours d&#8217;édition. Les commandes vont de passer le texte en italique à insérer une image ou créer une liste. Bref, si la spécification n&#8217;est pas encore complète, elle a l&#8217;ambition de fournir une API d&#8217;édition de texte riche pour tous les navigateurs HTML5. La bonne nouvelle de ce côté étant que les navigateurs principaux sont tous de la partie. Surtout Internet Explorer qui supporte l&#8217;édition en ligne depuis sa version 5.5 et a très largement inspiré cette fonctionnalité.</p><p>Pour plus d&#8217;information sur le sujet, vous pouvez jeter un œil à la <a
href="http://www.w3.org/TR/html5/editing.html" title="spécification du W3C" >spécification du W3C</a> ou lire cet <a
href="http://blog.whatwg.org/the-road-to-html-5-contenteditable" title="article dintroduction" >article d&#8217;introduction</a> en anglais sur le blog du WHATWG.</p><h3><a
name="Conclusion"></a>Conclusion</h3><p>Dans l&#8217;ensemble, les API JavaScript spécifiées dans HTML5 sont convaincantes et plutôt bien supportées par les navigateurs. Bien sûr Internet Explorer est à la traine mais les rumeurs vont bon train sur la roadmap d&#8217;IE 9. A l&#8217;occasion du <a
href="http://live.visitmix.com/" title="MIX 2010" >MIX 2010</a>, une conférence Microsoft de trois jours autour du développement web qui se tenait cette semaine, la preview IE9 a été publiée cette semaine. Avec cette pré-version, Microsoft confirme son entrée dans la bataille HTML5 avec : la vidéo, le canvas, une machine JavaScript largement optimisée et 55 points au test ACID CSS3. Même Mike Shaver haut responsable de Firefox félicite cette nouvelle concurrence dans un <a
href="http://twitter.com/shaver/statuses/10576726837" title="Tweet" >Tweet</a>. Plus performant, plus portable et plus puissant, avec HTML5 JavaScript peut gagner ses lettres de noblesses, voire même, convaincre les foules de développeurs réticents. Outre l&#8217;intérêt maintenant avéré de Microsoft pour la spécification, HTML5 manque cruellement d&#8217;outils pour pouvoir concurrencer Flex. Amis éditeurs à votre bon cœur.</p><ul><li><a
href="http://html5demos.com/" title="HTML5 Demos and Examples" >HTML5 Demos and Examples</a></li><li><a
href="http://a.deveria.com/caniuse/" title="Table de compatibilit des navigateurs HTML5 CSS3 SVG" >Table de compatibilité des navigateurs HTML5, CSS3, SVG</a></li><li><a
href="http://dev.w3.org/html5/spec/Overview.html" title="Draft HTML5 du W3C" >Draft HTML5 du W3C</a></li></ul><div
class="shr-publisher-4225"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F03%2F18%2Fhtml5-les-api-javascript%2F' data-shr_title='HTML5+-+Les+API+JavaScript'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F03%2F18%2Fhtml5-les-api-javascript%2F' data-shr_title='HTML5+-+Les+API+JavaScript'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/03/18/html5-les-api-javascript/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>HTML5 &#8211; Les nouveaux éléments</title><link>http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/</link> <comments>http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#comments</comments> <pubDate>Tue, 02 Mar 2010 13:30:10 +0000</pubDate> <dc:creator>Séven Le Mesle</dc:creator> <category><![CDATA[Mobilité]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[Apple]]></category> <category><![CDATA[Gears]]></category> <category><![CDATA[Google]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=4127</guid> <description><![CDATA[Comme évoqué dans une précédente revue de presse, voici le premier article de ma série sur HTML5. Plutôt que de faire du comptage de points entre Apple et Adobe, j&#8217;ai décidé de commencer par faire un tour d&#8217;horizon des nouveautés proposées par cette nouvelle spécification du W3C. Dans ce premier article, je vous propose donc [...]]]></description> <content:encoded><![CDATA[<p>Comme évoqué dans une précédente revue de presse, voici le premier article de ma série sur HTML5. Plutôt que de faire du comptage de points entre Apple et Adobe, j&#8217;ai décidé de commencer par faire un tour d&#8217;horizon des nouveautés proposées par cette nouvelle spécification du W3C. Dans ce premier article, je vous propose donc de faire un voyage à la découverte des nouveautés du côté de HTML. ; pour connaître les nouvelles balises, et les nouveaux attributs que nous pouvons déjà ou pourrons bientôt utiliser dans nos navigateurs. Du layout au canvas en passant par les WebForms, le son et la vidéo, tout tout tout, je vous dirai tout sur HTML5. Commençons donc par le commencement: HTML5 qu&#8217;est-ce que c&#8217;est ?</p><h3>Sommaire</h3><ul><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#HTML">HTML5 ?</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#Nouveaumodledecontenu">Nouveau modèle de contenu</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#Nouveauxlmentsdemiseenpage">Nouveaux éléments de mise en page</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#Elmentsinteractifs">Eléments interactifs</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#LesWebForms">Les WebForms</a><ul><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#Nouveauxinput">Nouveaux input</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#Validationnative">Validation native</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#Autocompltion">Auto-complétion</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#Rptitions">Répétitions</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/#Etatdeslieux">Etat des lieux</a></li></ul></li><li><a
href="http://blog.xebia.fr/2010/03/02/html5-les-nouveaux-elements/#Multimedia">Multimedia</a><ul><li><a
href="http://blog.xebia.fr/2010/03/02/html5-les-nouveaux-elements/#AudioetVideo">Audio et Video</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html5-les-nouveaux-elements/#LaguerredesCodecs">La guerre des Codecs</a></li><li><a
href="http://blog.xebia.fr/2010/03/02/html5-les-nouveaux-elements/#LeCanvas">Le Canvas</a></li></ul></li><li><a
href="http://blog.xebia.fr/2010/03/02/html5-les-nouveaux-elements/#Conclusion">Conclusion</a></li></ul><h3><a
name="HTML"></a>HTML5 ?</h3><p>HTML5 est au départ la nouvelle version du langage HTML en cours de développement par le W3C. Pour le moment, il s&#8217;agit d&#8217;une recommandation en DRAFT, fruit du travail initial réalisé par le <a
title="WHATWG" href="http://www.whatwg.org">WHATWG</a> depuis 2004. Le <a
title="W3C" href="http://www.w3c.org">W3C</a> espère en faire un de ses standards libres aux alentours de 2022. De prime abord, ça nous laisse le temps de réfléchir au problème pendant les 10 prochaines années. L&#8217;idée d&#8217;une nouvelle version de HTML serait motivée par quelques constats simples :</p><ul><li>Les navigateurs ont besoin de plugins pour gérer le multimédia (flash et consorts)</li><li>La structure des documents n&#8217;est pas intuitive et rend l&#8217;accessibilité difficile</li><li>Les API JavaScript varient trop d&#8217;un navigateur à l&#8217;autre pour garantir la portabilité des documents</li><li>Les sites sont de plus en plus proches des applications de bureaux mais souffrent encore de limitations</li></ul><p>Pour répondre à ces problématiques et favoriser l&#8217;émergence du web sémantique, la spécification propose :</p><ul><li>Un nouveau modèle de contenu des éléments</li><li>Des éléments de mise en page</li><li>De nouveaux éléments pour les formulaires</li><li>Du contenu multimédia</li><li>Plus d&#8217;interactivité</li><li>Des APIs standards JavaScript</li></ul><p>Bien que la spécification soit encore en cours d&#8217;écriture, certaines parties sont déjà très avancées et les navigateurs ont tous commencé à les implémenter. Google Chrome est actuellement en tête. Il bénéficie nativement de Gears et respecte 87% de la spécification. Parmi les principaux supporters de ce standard en devenir, nous retrouvons Google, Mozilla, Opera, Apple et Palm, pour ne citer que les plus grands. Apparemment, les navigateurs qui ont le vent en poupe sont tous de la partie. Microsoft, de son côté, suit la tendance de très loin en intégrant des fonctionnalités au compte goutte dans son IE, qui supporte tout de même 28% du langage.</p><h3><a
name="Nouveaumodledecontenu"></a>Nouveau modèle de contenu</h3><p>Bye, bye, les alignements hasardeux dus aux éléments de type bloc ou en ligne. Les éléments seront plutôt classés par catégories.</p><div><a
href="http://blog.xebia.fr/wp-content/uploads/2010/03/contenthtml5.png"><img
class="aligncenter size-full wp-image-4135" title="contenthtml5" src="http://blog.xebia.fr/wp-content/uploads/2010/03/contenthtml5.png" alt="contenthtml5" width="520" height="284" /></a></div><ul><li>La catégorie ancêtre <code>Flow</code> correspond à tous les éléments qui contiennent un flot de texte</li><li><code>Phrasing</code> correspond aux éléments qui apparaissent dans le texte (a, li)</li><li><code>Interactive</code> définit les éléments qui fournissent une interaction avec l&#8217;utilisateur</li><li><code>Embedded</code> affiche des ressource externes dans le document</li><li>Les <code>Metadata</code> représentent tout ce qui n&#8217;est pas affiché (style, script, &#8230;)</li><li><code>Heading</code> définit les en-têtes d&#8217;une section</li><li><code>Sectioning</code> définit le scope des en-têtes et pieds de page</li></ul><p>Toutes ces catégories permettent de définir le contenu autorisé pour les éléments. Leur but est d&#8217;une part de fournir une grande souplesse de composition (par exemple la balise <code>a</code> peut maintenant contenir un paragraphe entier, une liste ou des headers (<code>h*</code>)), d&#8217;autre part ces catégories permettent aux navigateurs d&#8217;assimiler le contenu de la page, notamment pour les exports d&#8217;impression ou l&#8217;accessibilité.</p><h3><a
name="Nouveauxlmentsdemiseenpage"></a>Nouveaux éléments de mise en page</h3><p>Jusqu&#8217;à maintenant, l&#8217;élément de mise en page par excellence était la balise <code>div</code>. La grande majorité des sites est construite sur un modèle d&#8217;empilement de ces boites avec des <code>id</code> différents pour finir par une grosse partie de styles <code>CSS</code> assurant le positionnement. Mais cela a quelques inconvénients:</p><ul><li>Ce n&#8217;est pas intuitif pour le développeur, vous en conviendrez.</li><li>Le navigateur ne peut pas connaître le rôle de chacune des parties de la mise en page, ce qui rend beaucoup plus difficile la génération de plan ou d&#8217;aide à la navigation.</li></ul><div><table
border="0"><tbody><tr><td><a
href="http://blog.xebia.fr/wp-content/uploads/2010/03/layoutHTML4.png"><img
title="layoutHTML4" src="http://blog.xebia.fr/wp-content/uploads/2010/03/layoutHTML4.png" alt="layoutHTML4" width="351" /></a></td><td><a
href="http://blog.xebia.fr/wp-content/uploads/2010/03/layoutHTML5.png"><img
title="layoutHTML5" src="http://blog.xebia.fr/wp-content/uploads/2010/03/layoutHTML5.png" alt="layoutHTML5" width="351" /></a></td></tr></tbody></table></div><p>Les balises <code>article</code>, <code>section</code>, <code>header</code> et <code>footer</code> indiquent clairement à quel type de texte elles correspondent et comment s&#8217;organise leur contenu. La balise <code>aside</code> définit un contenu lié au sujet principal, sans en faire partie pour autant. Reste le tag <code>nav</code> qui est prévu pour servir les liens de navigations de la page comme un menu par exemple. La mise en page proposée ci-dessus ne révèle pas la flexibilité d&#8217;utilisation de ces éléments. Notez bien que les <code>article</code> et <code>section</code> peuvent avoir leur propre <code>header</code> et <code>footer</code>.</p><p>Avec ces nouvelles balises, nous serons enfin capables de gérer l&#8217;organisation de nos documents de façon intuitive et les navigateurs pourront générer le plan des documents eux-mêmes. L&#8217;algorithme nécessaire est d&#8217;ailleurs décrit dans la spécification. Tous ces éléments sont déjà supportés nativement par les navigateurs avec l&#8217;exception habituelle de IE pour lequel il existe un <a
title="workaround JavaScript" href="http://code.google.com/p/html5shiv/">workaround JavaScript</a>. Vous pouvez dès maintenant vous familiariser avec ces nouvelles balises sans avoir peur des problèmes de compatibilité.</p><h3><a
name="Elmentsinteractifs"></a>Eléments interactifs</h3><p>Sous ce terme limpide se cachent les éléments qui fournissent de l&#8217;interaction utilisateur dans la page. Ce qui correspond aux <a
title="Interactive elements" href="http://dev.w3.org/html5/spec/interactive-elements.html">Interactive elements</a> de la spécification. La grosse nouveauté ici est la définition d&#8217;une balise <code>menu</code> permettant de construire des barres de menu (<code>type="toolbar"</code>), des menus contextuels (<code>type="context"</code>) ou de simples listes de commandes. Un tag <code>menu</code> peut contenir des sous-menus et se compose d&#8217;éléments permettant de lancer des commandes.</p><pre class="brush: xml; title: ; notranslate">
&lt;menu type=&quot;toolbar&quot;&gt;
 &lt;li&gt;
  &lt;menu label=&quot;File&quot;&gt;
   &lt;button type=&quot;button&quot; onclick=&quot;fnew()&quot;&gt;New...&lt;/button&gt;
   &lt;button type=&quot;button&quot; onclick=&quot;fopen()&quot;&gt;Open...&lt;/button&gt;
   &lt;button type=&quot;button&quot; onclick=&quot;fsave()&quot;&gt;Save&lt;/button&gt;
  &lt;/menu&gt;
 &lt;/li&gt;
 &lt;li&gt;
  &lt;menu label=&quot;Edit&quot;&gt;
   &lt;button type=&quot;button&quot; onclick=&quot;ecopy()&quot;&gt;Copy&lt;/button&gt;
   &lt;button type=&quot;button&quot; onclick=&quot;epaste()&quot;&gt;Paste&lt;/button&gt;
  &lt;/menu&gt;
 &lt;/li&gt;
&lt;/menu&gt;
</pre><p>Pour les commandes, HTML5 propose directement un élément <code>command</code> qui permet d&#8217;associer un texte ou icône à une exécution JavaScript sur événement <code>onclick="alert('hello world')"</code>. Pour utiliser le menu contextuel, il suffit d&#8217;ajouter l&#8217;attribut <code>contextmenu="menu_id"</code>, sur l&#8217;élément qui doit utiliser le menu.</p><p>L&#8217;autre nouveauté parmi les éléments interactifs est la balise <code>details</code>. Le fonctionnement de ce tag est proche d&#8217;un menu en accordéon, avec une partie de texte toujours affichée et une partie cachée pouvant être rendue visible sur demande de l&#8217;utilisateur. Cela peut être utile, pour cacher des options avancées par exemple.</p><pre class="brush: xml; title: ; notranslate">
&lt;section class=&quot;progress window&quot;&gt;
 &lt;h1&gt;Copying &quot;Really Achieving Your Childhood Dreams&quot;&lt;/h1&gt;
 &lt;details&gt;
  &lt;summary&gt;Copying... &lt;progress max=&quot;375505392&quot; value=&quot;97543282&quot;&gt;&lt;/progress&gt; 25%&lt;/summary&gt;
  &lt;dl&gt;
   &lt;dt&gt;Transfer rate:&lt;/dt&gt; &lt;dd&gt;452KB/s&lt;/dd&gt;
   &lt;dt&gt;Local filename:&lt;/dt&gt; &lt;dd&gt;/home/rpausch/raycd.m4v&lt;/dd&gt;
   &lt;dt&gt;Remote filename:&lt;/dt&gt; &lt;dd&gt;/var/www/lectures/raycd.m4v&lt;/dd&gt;
  &lt;/dl&gt;
 &lt;/details&gt;
&lt;/section&gt;
</pre><p>Ici, le tag <code>details</code> est utilisé pour cacher les informations techniques d&#8217;une copie. Vous noterez au passage l&#8217;utilisation d&#8217;une balise <code>progress</code>, pour afficher une barre d&#8217;avancement.</p><h3><a
name="LesWebForms"></a>Les WebForms</h3><h4><a
name="Nouveauxinput"></a>Nouveaux input</h4><p>Les formulaires aussi profitent de la mise à jour en reprenant en partie <a
title="XForms" href="http://www.w3.org/TR/xforms11/">XForms</a> pour les connaisseurs. Le principe est de fournir des <code>input</code> fortement typés  ainsi qu&#8217;une API JavaScript de validation en plus d&#8217;une interactivité accrue. Parmi les nouveaux types d&#8217;input, il y a :</p><ul><li>Le support des saisies de dates et heure décliné sous plusieurs formes (<code>date</code>, <code>datetime</code>, <code>datetime-local</code>, <code>month</code>, <code>week</code>, <code>time</code>). Nous n&#8217;aurons donc plus besoin des widgets supplémentaires JavaScript pour générer des calendriers.</li><li>La saisie de formats numériques via les <code>number</code> et les <code>range</code> qui pourront prendre la forme d&#8217;un slider vertical ou horizontal</li><li>Différents types de chaînes formatées comme les <code>url</code>, les <code>email</code> et <code>tel</code></li><li>Le selecteur de couleur <code>color</code></li><li>Le champ de recherche <code>search</code></li></ul><p>Les anciens types sont maintenus. Ils bénéficient d&#8217;un bon lifting, tel le type <code>file</code> qui permettra désormais de sélectionner plusieurs fichiers d&#8217;un seul coup, tout en précisant le type mime accepté. Il y a aussi l&#8217;attribut <code>placeHolder</code> qui permet de fournir un texte descriptif affiché dans le champs si il n&#8217;est pas renseigné.</p><h4><a
name="Validationnative"></a>Validation native</h4><p>Tous les <code>input</code> supportent de nouveaux attributs de validation qui permettent de contraindre les saisies de l&#8217;utilisateur, et peuvent interdire la soumission du formulaire, s&#8217;il n&#8217;est pas valide. Encore une fois, cela permettra de remplacer des solutions hétérogènes JavaScript par un standard nativement supporté par le navigateur. La validation s&#8217;accompagne aussi de nouveaux évènements DOM pour notifier les erreurs ou surcharger la validation avec son propre code JavaScript. Plus besoin non plus de jouer avec les classes CSS pour faire ressortir les champs en erreur grâce aux pseudo-formats (<code>:invalid</code>, <code>:valid</code>, <code>:Out-of-range</code>, &#8230;).</p><p>Des validateurs par défaut sont fournis sous la forme de nouveaux attributs à placer sur les <code>input</code> :</p><ul><li><code>required</code> pour un champ requis</li><li><code>min</code> et <code>max</code> permettent de définir une valeur minimum et maximum sur les types numérique et date</li><li><code>pattern</code> fournit une expression régulière que la saisie doit respecter</li></ul><h4><a
name="Autocompltion"></a>Auto-complétion</h4><p>Autre nouveauté inspirée des widgets JavaScript existant, les <code>datalist</code> sont des listes de valeurs construites à l&#8217;aide d&#8217;éléments de type liste (<code>li</code>, <code>option</code>, &#8230;). La <code>datalist</code> est transparente par défaut mais elle peut-être liée à un ou plusieurs <code>input</code> avec l&#8217;attribut <code>list</code>. Une fois l&#8217;association établie avec un <code>input</code>, la liste est utilisée pour fournir des suggestions à la saisie. Les éléments à l&#8217;intérieur de la liste peuvent-être décorés par CSS directement.</p><pre class="brush: xml; title: ; notranslate">
&lt;input type=&quot;text&quot; list=&quot;roles&quot; autofocus /&gt;
&lt;datalist id=&quot;roles&quot;&gt;
   &lt;li&gt;Designer&lt;/li&gt;
   &lt;li&gt;Integrateur&lt;/li&gt;
   &lt;li&gt;Programmeur&lt;/li&gt;
&lt;/datalist&gt;
</pre><h4><a
name="Rptitions"></a>Répétitions</h4><p>Une autre évolution sympathique est la création d&#8217;un système de template, facilitant la création de formulaire dynamique. Dans les applications de gestion, il est souvent utile de pouvoir ajouter et supprimer des lignes de saisie dans le formulaire. Le système de répétition est fait pour ça. Je peux définir un bloc comme étant mon template, et le contenu de cet élément pourra être dupliqué via une API JavaScript.</p><pre class="brush: xml; title: ; notranslate">
&lt;tr id=&quot;order&quot; repeat=&quot;template&quot; repeat-start=&quot;3&quot;&gt;
   &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;row[order].product&quot; value=&quot;&quot;&gt;&lt;/td&gt;
   &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;row[order].quantity&quot; value=&quot;1&quot;&gt;&lt;/td&gt;
   &lt;td&gt;&lt;button type=&quot;remove&quot;&gt;Remove This Row&lt;/button&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;p&gt;&lt;button type=&quot;add&quot; template=&quot;order&quot;&gt;Add Row&lt;/button&gt;&lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;&lt;/p&gt;
</pre><p>C&#8217;est l&#8217;attribut <code>repeat</code> qui définit notre bloc de répétition, le <code>repeat-start</code> permet de gérer les aller-retour serveur, pour afficher la liste avec le nombre d&#8217;éléments précédemment soumis. Pour assurer l&#8217;ajout et la suppression de ligne, j&#8217;ai utilisé les boutons de type <code>add</code> et <code>remove</code> mais j&#8217;aurais aussi bien pu utiliser des méthodes JavaScript de l&#8217;élément template <code>addRepetitionBlock()</code>. Il y a aussi des solutions pour gérer l&#8217;ordre des répétitions permettant de monter et descendre les lignes répétées.</p><h4><a
name="Etatdeslieux"></a>Etat des lieux</h4><p>Voilà la promesse d&#8217;un monde meilleur dans lequel nous aurons moins de travail à fournir (CSS, JS) pour obtenir des résultats simplement meilleurs. Notez une dernière chose, les input peuvent être liés à un ou plusieurs formulaires via le nouvel attribut <code>form</code>. En d&#8217;autres termes, il sera possible de placer nos <code>input</code> pour un formulaire à l&#8217;extérieur de ce dernier.</p><p>Comme vous l&#8217;avez remarqué, j&#8217;ai utilisé le futur dans ce paragraphe car pour le moment seul Opera 9 supporte nativement les WebForms. Pour permettre aux développeurs de s&#8217;y essayer et valider la spécification, le projet <a
title="WebForms2" href="http://code.google.com/p/webforms2/">WebForms2</a> propose une implémentation partielle en JavaScript. La spécification au départ avait été séparée du langage HTML5, mais le W3C a décidé de la ré-intégrer en y apportant des modifications. Du coup la plupart des fonctions développées sont liées à une ancienne version des WebForms.</p><p>Pour les autres navigateurs, notez tout de même que les développements ont déjà commencé. Par exemple Chrome 5 devrait être livré avec le support des nouveaux <code>input</code> et l&#8217;API de validation(<a
title="Chrome Web Platform Status" href="http://www.chromium.org/developers/web-platform-status">Chrome Web Platform Status</a>). Safari bénéficie du même support que chrome qui se limite aux types <code>search</code>, <code>range</code> et <code>file</code> multiple. Du côté de Firefox, les choses sont moins claires ; il existe bien un ensemble de <a
title="bugs" href="https://bugzilla.mozilla.org/showdependencytree.cgi?id=344614&amp;hide_resolved=0">bugs</a> pour le support des WebForms mais Mozilla communique peu sur le sujet. Actuellement, Internet Explorer 8 ne supporte aucune des ces nouveautés et il est impossible de connaître la roadmap de Microsoft sur le sujet. Tout ce que l&#8217;on sait, c&#8217;est que l&#8217;éditeur a décidé de mettre les bouchées doubles pour améliorer son support des travaux du W3C. Peut-être une bonne solution pour inverser la vapeur et en finir avec la descente aux enfers de son précieux navigateur.</p><p><a
title="Page de dmonstration pour Chrome Safari et Opera" href="http://www.miketaylr.com/pres/html5/forms2.html">Page de démonstration pour Chrome, Safari et Opera</a>.</p><h3><a
name="Multimedia"></a>Multimedia</h3><p>Il est temps de parler des nouveaux types de contenu poussés par HTML5. Les auteurs du whatwg se sont probablement demandé pourquoi doit-on installer des plugins dans nos navigateurs ? Nous savons a priori tous aujourd&#8217;hui que Flash est utilisé principalement pour 3 choses dans les applications :</p><ul><li>Pouvoir écouter de la musique</li><li>Pouvoir regarder des vidéos</li><li>Faire des animations de folies</li></ul><p>J&#8217;ai mis volontairement de côté Flex car il cible plutôt les applications d&#8217;entreprise, et les jeux Flash car le Boss ne veut pas en entendre parler <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> . Sachez, si vous êtes passé à côté de ça, que HTML5 adresse ces trois problématiques en sortant trois nouvelles balises de son chapeau :</p><ul><li><code>audio</code> permet de gérer la lecture de fichiers audio en streaming.</li><li><code>video</code> assure la lecture de vidéos en streaming toujours.</li><li><code>canvas</code> permet de dessiner et de faire des animations en JavaScript.</li></ul><h4><a
name="AudioetVideo"></a>Audio et Video</h4><p>Jusqu&#8217;à maintenant, les gros avantages de la technologie d&#8217;Adobe sont la portabilité puisque Flash est disponible pour tous les navigateurs, et la performance en comparaison avec les moteurs JavaScript. Il est clair que ces trois balises viennent marcher sur les plate-bandes de Flash. Les éléments média disposent des attributs :</p><ul><li><code>controls</code> pour activer l&#8217;affichage de l&#8217;interface de contrôle du navigateur</li><li><code>autobuffer</code> pour activer le chargement automatique de la ressource en cache</li><li><code>autoplay</code> pour activer le lancement automatique de la lecture</li><li><code>loop</code> pour lire le ou les médias en boucle</li><li><code>src</code> pour fournir l&#8217;url du fichier média à lire</li></ul><p>La balise <code>source</code> placée à l&#8217;intérieure d&#8217;une balise <code>audio</code> ou <code>video</code> permet aussi de définir l&#8217;url (<code>@src</code>), le type mime et le codec (<code>@type</code>) d&#8217;une ressource média. Il suffit de mettre plusieurs <code>source</code> pour créer une playlist.</p><pre class="brush: xml; title: ; notranslate">
&lt;audio controls autobuffer autoplay loop&gt;
  &lt;source src=&quot;elvis.ogg&quot; /&gt;
  &lt;source src=&quot;elvis.mp3&quot; /&gt;
&lt;/audio&gt;
&lt;video src=&quot;video.ogg&quot; controls&gt;
  &lt;source src='video.mp4' type='video/mp4; codecs=&quot;avc1.42E01E, mp4a.40.2&quot;'&gt;
  &lt;!-- Un texte alternatif pour les anciens navigateurs --&gt;
  Your browser does not support the &lt;code&gt;video&lt;/code&gt; element.
&lt;/video&gt;
</pre><p>Si le navigateurs n&#8217;arrivent pas à lire le fichier ogg, il tentera de lire le fichier H.264. De même, si le navigateur ne supporte pas l&#8217;élément <code>video</code>, il affichera le texte alternatif. Il suffit donc de placer un lecteur Flash à la place du texte pour que la vidéo reste lisible dans un ancien navigateur.</p><p>Si vous ne voulez pas utiliser l&#8217;interface native, ou que vous souhaitez simplement cacher le lecteur audio, vous pouvez utiliser l&#8217;API standard JavaScript pour créer un lecteur, et profiter des méthodes <code>play()</code>, <code>pause()</code>, et <code>load()</code> pour charger la prochaine ressource média. Une dernière méthode : <code>canPlayType(type)</code>, permet de demander au navigateur si il supporte le format vidéo ou audio fournit en paramètre. Cela sera très utile pour gérer les incompatibilités de format.</p><p>De plus l&#8217;interface <code>HTMLMediaElement</code> fournit quantité de propriétés allant du volume à l&#8217;état du buffer en passant par le temps de lecture courant. Le tout est, bien sûr, accompagné d&#8217;une batterie d&#8217;événements qui permettent de suivre l&#8217;avancement du chargement, l&#8217;état du lecteur, et les action lancées par l&#8217;utilisateur.</p><p>Pour plus de détail sur le sujet, je vous invite à lire la <a
title="spécification W3C des éléments média" href="http://www.w3.org/TR/html5/video.html">spécification W3C des éléments média</a> et à tester la démo de <a
title="jPlayer" href="http://www.happyworm.com/jquery/jplayer/latest/demos.htm">jPlayer</a> un lecteur audio pour jQuery.</p><h4><a
name="LaguerredesCodecs"></a>La guerre des Codecs</h4><p>Venons en au problème des codecs. Le W3C se contente de citer un certain nombre de formats allant du H.264 au DIRAC pour la vidéo en passant par mpeg-4 et Theora; même chose pour l&#8217;audio avec AAC, FLAC, Vorbis, &#8230; La spécification laisse le libre choix aux navigateurs et table sur la création d&#8217;extensions propres à ces derniers pour apporter le support de nouveaux formats. Si aujourd&#8217;hui <a
title="YouTube" href="http://www.youtube.com/html5">YouTube</a> et <a
title="Vimeo" href="http://vimeo.com/blog:268">Vimeo</a> ont choisi le H.264, <a
title="DailyMotion" href="http://www.dailymotion.com/openvideodemo">DailyMotion</a> joue les fidèles Mozilla avec sa démo basée sur Ogg et ne supportant que Firefox.</p><p>Chrome et Safari poussent H.264 tandis que Mozilla le rejette totalement et pousse les formats libres Vorbis et Theora (Ogg). Le gros avantage d&#8217;H.264, à mon sens, tient au fait qu&#8217;il est parfaitement adapté à l&#8217;embarqué et beaucoup plus optimisé que Theora. Malgré le barrage de Firefox (25% de parts de marché), avec Apple et Google le codec H.264 semble avoir de beaux jours devant lui. Google qui est justement le plus gros contributeur de Mozilla, fournira peut-être une extension, sinon ce sera probablement du codec pack pour tous.</p><p>Codecs supportés par navigateurs</p><table
style="border: 1px solid black" border="0" cellspacing="0" cellpadding="5"><tbody><tr><td
style="color: #ffffff; border: 1px solid black" bgcolor="#663366"><strong>Navigateur</strong></td><td
style="color: #ffffff; border: 1px solid black" bgcolor="#663366"><strong>Ogg</strong></td><td
style="color: #ffffff; border: 1px solid black" bgcolor="#663366"><strong>MP3</strong></td><td
style="color: #ffffff; border: 1px solid black" bgcolor="#663366"><strong>WAV</strong></td><td
style="color: #ffffff; border: 1px solid black" bgcolor="#663366"><strong>MP4</strong></td></tr><tr><td
style="border: 1px solid black"><strong>Firefox 3.5</strong></td><td
style="border: 1px solid black">Ok</td><td
style="border: 1px solid black">-</td><td
style="border: 1px solid black">Ok</td><td
style="border: 1px solid black">-</td></tr><tr><td
style="border: 1px solid black"><strong>Safari 4</strong></td><td
style="border: 1px solid black">-</td><td
style="border: 1px solid black">Ok</td><td
style="border: 1px solid black">Ok</td><td
style="border: 1px solid black">Ok</td></tr><tr><td
style="border: 1px solid black"><strong>Chrome 3</strong></td><td
style="border: 1px solid black">Ok</td><td
style="border: 1px solid black">Ok</td><td
style="border: 1px solid black">-</td><td
style="border: 1px solid black">Ok</td></tr><tr><td
style="border: 1px solid black"><strong>Opera 10</strong></td><td
style="border: 1px solid black">-</td><td
style="border: 1px solid black">-</td><td
style="border: 1px solid black">Ok</td><td
style="border: 1px solid black">-</td></tr><tr><td
style="border: 1px solid black"><strong>IE</strong></td><td
style="border: 1px solid black">-</td><td
style="border: 1px solid black">-</td><td
style="border: 1px solid black">-</td><td
style="border: 1px solid black">-</td></tr></tbody></table><p>Internet Explorer est pour le moment hors-jeu, sauf si on installe <a
title="Google Chrome Frame" href="http://code.google.com/intl/fr-FR/chrome/chromeframe/">Google Chrome Frame</a>. Mais il semblerait que Microsoft s&#8217;intéresse au sujet pour l&#8217;avenir et participe à la rédaction de la spécification. En attendant, Flash conserve une avance confortable et profite de sa très large base installée. Le changement arrive bizarrement par l&#8217;embarqué, iPhone et iPod Touch en tête, qui, d&#8217;une part, supportent pleinement les balises <code>audio</code>, et <code>video</code>, et d&#8217;autre part prouvent que les utilisateurs peuvent se passer de Flash sur le web.</p><h4><a
name="LeCanvas"></a>Le Canvas</h4><p>Passons maintenant au <code>canvas</code>. Inventé par Apple pour le Dashboard d&#8217;OS X et ses widgets, le <code>canvas</code> fournit une API JavaScript pour le dessin 2D. La balise définit une aire de dessins avec sa hauteur et sa largeur. L&#8217;objet DOM donne accès au contexte graphique qui possède les primitives de dessins. Outre les formes géométriques standards, l&#8217;API permet de faire de la composition, des transformations, de manipuler des images et d&#8217;afficher du texte formaté. Avec un timeout ou un intervalle sur l&#8217;objet et un peu de JavaScript, il devient possible d&#8217;animer les dessins. Les implémentations ne sont pas encore très optimisées. Un simple gif animé reste pour le moment plus performant en terme d&#8217;animation. Il existe déjà un tas de librairie JS construites autour de l&#8217;élément <code>canvas</code> pour générer des graphes et des charts par exemple (<a
title="Flotr" href="http://solutoire.com/flotr/">Flotr</a>, <a
title="ProtoChart" href="http://www.deensoft.com/lab/protochart/">ProtoChart</a>, <a
title="fgCharting" href="http://www.filamentgroup.com/lab/jquery_visualize_plugin_accessible_charts_graphs_from_tables_html5_canvas/">fgCharting</a>).</p><pre class="brush: xml; title: ; notranslate">
&lt;canvas id=firstCanvas&quot;&gt;Browser does not support the canvas element.&lt;/canvas&gt;
&lt;script type=&quot;text/JavaScript&quot;&gt;
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
ctx.fillStyle='#FF0006';
ctx.fillRect(0,0,80,120);
&lt;/script&gt;
</pre><p>Les détracteurs déplorent l&#8217;utilisation d&#8217;une API procédurale, et l&#8217;absence d&#8217;éléments crées dans l&#8217;arbre DOM de la page comme le fait SVG. Autre inconvénient, <code>canvas</code> travaille la composition directement en pixels et non en calques. SVCKit a donc implémenté en grande partie SVG dans <code>canvas</code> dans <a
title="SVGCanvas" href="http://svgkit.sourceforge.net/web/SVGCanvas.html">SVGCanvas</a>. Il existe déjà beaucoup de documentations et tutoriels autour de <code>canvas</code> qui rencontre, malgré ses défauts (de jeunesse ?), un grand succès. Mozilla a même développé un IDE en ligne basé sur <code>canvas</code>, nom de code : <a
title="BeSpin" href="https://bespin.mozilla.com/">BeSpin</a>.</p><p>Voilà pour les domaines d&#8217;application, passons maintenant à la question des navigateurs. Avec Apple pour inventeur et Mozilla comme évangéliste, <code>canvas</code> est déjà supporté nativement sur Safari, Firefox, Chrome et Opéra. Comme d&#8217;habitude IE est à la traine, mais il existe des contournements comme le plugin <a
title="IECanvas" href="http://hg.mozilla.org/users/vladimir_mozilla.com/iecanvas">IECanvas</a>, ou le portage Flash <a
title="ExplorerCanvas" href="http://code.google.com/p/explorercanvas/">ExplorerCanvas</a>.</p><h3><a
name="Conclusion"></a>Conclusion</h3><p>Nous voici à la fin de ce tour d&#8217;horizon des nouveautés d&#8217;HTML5, côté contenu du moins.<br
/> Avec les grands du web dans la poche, HTML5 est déjà promis à un bel avenir, malgré son jeune age. La prochaine échéance du W3C devrait être le passage en recommandation dans le courant de cette année peut-être. Si les WebForms ne sont pas pour tout de suite, le multimédia et le canvas sont déjà suffisamment supportés pour être utilisés aujourd&#8217;hui. Il faudra attendre la sortie d&#8217;IE 9 pour connaître les plans concrets de Microsoft sur le sujet. A mon humble avis, Microsoft intégrera HTML5 au fur et à mesure qu&#8217;il s&#8217;imposera sur le web. Il faudra aussi regarder de près l&#8217;évolution du standard CSS car HTML5 ne va pas sans CSS3. De ce côté, pas de crainte à avoir puisque même IE est dans la course.</p><p>Il reste un problème d&#8217;outillage, car il n&#8217;existe pas pour le moment de WYSIWYG compatible HTML5. Et il ne faut sans doute pas compter sur Adobe pour le faire rapidement. Apple propose déjà DashCode pour créer des widgets ou des applications web iPhone avec un éditeur graphique bien monté. Mais l&#8217;export vers d&#8217;autres navigateurs est presque impossible tant les applications construites reposent sur des fonctionnalités spécifiques de Safari.</p><p>Dans le prochain article, je vous présenterai les nouveautés JavaScript poussées par HTML5 et leur état actuel d&#8217;implémentation.</p><div
class="shr-publisher-4127"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F03%2F02%2Fhtml-5-les-nouveaux-elements%2F' data-shr_title='HTML5+-+Les+nouveaux+%C3%A9l%C3%A9ments'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F03%2F02%2Fhtml-5-les-nouveaux-elements%2F' data-shr_title='HTML5+-+Les+nouveaux+%C3%A9l%C3%A9ments'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/03/02/html-5-les-nouveaux-elements/feed/</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>Catalogue Xebia Training</title><link>http://blog.xebia.fr/2010/02/24/catalogue-xebia-training/</link> <comments>http://blog.xebia.fr/2010/02/24/catalogue-xebia-training/#comments</comments> <pubDate>Wed, 24 Feb 2010 12:32:34 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Exploitation]]></category> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Méthodes agiles]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[SOA]]></category> <category><![CDATA[eXtrem Programming]]></category> <category><![CDATA[JEE]]></category> <category><![CDATA[SCRUM]]></category> <category><![CDATA[XP]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=4085</guid> <description><![CDATA[Nous sommes heureux de vous proposer le nouveau catalogue de formation Xebia Traning : Le catalogue numérique. Le catalogue PDF. Xebia Training se positionne logiquement dans la continuité de Xebia, tant sur la qualité de son offre de formation technique que méthodologique (méthodes agiles), en proposant des formations haut de gamme animées uniquement par les [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://flipflashpages.uniflip.com/2/26742/50371/pub/"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/02/xebia-training.png" style="margin: 1em 1em 1em 1em; float: right;" /></a><br
/> Nous sommes heureux de vous proposer le nouveau <a
href="http://flipflashpages.uniflip.com/2/26742/50371/pub/">catalogue de formation Xebia Traning</a> :</p><ul><li>Le <a
href="http://flipflashpages.uniflip.com/2/26742/50371/pub/">catalogue numérique</a>.</li><li>Le <a
href="http://training.xebia.fr/wp-content/uploads/catalogue%20des%20formations%202010-xebia-training.pdf">catalogue PDF</a>.</li></ul><p><a
href="http://training.xebia.fr">Xebia Training</a> se positionne logiquement dans la continuité de Xebia, tant sur la qualité de son offre de formation technique que méthodologique (méthodes agiles), en proposant des formations haut de gamme animées uniquement par les référents de leur domaine.</p><p>Avec pour principe premier le refus de tout compromis sur la qualité du formateur et du contenu, <a
href="http://training.xebia.fr">Xebia Training</a> fait systématiquement intervenir des acteurs de références dans leurs domaines respectifs.</p><p>Nos formations, savant équilibre entre théorie et travaux pratiques, sont destinées à un large public soucieux d’acquérir les meilleures pratiques de notre industrie.</p><div
class="shr-publisher-4085"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F02%2F24%2Fcatalogue-xebia-training%2F' data-shr_title='Catalogue+Xebia+Training+'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2010%2F02%2F24%2Fcatalogue-xebia-training%2F' data-shr_title='Catalogue+Xebia+Training+'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/02/24/catalogue-xebia-training/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Flex : Custom style DataGrid</title><link>http://blog.xebia.fr/2009/11/26/flex-custom-style-datagrid/</link> <comments>http://blog.xebia.fr/2009/11/26/flex-custom-style-datagrid/#comments</comments> <pubDate>Thu, 26 Nov 2009 12:57:02 +0000</pubDate> <dc:creator>Nicolas Jozwiak</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Flex]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=3353</guid> <description><![CDATA[Lors de la finalisation de l&#8217;un de nos développements Flex, nous avons mis en place des styles pour les différents composants de l&#8217;application. Mais il se trouve que nous avons rencontré une petite difficulté sur le composant DataGrid. A noter également l&#8217;utilisation de Flex 4 dans cet exemple, mais ce problème est aussi valable avec [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://blog.xebia.fr/wp-content/uploads/2009/11/fx-150x150.png" border="0" alt="" style="margin: 1em 1em 1em 1em; float: right;" /><br
/> Lors de la finalisation de l&#8217;un de nos développements Flex, nous avons mis en place des styles pour les différents composants de l&#8217;application. Mais il se trouve que nous avons rencontré une petite difficulté sur le composant <code>DataGrid</code>. A noter également l&#8217;utilisation de Flex 4 dans cet exemple, mais ce problème est aussi valable avec Flex 3.</p><p>&nbsp;</p><h4><a
name="Lesstyles"></a>Les styles</h4><p>Avec Flex, les styles sont très simples à mettre en place, et se font de la même manière qu&#8217;en HTML :</p><ul><li>Soit via la définition des styles directement dans le fichier MXML :</li></ul><pre class="brush: xml; title: ; notranslate">
&lt;mx:Style&gt;
	myStyle {
		fontFamily: &quot;arial&quot;;
		background-color:#FFFFFF;
	}
&lt;/mx:Style&gt;
</pre><ul><li>Soit via la définition d&#8217;une feuille de styles CSS, déclarée dans le fichier MXML :</li></ul><pre class="brush: xml; title: ; notranslate">
&lt;mx:Style source=&quot;css/xebia.css&quot;/&gt;
</pre><p>Concernant le composant <code>DataGrid</code>, modifier les couleurs des lignes devient trivial avec la propriété <code>alternatingItemColors</code>. Néanmoins la situation se corse lorsque nous devons appliquer ces couleurs aux lignes d&#8217;une seule colonne&#8230;</p><h4><a
name="Exemple"></a>Exemple</h4><p>Prenons un exemple :</p><p><code>XebiaCustomDataGrid1.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot; xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot; xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot; minWidth=&quot;1024&quot; minHeight=&quot;768&quot;&gt;
	&lt;fx:Script&gt;
	&lt;![CDATA[
			import mx.collections.ArrayCollection;
			[Bindable]
			public var xebia:ArrayCollection = new ArrayCollection([
				{Company:&quot;Xebia France&quot;, City:&quot;Défense&quot;, Benefits:200000},
				{Company:&quot;Xebia Hollande&quot;, City:&quot;Hilversum&quot;, Benefits:400000},
				{Company:&quot;Xebia Inde&quot;, City:&quot;New Dehli&quot;, Benefits:150000},
				{Company:&quot;Xebia US&quot;, City:&quot;New York&quot;, Benefits:500000},
				{Company:&quot;Xebia Allemagne&quot;, City:&quot;Berlin&quot;, Benefits:160000},
				{Company:&quot;Xebia Espagne&quot;, City:&quot;Barcelone&quot;, Benefits:80000},
				{Company:&quot;Xebia Portugal&quot;, City:&quot;Lisbonne&quot;, Benefits:75000},
				{Company:&quot;Xebia Italie&quot;, City:&quot;Milan&quot;, Benefits:110000}
			]);
		]]&gt;
	&lt;/fx:Script&gt;
	&lt;mx: DataGrid dataProvider=&quot;{xebia}&quot; sortableColumns=&quot;false&quot; selectable=&quot;false&quot; height=&quot;228&quot; width=&quot;515&quot;&gt;
		&lt;mx:columns&gt;
			&lt;mx: DataGridColumn headerText=&quot;Company&quot; dataField=&quot;Company&quot;/&gt;
			&lt;mx: DataGridColumn headerText=&quot;City&quot; dataField=&quot;City&quot;/&gt;
			&lt;mx: DataGridColumn headerText=&quot;Benefits&quot; dataField=&quot;Benefits&quot;/&gt;
		&lt;/mx:columns&gt;
	&lt;/mx: DataGrid&gt;
&lt;/s:Application&gt;
</pre><p>Dans cet exemple, nous avons un simple <code>DataGrid</code> remplit avec une <code>ArrayCollection</code>, et dont les lignes ont des couleurs alternées.</p><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid1.swf" height="200" width="515" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid1.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid1.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid1.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="200" width="515" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid1.swf" type="application/x-shockwave-flash" /><br
/> </object></div><p>Dans ce second exemple, nous ajoutons une CSS :</p><p><code>xebia.css</code></p><pre class="brush: xml; title: ; notranslate">
.grid {
	alternatingItemColors: #ffccff, #ff99cc;
}
.header {
	fontWeight: bold;
}
</pre><p><code>XebiaCustomDataGrid2.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot; xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot; xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot; minWidth=&quot;1024&quot; minHeight=&quot;768&quot;&gt;
	&lt;fx:Style source=&quot;css/xebia.css&quot;/&gt;
	&lt;fx:Script&gt;
	&lt;![CDATA[
			import mx.collections.ArrayCollection;
			[Bindable]
			public var xebia:ArrayCollection = new ArrayCollection([
				{Company:&quot;Xebia France&quot;, City:&quot;Défense&quot;, Benefits:200000},
				{Company:&quot;Xebia Hollande&quot;, City:&quot;Hilversum&quot;, Benefits:400000},
				{Company:&quot;Xebia Inde&quot;, City:&quot;New Dehli&quot;, Benefits:150000},
				{Company:&quot;Xebia US&quot;, City:&quot;New York&quot;, Benefits:500000},
				{Company:&quot;Xebia Allemagne&quot;, City:&quot;Berlin&quot;, Benefits:160000},
				{Company:&quot;Xebia Espagne&quot;, City:&quot;Barcelone&quot;, Benefits:80000},
				{Company:&quot;Xebia Portugal&quot;, City:&quot;Lisbonne&quot;, Benefits:75000},
				{Company:&quot;Xebia Italie&quot;, City:&quot;Milan&quot;, Benefits:110000}
			]);
		]]&gt;
	&lt;/fx:Script&gt;
	&lt;mx: DataGrid dataProvider=&quot;{xebia}&quot; sortableColumns=&quot;false&quot; selectable=&quot;false&quot; styleName=&quot;grid&quot; headerStyleName=&quot;header&quot; height=&quot;228&quot; width=&quot;515&quot;&gt;
		&lt;mx:columns&gt;
			&lt;mx: DataGridColumn headerText=&quot;Company&quot; dataField=&quot;Company&quot;/&gt;
			&lt;mx: DataGridColumn headerText=&quot;City&quot; dataField=&quot;City&quot;/&gt;
			&lt;mx: DataGridColumn headerText=&quot;Benefits&quot; dataField=&quot;Benefits&quot;/&gt;
		&lt;/mx:columns&gt;
	&lt;/mx: DataGrid&gt;
&lt;/s:Application&gt;
</pre><p>On notera l&#8217;ajout des attributs <code>styleName</code> et <code>headerStyleName</code> dans les propriétés du <code>DataGrid</code>, ainsi que de la déclaration de la CSS :</p><pre class="brush: xml; title: ; notranslate">
&lt;fx:Style source=&quot;css/xebia.css&quot;/&gt;
</pre><p>Nous obtenons ainsi le rendu suivant :</p><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid2.swf" height="200" width="515" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid2.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid2.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid2.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="200" width="515" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid2.swf" type="application/x-shockwave-flash" /><br
/> </object></div><p>Mais que faire si nous voulons appliquer un style sur une seule colonne ? La solution consiste à surcharger les cellules de la colonne concernée par un <code>renderer</code>. Pour ce faire, une classe ActionScript doit être mise en place.</p><p>Voici la classe <code>CustomCell.as</code> :</p><pre class="brush: xml; title: ; notranslate">
public class CustomCell extends Label
     {
      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            var g:Graphics = graphics;
            g.clear();
	    	if (DataGridListData(listData).rowIndex % 2 == 0) {
	        	g.beginFill(0xffdfbf);
	     	} else {
	     		g.beginFill(0xffc080);
	     	}
	        g.drawRect(0, -2, unscaledWidth+1, unscaledHeight+4);
	        g.endFill();
        }
     }
</pre><p>Ainsi pour chaque ligne, nous dessinons un rectangle dans la cellule avec la même alternance de couleurs.<br
/> Il ne nous reste plus qu&#8217;à appliquer ce <code>renderer</code> au <code>DataGrid</code>.</p><p><code>XebiaCustomDataGrid3.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot; xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot; xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot; minWidth=&quot;1024&quot; minHeight=&quot;768&quot;&gt;
	&lt;fx:Style source=&quot;css/xebia.css&quot;/&gt;
	&lt;fx:Script&gt;
	&lt;![CDATA[
			import mx.collections.ArrayCollection;
			[Bindable]
			public var xebia:ArrayCollection = new ArrayCollection([
				{Company:&quot;Xebia France&quot;, City:&quot;Défense&quot;, Benefits:200000},
				{Company:&quot;Xebia Hollande&quot;, City:&quot;Hilversum&quot;, Benefits:400000},
				{Company:&quot;Xebia Inde&quot;, City:&quot;New Dehli&quot;, Benefits:150000},
				{Company:&quot;Xebia US&quot;, City:&quot;New York&quot;, Benefits:500000},
				{Company:&quot;Xebia Allemagne&quot;, City:&quot;Berlin&quot;, Benefits:160000},
				{Company:&quot;Xebia Espagne&quot;, City:&quot;Barcelone&quot;, Benefits:80000},
				{Company:&quot;Xebia Portugal&quot;, City:&quot;Lisbonne&quot;, Benefits:75000},
				{Company:&quot;Xebia Italie&quot;, City:&quot;Milan&quot;, Benefits:110000}
			]);
		]]&gt;
	&lt;/fx:Script&gt;
	&lt;mx: DataGrid dataProvider=&quot;{xebia}&quot; sortableColumns=&quot;false&quot; selectable=&quot;false&quot; styleName=&quot;grid&quot; headerStyleName=&quot;header&quot; height=&quot;228&quot; width=&quot;515&quot;&gt;
		&lt;mx:columns&gt;
			&lt;mx: DataGridColumn headerText=&quot;Company&quot; dataField=&quot;Company&quot;/&gt;
			&lt;mx: DataGridColumn headerText=&quot;City&quot; dataField=&quot;City&quot;/&gt;
			&lt;mx: DataGridColumn headerText=&quot;Benefits&quot; dataField=&quot;Benefits&quot; itemRenderer=&quot;renderer.CustomCell&quot;/&gt;
		&lt;/mx:columns&gt;
	&lt;/mx: DataGrid&gt;
&lt;/s:Application&gt;
</pre><p>Nous remarquons que la propriété <code>itemRenderer</code> a été ajoutée sur la troisième colonne du <code>DataGrid</code>.</p><p>Ainsi nous obtenons le rendu suivant :</p><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid3.swf" height="200" width="515" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid3.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid3.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid3.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="200" width="515" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/11/XebiaCustomDataGrid3.swf" type="application/x-shockwave-flash" /><br
/> </object></div><p>Enfin à travers cet exemple nous revoyons une des limites de Flex: malgré la richesse des composants et de leurs comportements, lorsque les développements deviennent un peu plus subtils, du code ActionScript est nécessaire, là où dans cet exemple une simple instruction CSS aurait suffit&#8230;</p><p>En espérant que cette solution puisse aider d&#8217;autres personnes !</p><p>Vous pouvez télécharger les sources sur le <a
href="http://code.google.com/p/xebia-france/source/browse/trunk/flex/XebiaFlex/" title="SVN de Xebia France" >SVN de Xebia France</a>.</p><div
class="shr-publisher-3353"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F11%2F26%2Fflex-custom-style-datagrid%2F' data-shr_title='Flex+%3A+Custom+style+DataGrid'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F11%2F26%2Fflex-custom-style-datagrid%2F' data-shr_title='Flex+%3A+Custom+style+DataGrid'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/11/26/flex-custom-style-datagrid/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Devoxx &#8211; Jour 2 &#8211; Les effets avec Flex 4</title><link>http://blog.xebia.fr/2009/11/19/devoxx-jour-2-les-effets-avec-flex-4/</link> <comments>http://blog.xebia.fr/2009/11/19/devoxx-jour-2-les-effets-avec-flex-4/#comments</comments> <pubDate>Thu, 19 Nov 2009 14:17:54 +0000</pubDate> <dc:creator>Ellène Dijoux</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Devoxx]]></category> <category><![CDATA[Flex]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=3226</guid> <description><![CDATA[La session Wicket initialement prévue Mardi matin ayant été annulée, j&#8217;ai assisté à la place à une présentation sur les effets Flex. Je pensais que je ne pouvais rien apprendre de plus à ce sujet, je me suis trompée : l&#8217;utilisation des effets a été simplifiée, et il est maintenant possible d&#8217;étendre les effets. &#160; [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://www.devoxx.com/"><img
src="http://blog.xebia.fr/wp-content/uploads/2009/11/logo.jpeg" alt="Devoxx" style="margin: 1em 1em 1em 1em; float: right;" /></a><br
/> La session Wicket initialement prévue Mardi matin ayant été annulée, j&#8217;ai assisté à la place à une présentation sur les effets Flex. Je pensais que je ne pouvais rien apprendre de plus à ce sujet, je me suis trompée : l&#8217;utilisation des effets a été simplifiée, et il est maintenant possible d&#8217;étendre les effets.</p><p>&nbsp;</p><h3><a
name="Questcequuneffet"></a>Qu&#8217;est ce qu&#8217;un effet ?</h3><h4><a
name="Flex"></a>Flex 3</h4><p>En Flex, il est possible de définir des effets pour des transitions ou lors du déclenchement d&#8217;un évènement (hide, show par exemple).<br
/> Nous allons reprendre l&#8217;exemple du Dissolve disponible sur le <a
href="http://examples.adobe.com/flex3/componentexplorer/explorer.html" title="Flex 3 Component Explorer" >Flex 3 Component Explorer</a>.<br
/> On commence par définir les effets :</p><pre class="brush: xml; title: ; notranslate">
&lt;mx: Dissolve id=&quot;dissolveOut&quot; duration=&quot;1000&quot; alphaFrom=&quot;1.0&quot; alphaTo=&quot;0.0&quot;/&gt;
</pre><p>Puis on indique au composant cible, l&#8217;effet qu&#8217;il doit utiliser lorsque l&#8217;on cache le label :</p><pre class="brush: xml; title: ; notranslate">
&lt;mx:Label text=&quot;Nokia 9930&quot;
          fontSize=&quot;14&quot;
          visible=&quot;{cb1.selected}&quot;
          hideEffect=&quot;{dissolveOut}&quot;/&gt;
...
&lt;mx:CheckBox id=&quot;cb1&quot; label=&quot;visible&quot; selected=&quot;true&quot;/&gt;
</pre><p>Dans Flex 3, il n&#8217;est pas possible de gérer des effets sur la valeur d&#8217;une propriété comme le texte ou la couleur par exemple. Les effets ne sont en effet applicables que sur les composants.</p><h4><a
name="Flex"></a>Flex 4</h4><p>La nouveauté dans Flex 4 tient tout d&#8217;abord dans la définition d&#8217;une nouvelle super classe Animate qui vient remplacer TweenEffect. Cette nouvelle super classe fournit de nouvelles propriétés telles que easer, interpolator et motionPaths que nous verrons par la suite.</p><p>Dans cette nouvelle version, les effets sont plus flexibles et il est possible de :</p><ul><li>modifier la valeur des propriétés telles que le gradient d&#8217;une couleur ou la taille,</li><li>régler la vitesse de l&#8217;effet, lui donner une accélération au début ou à la fin par exemple,</li><li>déplacer plus facilement les composants lors d&#8217;un effet.</li></ul><h3><a
name="Lesnouveauxeffets"></a>Les nouveaux effets</h3><h4><a
name="LeseffetsD"></a>Les effets 3D</h4><p>Parmi les nouveaux effets, voici probablement les plus impressionnants d&#8217;entre eux : les effets en trois dimensions. Grâce à Flash Player 10 qui est maintenant capable de représenter un objet 3D, on peut par exemple exécuter un effet de déplacement en profondeur ou une rotation.</p><h3><a
name="Laconfigurationdeseffets"></a>La configuration des effets</h3><p>Avec cette nouvelle super classe <em>Animate</em> viennent de nouvelles propriétés :</p><ul><li>easer : l&#8217;atténuation de l&#8217;effet (en quelque sorte une accélération ou décélération avec laquelle l&#8217;effet sera appliqué),</li><li>interpolator : fonction utilisée par l&#8217;effet pour calculer les valeurs à prendre pour une propriété entre le début et la fin de cet effet,</li><li>motionPaths : un vecteur contenant des objets MotionPath, chacun portant le nom et la valeur que la propriété peut prendre,</li><li>repeatBehavior : permet de répéter l&#8217;effet.</li></ul><p>Avec ces nouvelles fonctions, il est encore plus simple de réaliser des effets customisés comme par exemple un bouton qui s&#8217;enfonce lorsque l&#8217;on clique dessus, ou un changement de couleur lorsque le curseur pointe un composant. Maintenant à vous de laisser parler votre imagination.</p><div
class="shr-publisher-3226"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F11%2F19%2Fdevoxx-jour-2-les-effets-avec-flex-4%2F' data-shr_title='Devoxx+-+Jour+2+-+Les+effets+avec+Flex+4'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F11%2F19%2Fdevoxx-jour-2-les-effets-avec-flex-4%2F' data-shr_title='Devoxx+-+Jour+2+-+Les+effets+avec+Flex+4'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/11/19/devoxx-jour-2-les-effets-avec-flex-4/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Devoxx &#8211; Jour 1 &#8211; Adobe University</title><link>http://blog.xebia.fr/2009/11/17/devoxx-jour-1-adobe-university/</link> <comments>http://blog.xebia.fr/2009/11/17/devoxx-jour-1-adobe-university/#comments</comments> <pubDate>Tue, 17 Nov 2009 12:53:51 +0000</pubDate> <dc:creator>Ellène Dijoux</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[BlazeDS]]></category> <category><![CDATA[Devoxx]]></category> <category><![CDATA[Flash]]></category> <category><![CDATA[Flash Catalyst]]></category> <category><![CDATA[Flex]]></category> <category><![CDATA[Spring]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=3149</guid> <description><![CDATA[La première journée de Devoxx fut l&#8217;occasion pour Adobe de présenter lors de leur université leur nouvelle plateforme Flash. Pour cette présentation, quatre évangélistes Flex se sont relayés pour nous présenter ces différents produits Adobe : - Christophe Coenraets - Chet Haase qui travaillait anciennement sur JavaFX - Serge Jespers - Maarten Arten La plateforme [...]]]></description> <content:encoded><![CDATA[<p>La première journée de Devoxx fut l&#8217;occasion pour Adobe de présenter lors de leur université leur nouvelle plateforme Flash. Pour cette présentation, quatre évangélistes Flex se sont relayés pour nous présenter ces différents produits Adobe :<br
/> - <a
href="http://coenraets.org/" title="Christophe Coenraets" >Christophe Coenraets</a><br
/> - <a
href="http://graphics-geek.blogspot.com/" title="Chet Haase" >Chet Haase</a> qui travaillait anciennement sur JavaFX<br
/> - <a
href="http://www.webkitchen.be/" title="Serge Jespers" >Serge Jespers</a><br
/> - <a
href="http://blog.arten.fr" title="Maarten Arten" >Maarten Arten</a></p><p><img
src="http://blog.xebia.fr/wp-content/uploads/2009/11/DSC_1351.jpg" alt="DSC_1351" title="DSC_1351" width="680" height="300" class="alignnone size-full wp-image-3150" /></p><h3><a
name="LaplateformeFlashquestcequeces"></a>La plateforme Flash : qu&#8217;est ce que c&#8217;est ?</h3><p>Cette plateforme Flash est composée de :</p><ul><li>La gamme Creative Suite <em>(avec Fireworks, Photoshop et Illustrator)</em> destinée au designer.</li><li>Flash Catalyst qui permettra de générer une application Flex à partir des maquettes réalisées avec les outils précédents.</li><li>Flash Builder 4 pour le développement du reste de l&#8217;application et de son backend.</li></ul><h3><a
name="FlashCatalyst"></a>Flash Catalyst</h3><p>Pour rappel Flash Catalyst est un outil permettant à partir d&#8217;un dessin réalisé avec les outils de la gamme Creative Suite de générer une véritable application Flex sans toucher à une ligne de code. Cet outil est capable de générer tous les composants graphiques disponibles dans Flex 4 et gèrent également les <code>itemrenderer</code>. Les effets et les transitions peuvent être également gérés avec cet outil. Lors de la session Tools In Action, une démonstration bluffante d&#8217;environ 30 minutes a été effectuée avec cet outil. Il y a cependant quelques conditions pour que la génération s&#8217;effectue au mieux :</p><ul><li>Penser à bien séparer ses filtres et à les nommer proprement. Ceci afin que l&#8217;intégrateur puisse plus aisément les récupérer et les convertir en composant Flex.</li><li>L&#8217;intégrateur doit aussi bien nommer les composants une fois créés afin que le développeur puisse les exploiter plus facilement.</li></ul><p>À la fin de cette courte session, nous avons pu voir le résultat : une application Flex reprenant la maquette de départ.</p><h3><a
name="Flex"></a>Flex 4</h3><p>Cette nouvelle plateforme ne peut être utilisée qu&#8217;avec Flex 4. En effet, la nouvelle librairie de composants graphiques spark qui vient remplacer l&#8217;ancienne <em>(que l&#8217;on nomme halo ou mx aussi)</em> proposent de séparer l&#8217;aspect du composant de son comportement. Un billet a <a
href="http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/" title="dj t crit  ce sujet" >déjà été écrit à ce sujet</a>. C&#8217;est ce qui permettra à Catalyst de générer l&#8217;aspect des composants. Le développeur quant à lui ne se préoccupera plus que des comportements du bouton tels que le traitement des données, la gestion des événements et le traitement avec le backend. Les composants peuvent également supporter les formes primitives <em>(rectangles, ronds, carrés)</em>, les bitmaps, les textes riches et les vidéos. Autre nouveauté dans ce nouveau SDK, une nouvelle structure du code : les déclarations des <code>HTTPService</code> et autres <code>RemoteObject</code> s&#8217;effectuent dans les balises <code>&lt;fx:Declaration&gt;</code>.</p><h3><a
name="SpringBlazeDSIntegration"></a>Spring BlazeDS Integration</h3><p>Parmi les nouveautés, nous noterons la présentation de Spring BlazeDS Integration. Avec moins de configuration que BlazeDS, il est possible de mettre en place plus facilement un backend utilisant Spring. Grâce à des annotations, il est maintenant plus simple d&#8217;exposer ses services à la partie cliente.</p><p>Exemple :</p><pre class="brush: java; title: ; notranslate">
@Service(&quot;contactService&quot;)
@RemotingDestination
public class ContactDao {
...
</pre><p>On expose <code>contactService</code> à la partie cliente. Côté Flex, il n&#8217;y aura plus qu&#8217;à simplement appeler ce service grâce au <code>RemoteObject</code>. Concernant le lien client-serveur, Christophe Coenraets soulève un point intéressant : actuellement il est impossible pour le compilateur Flex de reconnaître les services exposés côté serveur. Effectivement, à ce niveau là le compilateur doit croire le développeur et ne possède aucune réelle visibilité. C&#8217;est pour cela que dans Flash Builder 4 a été ajoutée la possibilité de réaliser de l&#8217;introspection sur les services exposés côté serveur. Fonctionnant avec BlazeDS, LiveCycle Data Service ES et AMF PHP, Flash Builder est donc maintenant capable de reconnaître ses services et de les importer côté client.</p><h3><a
name="ModelDrivenDevelopmentdansFlas"></a>Model Driven Development dans FlashBuilder</h3><p>Une autre nouveauté dans FlashBuilder 4 est une nouvelle vue nommée Data Models permettant de réaliser des modèles de données et de les générer autant côté client que côté Serveur. Cette partie sera davantage détaillée dans la session de Jeudi : <a
href="http://devoxx.com/display/DV09/Model-Driven+Development+Using+Adobe+Flash+Builder+4+and+LiveCycle+Data+Services+ES" title="Model Driven Development using Adobe Flash Builder 4 and LiveCycle Data Services ES" >Model Driven Development using Adobe Flash Builder 4 and LiveCycle Data Services ES</a>.</p><p>La présentation était réussie et les démonstrations très bluffantes. Flash Catalyst semble mature et Flash Builder 4 répond mieux aux besoins des développeurs <em>(il est enfin possible de faire un Generate getter/setter sur une propriété !)</em>. Mais on attend toujours la release qui est maintenant prévue pour mi-2010 voire même un peu après.</p><div
class="shr-publisher-3149"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F11%2F17%2Fdevoxx-jour-1-adobe-university%2F' data-shr_title='Devoxx+-+Jour+1+-+Adobe+University'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F11%2F17%2Fdevoxx-jour-1-adobe-university%2F' data-shr_title='Devoxx+-+Jour+1+-+Adobe+University'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/11/17/devoxx-jour-1-adobe-university/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Les nouveautés de Flex 4</title><link>http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/</link> <comments>http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/#comments</comments> <pubDate>Wed, 19 Aug 2009 09:26:22 +0000</pubDate> <dc:creator>Ellène Dijoux</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Flash]]></category> <category><![CDATA[Flex]]></category> <category><![CDATA[Flex 4]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=2662</guid> <description><![CDATA[Il y a quelque temps est sortie la version bêta de Flex 4. Connue aussi sous le nom de Gumbo, cette nouvelle version n&#8217;a plus rien à voir avec les précédentes : possibilité de personnaliser ses composants, simplification des notations &#8230; Nous verrons dans ce billet quelques nouveautés de Flex 4 et les raisons d&#8217;un [...]]]></description> <content:encoded><![CDATA[<p>Il y a quelque temps est sortie la version bêta de Flex 4. Connue aussi sous le nom de Gumbo, cette nouvelle version n&#8217;a plus rien à voir avec les précédentes : possibilité de personnaliser ses composants, simplification des notations &#8230; Nous verrons dans ce billet quelques nouveautés de Flex 4 et les raisons d&#8217;un changement aussi radical des librairies.</p><ul><li><a
href="http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/#Leseffets">Les effets</a></li><li><a
href="http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/#Dessinemoiunboutonavecspark">Dessine moi un bouton &#8230; avec spark.</a></li><li><a
href="http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/#LesautresnouveautsdeFlex">Les autres nouveautés de Flex 4</a></li><li><a
href="http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/#Conclusion">Conclusion</a></li><li><a
href="http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/#Pourallerplusloin">Pour aller plus loin</a></li></ul><p>Pour visualiser les exemples Flex 4 ci dessous, il vous faudra installer Flash Player 10.</p><h4><a
name="Leseffets"></a>Les effets</h4><p>Une différence notable avec la précédente version de Flex est la gestion des états qui est maintenant nettement plus simple.<br
/> En Flex, il est possible de décrire plusieurs états associés à un composant. Ces états définissent, pour un composant, des éléments à ajouter, des styles ou des propriétés à appliquer. En effet, il est question de manipuler des <code>AddChild</code>, des <code>SetProperty</code> ou encore des <code>SetStyle</code> qui peuvent devenir très vite lourds à gérer. Pour mieux comprendre, prenons un exemple :<br
/> Nous allons réaliser une application sur 2 états, l&#8217;état <code>blueState</code> qui va colorer le label <code>helloLabel</code> en bleu et l&#8217;état <code>redState</code> qui va le colorer en rouge. Pour ce faire, avec Flex 3, nous utilisons les balises <code>SetStyle</code> qui permettent de modifier le style <code>color</code> du label et de le mettre à la couleur voulue.</p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; layout=&quot;absolute&quot; minWidth=&quot;300&quot; minHeight=&quot;300&quot;&gt;
    &lt;mx:states&gt;
        &lt;mx:State name=&quot;blueState&quot;&gt;
            &lt;mx:SetStyle target=&quot;{helloLabel}&quot; name=&quot;color&quot; value=&quot;blue&quot;/&gt;
        &lt;/mx:State&gt;
        &lt;mx:State name=&quot;redState&quot;&gt;
            &lt;mx:SetStyle target=&quot;{helloLabel}&quot; name=&quot;color&quot; value=&quot;red&quot;/&gt;
        &lt;/mx:State&gt;
    &lt;/mx:states&gt;
    &lt;mx:HBox&gt;
        &lt;mx:Label text=&quot;Bonjour !&quot; id=&quot;helloLabel&quot;/&gt;
        &lt;mx:Button label=&quot;Bleu&quot; id=&quot;blue&quot; click=&quot;currentState='blueState'&quot;/&gt;
        &lt;mx:Button label=&quot;Rouge&quot; id=&quot;red&quot; click=&quot;currentState='redState'&quot;/&gt;
    &lt;/mx:HBox&gt;
&lt;/mx:Application&gt;
</pre><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex3.swf" height="100" width="400" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex3.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex3.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex3.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="100" width="400" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex3.swf" type="application/x-shockwave-flash" /><br
/> </object></div><p>Avec Flex 4, il n&#8217;est plus question de définir des <code>SetStyle</code> ou <code>SetProperty</code> dans les composants. Tout se fait dans les attributs qui peuvent se décliner en fonction des états comme ceci : <code>styleOuPropriete.monEtat</code>. Ainsi <code>color.blueState</code> prendra la couleur bleu lorsque l&#8217;on sera dans cet état.D&#8217;autre attributs apparaissent également dans les composants graphiques comme <code>includeIn</code> ou encore <code>excludeFrom</code> pour permettre d&#8217;exclure ou d&#8217;inclure un composant en fonction de l&#8217;état courant. De plus, Flex prend maintenant par défaut le premier état lorsqu&#8217;on en définit plusieurs pour un composant. C&#8217;est la raison pour laquelle nous avons ajouté <code>defaultState</code> comme état par défaut. Avec Flex 4, notre précédent exemple donne donc ceci :</p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:Application
   xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
   xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
   xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;
	&lt;s:states&gt;
		&lt;mx:State name=&quot;defaultState&quot; /&gt;
		&lt;mx:State name=&quot;blueState&quot; /&gt;
		&lt;mx:State name=&quot;redState&quot; /&gt;
	&lt;/s:states&gt;
	&lt;mx:Label text=&quot;Bonjour !&quot; color=&quot;black&quot; color.blueState=&quot;blue&quot; color.redState=&quot;red&quot;/&gt;
	&lt;s:Button label=&quot;Rouge&quot; click=&quot;currentState='redState'&quot;/&gt;
	&lt;s:Button label=&quot;Bleu&quot; click=&quot;currentState='blueState'&quot;/&gt;
	&lt;s:layout&gt;
		&lt;s:HorizontalLayout /&gt;
	&lt;/s:layout&gt;
&lt;/s:Application&gt;
</pre><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex4.swf" height="100" width="400" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex4.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex4.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex4.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="100" width="400" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/08/testflex4.swf"  type="application/x-shockwave-flash" /><br
/> </object></div><p>Certes, il s&#8217;agit d&#8217;un petit exemple. Mais cela pourrait simplifier la gestion des états sur des applications plus élaborées.</p><h4><a
name="Dessinemoiunboutonavecspark"></a>Dessine moi un bouton &#8230; avec spark.</h4><p>De nouvelles librairies ont vu le jour dans Flex 4. Commençons par la librairie <strong>spark</strong>, présente depuis Mai 2009. Elle offre toute une nouvelle génération de composants dont l&#8217;architecture est clairement différente de son prédécesseur <strong>halo</strong>.  Cette dernière proposait des composants graphiques sur lesquels il n&#8217;était possible que de changer les couleurs et le style du texte : le <a
href="http://examples.adobe.com/flex3/consulting/styleexplorer/Flex3StyleExplorer.html#" title="Flex Style Explorer" >Flex Style Explorer</a> en est un bon exemple.<br
/> La librairie spark, de son côté, propose un nouveau type de composant « skinnable », c&#8217;est-à-dire que nous avons d&#8217;un côté le dessin représentant un bouton et de l&#8217;autre l&#8217;objet bouton. De plus, spark intègre la librairie FXG qui fournit tous les composants permettant de faire des dessins vectoriels.<br
/> Pour mieux comprendre le fonctionnement, rien de mieux qu&#8217;un exemple :<br
/> Nous créons d&#8217;abord un Skin sous le nom de <code>component.CustomSkin</code>.</p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:Skin xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
   xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
   xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot; height=&quot;300&quot; width=&quot;300&quot;&gt;
    &lt;fx:Metadata&gt;
        [HostComponent(&quot;spark.components.Button&quot;)]
    &lt;/fx:Metadata&gt;
    &lt;s:states&gt;
        &lt;mx:State name=&quot;up&quot; /&gt;
        &lt;mx:State name=&quot;over&quot; /&gt;
        &lt;mx:State name=&quot;down&quot; /&gt;
    &lt;/s:states&gt;
    &lt;s:Ellipse height=&quot;86&quot; width=&quot;96&quot; verticalCenter=&quot;0&quot; horizontalCenter=&quot;0&quot;&gt;
        &lt;s:fill&gt;
          &lt;mx:SolidColor color=&quot;#FF0000&quot; color.over=&quot;red&quot; color.up=&quot;blue&quot;/&gt;
         &lt;/s:fill&gt;
    &lt;/s:Ellipse&gt;
    &lt;s:layout&gt;
        &lt;s:BasicLayout/&gt;
    &lt;/s:layout&gt;
&lt;/s:Skin&gt;
</pre><p>Nous définissons le comportement de ce composant grâce au metatag <code>HostComponent</code>, ici il s&#8217;agit donc d&#8217;un bouton. Nous ajoutons ensuite les états en regardant dans la documentation, nous pouvons voir que <code>Button</code> dispose des états : <code>up</code>, <code>over</code>, <code>down</code> et <code>disabled</code>. Contentons-nous des trois premiers états pour cet exemple. Enfin, on finit par dessiner un bouton qui sera disposé dans un layout qui doit être défini dans tout composant spark. Ce <code>skin</code> est ensuite associé à un bouton dans l&#8217;application principale.</p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
    xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
    xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot;
    minWidth=&quot;1024&quot; minHeight=&quot;768&quot;
    xmlns:component=&quot;component.*&quot;&gt;
    &lt;fx:Script&gt;
        &lt;![CDATA[
            import mx.controls.Alert;
            import component.MyButton;
        ]]&gt;
    &lt;/fx:Script&gt;
    &lt;fx:Style source=&quot;TestFlex4.css&quot;/&gt;
    &lt;s:Button skinClass=&quot;component.CustomSkin&quot;  click=&quot;Alert.show('Je suis un bouton !')&quot;/&gt;
&lt;/s:Application&gt;
</pre><p>Et voici le rendu :</p><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/08/testbutton.swf" height="200" width="400" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testbutton.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testbutton.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/08/testbutton.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="200" width="400" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/08/testbutton.swf" type="application/x-shockwave-flash" /><br
/> </object></div><h4><a
name="LesautresnouveautsdeFlex"></a>Les autres nouveautés de Flex 4</h4><p><strong>Support dans l&#8217;ASDoc des fichiers MXML</strong><br
/> La SDK de Flex 3 ne générait que la documentation associée au code ActionScript 3. Il est maintenant possible dans le SDK 4 de générer de l&#8217;ASDoc pour les composants MXML.</p><p><strong>Le data binding dans les deux sens</strong><br
/> Actuellement, la liaison des données dans un composant avec Flex se fait de la façon suivante :</p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;&gt;
    &lt;mx:TextInput id=&quot;myText1&quot; /&gt;
    &lt;mx:TextInput id=&quot;myText2&quot; text=&quot;{myText1.text}&quot; /&gt;
&lt;/mx:Application&gt;
</pre><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex3.swf" height="100" width="400" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex3.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex3.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex3.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="100" width="400" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex3.swf" type="application/x-shockwave-flash" /><br
/> </object></div><p>Dans cet exemple, l&#8217;édition dans <code>myText1</code> modifie le champs <code>myText2</code> mais l&#8217;inverse ne se fait pas. Pour les lier tous les deux il faudrait modifier <code>myText1</code> comme ceci :</p><pre class="brush: xml; title: ; notranslate">
&lt;mx:TextInput id=&quot;myText1&quot; text=&quot;{myText2.text}&quot;/&gt;
</pre><p>Avec la nouvelle notation que propose Flex 4, il suffit de faire comme ceci :</p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
   xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
   xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot; minWidth=&quot;1024&quot; minHeight=&quot;768&quot;&gt;
    &lt;s:TextInput id=&quot;myText1&quot; /&gt;
    &lt;s:TextInput id=&quot;myText2&quot; text=&quot;@{myText1.text}&quot; /&gt;
    &lt;s:layout&gt;
        &lt;s:VerticalLayout/&gt;
    &lt;/s:layout&gt;
&lt;/s:Application&gt;
</pre><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex4.swf" height="100" width="400" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex4.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex4.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex4.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="100" width="400" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/08/databindingflex4.swf" type="application/x-shockwave-flash" /><br
/> </object></div><p>Et automatiquement les deux composants sont liés.</p><h4><a
name="Conclusion"></a>Conclusion</h4><p>Toutes ces nouveautés proposées par Adobe ont pour but :</p><ul><li>d&#8217;améliorer la productivité du développeur en simplifiant le langage,</li><li>d&#8217;avoir plus de liberté sur le design.</li></ul><p>La librairie <code>spark</code> propose des composants radicalement différents de ce que l&#8217;on peut actuellement utiliser dans Flex 3, mais il est cependant possible d&#8217;utiliser les composants de l&#8217;ancienne librairie nommée <code>halo</code>. Les habitués ne s&#8217;y perdront donc pas.<br
/> Mais alors pourquoi autant de changement ? La raison est très simple et se nomme Flash Catalyst. <a
href="http://blog.xebia.fr/2009/06/08/revue-de-presse-xebia-112/#SortiebetadeFlashBuilderetdeFl" title="Le nouvel outil dAdobe sorti en Juin 2009 en version bta" >Le nouvel outil d&#8217;Adobe sorti en Juin 2009 en version bêta</a> est capable de générer du code Flex à partir de dessins réalisés par la gamme Creative Suite 4.<br
/> Flex 4 est toujours en bêta actuellement, une release est prévue pour le dernier trimestre 2009.</p><h4><a
name="Pourallerplusloin"></a>Pour aller plus loin</h4><ul><li><a
href="http://livedocs.adobe.com/flex/gumbo/html/" title="LiveDocs Flex 4" >LiveDocs Flex 4</a></li><li><a
href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4" title="Tlcharger le SDK" >Télécharger le SDK</a></li></ul><div
class="shr-publisher-2662"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F08%2F19%2Fles-nouveautes-de-flex-4%2F' data-shr_title='Les+nouveaut%C3%A9s+de+Flex+4'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F08%2F19%2Fles-nouveautes-de-flex-4%2F' data-shr_title='Les+nouveaut%C3%A9s+de+Flex+4'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/08/19/les-nouveautes-de-flex-4/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Spring Flex BlazeDS Integration</title><link>http://blog.xebia.fr/2009/07/29/spring-flex-blazeds-integration/</link> <comments>http://blog.xebia.fr/2009/07/29/spring-flex-blazeds-integration/#comments</comments> <pubDate>Wed, 29 Jul 2009 08:11:55 +0000</pubDate> <dc:creator>Nicolas Jozwiak</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[BlazeDS]]></category> <category><![CDATA[Flex]]></category> <category><![CDATA[Spring]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=2591</guid> <description><![CDATA[Récemment, lors d&#8217;une intervention sur une application Flex, j&#8217;ai été confronté à un problème de migration d&#8217;une version de la librairie Spring BlazeDS Integration (passage de la version 1.0.0.RC2 à 1.0.0.M2). Cette librairie permet la configuration de BlazeDS à travers Spring de façon simplifiée. J&#8217;ai voulu configurer un appel à un service Java en Remoting. [...]]]></description> <content:encoded><![CDATA[<p>Récemment, lors d&#8217;une intervention sur une application Flex, j&#8217;ai été confronté à un problème de migration d&#8217;une version de la librairie Spring BlazeDS Integration <em>(passage de la version 1.0.0.RC2 à 1.0.0.M2)</em>. Cette librairie permet la configuration de BlazeDS à travers Spring de façon simplifiée. J&#8217;ai voulu configurer un appel à un service Java en Remoting.</p><p>Afin de déclarer votre service <code>Remote</code>, les lignes suivantes doivent être ajoutées dans votre <code>applicationContext.xml</code> :</p><pre class="brush: xml; title: ; notranslate">
&lt;bean class=&quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&quot;&gt;
	&lt;property name=&quot;mappings&quot;&gt;
	    &lt;value&gt;
	        /*=mySpringManagedMessageBroker
	    &lt;/value&gt;
	&lt;/property&gt;
&lt;/bean&gt;
&lt;!-- Envoie les requêtes au &quot;message broker&quot; --&gt;
&lt;bean class=&quot;org.springframework.flex.servlet.MessageBrokerHandlerAdapter&quot;/&gt;
&lt;!-- Le MessageBroker de BlazeDs --&gt;
&lt;bean id=&quot;mySpringManagedMessageBroker&quot; class=&quot;org.springframework.flex.core.MessageBrokerFactoryBean&quot; /&gt;
&lt;!-- Service myService --&gt;
&lt;bean id=&quot;myService&quot; class=&quot;com.xebia.impl.MyServiceImpl&quot; /&gt;
&lt;flex:remoting-destination message-broker=&quot;mySpringManagedMessageBroker&quot; destination-id=&quot;myServiceDest&quot; ref=&quot;myService&quot; /&gt;
</pre><p>Ainsi que la référence au fichier <code>xsd</code> : <code>http://www.springframework.org/schema/flex/spring-flex-1.0.xsd</code></p><p>Malheureusement, au démarrage de votre application, vous aurez cette erreur :</p><pre class="brush: java; title: ; notranslate">
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 67 in XML document from ServletContext resource [/WEB-INF/classes/applicationContext-service.xml] is invalid;
        nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'flex:remoting-destination'.
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
</pre><p>Pourtant cela fonctionnait parfaitement avec les versions précédentes de Spring BlazeDS Integration &#8230;</p><p>Je regarde donc le fichier <code>xsd</code> sur lequel se base mon <code>applicationContext</code> <em>(http://www.springframework.org/schema/flex/spring-flex-1.0.xsd)</em>, et le <code>remoting-destination</code> est bien présent&#8230; étrange. Je regarde également la <a
href=" http://static.springsource.org/spring-flex/docs/1.0.x/reference/html/index.html" title="documentation du projet" >documentation du projet</a> et d&#8217;après cette dernière, ma configuration est bonne &#8230; le mystère s&#8217;épaissit.</p><p>Après quelques recherches, j&#8217;ai l&#8217;idée de regarder le <code>xsd</code> du <code>jar</code> de Spring BlazDS Integration (<code>org.springframework.flex-1.0.0.M2.jar</code>). Et <em>eureka</em>, je trouve l&#8217;explication : le <code>xsd</code> du <code>jar</code> n&#8217;est pas le même que celui vers lequel pointe mon <code>applicationContext</code>&#8230; Au chargement de l&#8217;application, c&#8217;est le <code>xsd</code> du <code>jar</code> qui est recherché&#8230; De plus, je me rends compte que cette version a subi un peu de refactoring et certains chemins ont été modifiés.<br
/> Par conséquent, vous devez déclarer votre service <code>Remote</code> de cette manière :</p><pre class="brush: xml; title: ; notranslate">
&lt;bean class=&quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&quot;&gt;
  &lt;property name=&quot;mappings&quot;&gt;
	   &lt;value&gt;
	       /*=mySpringManagedMessageBroker
	   &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;
&lt;!-- Envoie les requêtes au &quot;message broker&quot; --&gt;
&lt;bean class=&quot;org.springframework.flex.messaging.servlet.MessageBrokerHandlerAdapter&quot;/&gt;
&lt;!-- Le MessageBroker de BlazeDs --&gt;
&lt;bean id=&quot;mySpringManagedMessageBroker&quot; class=&quot;org.springframework.flex.messaging.MessageBrokerFactoryBean&quot; /&gt;
&lt;!-- Service myService --&gt;
&lt;bean id=&quot;myService&quot; class=&quot;com.xebia.impl.MyServiceImpl&quot; /&gt;
&lt;flex:remote-service message-broker=&quot;mySpringManagedMessageBroker&quot; service-id=&quot;myServiceDest&quot; ref=&quot;myService&quot; /&gt;
</pre><p>Vous remarquerez que <code>remoting-destination</code> et <code>destination-id</code> sont devenus <code>remote-service</code> et <code>service-id</code> et que les chemins des classes <code>MessageBrokerHandlerAdapter</code> et <code>MessageBrokerFactoryBean</code> ont changé.</p><p>Néanmoins, une solution plus rapide consiste à effectuer une montée de version vers la 1.0.0.RELEASE de Spring BlazeDS Integration. En effet, le fichier <code>xsd</code> ainsi que les chemins ont été remis comme la version RC2, posant ainsi moins de problèmes.</p><p>En espérant que cette solution puisse aider d&#8217;autres personnes !</p><div
class="shr-publisher-2591"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F07%2F29%2Fspring-flex-blazeds-integration%2F' data-shr_title='Spring+Flex+BlazeDS+Integration'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F07%2F29%2Fspring-flex-blazeds-integration%2F' data-shr_title='Spring+Flex+BlazeDS+Integration'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/07/29/spring-flex-blazeds-integration/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Jazoon &#8211; Jour 2 &#8211; JDK 7</title><link>http://blog.xebia.fr/2009/06/24/jazoon-jour-2-jdk-7/</link> <comments>http://blog.xebia.fr/2009/06/24/jazoon-jour-2-jdk-7/#comments</comments> <pubDate>Wed, 24 Jun 2009 18:54:23 +0000</pubDate> <dc:creator>Guillaume Mathias</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[jazoon]]></category> <category><![CDATA[jdk-7]]></category> <category><![CDATA[Jigsaw]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=2348</guid> <description><![CDATA[Cette deuxième journée de Jazoon a commencé par une keynote de Danny Coward, qui a établi deux tops 5 distincts, à savoir le top 5 de ce qui va arriver dans le JDK 7, et celui de ce qui existe déjà dans JavaFX 1.2 (on peut noter cette amusante différence d&#8217;échelle). Laissons de coté le [...]]]></description> <content:encoded><![CDATA[<p>Cette deuxième journée de Jazoon a commencé par une keynote de Danny Coward, qui a établi deux tops 5 distincts, à savoir le top 5  de <i>ce qui va arriver</i> dans le JDK 7, et celui de <i>ce qui existe déjà</i> dans JavaFX 1.2 (on peut noter cette amusante différence d&#8217;échelle).<br
/> Laissons de coté le top 5 JavaFX (nous y reviendrons dans un autre billet), pour nous concentrer sur les 5 nouveautés du JDK 7,  &laquo;&nbsp;les plus excitantes&nbsp;&raquo; pour un Sun Fellow.</p><ul><li>La modularité : introduite par le projet <a
href="http://openjdk.java.net/projects/jigsaw/">Jigsaw</a>, actuellement <a
href="http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#JigsawvsOSGi">au cœur d&#8217;une polémique</a>, elle devrait permettre de supprimer les principaux reproches faits aux précédents JDKs, à savoir leur lenteur au démarrage, le plat de spaghettis des dépendances, et l&#8217;enfer du classpath.</li><li>La JVM polyglotte : capable d&#8217;exécuter de nombreux langages (la voie a été ouverte par JRuby), elle devrait faciliter l&#8217;émergence des langages dynamiques. C&#8217;est le projet <a
href="http://openjdk.java.net/projects/mlvm/">DaVinci</a>.</li><li>Les ajouts au langage : ils sont listés dans le projet <a
href="http://openjdk.java.net/projects/coin/">Coin</a>. Danny a listé les switch sur les String, la gestion d&#8217;exceptions multiples, une meilleure inférence de type, et <a
href="http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000047.html">l&#8217;opérateur Elvis</a></li><li>Plus d&#8217;APIs I/O : le <code>Path</code> remplace le <code>File</code>, manipulation des <code>Directory</code>, recherche en utilisant des <code>FileVisitor</code>, opérations asynchrones. On peut se demander si ce genre de fonctionnalités sera vraiment cross-platform (comportement identique ?).</li><li>Nouveau Garbage collector : le fameux G1 (dont nous avons parlé <a
href="http://blog.xebia.fr/2008/03/12/gc-generationnels-traditionnels-jdk6-vs-gc-garbage-first-jdk7/">ici</a>) est disponible en <em>preview</em> dans le JSE 6 update 14 en utilisant l&#8217;option <code>-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC</code></li></ul><p>La <em>final release</em> devrait être disponible (selon la <em>roadmap</em> annoncée) dans le courant du premier trimestre 2010.</p><p>On apprécie les efforts continus faits sur la VM mais nous regrettons que les évolutions du langage restent superficielles (c&#8217;est bien mais pas suffisant). C&#8217;est probablement l&#8217;une des raisons de l&#8217;émergence des langages dynamiques. Comme si Danny Coward avait voulu légitimer <em>l&#8217;opening keynote</em> de James Gosling : &laquo;&nbsp;la force de Java ce n&#8217;est pas son langage, mais sa VM&nbsp;&raquo;.</p><div
class="shr-publisher-2348"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F06%2F24%2Fjazoon-jour-2-jdk-7%2F' data-shr_title='Jazoon+-+Jour+2+-+JDK+7'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F06%2F24%2Fjazoon-jour-2-jdk-7%2F' data-shr_title='Jazoon+-+Jour+2+-+JDK+7'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/06/24/jazoon-jour-2-jdk-7/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Google I/O 2009 &#8211; annonces et stratégie Google</title><link>http://blog.xebia.fr/2009/06/01/google-io-2009-annonces-et-strategie-google/</link> <comments>http://blog.xebia.fr/2009/06/01/google-io-2009-annonces-et-strategie-google/#comments</comments> <pubDate>Mon, 01 Jun 2009 12:58:21 +0000</pubDate> <dc:creator>Erwan Alliaume</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Mobilité]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[Android]]></category> <category><![CDATA[Chrome]]></category> <category><![CDATA[Google App Engine]]></category> <category><![CDATA[googleio]]></category> <category><![CDATA[GWT]]></category> <category><![CDATA[GWT Query]]></category> <category><![CDATA[HTML 5]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[wave]]></category> <category><![CDATA[Widgets]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=2068</guid> <description><![CDATA[Google I/O 2009 s&#8217;est tenu la semaine dernière à San Francisco. Il s&#8217;agit d&#8217;une des conférence destinées aux développeurs utilisateurs des applications et des API de Google. Faute d&#8217;avoir eu l&#8217;occasion de me rendre sur place, j&#8217;ai essayé de suivre d&#8217;aussi prêt que possible son déroulement. Vu de l&#8217;extérieur : du grand spectacle ! Dans [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://code.google.com/events/io/" title="Google IO 2009" >Google I/O 2009</a> s&#8217;est tenu la semaine dernière à San Francisco. Il s&#8217;agit d&#8217;une des conférence destinées aux développeurs utilisateurs des applications et des API de Google. Faute d&#8217;avoir eu l&#8217;occasion de me rendre sur place, j&#8217;ai essayé de suivre d&#8217;aussi prêt que possible son déroulement. Vu de l&#8217;extérieur : du grand spectacle !</p><p>Dans cet article, je vais donc revenir sur les annonces et points marquants de ces deux jours de conférences.</p><p>D&#8217;autre part, les vidéos des keynotes sont disponibles, vous pouvez consulter celle du <a
href="http://www.youtube.com/watch?v=S5aJAaGZIvk" title="premier jour" >premier jour</a> (html5, android, web components &#8230;) ou celle du <a
href="http://www.youtube.com/watch?v=v_UyVmITiYQ" title="second jour" >second jour</a> (google wave).</p><p>Google I/O 2009, voici ce que j&#8217;en ai retenu  :</p><ul><li>Le futur du Web, avec les premières <strong>démonstrations émoustillantes <a
href="http://dev.w3.org/html5/spec/Overview.html" title="HTML 5" >HTML 5</a></strong>.</li><li><strong><a
href="http://wave.google.com" title="Google Wave" >Google Wave</a></strong>, le prochain outil de communication et collaboration made in Google.</li><li>La réconciliation de Google avec GWT et la sortie de <strong>GWT Query</strong>.</li><li>Le futur d&#8217;Android, avec l&#8217;annonce de la branche <strong>Android 2.0 : Donut</strong>.</li><li>Java sur Google App Engine en GA.</li><li><strong>Google Web Elements</strong>, comment intégrer les services Google dans vos pages web.</li><li>Les macros dans Google Document, avec <strong>Google Apps Script</strong>.</li><li>Arrivée des <strong>extensions dans Chrome</strong>.</li></ul><h3><a
name="HTMLlepremierwhaoueffect"></a>HTML 5, le premier whaou effect</h3><p>C&#8217;est la première fois que HTML 5 me fait rêver. C&#8217;est en effet un sacré coup de pouce que Google à donné afin de faire taire les <a
href="http://blog.xebia.fr/2008/08/11/revue-de-presse-xebia-69/#HTMLimmobilisparlestergiversat" title="tergiversions" >tergiversions</a>. Google a pris position, et nous en a mis plein la vue ! C&#8217;est ainsi qu&#8217;a débuté le premier jour de conférence avec <a
href="http://www.youtube.com/watch?v=W4FbF8GKChk" title="une vido dintroduction de 5 minutes" >une vidéo d&#8217;introduction de 5 minutes</a> présentant des applications écrites avec HTML 5. Application ai-je dit ? Eh bien oui, il semble bien loin le temps de la page web statique. Il semble bien loin le temps des hacks Javascript, arrêtons la bidouille et commençons le développement d&#8217;applications riches : c&#8217;est en tout cas ce que nous promet Google avec le HTML 5. Tout cela sans nécessiter le moindre plugin &#8230; pour peu que vous ayez un navigateur compatible.</p><p>Pour Google, le navigateur a encore de beaux jours devant lui. Installé sur prêt d&#8217;un <a
href="http://www.findmysoft.com/news/Google-I-O-2009-HTML-5-Web-Elements-App-Engine-Google-Earth-Android-Hardware/" title="demi-milliard d'ordinateurs" >demi-milliard d&#8217;ordinateurs</a>, il reste le moyen le plus simple et répandu pour accéder à Internet. Google l&#8217;a bien compris et a participé à la course <a
href="http://celtickane.com/labs/web-browser-javascript-benchmark/" title="aux performances des moteurs JavaScript" >aux performances des moteurs JavaScript</a>. En un an, les performances des moteurs JavaScript ont été multipliées par 5 ! Vous n&#8217;êtes pas fan de JavaScript, il faudra pourtant vous y faire. Comme nous vous pourrez le constater dans la suite de cet article, ce langage est l&#8217;un des points centraux de la stratégie Google.</p><p>Sans le savoir, vous possédez peut-être déjà l&#8217;un des navigateurs compatibles avec certaines fonctionnalités HTML 5, si tel est le cas vous pouvez lancer certaines des <a
href="http://htmlfive.appspot.com/" title="dmonstrations prsentes" >démonstrations présentées</a> directement depuis celui-ci.</p><p>Les principales nouveautés apportées par HTML 5 sont :</p><ul><li>Les <a
href="http://fr.wikipedia.org/wiki/Canvas_(balise_html)" title="canvas" >canvas</a>, zone sur laquelle il est possible de <em>dessiner</em> et d&#8217;effectuer des transformations : agrandissement, rotations, translations sur différents types de figures.</li><li>Des balises <em>audio</em> et <em>video</em>, qui permettent d&#8217;intégrer des médias dans le document sans nécessiter un plugin externe. Elles disposent de fonctionnalités similaires aux lecteurs <a
href="http://www.adobe.com/fr/products/flash" title="Flash" >Flash</a> ou <a
href="http://silverlight.net" title="Silverlight" >Silverlight</a> vous permettant de contrôler le comportement de vos médias.</li><li>Les <a
href="http://blog.whatwg.org/the-road-to-html-5-episode-1-the-section-element" title="sections" >sections</a> permettent de diviser vos pages en parts sémantiques. Elles se différencient des balises <em>div</em> qui ont pour rôle principal la présentation. Une section est complétée par un <em>header</em> et un <em>footer</em>.</li><li>Un nouvel attribut <em>async</em> pour les balises <em>script</em>, il permet d&#8217;exécuter un script indépendamment de l&#8217;affichage de la page. Ces scripts pourront s&#8217;activer à la demande selon la disponibilité de ressources.</li></ul><p>HTML 5 vous propose donc de transformer vos pages web en application riche, ce nouveau balisage vous permet de tirer pleinement partie de contenu multimédia sans nécessiter de plugin extérieur.</p><h3><a
name="GoogleWavelagrosseannoncedelac"></a>Google Wave, la grosse annonce de la conférence</h3><p>Sans conteste la grosse annonce de Google durant ces 2 jours, Google a annoncé la sortie prochaine de <a
href="http://wave.google.com/" title="Google Wave" >Google Wave</a>. Il s&#8217;agit d&#8217;un nouvel outil Open Source de communication et de collaboration, initié à l&#8217;origine par les deux frères Rasmussen, déjà à l&#8217;origine de Google Maps. Leur point de départ, à quoi les emails ressembleraient s&#8217;ils avaient été inventés aujourd&#8217;hui ? Après nous avoir parlé d&#8217;HTML 5 et d&#8217;applications riches, Google dévoile comment ils comptent tirer parti de ces nouveautés. A la vue du résultat, difficile de croire que l&#8217;application fonctionne sur un simple navigateur. Je vous encourage vivement de <a
href=" http://www.youtube.com/watch?v=v_UyVmITiYQ" title="regarder la démonstration" >regarder la démonstration</a>, le moins que l&#8217;on puisse dire est qu&#8217;elle donne envie <a
href="https://services.google.com/fb/forms/wavesignup/" title="dessayer le produit" >d&#8217;essayer le produit</a>. Pour ma part, même si j&#8217;avoue bien volontiers avoir été moins époustouflé qu&#8217;à la sortie de Google Earth il y a quelques années, il faut bien admettre qu&#8217;une fois encore Google est moteur d&#8217;innovations. Tout comme la sortie de Gmail, fort est à parier qu&#8217;une multitude de concurrents essayeront en vain d&#8217;égaler cette nouveauté. Et si une page était en train de se tourner dans le développement d&#8217;applications Web ?</p><p>Là où les emails permettaient un échange point à point, Google Wave centralise et met à disposition le contenu. On n&#8217;envoie pas une <em>Wave</em>, on y participe. L&#8217;historique des modifications des conversations (texte, média, widget) est stocké sur un serveur. Ainsi, tout nouveau participant pourra rejouer intégralement celle-ci.</p><p>Google Wave est un mixte entre email, messagerie instantanée, réseaux sociaux, partages de documents. Il se base sur un <a
href="http://www.waveprotocol.org/" title="protocole spcialement" >protocole spécialement</a> créé pour l&#8217;occasion. Celui-ci permet la transmission d&#8217;incréments de données et permet, entre autres, l&#8217;affichage caractère par caractère d&#8217;une conversation au fur et à mesure de la rédaction par son auteur.</p><p>Bien plus qu&#8217;une application, Google Wave est également contrôlable via une API spécifique. Vous pourrez donc y utiliser ces services à votre guise pour modeler vos propres solutions. Du coup, fort est à parier que Google Wave sera également disponible sous la forme de widget à utiliser sur vos blogs, sites web &#8230;</p><p>Pour plus d&#8217;information sur le sujet, vous pouvez <a
href=" http://mashable.com/2009/05/28/google-wave-guide/" title="consulter cette page" >consulter cette page</a> sur laquelle l&#8217;auteur à centralisé les informations, définitions et fonctionnalités de Google Wave.</p><h3><a
name="GWTaucurdelastratgieGoogle"></a>GWT, au cœur de la stratégie Google ?</h3><p>L&#8217;autre grosse surprise avec l&#8217;arrivée de Google Wave, l&#8217;utilisation de GWT à grande échelle dans un produit Google !</p><p>Jusqu&#8217;ici, il était drôle de constater que si GWT avait bien été créé intégralement en interne chez Google, au final, aucun produit phare n&#8217;utilisait cette technologie. Et bien, ceci sera bientôt du passé ! Non seulement le client Wave a été écrit en GWT, mais Google continue à investir beaucoup sur cette technologie. Certes GWT à tout de même dû subir pour l&#8217;occasion quelques modifications, mais force est de constater que GWT semble plus que jamais au centre de la stratégie Google. GWT permettra également la création d&#8217;applications pour Android et iPhone. C&#8217;est comme si Google voulait nous faire oublier nos applications locales/desktop aux bénéfices d&#8217;applications légères/riches.</p><p>Google I/O, c&#8217;est également l&#8217;annonce de la sortie de <a
href="http://code.google.com/p/gwtquery/" title="Gwt Query" >Gwt Query</a> : un clone de jQuery pour GWT. Cette nouvelle Api permet d&#8217;ajouter du comportement côté client sans rencontrer les lourdeurs des Widgets. À ce stage GWT Query reprend 98% des fonctionnalités de jQuery.</p><h3><a
name="AndroidDonutrecherchesetfiltre"></a>Android 2.0 Donut, recherches et filtres</h3><p>A l&#8217;heure où les premiers téléphones Android arrivent tout juste en France, Google a annoncé la création de la branche 2.0, appelée Donut. Sortie prévue : fin 2009.</p><p>Comme le communiquent <a
href=" http://www.zdnet.fr/actualites/telecoms/0,39040748,39501591,00.htm" title="certains" >certains</a>, 2009 sera probablement l&#8217;année d&#8217;Android. Si à ce jour seuls deux mobiles sous ce système sont timidement sortis en France, Google <a
href="http://bits.blogs.nytimes.com/2009/05/27/google-expect-18-android-phones-by-years-end/" title="attend la sortie dune vingtaine dappareils" >attend la sortie d&#8217;une vingtaine d&#8217;appareils</a> (pour une dizaine de fabriquants) en 2009.</p><p>Google I/O a donc été l&#8217;occasion de faire un point sur la roadmap de cette nouvelle version, celle-ci est prévue pour fin 2009 :</p><ul><li>Recherche globale : un champ de recherche commun pour le web, la musique, les contacts&#8230; C&#8217;est en effet, l&#8217;un des défauts de la version actuelle, le market nous encourage à installer toujours plus d&#8217;applications, il s&#8217;avère pour le moment peu pratique de retrouver celle que l&#8217;on cherche. J&#8217;avais d&#8217;ailleurs l&#8217;idée de développer une application &#8216;launcher&#8217;, je vais donc pouvoir nettoyer ma todo-list. Cette recherche globale vous permet donc d&#8217;effectuer des recherches aussi bien en local sur votre téléphone qu&#8217;en connecté sur le web. Démonstration de la fonctionnalité après la 3e minute <a
href="http://www.youtube.com/watch?v=uX9nt8Cpdqg&#038;feature=channel" title="de cette vido" >de cette vidéo</a>.</li><li>Contrôle par la voix : Android 1.5 (Cupcake) a introduit les embryons de Google Voice Search, vous permettant de lancer des recherches Google par la voix. Donut va davantage utiliser cette fonctionnalité qui vous permettra aussi bien d&#8217;appeler un contact que de contrôler vos applications à la voix. Ces fonctionnalités seront intégrées aux applications Google, mais pas seulement. Vous pourrez les utiliser dans vos applications via la nouvelle API. Révolutionnaire ? par forcément, j&#8217;ai utilisé cette fonctionnalité pour la première fois sur Pocket PC il y a 3 ans avec <a
href="http://www.microsoft.com/france/cp/2005/3/05030801_a79.mspx" title="Microsoft Voice Command" >Microsoft Voice Command</a>.</li><li>Synthèse vocale : vous contrôlez votre téléphone par la voix, celui-ci sait également vous parler. Donut offrira également des fonctionnalités de text2speach multi-langues, la présentation à été portée par une <a
href="http://www.youtube.com/watch?v=DZ-MZnMLb_A" title="application de traduction" >application de traduction</a> plutôt réussie.</li><li>Contrôle par le geste : votre téléphone sera capable également de reconnaître via l&#8217;écran tactile des formes complexes. Cela vous permettra entre autres de filtrer une liste de contacts en dessinant la première lettre du nom recherché.</li></ul><p>Pour clôturer ce sujet, notez l&#8217;ouverture d&#8217;un nouveau concours mondial de programmation sur Android : <a
href="http://code.google.com/intl/fr-FR/android/adc/" title="Android Developper Challenge 2" >Android Developper Challenge 2</a> avec de belles récompenses à la clé.</p><h3><a
name="JavasurGoogleAppEngineouvertto"></a>Java sur Google App Engine, ouvert à tous</h3><p>Bien qu&#8217;aucune annonce n&#8217;ait encore été faire sur le <a
href="http://googleappengine.blogspot.com/" title="blog officiel" >blog officiel</a>, il semblerait que Google ait annoncé officiellement le support Java sur <a
href="http://code.google.com/intl/fr/appengine/" title="Google App Engine" >Google App Engine</a>, ce qui veut dire : ouvert à tous. En effet, <a
href="http://blog.xebia.fr/2009/04/14/revue-de-presse-xebia-104/#GoogleAppEnginepourJavaetGroov" title="en avril dernier" >en avril dernier</a>, Google avait déjà pré-ouvert sa plateforme aux langages Java et Groovy aux 10 000 premiers inscrits.</p><h3><a
name="GoogleWebElementswidgetspourvo"></a>Google Web Elements, widgets pour vos sites internet</h3><p><a
href="http://www.google.com/webelements/" title="Google Web Elements" >Google Web Elements</a> vous permet d&#8217;utiliser les services Google sous la forme de widgets sur vos blogs ou sites web. Ces widgets nous permettront par exemple d&#8217;afficher facilement nos présentations PowerPoint sur le blog, les sites du type <a
href="http://www.slideshare.net/" title="Slideshare" >Slideshare</a> doivent grincer des dents&#8230;</p><p>Le fonctionnement est très simple :</p><ul><li>Rendez-vous sur le site de <a
href="http://www.google.com/webelements/" title="Google Web Elements" >Google Web Elements</a> pour choisir votre type de Widget.</li><li>Configurez-le en ligne via un simple formulaire permettant de générer le code HTML et JavaScript représentant le widget.</li><li>Copier-collez le code sur votre site ou blog.</li></ul><p>Huit applications sont disponibles pour le moment: Calendar, Presentation, Conversation, Custom Search, Maps, News, Spreadsheets et Youtube News.</p><h3><a
name="GoogleAppsScriptscriptezvosGoo"></a>Google Apps Script, scriptez vos Google Documents</h3><p>Google IO c&#8217;est du grand spectacle, comme nous l&#8217;avons vu durant les keynotes, mais aussi des annonces plus terre-à-terre : <a
href="http://www.youtube.com/watch?v=7ux-IexZFec" title="Google Apps Script" >Google Apps Script</a> en est un bon exemple. Avec cette fonctionnalité, il vous sera donc possible prochainement d&#8217;ajouter des fonctionnalités de scripting dans vos documents. Le développement de ces &#8216;macros&#8217; s&#8217;effectuera entièrement en JavaScript à partir d&#8217;un éditeur intégré aux différentes applications Google Document. Je vous invite à consulter une <a
href="http://www.youtube.com/watch?v=YJPsJOkaAzU" title="vido de dmonstration" >vidéo de démonstration</a> durant laquelle le présentateur effectue une macro d&#8217;envoi d&#8217;email.</p><h3><a
name="Chromearrivedesextensions"></a>Chrome, arrivée des extensions</h3><p>Comme certains le savent déjà, Chrome, le navigateur internet made in Google, proposera prochainement <a
href="http://dev.chromium.org/developers/design-documents/extensions/" title="un système de gestion d'extensions" >un système de gestion d&#8217;extensions</a>. Il vous est d&#8217;ailleurs déjà possible de commencer à écrire vos propres extensions en utilisant <a
href="http://dev.chromium.org/getting-involved/dev-channel" title="le dernier build developper" >le dernier build developper</a>, je m&#8217;y suis d&#8217;ailleurs essayé comme vous avez pu le <a
href="http://twitter.com/ealliaume" title="lire sur mon twitter" >lire sur mon twitter</a>. Si cela vous intéresse, jetez un coup d&#8217;œil au <a
href="http://dev.chromium.org/developers/design-documents/extensions/howto" title="howto" >howto</a> vous permettant de créer votre premier plugin en 30 secondes chrono.</p><p>Les extensions sont des archives ZIP contenant du HTML, des CSS et du JavaScript. Chaque partie d&#8217;UI d&#8217;une extension se présente sous la forme d&#8217;une simple page internet. Du coup, vous utilisez les mêmes outils, même debugger, mêmes librairies JavaScript et les mêmes techniques de programmation que pour créer vos pages web. Google a particulièrement bien travaillé son API pour la rendre aussi simple que possible.</p><p>Chrome dispose depuis <a
href="http://blog.xebia.fr/2008/09/09/google-chrome-1-semaine-apres/#Unrendustandardetquelquesnouve" title="sa premire version" >sa première version</a> d&#8217;une gestion des processus bien ficelée : chaque onglet dispose de son propre processus rendant de ce fait difficile de planter le navigateur à cause d&#8217;une des pages web. Les extensions fonctionneront sur un principe similaire et disposeront donc également de leur propre processus.</p><p>Les extensions seront distribuées sous la forme de fichier CRX composé de :</p><ul><li>Une signature, pour éviter les attaques du type Man In The Middle.</li><li>Un manifeste, contenant les informations générales (nom, version &#8230;).</li><li>Un fichier zip avec le contenu.</li></ul><p>Tiens tiens, cela n&#8217;est pas sans nous rappeler le packaging des applications Android&#8230;</p><div
align="center"> <a
href="http://twitter.com/ealliaume" ><br
/> <img
src="http://blog.xebia.fr/wp-content/uploads/2009/04/twitter4.png"  alt="twitter erwan alliaume" title="twitter erwan alliaume" border="0" /><br
/> </a></div><div
class="shr-publisher-2068"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F06%2F01%2Fgoogle-io-2009-annonces-et-strategie-google%2F' data-shr_title='Google+I%2FO+2009+-+annonces+et+strat%C3%A9gie+Google+'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F06%2F01%2Fgoogle-io-2009-annonces-et-strategie-google%2F' data-shr_title='Google+I%2FO+2009+-+annonces+et+strat%C3%A9gie+Google+'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/06/01/google-io-2009-annonces-et-strategie-google/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Ecrire son validateur Flex</title><link>http://blog.xebia.fr/2009/05/20/ecrire-son-validateur-flex/</link> <comments>http://blog.xebia.fr/2009/05/20/ecrire-son-validateur-flex/#comments</comments> <pubDate>Wed, 20 May 2009 11:56:32 +0000</pubDate> <dc:creator>Nicolas Jozwiak</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[Flex]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=2021</guid> <description><![CDATA[Pour les besoins de l&#8217;un de nos développements Flex, nous avons utilisé les validateurs Flex. De base, le framework nous fournit un ensemble de validateurs (StringValidator, EmailValidator&#8230;), mais il se trouve qu&#8217;ils ne répondaient pas tous à l&#8217;ensemble de nos besoins. En effet, nous avions besoin de valider la longueur d&#8217;une suite de chiffres, mais [...]]]></description> <content:encoded><![CDATA[<p>Pour les besoins de l&#8217;un de nos développements Flex, nous avons utilisé les validateurs Flex. De base, le framework nous fournit un ensemble de validateurs (<code>StringValidator</code>, <code>EmailValidator</code>&#8230;), mais il se trouve qu&#8217;ils ne répondaient pas tous à l&#8217;ensemble de nos besoins. En effet, nous avions besoin de valider la longueur d&#8217;une suite de chiffres, mais le <code>NumberValidator</code> ne permet pas de valider la longueur&#8230; De plus, nous avions aussi besoin d&#8217;une longueur minimale&#8230;</p><p>Heureusement, il est possible d&#8217;écrire votre validateur : il suffit de coder une classe <code>ActionScript</code> qui hérite de <code>mx.validators.Validator</code> et de surcharger la méthode <code>doValidation()</code>. Voici notre validateur permettant de contrôler qu&#8217;une suite de chiffres doit être comprise entre une longueur minimale et une longueur maximale.</p><h4><a
name="Ecritureduvalidateur"></a>Ecriture du validateur</h4><p><code>CustomNumberValidator.as</code></p><pre class="brush: xml; title: ; notranslate">
package validation
{
    import mx.validators.NumberValidator;
    import mx.validators.ValidationResult;
    public class CustomNumberValidator extends NumberValidator {
          public var minLength:Number;
          public var maxLength:Number;
	  public var lengthFieldError:String;
	  public function CustomNumberValidator() {
		super();
	  }
	  override protected function doValidation(value:Object):Array {
          	var results:Array = super.doValidation(value);
		var val:String = value ? String(value) : &quot;&quot;;
		// value has to be between minLength and maxLength
		if ((val.length &gt;= minLength &amp;&amp; val.length &lt;= maxLength) || ((val.length == 0) &amp;&amp; !required)) {
			return results;
		} else {
			return checkForLength(value);
		}
    	   }
	   public function checkForLength(value:Object):Array {
		var results:Array = [];
		results.push(new ValidationResult(
				 true, null, &quot;invalidChar&quot;,
				 lengthFieldError));
		return results;
	   }
    }
}
</pre><p>Tout d&#8217;abord, nous définissons des variables:</p><pre class="brush: xml; title: ; notranslate">
public var minLength:Number; //la longueur minimale de la suite de chiffres
public var maxLength:Number; //la longueur maximale de la suite de chiffres
public var lengthFieldError:String; //message d'erreur si la longueur n'est pas comprise entre minLength et maxLength
</pre><p>Ces 3 variables sont paramétrables lors de la définition du <code>Validator</code> dans le fichier MXML que nous verrons plus loin.</p><p>Comme vous pouvez le voir, dans la méthode <code>doValidation()</code> nous récupérons une chaîne (la suite de chiffres), et nous testons si cette dernière est bien comprise entre <code>minLength</code> et <code>maxLength</code>. Si la validation se passe mal, la méthode retournera un tableau de <code>ValidationResult</code> avec le message d&#8217;erreur que nous avons défini (<code>lengthFieldError</code>), sinon elle renverra un tableau vide.</p><p>Voici le fichier MXML utilisant ce <code>Validator</code>:</p><p><code>XebiaValidator1.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
                xmlns:validation=&quot;validation.*&quot;
                layout=&quot;absolute&quot;
                width=&quot;520&quot; height=&quot;242&quot;&gt;
    &lt;mx:StringValidator id=&quot;userNameValidator&quot;
		        source=&quot;{userName}&quot;
		        property=&quot;text&quot;
		        requiredFieldError=&quot;User Name can not be empty !&quot;/&gt;
    &lt;validation:CustomNumberValidator id=&quot;commandValidator&quot;
        source=&quot;{commandeId}&quot;
        property=&quot;text&quot;
        minLength=&quot;4&quot;
        maxLength=&quot;20&quot;
        domain=&quot;int&quot;
        required=&quot;true&quot;
        lengthFieldError=&quot;Number command has to be between 4 and 20 digits&quot;/&gt;
    &lt;mx:Panel title=&quot;Command management&quot; x=&quot;86&quot; y=&quot;31&quot;&gt;
    	   &lt;mx:Form defaultButton=&quot;{valideButton}&quot; verticalGap=&quot;20&quot;&gt;
    	        &lt;mx:FormItem label=&quot;User Name&quot;&gt;
    	            &lt;mx:TextInput id=&quot;userName&quot; styleName=&quot;textLogin&quot; width=&quot;172&quot;/&gt;
    	        &lt;/mx:FormItem&gt;
    	        &lt;mx:FormItem label=&quot;Command Number&quot;&gt;
    	            &lt;mx:TextInput id=&quot;commandeId&quot; width=&quot;172&quot;/&gt;
    	        &lt;/mx:FormItem&gt;
    	        &lt;mx:FormItem horizontalAlign=&quot;right&quot; width=&quot;100%&quot;&gt;
    	            &lt;mx:Button id=&quot;valideButton&quot; label=&quot;Validate&quot;/&gt;
    	        &lt;/mx:FormItem&gt;
    	    &lt;/mx:Form&gt;
    &lt;/mx:Panel&gt;
&lt;/mx:Application&gt;
</pre><p>Le résultat:</p><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator1.swf" width="520" height="242" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator1.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator1.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator1.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
width="520" height="242" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator1.swf"/><br
/> </object></div><p>Dans cet exemple, nous utilisons 2 validateurs (<code>StringValidator</code> et <code>CustomNumberValidator</code>). Au passage, afin d&#8217;utiliser notre validateur nous avons défini un namespace (<code>xmlns:validation="validation.*"</code>)<br
/> En ce qui concerne notre validateur, nous retrouvons nos attributs (<code>minLength</code>, <code>maxLength</code> et <code>lengthFieldError</code>) que nous avons renseignés.</p><h4><a
name="Amliorationdelavalidation"></a>Amélioration de la validation</h4><p>Améliorons notre processus de validation. En effet, pour le moment nous avons les messages d&#8217;erreurs lors du remplissage des champs du formulaire (un Tooltip s&#8217;affiche en cas d&#8217;erreur). Nous allons faire en sorte d&#8217;avoir également ces messages lors du click sur le bouton « Validate ».</p><p><code>XebiaValidator2.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
                xmlns:validation=&quot;validation.*&quot;
                layout=&quot;absolute&quot;
                width=&quot;520&quot; height=&quot;242&quot;
                initialize=&quot;this.fillValidators()&quot;&gt;
    &lt;mx:Script&gt;
        &lt;![CDATA[
            import mx.events.ValidationResultEvent;
            import mx.controls.Alert;
            import mx.core.Application;
            import mx.validators.Validator;
            public var validatorsList:Array;
            public function fillValidators() : void {
                this.validatorsList = new Array();
                this.validatorsList.push(
                userNameValidator,
                commandValidator);
            }
           public function validateForm():void {
            	var validationErrors:Array = Validator.validateAll(this.validatorsList);
                var isValidForm:Boolean = (validationErrors.length == 0);
                if (isValidForm) {
                    Alert.show(&quot;Validation OK&quot;);
                } else {
                	this.onValidationErrors(validationErrors);
                }
            }
            public function onValidationErrors(errors:Array):void  {
            	var error:ValidationResultEvent;
                var messages:Array = [];
                for each (error in errors) {
                    messages.push(error.message);
                }
                Alert.show(messages.join(&quot;n&quot;),
                		   &quot;ERROR&quot;,
                		   Alert.OK);
            }
        ]]&gt;
    &lt;/mx:Script&gt;
    &lt;mx:StringValidator id=&quot;userNameValidator&quot;
		        source=&quot;{userName}&quot;
		        property=&quot;text&quot;
		        requiredFieldError=&quot;User Name can not be empty !&quot;/&gt;
    &lt;validation:CustomNumberValidator id=&quot;commandValidator&quot;
        source=&quot;{commandeId}&quot;
        property=&quot;text&quot;
        minLength=&quot;4&quot;
        maxLength=&quot;20&quot;
        domain=&quot;int&quot;
        required=&quot;true&quot;
        lengthFieldError=&quot;Number command has to be between 4 and 20 digits&quot;/&gt;
    &lt;mx:Panel title=&quot;Command management&quot; x=&quot;86&quot; y=&quot;31&quot;&gt;
    	   &lt;mx:Form defaultButton=&quot;{valideButton}&quot; verticalGap=&quot;20&quot;&gt;
    	        &lt;mx:FormItem label=&quot;User Name&quot;&gt;
    	            &lt;mx:TextInput id=&quot;userName&quot; styleName=&quot;textLogin&quot; width=&quot;172&quot;/&gt;
    	        &lt;/mx:FormItem&gt;
    	        &lt;mx:FormItem label=&quot;Command Number&quot;&gt;
    	            &lt;mx:TextInput id=&quot;commandeId&quot; width=&quot;172&quot;/&gt;
    	        &lt;/mx:FormItem&gt;
    	        &lt;mx:FormItem horizontalAlign=&quot;right&quot; width=&quot;100%&quot;&gt;
    	            &lt;mx:Button id=&quot;valideButton&quot; label=&quot;Validate&quot; click=&quot;this.validateForm()&quot;/&gt;
    	        &lt;/mx:FormItem&gt;
    	    &lt;/mx:Form&gt;
    &lt;/mx:Panel&gt;
&lt;/mx:Application&gt;
</pre><p>Le résultat:</p><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator2.swf" width="520" height="242" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator2.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator2.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator2.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
width="520" height="242" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/05/xebiavalidator2.swf"/><br
/> </object></div><p>Dans ce fichier, du code <code>ActionScript</code> a fait son apparition. Dans un premier temps la méthode <code>fillValidators()</code>, appelée lors de l&#8217;initialisation du composant, remplit une liste composée des validateurs référencés par leurs id.</p><p>Par la suite, lors du clic sur « Validate », la méthode <code>validateForm()</code> est appelée. La classe <code>Validator</code> possède une méthode très pratique qui est <code>validateAll()</code>, prenant en paramètre une liste de validateurs. Cette méthode renvoie un tableau vide si la validation a réussi, et sinon il y aura des éléments de type <code>ValidationResultEvent</code> contenant le message que nous affichons. Dans notre exemple, en cas d&#8217;erreurs les messages apparaîtront dans une popup.</p><p>A travers ces deux exemples, nous voyons que le mécanisme de validation de Flex est assez simple, et écrire ses propres validateurs devient un jeu d&#8217;enfant !</p><p>Vous pouvez télécharger les sources sur le <a
href="http://code.google.com/p/xebia-france/source/browse/trunk/flex/XebiaFlex/" title="SVN de Xebia France" >SVN de Xebia France</a>.</p><div
class="shr-publisher-2021"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F05%2F20%2Fecrire-son-validateur-flex%2F' data-shr_title='Ecrire+son+validateur+Flex'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F05%2F20%2Fecrire-son-validateur-flex%2F' data-shr_title='Ecrire+son+validateur+Flex'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/05/20/ecrire-son-validateur-flex/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Flex, BlazeDS et Spring Security : The FlexSession is invalid</title><link>http://blog.xebia.fr/2009/03/12/flex-blazeds-et-spring-security-the-flexsession-is-invalid/</link> <comments>http://blog.xebia.fr/2009/03/12/flex-blazeds-et-spring-security-the-flexsession-is-invalid/#comments</comments> <pubDate>Thu, 12 Mar 2009 12:56:13 +0000</pubDate> <dc:creator>Nicolas Jozwiak</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[BlazeDS]]></category> <category><![CDATA[Flex]]></category> <category><![CDATA[Spring Security]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=1600</guid> <description><![CDATA[Lors du développement d&#8217;une application, j&#8217;ai été confronté à un problème avec l&#8217;intégration de BlazeDS et de Spring Security. En effet lorsque je me connectais, je pouvais accéder à l&#8217;application. Mais lorsque je fermais, ouvrais le navigateur puis me reconnectais, une erreur apparaissait : flex.messaging.LocalizedException: The FlexSession is invalid. at flex.messaging.FlexSession.checkValid(FlexSession.java:906) at flex.messaging.FlexSession.getUserPrincipal(FlexSession.java:225) at flex.messaging.HttpFlexSession.getUserPrincipal(HttpFlexSession.java:272) [...]]]></description> <content:encoded><![CDATA[<p>Lors du développement d&#8217;une application, j&#8217;ai été confronté à un problème avec l&#8217;intégration de <a
href="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/">BlazeDS</a> et de <a
href="http://static.springframework.org/spring-security/site/">Spring Security</a>. En effet lorsque je me connectais, je pouvais accéder à l&#8217;application. Mais lorsque je fermais, ouvrais le navigateur puis me reconnectais, une erreur apparaissait :</p><pre class="brush: java; title: ; notranslate">
flex.messaging.LocalizedException: The FlexSession is invalid.
    at flex.messaging.FlexSession.checkValid(FlexSession.java:906)
    at flex.messaging.FlexSession.getUserPrincipal(FlexSession.java:225)
    at flex.messaging.HttpFlexSession.getUserPrincipal(HttpFlexSession.java:272)
    at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:327)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1097)
    at com.wavecom.ui.util.AddToMDCFilter.doFilter(AddToMDCFilter.java:68)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378)
</pre><p>En se tournant vers la <a
href="http://livedocs.adobe.com/blazeds/1/blazeds_devguide/" title="documentation de BlazeDS" >documentation de <em>BlazeDS</em></a>, nous voyons que celui-ci n&#8217;est pas capable d&#8217;invalider lui-même des sessions <em>HTTP</em>. Il est cependant possible d&#8217;utiliser un paramètre dans les propriétés des <em>channels</em> afin d&#8217;invalider une session:</p><pre class="brush: xml; title: ; notranslate">
&lt;invalidate-session-on-disconnect&gt;true&lt;/invalidate-session-on-disconnect&gt;
</pre><p>Mais malgré cette option l&#8217;erreur restait présente&#8230; étrange.</p><p>Après quelques recherches plus poussées (merci Google), je suis tombé sur les problèmes liés aux <a
href="http://www.owasp.org/index.php/Session_Fixation" title="Session Fixation" >Session Fixation</a> et sur <a
href="http://www.blackpepper.co.uk/black-pepper-blog/printblog.html?index_php?view=article&#038;id=151&#038;tmpl=component&#038;print=1" title="cet article" >cet article</a>.<br
/> En effet, en creusant un peu plus, nous voyons dans la <a
href="http://static.springsource.org/spring-security/site/reference/html/ns-config.html" title="documentation de configuration de Spring" >documentation de configuration de <em>Spring</em></a> :</p><blockquote><p>&laquo;&nbsp;Session fixation attacks are a potential risk where it is possible for a malicious attacker to create a session by accessing a site, then persuade another user to log in with the same session (by sending them a link containing the session identifier as a parameter, for example).&nbsp;&raquo;</p></blockquote><p>Afin de contrer cela, <em>Spring</em> a pris le parti de créer une nouvelle session à chaque authentification d&#8217;un utilisateur.<br
/> Nous pouvons ainsi comprendre le problème. En effet, nous utilisons un channel <em>HTTP</em> et une instance de la classe <cod>HttpFlexSession</code> (<code>flex.messaging.HttpFlexSession</code>) contenant des attributs dont une <code>Map</code> de <code>flexSession</code>. Cette <code>Map</code> contient les id de session des utilisateurs. A la première connexion, cette instance récupère une requête avec un id session qui sera placé dans cette <code>Map</code>. Et lors de la deuxième connexion, la requête contiendra un autre id session. Le problème est que l'instance de <code>HttpFlexSession</code> va rechercher l'id session de la deuxième connexion dans la <code>Map</code> mais ne la trouvera pas, d'où l'exception citée ci-dessus.</p><p>Néanmoins, il existe une solution : mettre le paramètre <code>session-fixation-protection</code> à <code>none</code> dans votre fichier de configuration <em>Spring</em></p><pre class="brush: xml; title: ; notranslate">
&lt;security:http auto-config=&quot;true&quot; access-denied-page=&quot;/&quot; session-fixation-protection=&quot;none&quot;&gt;
</pre><p>Avec cette solution, la session ne sera pas systématiquement recréée et l'exception ne sera plus présente ! En espérant que cette solution puisse aider d'autres personnes !</p><div
class="shr-publisher-1600"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F03%2F12%2Fflex-blazeds-et-spring-security-the-flexsession-is-invalid%2F' data-shr_title='Flex%2C+BlazeDS+et+Spring+Security+%3A+The+FlexSession+is+invalid'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F03%2F12%2Fflex-blazeds-et-spring-security-the-flexsession-is-invalid%2F' data-shr_title='Flex%2C+BlazeDS+et+Spring+Security+%3A+The+FlexSession+is+invalid'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/03/12/flex-blazeds-et-spring-security-the-flexsession-is-invalid/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>GWT Galaxy</title><link>http://blog.xebia.fr/2009/01/23/gwt-galaxy/</link> <comments>http://blog.xebia.fr/2009/01/23/gwt-galaxy/#comments</comments> <pubDate>Fri, 23 Jan 2009 16:36:32 +0000</pubDate> <dc:creator>Romain Maton</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[GWT]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=1384</guid> <description><![CDATA[Vous avez peut-être assisté au Paris JUG sur GWT et vous vous êtes forcément dit en sortant de la conférence qu&#8217;il fallait absolument vous mettre à GWT. En plus, le pas à franchir n&#8217;est pas énorme : c&#8217;est du Java (ça devrait aller), agrémenté de nombreuses librairies comme dans le monde J2EE, des libraires graphiques [...]]]></description> <content:encoded><![CDATA[<p>Vous avez peut-être assisté au <a
href="http://www.parisjug.org/xwiki/bin/view/Meeting/20081104" title="Paris JUG" >Paris JUG</a> sur GWT et vous vous êtes forcément dit en sortant de la conférence qu&#8217;il fallait absolument vous mettre à GWT. En plus, le pas à franchir n&#8217;est pas énorme : c&#8217;est du Java (ça devrait aller), agrémenté de nombreuses librairies comme dans le monde J2EE, des libraires graphiques qui en jettent sont disponibles&#8230; Que d&#8217;avantages ! Mais par où commencer ?<br
/> Nous allons donc faire un tour d&#8217;horizon non exhaustif, mais balayant une grande partie de ce qui est utilisé dans la galaxie GWT : les plugins, les frameworks et les APIs générales et graphiques.</p><h3><a
name="volutionsdulangage"></a>Évolutions du langage</h3><p>Petit rappel : la toute première version de GWT (1.0) est sortie le 17 mai 2006. Oui, il y a seulement 2 ans et demi ! De nombreuses versions se sont suivies pour arriver à une version 1.4 (fin août 2007) stable et très complète, permettant de démarrer sereinement nos projets.<br
/> Mais voilà, fin août 2008 (1 an plus tard, la plus longue période entre 2 releases), la communauté GWT était en ébullition : en effet, l&#8217;importante version 1.5 pointa son nez apportant un lot de nouveautés assez importantes.<br
/> De nombreux articles nous exposent parfaitement ces nouveautés du langage ; on pourra se diriger sur le <a
href=" http://googlewebtoolkit.blogspot.com/2008/08/gwt-15-now-available.html" title="Blog de GWT" >Blog de GWT</a>, sur <a
href="http://www.infoq.com/news/2008/08/gwt-15" title="InfoQ" >InfoQ</a> ou chez <a
href=" http://blog.octo.com/index.php/2008/09/15/142-gwt-15-est-sorti" title="Octo" >Octo</a>.<br
/> Un rapide résumé donnerait :</p><ol><li>Enfin du Java en version 5 : annotations, generics, enhanced loop, autoboxing, import static&#8230;</li><li>Generics ? Donc nos <code>@gwt.typeArgs</code> sont terminés !</li><li>JRE Emulation beaucoup plus large avec entre autres les très attendues <code>TreeMap</code>, <code>LinkedHashMap</code> et autres <code>StringBuilder</code></li><li>Compilateur beaucoup plus rapide</li><li>Widgets plus complets et plus rapides</li></ol><p>En bref : que du bon !</p><h3><a
name="Plugins"></a>Plug-ins</h3><h4><a
name="ahrefhttpwwwinstantiationscomg"></a><a
href="http://www.instantiations.com/gwtdesigner/download.html" title="GWT Designer" >GWT Designer</a></h4><p>Plugin de type WYSIWYG. Il permet entre autres :</p><ul><li>la création de projet GWT, de module, de service et de librairie,</li><li>génération du service Async <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ,</li><li>la palette de widgets (intégrée dans une vue multi-onglets Design et Source),</li><li>ajout d&#8217;événements et modification des propriétés d&#8217;un composant dans les onglets Event et Properties,</li><li>Compilateur et Hosted Mode intégrés au projet (Builder Eclipse, menu « Run As&#8230; »),</li><li>drag and drop côté Design qui met automatiquement le « Source » à jour.</li></ul><p>À noter qu&#8217;il faudra, au-delà de la période d&#8217;essai, une <a
href="http://www.instantiations.com/gwtdesigner/purchase.html" title="licence annuelle ou perptuelle" >licence annuelle ou perpétuelle</a> pour continuer à l&#8217;utiliser.</p><h4><a
name="ahrefhttpwwwwirelexsoftcomVist"></a><a
href="http://www.wirelexsoft.com/VistaFei.html" title="VistaFei" >VistaFei</a></h4><p>Environnement de développement (qui s&#8217;appuie sur Eclipse 3.2) intégrant toute sorte de plugins spécialement conçus pour GWT. Il propose :</p><ul><li>la création de projet, de module (GWTView) et de service,</li><li>un WYSIWYG (très similaire à celui de GWT Designer) séparant l&#8217;onglet « Properties » de la vue « Design »,</li><li>la génération de code depuis la « GWTView »,</li><li>l&#8217;internationalisation aussi générée.</li></ul><p>Son utilisation est gratuite avec la licence « Community Edition ».</p><h4><a
name="ahrefhttpwwwjetbrainscomideafe"></a><a
href="http://www.jetbrains.com/idea/features/gwt.html" title="IntelliJ IDEA" >IntelliJ IDEA</a></h4><p>Un plugin GWT intégré à l&#8217;IDE très abouti :</p><ul><li>création de projet, de module et de service,</li><li>compilateur de projet,</li><li>complétion Javascript dans une méthode native (non, vous ne rêvez pas !!!),</li><li>quick-fix spécifiques GWT (votre code Java est correct mais il ne compilera pas, oubli de l&#8217;interface « IsSerializable », utilisation d&#8217;une librairie non émulée&#8230;), remplacement des @gwt.typeArgs&#8230;,</li><li>navigation rapide entre les méthodes synchrones et asynchrones.</li></ul><p>Le plugin est intégré à l&#8217;IDE de JetBrains, il faudra donc mettre la main à la poche pour <a
href="http://www.jetbrains.com/idea/buy/index.jsp" title="obtenir une licence" >obtenir une licence</a> à moins de vous lancer dans un projet Open Source.</p><h4><a
name="ahrefhttpwwwcypalinstudiotitle"></a><a
href="http://www.cypal.in/studio" title="Cypal Studio" >Cypal Studio</a></h4><p>Le plugin que tout développeur GWT anti-WYSIWYG a dans son IDE !</p><ul><li>création de module, de service et d&#8217;exemple (sample),</li><li>compilateur intégré au projet (« builder » Eclipse),</li><li>lancement du Hosted Mode.</li></ul><p>Simple mais efficace, ce produit est disponible gratuitement.</p><h3><a
name="Frameworks"></a>Frameworks</h3><h4><a
name="ahrefhttpcodegooglecompgwtmave"></a><a
href="http://code.google.com/p/gwt-maven/" title="GWTMaven" >GWT-Maven</a></h4><p>De nombreuses commandes maven adaptées à GWT sont disponibles, on notera parmi les plus intéressantes :</p><ul><li>Lancement du Hosted Mode (Tomcat, noserver, debug&#8230;),</li><li>Compilation GWT,</li><li>Lancement des tests unitaires GWT,</li><li>Génération des interfaces pour l&#8217;internationalisation,</li><li>Création de WAR GWT,</li><li>Création de JAR GWT.</li></ul><h4><a
name="ahrefhttpnoongileadfreefrgilea"></a><a
href="http://noon.gilead.free.fr/gilead/" title="Gilead" >Gilead</a> (anciennement <a
href="http://hibernate4gwt.sourceforge.net/" title="Hibernate4GWT" >Hibernate4GWT</a>)</h4><p>L&#8217;un des gros problèmes rencontrés au démarrage de GWT est l&#8217;utilisation des POJOs Hibernate côté client.<br
/> Je vous renvoie vers le très bon <a
href="http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur/" title="article d'Amin Fathallah (Xebia)" >article d&#8217;Amin Fathallah (Xebia)</a> qui détaille très bien les problèmes rencontrés.<br
/> Ainsi, Gilead nous permet d&#8217;utiliser nos POJOs Hibernate directement côté client sans aucun mapping Dozer !</p><h4><a
name="ahrefhttpgwtwidgetsourceforgen"></a><a
href="http://gwt-widget.sourceforge.net/" title="Spring" >Spring</a></h4><p>Accessible par les librairies <a
href=" http://gwt-widget.sourceforge.net/?q=node/51#GWTSpringController" title="GWTSL et  GWTWL" >GWT-SL et  GWT-WL</a>, il est tout à fait possible d&#8217;utiliser Spring dans un projet GWT.<br
/> Le principal changement est que les services ne sont plus définis en tant que servlets dans le <em>web.xml</em>. Ils sont remplacés par la classe <em> DispatcherServlet</em> de Spring qui pilotera l&#8217;application.<br
/> On notera aussi les classes GWTController et GWTHandler, cœur de GWT-SL, permettant de wrapper intégralement nos actions et nos services.</p><h4><a
name="ahrefhttpsajaxjsfdevjavanetnon"></a><a
href="https://ajax4jsf.dev.java.net/nonav/ajax/gwt/gwt-cdk.html" title="G4JSF" >G4JSF</a></h4><p>L&#8217;adaptation de JSF dans le monde GWT. Même mécanisme que pour le SpringController i.e. que l&#8217;on aura des interfaces/classes à implémenter/étendre au lieu des classes GWT standard, les principales étant ComponentEntryPoint et GwtFacesServiceAsync.<br
/> Le tutoriel de référence pour l&#8217;intégration de JSF avec GWT se trouve sur <a
href="http://www.theserverside.com/tt/articles/article.tss?l=GWTandJSF" title="The Server Side" >The Server Side</a>.</p><h3><a
name="APIsgraphiques"></a>APIs graphiques</h3><p>Le tour d&#8217;horizon continue avec les APIs graphiques.<br
/> Chaque composant ne sera pas détaillé à outrance, seuls certains seront cités pour donner un aperçu général de ce qui est proposé (détail complet sur les sites officiels respectifs de chaque librairie).</p><h4><a
name="ahrefhttpgwtgooglecomsamplesSh"></a><a
href="http://gwt.google.com/samples/Showcase/Showcase.html" title="Widgets Core (démo)" >Widgets Core (démo)</a></h4><p>Premier réflexe avec tout ce que l&#8217;on entend sur GWT : foncer sur la première librairie de composants graphiques à la mode !<br
/> Mais n&#8217;oublions pas toutefois que GWT propose en standard des widgets haut niveau très complets :</p><ul><li>Boutons : basique, checkbox, radio, custom&#8230;,</li><li>Listes : basique, suggest, arbre, menu&#8230;,</li><li>Text : basique et riche (à la <em>word</em>),</li><li>Popups,</li><li>Panels : décorateur, horizontal, vertical, dock, disclosure, onglet&#8230;,</li><li>Tables : tableau standard et flex.</li></ul><h4><a
name="ahrefhttpcodegooglecompgwtextt"></a><a
href="http://code.google.com/p/gwt-ext/" title="GWT-Ext" >GWT-Ext</a> (<a
href=" http://www.gwt-ext.com/demo/" title="dmo" >démo</a>)</h4><p>Certainement la librairie graphique la plus répandue.<br
/> Wrapping complet de l&#8217;API <a
href="http://extjs.com/" title="ExtJS" >ExtJS</a> dans sa version 2.0.2.<br
/> L&#8217;API ne contient donc quasiment que des classes dont les méthodes font une redirection native vers le code Javascript d&#8217;ExtJS.<br
/> On retrouvera donc tout ce qui se fait dans ExtJS avec des composants très puissants comme :</p><ul><li>Arbres : éditable, drag &#038; drop (arbre vers arbre ou tableau), tri, checkbox&#8230;,</li><li>Layouts : horizontal, vertical, accordéon&#8230;,</li><li>Liste : basique, listes liées, live (suggest), paginé&#8230;,</li><li>Tableau : éditable, tableaux groupés, JSON ou XML, chargement local ou distant, checkbox&#8230;,</li><li>Formulaire : à onglets, fieldset, multi-colonnes, binding avec un tableau&#8230;,</li><li>Éléments redimensionnables, déplaçables&#8230;</li><li>Widgets bien stylés et des thèmes out-of-the-box</li></ul><p>Le point noir reste toutefois la Javadoc, même si celle-ci s&#8217;étoffe au fur et à mesure des sorties de GWT-Ext (gros efforts fournis entre les versions 2.0.2 et 2.0.5). Elle reste cependant insuffisante. On pourra tout de même se retourner sur la doc d&#8217;ExtJS (puisque ce n&#8217;est que du pur wrapping) mais dès que l&#8217;on souhaitera aller un peu plus loin avec les composants, il faudra mettre les mains dans le <strike>cambouis</strike> Javascript.</p><h4><a
name="ahrefhttpextjscomproductsgxtti"></a><a
href="http://extjs.com/products/gxt/" title="Ext-GWT" >Ext-GWT</a> (<a
href="http://extjs.com/explorer/" title="dmo" >démo</a>)</h4><p>Le produit de la compagnie <a
href=" http://extjs.com/products/gxt/" title="ExtJS" >ExtJS</a> adapté à GWT.<br
/> Ext-GWT prend le parti de tout réécrire en pur GWT i.e. il n&#8217;y a aucun Javascript externe, tout est en Java.<br
/> Autre atout, l&#8217;API utilise les mécanismes internes de GWT permettant une intégration standard des fonctionnalités comme le remote service en Callback, retour JSON, XML&#8230; mais aussi du Java 5 (generics, enums et varargs).<br
/> On retrouve, sans surprise, les mêmes composants que pour GWT-Ext.<br
/> A noter enfin <a
href="http://extjs.com/products/license.php" title="3 licences" >3 licences</a> disponibles pour le produit (commercial, open source ou revendeur).</p><h4><a
name="ahrefhttpcodegooglecompsmartgw"></a><a
href="http://code.google.com/p/smartgwt/" title="Smart-GWT" >Smart-GWT</a> (<a
href="http://www.smartclient.com/smartgwt/showcase/" title="dmo" >démo</a>)</h4><p><a
href="http://www.jroller.com/sjivan/entry/smartgwt_1_0_released" title="Sanjiv Jivan" >Sanjiv Jivan</a> a encore frappé !<br
/> Après son wrapping complet d&#8217;ExtJS avec GWT-Ext, il s&#8217;attaque cette fois-ci à la librairie <a
href="http://www.smartclient.com/" title="SmartClient" >SmartClient</a> avec sa nouvelle API <a
href="http://www.smartclient.com/smartgwt/showcase/" title="SmartGWT" >SmartGWT</a> (nous vous en parlions dans une précédente <a
href="http://blog.xebia.fr/2008/12/01/revue-de-presse-xebia-85/#SortiedeSmartGWT" title="revue de presse" >revue de presse</a>).<br
/> Le wrapping est encore une fois très complet : tous les composants de SmartClient sont présents dont :</p><ul><li>Arbre : colonne bloquée, drag &#038; drop entre de nombreux composants, data binding multiples&#8230;,</li><li>Slider, effects, animations, dialogs, look &#038; feel, &#8230;</li><li>Tableau : filtres, interactions avancées, &#8230;</li><li>Tile (<a
href="http://www.smartclient.com/smartgwt/showcase/#featured_tile_filtering" title="dmo" >démo</a>),</li><li>Liste-Tableau, Calendrier (à la <em>outlook</em>), load on demand, &#8230;</li></ul><p>On retrouvera aussi, et sans surprise, la plupart des composants combobox, radio, field, &#8230; d&#8217;autres librairie du même type.</p><h4><a
name="ahrefhttprialtoimprovetechnolo"></a><a
href="http://rialto.improve-technologies.com/wiki/rialtogwt" title="Rialto-GWT" >Rialto-GWT</a> (<a
href="http://rialto.improve-technologies.com/Rialto-GWT-Demo/" title="dmo" >démo</a>)</h4><p>De même que pour Ext-GWT, Rialto-GWT dans sa version <a
href="http://rialto.improve-technologies.com/wiki/rialtogwt/download" title="20" >2.0</a> nous propose d&#8217;utiliser GWT 1.5 donc Java 5.<br
/> L&#8217;API utilise aussi les mécanismes internes à GWT, le Wrapping Javascript est présent mais l&#8217;abstraction avec les classes Java rend l&#8217;utilisation très simple.<br
/> A noter toutefois une Javadoc de composants peu fournie&#8230;<br
/> Les composants principaux sont proches de ceux d&#8217;Ext-GWT.</p><h4><a
name="ahrefhttpcodegooglecomptatamit"></a><a
href="http://code.google.com/p/tatami/" title="Tatami (Dojo)" >Tatami (Dojo)</a> (<a
href="http://tatami.googlecode.com/svn/trunk/site/samples/TatamiDemo/index.html" title="dmo" >démo</a>)</h4><p>Encore une célèbre librairie Javascript porté en GWT : <a
href="http://dojotoolkit.org/" title="Dojo" >Dojo</a> !<br
/> Une fois de plus, on retrouve le support de GWT 1.5, des tableaux en tout genre, des sliders, des pickers&#8230;</p><h4><a
name="Autres"></a>Autres&#8230;</h4><p>D&#8217;autres librairies/codes sont disponibles sur la plupart des sites d&#8217;informations GWT, on trouvera ainsi quelques wrapper <a
href="http://script.aculo.us/" title="Script.aculo.us" >Script.aculo.us</a> (<a
href="http://gwt.components.googlepages.com/script.aculo.usintegration" title="ici" >ici</a> ou <a
href="http://labs.pathf.com/GWTaculous/" title="là" >là</a>) mais aussi des wrapper <a
href="http://jquery.com/" title="jQuery" >jQuery</a> (avec entre autre <a
href="http://code.google.com/p/gwtquery/" title="GQuery" >GQuery</a>).</p><div
align="center"> <object
type="application/x-shockwave-flash" data="http://widget-44.slide.com/widgets/slideticker.swf" height="450" width="600" style="width:600px;height:450px"><param
name="movie" value="http://widget-44.slide.com/widgets/slideticker.swf" /><param
name="quality" value="high" /><param
name="scale" value="noscale" /><param
name="salign" value="l" /><param
name="wmode" value="transparent"/><param
name="flashvars" value="cy=ms&#038;il=1&#038;channel=3458764513824714820&#038;site=widget-44.slide.com"/></object></div><h3><a
name="APIsgnrales"></a>APIs générales</h3><h4><a
name="ahrefhttpgwtgooglecomsamplesSh"></a><a
href="http://gwt.google.com/samples/Showcase/Showcase.html#CwMessagesExample" title="I18N" >I18N</a></h4><p>GWT gère nativement l&#8217;internationalisation, donc pas de librairies externes pour cette fonctionnalité.<br
/> L&#8217;utilisation est simple :</p><ul><li>un fichier properties contenant toutes nos clés,</li><li>des interfaces (<em>I18NConstants</em>, <em>I18NMessages</em>&#8230;) Java permettant de faire appel à ces clés,</li><li>une entrée dans notre module.gwt.xml avec si besoin la locale par défaut,</li><li>une locale pouvant être définie au runtime, dans la JSP ou dans l&#8217;URL.</li></ul><h4><a
name="ahrefhttpcodegooglecompgwtlogt"></a><a
href="http://code.google.com/p/gwt-log/" title="Logs" >Logs</a> (<a
href="http://allen-sauer.com/com.allen_sauer.gwt.log.demo.LogDemo/LogDemo.html" title="demo" >demo</a>)</h4><p>Un logger côté client très complet avec différents niveaux de logs : <em>info</em>, <em>warn</em>, <em>debug</em>, <em>error</em> et <em>fatal</em>.<br
/> De nombreux loggers sont disponibles comme le <em>ConsoleLogger</em>, le <em>GWTLogger</em> ou bien encore le <em>FireBugLogger</em>.</p><h4><a
name="ahrefhttpcodegooglecompgwtgoog"></a><a
href="http://code.google.com/p/gwt-google-apis/" title="Google API" >Google API</a></h4><p>Gears, gadgets, Ajax Search et Maps, voici ce que propose la librairie de Google.<br
/> À noter que Visualization est en release candidate.</p><h4><a
name="ahrefhttpcodegooglecompgwtmath"></a><a
href="http://code.google.com/p/gwt-math/" title="Maths" >Maths</a></h4><p>Émulation de <em>BigInteger</em> et <em>BigDecimal</em> avec un grand nombre de méthodes (<em>add</em>, <em>subtract</em>, <em>multiply</em>, <em>divide</em>, <em>abs</em>, <em>negate</em>, <em>compareTo</em>, <em>equals</em>, <em>toString</em>&#8230;).</p><h4><a
name="Etbiendautresencore"></a>Et bien d&#8217;autres encore !</h4><p>A chercher/récupérer au besoin <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p><p>On pourra rapidement citer <a
href="http://code.google.com/p/gwteventservice/" title="GWTEventService" >GWTEventService</a> (qui permet entre autre de faire du pushing / comet), <a
href="http://trac.puremvc.org/PureMVC_Java_MultiCore/" title="PureMVC" >PureMVC</a> (MVC pour GWT) ou bien encore <a
href="http://code.google.com/p/goda-time/" title="GodaTime" >Goda-Time</a> (Joda-Time pour GWT !).</p><h3><a
name="Conclusion"></a>Conclusion</h3><p>Ce petit tour d&#8217;horizon de la galaxie GWT nous permet de retenir 3 choses : <em>vous avez dit galaxie ?</em>, <em>[Mode gros doutes] Tu penses que c&#8217;est possible ?</em> et enfin <em>ça ressemble vraiment à un puzzle cette techno&#8230;</em>.</p><p>Galaxie ? On peut se poser la question dans le sens où, si l&#8217;on creuse un peu, on trouve en effet quelques APIs très bien faites&#8230; mais elles sont tout de même rares ! Après plus de 2 ans d&#8217;existence, on a tout de même l&#8217;impression que cette techno se cherche encore et que, du coup, la communauté J2EE n&#8217;a pas encore confiance en GWT pour démarrer ses projets. Ce manque d&#8217;API robuste ne fera que renforcer cette tendance.</p><p>Est-ce possible ? Réponse : Google est ton ami <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> Très peu de sites (comme par exemple <a
href="http://www.ongwt.com/" title="onGWT" >onGWT</a>)  référencent ce qui se fait en GWT au niveau des outils, des frameworks&#8230; Il devient assez laborieux de <em>trouver</em> une API pour un besoin spécifique. N&#8217;oublions pas que GWT émule les packages java.util, java.lang et java.io. Suffisant pour certains projets, mais pour de grosses applications de gestion il en faudra d&#8217;autres&#8230;</p><p>Un puzzle ! C&#8217;est certainement ce qui ressort le plus des projets GWT. Les librairies se récupèrent <em>à droite, à gauche</em> sur Google, il y en a partout avec peu de référencement&#8230; GWT devrait peut-être intégrer directement des APIs reconnues qui ont fait leurs preuves (comme par exemple <a
href="http://www.jcp.org/en/jsr/detail?id=310" title="Java 7 avec JodaTime" >Java 7 avec Joda-Time</a>)&#8230;</p><p>Autrement dit, et c&#8217;est aussi une des conclusions de <a
href="http://www.manning.com/hanson/" title="GWT in Action" >GWT in Action</a>, GWT permet de développer très facilement des applications <em>Ajax</em> sans forcément connaitre Javascript (tout en laissant la possibilité de coder directement en Javascript). Il y a bien sûr encore des choses à revoir/améliorer mais le langage est en très bonne voie et les librairies existantes font le travail demandé.</p><p>Cependant, devez-vous foncer tête baissée sur GWT car vous démarrez un nouveau projet Web / Ajax et vous ne savez pas quelle technologie choisir (<em>GWT</em>, <em>Flex</em>, <em>Silverlight</em>, <em>JavaFX</em>&#8230;) ? Impossible de répondre de manière générale pour tous les projets, cela dépend du back-end existant, des besoins du projet, du temps imparti&#8230; Sachez en tout cas que GWT est un excellent compromis entre Ajax, Java et Javascript et que personnellement, sur les projets auxquels j&#8217;ai participé, je ne regrette absolument pas son utilisation !</p><div
class="shr-publisher-1384"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F01%2F23%2Fgwt-galaxy%2F' data-shr_title='GWT+Galaxy'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F01%2F23%2Fgwt-galaxy%2F' data-shr_title='GWT+Galaxy'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/01/23/gwt-galaxy/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Les évènements dans des composants Flex réutilisables</title><link>http://blog.xebia.fr/2009/01/09/les-evenements-dans-des-composants-flex-reutilisables/</link> <comments>http://blog.xebia.fr/2009/01/09/les-evenements-dans-des-composants-flex-reutilisables/#comments</comments> <pubDate>Fri, 09 Jan 2009 15:10:18 +0000</pubDate> <dc:creator>Ellène Dijoux</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Flex]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=1277</guid> <description><![CDATA[Dans un précédent article, nous vous présentions comment créer des composants Flex réutilisables. Nous allons ici poursuivre la présentation en vous parlant de la gestion des évènements au sein de ces composants. En effet, il n&#8217;est pas évident de gérer les évènements lorsque ceux-ci sont dans des fichiers MXML différents. Alors comment faire ? Une [...]]]></description> <content:encoded><![CDATA[<p>Dans un <a
href="http://blog.xebia.fr/2008/11/20/creer-des-composants-flex-reutilisables/" title="prcdent article" >précédent article</a>, nous vous présentions comment créer des composants Flex réutilisables. Nous allons ici poursuivre la présentation en vous parlant de la <strong>gestion des évènements</strong> au sein de ces composants. En effet, il n&#8217;est pas évident de gérer les évènements lorsque ceux-ci sont dans des fichiers MXML différents. Alors comment faire ?</p><p>Une solution existe, utiliser les tags <code>Metadata</code> et plus précisemment le tag <code>Event</code>. Dans <a
href="http://blog.xebia.fr/2008/11/20/creer-des-composants-flex-reutilisables/" title="lexemple du billet prcdent" >l&#8217;exemple du billet précédent</a>, nous avons créé plusieurs composants pour mettre en place un formulaire. Nous allons effectuer le même exercice, avec une liste de contacts dans laquelle il est possible d&#8217;ajouter des utilisateurs. Nous verrons comment deux composants indépendants l&#8217;un de l&#8217;autre pourront <strong>communiquer</strong> et <strong>échanger des données</strong>.</p><p>Ce billet se découpe de la façon suivante :</p><ul><li>Nous commencerons par <a
href="http://blog.xebia.fr/2009/01/09/les-evenements-dans-des-composants-flex-reutilisables#Miseenplacedescomposantsrutili">mettre en place les composants réutilisables</a> qui formeront l&#8217;application</li><li>Nous expliquerons <a
href="http://blog.xebia.fr/2009/01/09/les-evenements-dans-des-composants-flex-reutilisables#QuestcequuntagMetadata">ce qu&#8217;est un tag <code>Metadata</code></a></li><li>Nous présenterons <a
href="http://blog.xebia.fr/2009/01/09/les-evenements-dans-des-composants-flex-reutilisables#Etconcrtement">comment les mettre en place</a> sur notre exemple</li><li>Et enfin, nous verrons <a
href="http://blog.xebia.fr/2009/01/09/les-evenements-dans-des-composants-flex-reutilisables#Rsultat">le résultat</a></li></ul><h3><a
name="Miseenplacedescomposantsrutili"></a>Mise en place des composants réutilisables</h3><p>Pour créer notre application, nous allons mettre en place :</p><ul><li><code>ContactListView</code> : une liste de contacts contenant une <code>Datagrid</code> et un bouton <em>Ajouter</em></li></ul><pre class="brush: xml; title: ; notranslate">
&lt;mx:VBox xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
	width=&quot;400&quot; height=&quot;300&quot;
	horizontalAlign=&quot;center&quot;&gt;
	&lt;mx: DataGrid width=&quot;100%&quot; height=&quot;100%&quot; dataProvider=&quot;{contacts}&quot;&gt;
		&lt;mx:columns&gt;
			&lt;mx: DataGridColumn headerText=&quot;Nom et prénoms&quot;/&gt;
		&lt;/mx:columns&gt;
	&lt;/mx: DataGrid&gt;
	&lt;mx:Button label=&quot;Ajouter&quot;/&gt;
&lt;/mx:VBox&gt;
</pre><ul><li><code>ContactFormView</code> : un formulaire contenant un champ texte nom, un autre prénom et deux boutons <em>Valider</em> et <em>Annuler</em></li></ul><pre class="brush: xml; title: ; notranslate">
&lt;mx:VBox xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; width=&quot;400&quot; height=&quot;300&quot;&gt;
	&lt;mx:Form width=&quot;100%&quot; height=&quot;100%&quot;&gt;
		&lt;mx:FormItem label=&quot;Nom&quot; width=&quot;100%&quot;&gt;
			&lt;mx:TextInput width=&quot;100%&quot; id=&quot;lastName&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem label=&quot;Prénom&quot; width=&quot;100%&quot;&gt;
			&lt;mx:TextInput width=&quot;100%&quot; id=&quot;firstName&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem width=&quot;100%&quot;&gt;
			&lt;mx:HBox width=&quot;100%&quot; horizontalAlign=&quot;right&quot;&gt;
				&lt;mx:Button label=&quot;Valider&quot;/&gt;
				&lt;mx:Button label=&quot;Annuler&quot;/&gt;
			&lt;/mx:HBox&gt;
		&lt;/mx:FormItem&gt;
	&lt;/mx:Form&gt;
&lt;/mx:VBox&gt;
</pre><p>Ils seront stockés dans une pile de vues ({{ViewStack}}). Le composant <code>ViewStack</code> contient des vues filles dans lesquelles il est possible de naviguer. Seule une vue fille peut être affichée à la fois grâce à la propriété <code>selectedItem</code> ou <code>selectedIndex</code>. En manipulant ce composant, nous allons tenter de passer d&#8217;une vue à l&#8217;autre en modifiant la valeur de <code>selectedIndex</code>.<br
/> - <code>selectedIndex = 0</code> : le <code>ViewStack</code> affiche <code>ContactListView</code><br
/> - <code>selectedIndex = 1</code> : le <code>ViewStack</code> affiche <code>ContactFormView</code></p><pre class="brush: xml; title: ; notranslate">
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; layout=&quot;absolute&quot;&gt;
	&lt;mx:ViewStack id=&quot;viewStack&quot;&gt;
		&lt;view:ContactListView id=&quot;contactListView&quot;/&gt;
		&lt;view:ContactFormView id=&quot;contactFormView&quot;/&gt;
	&lt;/mx:ViewStack&gt;
&lt;/mx:Application&gt;
</pre><p>Lorsque l&#8217;utilisateur clique sur le bouton <em>Ajouter</em>, l&#8217;application change de vue pour passer sur le formulaire. Les boutons <em>Valider</em> et <em>Annuler</em> quant à eux permettent de revenir sur la première vue.</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2009/01/shematestcontact.png" border="0" alt="" /></div><p>La partie graphique est en place mais comment signaler à la pile de vue de passer de l&#8217;une à l&#8217;autre ? Effectivement depuis une vue, comment peut-on signaler à son parent qu&#8217;il s&#8217;est passé quelque chose ?</p><p>C&#8217;est là que les tags <code>Metadata</code> viennent à notre secours.</p><h3><a
name="QuestcequuntagMetadata"></a>Qu&#8217;est ce qu&#8217;un tag <code>Metadata</code> ?</h3><p>Un tag <code>Metadata</code> fournit au compilateur des informations sur la façon dont le composant MXML est utilisé dans une application Flex. Il existe 12 tags <code>Metadata</code> documentés dont entre autres <code>Bindable</code>, <code>Embed</code>, <code>Effect</code> et celui que nous allons utilisé <code>Event</code>. Le tag <code>Event</code> permet de définir des évènements que le composant concerné peut déclencher, ce qui convient très bien à notre problème.</p><h3><a
name="Etconcrtement"></a>Et concrètement ?</h3><h4><a
name="Ctdclencheur"></a>Côté déclencheur</h4><p>Créons un tag <code>Event</code> dans notre vue <code>ContactListView</code>:</p><pre class="brush: xml; title: ; notranslate">
&lt;mx:Metadata&gt;
    [Event(name=&quot;addContact&quot;, type=&quot;flash.events.Event&quot;)]
&lt;/mx:Metadata&gt;
</pre><p>Lorsque l&#8217;utilisateur clique sur le bouton <em>Ajouter</em>, le composant déclenche l&#8217;évènement <code>addContact</code>.</p><pre class="brush: xml; title: ; notranslate">
&lt;mx:Script&gt;
	&lt;![CDATA[
        import mx.collections.ArrayCollection;
	[Bindable]
	private var contacts:ArrayCollection;
        private function onClick():void{
	        // on dispatche un nouvel évènement
	        // qui sera intercepté ici par le composant parent
	        dispatchEvent(new Event(&quot;addContact&quot;));
        }
	]]&gt;
&lt;/mx:Script&gt;
&lt;mx: DataGrid width=&quot;100%&quot; height=&quot;100%&quot; dataProvider=&quot;{contacts}&quot;&gt;
	&lt;mx:columns&gt;
		&lt;mx: DataGridColumn headerText=&quot;Nom et prénoms&quot;/&gt;
	&lt;/mx:columns&gt;
&lt;/mx: DataGrid&gt;
&lt;mx:Button label=&quot;Ajouter&quot; click=&quot;onClick()&quot;/&gt;
</pre><h4><a
name="Ctabonn"></a>Côté abonné</h4><p>Le parent de la vue, qui est ici l&#8217;application, ajoute un listener sur la vue pour attendre l&#8217;évènement <code>addContact</code>. Une fois l&#8217;évènement déclenché, nous changeons de vue.</p><pre class="brush: xml; title: ; notranslate">
&lt;mx:Script&gt;
	&lt;![CDATA[
		import mx.collections.ArrayCollection;
		private function onAddContact(event:Event):void{
			// passage de la vue contenant la liste de contacts
			// à la vue d'ajout de contacts.
			viewStack.selectedIndex = 1;
		}
        ]]&gt;
&lt;/mx:Script&gt;
&lt;mx:ViewStack id=&quot;viewStack&quot;&gt;
	&lt;view:ContactListView id=&quot;contactListView&quot; addContact=&quot;onAddContact(event)&quot;/&gt;
	&lt;view:ContactFormView id=&quot;contactFormView&quot;/&gt;
&lt;/mx:ViewStack&gt;
</pre><h3><a
name="Rsultat"></a>Résultat</h3><p>En faisant de même avec les boutons <em>Valider</em> et <em>Annuler</em>, nous arrivons au résultat suivant:</p><div
align="center"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2009/01/contacttest.swf" height="300" width="400" type="application/x-shockwave-flash" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2009/01/contacttest.swf" /><param
name="loop" value="false" /><param
name="menu" value="false" /><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2009/01/contacttest.swf" /><param
name="quality" value="high" /><param
name="scale" value="exactfit" /><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2009/01/contacttest.swf" /><param
name="type" value="application/x-shockwave-flash" /><embed
height="300" width="400" quality="high" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash" src="http://blog.xebia.fr/wp-content/uploads/2009/01/contacttest.swf" type="application/x-shockwave-flash" /><br
/> </object></div><p>Ce billet présente un exemple très simple d&#8217;utilisation du tag <code>Event</code> avec un évènement de type <code>flash.events.Event</code>. Mais vous pouvez créer vos propres classes d&#8217;évènements comme le montre le <a
href="http://livedocs.adobe.com/flex/3/html/help.html?content=metadata_2.html" title="livedocs" >livedocs</a>. Le code source est disponible <a
href="http://code.google.com/p/xebia-france/source/browse/#svn/trunk/ContactTest" title="ici" >ici</a>, vous trouverez l&#8217;exemple complet avec la gestion de l&#8217;ajout d&#8217;un contact et le retour vers la liste.</p><h3><a
name="Rfrences"></a>Références</h3><p><a
href="http://livedocs.adobe.com/flex/3/html/help.html?content=metadata_2.html" title="http://livedocs.adobe.com/flex/3/html/help.html?content=metadata_2.html" >http://livedocs.adobe.com/flex/3/html/help.html?content=metadata_2.html</a></p><div
class="shr-publisher-1277"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F01%2F09%2Fles-evenements-dans-des-composants-flex-reutilisables%2F' data-shr_title='Les+%C3%A9v%C3%A8nements+dans+des+composants+Flex+r%C3%A9utilisables'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2009%2F01%2F09%2Fles-evenements-dans-des-composants-flex-reutilisables%2F' data-shr_title='Les+%C3%A9v%C3%A8nements+dans+des+composants+Flex+r%C3%A9utilisables'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/01/09/les-evenements-dans-des-composants-flex-reutilisables/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Créer des composants Flex réutilisables</title><link>http://blog.xebia.fr/2008/11/20/creer-des-composants-flex-reutilisables/</link> <comments>http://blog.xebia.fr/2008/11/20/creer-des-composants-flex-reutilisables/#comments</comments> <pubDate>Thu, 20 Nov 2008 15:21:27 +0000</pubDate> <dc:creator>Nicolas Jozwiak</dc:creator> <category><![CDATA[RIA]]></category> <category><![CDATA[Flex]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=1027</guid> <description><![CDATA[Dans les précédents articles sur Flex, nous avons vu la mise en place d&#8217;une galerie d&#8217;images ainsi que le drag and drop. Ce billet sera consacré à la création de composants Flex génériques et réutilisables. Nous prendrons comme exemple un formulaire classique permettant de gérer les permissions d&#8217;un utilisateur. Jeu de données &#60;mx:ArrayCollection id=&#34;countries&#34;&#62; &#60;mx:Object [...]]]></description> <content:encoded><![CDATA[<p>Dans les précédents articles sur Flex, nous avons vu la mise en place d&#8217;une <a
href="http://blog.xebia.fr/2008/05/14/galerie-dimages-flex/" title="galerie d'images" >galerie d&#8217;images</a> ainsi que <a
href="http://blog.xebia.fr/2008/06/19/drag-and-drop-flex/" title="le drag and drop" >le drag and drop</a>. Ce billet sera consacré à la création de composants Flex génériques et réutilisables. Nous prendrons comme exemple un formulaire classique permettant de gérer les permissions d&#8217;un utilisateur.</p><h4><a
name="Jeudedonnes"></a>Jeu de données</h4><pre class="brush: xml; title: ; notranslate">
&lt;mx:ArrayCollection id=&quot;countries&quot;&gt;
        &lt;mx:Object label=&quot;Germany&quot; data=&quot;0&quot;/&gt;
	&lt;mx:Object label=&quot;England&quot; data=&quot;1&quot;/&gt;
	&lt;mx:Object label=&quot;Spain&quot; data=&quot;2&quot;/&gt;
	&lt;mx:Object label=&quot;United States&quot; data=&quot;3&quot;/&gt;
	&lt;mx:Object label=&quot;France&quot; data=&quot;4&quot;/&gt;
	&lt;mx:Object label=&quot;India&quot; data=&quot;5&quot;/&gt;
	&lt;mx:Object label=&quot;Netherlands&quot; data=&quot;6&quot;/&gt;
&lt;/mx:ArrayCollection&gt;
&lt;mx:Array id=&quot;roles&quot;&gt;
      &lt;mx:Object label=&quot;Administrator&quot;/&gt;
      &lt;mx:Object label=&quot;Gold Customer&quot;/&gt;
      &lt;mx:Object label=&quot;Read only Customer&quot;/&gt;
      &lt;mx:Object label=&quot;Editor Customer&quot;/&gt;
      &lt;mx:Object label=&quot;Read only User&quot;/&gt;
      &lt;mx:Object label=&quot;Admin User&quot;/&gt;
&lt;/mx:Array&gt;
</pre><p>Nous créons deux listes (<code>id='countries'</code>, <code>id='roles'</code>) composées d&#8217;objets qui ont comme attribut <code>label</code>.</p><h4><a
name="Formulaire"></a>Formulaire</h4><p><code>XebiaForm1.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
		layout=&quot;absolute&quot; width=&quot;522&quot; height=&quot;338&quot;&gt;
        &lt;mx: Panel title=&quot;Gestion des utilisateurs&quot;&gt;
	    &lt;mx:Form&gt;
		&lt;mx:FormItem label=&quot;Login&quot;&gt;
		     &lt;mx:TextInput width=&quot;182&quot; id=&quot;login&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem label=&quot;Password&quot;&gt;
		     &lt;mx:TextInput width=&quot;182&quot; id=&quot;password&quot; displayAsPassword=&quot;true&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem label=&quot;Country&quot;&gt;
		     &lt;mx:ComboBox id=&quot;country&quot; dataProvider=&quot;{countries}&quot; width=&quot;182&quot;
		        	  prompt=&quot;Select a Country&quot;
				  selectedIndex=&quot;-1&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem&gt;
		     &lt;mx:HBox width=&quot;400&quot; height=&quot;175&quot;&gt;
			&lt;mx:VBox width=&quot;50%&quot;&gt;
			    &lt;mx:Label text=&quot;Available Role&quot;/&gt;
                            &lt;mx:List id=&quot;roleProvider&quot; width=&quot;100%&quot;
    				     dataProvider=&quot;{roles}&quot;
 				     height=&quot;138&quot;
				     allowMultipleSelection=&quot;true&quot;
				     dragEnabled=&quot;true&quot;
				     dropEnabled=&quot;true&quot;
                                     dragMoveEnabled=&quot;true&quot;/&gt;
			&lt;/mx:VBox&gt;
			&lt;mx:VBox width=&quot;50%&quot;&gt;
			    &lt;mx:Label text=&quot;Selected Role&quot;/&gt;
			    &lt;mx:List id=&quot;roleSelected&quot; width=&quot;100%&quot;
                                     height=&quot;138&quot;
				     dropEnabled=&quot;true&quot;
				     dragEnabled=&quot;true&quot;
				     dragMoveEnabled=&quot;true&quot;/&gt;
			&lt;/mx:VBox&gt;
		     &lt;/mx:HBox&gt;
		&lt;/mx:FormItem&gt;
	&lt;/mx:Form&gt;
&lt;/mx: Panel&gt;
&lt;/mx:Application&gt;
</pre><p>Nous avons un composant Panel dans lequel se trouve un <code>Form</code> composé de <code>FormItem</code>. Ce formulaire possède :</p><ul><li>Un champ texte pour le login.</li><li>Un champ texte pour le password.</li><li>Une liste déroulante pour les pays.</li><li>Deux listes : la première propose les permissions, et la seconde accueille les permissions accordées à l&#8217;utilisateur.</li></ul><p>En ce qui concerne les attributs des deux listes pour le drag and drop, vous trouverez les détails dans <a
href="http://blog.xebia.fr/2008/06/19/drag-and-drop-flex/" title="ce billet" >ce billet</a>.</p><p>Le résultat :</p><div
align="center"> <object
classid="clsid:\D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform1.swf" height="338" type="application/x-shockwave-flash" width="522" ><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform1.swf"/><param
name="loop" value="false"/><param
name="menu" value="false"/><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform1.swf"/><param
name="quality" value="high"/><param
name="scale" value="exactfit"/><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform1.swf"/><param
name="type" value="application/x-shockwave-flash"/><embed
height="338" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" quality="high" src="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform1.swf" type="application/x-shockwave-flash" width="522" /><br
/> </object></div><p>Imaginons maintenant que nous ayons besoin de la liste des pays et des permissions dans d&#8217;autres écrans. Comment faire pour réutiliser ce même code ? Flex propose un mécanisme très simple afin de pouvoir « créer ses propres composants ».</p><h4><a
name="Formulairesimplifi"></a>Formulaire simplifié</h4><p>Dans un premier temps, nous allons créer notre composant pour la liste déroulante :</p><p><code>ComboCountry.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;mx:ComboBox xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; prompt=&quot;Select a Country&quot; selectedIndex=&quot;-1&quot;&gt;
	&lt;mx:dataProvider&gt;
		&lt;mx:ArrayCollection&gt;
			&lt;mx:Object label=&quot;Germany&quot; data=&quot;0&quot;/&gt;
			&lt;mx:Object label=&quot;England&quot; data=&quot;1&quot;/&gt;
			&lt;mx:Object label=&quot;Spain&quot; data=&quot;2&quot;/&gt;
			&lt;mx:Object label=&quot;United States&quot; data=&quot;3&quot;/&gt;
			&lt;mx:Object label=&quot;France&quot; data=&quot;4&quot;/&gt;
			&lt;mx:Object label=&quot;India&quot; data=&quot;5&quot;/&gt;
			&lt;mx:Object label=&quot;Netherlands&quot; data=&quot;6&quot;/&gt;
		&lt;/mx:ArrayCollection&gt;
	&lt;/mx:dataProvider&gt;
&lt;/mx:ComboBox&gt;
</pre><p>Lorsque vous créez un composant, vous devez lui indiquer le namespace (ici le préfixe <code>mx</code> et comme nom <code>http://www.adobe.com/2006/mxml</code>). Vous remarquerez que la liste des pays est directement incluse dans le composant <code>ComboBox</code> grâce à la propriété <code>dataProvider</code>. Néanmoins, il est possible d&#8217;écrire ce composant de la manière suivante :</p><pre class="brush: xml; title: ; notranslate">
&lt;mx:ComboBox xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; prompt=&quot;Select a Country&quot; selectedIndex=&quot;-1&quot;
             dataProvider=&quot;{countries}&quot;&gt;
	&lt;mx:ArrayCollection id=&quot;countries&quot;&gt;
		&lt;mx:Object label=&quot;Germany&quot; data=&quot;0&quot;/&gt;
		&lt;mx:Object label=&quot;England&quot; data=&quot;1&quot;/&gt;
		&lt;mx:Object label=&quot;Spain&quot; data=&quot;2&quot;/&gt;
		&lt;mx:Object label=&quot;United States&quot; data=&quot;3&quot;/&gt;
		&lt;mx:Object label=&quot;France&quot; data=&quot;4&quot;/&gt;
		&lt;mx:Object label=&quot;India&quot; data=&quot;5&quot;/&gt;
		&lt;mx:Object label=&quot;Netherlands&quot; data=&quot;6&quot;/&gt;
	&lt;/mx:ArrayCollection&gt;
&lt;/mx:ComboBox&gt;
</pre><p>De la même manière que la liste déroulante, les deux listes permettant de « drag and droper » les permissions peuvent être externalisées dans un composant :</p><p><code>ListPerm.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;mx:HBox xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; width=&quot;400&quot;
 	 height=&quot;175&quot;&gt;
	&lt;mx:Array id=&quot;roles&quot;&gt;
          &lt;mx:Object label=&quot;Administrator&quot;/&gt;
          &lt;mx:Object label=&quot;Gold Customer&quot;/&gt;
          &lt;mx:Object label=&quot;Read only Customer&quot;/&gt;
          &lt;mx:Object label=&quot;Editor Customer&quot;/&gt;
          &lt;mx:Object label=&quot;Read only User&quot;/&gt;
          &lt;mx:Object label=&quot;Admin User&quot;/&gt;
        &lt;/mx:Array&gt;
 	&lt;mx:VBox width=&quot;50%&quot;&gt;
           &lt;mx:Label text=&quot;Available Role&quot;/&gt;
           &lt;mx:List id=&quot;roleProvider&quot; dataProvider=&quot;{roles}&quot; width=&quot;100%&quot;
                    height=&quot;138&quot;
                    allowMultipleSelection=&quot;true&quot;
                    dragEnabled=&quot;true&quot;
                    dropEnabled=&quot;true&quot;
		    dragMoveEnabled=&quot;true&quot;/&gt;
        &lt;/mx:VBox&gt;
        &lt;mx:VBox width=&quot;50%&quot;&gt;
            &lt;mx:Label text=&quot;Selected Role&quot;/&gt;
            &lt;mx:List id=&quot;roleSelected&quot; width=&quot;100%&quot; height=&quot;138&quot;
                     dropEnabled=&quot;true&quot;
                     dragEnabled=&quot;true&quot;
		     dragMoveEnabled=&quot;true&quot;/&gt;
	&lt;/mx:VBox&gt;
&lt;/mx:HBox&gt;
</pre><p>Maintenant que ces deux composants ont été externalisés, nous pouvons les intégrer dans le formulaire :</p><p><code>XebiaForm2.mxml</code></p><pre class="brush: xml; title: ; notranslate">
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
		xmlns:myComponent=&quot;myComponents.*&quot;
		layout=&quot;absolute&quot; width=&quot;522&quot; height=&quot;338&quot;&gt;
	&lt;mx: Panel title=&quot;Gestion des utilisateurs&quot;&gt;
	   &lt;mx:Form&gt;
	        &lt;mx:FormItem label=&quot;Login&quot;&gt;
		   &lt;mx:TextInput width=&quot;182&quot; id=&quot;login&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem label=&quot;Password&quot;&gt;
		   &lt;mx:TextInput width=&quot;182&quot; id=&quot;password&quot; displayAsPassword=&quot;true&quot;/&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:FormItem label=&quot;Country&quot;&gt;
		    &lt;myComponent:ComboCountry width=&quot;182&quot; id=&quot;country&quot;/&gt;
		&lt;/mx:FormItem&gt;
	        &lt;mx:FormItem&gt;
	            &lt;myComponent:ListPerm id=&quot;listRoles&quot;/&gt;
		&lt;/mx:FormItem&gt;
	    &lt;/mx:Form&gt;
	&lt;/mx: Panel&gt;
&lt;/mx:Application&gt;
</pre><p>On remarquera que nous avons ajouté un namespace afin de pouvoir utiliser nos composants :</p><pre class="brush: xml; title: ; notranslate">
xmlns:myComponent=&quot;myComponents.*&quot;
</pre><p>Cela signifie que nous pouvons utiliser nos deux composants se situant dans le package <code>myComponents</code>, et ayant comme préfixe <code>myComponent</code> :</p><pre class="brush: xml; title: ; notranslate">
&lt;myComponent:ComboCountry width=&quot;182&quot; id=&quot;country&quot;/&gt;
&lt;myComponent:ListPerm id=&quot;listRoles&quot;/&gt;
</pre><p>Ainsi, pour utiliser nos composants nous déclarons le préfixe, ainsi que le nom de ce dernier (égal au nom_du_composant.mxml).</p><p>Le résultat :</p><div
align="center"> <object
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" data="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform2.swf" height="338" width="522" type="application/x-shockwave-flash"><param
name="data" value="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform2.swf"/><param
name="loop" value="false"/><param
name="menu" value="false"/><param
name="movie" value="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform2.swf"/><param
name="quality" value="high"/><param
name="scale" value="exactfit"/><param
name="src" value="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform2.swf"/><param
name="type" value="application/x-shockwave-flash"/><embed
height="338" pluginspage="https://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" quality="high" src="http://blog.xebia.fr/wp-content/uploads/2008/11/xebiaform2.swf" type="application/x-shockwave-flash" width="522" /><br
/> </object></div><p>À travers ce billet, nous avons pu voir que la création de composants Flex est vraiment très simple, permettant d&#8217;avoir un code plus clair, mieux structuré et d&#8217;avoir des composants réutilisables !</p><p>Vous pouvez télécharger les sources sur le <a
href="http://code.google.com/p/xebia-france/source/browse/trunk/flex/XebiaFlex/" title="SVN de Xebia France" >SVN de Xebia France</a>.</p><h4><a
name="Rfrences"></a>Références</h4><ul><li><a
href="http://livedocs.adobe.com/flex/3/html/help.html?content=Part4_CreateComps_1.html">http://livedocs.adobe.com/flex/3/html/help.html?content=Part4_CreateComps_1.html</a></li></ul><div
class="shr-publisher-1027"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2008%2F11%2F20%2Fcreer-des-composants-flex-reutilisables%2F' data-shr_title='Cr%C3%A9er+des+composants+Flex+r%C3%A9utilisables'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2008%2F11%2F20%2Fcreer-des-composants-flex-reutilisables%2F' data-shr_title='Cr%C3%A9er+des+composants+Flex+r%C3%A9utilisables'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/11/20/creer-des-composants-flex-reutilisables/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>RIA Contest : Flex / Silverlight / GWT / Echo3 / JavaFX</title><link>http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/</link> <comments>http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/#comments</comments> <pubDate>Fri, 03 Oct 2008 14:23:19 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[Echo 3]]></category> <category><![CDATA[Flex]]></category> <category><![CDATA[GWT]]></category> <category><![CDATA[JavaFX]]></category> <category><![CDATA[Silverlight]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=733</guid> <description><![CDATA[Après le Xebia Web Framework Contest de l&#8217;année dernière, le thème du XKE du mois d&#8217;Octobre était un nouveau contest dédié aux RIA. Le but de cette journée était de développer une application de gestion de playlist de morceaux de musique. En promoteurs des méthodes Agiles, les spécifications furent données sous forme d&#8217;un Product Backlog. [...]]]></description> <content:encoded><![CDATA[<p>Après le <a
href="http://blog.xebia.fr/2007/10/26/xebia-web-framework-contest/" title="Xebia Web Framework Contest" >Xebia Web Framework Contest</a> de l&#8217;année dernière, le thème du <a
href="http://blog.xebia.fr/tag/xke/" title="XKE" >XKE</a> du mois d&#8217;Octobre était un nouveau <em>contest</em> dédié aux <a
href="http://fr.wikipedia.org/wiki/Rich_Internet_Application" title="RIA" >RIA</a>.</p><p>Le but de cette journée était de développer une application de gestion de playlist de morceaux de musique. En promoteurs des méthodes Agiles, les spécifications furent données sous forme d&#8217;un Product Backlog. Trois sprints d&#8217;une durée de 90 minutes ont permis à tous de suivre l&#8217;évolution des différentes réalisations. Un web service SOAP fournissait les différentes données: Artiste, Album, Titres et Pochettes d&#8217;album.</p><h3><a
name="LesframeworksRIAtests"></a>Les frameworks RIA testés</h3><p>Cinq équipes ont été constituées, cinq frameworks ont donc été choisis :</p><ul><li><a
href="http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/#Flex" title="Flex 3" >Flex 3</a></li><li><a
href="http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/#Silverlight" title="Silverlight 2.0 beta 2" >Silverlight 2.0 beta 2</a></li><li><a
href="http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/#GoogleGWT" title="Google GWT 1.5" >Google GWT 1.5</a></li><li><a
href="http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/#Echo" title="Echo3" >Echo3</a></li><li><a
href="http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/#JavaFX" title="JavaFX Preview SDK" >JavaFX Preview SDK</a></li></ul><p>Le nombre d&#8217;équipes étant limité, la liste des frameworks choisis l&#8217;est aussi, et nous avons donc nécessairement mis de côté certains frameworks qui auraient certainement eu leur place dans le contest. Citons par exemple <a
href="http://extjs.com/" title="Ext JS" >Ext JS</a>, <a
href="http://developer.yahoo.com/yui/" title="Yahoo! UI" >Yahoo! UI</a>, <a
href="http://www.curl.com/" title="Curl" >Curl</a>, <a
href="http://www.mozilla.org/projects/xul/" title="XUL" >XUL</a>, <a
href="http://www.zkoss.org/" title="ZK" >ZK</a> ou <a
href="http://www.openlaszlo.org/" title="OpenLaszlo" >OpenLaszlo</a>. Si vous avez une expérience sur un de ces frameworks, n&#8217;hésitez pas à la partager dans les commentaires de cet article!</p><p>Au terme de cette journée, chaque équipe a pu exprimer un retour d&#8217;expérience significatif, que vous trouverez ci-dessous.</p><h3><a
name="ProductBacklog"></a>Product Backlog</h3><table><tr><td
bgcolor="#663366" style="color: #ffffff; border: 1px solid black"><strong> Priorité</td><td
bgcolor="#663366" style="color: #ffffff; border: 1px solid black"><strong> Nom</td></tr><tr><td
style="border: 1px solid black"> 10</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux visualiser la liste des catégories</td></tr><tr><td
style="border: 1px solid black"> 20</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux visualiser la liste des artistes</td></tr><tr><td
style="border: 1px solid black"> 30</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux consulter la liste des albums d&#8217;une catégorie</td></tr><tr><td
style="border: 1px solid black"> 40</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux consulter la liste des albums d&#8217;un artiste</td></tr><tr><td
style="border: 1px solid black"> 45</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux consulter la liste des pistes d&#8217;un album</td></tr><tr><td
style="border: 1px solid black"> 50</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux rechercher un album</td></tr><tr><td
style="border: 1px solid black"> 60</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux consulter la liste des playlists enregistrées</td></tr><tr><td
style="border: 1px solid black"> 70</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux charger une playlist existante</td></tr><tr><td
style="border: 1px solid black"> 80</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux créer et enregistrer une nouvelle playlist</td></tr><tr><td
style="border: 1px solid black"> 90</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux ajouter des pistes à une playlist</td></tr><tr><td
style="border: 1px solid black"> 95</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux réordonner les pistes d&#8217;une playlist</td></tr><tr><td
style="border: 1px solid black"> 97</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux enlever des pistes à une playlist</td></tr><tr><td
style="border: 1px solid black"> 100</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux sauvegarder une playlist</td></tr><tr><td
style="border: 1px solid black"> 110</td><td
style="border: 1px solid black"> En tant qu&#8217;utilisateur, je peux supprimer une playlist</td></tr></table><h3><a
name="Flex"></a>Flex</h3><p>Le premier sprint a été consacré :</p><ul><li>A la création du layout de l&#8217;interface, à l&#8217;aide du langage MXML. Pour cette étape, Flex Builder a été d&#8217;une aide précieuse et nous a permis d&#8217;être productif.</li><li>A la mise en place du proxy SOAP et de la &#8216;<code>destination</code>&#8216; vers le web service du backend. Pour ce faire nous avons utilisé <a
href="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS" title="BlazeDS" >BlazeDS</a>. Vous pouvez trouver <a
href="http://learn.adobe.com/wiki/display/Flex/Creating+a+BlazeDS+web+service+application+in+Flex+Builder" title="sur le wiki d'Adobe" >sur le wiki d&#8217;Adobe</a> un exemple d&#8217;utilisation du proxy BlazeDS.</li></ul><p>Le second sprint a été l&#8217;occasion de :</p><ul><li>Mettre en place le binding entre les résultats d&#8217;invocation des web services et le layout (cliquez <a
href="http://www.adobe.com/devnet/flex/quickstart/using_data_binding/" title="ici" >ici</a> pour une description du mécanisme de databinding dans Flex)</li><li>De mettre en place la gestion des événements.</li></ul><p>Arrivée au troisième et dernier sprint, l&#8217;équipe était très à l&#8217;aise avec <a
href="http://www.adobe.com/fr/products/flex/" title="Flex 3" >Flex</a>. Celui-ci a donc été l&#8217;occasion de compléter les fonctionnalités et très rapidement de refondre l&#8217;interface et d&#8217;y ajouter un ensemble d&#8217;effets visuels.</p><h4><a
name="Pointsforts"></a>Points forts</h4><ul><li>Facilité de prise en main: le coût d&#8217;entrée pour un développeur d&#8217;applications web Java est réduit, les composants MXML sont simples à utiliser, et le langage ActionScript se rapproche fortement de JavaScript (ils implémentent tous deux la spécification <a
href="http://fr.wikipedia.org/wiki/ECMAScript" title="ECMAScript" >ECMAScript</a>)</li><li>Richesse des composants <em>(nombreux composants de haut niveau)</em> (<a
href="http://examples.adobe.com/flex3/componentexplorer/explorer.html" title="voir le component explorer Flex 3" >voir le component explorer Flex 3</a>)</li><li>Communauté active : facilité de trouver des ressources de qualité <em>(exemples, tutoriels, mailing lists)</em> sur le web.</li></ul><h4><a
name="Pointsfaibles"></a>Points faibles</h4><ul><li>Flex Builder ne propose pas de compilation à la volée du code mxml (peut être dû à un souci sur notre environnement de développement)</li><li>Tester notre code directement dans Flex Builder n&#8217;est pas possible sans déploiement (mais un simple serveur Apache ou Tomcat fait l&#8217;affaire)</li><li>L&#8217;adaptation au modèle documentaire Adobe (style javadoc) n&#8217;est pas sans douleur</li></ul><h3><a
name="Silverlight"></a>Silverlight</h3><p>Version Microsoft de l&#8217;approche RIA à base de plugins, Silverlight permet l&#8217;exécution d&#8217;applications web riches au sein de moteur de rendu vectoriel. Avec l&#8217;arrivée de <a
href="http://silverlight.net/" title="Silverlight 2.0 beta 2" >Silverlight 2</a>, Microsoft enrichit de façon notable sa technologie et rattrape son retard sur ses concurrents.</p><p>Même si elle propose une intégration forte et séduisante avec les technologies DotNet, Silverlight ne se reste pas pour autant limité à celles-ci. C&#8217;est d&#8217;ailleurs dans ce contexte de cohabitation particulier, FrontEnd Silverlight / BackEnd Java, que le contest s&#8217;est déroulé.</p><h4><a
name="Pointsforts"></a>Points forts</h4><ul><li>Silverlight utilise un descripteur d&#8217;interface utilisateur en XAML, dérivée de fichier XML pour définir son UI. Contrairement à ses concurrents, ce format est directement interprété par le plugin, aucune compilation n&#8217;est nécessaire, facilitant ainsi le déploiement et le débogage. De plus, ces fichiers .xaml sont directement packagés dans des archives .XAP (donc ZIP) qui permet d&#8217;espérer une indexation aisée des éléments statiques par nos moteurs de recherches préférés.</li><li>Il est ensuite possible de scripter ces UI en utilisant soit le langage Javascript, soit n&#8217;importe quel langage supporté par .net (C# par exemple). Vous écrivez donc du C# sur la partie cliente de la même façon que sur la partie serveur.</li><li>Une application Silverlight ne requiert pas forcément de backend server.</li><li>Visuellement, Silverlight nous permet d&#8217;ajouter des effets et des animations proches de ce que fait Flex.</li><li>Prise en main plutôt facile, dès le 1er sprint (1h30) on avait un début d&#8217;interface (sans compter le temps de l&#8217;installation)</li></ul><h4><a
name="Pointsfaibles"></a>Points faibles</h4><ul><li>Manque flagrant de maturité par rapport à son rival. Silverlight devrait sortir de sa version bêta sous peu.</li><li>Installation longue et complexe pour des développeurs non familiers avec la technologie .net : .net framework, Visual Studio Pro et son extension Silverlight pour faciliter la programmation, et Expression Blend pour faciliter la création d&#8217;interfaces. Il est d&#8217;ailleurs rageant d&#8217;avoir à utiliser un outil séparé pour créer ses écrans. En outre l&#8217;éditeur de composant de Visual Studio n&#8217;est pas assez puissant, il ressemble plus à une preview qu&#8217;à un véritable éditeur WYSIWYG</li><li>XAML peut devenir rapidement volumineux (même si nous présumons que nous avons mal développé nos composants). L&#8217;exemple Microsoft dont nous nous sommes inspiré utilise par exemple 5 à 10 formes de base pour un simple bouton.</li><li>Si la communication avec un backend .net semble aisée, il n&#8217;en est pas de même pour un backend Java. Silverlight nous permet, sur le papier, de nous connecter très facilement via Webservices ou la technologie REST (un simple clic droit, ajoutez un service web semble suffisant). Dans la réalité, nous n&#8217;avons jamais réussi à communiquer avec notre backend Webservice Java généré par CXF. D&#8217;autre part, Silverlight ne possède pas de protocole binaire permettant d&#8217;optimiser les échanges.</li><li>Linux est supporté via Moonlight, mais on peut craindre que l&#8217;implémentation Linux n&#8217;ait toujours une longueur de retard par rapport aux releases Windows et Mac. D&#8217;autre part, qu&#8217;en est-il du plugin Silverlight sur téléphone mobile si le téléphone ne fonctionne pas sur Windows Mobile?</li><li>Silverlight fonctionne uniquement dans un navigateur, il n&#8217;existe pas d&#8217;équivalent à Adobe AIR pour Silverlight.</li></ul><p>Tous ces points négatifs doivent être tempérés, n&#8217;oublions pas qu&#8217;il ne s&#8217;agit que d&#8217;une version bêta!</p><h3><a
name="GoogleGWT"></a>Google GWT</h3><p><a
href="http://code.google.com/webtoolkit/" title="Google GWT 1.5" >Google Web Toolkit</a> propose une approche différente des autres frameworks RIA :</p><ul><li>Tout d&#8217;abord le développeur réalise l&#8217;interface graphique entièrement en Java en utilisant les API fournies par GWT.</li><li>Ensuite, avec les outils GWT, le code précédemment produit est parsé afin de générer l&#8217;équivalent en HTML et Javascript.</li></ul><p>L&#8217;objectif premier de GWT est de confier la réalisation d&#8217;une application Web à un développeur Java, sans que ce dernier n&#8217;ait à maîtriser les particularités de fonctionnement des navigateurs : le compilateur GWT génère automatiquement, à partir du code Java, le code HTML/JavaScript adéquat et portable sur différents navigateurs.</p><p>Pour le RIA Contest, l&#8217;équipe GWT a utilisé : <a
href="http://code.google.com/webtoolkit/" title="GWT 1.5" >GWT 1.5</a> et la surcouche <a
href="http://code.google.com/p/gwt-ext/" title="GWT-ext-2.04" >GWT-ext-2.04</a></p><p>Grâce à GWT, le développement des fonctionnalités demandées a été réalisé assez rapidement. A l&#8217;issue des premiers sprints les 5 premières fonctionnalités ont été implémentées entièrement.</p><p>Pour l&#8217;équipe GWT, la principale cause de perte de temps est dûe à des composants GWT-ext. Certains composants GWT-ext ne fonctionnaient pas toujours de manière déterministe, sans compter leur prise en main difficile (exemple : l&#8217;arbre ou la liste). Finalement l&#8217;équipe GWT s&#8217;est retranchée sur les composants GWT (mieux documentés).</p><p>L&#8217;équipe GWT a appris une leçon au cours de ce RIA contest qui est de privilégier l&#8217;utilisation des composants fournis par GWT. D&#8217;une part ils fonctionnent très bien, et d&#8217;autre part ils sont simples d&#8217;utilisation. Même si le contexte de développement favorisait le développement sans conception, un refactoring a été réalisé très simplement grâce aux outils d&#8217;Eclipse (extraction de méthode, découpage de classe). L&#8217;équipe a pu pointer du doigt un point fort de GWT concernant la conception d&#8217;une interface graphique : une conception plus riche (conception par concept métier ou/et fonctionnalité de la page) par rapport au modèle classique MVC (type action, jsp).</p><h4><a
name="Pointsforts"></a>Points forts</h4><ul><li><strong>Compétences</strong> : tout le développement de l&#8217;interface est effectué en Java. De plus l&#8217;utilisation de Java 5 est un réel apport sur les versions antérieures de GWT. Cependant afin de personnaliser, améliorer le rendu et le rendre plus sexy, il est nécessaire de manipuler des feuilles de style CSS.</li><li><strong>Paradigme</strong> : Le modèle de programmation événementielle est très intuitif pour un développeur Java, et ce n&#8217;est pas sans rappeler la programmation Swing. Cependant GWT reste plus simple, car il n&#8217;y a pas l&#8217;aspect programmation concurrentielle et déploiement sur le poste client.</li><li><strong>Productivité</strong> : permet de développer une application RIA (1 écran) très rapidement. Le code produit est très maintenable (c&#8217;est du Java).</li><li><strong>Outillage</strong> : les outils fonctionnent correctement : script de génération du squelette de l&#8217;application, l&#8217;intégration avec Eclipse (Host Mode, debugging de la partie cliente et serveur)</li><li><strong>Bonne courbe d&#8217;apprentissage</strong> : les outils fournis par GWT sont d&#8217;une fiabilité remarquable. Cela permet de rapidement monter un projet &laquo;&nbsp;HelloWord&nbsp;&raquo; et de le lancer dans un navigateur (ou le GWTHost). De plus, le fait de manipuler du langage Java permet d&#8217;être directement productif.</li></ul><h4><a
name="Pointsfaibles"></a>Points faibles</h4><ul><li><strong>Pauvreté des composants</strong> : la librairie de composant GWT-ext n&#8217;est pas à la hauteur de GWT au niveau utilisabilité et robustesse. GWT doit encore travailler sur ses composants graphiques afin d&#8217;arriver au niveau de Flex. Vus les progrès sur ce point dans la version 1.5 de GWT et les bases solides du framework, on peut rester très optimiste sur l&#8217;amélioration de cet aspect.</li><li>Il y a des conventions de programmation qui empêchent le bon fonctionnement des outils de refactoring, comme par exemple le pattern d&#8217;appel asynchrone. De manière générale, on peut regretter que GWT ne tienne pas compte des bonnes pratiques acquises dans le développement d&#8217;applications en Java.</li><li><strong>Intégration</strong> : l&#8217;intégration dans l&#8217;existant n&#8217;est pas si facile tant au niveau des technologies qu&#8217;au niveau du packaging. Un exemple concret : comment intégrer de manière élégante un modèle métier existant comme modèle de données pour l&#8217;interface sans faire de <a
href="http://en.wikipedia.org/wiki/Data_Transfer_Object" title="DTO" >DTO</a>?</li><li>Une application plus complexe doit demander une bonne expertise du framework pour découper correctement les différents composants</li></ul><ul><li><strong>Mauvaise courbe de mise en œuvre</strong> : il y a des points un peu flous et des pièges à éviter. Par exemple, la mise en oeuvre d&#8217;un appel RPC demande de bien mettre en place la convention fixée par GWT, de même pour le binding d&#8217;objet.</li></ul><h3><a
name="Echo"></a>Echo3</h3><p><a
href="http://echo.nextapp.com/site/echo3" title="Echo3" >Echo</a> est une plateforme de type RIA orientée composant et évènement. La version 3 est aujourd&#8217;hui en beta 1. Cette version propose de développer soit directement côté client en javascript, soit côté serveur en Java.<br
/> L&#8217;API Server, utilisée pour le contest, permet de développer l&#8217;interface utilisateur dans une logique proche de Swing (Composants, Layout et évènementiel).</p><p>Le framework Echo se veut concurrent de GWT dans la mesure où il permet le développement d&#8217;applications entièrement server-side. Une particularité cependant est qu&#8217;il ne possède pas de phase de pré-compilation Java vers Javascript. Durant l&#8217;exécution l&#8217;état des composants est sérialisé puis envoyé vers le client qui effectue le rendu des composants grâce à la librairie Javascript de Echo.</p><p>Bien que méconnu, ce framework a été choisi comme challenger GWT. En effet, il en possède plusieurs aspects intéressants, comme le développement intégral server-side et la gestion de l&#8217;évènementiel. Mais l&#8217;absence de phase de précompilation Javascript et la simplicité d&#8217;intégration avec Maven sont des avantages qui nous ont tenté.</p><h4><a
name="Pointsforts"></a>Points forts</h4><ul><li><strong>Accessibilité</strong> : Facile à mettre en oeuvre et à déployer, quelques minutes suffisent pour obtenir une première application type &laquo;&nbsp;hello world&nbsp;&raquo;.</li><li><strong>Flexibilité</strong> : Possibilité de choisir son mode de développement, application server-side (développement 100% Java) ou client-side (développement 10% Java, 90% Javascript).</li><li><strong>Intégration</strong> : Echo s&#8217;appuie directement sur l&#8217;API servlet et ne nécessite rien de plus que le déploiement d&#8217;une application web avec sa servlet proprement configurée.</li><li><strong>HTML Agnostic</strong> : Aucune connaissance HTML, JavaScript ni CSS n&#8217;est nécessaire pour la conception d&#8217;une application.</li></ul><h4><a
name="Pointsfaibles"></a>Points faibles</h4><ul><li><strong>Documentation</strong> : seule existe la documentation officielle, qui est encore en cours d&#8217;écriture, et la javadoc est très limitée en commentaires.</li><li><strong>Contenu</strong> : Peu de composants &#8216;haut niveau&#8217; (pas de Datatable par exemple). On est obligé d&#8217;étendre l&#8217;existant pour obtenir des composants évolués. De plus, certaines fonctionnalités offertes par l&#8217;API ne sont pas encore implémentées au niveau du moteur de rendu (Echo3 est toujours en beta1).</li><li><strong>Communauté</strong> : Echo2 ne bénéficie déjà pas d&#8217;une grosse communauté, et Echo3 est en beta donc encore très peu utilisé.</li><li><strong>Eye candy</strong> : Il manque de précieux effets visuels (notamment le drag&#8217;n'drop) et des styles embarqués, permettant aux non-graphistes de facilement créer une jolie interface.</li></ul><h3><a
name="JavaFX"></a>Java FX</h3><p><a
href="http://www.sun.com/software/javafx/index.jsp" title="JavaFX" >JavaFX</a> est la réponse de Sun à Flex et aux autres frameworks RIA. Présenté il y a un an à la conférence <a
href="http://thegeekintheshell.blogspot.com/2007/07/java-one-2007-et-javafx.html" title="JavaOne 2007" >JavaOne 2007</a>, puis cette année encore à l&#8217;<a
href="http://www.lemagit.fr/article/sun-air-java-web2-0-ria/341/1/javaone-2008-javafx-invite-tardivement-table-des-ria/" title="édition 2008" >édition 2008</a>, JavaFX se fait attendre. Pour nous faire patienter, Sun a sorti une <a
href="http://blog.xebia.fr/2008/08/04/revue-de-presse-xebia-68/#JavaFXenprerelease" title="pre-release" >pre-release</a>, incluse avec <a
href="https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=netbeans-6.1-javafx-1.0-pre1-oth-JPR@CDS-CDS_Developer" title="NetBeans 6.1" >NetBeans 6.1</a>.</p><p>Les 2 premiers sprints ont été consacrés à la réalisation de l&#8217;IHM à l&#8217;aide du langage de script JavaFX. L&#8217;équipe a eu quelques difficultés à implémenter la première fonctionnalité, heureusement l&#8217;exemple de playlist de <a
href="http://learnjavafx.typepad.com/weblog/2008/08/tablenode-creat.html" title="James Weaver" >James Weaver</a> a été d&#8217;un grand secours. Le code est toutefois d&#8217;assez bas niveau puisque l&#8217;affichage d&#8217;un tableau se fait en dessinant des rectangles que l&#8217;on déplace pour représenter les lignes du tableau.</p><p>Passée cette mauvaise surprise, il fut très facile d&#8217;intégrer l&#8217;appel du webservice. En effet le script JavaFX permet d&#8217;appeler naturellement des classes Java, en l&#8217;occurrence CXF. La sérialisation / désérialisation étant réalisée par ce framework, la manipulation du XML est transparente, et il est aisé d&#8217;afficher les propriétés ad-hoc des objets vers le tableau.<br
/> Il fut plus délicat d&#8217;arriver à rafraîchir automatiquement les listes, mais une fois le binding compris et assimilé, là aussi cela se fait de manière transparente.</p><p>Le dernier sprint a été l&#8217;occasion d&#8217;essayer quelques effets graphiques, par exemple faire tourner la pochette des albums. Ce n&#8217;est pas très utile, mais c&#8217;est quand même impressionnant !</p><h4><a
name="Pointsforts"></a>Points forts</h4><ul><li><strong>Communauté</strong> : JavaFX s&#8217;appuie sur du Java, très largement répandu</li><li><strong>Scripting</strong> : malgré une syntaxe un peu différente du Java et quelques nouveautés, JavaFX Script simplifie l&#8217;écriture d&#8217;interface comparé à Swing. On apprécie particulièrement le <a
href="http://jfx.wikia.com/wiki/Introduction_to_Binding_in_JavaFX" title="binding" >binding</a>.</li><li><strong>Intégration</strong> : il est très facile d&#8217;appeler du code Java depuis un script JavaFX</li><li><strong>Return of the applet</strong> : il est possible de détacher une applet du browser pour la mettre sur le desktop (à partir de Java SE 6 update 10)</li></ul><h4><a
name="Pointsfaibles"></a>Points faibles</h4><ul><li><strong>Outillage</strong> : NetBeans possède un début de plugin pour JavaFX Script, mais il est encore assez bugué.</li><li><strong>Documentation</strong> : la documentation est assez mince et les exemples sont souvent difficiles à reprendre</li><li><strong>Manque de composants</strong> : il n&#8217;y a aucun composant graphique &laquo;&nbsp;évolué&nbsp;&raquo;.</li></ul><p>JavaFX n&#8217;est évidemment pas mature, rappelons qu&#8217;il ne s&#8217;agit que d&#8217;une preview. Malgré les difficultés rencontrées, nous gardons l&#8217;impression agréable de pouvoir faire des interfaces jolies en Java, et assez simplement grâce au langage de script JavaFX. La preview est plutôt prometteuse, mais il reste encore beaucoup de travail pour aboutir à un vrai produit. Il faudrait enrichir l&#8217;API avec des librairies de composants graphiques et offrir un vrai support pour les IDE, et pas seulement NetBeans. Heureusement Sun peut compter sur la communauté Java pour l&#8217;aider à combler ces défauts.<br
/> Il va cependant falloir courir vite pour rattraper un Flex déjà bien lancé.</p><h3><a
name="Alorsquiestlegagnant"></a>Alors qui est le gagnant ?</h3><p>Au terme de cette journée, l&#8217;équipe Flex, s&#8217;est nettement démarquée de ses concurrentes. Après deux sprints de mise en place et de prise en main, elle a pu consacrer le troisième et dernier sprint à l&#8217;enrichissement rapide et aisé de l&#8217;application, se concentrant uniquement sur les aspects fonctionnalités et expérience utilisateur.<br
/> C&#8217;est grâce à la richesse des composants de haut niveau, à la richesse de la documentation disponible et a la maturité du framework que l&#8217;équipe Flex a réalisé l&#8217;application la plus aboutie.</p><p><a
href="http://blog.xebia.fr/wp-content/uploads/2008/10/flex-screen1.jpg"><img
src="http://blog.xebia.fr/wp-content/uploads/2008/10/flex-screen1-300x176.jpg" alt="" title="flex-screen1" width="300" height="176" class="aligncenter size-medium wp-image-784" /></a></p><p><a
href="http://blog.xebia.fr/wp-content/uploads/2008/10/flex-screen2.jpg"><img
src="http://blog.xebia.fr/wp-content/uploads/2008/10/flex-screen2-300x209.jpg" alt="" title="flex-screen2" width="300" height="209" class="aligncenter size-medium wp-image-783" /></a></p><p>L&#8217;année dernière Wicket fut la révélation du <a
href="http://blog.xebia.fr/2007/10/26/xebia-web-framework-contest/" title="Xebia Web Framework Contest" >Xebia Web Framework Contest</a>. Cette année, peu de surprises, même si GWT semble avoir atteint le bon niveau de maturité.</p><div
class="shr-publisher-733"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2008%2F10%2F03%2Fria-contest-flex-silverlight-gwt-echo3-javafx%2F' data-shr_title='RIA+Contest+%3A+Flex+%2F+Silverlight+%2F+GWT+%2F+Echo3+%2F+JavaFX'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2008%2F10%2F03%2Fria-contest-flex-silverlight-gwt-echo3-javafx%2F' data-shr_title='RIA+Contest+%3A+Flex+%2F+Silverlight+%2F+GWT+%2F+Echo3+%2F+JavaFX'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/feed/</wfw:commentRss> <slash:comments>26</slash:comments> </item> <item><title>Exadel Flamingo &#8211; Applications Flex, AMF, Spring</title><link>http://blog.xebia.fr/2008/09/26/exadel-flamingo-applications-flex-amf-spring/</link> <comments>http://blog.xebia.fr/2008/09/26/exadel-flamingo-applications-flex-amf-spring/#comments</comments> <pubDate>Fri, 26 Sep 2008 13:29:28 +0000</pubDate> <dc:creator>Christophe Heubès</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[AMF]]></category> <category><![CDATA[Flamigo]]></category> <category><![CDATA[Flex]]></category> <category><![CDATA[Spring]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=746</guid> <description><![CDATA[L&#8217;article du Touilleur Express (aka Nicolas Martignole) intitulé Exadel Flamingo : JBoss Seam et Adobe Flex ensembles m&#8217;a donné envie de tester les capacité de flamingo d&#8217;Exadel. Exadel Flamingo fournit un ensemble de scripts, basés sur Maven, visant à simplifier le démarrage de projets RIA. Ces scripts permettent de générer le code initial et redondant [...]]]></description> <content:encoded><![CDATA[<p>L&#8217;article du <a
href="http://www.touilleur-express.fr" title="Touilleur Express" >Touilleur Express</a> <em>(aka Nicolas Martignole)</em> intitulé <a
href="http://www.touilleur-express.fr/2008/07/31/jboss-seam-et-adobe-flex/" title="Exadel Flamingo : JBoss Seam et Adobe Flex ensembles" >Exadel Flamingo : JBoss Seam et Adobe Flex ensembles</a> m&#8217;a donné envie de tester les capacité de <a
href="http://exadel.com/web/portal/flamingo" title="flamingo d'Exadel" >flamingo d&#8217;Exadel</a>.</p><p><a
href="http://exadel.com/web/portal/flamingo" title="Exadel Flamingo" >Exadel Flamingo</a> fournit un ensemble de scripts, basés sur Maven, visant à simplifier le démarrage de projets RIA. Ces scripts permettent de générer le code initial et redondant d&#8217;un projet.<br
/> La promesse est donc d&#8217;offrir la capacité de créer une application CRUD dotée d&#8217;une interface riche très rapidement et sans effort de développement.<br
/> <em>(Nous ne discuterons pas ici de l&#8217;intérêt ou non de doter une application de type CRUD d&#8217;une interface riche &#8230;)</em></p><p>Les technologies couvertes aujourd&#8217;hui sont :</p><ul><li>Flex et JavaFX pour partie cliente,</li><li>AMF et Hessian pour la communication,</li><li>JBoss Seam et Spring pour la partie serveur.</li></ul><p>Question de contexte et de goût, j&#8217;ai pour ma part porté mon attention sur le triplet Flex / AMF / Spring.</p><p>Même si certains aspects méritent des améliorations, la promesse est tenue. Bien que n&#8217;ayant jamais pratiqué Flex <em>(ou presque)</em>, il ne m&#8217;a pas fallu longtemps pour monter mon CRUD Flex / Spring / Hibernate.<br
/> Ce billet présente le déroulé de mes premiers essais.</p><h3><a
name="InstallationdeFlamingoetprrequ"></a>Installation de Flamingo et pré-requis</h3><p>L&#8217;utilisation de flamingo requiert un poste de travail sur lequel sont installés et configurés :</p><ul><li>Maven 2</li><li>Un JDK 1.5 ou supérieur</li><li>Un SDK Flex</li></ul><p>L&#8217;installation de flamingo est on ne peut plus simple :</p><ul><li>Décompression de l&#8217;archive <code>flamingo-1.x.x.zip</code>.</li><li>Exécution du script <code>flamingoinstall</code> <em>(ce script installe les librairies flamingo dans le repository maven local du poste de travail)</em>.</li><li>Ajout du répertoire <code>bin</code> de flamingo dans le {{PATH}}</li></ul><h3><a
name="Crationduprojet"></a>Création du projet</h3><p>La création d&#8217;un projet à partir de flamingo en mode ligne de commande se fait tout bonnement par exécution de <code>flamingo create project</code> :</p><pre class="brush: java; title: ; notranslate">
X:\XFR_Code\trunk\flex&gt;flamingo create project
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [com.exadel.flamingo.maven.plugin:flamingoapp:1.6.0:create-project] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] [flamingoapp:create-project]
discovered andromdapp type --&gt; 'flamingo-spring'
discovered andromdapp type --&gt; 'flamingo-seam'
</pre><p>Il suffit ensuite de répondre à une douzaine de questions afin de paramétrer le projet :</p><ul><li>Choix de la technologie serveur :</li></ul><pre class="brush: java; title: ; notranslate">
	Please choose the type of application to generate (flamingo-spring, flamingo-seam):[flamingo-spring]
	flamingo-spring
	</pre><ul><li>Caractéristiques du projet :</li></ul><pre class="brush: java; title: ; notranslate">
	Please enter the location in which your new application will be created (i.e. c:/java/development):
	X:\XFR_Code\trunk\flex
	Enter the project name (e.g. myproject):
	flamingo-demo
	Please enter the root package name for your project (e.g. com.mydomain.myproject): [fr.xebia.demo.flamingo]
	fr.xebia.demo.flamingo
	</pre><ul><li>Choix de la technologie cliente :</li></ul><pre class="brush: java; title: ; notranslate">
	Will this project have Flex or JavaFX user interface? (flex, javafx): [flex]
	flex
	</pre><ul><li>Choix du protocole de communication :</li></ul><pre class="brush: java; title: ; notranslate">
	Will this project use Hessian or AMF protocol? (amf, hessian): [amf]
	amf
	</pre><ul><li>Configuration de la base de données :</li></ul><pre class="brush: java; title: ; notranslate">
	What kind of database are you using? (hsql, mysql, oracle, postgres, mssql, db2, sybase, none): [hsql]
	hsql
	Enter the JDBC URL for your database (e.g. jdbc:hsqldb:.): [jdbc:hsqldb:.]
	jdbc:hsqldb:.
	Enter database username: [sa]
	sa
	Enter database password: []
	Do you want to update the database schema each time you deploy? (y, n): [y]
	y
	</pre><ul><li>Nom de la première entité du projet :</li></ul><pre class="brush: java; title: ; notranslate">
	Enter the entity class name (Flex source files to view and modify entities will be generated as well): [Product]
	Product
	</pre><p>Le projet est ensuite généré au format Maven :</p><pre class="brush: java; title: ; notranslate">
-------------------------------------------------------------------------------------
    G e n e r a t i n g   A n d r o M D A   P o w e r e d   A p p l i c a t i o n
-------------------------------------------------------------------------------------
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/flamingoproject.properties'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/flex/pom.xml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/flex/src/main/flex/fr/xebia/demo/flamingo/view/ProductManager.mxml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/flex/src/main/flex/fr/xebia/demo/flamingo/vo/Product.as'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/flex/src/main/flex/main.mxml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/flex/src/main/resources/services-config.xml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/pom.xml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/readme.txt'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/pom.xml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/java/fr/xebia/demo/flamingo/Product.java'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/java/fr/xebia/demo/flamingo/ProductDAO.java'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/java/fr/xebia/demo/flamingo/ProductDAOImpl.java'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/java/fr/xebia/demo/flamingo/service/ProductService.java'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/java/fr/xebia/demo/flamingo/service/ILoginService.java'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/java/fr/xebia/demo/flamingo/service/LoginService.java'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/resources/applicationContext-test.xml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/resources/applicationContext.xml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/resources/hibernate.cfg.xml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/webapp/index.html'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/main/webapp/WEB-INF/web.xml'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/test/java/fr/xebia/demo/flamingo/dao/ProductDAOTest.java'
    Output: 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/web/src/test/java/fr/xebia/demo/flamingo/DataSourceTestCase.java'
-------------------------------------------------------------------------------------
    New application generated to --&gt; 'file:/X:/XFR_Code/trunk/flex/flamingo-demo/'
-------------------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 42 seconds
[INFO] Finished at: Fri Aug 01 11:17:54 CEST 2008
[INFO] Final Memory: 9M/19M
[INFO] ------------------------------------------------------------------------
</pre><h3><a
name="CompilationTestsUnitairesetPac"></a>Compilation, Tests Unitaires et Packaging</h3><p>Le projet étant généré au format Maven, un simple <code>mvn clean package -Denv.FLEX_HOME=C:toolsflex_sdk_3</code> permet de compiler, lancer les tests unitaires et packager un war :</p><pre class="brush: java; title: ; notranslate">
X:\XFR_Code\trunk\flex\flamingo-demo&gt;mvn clean package -Denv.FLEX_HOME=C:\tools\flex_sdk_3
</pre><h3><a
name="Premireexcution"></a>Première exécution</h3><p>Souhaitant exécuter mes essais sous jetty depuis Maven, il m&#8217;a fallu :</p><ul><li>Ajouter le plugin jetty au projet web <em>({{flamingo-demo/web/pom.xml}})</em> :</li></ul><pre class="brush: xml; title: ; notranslate">
&lt;plugin&gt;
    &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
    &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;commons-logging&lt;/groupId&gt;
            &lt;artifactId&gt;commons-logging&lt;/artifactId&gt;
            &lt;version&gt;1.1.1&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.slf4j&lt;/groupId&gt;
            &lt;artifactId&gt;slf4j-jcl&lt;/artifactId&gt;
            &lt;version&gt;1.4.3&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;log4j&lt;/groupId&gt;
            &lt;artifactId&gt;log4j&lt;/artifactId&gt;
            &lt;version&gt;1.2.15&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
    &lt;configuration&gt;
        &lt;stopPort&gt;9181&lt;/stopPort&gt;
        &lt;stopKey&gt;STOP&lt;/stopKey&gt;
        &lt;systemProperties&gt;
            &lt;systemProperty&gt;
                &lt;name&gt;log4j.configuration&lt;/name&gt;
                &lt;value&gt;file:./target/classes/log4j.xml&lt;/value&gt;
            &lt;/systemProperty&gt;
        &lt;/systemProperties&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;
</pre><ul><li>Ajouter un fichier log4j.xml dans flamingo-demowebsrcmainresources</li><li>Supprimer le scope test sur la dépendance à hsqldb <em>({{flamingo-demo/web/pom.xml}})</em> :</li></ul><pre class="brush: xml; title: ; notranslate">
	&lt;dependency&gt;
        &lt;groupId&gt;hsqldb&lt;/groupId&gt;
        &lt;artifactId&gt;hsqldb&lt;/artifactId&gt;
        &lt;version&gt;1.8.0.7&lt;/version&gt;
    &lt;/dependency&gt;
</pre><p>J&#8217;ai également modifié le fichier <code>flamingo-demo/flex/src/main/resources/services-config.xml</code> afin que le canal AMF pointe au bon endroit <em>(dans le cadre d&#8217;un projet, on veillera à templatiser)</em>.</p><pre class="brush: xml; title: ; notranslate">
&lt;channels&gt;
    &lt;channel-definition id=&quot;spring-amf&quot; class=&quot;mx.messaging.channels.AMFChannel&quot;&gt;
        &lt;endpoint
            uri=&quot;http://localhost:9081/flamingo-demo-web/flamingo/amf&quot;
            class=&quot;flex.messaging.endpoints.AMFEndpoint&quot;/&gt;
    &lt;/channel-definition&gt;
&lt;/channels&gt;
</pre><p>Après installation du projet avec la commande <code>mvn clean install -Denv.FLEX_HOME=C:toolsflex_sdk_3</code> <em>(à la racine du projet parent)</em>, la commande <code>mvn jetty:run-war -Djetty.port=9081</code> <em>(dans le projet web)</em> lance l&#8217;exécution du war packagé sous jetty :</p><pre class="brush: java; title: ; notranslate">
	X:\XFR_Code\trunk\flex\flamingo-demo\web&gt;mvn -Dmaven.test.skip=true jetty:run-war -Djetty.port=9081
</pre><p>L&#8217;application est alors accessible à l&#8217;url <code>http://localhost:9081/flamingo-demo-web/</code>. Elle démarre sur un écran de login assez inattendu avec le mot de passe en clair :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2008/09/screen-01.png" border="0" alt="" /></div><p>Une fois &laquo;&nbsp;authentifié&nbsp;&raquo;, on accède à un écran présentant la liste des entités sous forme de tableau triable et aux fonctions de création modification suppression :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2008/09/screen-02.png" border="0" alt="" /></div><h3><a
name="Modificationdelentitetregnrati"></a>Modification de l&#8217;entité et regénération des écrans</h3><p>Modifions maintenant notre entité <code>Product</code> pour y ajouter les attributs suivants <em>(avec leurs accesseurs)</em> :</p><pre class="brush: java; title: ; notranslate">
private String description;
private Float price;
private Date avaibility;
</pre><p>La regénération des beans et des écrans passe par la commande <code>flamingo create screen</code> :</p><pre class="brush: java; title: ; notranslate">
	X:\XFR_Code\trunk\flex\flamingo-demo&gt;flamingo create screen
	X:\XFR_Code\trunk\flex\flamingo-demo&gt;set MAVEN_OPTS=-Xmx1024m
	[INFO] Scanning for projects...
	[INFO] Reactor build order:
	[INFO]   flamingo-demo
	[INFO]   flamingo-demo Flex
	[INFO]   flamingo-demo Web
	[INFO] ----------------------------------------------------------------------------
	[INFO] Building flamingo-demo
	[INFO]    task-segment: [com.exadel.flamingo.maven.plugin:flamingoapp:1.6.0:create-screen] (aggregator-style)
	[INFO] ----------------------------------------------------------------------------
	[INFO] [flamingoapp:create-screen]
	File Product.as already exists. Do you want replace it? (yes, no, all):[all]
	all
	[INFO] all
	[INFO] Product is a root entity
	File ProductScreens.mxml already exists. Do you want replace it? (yes, no, all):[all]
	all
	[INFO] all
	Check if the services-config.xml file contains the following destinations:
	&lt;destination id=&quot;Product&quot; /&gt;
	[INFO] ------------------------------------------------------------------------
	[INFO] BUILD SUCCESSFUL
	[INFO] ------------------------------------------------------------------------
	[INFO] Total time: 22 seconds
	[INFO] Finished at: Tue Aug 05 09:16:42 CEST 2008
	[INFO] Final Memory: 8M/15M
	[INFO] ------------------------------------------------------------------------
</pre><p>Après réinstallation de l&#8217;application dans notre repository local et redémarrage de jetty, nous obtenons les écrans suivants :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2008/09/screen-03.png" border="0" alt="" /></div><p>&nbsp;<br
/></p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2008/09/screen-04.png" border="0" alt="" /></div><p>L&#8217;ajout de nouvelles entités se fait tout aussi simplement. Les différentes entités sont alors présentées au travers d&#8217;onglets.</p><h3><a
name="Pourconclure"></a>Pour conclure</h3><p>Exadel Flamingo répond donc bien au besoin de génération du code initial et redondant d&#8217;un CRUD RIA. La création d&#8217;un CRUD Flex / Spring / Hibernate se fait sans heurt et sans que l&#8217;on ait trop à regarder sous le capot.</p><p>Quelques points restent cependant à améliorer <em>(gageons qu&#8217;ils le seront rapidement)</em>, notamment la validation des données saisies : apparemment, aucune validation n&#8217;est faite sur le type des données. Si l&#8217;on saisit des données erronées pour des attributs de type numérique ou date, la soumission du formulaire est &laquo;&nbsp;acceptée&nbsp;&raquo; et ses attributs se voient affecter une valeur null.</p><p>Le résultat de ces premiers essais est disponible sur le SVN de Xebia France : <a
href="http://code.google.com/p/xebia-france/source/browse/#svn/trunk/flex/flamingo-demo">http://code.google.com/p/xebia-france/source/browse/#svn/trunk/flex/flamingo-demo</a>.</p><div
class="shr-publisher-746"></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div
class='shareaholic-like-buttonset' style='float:none;height:30px;'><a
class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2008%2F09%2F26%2Fexadel-flamingo-applications-flex-amf-spring%2F' data-shr_title='Exadel+Flamingo+-+Applications+Flex%2C+AMF%2C+Spring'></a><a
class='shareaholic-tweetbutton' data-shr_count='horizontal' data-shr_href='http%3A%2F%2Fblog.xebia.fr%2F2008%2F09%2F26%2Fexadel-flamingo-applications-flex-amf-spring%2F' data-shr_title='Exadel+Flamingo+-+Applications+Flex%2C+AMF%2C+Spring'></a></div><div
style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/09/26/exadel-flamingo-applications-flex-amf-spring/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> </channel> </rss>
