Archive for October, 2006

La Police Idéale pour le Code

Monday, October 16th, 2006

Selon moi, la police Bitstream Vera Sans Mono est sans conteste la plus agréable pour écrire du code. J’en ai essayé pas mal ces dernières années et il y a quelques temps je suis tombé sur l’article Finding the Best Programmer’s Font. J’ai eu le “coup de foudre” pour la police citée en première place et je l’ai instantanément adoptée. Pour ne rien gâcher, c’est une police open source créée par le team Gnome. Voici pour la route une petite transcription des critères de notre ami n8f8 :

  • Caractères clairs et lisibles.
  • Jeu de caractères étendu (i.e. ascii 127+).
  • Interlettrage (espacement entre les caractères) judicieux et harmonieux.
  • Distinction claire entre ‘l’, ‘1′ et ‘i’.
  • Distinction claire entre ‘0′, ‘o’ and ‘O’.
  • Les “forward quotes” et les “back quotes” sont facilement distinguables - apparence miroir de préférence.
  • Caractères de ponctuation bien définis, particulièrement les braces et les parenthèses.

ASP.NET Web Parts Default Provider Loading Error Fix

Friday, October 13th, 2006

If your Visual Studio 2005 setup diverges slightly from the default setup, you may run into issues when trying to use the ASP.NET web parts. For example, on my development machine I got rid of SQL Server Express. The first time I tried to create a test portal with web parts, I had the following error message: “An error has occurred while establishing a connection to the server…” This error occurred because the web parts system tried to mount a database on the “./SQLEXPRESS” server, which I removed from my system.

The issue is very easy to fix. Locate the machine.config file in %WINDIR%\Microsoft.NET\Framework\v2.x\Config and change the “LocalSqlServer” connection string to wherever is your ASP.NET application services database, usually called aspnetdb. You will easily locate this entry in the “<connectionstrings>” section. For example, I changed my entry to the following:

<connectionstrings>
 <add name="LocalSqlServer"
   connectionString="Data source=.;Integrated Security=
   SSPI;Initial Catalog=aspnetdb"
   providerName="System.Data.SqlClient" />
</connectionstrings>

To initialize aspnetdb, you may have to run the aspnet_regsql.exe tool. See here for more information.

If you don’t want to change the machine.config, you can override the “LocalSqlServer” value in your web.config file as shown here:

<connectionstrings>
 <remove name="LocalSqlServer"/>
 <add name="LocalSqlServer"
   connectionString="Data source=.;Integrated Security=
   SSPI;Initial Catalog=aspnetdb"
   providerName="System.Data.SqlClient" />
</connectionstrings>

XSLT for the dummies

Monday, October 9th, 2006

Je ne sais pas si je suis victime du syndrome “quand tu as un marteau en main, au bout d’un moment tout ressemble à un clou”, mais en tout cas après StringTemplate la semaine dernière je m’adonne cette semaine aux joies de XSLT, un autre langage de définition de templates. Mon problème était de fournir un moyen générique à nos clients pour intégrer des fichiers XML dans notre produit. La solution évidente à ce problème est d’intégrer un moteur de transformation dans notre produit avec comme format de sortie notre format d’intégration existant (CSV).

Vu que nous utilisons déjà MSXML 4.0+ pour d’autres tâches, il était facile d’ajouter un point d’entrée vers cette API dans le module d’importation. C’est là que mon Program Manager me demande si on pouvait intégrer un mode “dummy” qui permet de générer un script XSLT à partir d’instructions de mapping simples. En effet, certaines personnes du support pourraient être rebutées par la syntaxe chevelue de XSLT. Il faut donc proposer une alternative simple à leurs pauvres cerveaux sursaturés. Certes, il nous faut donc quelque chose pour générer du XSLT. Euh, pourquoi ne pas utiliser XSLT lui-même? Et voilà! Le tag xsl:namespace-alias est exactement ce qu’il faut dans ces cas là, sans oublier xsl:comment qui permet de générer des commentaires dans le XML de sortie. Voici un extrait de mon générateur de XSLT (c’est vrai que la syntaxe est vraiment laide!):


    <?xml version="1.0" encoding="utf-8"?>

    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:xso="http://www.intelligo.ie/2006/XSLT/Generation"
      exclude-result-prefixes="xs"
      xmlns="http://www.w3.org/1999/xhtml"
      >

      <!--
        Générateur de XSLT
       -->

      <xsl:output method="xml" encoding="iso-8859-1"
           indent="yes" version="1.0"/>

      <!--On utilise l'alias xso quand on a besoin
          de générer des tags XSLT -->
      <xsl:namespace-alias stylesheet-prefix="xso"
          result-prefix="xsl"/>

      <!-- Template racine -->
      <xsl:template match="/">
        <xsl:apply-templates name="/tupleGen" />
      </xsl:template>

      <xsl:template match="tupleGen">
        <xso:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          exclude-result-prefixes="xs"
          xmlns="http://www.w3.org/1999/xhtml">

          <xsl:comment>** Generated on:
         <xsl:value-of select="@date" /> **</xsl:comment>

          <xso:output method="text"
         encoding="iso-8859-1" indent="no"/>

          <xsl:comment> This is the root template </xsl:comment>
          <xso:template match="/">

           [etc.]

          </xso:template>
        </xso:stylesheet>    
      </xsl:template>
    </xsl:stylesheet>

StringTemplate

Thursday, October 5th, 2006

L’une des grandes plaies du génie logiciel est la réinvention perpétuelle de la roue. Récemment confronté à un problème de génération de code, j’ai décidé de briser le cercle infernal. Ce que je m’apprêtais à ne pas redévelopper pour la énième fois s’appelle “template engine”. Travaillant dans le monde .NET, j’ai donc juste googlé “template engine .net” et je suis tout de suite tombé sur StringTemplate. Ayant déjà eu un bon feeling avec le compilateur de compilateur ANTLR je n’ai pas hésité à investir un peu de temps pour explorer le package.

Les points forts de StringTemplate sont:

  • Stricte séparation modèle/vue (en gros, pas de template spaghetti comme JSP ou ASP).

  • Fondements théoriques clairs et argumentés (ST, le langage de définition des templates, présente toutes les caractéristiques d’un langage fonctionnel).

  • Modèle push (toutes les données sont fournies au template avant l’évaluation i.e. pas de connexion à une base de données au sein du template!)

  • Une syntaxe très clean aussi bien pour les templates que pour l’API.

  • Bonne pérennité et bon support (ANTLR existe depuis 1989).

  • Disponible pour Java, .NET et Python.

En m’inspirant des exemples fournis, j’ai pu très vite monter mon système. En fait StringTemplate permet de faire les choses simples très facilement et possède assez de puissance pour rendre les choses bien plus complexes faisables sans trop bidouiller.

Pour le petit job que j’avais à faire les concepts de base m’ont suffit:

  • Groupe de templates (classe StringTemplateGroup) qui permet de définir une espèce de CLASSPATH où les fichiers template sont stockés (avec une extension “.st”). Un template stocké peut ensuite être référencé par son nom ou son chemin. En gros un template peut être vu comme une fonction.

  • Attribut multi-valué: il s’agit d’un attribut qui contient une liste de valeurs vs. attribut simple.

  • Application d’un template qui s’apparente à un appel de fonction.

Le principe de StringTemplate est plus long à expliquer qu’à coder. Imaginons que l’on veuille réaliser un mailing à partir d’une liste de noms et d’adresses. Il suffit de créer un fichier template appelé “c:\templates\mailing.st” avec le contenu suivant:

    Cher $nom$,

    Nous savons que vous habitez dans la ville de $ville$.

    Signé: Furax

Comme vous l’aurez deviné, les éléments du template sont isolés entre des dollars (”$”). Il est aussi possible d’utiliser les brackets à la HTML (”<” et “>”). Dans notre programme, le fichier mailing “mailing.txt” est généré grâce au code suivant:

    using System;
    using System.IO;
    using Antlr.StringTemplate;
    using Antlr.StringTemplate.Language;

    StringTemplateGroup group =
            new StringTemplateGroup("templates", @"c:\templates",
                    typeof(DefaultTemplateLexer));
    StringTemplate mailing = group.GetInstanceOf("mailing");

    mailing.SetAttribute("nom", "Jean Paul");
    mailing.SetAttribute("ville", "Paris");

    TextWriter tw = new StreamWriter("mailing.txt");
    tw.WriteLine(mailing.ToString());
    tw.Close();

Pour la petite histoire, j’ai bien apprécié la syntaxe de bloc inspirée de Smalltalk pour l’application de templates qui permet d’écrire des trucs du genre:

    $records:{ record |
        fields = new string[] {
            $record.fieldNames:{ f | "$f$"}; separator=", "$ };
        values = new object[] {
            $record.fieldCValues; separator=", "$ };
    }

Si records est une liste d’objets record dont l’attribut fieldNames contient une liste de noms de champs et l’attribut fieldCValues une liste d’expression C#, l’évaluation du template pourrait donner le résultat suivant:

    fields = new string[] { "A", "B", "C" };
    values = new object[] { 0, "32", DateTime.Today };
    fields = new string[] { "A", "B", "C" };
    values = new object[] { 44, "AA", DBNull.Value };

Je vais certainement réutiliser StringTemplate, notamment dans sa version pour Python. Par exemple, je pourrai l’utiliser avantageusemet comme une alternative gratuite à CodeSmith.