| Ce site met a disposition le build journalier de la traduction francaise du Maven: The Definitive Guide Consultez : | ![]() |
L'application en ligne de commande Simple Weather se compose de cinq classes Java.
org.sonatype.mavenbook.weather.MainLa classe Main contient une méthode static main(). Il s'agit
du point d'entrée de votre système.
org.sonatype.mavenbook.weather.WeatherLa 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.YahooRetrieverLa classe YahooRetriever se connecte à Yahoo! Météo et renvoie un InputStream des données du flux RSS.
org.sonatype.mavenbook.weather.YahooParserLa classe YahooParser parse le XML de Yahoo! Météo, et renvoie
un objet de type Weather.
org.sonatype.mavenbook.weather.WeatherFormatterLa 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.