5. Annexes
5.1. Codes du paquetage [istia.st.articles.dao]
5.1.1. IArticlesDao
package istia.st.articles.dao;
import istia.st.articles.domain.Article;
import java.util.List;
/**
* @author serge
*
*/
public interface IArticlesDao {
/**
* @return : liste de tous les articles
*/
public List getAllArticles();
/**
* @param unArticle :
* l'article à ajouter
*/
public int ajouteArticle(Article unArticle);
/**
* @param idArticle :
* id de l'article à supprimer
*/
public int supprimeArticle(int idArticle);
/**
* @param unArticle :
* l'article à modifier
*/
public int modifieArticle(Article unArticle);
/**
* @param idArticle :
* id de l'article cherché
* @return : l'article trouvé ou null
*/
public Article getArticleById(int idArticle);
/**
* vide la table des articles
*/
public void clearAllArticles();
/**
*
* @param idArticle id de l'article dont on change le stock
* @param mouvement valeur à ajouter au stock (valeur signée)
*/
public int changerStockArticle(int idArticle, int mouvement);
}
5.1.2. ArticlesDaoSqlMap
package istia.st.articles.dao;
import java.io.*;
import java.sql.*;
import java.util.*;
import com.ibatis.common.resources.*;
import com.ibatis.sqlmap.client.*;
import istia.st.articles.domain.*;
import istia.st.articles.exception.*;
/**
* @author ST-ISTIA
*
*/
public class ArticlesDaoSqlMap
implements IArticlesDao {
/**
* sqlMap objet permettant l'accès aux données d'un SGBD
* est construit à partir d'un fichier de configuration
* exécute des requêtes SQL elles-aussi enregistrées dans un fichier de configuration
*/
private SqlMapClient sqlMap = null;
/**
*
* @return l'objet sqlMap d'accès aux données
*/
public SqlMapClient getSqlMap() {
return sqlMap;
}
/**
*
* @param sqlMap l'objet sqlMap d'accès aux données
*/
public void setSqlMap(SqlMapClient sqlMap) {
this.sqlMap = sqlMap;
}
/**
*
* @param sqlMapConfigFileName le nom du fichier de configuration de SqlMap
* @throws UncheckedAccessArticlesException si pb quelconque
*/
public ArticlesDaoSqlMap(String sqlMapConfigFileName) {
Reader reader = null;
UncheckedAccessArticlesException ex = null;
try {
reader = Resources.getResourceAsReader(sqlMapConfigFileName);
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
}
catch (Exception ex1) {
ex = new UncheckedAccessArticlesException(
"Erreur lors de la construction de l'objet [sqlMap] à partir du fichier de configuration ["
+ sqlMapConfigFileName + "] : ", ex1);
}
finally {
try {
reader.close();
}
catch (Exception ex2) {
if (ex != null) {
ex = new UncheckedAccessArticlesException(
"Erreur lors de la fermeture de l'objet [reader] à partir du fichier de configuration ["
+ sqlMapConfigFileName + "] : ", ex2);
}
}
}
// exception à lancer ?
if (ex != null) {
throw ex;
}
}
/**
* @return la liste de tous les articles de type Article
*/
public synchronized List getAllArticles() {
try {
return sqlMap.queryForList("getAllArticles", null);
}
catch (SQLException ex) {
throw new UncheckedAccessArticlesException(
"Echec de l'obtention de tous les articles : [" + ex + "]", ex);
}
}
/**
* @param unArticle l'article à ajouter
* @return le nombre d'articles ajoutés
* @throws UncheckedAccessArticlesException si échec
*/
public synchronized int ajouteArticle(Article unArticle) {
try {
// on prépare les paramètres
Map paramètres = new HashMap(5);
paramètres.put("id", new Integer(unArticle.getId()));
paramètres.put("nom", unArticle.getNom());
paramètres.put("prix", new Double(unArticle.getPrix()));
paramètres.put("stockactuel", new Integer(unArticle.getStockActuel()));
paramètres.put("stockminimum", new Integer(unArticle.getStockMinimum()));
// on joue la requête
return sqlMap.update("insertArticle", paramètres);
}
catch (SQLException ex) {
throw new UncheckedAccessArticlesException(
"Echec de l'ajout de l'article [" + unArticle + "] : [" + ex + "]",
ex);
}
}
/**
* @param idArticle id de l'article à supprimer
* @return le nombre d'articles supprimés
* @throws UncheckedAccessArticlesException si échec
*/
public synchronized int supprimeArticle(int idArticle) {
try {
// on prépare les paramètres
Map paramètres = new HashMap(1);
paramètres.put("id", new Integer(idArticle));
// on joue la requête
return sqlMap.update("deleteArticle", paramètres);
}
catch (SQLException ex) {
throw new UncheckedAccessArticlesException(
"Erreur lors de la suppression de l'article d'id [" + idArticle
+ "] : [" + ex + "]", ex);
}
}
/**
* @param unArticle l'article modifié qui doit remplacer l'ancien de même id
* @return le nombre d'articles modifiés
* @throws UncheckedAccessArticlesException si échec
*/
public synchronized int modifieArticle(Article unArticle) {
try {
// on prépare les paramètres
Map paramètres = new HashMap(5);
paramètres.put("id", new Integer(unArticle.getId()));
paramètres.put("nom", unArticle.getNom());
paramètres.put("prix", new Double(unArticle.getPrix()));
paramètres.put("stockactuel", new Integer(unArticle.getStockActuel()));
paramètres.put("stockminimum", new Integer(unArticle.getStockMinimum()));
// on joue la requête
return sqlMap.update("modifyArticle", paramètres);
}
catch (SQLException ex) {
throw new UncheckedAccessArticlesException(
"Erreur lors de la mise à jour de l'article [" + unArticle +
"] : ["
+ ex + "]", ex);
}
}
/**
* @param idArticle id de l'article cherché
* @return Article : l'article trouvé ou null
* @throws UncheckedAccessArticlesException si échec
*/
public synchronized Article getArticleById(int idArticle) {
try {
// on prépare les paramètres
Map paramètres = new HashMap(1);
paramètres.put("id", new Integer(idArticle));
// on joue la requête
Article article = (Article) sqlMap.queryForObject("getArticleById",
paramètres);
// on rend le résultat
return article;
}
catch (SQLException ex) {
throw new UncheckedAccessArticlesException(
"Erreur lors de la recherche de l'article d'id [" + idArticle
+ "] : [" + ex + "]", ex);
}
}
/**
* vide la table des articles
* @throws UncheckedAccessArticlesException si échec
*/
public synchronized void clearAllArticles() {
try {
sqlMap.update("clearAllArticles", null);
}
catch (SQLException ex) {
throw new UncheckedAccessArticlesException(
"Erreur lors de l'effacement de la table des articles : [" + ex +
"]",
ex);
}
}
/**
*
* @param pourcentage le pourcentage d'augmenttaion en entier
* @throws UncheckedAccessArticlesException si échec
*/
public synchronized void augmenterTousLesPrix(int pourcentage) {
try {
// on prépare les paramètres
Map paramètres = new HashMap(1);
paramètres.put("pourcentage", new Double(0.01 * pourcentage));
// on joue la requête
sqlMap.update("augmentationPrix", paramètres);
}
catch (SQLException ex) {
throw new UncheckedAccessArticlesException(
"Erreur l'augmentation des prix : [" + ex + "]", ex);
}
}
/**
* méthode de test
*/
public void badOperationThrowsException() {
// lance artificiellement une exception
throw new UncheckedAccessArticlesException();
}
/**
*
* @param articles Article[] liste d'articles à insérer dans une même transaction
* @throws UncheckedAccessArticlesException si échec
*/
public synchronized void doInsertionsInTransaction(Article[] articles) {
// on insère tous les articles comme un tout
UncheckedAccessArticlesException ex = null;
int i = 0;
Connection connexion = null;
try {
// on démarre la transaction
sqlMap.startTransaction();
// on fait les insertions
for (; i < articles.length; i++) {
ajouteArticle(articles[i]);
}
// on committe la transaction
sqlMap.commitTransaction();
}
catch (Exception ex1) {
// on encapsule l'exception
ex = new UncheckedAccessArticlesException(
"doInsertionsInTransaction, erreur d'accès à la base : [" + ex1 +
"]",
ex1);
}
finally {
try {
sqlMap.endTransaction();
}
catch (SQLException ex2) {
if(ex!=null){
ex = new UncheckedAccessArticlesException(
"doInsertionsInTransaction, échec du close : [" + ex2 + "]", ex2);
}
}
}
// exception à lancer ?
if (ex != null) {
throw ex;
}
}
/**
*
* @param idArticle id de l'article dont on change le stock
* @param mouvement mouvement de stock
*/
public synchronized int changerStockArticle(int idArticle, int mouvement) {
try {
// on prépare les paramètres
Map paramètres = new HashMap(2);
paramètres.put("id", new Integer(idArticle));
paramètres.put("mouvement", new Integer(mouvement));
// on joue la requête
return sqlMap.update("changerStockArticle", paramètres);
}
catch (SQLException e1) {
throw new UncheckedAccessArticlesException(
"Erreur lors du changement de stock [idArticle=" + idArticle +
", mouvement=" + mouvement + "] : [" + e1 + "]", e1);
}
}
}
5.1.3. Article
package istia.st.articles.dao;
import istia.st.articles.exception.UncheckedAccessArticlesException;
/**
* @author ST - ISTIA
*
*/
public class Article {
private int id;
private String nom;
private double prix;
private int stockActuel;
private int stockMinimum;
/**
* constructeur par défaut
*/
public Article() {
}
public Article(int id, String nom, double prix, int stockActuel,
int stockMinimum) {
// init attributs d'instance
setId(id);
setNom(nom);
setPrix(prix);
setStockActuel(stockActuel);
setStockMinimum(stockMinimum);
}
// getters - setters
public int getId() {
return id;
}
public void setId(int id) {
// id valide ?
if (id < 0)
throw new UncheckedAccessArticlesException("id[" + id + "] invalide");
this.id = id;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
// nom valide ?
if(nom==null || nom.trim().equals("")){
throw new UncheckedAccessArticlesException("Le nom est [null] ou vide");
}
this.nom = nom;
}
public double getPrix() {
return prix;
}
public void setPrix(double prix) {
// prix valide ?
if(prix<0) throw new UncheckedAccessArticlesException("Prix["+prix+"]invalide");
this.prix = prix;
}
public int getStockActuel() {
return stockActuel;
}
public void setStockActuel(int stockActuel) {
// stock valide ?
if (stockActuel < 0)
throw new UncheckedAccessArticlesException("stockActuel[" + stockActuel + "] invalide");
this.stockActuel = stockActuel;
}
public int getStockMinimum() {
return stockMinimum;
}
public void setStockMinimum(int stockMinimum) {
// stock valide ?
if (stockMinimum < 0)
throw new UncheckedAccessArticlesException("stockMinimum[" + stockMinimum + "] invalide");
this.stockMinimum = stockMinimum;
}
public String toString() {
return "[" + id + "," + nom + "," + prix + "," + stockActuel + ","
+ stockMinimum + "]";
}
}
5.2. Le paquetage [istia.st.articles.domain]
5.2.1. IArticlesDomain
package istia.st.articles.domain;
import java.util.ArrayList;
import java.util.List;
public interface IArticlesDomain {
public void acheter(Panier panier);
public List getAllArticles();
public Article getArticleById(int id);
public ArrayList getErreurs();
}
5.2.2. Achat
package istia.st.articles.domain;
public class Achat {
/**
* l'article acheté
*/
private Article article;
/**
* la qté achetée
*/
private int qte;
/**
* @return Returns le montant à payer pour l'achat
*/
public double getTotal() {
return article.getPrix() * qte;
}
/**
*
* @param article
* l'article acheté
* @param qte
* la qté achetée
*/
public Achat(Article article, int qte) {
this.article = article;
this.qte = qte;
}
/**
* @return Returns l'article acheté
*/
public Article getArticle() {
return article;
}
/**
* @param article
* l'article acheté
*/
public void setArticle(Article article) {
this.article = article;
}
/**
* @return Returns la qté achetée
*/
public int getQte() {
return qte;
}
/**
* @param qte
* la qté achetée
*/
public void setQte(int qte) {
this.qte = qte;
}
/**
* @return chaîne représentant l'achat
*/
public String toString() {
return "[" + this.article.toString() + "," + this.qte + "]";
}
}
5.2.3. Panier
package istia.st.articles.domain;
import java.util.ArrayList;
public class Panier {
/**
* liste des achats
*/
private ArrayList achats = new ArrayList();
/**
* @return Returns the achats.
*/
public ArrayList getAchats() {
return achats;
}
/**
* ajoute un achat
*
* @param unAchat
*/
public void ajouter(Achat unAchat) {
// on ajoute l'achat
// on cherche si l'article a déjà été acheté
int idArticle = unAchat.getArticle().getId();
Article article = null;
Achat achat = null;
boolean trouve = false;
for (int i = 0; !trouve && i < achats.size(); i++) {
achat = (Achat) achats.get(i);
article = (Article) achat.getArticle();
if (article.getId() == idArticle) {
achat.setQte(achat.getQte() + unAchat.getQte());
trouve=true;
}
}
// article trouvé ?
if (!trouve) {
// pas encore acheté - on ajoute l'achat
achats.add(unAchat);
}
}
/**
*
* @param idAchat
* l'id de l'achat à enlever du panier
*/
public void enlever(int idArticle) {
// on enlève l'achat d'id idAchat
for (int i = 0; i < achats.size(); i++) {
if (((Achat) achats.get(i)).getArticle().getId() == idArticle) {
achats.remove(i);
}
}
}
/**
*
* @return le total à payer
*/
public double getTotal() {
// on fait le total des achats
double total = 0;
for (int i = 0; i < achats.size(); i++) {
total += ((Achat) achats.get(i)).getTotal();
}
return total;
}
/**
* @return une chaîne représentant le panier
*/
public String toString() {
return this.achats.toString();
}
}
5.2.4. AchatsArticles
package istia.st.articles.domain;
import java.util.ArrayList;
import java.util.List;
import istia.st.articles.dao.IArticlesDao;
public class AchatsArticles implements IArticlesDomain {
private IArticlesDao articlesDao;
private Object synchro = new Object();
private ArrayList erreurs;
/**
* @return Returns the erreurs.
*/
public ArrayList getErreurs() {
return erreurs;
}
/**
*
* @param articlesDao
* leservice d'accès aux données
*/
public AchatsArticles(IArticlesDao articlesDao) {
this.articlesDao = articlesDao;
}
public List getAllArticles() {
return articlesDao.getAllArticles();
}
public Article getArticleById(int id) {
return articlesDao.getArticleById(id);
}
public void acheter(Panier panier) {
// on parcourt les achats
ArrayList achats = panier.getAchats();
erreurs = new ArrayList();
Article article = null;
Achat achat = null;
for (int i = achats.size() - 1; i >= 0; i--) {
// on récupère l'achat
achat = (Achat) achats.get(i);
// on tente de modifier le stock de l'article dans la base
int nbarticles =
articlesDao.changerStockArticle(
achat.getArticle().getId(),
-achat.getQte());
// a-t-on réussi ?
if (nbarticles != 0) {
achats.remove(i);
} else {
erreurs.add(
"Achat article ["
+ achat.getArticle()
+ ","
+ achat.getQte()
+ "] impossible - Vérifiez son stock");
}
}
}
}
5.3. Le paquetage [istia.st.articles.exception]
package istia.st.articles.exception;
public class UncheckedAccessArticlesException
extends RuntimeException {
public UncheckedAccessArticlesException() {
super();
}
public UncheckedAccessArticlesException(String mesg) {
super(mesg);
}
public UncheckedAccessArticlesException(String mesg, Throwable th) {
super(mesg, th);
}
}