<?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</title>
	<atom:link href="http://www.pierreschambacher.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pierreschambacher.com</link>
	<description>Ingénieur en Informatique pour Intellicore</description>
	<lastBuildDate>Mon, 26 Sep 2011 07:59:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Maîtriser le outer join comme un pro !</title>
		<link>http://www.pierreschambacher.com/blog/maitriser-le-outer-join-comme-un-pro/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=maitriser-le-outer-join-comme-un-pro</link>
		<comments>http://www.pierreschambacher.com/blog/maitriser-le-outer-join-comme-un-pro/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 07:59:04 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=370</guid>
		<description><![CDATA[Il y a peu, j&#8217;ai eu l&#8217;occasion de m&#8217;occuper de l&#8217;optimisation d&#8217;une méthode qui chargeait plusieurs petits sets de données dans une table pour finalement renvoyer un seul paquet d&#8217;objets. Après avoir observé le code quelques secondes je me dis &#8230; <a href="http://www.pierreschambacher.com/blog/maitriser-le-outer-join-comme-un-pro/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Il y a peu, j&#8217;ai eu l&#8217;occasion de m&#8217;occuper de l&#8217;optimisation d&#8217;une méthode qui chargeait plusieurs petits sets de données dans une table pour finalement renvoyer un seul paquet d&#8217;objets. Après avoir observé le code quelques secondes je me dis que tout ça peut être fait directement dans la base de données à condition de lui fournir la requête voulue !<br />
Après un petit moment d&#8217;effort, j&#8217;ai fini par réussir mon coup à l&#8217;aide d&#8217;une fonctionnalité SQL qui m&#8217;avait toujours fait peur: le outer join !</p>
<p>Pour ceux qui ne sont pas à l&#8217;aise avec la syntaxe du code que j&#8217;utilise ici, je suis fan de la gem <a title="Gem MetaWhere" href="http://erniemiller.org/projects/metawhere/" target="_blank">MetaWhere</a>, et je ne sais plus vraiment écrire de ActiveRecord pur <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-370"></span></p>
<h1>L&#8217;Exemple</h1>
<p><em>Prenons un petit exemple simple pour bien visualiser.</em></p>
<p>Imaginons une application avec des utilisateurs.<br />
Ces utilisateurs ont besoin d&#8217;être validés par un administrateur pour se connecter au site.<br />
Ils peuvent également payer pour différents abonnements qui eux aussi nécessitent la validation d&#8217;un administrateur pour être en règle.</p>
<p>Imaginons maintenant que vous vouliez une page de type TODO pour l&#8217;administrateur, avec la liste des utilisateurs en attente d&#8217;une validation et qu&#8217;il faut appeler.</p>
<h1>Première solution (pas maline)</h1>
<p>Bon &#8230; on va pas être bien malins pour le coup !</p>
<pre><strong>User</strong>.<span style="text-decoration: underline;">where</span>(:validated =&gt; false).all
  + <strong>User</strong>.<span style="text-decoration: underline;">joins</span>(:subscriptions)
        .<span style="text-decoration: underline;">where</span>(:subscriptions =&gt; {:validated =&gt; false}).<span style="text-decoration: underline;">all</span></pre>
<p>Simple, efficace. Deux chargements en base de données qu&#8217;on réuni en suite à l&#8217;aide d&#8217;une simple addition de tableau.</p>
<h1>Deuxième solution (qui marche pas)</h1>
<p>OK soyons plus malin maintenant. Finalement ce qu&#8217;on veut, c&#8217;est charger des utilisateurs ! On a qu&#8217;à faire ça en une seule fois !</p>
<pre><strong>User</strong>.<span style="text-decoration: underline;">joins</span>(:subscriptions)
    .<span style="text-decoration: underline;">where</span>({:validated =&gt; false} 
           | {:subscriptions =&gt; {:validated =&gt; false}}).<span style="text-decoration: underline;">all</span></pre>
<p>Et là c&#8217;est avec un grand sourire qu&#8217;on lance ses tests vérifier qu&#8217;on a bien le résultat attendu, et c&#8217;est donc tout naturellement qu&#8217;on tire la gueule en le voyant s&#8217;allumer en rouge&#8230;</p>
<p>Que s&#8217;est-il passé ? C&#8217;est simple, tout se joue au début avec la jointure:</p>
<pre><strong>User</strong>.<span style="text-decoration: underline;">joins</span>(:subscriptions)</pre>
<p>Ceci va être traduit en SQL par un <strong>LEFT INNER JOIN</strong>. Le comportement de cette instruction est &laquo;&nbsp;fusionnes les éléments de cette table dans cette autre table à condition qu&#8217;il respecte telle condition&nbsp;&raquo;, et la condition en question c&#8217;est que l&#8217;id de l&#8217;utilisateur corresponde au user_id de l&#8217;abonnement.</p>
<p>Que se passe-t-il si un utilisateur n&#8217;a aucun abonnement, et bien la base SQL ne trouve aucune ligne dans les abonnements à faire correspondre à l&#8217;utilisateur, et il supprime donc la ligne des résultats.</p>
<p>Notre joli test nous indique ainsi que tous les utilisateurs qui sont en attente de validation (et non pas la validation de leur abonnement) ne sont pas renvoyés par notre méthode.</p>
<p>Quelle est la solution ?</p>
<h1>Troisième solution (la bonne)</h1>
<p>OK sur ce coup là il va falloir me faire confiance au début.</p>
<pre><strong>User</strong>.<span style="text-decoration: underline;">joins</span>(:subscriptions.outer)
     .<span style="text-decoration: underline;">where</span>({:validated =&gt; false}
            | {:subscriptions =&gt; {:validated =&gt; false}}).<span style="text-decoration: underline;">all</span></pre>
<p>Eh bah on était pas si loin que ça avec notre deuxième solution ! Le soucis venait simplement du joins ! Explication.</p>
<p>Si le <strong>LEFT INNER JOIN</strong> cherche absolument à faire correspondre la table jointe, le <strong>OUTER JOIN</strong> lui en revanche s&#8217;en fout un peu &#8230; s&#8217;il ne trouve aucune ligne dans les abonnements avec l&#8217;id de l&#8217;utilisateur courant, il le conserve quand même et considère toutes les valeurs des colonnes de la table abonnement comme vides.</p>
<h1>Au final</h1>
<p>Je suis passé un peu au travers de l&#8217;explication du fonctionnement précis du JOIN en lui-même, mais pour ça vous trouverez bien assez d&#8217;aide sur le inner join sur le reste du web.</p>
<p>Le outer join lui est souvent moins traité, voilà pourquoi j&#8217;ai voulu en faire une explication simple par un exemple pratique.  Le cas se répète, si vous faite une requête avec une jointure, mais que cette jointure est &laquo;&nbsp;optionnelle&nbsp;&raquo;, alors n&#8217;oubliez pas que c&#8217;est d&#8217;un <strong>OUTER JOIN</strong> dont vous avez besoin.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/maitriser-le-outer-join-comme-un-pro/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Résurrection du blog</title>
		<link>http://www.pierreschambacher.com/blog/resurrection-du-blog/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=resurrection-du-blog</link>
		<comments>http://www.pierreschambacher.com/blog/resurrection-du-blog/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 19:52:49 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Vie du Site]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=365</guid>
		<description><![CDATA[Après de très très longs mois sans rien publier, voilà le redémarrage du blog ! Pour fêter ça un nouveau thème, et un custom s&#8217;il vous plait ! Un grand merci à mon amie webdesigner Maeva Cecchi qui s&#8217;est donnée beaucoup &#8230; <a href="http://www.pierreschambacher.com/blog/resurrection-du-blog/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Après de très très longs mois sans rien publier, voilà le redémarrage du blog !</p>
<p style="text-align: justify;">Pour fêter ça un nouveau thème, et un custom s&#8217;il vous plait ! Un grand merci à mon amie webdesigner <a title="Maeva Cecchi Webdesigner" href="http://www.cecchi-maeva.com/" target="_blank">Maeva Cecchi</a> qui s&#8217;est donnée beaucoup de mal pour que le site soit beau, j&#8217;espère qu&#8217;il vous plaira autant qu&#8217;à moi !</p>
<p style="text-align: justify;">Pourquoi rouge alors que l&#8217;ancien était bleu ? Tout simplement parce que depuis environ 10 mois j&#8217;ai arrêté de faire du Java, et je fais maintenant du Ruby (avec Rails). Il fallait donc un thème en accord avec ça <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align: justify;">A venir très bientôt quelques articles sur Ruby et Rails justement. A noter que le 4 Octobre prochain il y aura la 2ème édition du <a title="Ruby user group" href="http://rivierarb.fr/" target="_blank">Riviera.rb</a> au Green King à 18h30 où je ferai une présentation de la gem MetaWhere.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/resurrection-du-blog/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Liberty Global annonce le projet Horizon avec Intellicore</title>
		<link>http://www.pierreschambacher.com/blog/liberty-global-annonce-le-projet-horizon-avec-intellicore/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=liberty-global-annonce-le-projet-horizon-avec-intellicore</link>
		<comments>http://www.pierreschambacher.com/blog/liberty-global-annonce-le-projet-horizon-avec-intellicore/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 12:43:13 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[intellicore]]></category>
		<category><![CDATA[sophia]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=353</guid>
		<description><![CDATA[Comme vous le savez sans doute, je travaille pour la société Intellicore, composée d&#8217;une vingtaine de personnes et dont les bureaux sont situés à Sophia. La nouvelle de la semaine est que Liberty Global, leader mondial de la télévision par &#8230; <a href="http://www.pierreschambacher.com/blog/liberty-global-annonce-le-projet-horizon-avec-intellicore/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Comme vous le savez sans doute, je travaille pour la société Intellicore, composée d&#8217;une vingtaine de personnes et dont les bureaux sont situés à Sophia.</p>
<p style="text-align: justify;">La nouvelle de la semaine est que Liberty Global, leader mondial de la télévision par cable et satellite américain (c&#8217;est pas moi qui le dit c&#8217;est <a title="Liberty Global" href="http://fr.wikipedia.org/wiki/Liberty_Global" target="_blank">Wikipedia</a>) vient d&#8217;annoncer lors d&#8217;une conférence le projet Horizon pour iPad, réalisé par mes collègues développeurs iOS ! Voilà un petit lien vers un <a title="Liberty Global annonce Horizon" href="http://www.businesswire.com/news/home/20110909005368/en/Liberty-Global-2nd-Screen-iPad-TV-Application" target="_blank">article qui en parle</a> et également une <a title="Projet Horizon" href="http://www.youtube.com/watch?v=JjVg8gidGmA" target="_blank">vidéo de promotion</a> de l&#8217;application. Félicitations à mes collègues pour leur boulot !</p>
<p style="text-align: justify;">J&#8217;en profite tant qu&#8217;on y est pour rappeler qu&#8217;Intellicore souhaite recruter plusieurs développeurs iOS si possible avec des connaissances en OpenGL ES. Pour le contact voici l&#8217;adresse <a title="Recrutement Intellicore" href="http://www.intellicore.net/positions/" target="_blank">http://www.intellicore.net/positions/</a> et vous pouvez me poser des questions sur Twitter (@PierreSchambac).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/liberty-global-annonce-le-projet-horizon-avec-intellicore/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ouverture de la galerie photo</title>
		<link>http://www.pierreschambacher.com/blog/ouverture-de-la-galerie-photo/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ouverture-de-la-galerie-photo</link>
		<comments>http://www.pierreschambacher.com/blog/ouverture-de-la-galerie-photo/#comments</comments>
		<pubDate>Sat, 22 May 2010 10:46:54 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Vie du Site]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=344</guid>
		<description><![CDATA[Comme promis la semaine dernière, j&#8217;ouvre une galerie photo ! Elle est disponible à l&#8217;adresse http://photo.pierreschambacher.com et repose sur zenphoto auquel je consacrerai un billet prochainement. Avant de me faire lyncher je tiens à souligner le fait que je n&#8217;ai aucune prétention &#8230; <a href="http://www.pierreschambacher.com/blog/ouverture-de-la-galerie-photo/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Comme promis la semaine dernière, j&#8217;ouvre une galerie photo ! Elle est disponible à l&#8217;adresse <a title="Galerie Photo" href="http://photo.pierreschambacher.com" target="_blank">http://photo.pierreschambacher.com</a> et repose sur zenphoto auquel je consacrerai un billet prochainement.</p>
<p>Avant de me faire lyncher je tiens à souligner le fait que je n&#8217;ai aucune prétention de professionnel de la photo ! Je voulais juste partager mes photos avec mes amis et avec les internautes qui pourraient le cas échéant bien aimer une de mes photos. Pour le reste vous êtes cordialement invités à visiter le site et éventuellement noter une photo, en bien ou en mal <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/ouverture-de-la-galerie-photo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>git in a nutshell Part 2</title>
		<link>http://www.pierreschambacher.com/blog/git-in-a-nutshell-part-2/?utm_source=rss&#038;utm_medium=rss&#038;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 &#8230; <a href="http://www.pierreschambacher.com/blog/git-in-a-nutshell-part-2/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></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>Nouveautés à venir</title>
		<link>http://www.pierreschambacher.com/blog/nouveautes-a-venir/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=nouveautes-a-venir</link>
		<comments>http://www.pierreschambacher.com/blog/nouveautes-a-venir/#comments</comments>
		<pubDate>Sun, 16 May 2010 12:14:51 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Vie du Site]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=335</guid>
		<description><![CDATA[Bonjour à mes lecteurs (ou ce qu&#8217;il en reste &#8230;) Si vous avez l&#8217;oeil vous devriez avoir constaté l&#8217;ajout à droite d&#8217;un bouton pour faire un don PayPal. L&#8217;idée est de compenser les frais d&#8217;hébergement du site et d&#8217;autre part &#8230; <a href="http://www.pierreschambacher.com/blog/nouveautes-a-venir/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Bonjour à mes lecteurs (ou ce qu&#8217;il en reste &#8230;)</p>
<p style="text-align: justify;">Si vous avez l&#8217;oeil vous devriez avoir constaté l&#8217;ajout à droite d&#8217;un bouton pour faire un don PayPal. L&#8217;idée est de compenser les frais d&#8217;hébergement du site et d&#8217;autre part d&#8217;encourager l&#8217;écriture de nouveaux billets techniques et tutoriaux car ils me demandent beaucoup de temps et de motivation. Vous êtes libre de m&#8217;insulter si ça ne vous plait pas ou de faire un don si vous m&#8217;approuvez, je ne contrains personne et je promet de ne pas faire de rappels intempestifs dans les articles.</p>
<p style="text-align: justify;">J&#8217;en profite pour annoncer cette semaine l&#8217;arrivée d&#8217;une partie 2 au billet sur GIT qui est le billet le plus consulté du blog (et ne l&#8217;ayant pas rédigé moi-même, mon égo en prend un coup <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). Guettez le flux RSS, c&#8217;est pour cette semaine !</p>
<p style="text-align: justify;">Dernière information, l&#8217;arrivée imminente d&#8217;un sous-domaine photo.pierreschambacher.com pour une galerie photo. J&#8217;ai fait l&#8217;acquisition d&#8217;un appareil photo réflex il y a peu et je souhaite publier mes photos pour avoir l&#8217;avis d&#8217;autres personnes. Les photos seront librement téléchargeables dans une excellente résolution et ce sera une fois encore le système de don qui sera utilisé par les gens qui souhaitent me soutenir ou utiliser mes photos. Il faut bien rembourser l&#8217;appareil et les objectifs qui sont très loin d&#8217;être gratuits.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/nouveautes-a-venir/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java c&#8217;est nul !</title>
		<link>http://www.pierreschambacher.com/blog/java-cest-nul/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=java-cest-nul</link>
		<comments>http://www.pierreschambacher.com/blog/java-cest-nul/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 18:02:02 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Informatique générale]]></category>
		<category><![CDATA[coup de gueule]]></category>
		<category><![CDATA[fail]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=312</guid>
		<description><![CDATA[Aujourd&#8217;hui c&#8217;est coup de gueule ! Je sors de ma longue torpeur pour gueuler un coup, JAVA C&#8217;EST NUL ! http://cestnul.fr/Java Etant donné que je ne suis pas homme à gueuler sans preuve, voici la démonstration de ce que j&#8217;avance. &#8230; <a href="http://www.pierreschambacher.com/blog/java-cest-nul/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui c&#8217;est coup de gueule ! Je sors de ma longue torpeur pour gueuler un coup, JAVA C&#8217;EST NUL ! <a href="http://cestnul.fr/Java">http://cestnul.fr/Java</a></p>
<p><span id="more-312"></span></p>
<p>Etant donné que je ne suis pas homme à gueuler sans preuve, voici la démonstration de ce que j&#8217;avance.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://www.pierreschambacher.com/wp-content/uploads/2010/02/javaFail-300x280.png" alt="Java Fail" /></p>
<p>Je vous laisse le temps de lire ce petit bout de code et deviner le résultat logique d&#8217;une exécution&#8230;<br />
Si vous pensez comme moi, vous vous attendez à ce résultat:</p>
<blockquote>
<div id="_mcePaste">Object: java.lang.String</div>
<div id="_mcePaste">Integer</div>
<div id="_mcePaste">Float</div>
</blockquote>
<p>Réfléchissons deux minutes.</p>
<p>Nous avons une liste qui contient différents objets, une chaîne de caractère, un entier et un nombre décimal. Notre classe Main présente une méthode polymorphique prenant en paramètre un Object, un Integer ou un Float.<br />
Pour le premier objet la méthode la plus approchante est la méthode avec le paramètre Object.<br />
Pour les deux autres la méthode avec le paramètre de type exact va être appelé du fait que la liaison en java est dynamique et décidée à l&#8217;exécution. Le fameux &laquo;&nbsp;VIRTUAL&nbsp;&raquo; des programmeurs C++.</p>
<p>Voyons le résultat de l&#8217;exécution (JVM 1.6 sur MacOS 10.6 dit &laquo;&nbsp;Snow Leopard&nbsp;&raquo;):</p>
<blockquote><p>Object: java.lang.String<br />
Object: java.lang.Integer<br />
Object: java.lang.Float</p></blockquote>
<p>Mais ????!!!! Voilà un résultat qui ferait lacher à nos amis anglo-saxons un virulent &laquo;&nbsp;WTF ?!&nbsp;&raquo;. Que c&#8217;est-il passé ?</p>
<p>Et bien c&#8217;est extrêmement facile. Nous nous trouvons devant un manique échec de Java et ses méthodes liées à l&#8217;exécution&#8230; Le compilateur voit que l&#8217;ArrayList contient des instances de Object, il voit une méthode prenant en paramètre un Object, il fait la liaison à la compilation. Dans le langage courant on dirait simplement: JAVA FAIL !</p>
<p>Si vous ne me croyez pas, vous pouvez simplement télécharger le fichier de test <a title="Démonstration du Java Fail" href="http://www.pierreschambacher.com/wp-content/uploads/2010/02/Main-exemple-1.txt" target="_blank">ici</a> (en renommant le fichier Main.java évidemment). Pour le principe j&#8217;ai changé Object en Number (superclasse de Integer, Float, Double, &#8230;) et le résultat est bien sûr le même, comme vous le constaterez <a title="Démonstration du Java Fail" href="http://www.pierreschambacher.com/wp-content/uploads/2010/02/Main-exemple-2.txt" target="_blank">là</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/java-cest-nul/feed/</wfw:commentRss>
		<slash:comments>11</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&#038;utm_medium=rss&#038;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 &#8230; <a href="http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-composants-classiques/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></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&#038;utm_medium=rss&#038;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 &#8230; <a href="http://www.pierreschambacher.com/blog/tutoriel-pour-developpeur-webobjects-hello-world/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></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>2</slash:comments>
		</item>
		<item>
		<title>Personnaliser eclipse sous Mac OS</title>
		<link>http://www.pierreschambacher.com/blog/personnaliser-eclipse-sous-mac-os/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=personnaliser-eclipse-sous-mac-os</link>
		<comments>http://www.pierreschambacher.com/blog/personnaliser-eclipse-sous-mac-os/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 11:38:44 +0000</pubDate>
		<dc:creator>Pierre Schambacher</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Informatique générale]]></category>
		<category><![CDATA[astuces]]></category>

		<guid isPermaLink="false">http://www.pierreschambacher.com/?p=267</guid>
		<description><![CDATA[Peut-être comme moi avez vous plusieurs versions d&#8217;eclipse installées sur votre Mac, et vous éprouvez quelques difficultés à vous y retrouver. Sachez qu&#8217;il est possible de personnaliser chaque version en lui attribuant un nom spécifique dans le dock, dans la &#8230; <a href="http://www.pierreschambacher.com/blog/personnaliser-eclipse-sous-mac-os/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Peut-être comme moi avez vous plusieurs versions d&#8217;eclipse installées sur votre Mac, et vous éprouvez quelques difficultés à vous y retrouver. Sachez qu&#8217;il est possible de personnaliser chaque version en lui attribuant un nom spécifique dans le dock, dans la barre de menu et également de changer son icône. Puisque l&#8217;on est dans la personnalisation d&#8217;eclipse j&#8217;en profiterais pour expliquer comment changer la quantité de RAM dédiée à eclipse. Par ici les explications.</p>
<p><span id="more-267"></span></p>
<h1>Nom dans le dock</h1>
<p>Ici c&#8217;est la manoeuvre la plus simple. Repérez dans votre dock le eclipse que vous souhaitez renommez, clic droit, [Snow Leopard] menu Options, [/Snow Leopard] Afficher dans le Finder.<br />
Vous devriez voir votre Eclipse.app. Renommez ce fichier avec le nom que vous souhaitez, si par exemple comme moi vous avez un eclipse spécialement pour WOLips, appelez le WOLips.app. Pour que le changement prenne effet immédiatement, supprimez l&#8217;ancienne icône du dock et cliquez-glissez l&#8217;application renommée vers le dock.</p>
<h1>Icône dans le dock</h1>
<p>Reproduisez la manoeuvre précédente pour arriver jusqu&#8217;au fichier .app, faites un clic droit dessus et choisissez &laquo;&nbsp;Affichier le contenu du paquet&nbsp;&raquo;. Une nouvelle fenêtre s&#8217;ouvre avec un dossier &laquo;&nbsp;Contents&nbsp;&raquo; qui contient lui-même un dossier &laquo;&nbsp;MacOS&nbsp;&raquo; et un dossier &laquo;&nbsp;Resources&nbsp;&raquo;. Ouvrez le dossier Resources et vous êtes devant l&#8217;icône utilisée par eclipse au format icns. Je vous conseille de renommer cette icône en Eclipse_old.icns afin de pouvoir éventuellement la remettre en place un jour, puis placez dans ce dossier l&#8217;icône que vous souhaitez utiliser avec pour nom &laquo;&nbsp;Eclipse.icns&nbsp;&raquo;.</p>
<p>Le format à utiliser n&#8217;est pas jpg ou png mais icns. Je vous recommande cet <a title="Utilitaire Image to ICNS" href="http://mac.softpedia.com/get/Multimedia/img2icns.shtml" target="_blank">utilitaire</a> pour transformer vos images en fichier icône. Privilégiez le format png en entrée avec une bonne gestion de la transparence et une bonne résolution (idéalement 512&#215;512 minimum) pour ne pas avoir une icône dégueulasse dans votre joli dock.</p>
<h1>Nom dans la barre de menu</h1>
<p>Vous remarquerez que malgré que vous ayez changé le nom du fichier .app, l&#8217;application une fois lancée s&#8217;appelle toujours Eclipse dans la barre de menu (tout en haut à gauche, à côté de l&#8217;icône Pomme).<br />
Pour changer cela, direction le fichier eclipse.ini qui se trouve dans le fichier .app (reproduire la manoeuvre indiquée pour le changement d&#8217;icône) dans le dossier Contents/MacOS. Modifiez ce fichier avec un éditeur texte quelconque et ajoutez simplement une ligne:</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">-Xdock:icon=../Resources/Eclipse.icns</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">-Xdock:name=WOLips</div>
<blockquote><p>-Xdock:icon=../Resources/Eclipse.icns<br />
-Xdock:name=WOLips</p></blockquote>
<p>Si vous regardez votre fichier la ligne Xdock:icon existe déjà. Il suffit d&#8217;ajouter -Xdock:name= suivi du nom que vous souhaitez utiliser pour votre application, probablement le même que celui que vous avez donné à l&#8217;icône dans le dock.</p>
<h1>Mémoire autorisée pour l&#8217;application</h1>
<p>Selon l&#8217;usage que vous faite de votre instance d&#8217;eclipse, vous pouvez avoir des besoins particulier en mémoire. Si par exemple vous utilisez le plug-in Flex Builder 3 et sa gestion pitoyable de la mémoire, vous risquez d&#8217;être confronté à des ralentissements du fait du trop faible espace mémoire dédié à l&#8217;application. Inversement, vous utilisez peut-être plusieurs instances d&#8217;eclipse en même temps et vous tenez absolument à ne pas swapper, et vous souhaitez donc que chaque instance utilise une quantité maximum de mémoire précise qui évitera de déborder de votre quantité de RAM.<br />
Retournez donc dans le fichier eclipse.ini situé dans Eclipse.app/Contents/MacOS et repérez les deux lignes suivantes:</p>
<blockquote><p>-Xms128m<br />
-Xmx1024m</p></blockquote>
<p>Si vous n&#8217;avez rien touché les valeurs après Xms et Xmx devraient différer ce celles-ci. Le chiffre suivant Xms est la quantité minimum de mémoire allouée à eclipse, et celle après Xmx est la quantité maximum qui lui sera dédiée. Étant donné que je dispose de 4Go de RAM que j&#8217;exploite peu, la quantité maximum est réglée sur 1Go afin d&#8217;éviter des ralentissements dans eclipse. À vous de juger de la quantité adéquat pour votre machine et votre utilisation d&#8217;eclipse.</p>
<h1>Appel aux lecteurs</h1>
<p>Je suis toujours à la recherche d&#8217;une personnalisation supplémentaire. Malgré tous ces changements, Spaces identifie toujours les deux instances d&#8217;eclipse comme une seule application. Il est donc impossible d&#8217;indiquer que l&#8217;instance &laquo;&nbsp;eclipse normal&nbsp;&raquo; va sur la Space 1, et que l&#8217;instance &laquo;&nbsp;eclipse WOLips&nbsp;&raquo; va sur le Space 2. Si un lecteur passant par là sait ce qu&#8217;il faut toujours pour que Spaces soit capable de distinguer les deux applications, je suis preneur !! Laissez un commentaire, merci <img src='http://www.pierreschambacher.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Si vous avez d&#8217;autres idées de personnalisation, partagez aussi d&#8217;ailleurs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pierreschambacher.com/blog/personnaliser-eclipse-sous-mac-os/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

