<?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/"
	>

<channel>
	<title>Pierre Schambacher.com &#187; Programmation</title>
	<atom:link href="http://www.pierreschambacher.com/blog/category/articles/programmation/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pierreschambacher.com</link>
	<description>Ingénieur en Informatique pour Intellicore</description>
	<lastBuildDate>Fri, 28 May 2010 06:45:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>git in a nutshell Part 2</title>
		<link>http://www.pierreschambacher.com/blog/git-in-a-nutshell-part-2/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=git-in-a-nutshell-part-2</link>
		<comments>http://www.pierreschambacher.com/blog/git-in-a-nutshell-part-2/#comments</comments>
		<pubDate>Thu, 20 May 2010 07:00:03 +0000</pubDate>
		<dc:creator>soutade</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[billet invité]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=325</guid>
		<description><![CDATA[Comme je l&#8217;avais promis dans mon court billet de dimanche dernier, mon ami Grégory nous offre le deuxième volet du tutoriel consacré à Git.
Dans le cas où vous auriez malencontreusement loupé la première partie consacrée à l&#8217;utilisation générale de Git, ou que vous souhaitiez tout simplement le relire pour le plaisir: http://www.pierreschambacher.com/blog/git-in-a-nutshell/
Relire le premier billet ne serait [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Comme je l&#8217;avais promis dans mon court billet de dimanche dernier, mon ami Grégory nous offre le deuxième volet du tutoriel consacré à Git.<br />
Dans le cas où vous auriez malencontreusement loupé la première partie consacrée à l&#8217;utilisation générale de Git, ou que vous souhaitiez tout simplement le relire pour le plaisir: <a href="http://www.pierreschambacher.com/blog/git-in-a-nutshell/">http://www.pierreschambacher.com/blog/git-in-a-nutshell/</a></p>
<p style="text-align: justify;">Relire le premier billet ne serait d&#8217;ailleurs pas idiot puisqu&#8217;il y a eu quelques ajouts dans le tutoriel précédents (stashs, hooks, alias).</p>
<p style="text-align: justify;"><span id="more-325"></span></p>
<h1 style="text-align: justify;">Système de version décentralisé vs centralisé ?</h1>
<p style="text-align: justify;">La puissance d&#8217;un modèle décentralisé à la git c&#8217;est justement qu&#8217;il n&#8217;est pas figé. En effet il peut aussi bien être utilisé avec un dépôt local unique, avec une multitude de dépôts locaux, ainsi qu&#8217;avec un dépôt central&#8230; ou la combinaison de tous ces modes, tandis qu&#8217;avec un dépôt central unique on ne peut changer de modèle. Si on rajoute la facilité d&#8217;utilisation et la rapidité des opérations, il n&#8217;y a plus de raisons d&#8217;aller voir ailleurs ! Bien sûr on pourra toujours critiquer les aspects de configurations à mettre en place pour un mode centralisé, mais quand on achète une Ferrari il faut aussi apprendre à la conduire.</p>
<p style="text-align: justify;">
<h1 style="text-align: justify;">Commandes de base</h1>
<p style="text-align: justify;">L&#8217;utilisation en mode centralisé est aussi simple, côté client, que l&#8217;utilisation générale de Git. Pour ainsi dire il n&#8217;y a que 4 commandes importantes :</p>
<ul>
<li>clone</li>
<li>remote</li>
<li>pull</li>
<li>push</li>
</ul>
<h2 style="text-align: justify;">clone</h2>
<blockquote>
<p style="text-align: justify;">git clone dépôt_distant [dossier]</p>
</blockquote>
<p style="text-align: justify;">Permet de récupérer un dépôt distant dans dossier. Les protocoles supportés sont : rsync, http, https, git, ssh, file. Les fichiers étant compressés et empaquetés un checkout est donc très rapide comparé à un svn qui va tout télécharger unitairement !<br />
Par défaut la référence au projet distant sera « origin » (voir remote).</p>
<p style="text-align: justify;">
<h2 style="text-align: justify;">Remote</h2>
<p style="text-align: justify;">Cette commande permet de gérer les dépôts distants :</p>
<p style="text-align: justify;">Lister les références aux dépôts distants :</p>
<blockquote>
<p style="text-align: justify;">git remote [-v]</p>
</blockquote>
<p style="text-align: justify;">Ajouter la référence nom à un dépôt distant. Dans le cas de clone, origin référencera le dépôt distant :</p>
<blockquote>
<p style="text-align: justify;">git remote add nom dépôt_distant</p>
</blockquote>
<p style="text-align: justify;">Supprimer une référence</p>
<blockquote>
<p style="text-align: justify;">git remote rm reference</p>
</blockquote>
<p style="text-align: justify;">Renommer une référence :</p>
<blockquote>
<p style="text-align: justify;">git remote rename ancienne_ref nouvelle_ref</p>
</blockquote>
<p style="text-align: justify;">Modifier une référence</p>
<blockquote>
<p style="text-align: justify;">git remote set-url reference nouvelle_adresse</p>
</blockquote>
<p style="text-align: justify;">Afficher les informations d&#8217;une référence</p>
<blockquote>
<p style="text-align: justify;">git show reference</p>
</blockquote>
<p style="text-align: justify;">
<h2 style="text-align: justify;">pull</h2>
<blockquote>
<p style="text-align: justify;">git pull [--rebase] reference branche</p>
</blockquote>
<p style="text-align: justify;">Cette commande est équivalent à un checkout de svn. On va récupérer l&#8217;état actuel de la branche distante. Le paramètre &#8216;reference&#8217; est la référence que nous avons manipulé avec la commande remote. Par défaut on utilise origin. Après le pull il y a un merge automatique, sauf avec l&#8217;option &#8211;rebase qui permet de revenir à la version exacte du serveur (équivalent à un reset –hard de la version sur le serveur).</p>
<h2 style="text-align: justify;">push</h2>
<blockquote>
<p style="text-align: justify;">git push reference branch</p>
<p style="text-align: justify;">git push &#8211;tags dépôt</p>
</blockquote>
<p style="text-align: justify;">Cette Commande est l&#8217;inverse de pull, elle permet d&#8217;envoyer ses modifications sur le serveur. C&#8217;est l&#8217;équivalent d&#8217;un checkin de svn.<br />
L&#8217;option &#8211;tags permet d&#8217;envoyer la liste de tous tags locaux. Pour n&#8217;envoyer qu&#8217;un seul tag on procède comme suit :</p>
<blockquote>
<p style="text-align: justify;">git push reference tag NomDuTag</p>
</blockquote>
<p style="text-align: justify;">
<h1 style="text-align: justify;">Cycle de vie des commandes</h1>
<p style="text-align: justify;">Un petit exemple vaut mieux qu&#8217;un long discours :</p>
<p style="text-align: justify;">Initialisation</p>
<blockquote>
<p style="text-align: justify;">git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux</p>
</blockquote>
<p>ou</p>
<blockquote>
<p style="text-align: justify;">git init linux<br />
cd linux<br />
git remote add origin git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git<br />
git pull origin master</p>
</blockquote>
<p style="text-align: justify;">Ensuite on fait des modifications comme vu dans le tutoriel précédent avec la puissance d&#8217;un gestionnaire de version décentralisé.</p>
<p style="text-align: justify;">Pour se resynchroniser avec le serveur :</p>
<blockquote>
<p style="text-align: justify;">git commit -a<br />
git pull origin master</p>
</blockquote>
<p style="text-align: justify;">Puis on pousse nos modifications sur le serveur :</p>
<blockquote>
<p style="text-align: justify;">git push origin master</p>
</blockquote>
<p>Simple non ?</p>
<h1 style="text-align: justify;">On est mal barrés !</h1>
<p style="text-align: justify;">Les dépôts distants sont généralement crées avec l&#8217;option &#8211;bare et se terminent par .git</p>
<blockquote>
<p style="text-align: justify;">git init &#8211;bare dossier.git</p>
</blockquote>
<p style="text-align: justify;">Un dépôt de type « bare » est en fait un dépôt sans espace de travail (working directory), ainsi il n&#8217;y a pas directement les fichiers sources mais uniquement le contenu du dossier .git. Cela empêche l&#8217;utilisation de certaines commandes (git add, git rm, git commit …).</p>
<p style="text-align: justify;">
<h1 style="text-align: justify;">Supprimer une référence distante</h1>
<p style="text-align: justify;">Il peut être utile de supprimer à distance une branche ou un tag. Pour se faire il suffit d&#8217;ajouter « : » avant la référence à supprimer. En théorie lors de la spécification d&#8217;une référence on devrait la noter +ref_locale:ref_distante, donc si on omet la référence locale il y aura suppression. La syntaxe de git permet de se passer du « + » et du « : » comme dans l&#8217;exemple.</p>
<p style="text-align: justify;">Supprimer un tag distant :</p>
<blockquote>
<p style="text-align: justify;">git push &#8211;tags origin :TagASupprimer</p>
</blockquote>
<p style="text-align: justify;">Supprimer une branche distante :</p>
<blockquote>
<p style="text-align: justify;">git push origin :MaBranche</p>
</blockquote>
<p style="text-align: justify;">Pour lister les références distantes, on utilise la commande :</p>
<blockquote>
<p style="text-align: justify;">git ls-remote [--heads] [--tags] reference</p>
</blockquote>
<p style="text-align: justify;">
<h1 style="text-align: justify;">Exporter un dépôt sur le réseau</h1>
<p style="text-align: justify;">Le site <a href="http://www.jedi.be/blog/2009/05/06/8-ways-to-share-your-git-repository">http://www.jedi.be/blog/2009/05/06/8-ways-to-share-your-git-repository</a> (in English, sorry) liste les différentes façons d&#8217;exporter les dépôts git.<br />
La version maison est un démon intégré à git qui écoute sur le port 9418 par défaut, il va scanner les dossiers de sa liste blanche et s&#8217;il détecte le fichier &laquo;&nbsp;git-daemon-export-ok&nbsp;&raquo; dans le .git du dépôt, alors celui-ci sera exporté.</p>
<blockquote>
<p style="text-align: justify;">git daemon [--export-all] [--base-path=path][--user-path] [--reuseaddr] [directory…]</p>
</blockquote>
<ul>&#8211;export-all exporte tous les dépôts que le fichier &laquo;&nbsp;git-daemon-export-ok&nbsp;&raquo; soit présent ou non</ul>
<ul>&#8211;base-path permet d&#8217;indiquer le répertoire de base des dépôts</ul>
<ul>&#8211;user_path permet d&#8217;utiliser la notation ~user dans l&#8217;adresse de git clone</ul>
<ul>&#8211;reuseaddr permet de pouvoir se lier au port même s&#8217;il est déjà utilisé (après un crash en général)</ul>
<p style="text-align: justify;">On peut spécifier ensuite les répertoires de la liste blanche (en plus de &#8211;base-path). On peut utiliser un démarrage manuel ou un service comme inetd.</p>
<p style="text-align: justify;">
<h1 style="text-align: justify;">Contrôle d&#8217;accès au dépôt</h1>
<p style="text-align: justify;">Et bien c&#8217;est simple, git n&#8217;intègre pas de mécanisme de contrôle d&#8217;accès aux dépôts ! C&#8217;est un gestionnaire de version, il laisse donc ce travail à d&#8217;autres couches systèmes spécialisées. Mais ceci vient aussi du fait que le mode décentralisé est celui par défaut, donc si quelqu&#8217;un a fait une modification dans le code de Linux, il va demander à Linus de faire un pull de ses modifications. Dans ce schéma il n&#8217;y a pas besoin d&#8217;intégrer des mécanismes de sécurité divers et variés.<br />
Néanmoins il existe des solutions.</p>
<ul>
<li>Pour http(s), on peut utiliser l&#8217;authentification intégrée (voir liée à un LDAP)</li>
<li>Pour un système de fichier on a toute la gestion des droits intégrée au système (un peu lourd à mettre en place)</li>
<li>Idem pour ssh, mais cela nécessite en plus de créer des comptes ssh sur le serveur</li>
</ul>
<p style="text-align: justify;">Néanmoins la solution la plus pratique est Gitosis. Avec Gitosis il n&#8217;est nécessaire de créer qu&#8217;un seul compte sur la machine « git », chaque utilisateur est authentifié par sa clé ssh (clé unique, authentification forte) et les dépôts peuvent avoir un accès lecture seule ou lecture/écriture.<br />
Pour modifier la configuration de Gitosis, on fait un pull du projet gitosis-admin, on obtient l&#8217;arborescence suivante :</p>
<ul>
<li><strong>keydir</strong> dossier qui contient les fichiers de clés ssh publiques (.pub) de tous les utilisateurs</li>
<li><strong>gitosis.conf</strong> fichier qui contient la configuration des dépôts</li>
</ul>
<p style="text-align: justify;">Ensuite modifications, commit, push comme vu plus haut.<br />
Les dépôts contrôlés par Gitosis sont situés dans /home/git/repositories, mais rien n&#8217;empêche de faire des liens symbolique pour les stocker ailleurs.<br />
Exemple de fichier de configuration :</p>
<blockquote>
<p style="text-align: justify;">[gitosis]<br />
## Autoriser gitweb à montrer tous les dépôts<br />
gitweb = no</p>
<p>## Autoriser git-daemon à publier tous les dépôts<br />
daemon = no</p>
<p>[group quux]<br />
members = jdoe wsmith @anothergroup<br />
writable = repo1 repo2<br />
readonly = repo3</p>
<p>[group anothergroup]<br />
members = alice bill</p>
<p>[repo foo]<br />
## Configuration par dépôt au lieu de la configuration globale pour gitweb (idem pour git daemon)<br />
gitweb = yes</p></blockquote>
<p style="text-align: justify;">On définit des groupes avec des membres et les dépôts auxquels ils peuvent accéder en lecture seule ou lecture/écriture. La syntaxe de contrôle est inversée par rapport à ce qu&#8217;on a l&#8217;habitude de voir : un dépôt ne définit pas ses permissions, c&#8217;est un groupe qui définit ses accès.<br />
Le seul défaut de Gitosis est que la granularité des accès se font au niveau du dépôt complet (y compris pour les tags). Pour avoir un contrôle plus fin on sera obligé de passer par des hooks (le hook update en l&#8217;occurrence) ou de se tourner vers Gitolite qui a un comportement identique avec la possibilité de définir précisément les droits d&#8217;accès.</p>
<p style="text-align: justify;">Pour accéder à un dépôt on procède de la manière suivante :</p>
<blockquote>
<p style="text-align: justify;">git clone git@serveur:repo1</p>
</blockquote>
<p><a rel="license" href="http://creativecommons.org/licenses/by-sa/2.0/fr/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/2.0/fr/88x31.png" /></a><br /><span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Text" property="dc:title" rel="dc:type">Tutoriel GIT</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="http://www.pierreschambacher.com/" property="cc:attributionName" rel="cc:attributionURL">Gr&#233;gory Soutad&#233;</a> est mis &#224; disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-sa/2.0/fr/">licence Creative Commons Paternit&#233;-Partage des Conditions Initiales &#224; l&#8217;Identique 2.0 France</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/git-in-a-nutshell-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutoriel pour développeur WebObjects: Composants classiques</title>
		<link>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-composants-classiques/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=tutoriel-pour-developpeur-webobjects-composants-classiques</link>
		<comments>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-composants-classiques/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 19:29:13 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[Tutoriaux WebObjects]]></category>
		<category><![CDATA[tutoriel]]></category>
		<category><![CDATA[webobjects]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=291</guid>
		<description><![CDATA[Vous avez appris dans ce billet à manipuler les composants de WebObjects. Vous devriez avoir compris comment les pages fonctionnent, mais il vous manque encore de connaître les composants que l&#8217;on utilise au quotidien.
Voici une liste de ces composants avec leur syntaxe à l&#8217;ancienne, la nouvelle syntaxe et quelques exemples d&#8217;utilisation.

Comme d&#8217;habitude vous pouvez opter pour [...]]]></description>
			<content:encoded><![CDATA[<p>Vous avez appris dans ce <a title="Tutoriel WebObjects 2" href="http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-hello-world/" target="_blank">billet</a> à manipuler les composants de WebObjects. Vous devriez avoir compris comment les pages fonctionnent, mais il vous manque encore de connaître les composants que l&#8217;on utilise au quotidien.</p>
<p>Voici une liste de ces composants avec leur syntaxe à l&#8217;ancienne, la nouvelle syntaxe et quelques exemples d&#8217;utilisation.</p>
<p><span id="more-291"></span></p>
<p>Comme d&#8217;habitude vous pouvez opter pour la version <a class="wp-caption" style="font-size: 16pt;" title="Tutoriel WebObjects composants" href="http://www.pierreschambacher.com/wp-content/uploads/2009/11/03-Composants-classiques.pdf" target="_blank">PDF</a> du tutoriel.</p>
<h1 style="font-size: 2em;">WOString</h1>
<h2 style="font-size: 1.5em;">Rôle</h2>
<p>C&#8217;est probablement le composant le plus utilisé du framework. Son but est simple, afficher une chaîne de caractère. Vous pouvez l&#8217;inclure un peu où vous voulez pour y insérer une chaîne de caractère.</p>
<h2 style="font-size: 1.5em;">Bindings importants</h2>
<p><span style="text-decoration: underline;">value</span>: chaîne de caractère que vous souhaitez afficher, tout simplement.<br />
<span style="text-decoration: underline;">numberFormatter</span>: instance de NSNumberFormatter à utiliser s&#8217;il s&#8217;agit d&#8217;une valeur numérique qu&#8217;il faudra parser et/ou formatter.<br />
<span style="text-decoration: underline;">dateFormatter</span>: chaîne de caractère pour indiquer les informations l&#8217;affichage d&#8217;une valeur de type date.</p>
<h2 style="font-size: 1.5em;">Inline tags</h2>
<blockquote><p>&lt;wo:str /&gt;<br />
&lt;wo:string&gt;</p></blockquote>
<h1 style="font-size: 2em;">WOConditionnal</h1>
<h2 style="font-size: 1.5em;">Rôle</h2>
<p>Permet d&#8217;afficher un bloc selon une condition, par exemple &laquo;&nbsp;Afficher ce bloc si l&#8217;utilisateur connecté est administrateur&nbsp;&raquo;.</p>
<h2 style="font-size: 1.5em;">Bindings importants</h2>
<p><span style="text-decoration: underline;">condition</span>: condition à laquelle le code contenu sera affiché. Quelque soit le type de paramètre passé, un cast vers boolean est effectué. Comprenez que false, null, chaîne vide et 0 (zéro) valent FAUX. N&#8217;importe quoi d&#8217;autre est vrai.<br />
<span style="text-decoration: underline;">negate</span>: si ce binding est mis à vrai, c&#8217;est la négation de la condition qui déclanchera l&#8217;affichage du code. Par défaut ce binding est à faux.</p>
<h2 style="font-size: 1.5em;">Inline tags</h2>
<blockquote><p>&lt;wo:if&gt; &#8230; &lt;/wo:if&gt;<br />
&lt;wo:conditionnal&gt; &#8230; &lt;/wo:conditionnal&gt;<br />
&lt;wo:condition&gt; &#8230; &lt;/wo:condition&gt;</p></blockquote>
<p>Notez qu&#8217;en utilisant ces tags inline vous disposez d&#8217;un petit raccourci avec un tag ayant pour sa part negate par défaut à vrai comme son nom l&#8217;indique.</p>
<blockquote><p>&lt;wo:not&gt; &#8230; &lt;/wo:not&gt;</p></blockquote>
<h1 style="font-size: 2em;">WORepetition</h1>
<h2 style="font-size: 1.5em;">Rôle</h2>
<p>En complément des trois éléments précédents, vous avez avec celui-ci de quoi faire les trois quarts de vos applications. L&#8217;élément WORepetition permet de parcourir une liste ou de faire un certain nombre d&#8217;itérations. C&#8217;est le composant dont le fonctionnement demande le plus d&#8217;explication sur son fonctionnement.</p>
<p>Admettons que vous utilisiez le WORepetition avec une liste d&#8217;éléments de type User. Vous allez alors mettre en place un binding sur item de type User appelé &laquo;&nbsp;currentUser&nbsp;&raquo;, accessible en lecture et en écriture. À chaque tour de boucle, le setter de ce binding sera appelé afin d&#8217;y placer la valeur courante. Ainsi lorsque vous allez vouloir afficher par exemple le nom de votre utilisateur courant, vous utiliserez simplement un binding currentUser.name, donc inutile de vous prendre la tête avec des indices de liste quand vous codez le contenu du composant.</p>
<h2 style="font-size: 1.5em;">Bindings importants</h2>
<p><span style="text-decoration: underline;">list</span>: si vous souhaitez itérer sur les composants d&#8217;une liste, c&#8217;est ici que vous devrez fournir la liste.<br />
<span style="text-decoration: underline;">item</span>: élément courant pendant l&#8217;execution de la boucle.<br />
<span style="text-decoration: underline;">count</span>: il s&#8217;agit d&#8217;une alternative à list, permettant d&#8217;itérer un nombre de fois précis sans se référer au parcours d&#8217;une liste.<br />
<span style="text-decoration: underline;">index</span>: binding lecture/écriture qui contiendra la valeur i pour la ième itération.</p>
<h2 style="font-size: 1.5em;">Inline tags</h2>
<blockquote><p>&lt;wo:foreach&gt; &#8230; &lt;/wo:foreach&gt;<br />
&lt;wo:repeat&gt; &#8230; &lt;/wo:repeat&gt;<br />
&lt;wo:repetition&gt; &#8230; &lt;/wo:repetition&gt;<br />
&lt;wo:loop&gt; &#8230; &lt;/wo:loop&gt;</p></blockquote>
<h1 style="font-size: 2em;">AjaxUpdateContainer</h1>
<h2 style="font-size: 1.5em;">Rôle</h2>
<p>Par la suite, je vais parler de composants Ajax, il m&#8217;est donc obligatoire de parler de l&#8217;AjaxUpdateContainer. Son principe est très simple, le composant sera par la suite transformé en une zone &lt;div&gt; munie d&#8217;un id que vous lui aurez fourni. Vous pouvez alors ajouter à votre page des composants Ajax qui vont déclencher une action sur le serveur, et indiquer l&#8217;id de votre AjaxUpdateContainer de façon à ce que le résultat de votre action vienne remplacer son contenu actuel.</p>
<p>Si vous aviez besoin de mettre à jour plusieurs panneaux de votre écran sur une seule action du serveur, regardez <a title="AjaxUpdateTrigger" href="http://webobjects.mdimension.com/hudson/job/Wonder53/javadoc/er/ajax/AjaxUpdateTrigger.html" target="_blank">AjaxUpdateTrigger</a></p>
<h2 style="font-size: 1.5em;">Bindings importants</h2>
<p><span style="text-decoration: underline;">id</span>: chaîne de caractère qui permet d&#8217;identifier votre élément de manière unique dans une page.</p>
<h2 style="font-size: 1.5em;">Inline tags</h2>
<blockquote><p>&lt;wo:AjaxUpdateContainer&gt; &#8230; &lt;/wo:AjaxUpdateContainer&gt;</p></blockquote>
<h1 style="font-size: 2em;">WOHyperlink / AjaxHyperlink</h1>
<h2 style="font-size: 1.5em;">Rôle</h2>
<p>Inutile de vous faire un dessin. Il s&#8217;agit de liens classiques et ajax.</p>
<h2 style="font-size: 1.5em;">Bindings importants</h2>
<p><span style="text-decoration: underline;">action</span>: il est vivement recommandé d&#8217;utiliser ce bindings plutôt que href ou pageName car il est plus facile de détecter une erreur dans un fichier Java que dans un fichier HTML.<br />
<span style="text-decoration: underline;">directActionName</span>: pour appeler une directAction plutôt qu&#8217;une action du composant sous-jacent.<br />
<span style="text-decoration: underline;">string</span>: chaîne de caractère à afficher pour représenter le lien (vous pouvez aussi l&#8217;insérer dans les balises)<br />
<span style="text-decoration: underline;">updateContainerID</span>: pour AjaxHyperlink, partie de la page à rafraichir avec le composant renvoyé par l&#8217;action appelée.</p>
<h2 style="font-size: 1.5em;">Inline tags</h2>
<p>Pour le WOHyperlink</p>
<blockquote><p>&lt;wo:link&gt; &#8230; &lt;/wo:link&gt;<br />
&lt;wo:hyperlink&gt; &#8230; &lt;/wo:hyperlink&gt;</p></blockquote>
<p>Le AjaxHyperlink n&#8217;a par défaut pas de raccourci.</p>
<blockquote><p>&lt;wo:AjaxHyperlink&gt; &#8230; &lt;/AjaxHyperlink&gt;</p></blockquote>
<h1 style="font-size: 2em;">WOSubmitButton / AjaxSubmitButton</h1>
<h2 style="font-size: 1.5em;">Rôle</h2>
<p>Vous aurez compris que vous avec affaire aux éléments qui vont générer un input de type submit. Ces deux composants doivent se trouver dans un formulaire (créé de préférence à l&#8217;aide d&#8217;un WOForm, aucun binding important).</p>
<h2 style="font-size: 1.5em;">Bindings importants</h2>
<p><span style="text-decoration: underline;">action</span>: le fonctionnement est le même que pour le WOHyperlink à ceci près que les données contenues dans le formulaire contenant le bouton vont être envoyées au serveur, ce qui n&#8217;est pas le cas avec le WOHyperlink (ni avec le AjaxUpdateLink).<br />
<span style="text-decoration: underline;">value</span>: chaîne de caractère à afficher sur le bouton.<br />
<span style="text-decoration: underline;">updateContainerID</span>: pour AjaxSubmitButton, partie de la page à rafraichir avec le composant renvoyé par l&#8217;action appelée.</p>
<h2 style="font-size: 1.5em;">Inline tags</h2>
<p>Pour le WOSubmitButton</p>
<blockquote><p>&lt;wo:submit&gt; &#8230; &lt;/wo:submit&gt;<br />
&lt;wo:submitButton&gt; &#8230; &lt;/wo:submitButton&gt;</p></blockquote>
<p>Pour le AjaxSubmitButton</p>
<blockquote><p>&lt;wo:AjaxSubmitButton&gt; &#8230; &lt;/wo:AjaxSubmitButton&gt;</p></blockquote>
<h1 style="font-size: 2em;">ERXElse</h1>
<h2 style="font-size: 1.5em;">Rôle</h2>
<p>Pas un essentiel du tout mais un apport particulièrement appréciable de Wonder. Souvent lors de l&#8217;usage d&#8217;un WOConditionnal, on a également un comportement à définir pour le cas où la condition n&#8217;est pas satisfaite. C&#8217;est une partie de l&#8217;origine du binding negate, puisqu&#8217;au lieu d&#8217;écrire deux conditions, il suffisait d&#8217;utiliser deux fois la même et d&#8217;utiliser ce binding. Wonder offre une possibilité entre plus simple, le else ! Situé après un WOConditionnal, son contenu ne sera affiché qu&#8217;à condition que celle du WOConditionnal ne le soit pas. Ce composant n&#8217;a aucun binding.</p>
<h2 style="font-size: 1.5em;">Inline tags</h2>
<blockquote><p>&lt;wo:else&gt; &#8230; &lt;/wo:else&gt;</p></blockquote>
<h1 style="font-size: 2em;">Aller plus loin</h1>
<p>Ce tutoriel s&#8217;arrête ici. Le but n&#8217;est pas de faire toute la chevauchée avec vous mais simplement de vous mettre le pied à l&#8217;étrier. J&#8217;espère que vous suivez ces tutoriaux en faisant vos propres tentatives à côté et non pas simplement en lisant ces pages l&#8217;une après l&#8217;autre. La mise en application est très importante pour vérifier que vous avez mémorisé ce qui a été abordé et compris les principes.</p>
<p>Pour aller plus loin dans la création de votre propre application, voici une liste de noms de composants qui vous seront utiles. Vous avez un nom, cherchez simplement comment l&#8217;utiliser sur internet et dans le pire des cas, servez vous de la fonction d&#8217;auto-complétion d&#8217;eclipse pour comprendre le fonctionnement du composant. eclipse est un excellent outil pour apprendre notamment les bindings obligatoires.</p>
<p>Faites attention aux bindings GET et aux bindings GET/SET. Attention également aux chaînes de caractères, qui sont à mettre des fois sur le binding string et des fois sur value. Vous aurez remarqué d&#8217;ailleurs qu&#8217;il ne faut pas utiliser le même pour le WOHyperlink et le WOSubmitButton. Il n&#8217;y a pas vraiment de règle pour savoir lequel des deux il faudra utiliser, la seule chose certaine est que si le binding string existe, c&#8217;est celui à utiliser.</p>
<p>WOBody, WOForm, WORadioButton, WORadioButtonList, WOCheckBox, WOCheckBoxList, WOTextField, WOPasswordField, WOText, WOPopUpButton, WOResetButton, WOImage, AjaxModalDialog, &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-composants-classiques/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutoriel pour développeur WebObjects: Hello World</title>
		<link>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-hello-world/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=tutoriel-pour-developpeur-webobjects-hello-world</link>
		<comments>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-hello-world/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 15:35:02 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[Tutoriaux WebObjects]]></category>
		<category><![CDATA[tutoriel]]></category>
		<category><![CDATA[webobjects]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=260</guid>
		<description><![CDATA[Ce nouveau volet de la série de tutoriaux sur WebObjects fait suite au billet sur l&#8217;installation de l&#8217;environnement de travail. Nous allons ici créer notre premier projet et en expliquer les différentes parties et le fonctionnement général.
Tout au long de ce tutoriel je vais considérer que vous avez déjà une connaissance normale du langage Java [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Ce nouveau volet de la série de tutoriaux sur WebObjects fait suite au billet sur <a title="Tutoriel pour installer WebObjects" href="http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-install-party/" target="_blank">l&#8217;installation</a> de l&#8217;environnement de travail. Nous allons ici créer notre premier projet et en expliquer les différentes parties et le fonctionnement général.</p>
<p style="text-align: justify;">Tout au long de ce tutoriel je vais considérer que vous avez déjà une connaissance normale du langage Java et d&#8217;eclipse. Si tel n&#8217;est pas le cas je vous conseille de vous former dans un premier temps sur ces outils car sinon vous risquez d&#8217;éprouver quelques difficultés à suivre ce qu&#8217;il se passe.</p>
<p style="text-align: justify;">Pour ce tutoriel et les suivants, je m&#8217;inspire fortement des screencasts de David LeBer WebObjects, WOLips and Wonder tutorial <a title="WebObjects, WOLips and Wonder tutorial" href="http://www.wocommunity.org/podcasts/WO_WOLips_Wonder_Tutorial_Part_1-desktop.m4v" target="_blank">part 1</a> et <a title="WebObjects, WOLips and Wonder tutorial" href="http://www.wocommunity.org/podcasts/WO_WOLips_Wonder_Tutorial_Part_2-desktop.m4v" target="_blank">part 2</a> qui sont disponible sur le site de WOCommunity avec tous les autres <a title="Screencasts WebObjects" href="http://www.wocommunity.org/webobjects_screencasts.html" target="_blank">screencasts</a> que je vous recommande vraiment.</p>
<p style="text-align: justify;">Vous pouvez aussi utiliser la version <a class="wp-caption" style="font-size: 14pt;" title="Tutoriel format pdf" href="http://www.pierreschambacher.com/wp-content/uploads/2009/11/02-Hello-World.pdf" target="_blank">PDF</a> de ce tutoriel et si vous souhaitez le traduire je me ferais un plaisir de le publier ici même.</p>
<p style="text-align: justify;"><span id="more-260"></span></p>
<h1>Créer un projet Wonder</h1>
<p style="text-align: justify;">Première étape, nous allons créer dans notre joli eclipse disposant du plug-in WOLips un projet Wonder.<br />
Vous êtes habitué à eclipse donc aucune difficulté jusqu&#8217;ici: File &gt; New &gt; Wonder Application.</p>
<p style="text-align: justify;">Première étape, le nom du projet. Pour illustrer notre tutoriel, nous allons créer une petite application permettant à un utilisateur de créer sa collection de séries et de se souvenir du dernier épisode regardé. Notre projet s&#8217;appellera donc &laquo;&nbsp;Series&nbsp;&raquo;. Vous pouvez également choisir votre workspace eclipse pour ce projet.</p>
<p style="text-align: justify;">Deuxième étape vous pouvez choisir le package de base de vos classes et de vos composants. Le standart pour le package des composants est d&#8217;utiliser le package de base auquel est ajouté .components, c&#8217;est à dire que pour un package de base xxx.yyy vous utiliserez le package xxx.yyy.components. Dans notre exemple je vais utiliser comme racine com.pierreschambacher.series.</p>
<p style="text-align: justify;">Etape intermédiaire, si vous avez d&#8217;autres projets vous pourrez indiquer que vous les utilisez dans votre nouvelle application. Si vous n&#8217;avez pas d&#8217;autre projet eclipse cet écran n&#8217;apparait normalement pas, s&#8217;il apparait choisissez next.</p>
<p style="text-align: justify;">Dernière étape, l&#8217;import d&#8217;EOModels existants. Nous n&#8217;avons pas non plus d&#8217;EOModel existant, cliquez donc sur Finish. Pour information cette étape vous permettra d&#8217;utiliser un modèle déjà existant.</p>
<p style="text-align: justify;">Vous pouvez voir qu&#8217;eclipse vient de créer votre projet avec tout un tas de dossiers, packages et fichiers déjà écrits.</p>
<h1>Classes, packages, ressources, &#8230;</h1>
<p>Faisons un tour des dossiers et fichiers générés pour maîtriser la structure de notre projet.</p>
<h2>Sources</h2>
<p style="text-align: justify;">Tout d&#8217;abord vous remarquez trois classes dans le package de base que vous avez fourni au wizard: Application, DirectAction et Session.</p>
<h3>Application</h3>
<p style="text-align: justify;">Il s&#8217;agit de votre classe main. Peu de choses sont à faire avec ce fichier si ce n&#8217;est de la configuration au démarrage comme l&#8217;indique le commentaire inséré par le template.</p>
<h3>DirectAction</h3>
<p style="text-align: justify;">Les direct actions sont des méthodes dites &laquo;&nbsp;stateless&nbsp;&raquo;. Elles n&#8217;ont pas besoin d&#8217;une session, bien qu&#8217;il soit possible de la transmettre par cookie par exemple, et sont accessible directement par leur URL à tout moment et par n&#8217;importe qui. La méthode la plus classique que l&#8217;on trouvera dans un fichier de direct action est la méthode d&#8217;authentification sur un site web, car on ne souhaite par forcement qu&#8217;elle soit couplée à une page en particulier et n&#8217;est associée à aucune session.</p>
<h3>Session</h3>
<p style="text-align: justify;">Comme son nom l&#8217;indique il s&#8217;agit de la classe qui sera instanciée pour créer des sessions pour les utilisateurs. Les attributs d&#8217;instance que vous y ajouté dureront aussi longtemps que la session de l&#8217;utilisateur durera. C&#8217;est ici généralement que l&#8217;on retrouve stocké l&#8217;utilisateur connecté et quelques autres informations. Lorsque vous vous trouvez dans un composant WebObjects, la session est simplement accessible à l&#8217;aide de la méthode session() qui par défaut demandera un cast vers le type Session de votre projet, le type renvoyé étant une classe de plus haut niveau.</p>
<p style="text-align: justify;">Dans le package components se trouve un unique fichier.</p>
<h3 style="font-size: 1.17em;">Main</h3>
<p style="text-align: justify;">Ce fichier au nom un peu trompeur ne contient pas le main de votre application (il est dans la classe Application, regardez juste au dessus :-p). Il s&#8217;agit de la page principale de votre application qui a été gentiment déjà créée pour vous. Ou plutôt une partie du composant Main, voir juste ci-dessous.</p>
<h2>Components</h2>
<p style="text-align: justify;">À côté du dossier Sources, vous remarquez un autre dossier appelé Components qui contient un élément Main WO, et conjointement dans le package com.pierreschambacher.series.components vous remarquez un Main.java. Sachez donc qu&#8217;un composant graphique WebObjects est constitué de plusieurs éléments portant tous le même nom mais des extentions différentes:</p>
<ul>
<li>Composant.html: fichier de template contenant du texte, des balises html et des balises WebObjects. C&#8217;est le principal fichier sur lequel vous allez travailler.</li>
<li>Composant.java: fichier de code qui permet de définir le comportement de votre page. N&#8217;oubliez pas que vous êtes cependant dans une vue et le code contenu ici devrait être minimaliste.</li>
<li>Composant.wod: vous allez définir ici la nature des webobjects défini dans votre fichier HTML et mettre en place le binding des variables à l&#8217;aide du fichier java, mais j&#8217;y reviendrais plus tard.</li>
<li>Composant.api: définition des bindings visibles depuis l&#8217;extérieur de votre composant. Vous pouvez définir qu&#8217;un binding est requis pour obliger le programmeur à vous le fournir par la suite.</li>
<li>Composant.woo: contient des informations comme la version de WebObjects, l&#8217;encodage des caractères et la configuration des DisplayGroups. Nous n&#8217;aborderons pas ce fichier, inutile d&#8217;y toucher.</li>
</ul>
<h2>Libraries</h2>
<p>Rien de particulier ici, il s&#8217;agit du dossier où déposer les fichiers jar nécéssaires à votre projet avant de les ajouter dans votre Build Path.</p>
<h2>Resources</h2>
<p>C&#8217;est dans ce dossier que se trouve le fichier de configuration Properties. C&#8217;est également ici que plus tard nous ajouterons notre modèle mais il est encore trop tôt pour cela.</p>
<h2>WebServerRessources</h2>
<p>Images, vidéos, fichiers de style CSS &#8230; les ressources statiques de votre site vont ici. Vous êtes libre de les organiser dans une hiérarchie de dossier.</p>
<h2>woproject</h2>
<p>NE TOUCHEZ PAS !! :-p</p>
<h1>Run as &#8230;</h1>
<p>Rien de compliqué pour cette opération. Faites un clic droit sur votre projet, choisissez &laquo;&nbsp;Run as&#8230;&nbsp;&raquo; ou plutôt &laquo;&nbsp;Debug as&#8230;&nbsp;&raquo;, puis WOApplication.<br />
eclipse recherche le main et vous demande de lui indiquer lequel choisir, prenez bien évidemment celui qui se trouve dans votre classe Application (dans mon cas dans le package com.pierreschambacher.series).</p>
<p>À cette étape, votre navigateur préféré se lance et affiche le message &laquo;&nbsp;Hello World&nbsp;&raquo;. Bravo vous venez de lancer votre première application WebObjects. <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h1>Modifier un composant</h1>
<p>Maintenant que vous avez pris connaissance de l&#8217;arborescence de votre nouveau projet, nous allons essayer de le modifier un petit peu !</p>
<p>REMARQUE IMPORTANTE: dans la mesure du possible lorsque vous avez une instance de l&#8217;application en train de fonctionner et que vous modifiez du code, WOLips va essayer de modifier votre instance &laquo;&nbsp;à chaud&nbsp;&raquo;. Des fois votre modification permettra un tel remplacement mais des fois le changement sera trop important pour le permettre et vous aurez une fenêtre d&#8217;alerte &laquo;&nbsp;Hot Code Replace Failed&nbsp;&raquo; vous demandant quoi faire. Ne vous inquietez pas, contentez vous de cliquer sur &laquo;&nbsp;Terminate&nbsp;&raquo; afin de tuer l&#8217;instance courante. Vous aurez simplement à relancer l&#8217;application une fois vos modifications terminées.</p>
<p>Ouvrez le dossier Components et double-cliquez sur Main et sa petite icône de pièce de puzzle. Eclipse ouvre une fenêtre partagée horizontalement en deux. La partie haute contient du HTML tout ce qu&#8217;il y a de plus classique et la partie basse est vide complètement.</p>
<h2>Mon premier WebObject</h2>
<p>Vous remarquez dans le code HTML une message &laquo;&nbsp;Hello World&nbsp;&raquo;. Supprimez ce texte et rentrez à la place la balise suivante:</p>
<blockquote><p>&lt;webobject name = &laquo;&nbsp;helloString&nbsp;&raquo; /&gt;</p></blockquote>
<p>Si vous sauvegardez maintenant, vous remarquez d&#8217;eclipse n&#8217;est pas très heureux parce que vous utilisé un WebObject helloString qu&#8217;il ne connait pas. Ajoutez donc les lignes suivantes dans la partie basse de la fenêtre jusqu&#8217;à présent encore vite:</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 937px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">helloString: WOString {</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 937px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span></div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 937px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">}</div>
<blockquote><p>helloString: WOString {</p>
<p>}</p></blockquote>
<p>Sauvegardez et vous remarquez qu&#8217;eclipse n&#8217;est toujours pas heureux parce que vous utilisez un WOString sans définir le binding &laquo;&nbsp;value&nbsp;&raquo; qui est requit ! Insérez donc entre les accolades:</p>
<blockquote><p>value = &laquo;&nbsp;Hello World !&nbsp;&raquo;;</p></blockquote>
<p>Et cette fois si après sauvegarde, eclipse est heureux. Relancez l&#8217;application et vous devriez avoir votre Hello World ! affiché dans votre navigateur préféré. Vous pouvez changer la chaîne de caractère pour ce que vous voulez, sauvegarder et actualiser la page, vous remarquez que le message affiché dans le navigateur change !<br />
Cependant sachez qu&#8217;il existe deux façon d&#8217;écrire les templates WebObjects. Vous venez d&#8217;utilisé l&#8217;ancienne façon, voyons à présent la nouvelle écrire apportée par le projet Wonder et que personnellement je préfère.</p>
<p>Supprimez complètement le contenu de la fenêtre du bas, le fichier WOD. Dans le fichier HTML, supprimez votre balise &lt;webobject&gt; et remplacez la par celle-ci:</p>
<blockquote><p>&lt;wo:str value = &laquo;&nbsp;Hello World !&nbsp;&raquo; /&gt;</p></blockquote>
<p>Vous remarquez que l&#8217;on a plus besoin de nommer notre variable ce qui je vous l&#8217;assure est un gros point positif. De plus à l&#8217;usage cette notation est plus pratique pour relire un fichier et savoir rapidement ce qu&#8217;il fait car on sait immédiatement ce que fait une balise sans avoir à consulter le WOD. Relancez l&#8217;application pour vérifier que tout va bien.</p>
<h2>Un peu de dynamisme</h2>
<p>Afficher une chaîne de caractère, c&#8217;est bien mais on voudrait pouvoir afficher quelqu&#8217;un d&#8217;un peu plus dynamique. Nous sommes au XXIème siècle quand même !</p>
<h3>Chaîne de caractère</h3>
<p>Dirigez vous vers votre fichier Main.java. Ajoutez une méthode currentTime renvoyant un objet String comme suit:</p>
<blockquote><p>public String currentTime() {<br />
<span style="white-space: pre;"> </span>return new java.util.Date().toString();<br />
}</p></blockquote>
<p>À présent dans votre fichier Main.html, remplacez dans la balise wo:str le value=&nbsp;&raquo;Hello World !&nbsp;&raquo; par value=&nbsp;&raquo;$currentTime&nbsp;&raquo;. La présente du caractère $ indique qu&#8217;il s&#8217;agit d&#8217;un binding. WebObjects va alors rechercher dans le fichier Java:</p>
<ol>
<li>une méthode getCurrentTime renvoyant un objet et ne prenant aucun paramètre</li>
<li>une méthode publique nommée currentTime, renvoyant un objet et ne prenant aucun paramètre</li>
<li>un attribut public nommé currentTime</li>
</ol>
<p>Vous aurez compris dans notre cas que WebObjects sera satisfait de trouver notre méthode fraichement créée. Dans le cas où plusieurs de ces éléments existent, ils sont choisis dans l&#8217;ordre indiqué, c&#8217;est donc une méthode get qui sera choisie en premier.</p>
<p>Relancez l&#8217;application, vous voyez l&#8217;heure actuelle affichée dans votre navigateur. Si vous actualisez la page, l&#8217;heure est mise à jour.</p>
<h3>Une date</h3>
<p>Nous avons renvoyé une chaîne de caractère afin d&#8217;afficher la date dans notre fenêtre. Cependant il existe une façon un peu plus propre de faire la même chose.</p>
<p>Changez la signature de la méthode currentTime, qui ne renvoie plus un objet String mais un objet NSTimestamp. Il suffit de créer une nouvelle instance de cet objet:</p>
<blockquote><p>public NSTimestamp currentTime() {<br />
<span style="white-space:pre"> </span>return new NSTimestamp();<br />
}</p></blockquote>
<p>Vous constatez alors que votre page affiche l&#8217;heure actuelle, mais il faut bien le dire, dans un format absolument dégueulasse ! Il faut à tout prix remédier à cela.<br />
Non non, modifier la méthode dans le fichier java n&#8217;est pas une bonne idée, ajoutez plutôt l&#8217;attribut dateFormat à votre balise wo:str comme suit:</p>
<blockquote><p>&lt;wo:str value = &laquo;&nbsp;$currentTime&nbsp;&raquo; dateformat = &laquo;&nbsp;HH:mm:ss dd/MM/yyyy&nbsp;&raquo; /&gt;</p></blockquote>
<p>Actualisez la page &#8230; c&#8217;est mieux non ? <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h4>Un peu d&#8217;Histoire</h4>
<p>WebObjects a été développé par la société NeXT en Objective C. Les classes utilisées en Objective C sont précédées par NS (NeXT Step). La société est rachetée plus tard par Apple mais les classes garderont historiquement ce préfixe. À partir de la version 4 de WebObjects, Java remplace petit à petit l&#8217;Objective C jusqu&#8217;à l&#8217;avoir complètement remplacé aujourd&#8217;hui mais afin de ne pas perdre les personnes ayant développé pendant longtemps en Objective C, les méthodes du framework ont été porté vers Java avec leur nom et leurs méthodes. Ce choix est fait au détriment en revanche des programmeurs Java qui devront apprendre à remplacer leurs classes habituelles par celles de WebObjects.</p>
<p>Comme vous l&#8217;avez vu dans l&#8217;exemple précédent, il faudra utiliser NSTimestamp en lui et place d&#8217;une Date.<br />
Pour les tableaux, oubliez l&#8217;ArrayList, vous allez utiliser les classes NSArray et NSMutableArray. Pourquoi deux classes me direz vous ? Comme leur nom l&#8217;indique, l&#8217;un est un tableau, l&#8217;autre un tableau modifiable. Si vous avez besoin en paramètre d&#8217;un tableau que vous n&#8217;allez pas modifier, indiquez qu&#8217;il s&#8217;agit d&#8217;un NSArray, mais si vous avez l&#8217;intention de changer son contenu utilisez NSMutableArray. Si vous avez un NSArray et que vous tenez absolument à pouvoir effectuer des modifications sur ses éléments vous disposez de la méthode mutableClone qui créera un clone de votre NSArray en version Mutable.<br />
Pour les dictionnaires, oubliez la HashMap et dites bonjour à NSDictionary et NSMutableDictionary . Je vous renvoie au paragraphe précédent pour le Mutable/non Mutable.<br />
Si vous aimez utiliser les Sets, utilisez NSSet et NSMutableSet.</p>
<h2>Interaction avec l&#8217;utilisateur</h2>
<p>Suffit d&#8217;afficher la date dans son navigateur sauf si vous êtes en train de créer horloge-parlante.com ! Nous allons inviter l&#8217;utilisateur à rentrer son nom et le saluer pour le remercier.</p>
<h3>Mise en place</h3>
<p>Modifiez votre fichier HTML pour obtenir le résultat suivant dans la partie body:</p>
<blockquote><p>&lt;wo:form&gt;<br />
<span style="white-space: pre;"> </span>Enter your name: &lt;wo:textfield value = &laquo;&nbsp;$username&nbsp;&raquo; /&gt;<br />
<span style="white-space: pre;"> </span>&lt;wo:submit value = &laquo;&nbsp;Say hi&nbsp;&raquo; action = &laquo;&nbsp;$sayHi&nbsp;&raquo; /&gt;<br />
&lt;/wo:form&gt;<br />
&lt;br /&gt;<br />
&lt;h1&gt;Hello &lt;wo:str value = &laquo;&nbsp;$username&nbsp;&raquo; /&gt; !&lt;/h1&gt;</p></blockquote>
<p>Si vous sauvez, vous constaterez d&#8217;eclipse n&#8217;est pas vraiment heureux parce qu&#8217;il ne trouve pas username et sayHi dans votre fichier Java. Nous allons résoudre le problème. Ne quittez pas le fichier HTML, maintenez le bouton Command enfoncé et placez votre souris sur $username, vous remarquez que le nom se transforme en lien. Si vous cliquez, eclipse vous indique qu&#8217;il ne trouve pas username dans votre fichier Java et se propose de le créer pour vous. Voyons les différents éléments de cette boîte de dialogue</p>
<ul>
<li>les boutons radio vous permettent de choisir si votre binding est un objet, un NSArray d&#8217;objets ou un NSMutableArray d&#8217;objet.</li>
<li>le champ texte permet de choisir le type de notre objet, ici java.lang.String nous convient parfaitement.</li>
<li>les checkbox suivantes permettent de demander la génération d&#8217;un attribut, d&#8217;un get et d&#8217;un set, ce qui est coché par défaut. Vous pouvez choisir de mettre &laquo;&nbsp;get&nbsp;&raquo; ou non sur le getter avec la dernière checkbox.</li>
</ul>
<p>Dans notre cas tout est configuré comme il faut, faite simplement OK et vous vous retrouvez dans le fichier Java où vous constatez qu&#8217;eclipse s&#8217;est chargé de générer un attribut privé username, une méthode publique username qui renvoie cet attribut et une méthode setUsername qui s&#8217;occupe de peupler l&#8217;attribut. Concernant username eclipse est heureux.</p>
<p>Retournez dans le fichier HTML, command-clic sur $sayHi qui est une action et remarquez que cette fois ci eclipse propose de créer une méthode renvoyant un objet de type WOActionResult. Cliquez sur OK la configuration par défaut nous convient. Voici la méthode générée:</p>
<blockquote><p>public WOActionResults sayHi() {<br />
<span style="white-space: pre;"> </span>return null;<br />
}</p></blockquote>
<p>Petite explication. Les actions sont des méthodes qui permettent de définir un comportement sur une action de l&#8217;utilisateur, par exemple ici le clic sur le bouton submit.<br />
L&#8217;objet retourné par une action est très important car il définit la prochaine page à afficher. Si la méthode retourne null, alors c&#8217;est la même page qui est regardée, sinon c&#8217;est la page retournée qui sera envoyée au client. Pour créer une page différente, utilisez la méthode pageWithName qui possède deux signatures. Nous y reviendrons un peu plus tard dans ce tutoriel dans la section &laquo;&nbsp;Deuxième composant&nbsp;&raquo;.</p>
<p>Dans le cas présent, il suffit de recharger la page courante, donc laissez la méthode générée telle quelle. Sauvegardez tout et lancez l&#8217;application, ça fonctionne, magique non ? <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h3>Explications</h3>
<p>Vous n&#8217;avez pas l&#8217;impression d&#8217;avoir fait grand chose et pourtant ça marche. Faisons un petit retour sur le fonctionnement de cette page.</p>
<p>Concernant le wo:str, vous voyez qu&#8217;il y a un binding de value sur username, donc de façon très simple au moment du chargement de la page la méthode username est appelée et insérée dans la page. Rien n&#8217;a changé par rapport à tout à l&#8217;heure.</p>
<p>Pour le wo:textfield et le wo:submit, vous avez mis en place un binding à l&#8217;aide de l&#8217;élément value du textfield sur username. Donc au chargement de la page la valeur de username est utilisée pour remplir le textfield, mais dans le cas d&#8217;un retour d&#8217;informations, comme c&#8217;est le cas avec le clic sur le bouton submit, c&#8217;est la méthode SET qui est appelée pour modifier la valeur dans le fichier Java avec la valeur que l&#8217;utilisateur a mis dans son navigateur. Comme l&#8217;action du bouton submit renvoie null, la même page est rechargée avec cette fois ci username différent de null.</p>
<p>Vous l&#8217;aurez compris, certains bindings fonctionnent uniquement en GET, comme le value du wo:str, et d&#8217;autres fonctionnent en GET et SET comme le value du textfield. Consultez la documentation pour savoir à quel type de binding vous avez affaire, de toute façon c&#8217;est généralement assez explicite. Dernier type de binding, les actions pour réagir aux actions utilisateurs. Quelque chose que vous remarquez rapidement, votre fichier HTML a connaissance des éléments publiques de votre fichier Java, mais ce dernier ignore totalement l&#8217;existence de la page HTML. Tout fonctionne par bindings, il faudra vous habituer.</p>
<h3>Améliorations</h3>
<p>Première chose, vous avez remarqué qu&#8217;au premier chargement il est simplement affiché &laquo;&nbsp;Hello  !&nbsp;&raquo; ce qui est un peu bête. Ajoutez sur votre wo:str le binding suivant:</p>
<blockquote><p>valueWhenEmpty = &laquo;&nbsp;World&nbsp;&raquo;</p></blockquote>
<p>Rafraichissez la page. Mieux non ? <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
Deuxième petite amélioration-démonstration, sur le binding value du wo:str, changez le pour mettre ceci:</p>
<blockquote><p>value = &laquo;&nbsp;$username.toUpperCase&nbsp;&raquo;</p></blockquote>
<p>Rafraichissez de nouveau. Vous aurez compris, rien n&#8217;empêche dans un binding d&#8217;utiliser un chaînage de méthodes.</p>
<h1>Deuxième Composant</h1>
<p>Dernier point que nous aborderons sur ce tutoriel, nous allons créer un deuxième composant et créer un lien entre les deux.</p>
<p>Sur le dossier Components, faite un clic droit New &gt; WOComponent. Entrez comme nom &laquo;&nbsp;About&nbsp;&raquo; et assurez vous que la superclass est er.extensions.components.ERXComponent et que la case &laquo;&nbsp;Create HTML contents&nbsp;&raquo; soit cochée. Vous avez votre deuxième composant WebObjects. Mettez ce que vous souhaitez dans le HTML pour reconnaitre votre page About puis retournez dans votre page Main. Ajoutez un nouveau composant dans le HTML comme ceci:</p>
<p>&lt;wo:link string = &laquo;&nbsp;About&nbsp;&raquo; action = &laquo;&nbsp;$openAbout&nbsp;&raquo; /&gt;</p>
<p>Comme tout à l&#8217;heure, command-clic sur openAbout et laissez eclipse créer le squelette de la méthode pour vous. Dans le code remplacez le return null par ceci:</p>
<p>return pageWithName(About.class);</p>
<p>Vous disposez également de la signature suivante:</p>
<p>return pageWithName(About.class.getName());</p>
<p>Lorsque vous utilisez la méthode pageWithName, utilisez toujours le style MonComposant.class et jamais &laquo;&nbsp;MonComposant&nbsp;&raquo;. Cela au cas où vous souhaiteriez renommer votre composant un jour. La méthode pageWithName va instancier votre composant et l&#8217;initialiser, et en étant retourné par l&#8217;action vous indiquez à WebObjects qu&#8217;il s&#8217;agit de la prochaine page à afficher. Compilez et lancez l&#8217;application et observez le résultat.</p>
<h1>Conclusion</h1>
<p>Suite à ce tutoriel vous devriez avoir compris comment créer une page, y insérer du HTML et des composants mélangés. Vous savez mettre en place des bindings avec le code Java, changer la page courante, créer des données dynamiques. Vous êtes cependant un peu léger concernant les composants que vous connaissez, le prochain tutoriel sera consacré à la liste des principaux composants que l&#8217;on utilise 80% du temps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutoriel pour développeur WebObjects: install party</title>
		<link>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-install-party/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=tutoriel-pour-developpeur-webobjects-install-party</link>
		<comments>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-install-party/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 17:46:05 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[Tutoriaux WebObjects]]></category>
		<category><![CDATA[tutoriel]]></category>
		<category><![CDATA[webobjects]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=219</guid>
		<description><![CDATA[Un des plus gros défauts de WebObjects est la difficulté de la documentation sur le net. Cela est notamment du au fait qu&#8217;une des meilleurs source de documentation est un ensemble de screencasts, et une vidéo n&#8217;est pas forcement bien référencée par Google. D&#8217;une manière générale, la plupart des sites de documentation de WebObjects ne [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Un des plus gros défauts de WebObjects est la difficulté de la documentation sur le net. Cela est notamment du au fait qu&#8217;une des meilleurs source de documentation est un ensemble de screencasts, et une vidéo n&#8217;est pas forcement bien référencée par Google. D&#8217;une manière générale, la plupart des sites de documentation de WebObjects ne sont d&#8217;ailleurs pas bien référencés du tout &#8230; Il existe bien sûr des sites de documentation Javadoc, mais ce n&#8217;est pas vraiment ce dont on a envie lorsque l&#8217;on a jamais fait une seule ligne de WebObjects et que l&#8217;on souhaite s&#8217;y mettre, par envie ou par besoin.<br />
Il est plus facile de critiquer que d&#8217;essayer d&#8217;améliorer les choses &#8230; aussi voici ma modeste contribution pour aider les gens qui souhaiteraient se former à WebObjects à l&#8217;aide d&#8217;un petit tutoriel, et en Français s&#8217;il vous plait <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  (je n&#8217;aurais pas le temps et la motivation de traduire en anglais mais si quelqu&#8217;un de motivé pouvait me faire parvenir les versions traduites de mes tutoriaux, ils seront publiés ici avec son nom).</p>
<p><span id="more-219"></span></p>
<h1 style="text-align: justify;">Présentation rapide</h1>
<p style="text-align: justify;">Développer en WebObjects se fait sous Mac OS X avec eclipse équipé du plug-in WoLips.<br />
À l&#8217;origine WebObjects est développé et maintenu par Apple. Toutefois ils sont assez lents à apporter des mises à jours notamment pour correspondre aux besoins du web moderne comme par exemple des composants Ajax. Pour combler ces manques, le projet Wonder a été créé. Celui-ci est OpenSource et propose non pas d&#8217;être une surcouche à WebObjects (dans le sens couche logicielle par dessus une autre) mais remplace la plupart des classes du framework par un équivalent qui dans la plupart des cas hérite du composant d&#8217;origine. En clair, vous n&#8217;allez plus utiliser un WOTextField mais un ERXTextField, qui hérite de WOTextfield et lui ajoute quelques nouveautés.</p>
<p style="text-align: justify;">De ce que j&#8217;en sais, il est possible de développer en WebObjects sous Windows mais Apple ne le supporte pas &#8230; Je n&#8217;aborderais pas ce point mais si quelqu&#8217;un a l&#8217;expérience de développement WO sous Windows, libre à lui de laisser un commentaire.</p>
<p style="text-align: justify;">Une version imprimable de ce tutoriel est disponible au format <a class="wp-caption" style="font-size: 14pt;" title="Tutoriel au format PDF" href="http://www.pierreschambacher.com/wp-content/uploads/2009/11/Install-Paty.pdf" target="_blank"><strong>PDF</strong></a>.</p>
<h1 style="text-align: justify;">Base de données</h1>
<p style="text-align: justify;">Le développement en WebObjects se fait généralement au dessus d&#8217;une base de données. Assurez vous donc d&#8217;en avoir une d&#8217;installée sur votre machine.<br />
J&#8217;ai personnellement fait le choix d&#8217;utiliser <a title="MySQL 5.1 pour Mac OS X" href="http://dev.mysql.com/downloads/mysql/5.1.html#macosx-dmg" target="_blank">MySQL 5.1</a> avec le <a title="MySQL GUI Tools" href="http://dev.mysql.com/downloads/gui-tools/5.0.html" target="_blank">MySQL GUI Tools</a> pour l&#8217;administrer. Certains puristes vous orienteraient plutôt vers <a title="Téléchargement de Frontbase" href="http://www.frontbase.com/cgi-bin/WebObjects/FrontBase" target="_blank">Frontbase</a>, je n&#8217;entrerais pas dans le débat. <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align: justify;">Pour cette partie je vous laisse faire, vous disposez qui plus est peut-être déjà d&#8217;une base de donnée sur votre machine donc autant l&#8217;utiliser. Il suffira de s&#8217;adapter dans les prochains tutoriels lors de la configuration de la base de données, ce qui n&#8217;est vraiment pas difficile.</p>
<h1 style="text-align: justify;">Eclipse</h1>
<p style="text-align: justify;">Comme vous pourrez le voir sur le site de la <a title="WO Community" href="http://www.wocommunity.org/" target="_blank">WO Community</a> la version 3.5 d&#8217;eclipse n&#8217;est pas vraiment recommandée pour faire du développement WebObjects. Orientez vous donc vers la version 3.4 et de préférence en version développement J2EE notamment pour la gestion de ant et d&#8217;autres parties bien pratiques. Vous trouverez l&#8217;archive d&#8217;eclipse sur cette page: <a title="eclipse ganymede" href="http://www.eclipse.org/downloads/packages/release/ganymede/sr2" target="_blank">eclipse ganymede</a>.</p>
<p style="text-align: justify;">Quelques conseils à propos de eclipse. Dès que vous l&#8217;avez installé, rendez vous dans le menu des Préférences afin d&#8217;y effectuer quelques changements:</p>
<ul>
<li>dans General &gt; Workspace mettez l&#8217;encodage du texte par défaut sur UTF-8</li>
<li>dans General &gt; Workspace toujours mettez la fin de ligne sur Unix, c&#8217;est à dire &#8216;\n&#8217;</li>
<li>dans General &gt; Keys assignez un raccourci qui vous convient pour &laquo;&nbsp;Content Assist&nbsp;&raquo; (qui affiche l&#8217;aide pour auto-complétion)</li>
<li>dans General &gt; Keys assignez un raccourci qui vous convient pour la génération de Getter et Setter, c&#8217;est plus pratique pour travailler vite</li>
</ul>
<p>Pour le reste, je vous renvoie à mon billet sur les r<a title="Raccourcis Clavier" href="http://www.pierreschambacher.com/blog/raccourcis-clavier/" target="_blank">accourcis claviers</a>, sections General et Eclipse.</p>
<h1 style="text-align: justify;">WebObjects</h1>
<p style="text-align: justify;">Sauf indication contraire, je vous oriente vers la version 5.4.3 qui est disponible à cette <a title="WebObjects 5.4.3" href="http://download.info.apple.com/Mac_OS_X/061-4634.20080915.3ijd0/WebObjects543.dmg" target="_blank">adresse</a>. Si vous utilisez Mac OS 10.5 il est possible que vous ayez une version récente d&#8217;installée. Pour les utilisateur de la 10.6 dite Snow Leopard, WebObjects n&#8217;est plus installée par défaut. Utilisez donc le lien que je viens de fournir.</p>
<h1>Wonder</h1>
<p style="text-align: justify;">Vous trouverez les fichiers nécessaires au bon fonctionnement de Wonder sur leur <a title="Wonder installation" href="http://webobjects.mdimension.com/wonder/" target="_blank">site officiel</a>. Prenez le fichier Wonder-latest-Frameworks suivi de la version de WebObjects que vous avez choisi (5.3 ou 5.4).<br />
Une fois l&#8217;archive récupérée et décompressez, déplacez tous les dossiers .framework vers /Library/Frameworks. Félicitation, vous avez installé Wonder. <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h1>WOLips</h1>
<p style="text-align: justify;">Maintenant qu&#8217;eclipse est correctement installé, il est temps d&#8217;ajouter le plug-in WOLips.<br />
Celui ci est très simple à installer. Direction le menu &laquo;&nbsp;Help&nbsp;&raquo; puis &laquo;&nbsp;Software Updates&#8230;&nbsp;&raquo; tout en bas du menu. Ouvrez le panneau &laquo;&nbsp;Available Software&nbsp;&raquo; et repérez à droite le bouton &laquo;&nbsp;Add Site&#8230;&nbsp;&raquo;.</p>
<p style="text-align: justify;">L&#8217;adresse du dépot est la suivante: <a title="Depot wolips pour eclipse" href="http://webobjects.mdimension.com/hudson/job/WOLipsStable/lastSuccessfulBuild/artifact/site/" target="_blank">http://webobjects.mdimension.com/hudson/job/WOLipsStable/lastSuccessfulBuild/artifact/site/</a><br />
Une fois  le nouveau dépot disponible, déroulez le et choisissez dans Standart Install les paquets WOLips, WOLips Base, WOLips Goodies Mac et WOLips Third Party Feature. Cliquez sur Install, acceptez le contrat de licence et à la fin de la barre de progression, eclipse vous indiquera qu&#8217;il souhaite redémarrer. Une fois cela fait vous disposez à présent de la Perspective &laquo;&nbsp;WOLips&nbsp;&raquo;, et vous pouvez créer un projet de type &laquo;&nbsp;WebObjects Application&nbsp;&raquo; ou &laquo;&nbsp;Wonder Application&nbsp;&raquo;.</p>
<h1>Félicitations</h1>
<p style="text-align: justify;">Vous venez de terminer l&#8217;installation de votre environnement de travail pour attaquer le développement sur WebObjects.<br />
Le prochain tutoriel abordera la création de mon premier projet, son premier model et la mise en place d&#8217;une première page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-install-party/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Pourquoi je souhaite arrêter le Flex</title>
		<link>http://www.pierreschambacher.com/blog/pourquoi-je-souhaite-arreter-le-flex/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=pourquoi-je-souhaite-arreter-le-flex</link>
		<comments>http://www.pierreschambacher.com/blog/pourquoi-je-souhaite-arreter-le-flex/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 20:04:25 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[cv]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=202</guid>
		<description><![CDATA[Dans ma recherche d&#8217;emploi, nombreux ont été ceux qui m&#8217;ont proposé un poste de développeur Flex, et beaucoup ont été surpris d&#8217;apprendre que je ne souhaitais plus en faire.
Outrage que ce jeune diplômé qui saborde sa plus grosse expérience et voudrait changer d&#8217;horizon !! Voici donc quelques explications pour expliquer ma décision qui pourraient en [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Dans ma recherche d&#8217;emploi, nombreux ont été ceux qui m&#8217;ont proposé un poste de développeur Flex, et beaucoup ont été surpris d&#8217;apprendre que je ne souhaitais plus en faire.<br />
Outrage que ce jeune diplômé qui saborde sa plus grosse expérience et voudrait changer d&#8217;horizon !! Voici donc quelques explications pour expliquer ma décision qui pourraient en guider certains dans le choix de la technologie.</p>
<p style="text-align: justify;"><span id="more-202"></span></p>
<h1 style="text-align: justify;">Expert bien avant l&#8217;heure</h1>
<p style="text-align: justify;">Flex est une technologie jeune qui a le vent en poupe depuis peu. Combien de personnes en France peuvent justifier une expérience professionnelle d&#8217;un an de développement sur ce framework ? Peu.<br />
Aussi malgré le fait que je sorte à peine d&#8217;école, je suis considéré comme &laquo;&nbsp;Expert Flex&nbsp;&raquo;. Les propositions qui m&#8217;ont été faites sur Flex était simples: vous savez des choses, utilisez les ! Mais ça ne colle pas vraiment avec ma vision du premier emploi. Je n&#8217;ai pas l&#8217;âge d&#8217;être un expert, j&#8217;ai envie d&#8217;apprendre des choses, découvrir de nouvelles possibilités. J&#8217;ai envie que mon entreprise m&#8217;apporte quelque chose en retour du travail que je fournis, et non pas livrer mes connaissances sans en avoir en retour, ou trop peu.</p>
<h1 style="text-align: justify;">Outil principalement graphique</h1>
<p style="text-align: justify;">Lorsque l&#8217;on fait une application il y a deux aspects: la logique métier et l&#8217;aspect graphique.<br />
Personnellement c&#8217;est la logique métier qui m&#8217;amuse le plus, la réflexion sur le modèle, les algorithmes, &#8230; Faire les fenêtres ne me dérange pas mais je ne suis pas bon d&#8217;une part, et je n&#8217;ai pas envie de me prendre la tête avec d&#8217;autre part. Le soucis avec Flex est que l&#8217;on passe la plupart de son temps à travailler sur l&#8217;aspect graphique. La principale préoccupation dans le développement en Flex est d&#8217;encastrer correctement les éléments d&#8217;interface tout en trouvant comment contourner les limitations imposées pour arriver à ce que l&#8217;on veut &#8230;<br />
Après, je parle pour moi-même ! De très nombreuses personnes s&#8217;éclatent sans doute à faire des interfaces bien agencées mais ce n&#8217;est pas mon cas, et ça transforme donc souvent Flex en source d&#8217;ennui.</p>
<h1 style="text-align: justify;">Limitations &#8230;</h1>
<p style="text-align: justify;">Je l&#8217;ai abordé précédemment, le framework en version 3 est par endroit vraiment mal foutu. L&#8217;API est pauvre, certaines choses sont mal pensées et on finit rapidement par passer plus de temps à réfléchir sur les difficultés de l&#8217;outil que sur l&#8217;application sur laquelle on travaille&#8230; Depuis quelques jours j&#8217;ai recommencé à faire du Java et je suis en permanence impressionné par la rapidité et la facilité avec laquelle j&#8217;avance. Inutile de luter contre le langage et le framework, au contraire ils aident à aller plus vite !!!<br />
Pour reprendre le point précédent, je dirais qu&#8217;avec Flex on passe 20% de son temps à faire du code métier, 30% de son temps à coder des contournements du framework et 50% de son temps à lutter avec les composants graphiques. Un outil bien peu productif donc au final.</p>
<h1 style="text-align: justify;">Enfermement</h1>
<p style="text-align: justify;">Après avoir vu l&#8217;effet d&#8217;une expérience d&#8217;un an, je n&#8217;ai pas envie de voir comment je serais traité si je venais à avoir une expérience de 5 ans en Flex&#8230; En tant que jeune diplômé j&#8217;ai encore la possibilité facilement de changer d&#8217;horizon car les entreprises tolèrent que je débute, mais d&#8217;ici quelques années ce sera sans doute plus difficile à faire.<br />
J&#8217;évite cet enfermement d&#8217;une part parce que je ne me vois pas faire du Flex toute ma carrière, mais aussi parce que cela peut s&#8217;avérer dangereux. Miser toute ma carrière sur une technologie qui aura peut-être complètement disparu dans quelques années n&#8217;est pas rassurant. Même si Flex est à la mode en ce moment, qui sait ce qu&#8217;il adviendra dans les 5 ans à venir ? Notamment avec son étroite collaboration avec Flash que beaucoup de gens voudraient voir disparaitre de leur navigateur&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/pourquoi-je-souhaite-arreter-le-flex/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>git in a nutshell</title>
		<link>http://www.pierreschambacher.com/blog/git-in-a-nutshell/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=git-in-a-nutshell</link>
		<comments>http://www.pierreschambacher.com/blog/git-in-a-nutshell/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 19:45:00 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[billet invité]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=172</guid>
		<description><![CDATA[Aujourd&#8217;hui, place à un billet invité. C&#8217;est mon ami Grégory Soutadé qui propose un petit tutoriel pour apprendre à utiliser les différentes commandes de GIT, le gestionnaire de versions, pour un usage personnel. J&#8217;ai modestement aidé à la rédaction et mise en forme de ce document que vous trouverez très bientôt au format PDF.
Vous vous [...]]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui, place à un billet invité. C&#8217;est mon ami Grégory Soutadé qui propose un petit tutoriel pour apprendre à utiliser les différentes commandes de GIT, le gestionnaire de versions, pour un usage personnel. J&#8217;ai modestement aidé à la rédaction et mise en forme de ce document que vous trouverez très bientôt au format PDF.</p>
<p style="text-align: justify;">Vous vous lancez dans un petit projet perso ? Vous aurez toutes les clés en main pour que GIT soit votre gestionnaire de versions sur ce projet.</p>
<p style="text-align: justify;"><em>Cet article ne se veut pas exhaustif mais reflète le résultat d&#8217;un usage quotidien par un autodidacte. Si vous souhaitez corriger une éventuelle erreur ou partager une connaissance, n&#8217;hésitez pas à laisser un commentaire.<br />
Il est recommandé pour la bonne compréhension de cet article de connaitre SVN.<br />
L&#8217;auteur du tutoriel est un utilisateur Linux et certaines commandes peuvent poser problème sur d&#8217;autres système (notamment gitk).</em></p>
<p style="text-align: justify;"><em><span style="text-decoration: underline;">Note à nos amis sous Windows:</span> vous pouvez utiliser git sur Windows à l&#8217;aide de msysgit disponible <a title="Git pout Windows" href="http://code.google.com/p/msysgit/">ici</a>.<br />
</em></p>
<p style="text-align: justify;"><span id="more-172"></span></p>
<p style="text-align: justify;">Tout d&#8217;abord qu&#8217;est ce que git ?! Et bien avant d&#8217;être un logiciel de gestion de versions décentralisé (ou DSCM pour Distributed Source Code Management) il a été conçu comme un système de fichiers avec un système de versionning, le tout construit pour la performance. Et quoi de plus normal quand on sait qu&#8217;il était destiné à être le système de gestion de versions du noyau Linux en remplacement de BitKeeper. Git a été écrit par Junio Hamano et Linus Torvald lui même. Bref on a entre les mains un gros bébé, pourtant simple à utiliser et performant : tout est instantané !<br />
On entend par décentralisé le fait de pouvoir « commiter » et faire évoluer un bout de code en local indépendamment d&#8217;un serveur central (contrairement à svn qui nécessite un serveur central), cela offre un confort de développement très important car on ne commite que ce qui marche VRAIMENT. Bien sûr on a tout le loisir de travailler avec un serveur central, il est même possible de faire des ponts avec un serveur svn, mais l&#8217;aspect collaboratif ne sera pas abordé ici.</p>
<p style="text-align: justify;">Comme pour svn, chaque commit donne lieu à une nouvelle version (ou révision). Git a choisit non pas d&#8217;utiliser des numéros de révision, mais un identifiant unique SHA-1 pour chaque commit (donc révision). Cela évite d&#8217;avoir des conflits entre les différentes révisions de toutes les branches de tous les clones du dépôt. Il n&#8217;est pas toujours nécessaire d&#8217;indiquer le SHA-1 complet d&#8217;un objet, mais seulement les premiers octets qui le différencie des autres objets. Si j&#8217;ai deux commits :<br />
<strong>3bdc</strong>6feaa01b6b86a0f94acab32bc3ad4c207a5d<br />
<strong>3bdc</strong>4d695b90545c891392a486da9a9e07c053b<br />
je peux identifier le premier avec 3bdc6 et le second avec 3bdc4</p>
<p style="text-align: justify;">Chaque commande git peut être appelée de deux manières différentes :</p>
<blockquote>
<p style="text-align: justify;">git commande</p>
</blockquote>
<p style="text-align: justify;">Après ces petites notions théoriques passons à la pratique !!</p>
<h1 style="text-align: justify;">Par où qu&#8217;on commence ?</h1>
<p style="text-align: justify;">Et bien pour commencer il faut initialiser ou récupérer un dépôt. Avant d&#8217;initialiser un dépôt il faut renseigner quelques variables permettant de vous identifier lors des commit. Donc :</p>
<blockquote>
<p style="text-align: justify;">git config &#8211;global user.name Grégory<br />
git config &#8211;global user.email greg@wordpress.com<br />
git config &#8211;global core.editor emacs<br />
mkdir MonDepot<br />
cd MonDepot<br />
git init</p>
</blockquote>
<p style="text-align: justify;">L&#8217;avant dernière ligne est importante si vous ne savez/voulez pas utiliser vim comme éditeur de messages lors des commits. Un joli fichier ~/.gitconfig contiendra votre configuration pour les projets suivants. Si vous omettez le –global, les informations ne seront inscrites que pour le dépôt crée.</p>
<p style="text-align: justify;">Il est aussi possible de récupérer un dépôt git déjà existant depuis : ssh, système de fichier local, internet (http://, ftp://, git://) :</p>
<blockquote>
<p style="text-align: justify;">git clone soutade@monserveur:/mondepot mondepot<br />
git clone /mon/de/pot mondepot<br />
git clone http://www.kernel.org/mondepot<br />
&#8230;</p>
</blockquote>
<h1 style="text-align: justify;">Et maintenant qu&#8217;on a un beau dépôt ?!</h1>
<p style="text-align: justify;">Et bien il faut faire des opérations sur les fichiers :</p>
<h2 style="text-align: justify;">Modification</h2>
<blockquote>
<p style="text-align: justify;">emacs MonFichier.c</p>
</blockquote>
<h2 style="text-align: justify;">Ajout au dépôt</h2>
<blockquote>
<p style="text-align: justify;">git add MonFichier.c</p>
</blockquote>
<h2 style="text-align: justify;">Renomage du fichier</h2>
<blockquote>
<p style="text-align: justify;">git mv [-f] MonFichier.c MonFichier2.c</p>
</blockquote>
<p style="text-align: justify;">Si vous ne passez par cette commande, git considère que le fichier aura été supprimé et il faudra faire un git add sur le nouveau fichier.<br />
-f pour forcer le rennomage (si le fichier existe)</p>
<h2 style="text-align: justify;">Suppression</h2>
<blockquote>
<p style="text-align: justify;">git rm [-f] [--cached] MonFichier.c</p>
</blockquote>
<p style="text-align: justify;">Si vous ajoutez l&#8217;option –cached, le fichier sera uniquement supprimé du gestionnaire de versions, mais pas du système de fichier.</p>
<h1 style="text-align: justify;">Oui, mais maintenant ça compile !</h1>
<p style="text-align: justify;">Si ça compile, c&#8217;est que ça marche (&#8230;). Bref il est temps de commiter ! Mais avant j&#8217;effectue toujours deux opérations :</p>
<blockquote>
<p style="text-align: justify;">git status</p>
</blockquote>
<p style="text-align: justify;">Cela permet de voir les fichiers ajoutés/supprimés/modifiés, voir si on n&#8217;a rien oublié (un nouveau fichier par exemple). « Untracked files » correspond aux fichiers qui existent mais qui ne sont pas (encore) pris en compte dans le gestionnaire de versions.</p>
<blockquote>
<p style="text-align: justify;">git diff [--color]</p>
</blockquote>
<p style="text-align: justify;">Avec cette opération on peut visualiser les modifications (au format « patch ») effectuées sur nos fichiers, cela va nous aider à renseigner le message du commit.</p>
<p style="text-align: justify;">Cette commande peut prendre plusieurs options :</p>
<blockquote>
<p style="text-align: justify;">git diff [--color] [&lt;commit1&gt;..&lt;commit2&gt;] [--] [paths]</p>
</blockquote>
<p style="text-align: justify;">et toutes les options de diff</p>
<p>&lt;commit1&gt;..&lt;commit2&gt; est un intervalle de commits, sachant que &lt;commit&gt; peut être désigné sous la forme :</p>
<ul>
<li> le SHA-1 d&#8217;un commit</li>
<li> le tag</li>
<li> une référence depuis le commit courant</li>
</ul>
<p style="text-align: justify;">
<p style="text-align: justify;">paths correspond à n fichiers</p>
<h2 style="text-align: justify;"><em>Apparté</em> : Le commit courant</h2>
<p style="text-align: justify;">Dans git, le commit courant (ou dernier commit avant modifications) s&#8217;appelle HEAD. On peut accéder aux commits précédents en les référençant par rapport à HEAD :<br />
HEAD^ : Père du commit courant<br />
HEAD^^ : Grand père du commit courant<br />
HEAD~n : ancêtre de nième génération de HEAD (grand grand &#8230; grand parent de HEAD)</p>
<p style="text-align: justify;">
<h2 style="text-align: justify;"><em>Apparté</em> : .gitignore</h2>
<p style="text-align: justify;">.gitignore est un fichier à créer dans le dépôt git pour ignorer un certains nombre de fichiers (dans git status). Par exemple tous les fichiers « MonFichier~ » crées par emacs. A chaque ligne on intègre une expression régulière pour le ou les fichiers à ignorer (*~ pour emacs):<br />
Si la ligne fini par /, cela désigne un répertoire et tous ce qu&#8217;il y a dessous.<br />
Si la ligne commence par !, on a la négation de l&#8217;expression.<br />
Si la ligne est vide ou qu&#8217;elle commence par #, elle est ignorée.</p>
<p style="text-align: justify;">Étant donné qu&#8217;on ne va pas re créer ce fichier pour chaque dépôt, on peut en spécifier un qui sera réutilisé à chaque fois (qui peut être composé avec un .gitignore interne au dépôt). Pour cela il faut créer un fichier quelconque avec les même règles que .gitignore et inscrire la variable globale core.excludesfile :</p>
<blockquote>
<p style="text-align: justify;">git config &#8211;global core.excludesfile CheminFichier</p>
</blockquote>
<p>Attention toutefois, le chemin ne supporte pas ~ (Référence à la racine du répertoire personnel).</p>
<p style="text-align: justify;">
<p style="text-align: justify;">Et le tant attendu :</p>
<blockquote>
<p style="text-align: justify;">git commit [-a] [-m « message »] [paths]</p>
</blockquote>
<p style="text-align: justify;">L&#8217;option -a (recommandée) permet d&#8217;ajouter toutes les modifications au dépôt, sinon il faut spécifier les fichiers dans paths ou faire explicitement un git add (même sur des fichiers modifiés) pour chaque fichier à intégrer au commit.<br />
Si vous ne précisez pas le message sur la ligne de commande (-m), un éditeur va s&#8217;ouvrir (vim par défaut) pour que vous entriez le message du commit. Le message du commit est obligatoire !</p>
<p style="text-align: justify;">Si Bob s&#8217;est trompé dans son message de commit, il est toujours possible de le modifier avec :</p>
<blockquote>
<p style="text-align: justify;">git commit &#8211;amend -c &lt;commit&gt;</p>
</blockquote>
<h1 style="text-align: justify;">Un peu d&#8217;histoire</h1>
<p style="text-align: justify;">Maintenant qu&#8217;on a fait plusieurs commits et que notre projet grossi il peut être intéressant d&#8217;avoir un résumé de l&#8217;état du projet. Pour cela deux commandes :</p>
<blockquote>
<p style="text-align: justify;">git log [options] [&lt;commit1&gt;..&lt;commit2&gt;] [--] [paths]</p>
</blockquote>
<p style="text-align: justify;">Liste des commits avec leurs message influant sur les fichiers paths.</p>
<blockquote>
<p style="text-align: justify;">git show [options] &lt;commit&gt; [--] [paths]</p>
</blockquote>
<p style="text-align: justify;">Contenu de tous les fichiers modifiés ou seulement ceux dans paths.<br />
Les options sont celles de git diff.</p>
<p style="text-align: justify;">En ligne de commande la visualisation n&#8217;est pas aisée, c&#8217;est pourquoi je recommande l&#8217;utilisation de la commande gitk qui permettra d&#8217;avoir une vue graphique et synthétique du dépôt.</p>
<h1 style="text-align: justify;">Eh Bob, j&#8217;ai une idée !</h1>
<p style="text-align: justify;">Oui, mais les idées de Bob c&#8217;est pas toujours terrible, heureusement git permet de créer FACILEMENT des branches, pas besoin d&#8217;appeler la gconf et d&#8217;imputer sur le budget du projet déjà en déficit &#8230;<br />
Bref pour créer un branche :</p>
<blockquote>
<p style="text-align: justify;">git branch NomDeLaBranche [BrancheInitiale]</p>
</blockquote>
<p style="text-align: justify;">Et voilà la branche est crée à partir de HEAD ou de BrancheInitiale.</p>
<p style="text-align: justify;"><strong>ATTENTION</strong> vous êtes toujours dans la branche de départ, pour pouvoir changer de branche il faut faire un :</p>
<blockquote>
<p style="text-align: justify;">git checkout NomDeLaBranche</p>
</blockquote>
<p style="text-align: justify;">Pour récupérer uniquement un fichier d&#8217;une autre branche :</p>
<blockquote>
<p style="text-align: justify;">git checkout AutreBranche paths</p>
</blockquote>
<p>Ces deux actions peuvent être combinée en :</p>
<blockquote><p>git checkout -b NomDeLaBranche [BrancheInitiale]</p></blockquote>
<p style="text-align: justify;">Bon ben en fait Bob il a des idées toutes pourries, suppression de la branche :</p>
<blockquote>
<p style="text-align: justify;">git branch -d NomDeLaBranche</p>
</blockquote>
<p style="text-align: justify;"><strong>ATTENTION</strong> la branche sera détruite sans confirmation, toutes les modifications seront perdues et il ne sera pas possible de les retrouver !!</p>
<p style="text-align: justify;">On peut lister les branches avec :</p>
<blockquote>
<p style="text-align: justify;">git branch</p>
</blockquote>
<p style="text-align: justify;">Pour voir le contenu d&#8217;un fichier d&#8217;une autre branche :</p>
<blockquote>
<p style="text-align: justify;">git show MaBranche:MonFichier</p>
</blockquote>
<p style="text-align: justify;">Oui, mais mon idée était beaucoup plus classe que celle de Bob, je vais donc l&#8217;intégrer dans la branche principale (master) :</p>
<blockquote>
<p style="text-align: justify;">git checkout master<br />
git merge MesBranches</p>
</blockquote>
<p style="text-align: justify;">(on peut merger depuis plusieurs branches)<br />
S&#8217;il n&#8217;y a pas de conflit, l&#8217;opération est commitée (sauf option &#8211;no-commit).</p>
<p style="text-align: justify;">Ah il y a un conflit que git n&#8217;est pas capable de résoudre: il nous l&#8217;indique et il faut le résoudre  manuellement. Le fichier accusé sera de la forme :</p>
<blockquote>
<p style="text-align: justify;">&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD:test.c<br />
printf(&laquo;&nbsp;Hello world 2\n&nbsp;&raquo;) ;<br />
=======<br />
printf(&laquo;&nbsp;Hello world 1\n&nbsp;&raquo;) ;<br />
&gt;&gt;&gt;&gt;&gt;&gt;&gt; test:test.c</p>
</blockquote>
<p style="text-align: justify;">HEAD, c&#8217;est la branche actuelle ! test est ici une branche de test. Le fichier en conflit sera affiché dans git status comme unmerged.</p>
<p style="text-align: justify;">Pas très lisible ?  On peut voir séparément les différences introduites par les deux commits sur le fichier en conflit :</p>
<blockquote>
<p style="text-align: justify;">git log &#8211;merge -p test.c</p>
</blockquote>
<p style="text-align: justify;">Une autre option très pratique pour choisir entre telle et telle version quand on est fainéant et qu&#8217;on n&#8217;a pas envie de tout éditer à la main (de toutes façons c&#8217;est ma version la meilleure) :</p>
<blockquote>
<p style="text-align: justify;">git show :z:test.c</p>
</blockquote>
<p style="text-align: justify;">où z correspond à :</p>
<ul>
<li> l&#8217;ancêtre commun des deux branches</li>
<li> branche actuelle</li>
<li> branche distante</li>
</ul>
<p>Qui montre la version z du fichier test.c. On redirige ensuite la sortie dans le fichier test.c</p>
<p style="text-align: justify;">Ne pas oublier de commiter les changements introduits par le merge (en cas de conflits) !</p>
<h1 style="text-align: justify;">On a enfin une version stable !!</h1>
<p style="text-align: justify;">Il est possible de la tagger pour avoir une référence un peu plus explicite que son SHA-1.</p>
<blockquote>
<p style="text-align: justify;">git tag MonTag [&lt;commit&gt;]</p>
</blockquote>
<p style="text-align: justify;">Par défaut HEAD de la branche courante. Un commit peut avoir plusieurs tags.</p>
<p style="text-align: justify;">Ah, en fait non, Bob avait laissé un buffer overflow, supprimer un tag :</p>
<blockquote>
<p style="text-align: justify;">git tag -d MonTag</p>
</blockquote>
<p style="text-align: justify;">Ouais, en fait la v1 c&#8217;était le top. Il est possible de revenir à une version précédente (et heureusement) via trois techniques.</p>
<p style="text-align: justify;">
<h2>Je m&#8217;appelle Rambo et rien ne me fait peur</h2>
<blockquote>
<p style="text-align: justify;">git reset [--mixed | --soft | --hard] [&lt;commit&gt;]</p>
</blockquote>
<p style="text-align: justify;">Ici on revient à un commit précédent en SUPPRIMANT tous les commits suivants<br />
&#8211;mixed : les changements n&#8217;affectent que le gestionnaire de versions et pas le système de fichier<br />
&#8211;soft : On revient simplement au commit &lt;commit&gt; au niveau du gestionnaire de versions, mais les fichiers ne sont pas changés sur le disque (un prochain commit n&#8217;effacera pas le commit suivante [i.e qu'on a reseté])<br />
&#8211;hard : Le gestionnaire de versions et les fichiers sur le disque se retrouvent en position &lt;commit&gt;, les commits suivants sont perdus.</p>
<h2 style="text-align: justify;">Méthode propre</h2>
<blockquote>
<p style="text-align: justify;">git revert &lt;commit&gt;</p>
</blockquote>
<p style="text-align: justify;">Cette méthode est « propre » car elle permet de conserver les changements introduits (même si on veut s&#8217;en séparer) en introduisant un commit faisant le travail inverse de ce qui a été cassé.</p>
<h2 style="text-align: justify;">Méthode pour un ensemble restreint de fichiers</h2>
<blockquote>
<p style="text-align: justify;">git checkout &lt;commit&gt; paths</p>
</blockquote>
<p style="text-align: justify;">Cela permet de retrouver ponctuellement un fichier d&#8217;une ancienne version.</p>
<h1 style="text-align: justify;">J&#8217;te jure ça marchait et j&#8217;ai rien touché !</h1>
<p style="text-align: justify;">12 commits ont été réalisé pendant que vous étiez en vacances et maintenant plus rien ne compile (Bob ??). Bref, git offre un mécanisme très puissant pour identifier le commit qui a tout fait planter : bisect ! On va pouvoir faire une recherche semi-automatique voir même automatique du commit fautif, git se chargera tout seul de mettre l&#8217;espace de travail tel qu&#8217;il était à chaque commit (sinon il aurait fallu jouer avec reset/revert).</p>
<p style="text-align: justify;">On commence par démarrer une session de bisect en identifiant le point où ça bloque (en général HEAD) et le point où on est sûr que c&#8217;était bon:</p>
<blockquote>
<p style="text-align: justify;">git bisect start [&lt;commit-bad&gt;] [&lt;commit-good&gt;]</p>
</blockquote>
<p style="text-align: justify;">Puis on va identifier les différents commits (la recherche est dichotomique, c&#8217;est à dire qu&#8217;il prend toujours le commit intermédiaire dans l&#8217;intervalle good-bad afin de trouver au plus vite la version responsable du problème) avec :</p>
<blockquote>
<p style="text-align: justify;">git bisect bad<br />
git bisect good</p>
</blockquote>
<p style="text-align: justify;">Chaque appel de cette commande « tag » le commit avec good ou bad et passe au commit suivant jusqu&#8217;à tomber sur le fautif (ou qu&#8217;on en ais marre). Si on sait qu&#8217;un commit (ou un intervalle de commits (ie : v1..v2)) est bon par avance on peux l&#8217;ignorer avec :</p>
<blockquote>
<p style="text-align: justify;">git bisect skip [&lt;commit&gt;[..&lt;commit&gt;]]</p>
</blockquote>
<p style="text-align: justify;">good et bad ne sont que des marqueurs, il appartient ensuite au développeur d&#8217;effectuer les actions pour retrouver un environnement correct/stable/sans bugs. On peut visualiser l&#8217;état des marqueurs (dans gitk) avec :</p>
<blockquote>
<p style="text-align: justify;">git bisect visualize</p>
</blockquote>
<p style="text-align: justify;">Une fois qu&#8217;on a fini le boulot on peut revenir au point de départ (effacer les tags et retour à HEAD) avec :</p>
<blockquote>
<p style="text-align: justify;">git bisect reset</p>
</blockquote>
<p style="text-align: justify;">Il est possible d&#8217;enregistrer toutes les opérations (ou au moins les « visualiser ») avec :</p>
<blockquote>
<p style="text-align: justify;">git bisect log</p>
</blockquote>
<p style="text-align: justify;">Et on peut ensuite les rejouer avec :</p>
<blockquote>
<p style="text-align: justify;">git bisect replay &lt;fichier créée par git bisect log&gt;</p>
</blockquote>
<p style="text-align: justify;">Mais là où git est très intéressant c&#8217;est avec le mode tout automatique :</p>
<blockquote>
<p style="text-align: justify;">git bisect run cmd</p>
</blockquote>
<p style="text-align: justify;">cmd est une commande (ou un script) qui va être appliqué sur tous les commits entre bad et good et qui va les marquer selon son code de retour :</p>
<ul>
<li> 0 : good</li>
<li> 125 : skip</li>
<li> autre : bad</li>
</ul>
<p style="text-align: justify;">
<p style="text-align: justify;">Une fois qu&#8217;on a le commit fautif on peut savoir exactement qui a fait quoi dans le fichier qui a fait que et quand il l&#8217;a fait :</p>
<blockquote>
<p style="text-align: justify;">git blame &lt;paths&gt;</p>
</blockquote>
<p style="text-align: justify;">Ce qui donne quelque chose comme :</p>
<blockquote>
<p style="text-align: justify;">1692b633 (Grégory 2009-09-19  1 ) #include &lt;stdio.h&gt;<br />
1692b633 (Grégory 2009-09-19  2 )<br />
1692b633 (Grégory 2009-09-19  3 )<br />
1692b633 (Grégory 2009-09-19  4 )<br />
1692b633 (Grégory 2009-09-19  5 ) int main()<br />
1692b633 (Grégory 2009-09-19  6 ) {<br />
<span style="text-decoration: underline;">795a06c9</span> (Grégory <span style="text-decoration: underline;">2009-09-29</span> 7 )   printf( &laquo;&nbsp;Hello world\n&nbsp;&raquo; ) ;<br />
1692b633 (Grégory 2009-09-19  8 )<br />
1692b633 (Grégory 2009-09-19  9 )   return 0 ;<br />
1692b633 (Grégory 2009-09-19 10) }</p>
<p style="text-align: justify;">
<p style="text-align: justify;">
</blockquote>
<h1 style="text-align: justify;">Ça fait stash !</h1>
<p style="text-align: justify;">Vous êtes tranquillement en train de travailler sur l&#8217;ajout d&#8217;une fonctionnalité révolutionnaire quand Bob vous apprend catastrophé qu&#8217;il a trouvé un bug terrible dans le projet et qu&#8217;il faut le corriger dans la seconde. On peut bien évidement créer une branche pour reporter les modifications et merger par la suite d&#8217;une manière plus ou moins élégante, mais git introduit un concept très intéressant : le « stash ». Cela permet de mettre les modifications en cours dans une pile et de revenir à la dernière version (~ git reset &#8211;hard HEAD), faire les bonnes modifications, commiter et retrouver son espace de travail.</p>
<p style="text-align: justify;">Créer le stash (éventuellement avec un message) :</p>
<blockquote>
<p style="text-align: justify;">git stash [save [message]]</p>
</blockquote>
<p style="text-align: justify;">Voir la liste des stashs :</p>
<blockquote>
<p style="text-align: justify;">git stash list</p>
</blockquote>
<p style="text-align: justify;">Récupérer les modifications du stash et le supprimer de la liste des stashs :</p>
<blockquote>
<p style="text-align: justify;">git stash pop [stash]</p>
</blockquote>
<p style="text-align: justify;">La syntaxe des stashs est : stash@{0}</p>
<p style="text-align: justify;">Le stash le plus récent est toujours 0. Si aucun stash n&#8217;est précisé, le plus récent est celui par défaut</p>
<p style="text-align: justify;">Voir les modifications du stash :</p>
<blockquote>
<p style="text-align: justify;">git stash show [stash]</p>
</blockquote>
<p style="text-align: justify;">Appliquer les modifications d&#8217;un stash sans le supprimer de la pile :</p>
<blockquote>
<p style="text-align: justify;">git stash apply [stash]</p>
</blockquote>
<p style="text-align: justify;">Supprimer tous les stashs :</p>
<blockquote>
<p style="text-align: justify;">git stash clear</p>
</blockquote>
<p style="text-align: justify;">Supprimer un stash sans l&#8217;appliquer :</p>
<blockquote>
<p style="text-align: justify;">git stash drop [stash]</p>
<p style="text-align: justify;">
</blockquote>
<h1 style="text-align: justify;">Hooks</h1>
<p style="text-align: justify;">Les hooks sont des scripts appelés durant l&#8217;exécution de certaines tâches, ils se trouvent dans le répertoire .git/hooks. Cela permet de contrôler/valider certaines actions. Si la valeur de retour du script est différente de 0, alors l&#8217;action ne sera pas exécutée. Git propose les hooks suivants :</p>
<ul>pre/post commit</ul>
<ul>[prepare-]commit-msg : invoqué lors de la création du message dans git commit</ul>
<ul>pre-rebase : invoqué avant un git rebase</ul>
<ul>post-checkout : invoqué après un git checkout</ul>
<ul>post-merge : après un merge et/ou un pull</ul>
<ul>pre/post receive : invoqué (sur le serveur uniquement) lors d&#8217;un git push</ul>
<ul>update : invoqué (sur le serveur uniquement) lors d&#8217;un git push</ul>
<ul>post-rewrite : invoqué lorsque le message d&#8217;un commit est modifié (git commit &#8211;amend ou git rebase)</ul>
<p>Pour les différents paramètres que prennent les hooks, voir le man. Des exemples se trouvent dans le dossier (les .sample). Pour qu&#8217;un hook soit pris en compte il faut enlever l&#8217;extension .sample (attention à ne pas oublier les droits en exécution).</p>
<h1 style="text-align: justify;">Git, mon couteau Suisse</h1>
<p style="text-align: justify;">Quelques commandes supplémentaires :</p>
<p style="text-align: justify;">Exporter les sources du projet (sans le .git)</p>
<blockquote>
<p style="text-align: justify;">git archive &#8211;format=[tar|zip] &#8211;output=File &lt;commit&gt; [paths ...]</p>
</blockquote>
<p style="text-align: justify;">Appliquer un/des patch(s)</p>
<blockquote>
<p style="text-align: justify;">git apply &lt;patchs&gt;</p>
</blockquote>
<p>Supprimer les fichiers qui sont dans le dépôt, mais pas dans le gestionnaire de versions (untracked files) :</p>
<blockquote>
<p style="text-align: justify;">git clean [-d] [fichiers]</p>
</blockquote>
<p style="text-align: justify;">Si l&#8217;argument fichiers est renseigné, seuls ces fichiers là seront supprimés.<br />
-d : Supprimer aussi les dossiers</p>
<p style="text-align: justify;">Optimiser le dépôt local pour de meilleures performances (à faire de temps en temps)</p>
<blockquote>
<p style="text-align: justify;">git gc</p>
</blockquote>
<h1 style="text-align: justify;">Pour aller plus loin</h1>
<p style="text-align: justify;">La documentation de git (en pages man) est très bien faite, il y a deux solutions :</p>
<blockquote>
<p style="text-align: justify;">git help command</p>
</blockquote>
<p style="text-align: justify;">Toutes les options pour les commandes présentées n&#8217;ont pas été spécifiées ici, je vous recommande donc pour certaines tâches spécifiques d&#8217;aller voir le man.<br />
L&#8217;aspect travail collaboratif (pull, push, rebase) n&#8217;a pas été abordé, si vous êtes curieux il y a d&#8217;autres documentation qui en parlent (peut être pour une prochaine version de ce tutoriel).</p>
<p style="text-align: justify;">Pour savoir pourquoi git est le meilleur gestionnaire de versions du noyau : <a title="http://www.youtube.com/watch?v=4XpnKHJAok8" href="http://www.youtube.com/watch?v=4XpnKHJAok8">http://www.youtube.com/watch?v=4XpnKHJAok8</a></p>
<h1 style="text-align: justify;">Le Terminal c&#8217;est bien, mais bon</h1>
<p style="text-align: justify;">Vous devriez maintenant être capable d&#8217;utiliser git en ligne de commande pour vos besoins personnels. Le terminal &#8230; ça va bien un moment mais on aime aussi avoir un client graphique un peu plus convivial qui fait le boulot pour nous ! Faisons un petit tour d&#8217;horizon des solutions existantes. Malheureusement, je n&#8217;ai pas pu tester ces solutions, libre à vous donc de vous faire une opinion sur l&#8217;état d&#8217;avancement et la fiabilité de chacun, n&#8217;hésitez pas à laisser un commentaire pour partager vos retours.</p>
<p style="text-align: justify;"><a title="Client git en Qt4" href="http://sourceforge.net/projects/qgit/">QGit</a>: Client Qt4 (donc pour les utilisateur KDE principalement). Hébergé par SourceForce avec une dernière version datée du 9 Mai de cette année. De bons retours indiqués sur le site.</p>
<p style="text-align: justify;"><a title="TortoiseGit pour Windows" href="http://code.google.com/p/tortoisegit/">TortoiseGIT</a>: Client Windows se voulant le remplaçant de TortoiseSVN. Nécessite l&#8217;installation préalable de msysgit.</p>
<p style="text-align: justify;"><a title="Client Git pour Mac" href="http://gitx.frim.nl/">GitX</a>: Application pour Mac OS X.</p>
<p style="text-align: justify;"><a title="Client git pour Mac OS" href="http://github.com/Caged/gitnub/downloads">GitNub</a>: Autre application pour Mac OS X écrite en RubyCocoa.</p>
<p style="text-align: justify;"><a title="Plug-in git pour eclipse" href="http://www.eclipse.org/egit/">EGit</a>: Plug-in pour eclipse, malheureusement peu avancé. Si vous avez du temps et de la motivation, n&#8217;hésitez pas à participer.</p>
<h1>Ressources</h1>
<p style="text-align: justify;"><a title="Site officiel de git" href="http://git-scm.com/">http://git-scm.com/</a><a title="Git sur Wikipedia" href="http://fr.wikipedia.org/wiki/Git"></p>
<p>http://fr.wikipedia.org/wiki/Git</a></p>
<p><a title="Tutoriel GIT" href="http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html">http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html</a><br />
<a title="Tutoriaux GIT" href="http://linux.efrei.fr/doku.php/tutoriaux/git">http://linux.efrei.fr/doku.php/tutoriaux/git<br />
</a><a title="GitHub" href="http://github.com/">http://github.com/</a><a title="Tutoriaux GIT" href="http://linux.efrei.fr/doku.php/tutoriaux/git"></a><br />
<a title="Git pour futurs barbus" href="http://www.unixgarden.com/index.php/administration-systeme/git-pour-les-futurs-barbus">http://www.unixgarden.com/index.php/administration-systeme/git-pour-les-futurs-barbus</a><br />
<a title="Git, les mains dans le cambouis" href="http://www.unixgarden.com/index.php/administration-systeme/git-les-mains-dans-le-cambouis">http://www.unixgarden.com/index.php/administration-systeme/git-les-mains-dans-le-cambouis</a></p>
<p><a rel="license" href="http://creativecommons.org/licenses/by-sa/2.0/fr/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/2.0/fr/88x31.png" /></a><br /><span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Text" property="dc:title" rel="dc:type">Tutoriel GIT</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="http://www.pierreschambacher.com/" property="cc:attributionName" rel="cc:attributionURL">Gr&#233;gory Soutad&#233;</a> est mis &#224; disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-sa/2.0/fr/">licence Creative Commons Paternit&#233;-Partage des Conditions Initiales &#224; l&#8217;Identique 2.0 France</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/git-in-a-nutshell/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Expérience d’un ingénieur sur Adobe Flex</title>
		<link>http://www.pierreschambacher.com/blog/experience-d%e2%80%99un-ingenieur-sur-adobe-flex/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=experience-d%25e2%2580%2599un-ingenieur-sur-adobe-flex</link>
		<comments>http://www.pierreschambacher.com/blog/experience-d%e2%80%99un-ingenieur-sur-adobe-flex/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 17:46:54 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[cv]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[ingénieur]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=152</guid>
		<description><![CDATA[Après avoir utilisé le framework Flex pendant une année au cours de mon stage d&#8217;ingénieur à Polytech&#8217;Nice Sophia (voir mon CV), je souhaite donner un peu mon avis sur cette technologie, ses avantages, ses inconvénients, points forts et faibles. Comme pour WebObjects, voici une petite description pour les personnes qui ne connaitraient pas Flex.
Adobe Flex [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Après avoir utilisé le framework Flex pendant une année au cours de mon stage d&#8217;ingénieur à Polytech&#8217;Nice Sophia (voir mon <a title="CV Ingénieur Sophia" href="http://www.pierreschambacher.com/cv">CV</a>), je souhaite donner un peu mon avis sur cette technologie, ses avantages, ses inconvénients, points forts et faibles. Comme pour WebObjects, voici une petite description pour les personnes qui ne connaitraient pas Flex.</p>
<p style="text-align: justify;">Adobe Flex est un framework de développement de clients riches (ou clients lourds) compilé vers la machine virtuelle Flash. Pour les personnes connaissant Silverlight, Flex a inspiré Microsoft pour sa création. Les interfaces sont réalisées à l&#8217;aide d&#8217;un langage basé sur XML, le MXML (XAML pour Silverlight) et le comportement est écrit à l&#8217;aide du langage Action Script 3 (.Net pour Silverlight).<br />
Il ne surtout pas considérer Flex comme un outil fait pour les designeurs, c&#8217;est un framework créé pour les développeurs.</p>
<p style="text-align: justify;"><span id="more-152"></span></p>
<h2 style="text-align: justify;">Déploiement</h2>
<p style="text-align: justify;">Comme dit dans l&#8217;introduction, Flex est compilé dans un fichier SWF qui est lu par la machine virtuelle Flash. Pour lire une application Flex, la version 9 du plug-in est au minimum nécessaire, or plus de <a title="Statistiques d'installation des plugins" href="http://riastats.com/" target="_blank">95%</a> des personnes répondent à ce besoin. C&#8217;est un point assez fort du framework, surtout en comparaison avec Silverlight qui peine à passer les 30% (toutes versions confondues).<br />
Étant donné que Flex se base sur le plug-in Flash, vous bénéficiez également d&#8217;une compatibilité entre les différents systèmes d&#8217;exploitation et les différents navigateurs. Pas de mal de tête à assurer le même rendu entre IE6 sur Windows et Safari sur Mac, c&#8217;est le travail des gens d&#8217;Adobe.<br />
Pas de doute ici, c&#8217;est un gros point fort et un très bon travail d&#8217;Adobe qui donne à Flex un avantage certain sur ses concurrents directs. On pourra également remarquer sur l&#8217;utilisation de Flash la mise à disposition d&#8217;une excellente librairie pour créer des animations de l&#8217;interface qui donnent un cachet très professionnel aux applications.</p>
<h2 style="text-align: justify;">ActionScript et API</h2>
<p style="text-align: justify;">Le comportement et le business d&#8217;une application Flex est décrit dans le langage ActionScript 3. Pour le langage en lui-même, il est souple et propose un certain nombre de fonctionnalités puissantes et pratiques, je citerais en exemple la possibilité d&#8217;appeler une méthode sur une variable à l&#8217;aide de l&#8217;opérateur [] comme suit: maVariable["maMethode"].<br />
En revanche on peut vraiment reprocher à Adobe la pauvreté de l&#8217;API. Pour l&#8217;anecdote, sachez que la méthode addAll permettant d&#8217;ajouter tous les éléments d&#8217;un tableau dans un autre tableau vient d&#8217;être implémentée dans la version 3.4 du framework &#8230; Sachez également que la gestion de dictionnaire est extrêmement réduite, impossible par exemple de récupérer l&#8217;ensemble des clés d&#8217;un dictionnaire &#8230;<br />
Il est certes possible d&#8217;écrire soit-même toutes ses classes, mais d&#8217;une part on n&#8217;a pas forcément envie de coder toutes les classes de base lorsque l&#8217;on s&#8217;attaque à un projet ambitieux et d&#8217;autre part, si Adobe comble le manque un jour il faudra faire le remplacement partout.</p>
<h2 style="text-align: justify;">Modèle MVC</h2>
<p style="text-align: justify;">A première vue, Flex semble proposer une bonne architecture pour respecter le pattern Modèle-Vue-Contrôleur avec les interfaces et leur comportement décrites en MXML, des classes de comportement et des classes de modèle. Cependant en pratique, on a rapidement tendance à mélanger la vue et le contrôleur. En effet il est possible d&#8217;écrire de l&#8217;ActionScript dans le fichier MXML et la tentation est grande d&#8217;y écrire le code business de la vue.</p>
<p style="text-align: justify;">Quelques framework tentent d&#8217;imposer de bonnes pratiques (je citerais Cairngorn et Tide) mais ils ne sont pas toujours simple à mettre en place. En pratique il devient également difficile de maintenir du code propre au sein d&#8217;un projet de grande envergure. Le projet peut être découpé en modules qui sont chargés à la demande, mais on arrive assez facilement à des dépendances inter-modules ou de la recopie de code pour effectuer la même action dans deux endroits différents mais inaccessibles entre eux.</p>
<h2 style="text-align: justify;">Asynchronisme et thread unique</h2>
<p style="text-align: justify;">Le plug-in Flash est presque mono-threadé. Je dis presque car en réalité un deuxième thread existe, qui attend les réponses aux requêtes effectuées vers des adresses externes. De cette situation ressort deux choses.</p>
<p style="text-align: justify;">Toute demande de données est asynchrone. La demande est déposée vers le thread de communication qui propagera un évènement lorsque celle-ci sera complétée. S&#8217;il n&#8217;est pas dérangeant que vos données arrivent de façon asynchrone, pas de soucis mais dans le cas où vous aimeriez attendre d&#8217;avoir concrètement les informations, vous allez commencer à rencontrer des difficultés.</p>
<p style="text-align: justify;">Il est impossible d&#8217;effectuer deux actions à la fois, cela incluant le dessin de l&#8217;interface ou le traitement d&#8217;un clic souris. Par conséquent, si vous lancez un traitement lourd de calculs, l&#8217;interface sera figée. Avantage en contrepartie, vous n&#8217;avez pas du tout à vous préoccupé de problèmes de validité des données entres threads ou de deadlocks, cela est impossible !</p>
<h2 style="text-align: justify;">Bindings</h2>
<p style="text-align: justify;">Il est possible dans les interfaces MXML de réaliser des &laquo;&nbsp;bindings&nbsp;&raquo; entre une variable ActionScript et une propriété d&#8217;un élément graphique. Une fois le binding mis en place, la modification de la valeur de la variable entrainera la modification de la valeur de la propriété de l&#8217;élément graphique. Cela est très pratique puisque le mécanisme permet de réaliser à vitesse grand V l&#8217;écran de visualisation d&#8217;un objet Business en &laquo;&nbsp;bindant&nbsp;&raquo; sur ses différents attributs.</p>
<p style="text-align: justify;">Dans la version 3 de Flex quelques embuches appaissent pour mettre en place des double bindings, c&#8217;est à dire que les modifications de valeur s&#8217;effectuent dans les deux sens. En effet, le premier binding mis en place aura pour effet d&#8217;effacer la valeur d&#8217;une des deux variables avec la valeur de l&#8217;autre. Dans le cas d&#8217;un objet business et un objet graphique, il vaut mieux effacer la valeur de la propriété graphique avec celle de l&#8217;objet business et non pas le contraire &#8230; Ce petit problème a été corrigé dans Flex 4 qui sortira prochainement.</p>
<h2 style="text-align: justify;">Flex est un outil</h2>
<p style="text-align: justify;">En conclusion de l&#8217;article et avant de tirer avantages et inconvénient, j&#8217;aimerais donner un avis très subjectif sur le framework. Flex un outil jeune mais toutefois puissant pour développer rapidement les applications pour lesquelles il a été créé. Et je vais insister sur ce point.</p>
<p style="text-align: justify;">A mon idée, Flex est parfait pour des applications simples, avec peu de code business. La manière classique de travailler va être d&#8217;appeler un WebService ou une page Web, parser les résultats pour remplir des variables sur lesquelles l&#8217;interface est bindée. Le résultat sera obtenu rapidement, propre, et joliment animée.</p>
<p style="text-align: justify;">En revanche, Flex n&#8217;est pas fait pour une lourde application avec de nombreuses implications de code business entre les écrans et des grappes d&#8217;objets à récupérer, modifier, renvoyer, etc. Pour avoir tenté d&#8217;utiliser le framework pour ce type d&#8217;application, je peux dire qu&#8217;on passe plus de temps à lutter contre Flex qu&#8217;à lutter contre les difficultés de l&#8217;application elle-même.</p>
<p style="text-align: justify;">Comme beaucoup d&#8217;autres framework, Flex est un outil. Flex est un tournevis cruciforme. Si votre application est faite de vis cruciformes, ce sera un excellent outil et vous allez aboutir rapidement à un résultat de qualité. Si en revanche vous devez fabriquer une chaise avec des clous, vous êtes condamné à taper sur les clous avec le manche, et au final vos clous seront plantés de travers, votre chaise sera bancale et s&#8217;effondrera à la troisième personne qui tentera de s&#8217;assoir dessus et enfin vous vous serez fait mal à la main.</p>
<p style="text-align: justify;">Mais assez parlé et voyons le bilan avantages/inconvénients</p>
<h2 style="text-align: justify;">Avantages</h2>
<ul>
<li>Compatibilité OS/Navigateur</li>
<li>Plug-In flash très répandu (95%)</li>
<li>Animations simple à utiliser et très classes</li>
<li>Pas de problématique de programmation concurrente</li>
<li>Mécanisme de binding très pratique</li>
</ul>
<h2 style="text-align: justify;">Inconvénients</h2>
<ul>
<li>Inconvénients de Flash (vous devriez les trouver facilement sur d&#8217;autres sites)</li>
<li>Pauvreté de l&#8217;API ActionScript</li>
<li>Trop grande facilité de mélanger Vue et Contrôleur</li>
<li>Impossibilité d&#8217;utiliser la programmation concurrente</li>
<li>Obligation de récupérer les données de façon asynchrone</li>
<li>Doubles bindings laborieux (résolu normalement dans Flex 4)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/experience-d%e2%80%99un-ingenieur-sur-adobe-flex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Expérience d&#8217;un ingénieur sur WebObjects</title>
		<link>http://www.pierreschambacher.com/blog/experience-dun-ingenieur-sur-webobjects/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=experience-dun-ingenieur-sur-webobjects</link>
		<comments>http://www.pierreschambacher.com/blog/experience-dun-ingenieur-sur-webobjects/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 16:04:21 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[cv]]></category>
		<category><![CDATA[ingénieur]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[webobjects]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=141</guid>
		<description><![CDATA[Utilisant WebObjects depuis maintenant 6 mois dans le cadre de mon stage ingénieur sur Sophia (voir mon CV), j&#8217;aimerais revenir sur cette expérience et donner mon avis sur cette technologie assez peu connue. Pour ceux qui ne connaitraient que de nom ce framework, en voici une petite description.
WebObjects est un framework initialement développé en Objective [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Utilisant WebObjects depuis maintenant 6 mois dans le cadre de mon stage ingénieur sur Sophia (voir mon <a title="CV ingénieur WebObjects Sophia" href="http://www.pierreschambacher.com/cv" target="_self">CV</a>), j&#8217;aimerais revenir sur cette expérience et donner mon avis sur cette technologie assez peu connue. Pour ceux qui ne connaitraient que de nom ce framework, en voici une petite description.</p>
<p style="text-align: justify;">WebObjects est un framework initialement développé en Objective C par la société NeXT de Steve Jobs qui sera ensuite rachetée par Apple. Il est constitué d&#8217;une couche basse d&#8217;abstraction de la base de donnée appelée EOModel, d&#8217;une architecture de gestion de cache et de persistance et d&#8217;un moteur de template. WebObjects passera progressivement d&#8217;Objective C à Java vers l&#8217;an 2000. Bien que différents par de nombreux points, il est comparable aux technologies J2EE.</p>
<p style="text-align: justify;">Je tiens à signaler que mes commentaires sont faits sur la version 5.3 de WebObjects et je ne sais pas si certaines choses n&#8217;ont pas été corrigées en version 5.4.</p>
<p style="text-align: justify;"><span id="more-141"></span></p>
<h2 style="text-align: justify;">Coût de formation et cadre de développement</h2>
<p style="text-align: justify;">Soyons assez clair, le coup d&#8217;entrée de WebObjects est assez élevé. Le framework a été pensé pour réaliser des projets d&#8217;entreprise et vous ne pourrez pas sortir une page de démonstration en moins d&#8217;une heure comme le proposent des plateformes de développement comme Google App Engine. En revanche, une fois formé à l&#8217;architecture logiciel vous disposerez d&#8217;un cadre de programmation assez stricte dans la forme, mais souple dans les possibilités. Comprenez que vous pourrez faire à peu près n&#8217;importe quoi, mais pas n&#8217;importe comment. À mon sens, c&#8217;est un avantage puisque vous êtes à peu près certain que les personnes utilisant WebObjects vont travailler relativement proprement, contrairement à d&#8217;autres technologies où il est possible de faire tout et n&#8217;importe quoi, surtout n&#8217;importe quoi.</p>
<h2 style="text-align: justify;">Tenue de charge et modularité</h2>
<p style="text-align: justify;">WebObjects est designé pour être capable de gérer de grandes charges, aussi les données sont toujours chargées progressivement au moment où elles sont réellement nécessaires. Au niveau du fonctionnement lui-même, le framework est construit autour de dictionnaires de données. Par exemple pour les attributs d&#8217;un objet, les getters vont simplement chercher la valeur dans un dictionnaire à partir du nom de l&#8217;attribut. C&#8217;est de ce mécanisme que vient toute la souplesse de WebObjects puisqu&#8217;il est possible de faire évoluer dynamiquement le modèle pendant l&#8217;exécution. Même si les occasions d&#8217;utiliser une telle possibilité sont assez rares, elles sont quasiment impossible à réaliser autrement.</p>
<h2 style="text-align: justify;">Mélange d&#8217;API</h2>
<p style="text-align: justify;">Comme je l&#8217;ai dis dans mon introduction, WebObjects reposait initialement sur le langage Objective C, mais a été migré vers le langage Java depuis plusieurs années maintenant. Cependant les choix qui ont été faits me laissent quelque peu sceptiques. En effet afin que les personnes ayant travaillé avec l&#8217;Objective C ne perdent pas leurs connaissances acquises, les classes de  base de NeXT ont été portées en Java. Un ingénieur d&#8217;expérience sur l&#8217;API Java sera donc un peu perdu face aux NSArray, NSMutableArray et autres NSDictionnary. Pire encore, ces classes implémentent des interfaces de l&#8217;API Java, mais n&#8217;implémentent pas les méthodes qu&#8217;elles apportent, se contentant de propager une exception ! Assez perturbant donc et pouvant se révéler source de surprises.</p>
<p style="text-align: justify;"><strong>[MISE A JOUR]</strong><br />
On me signale que le problème des exceptions sur les méthodes ont été corrigé en version 5.4 sauf dans les cas où il y avait une raison. Je m&#8217;explique, en WebObjects il éxiste deux types de tableaux, les NSArray en lecture seul et les NSMutableArray en lecture écriture. Bien évidemment la méthode ADD n&#8217;a aucun sens dans un NSArray qui ne supporte que des GET. En revanche la méthode ADD ne NSMutableArray ne demande plus d&#8217;utiliser à la place la méthode addObject.<br />
Il reste toutefois que quelqu&#8217;un ayant utilisé un certain temps les classes de la JRE de base, ArrayList et autres, aura besoin d&#8217;un petit temps d&#8217;adaptation.</p>
<h2 style="text-align: justify;">Trouver des personnes</h2>
<p style="text-align: justify;">Abordons finalement un point assez critique: les ressources. Il sera difficile à la plupart des personnes ayant des années d&#8217;expérience sur des plateformes J2EE de se former à WebObjects en raison des différences conceptuelles et à l&#8217;API s&#8217;écartant de celle de Java. Le coup de formation est assez élevé et l&#8217;intégration à des processus d&#8217;entreprises comme Maven, bien qu&#8217;existant, peut s&#8217;avérer coûteuse en temps.<br />
En comparaison d&#8217;autres framework, WebObjects souffre d&#8217;une très faible documentation. Le site d&#8217;Apple propose une documentation technique, mais très peu d&#8217;autres sites proposent des exemples ou des explications différentes de la version officielle. On se retrouve donc facilement le bec dans l&#8217;eau devant un problème dont la solution n&#8217;est pas documentée sur le site d&#8217;Apple. Une solution existe: la mailing list qui est fréquentée par des experts de la technologie, mais on ne peut évidemment pas abuser et questionner ces personnes en permanence.<br />
Il est très profitable d&#8217;avoir au sein de son entreprise une personne expérimentée en WebObjects donc, cependant il s&#8217;agit d&#8217;une ressource rare. Lors d&#8217;un recensement récent, 800 développeurs ont été dénombrés dans le Monde, dont 40 en France. Autant dire qu&#8217;il est difficile de se procurer un &laquo;&nbsp;expert&nbsp;&raquo; dans le domaine, sachant que connaissant la technologie, je ne me considère pas du tout comme un expert, mais un simple utilisateur.</p>
<p style="text-align: justify;">
<p style="text-align: justify;">En conclusion, voici un petit récapitulatif de ce billet en avantages/inconvénients.</p>
<h2 style="text-align: justify;">Avantages</h2>
<ul>
<li>Framework avec architecture</li>
<li>Développement propre</li>
<li>Flexible</li>
<li>Pensé pour tenir la charge</li>
</ul>
<h2>Inconvénients</h2>
<ul>
<li>Peu de ressources et très peu d&#8217;experts</li>
<li>Mélange d&#8217;API Java/Objective C</li>
<li>Manque de documentation tierce</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/experience-dun-ingenieur-sur-webobjects/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
