Ce site met a disposition le build journalier de la traduction francaise du Maven: The Definitive Guide
Consultez :
  • Les documents de reference sur le projet original
  • Les sources de la traduction fr sur GitHub
  • maven


    4.6. Code source de Simple Weather

    L'application en ligne de commande Simple Weather se compose de cinq classes Java.

    org.sonatype.mavenbook.weather.Main

    La classe Main contient une méthode static main(). Il s'agit du point d'entrée de votre système.

    org.sonatype.mavenbook.weather.Weather

    La classe Weather est un simple Java bean qui contient la position du rapport météo et quelques éléments clés, comme la température et l'humidité.

    org.sonatype.mavenbook.weather.YahooRetriever

    La classe YahooRetriever se connecte à Yahoo! Météo et renvoie un InputStream des données du flux RSS.

    org.sonatype.mavenbook.weather.YahooParser

    La classe YahooParser parse le XML de Yahoo! Météo, et renvoie un objet de type Weather.

    org.sonatype.mavenbook.weather.WeatherFormatter

    La classe WeatherFormatter prend un objet de type Weather en paramètre, construit un VelocityContext et applique le template Velocity.

    Même si nous ne détaillerons pas le code ici, nous vous fournirons tout le code nécessaire pour vous permettre d'exécuter cet exemple. Nous supposons que la plupart des lecteurs ont téléchargé les exemples qui accompagnent ce livre, mais nous prenons en compte ceux qui veulent suivre l'exemple de ce chapitre étape par étape. Les sections qui suivent listent les classes du projet simple-weather. Chacune de ces classes devrait être mise dans le même package : org.sonatype.mavenbook.weather.

    Supprimons les classes App et AppTest générées par archetype:generate et ajoutons notre nouveau package. Dans un projet Maven, tout le code source doit se trouver dans src/main/java. Depuis le répertoire racine de ce nouveau projet, exécutez les commandes suivantes :

    $ cd src/test/java/org/sonatype/mavenbook
    $ rm AppTest.java
    $ cd ../../../../../..
    $ cd src/main/java/org/sonatype/mavenbook
    $ rm App.java
    $ mkdir weather
    $ cd weather

    Ainsi, nous avons créé un nouveau package appelé org.sonatype.mavenbook.weather. Maintenant, il nous faut mettre nos classes dans ce répertoire. A l'aide de votre éditeur de texte favori, créez un nouveau fichier appelé Weather.java avec le contenu de l'Exemple 4.5, « Modèle Objet de la classe Weather du projet Simple Weather ».

    Exemple 4.5. Modèle Objet de la classe Weather du projet Simple Weather

    package org.sonatype.mavenbook.weather;
    
    public class Weather {
      private String city;
      private String region;
      private String country;
      private String condition;
      private String temp;
      private String chill;
      private String humidity;
        
      public Weather() {}
    
      public String getCity() { return city; }
      public void setCity(String city) { this.city = city; }
    
      public String getRegion() { return region; }
      public void setRegion(String region) { this.region = region; }
    
      public String getCountry() { return country; }
      public void setCountry(String country) { this.country = country; }
    
      public String getCondition() { return condition; }
      public void setCondition(String condition) { this.condition = condition; }
    
      public String getTemp() { return temp; }
      public void setTemp(String temp) { this.temp = temp; }
             
      public String getChill() { return chill; }
      public void setChill(String chill) { this.chill = chill; }
    
      public String getHumidity() { return humidity; }
      public void setHumidity(String humidity) { this.humidity = humidity; }
    }
    

    La classe Weather définit un simple bean utilisé pour stocker les données météo extraites du flux RSS de Yahoo! Météo. Ce flux fournit un grand nombre d'informations, depuis les heures de lever et de coucher du soleil, à la vitesse et la direction des vents. Pour garder cet exemple relativement simple, le modèle objet de Weather ne garde que la température, le facteur vent, l'humidité et une description textuelle des conditions actuelles.

    Maintenant, dans le même répertoire, créez un fichier Main.java. Cette classe Main contiendra la méthode static main() — point d'entrée de cet exemple.

    Exemple 4.6. Classe Main du projet Simple Weather

    package org.sonatype.mavenbook.weather;
    
    import java.io.InputStream;
    import org.apache.log4j.PropertyConfigurator;
    
    public class Main {
    
      public static void main(String[] args) throws Exception {
        // Configure Log4J
        PropertyConfigurator.configure(Main.class.getClassLoader()
                                           .getResource("log4j.properties"));
        // Read the Zip Code from the Command-line (if none supplied, use 60202)
        String zipcode = "60202";
        try {
          zipcode = args[0]);
        } catch( Exception e ) {}
        // Start the program
        new Main(zipcode).start();
      }
    
      private String zip;
    
      public Main(String zip) {
        this.zip = zip;
      }
    
      public void start() throws Exception {
        // Retrieve Data
        InputStream dataIn = new YahooRetriever().retrieve( zip );
        // Parse Data
        Weather weather = new YahooParser().parse( dataIn );
        // Format (Print) Data
        System.out.print( new WeatherFormatter().format( weather ) );
      }
    }
    

    La méthode main() ci-dessus configure Log4J en récupérant une ressource depuis le classpath, puis essaye de lire un code postal depuis la ligne de commande. Si une exception survient lors de la lecture du code postal, le programme utilisera par défaut la valeur 60202 comme code postal. Une fois qu'il a un code postal, il instancie la classe Main et appelle la méthode start() de cette instance. La méthode start() appelle le YahooRetriever pour qu'il récupère le XML représentant les prévisions météo. Le YahooRetriever renvoie un InputStream qui est ensuite passé en paramètre du YahooParser. Le YahooParser parse le XML de Yahoo! Météo et renvoie un objet de type Weather. Pour terminer, le WeatherFormatter prend en paramètre un objet de type Weather et retourne une String formatée qui est affichée sur la sortie standard.

    Créez un fichier YahooRetriever.java dans le même répertoire avec le contenu présenté dans l'Exemple 4.7, « La classe YahooRetriever du projet Simple Weather ».

    Exemple 4.7. La classe YahooRetriever du projet Simple Weather

    package org.sonatype.mavenbook.weather;
    
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;
    
    import org.apache.log4j.Logger;
    
    public class YahooRetriever {
    
      private static Logger log = Logger.getLogger(YahooRetriever.class);
    
      public InputStream retrieve(int zipcode) throws Exception {
        log.info( "Retrieving Weather Data" );
        String url = "http://weather.yahooapis.com/forecastrss?p=" + zipcode;
        URLConnection conn = new URL(url).openConnection();
        return conn.getInputStream();
      }
    }
    

    Cette classe très simple ouvre une URLConnection sur l'API de Yahoo! Météo et renvoie un InputStream. Pour créer quelque chose capable de parser ce flux, nous allons devoir créer le fichier YahooParser.java dans le même répertoire.

    Exemple 4.8. Classe YahooParser du projet Simple Weather

    package org.sonatype.mavenbook.weather;
    
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.log4j.Logger;
    import org.dom4j.Document;
    import org.dom4j.DocumentFactory;
    import org.dom4j.io.SAXReader;
    
    public class YahooParser {
    
      private static Logger log = Logger.getLogger(YahooParser.class);
    
      public Weather parse(InputStream inputStream) throws Exception {
        Weather weather = new Weather();
      
        log.info( "Creating XML Reader" );
        SAXReader xmlReader = createXmlReader();
        Document doc = xmlReader.read( inputStream );
    
        log.info( "Parsing XML Response" );
        weather.setCity( doc.valueOf("/rss/channel/y:location/@city") );
        weather.setRegion( doc.valueOf("/rss/channel/y:location/@region") );
        weather.setCountry( doc.valueOf("/rss/channel/y:location/@country") );
        weather.setCondition( doc.valueOf("/rss/channel/item/y:condition/@text") );
        weather.setTemp( doc.valueOf("/rss/channel/item/y:condition/@temp") );
        weather.setChill( doc.valueOf("/rss/channel/y:wind/@chill") );
        weather.setHumidity( doc.valueOf("/rss/channel/y:atmosphere/@humidity") );
      
        return weather;
      }
    
      private SAXReader createXmlReader() {
        Map<String,String> uris = new HashMap<String,String>();
            uris.put( "y", "http://xml.weather.yahoo.com/ns/rss/1.0" );
            
        DocumentFactory factory = new DocumentFactory();
        factory.setXPathNamespaceURIs( uris );
            
        SAXReader xmlReader = new SAXReader();
        xmlReader.setDocumentFactory( factory );
        return xmlReader;
      }
    }
    

    La classe YahooParser est la classe la plus complexe de cet exemple. Nous n'allons pas détailler l'utilisation de Dom4J ou de Jaxen ici, cependant cette classe mérite quelques explications. Dans la classe YahooParser, la méthode parse() prend un InputStream en paramètre et renvoie un objet de type Weather. Pour cela, elle doit parser un document XML avec Dom4J. Puisque nous nous intéressons aux éléments dans l'espace de nommage XML de Yahoo! Météo, nous avons besoin d'un SAXReader sensible aux espaces de nommage dans la méthode createXmlReader(). Une fois que nous avons créé ce parseur et que nous avons parsé le document, nous obtenons en retour un objet de type org.dom4j.Document. Au lieu de parcourir tous ses éléments fils, nous récupérons uniquement les informations qui nous intéressent en les sélectionnant avec des expressions XPath. Dom4J permet de parser le XML dans cet exemple et Jaxen apporte ses capacités XPath.

    Une fois que nous avons créé un objet de type Weather, nous avons besoin de formater ce résultat pour qu'il soit lisible. Créez un fichier WeatherFormatter.java dans le même répertoire que les autres classes.

    Exemple 4.9. Classe WeatherFormatter du projet Simple Weather

    package org.sonatype.mavenbook.weather;
    
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.io.StringWriter;
    
    import org.apache.log4j.Logger;
    import org.apache.velocity.VelocityContext;
    import org.apache.velocity.app.Velocity;
    
    public class WeatherFormatter {
    
      private static Logger log = Logger.getLogger(WeatherFormatter.class);
    
      public String format( Weather weather ) throws Exception {
        log.info( "Formatting Weather Data" );
        Reader reader = 
          new InputStreamReader( getClass().getClassLoader()
                                     .getResourceAsStream("output.vm"));
        VelocityContext context = new VelocityContext();
        context.put("weather", weather );
        StringWriter writer = new StringWriter();
        Velocity.evaluate(context, writer, "", reader);
        return writer.toString();
      }
    }
    

    La classe WeatherFormatter utilise Velocity pour appliquer un masque. La méthode format() prend un bean de type Weather en paramètre et renvoie une String formatée. La première chose que fait la méthode format() est de charger depuis le classpath un template Velocity appelé output.vm. Puis nous créons un VelocityContext qui contient un unique objet de type Weather appelé weather. Un objet de type StringWriter est créé pour contenir le résultat de l'application du masque. Le masque est évalué par un appel à Velocity.evaluate() et le résultat est renvoyé sous la forme d'une String.

    Avant de pouvoir exécuter cet exemple, nous allons devoir ajouter des ressources à notre classpath.