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


    7.8. Le module de ligne de commande

    Le projet simple-command est la version ligne de commande du projet simple-webapp. Cet utilitaire possède donc les mêmes dépendances : simple-persist et simple-weather. Au lieu d'interagir avec l'application par l'intermédiaire d'un navigateur web, vous pourrez exécuter cet utilitaire à partir de la ligne de commande.

    L'application en ligne de commande référence simple-weather et simple-persist

    Figure 7.4. L'application en ligne de commande référence simple-weather et simple-persist


    Exemple 7.19. POM du module simple-command

    <project xmlns="http://maven.apache.org/POM/4.0.0" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                          http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>org.sonatype.mavenbook.multispring</groupId>
        <artifactId>simple-parent</artifactId>
        <version>1.0</version>
      </parent>
    
      <artifactId>simple-command</artifactId>
      <packaging>jar</packaging>
      <name>Simple Command Line Tool</name>
    
      <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.5</source>
              <target>1.5</target>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
              <testFailureIgnore>true</testFailureIgnore>
            </configuration>
          </plugin>
          <plugin>
           <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>hibernate3-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
              <components>
                <component>
                  <name>hbm2ddl</name>
                  <implementation>annotationconfiguration</implementation>
                </component>
              </components>
            </configuration>
            <dependencies>
              <dependency>
                <groupId>hsqldb</groupId>
                <artifactId>hsqldb</artifactId>
                <version>1.8.0.7</version>
              </dependency>
            </dependencies>           
          </plugin>
        </plugins>
      </build>
    
      <dependencies>
        <dependency>
          <groupId>org.sonatype.mavenbook.multispring</groupId>
          <artifactId>simple-weather</artifactId>
          <version>1.0</version>
        </dependency>
        <dependency>
          <groupId>org.sonatype.mavenbook.multispring</groupId>
          <artifactId>simple-persist</artifactId>
          <version>1.0</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring</artifactId>
          <version>2.0.7</version>
        </dependency>
        <dependency>
          <groupId>hsqldb</groupId>
          <artifactId>hsqldb</artifactId>
          <version>1.8.0.7</version>
        </dependency>
      </dependencies>
    </project>
    

    Ce POM crée un fichier JAR qui contient la classe org.sonatype.mavenbook.weather.Main présentée dans l'Exemple 7.20, « La classe Main du module simple-command ». Dans ce POM nous configurons le plugin Maven Assembly pour utiliser le descripteur d'assemblage intégré appelé jar-with-dependencies qui créé un JAR contenant tout le bytecode nécessaire au projet pour s'exécuter : le bytecode du projet et celui de ses dépendances.

    Exemple 7.20. La classe Main du module simple-command

    package org.sonatype.mavenbook.weather;
    
    import java.util.List;
    
    import org.apache.log4j.PropertyConfigurator;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import org.sonatype.mavenbook.weather.model.Location;
    import org.sonatype.mavenbook.weather.model.Weather;
    import org.sonatype.mavenbook.weather.persist.LocationDAO;
    import org.sonatype.mavenbook.weather.persist.WeatherDAO;
    
    public class Main {
    
      private WeatherService weatherService;
      private WeatherDAO weatherDAO;
      private LocationDAO locationDAO;
    
      public static void main(String[] args) throws Exception {
        // Configuration de Log4J
        PropertyConfigurator.configure(Main.class.getClassLoader().getResource(
            "log4j.properties"));
    
        // Lecture du code postal à partir de la ligne de commande 
        String zipcode = "60202";
        try {
          zipcode = args[0];
        } catch (Exception e) {
        }
    
        // Lecture de l'opération à partir de la ligne de commande
        String operation = "weather";
        try {
          operation = args[1];
        } catch (Exception e) {
        }
    
        // Démarrage du programme
        Main main = new Main(zipcode);
    
        ApplicationContext context = 
          new ClassPathXmlApplicationContext(
            new String[] { "classpath:applicationContext-weather.xml",
                           "classpath:applicationContext-persist.xml" });
        main.weatherService = (WeatherService) context.getBean("weatherService");
        main.locationDAO = (LocationDAO) context.getBean("locationDAO");
        main.weatherDAO = (WeatherDAO) context.getBean("weatherDAO");
        if( operation.equals("weather")) {
          main.getWeather();
        } else {
          main.getHistory();
        }
      }
    
      private String zip;
    
      public Main(String zip) {
        this.zip = zip;
      }
    
      public void getWeather() throws Exception {
        Weather weather = weatherService.retrieveForecast(zip);
        weatherDAO.save( weather );
        System.out.print(new WeatherFormatter().formatWeather(weather));
      }
    
      public void getHistory() throws Exception {
        Location location = locationDAO.findByZip(zip);
        List<Weather> weathers = weatherDAO.recentForLocation(location);
        System.out.print(new WeatherFormatter().formatHistory(location, weathers));
      }
    }
    

    La classe Main possède des références vers WeatherDAO, LocationDAO et WeatherService. La méthode statique main() de cette classe :

    • Lit le code postal passé en premier argument de la ligne de commande

    • Lit l'opération à effectuer. Il s'agit du second argument à passer à la ligne de commande. Si l'opération est "weather", la dernière prévision sera récupérée à partir du service web. Si l'opération est "history", le programme récupérera l'historique des prévisions à partir de la base de données.

    • Charge l'ApplicationContext Spring en utilisant deux fichiers XML provenant des modules simple-persist et simple-weather

    • Crée une instance de la classe Main

    • Récupère les propriétés weatherService, weatherDAO, et locationDAO à partir des beans Spring de l'ApplicationContext

    • Appelle la méthode appropriée getWeather() ou getHistory() en fonction de l'opération demandée.

    Dans l'application web, nous utilisions le VelocityViewResolver proposé par Spring pour effectuer le rendu d'un template Velocity. Dans l'implémentation en ligne de commande, nous avons besoin d'écrire manuellement une classe qui permet d'afficher les données météorologiques à partir d'un template Velocity. L'Exemple 7.21, « WeatherFormatter affiche les prévisions météo en utilisant un template Velocity » affiche la classe WeatherFormatter. Cette classe possède donc deux méthodes qui permettent d'afficher respectivement les prévisions météorologiques et leur historique.

    Exemple 7.21. WeatherFormatter affiche les prévisions météo en utilisant un template Velocity

    package org.sonatype.mavenbook.weather;
    
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.io.StringWriter;
    import java.util.List;
    
    import org.apache.log4j.Logger;
    import org.apache.velocity.VelocityContext;
    import org.apache.velocity.app.Velocity;
    
    import org.sonatype.mavenbook.weather.model.Location;
    import org.sonatype.mavenbook.weather.model.Weather;
    
    public class WeatherFormatter {
    
      private static Logger log = Logger.getLogger(WeatherFormatter.class);
    
      public String formatWeather( Weather weather ) throws Exception {
        log.info( "Formatting Weather Data" );
        Reader reader = 
          new InputStreamReader( getClass().getClassLoader().
                                     getResourceAsStream("weather.vm"));
        VelocityContext context = new VelocityContext();
        context.put("weather", weather );
        StringWriter writer = new StringWriter();
        Velocity.evaluate(context, writer, "", reader);
        return writer.toString();
      }
    
      public String formatHistory( Location location, List<Weather> weathers )  
            throws Exception {
        log.info( "Formatting History Data" );
        Reader reader = 
          new InputStreamReader( getClass().getClassLoader().
                                     getResourceAsStream("history.vm"));
        VelocityContext context = new VelocityContext();
        context.put("location", location );
        context.put("weathers", weathers );
        StringWriter writer = new StringWriter();
        Velocity.evaluate(context, writer, "", reader);
        return writer.toString();
      }
    }
    

    Le template weather.vm affiche le code postal, la ville, le pays et les prévisions de température. Le template history.vm affiche le lieu et itère sur la liste des prévisions stockées dans la base de données. Ces deux templates se trouvent dans le dossier ${basedir}/src/main/resources.

    Exemple 7.22. Le template Velocity weather.vm

    ****************************************
    Current Weather Conditions for:
      ${weather.location.city},
      ${weather.location.region},
      ${weather.location.country}
    ****************************************
    
     * Temperature: ${weather.condition.temp}
     * Condition: ${weather.condition.text}
     * Humidity: ${weather.atmosphere.humidity}
     * Wind Chill: ${weather.wind.chill}
     * Date: ${weather.date}
    

    Exemple 7.23. Le template Velocity history.vm

    Weather History for:
    ${location.city},
    ${location.region},
    ${location.country}
    
    
    #foreach( $weather in $weathers )
    ****************************************
     * Temperature: $weather.condition.temp
     * Condition: $weather.condition.text
     * Humidity: $weather.atmosphere.humidity
     * Wind Chill: $weather.wind.chill
     * Date: $weather.date
    #end