/**
*
*/
package factories;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import data.abonne.Abonne;
import data.reservation.Fauteuil;
import data.reservation.Personne;
import data.reservation.Reservation;
import data.tarif.Categorie;
import exceptions.ReservationInexistanteException;
/**
* @author Matej Hausenblas
* @author brahim
*
*/
/**
* @author Matej Hausenblas matej.hausenblas@gmail.com
*
*/
public class FabReservation {
/**
* 8 x 24h pour expiration d'une reservation
*/
private static long CONST_EXPIRATION_TIME = 8*86400000;
/**
* Connexion JDBC
*/
private Connection c;
/*
* Traitement du singleton de la fabrique
*/
private static FabReservation instance;
/**
* Constructeur prive
*
*/
public FabReservation() {
}
/**
* Recuperation du singleton de FabReservation
*
* @return
*/
public static FabReservation getInstance() {
if (instance == null)
instance = new FabReservation();
return instance;
}
// requetes SQL
/**
* Ordre des colonnes recuperees
* 1. String IDRESERVATION
*/
private String SQLReservationsSeanceZone = "SELECT IDRESERVATION"
+ " FROM RESERVATION "
+ " WHERE IDSEANCE = ?" + " AND IDZONE = ?";
/**
* Recherche du maximum parmi les identifiants de reservations
*/
private String selectMaxId = "select max(idreservation) from reservation";
/**
* Recherche de tous les fauteuils correspondant a une reservation
*/
private String SQLSelectFauteuilsReservation = "SELECT IDZONEFT, IDRANGEEFT, IDFAUTEUIL" +
" FROM FAUTEUIL " +
"WHERE IDRESERVATION = ?";
/** rechercher toutes les personnes correspondant a une reservation */
private String SQLSelectPersonnesReservation = "SELECT NOM, PRENOM, NOMCATEGORIE " +
"FROM PERSONNE " +
"WHERE IDRESERVATION = ?";
/*
* Requêtes de création d'une réservationn des fauteuil et personnes
* associées
*
*/
private String insertReservation = "insert into reservation(idReservation,"
+ "dateReservation,dateConfirmation,nbPlacesReservees,idSeance,idAbonne,idZone) "
+ "values(?,?,?,?,?,?,?) ";
/** inserer un fauteuil */
private String insertFauteuil = "insert into fauteuil(idFAuteuil,idRangeeFt,"
+ "idZoneFt,idReservation) values(?,?,?,?)";
/** inserer une personne */
private String insertPersonne = "insert into personne(nom,prenom,idReservation,"
+ "nomCategorie) values(?,?,?,?)";
/** recherche d'une reservation */
private String selectReservation = "select * from reservation where "
+ " idReservation = ? ";
/*
* Requetes de deletion de reservations
*/
private String deleteReservation = "DELETE FROM RESERVATION " +
"WHERE IDRESERVATION = ?";
/** recherche de la date de confirmation d'une reservation */
private String selectDateConfirmation = "select dateConfirmation from "+
" reservation where idReservation = ? ";
/** effacement des personnes correspondant a une reservation */
private String SQLDeletePersonnesReservation = "DELETE FROM PERSONNE WHERE IDRESERVATION = ?";
/** suppression des fauteuils d'une reservation */
private String SQLDeleteFauteuilsReservation = "DELETE FROM FAUTEUIL WHERE IDRESERVATION = ?";
/** recherche des reservations avec la date de reservation etant
* trop ancienne pour la regle de gestion
*/
private String SQLSelectReservationsAnciennes = "SELECT IDRESERVATION, DATECONFIRMATION, DATERESERVATION FROM RESERVATION " +
"WHERE DATERESERVATION <= ?";
/** confirmation d'une reservation a une date */
private String SQLInvalidateReservation = "UPDATE RESERVATION SET DATECONFIRMATION=? WHERE IDRESERVATION = ?";
/** recherche d'existence d'une reservation */
private String SQLFindReservation = "SELECT IDRESERVATION FROM RESERVATION WHERE IDRESERVATION = ?";
/** validation d'une reservation */
private String SQLConfirmReservation = "UPDATE RESERVATION SET DATECONFIRMATION = ? WHERE IDRESERVATION = ?";
// Statements
private PreparedStatement pReservSeanceZone;
private PreparedStatement pInsertReservation;
private PreparedStatement pInsertFauteuil;
private PreparedStatement pInsertPersonne;
private PreparedStatement pSelectMaxId;
private PreparedStatement pSelectReservation;
private PreparedStatement pSelectFauteuilsReserv;
private PreparedStatement pSelectPersonnesReservation;
private PreparedStatement pDeleteReservation;
private PreparedStatement pDeletePersonnesReservation;
private PreparedStatement pDeleteFauteuilsReservation;
private PreparedStatement pSelectAnciens;
private PreparedStatement pInvalidateReservation;
private PreparedStatement pFindReservation;
private PreparedStatement pSelectDateConfirmation;
/** 1. Date 2. idReservation */
private PreparedStatement pConfirmReservation;
/**
* Initialise les Statements
*
*/
private void init() throws SQLException {
pReservSeanceZone = this.c.prepareStatement(SQLReservationsSeanceZone);
//pFauteuilsReserv = this.c.prepareStatement(SQLFauteuilsReservation);
pInsertReservation = this.c.prepareStatement(insertReservation);
pInsertFauteuil = this.c.prepareStatement(insertFauteuil);
pInsertPersonne = this.c.prepareStatement(insertPersonne);
pSelectMaxId = this.c.prepareStatement(selectMaxId);
pSelectReservation = this.c.prepareStatement(selectReservation);
pSelectFauteuilsReserv = this.c.prepareStatement(SQLSelectFauteuilsReservation);
pSelectPersonnesReservation = this.c.prepareStatement(SQLSelectPersonnesReservation);
pDeleteReservation = this.c.prepareStatement(deleteReservation);
pDeletePersonnesReservation = this.c.prepareStatement(SQLDeletePersonnesReservation);
pDeleteFauteuilsReservation = this.c.prepareStatement(SQLDeleteFauteuilsReservation);
pSelectAnciens = this.c.prepareStatement(SQLSelectReservationsAnciennes);
pInvalidateReservation = this.c.prepareStatement(SQLInvalidateReservation);
pFindReservation = this.c.prepareStatement(SQLFindReservation);
pConfirmReservation = this.c.prepareStatement(SQLConfirmReservation);
pSelectDateConfirmation = this.c.prepareStatement(selectDateConfirmation);
}
/**
* Mise en place d'une connexion JDBC au singleton
*
* @param c
* @throws SQLException
*/
public void setConnection(Connection c) throws SQLException {
this.c = c;
this.init();
}
/**
* Recuperation des reservations pour une seance donnee et pour une zone
* donnee
*/
public Collection getLesReservations(String idSeance, String idZone) throws SQLException {
ArrayList reservs = new ArrayList();
pReservSeanceZone.clearParameters();
pReservSeanceZone.setString(1, idSeance);
pReservSeanceZone.setString(2, idZone);
ResultSet rs = pReservSeanceZone.executeQuery();
while (rs.next()) {
/* TODO: verify reservations load correctly!!! */
Reservation r = this.getReservation(rs.getString(1));
reservs.add(r);
}
return reservs;
}
/**
*
* @return
* @throws SQLException
*/
private int getNewNumberId() throws SQLException {
pSelectMaxId.clearParameters();
ResultSet rsMaxId = pSelectMaxId.executeQuery();
int maxValue = 0;
if (rsMaxId.next())
maxValue = rsMaxId.getInt(1);
return ++maxValue;
}
/**
*
* @param idSeance
* @return
* @throws SQLException
*/
public String getNewId(String idSeance) throws SQLException {
return idSeance +"-"+ this.getNewNumberId();
}
/**
*
* @param idReservation
* @param f
* @throws SQLException
*/
public int creerFauteuil(String idReservation, Fauteuil f)
throws SQLException {
int idR = this.extractIDReservation(idReservation);
pInsertFauteuil.clearParameters();
//System.out.println("NUMERO DE FAUTEUIL = "+f.getNumero());
pInsertFauteuil.setInt(1, f.getNumero());
pInsertFauteuil.setString(2, f.getRangee());
pInsertFauteuil.setString(3, f.getZone());
pInsertFauteuil.setInt(4, idR);
// On insére le fauteuil dans la bdd
return pInsertFauteuil.executeUpdate();
}
/**
*
* @param idReservation
* @param p
* @return
* @throws SQLException
*/
public int creerPersonnes(String idReservation, Personne p)
throws SQLException {
int idR = this.extractIDReservation(idReservation);
pInsertPersonne.clearParameters();
pInsertPersonne.setString(1, p.getNom());
pInsertPersonne.setString(2, p.getPrenom());
pInsertPersonne.setInt(3, idR);
pInsertPersonne.setString(4, p.getCategorie().toString());
return pInsertPersonne.executeUpdate();
}
/**
*
* @param idReservation
* @return
* @throws SQLException
*/
/*
public Reservation getReservation(String idReservation) throws SQLException {
pSelectReservation.clearParameters();
pSelectReservation.setString(1, idReservation);
ResultSet rsRes = pSelectReservation.executeQuery();
if (rsRes.next()) {
String idRes = rsRes.getString(1);
Date dateRes = rsRes.getDate(2);
// Vaut peut etre null, attention
Date dateConfirm = rsRes.getDate(3);
int nbPlaces = rsRes.getInt(4);
String idSeance = rsRes.getString(5);
//Que faire de cela ?
String idAbonne = rsRes.getString(6);
String idZone = rsRes.getString(7);
Reservation res = new Reservation(idRes,idZone,dateRes, dateConfirm,idSeance,
nbPlaces);
return res;
}
return null;
}
*/
/**
* Recherche d'une reservation a partir d'un identifiant.<br />
* Remplit les fauteuils et personnes
* @param idReservation
* @return
* @throws SQLException
*/
public Reservation getReservation(String idReservation)
throws SQLException {
int idR = this.extractIDReservation(idReservation);
// preparation des requetes
pSelectReservation.clearParameters();
pSelectReservation.setInt(1, idR);
pSelectPersonnesReservation.clearParameters();
pSelectPersonnesReservation.setInt(1, idR);
ResultSet rsRes = pSelectReservation.executeQuery();
ResultSet rsPersRes = pSelectPersonnesReservation.executeQuery();
if (rsRes.next()) {
int idRes = rsRes.getInt(1);
Date dateRes = rsRes.getDate(2);
// Vaut peut etre null, attention
Date dateConfirm = rsRes.getDate(3);
int nbPlaces = rsRes.getInt(4);
String idSeance = rsRes.getString(5);
//Que faire de cela ?
String idAbonne = rsRes.getString(6);
Abonne abo = null;
if(idAbonne != null){
FabAbonne.getInstance().setConnection(this.c);
abo = FabAbonne.getInstance().rechercher(idAbonne);
}
String idZone = rsRes.getString(7);
Reservation res = new Reservation(idReservation,idZone,dateRes,
dateConfirm,idSeance,nbPlaces);
// ajout de l'abonne eventuel
if(abo != null)
res.setAbonne(abo);
// remplissage des fauteuils, delegue par interet
res.remplirFauteuils(this.getFauteuilsReservation(idReservation));
/*
* de meme remplissage des personnes
*/
while(rsPersRes.next()){
String nom = rsPersRes.getString(1);
String prenom = rsPersRes.getString(2);
String categorie = rsPersRes.getString(3);
Personne p = new Personne(nom, prenom, new Categorie(categorie));
res.addPersonne(p);
}
// retourner le resultat
return res;
}
return null;
}
/**
* Création de la réservation et des éléments associés tels que les
* fauteuils et les personnes
*
* @param r
*/
public void creerReservation(Reservation r) throws SQLException {
int idR = this.extractIDReservation(r.getIdReserv());
pInsertReservation.clearParameters();
// Insertion de la réservation
pInsertReservation.setInt(1, idR);
pInsertReservation.setDate(2, r.getDateReserv());
// On ne fixe pas la date de réservation, elle sera fixée plus tard
pInsertReservation.setDate(3, null);
pInsertReservation.setInt(4, r.getNbPersonnes());
pInsertReservation.setString(5, r.getIdSeance());
Abonne a = r.getAbonne();
if (a != null)
pInsertReservation.setString(6, a.getIdAbo());
pInsertReservation.setString(7, r.getIdZone());
//Création de la réservation
pInsertReservation.executeUpdate();
pInsertReservation.close();
// Insertion des personnes
Iterator itPersonnes = r.getLesPersonnes().iterator();
while (itPersonnes.hasNext()) {
this.creerPersonnes(r.getIdReserv(), (Personne) itPersonnes.next());
}
// Insertion des fauteuils
Iterator itFauteuils = r.getLesFauteuils().iterator();
while (itFauteuils.hasNext()) {
this.creerFauteuil(r.getIdReserv(), (Fauteuil) itFauteuils.next());
}
//On commite pour etre sur que tout est pris en compte
/*c.commit();
Connection oldConnection = c;
c = oldConnection;
*/
//On ferme pour commiter
}
/**
* Recuperation de l'ensemble des Fauteuils pour une reservation
* @param idReservation String identifiant la reservation pour laquelle on cherche
* les Fauteuils
* @return Collection de Fauteuils de cette Reservation.
* @throws SQLException Si probleme de connexion a la base de donnees.
*/
public Collection getFauteuilsReservation(String idReservation)
throws SQLException{
int idR = this.extractIDReservation(idReservation);
pSelectFauteuilsReserv.clearParameters();
pSelectFauteuilsReserv.setInt(1, idR);
ResultSet rsFtRes = pSelectFauteuilsReserv.executeQuery();
ArrayList res = new ArrayList();
/*
* remplissage des fauteuils
*/
while(rsFtRes.next()){
String idZone = rsFtRes.getString(1);
String idRangee = rsFtRes.getString(2);
int idFauteuil = rsFtRes.getInt(3);
Fauteuil f = new Fauteuil(idZone, idRangee, idFauteuil);
res.add(f);
}
return res;
}
/**
* Deletion d'une reservation avec tout ce qui en depend:
* suppose que Fauteuil et Personne est en dependance de clef etrangere a on delete cascade
* @param idReservation Identifiant de la reservation
* @throws SQLException Exception en cas de probleme de connexion SQL.
*/
public void supprimerReservation(String idReservation) throws SQLException{
int idR = this.extractIDReservation(idReservation);
// preparation de l'effacement de Reservation
pDeleteReservation.clearParameters();
pDeleteReservation.setInt(1, idR);
// preparation de l'effacement des Personnes de la Reservation
pDeletePersonnesReservation.clearParameters();
pDeletePersonnesReservation.setInt(1, idR);
// preparation de l'effacement des Fauteuils de la Reservation
pDeleteFauteuilsReservation.clearParameters();
pDeleteFauteuilsReservation.setInt(1, idR);
// deletion des Personnes
pDeletePersonnesReservation.executeUpdate();
// deletion des Fauteuils
pDeleteFauteuilsReservation.executeUpdate();
// deletion de la Reservation-meme
pDeleteReservation.executeUpdate();
}
/**
* Recuperation d'anciennes reservations non confirmees
* @param d Date d'aujourd'hui
* @return Collection de String IdReservation qui ne sont pas confirmees et qui
* ont ete creees il y a plus de CONST_EXPIRATION_TIME jours.
* @throws SQLException Si probleme de connexion a la base de donnees.
*/
public Collection getAnciennesReservations(java.util.Date d) throws SQLException{
ArrayList l = new ArrayList();
java.sql.Date seuilExpiration = new Date(d.getTime() - CONST_EXPIRATION_TIME);
pSelectAnciens.clearParameters();
pSelectAnciens.setDate(1, seuilExpiration);
ResultSet rs = pSelectAnciens.executeQuery();
while(rs.next()){
String idReserv = rs.getString(1);
Date dateConfirm = rs.getDate(2);
if(dateConfirm == null){
// Reservation r = this.getReservation(id);
l.add(idReserv);
}
}
return l;
}
/**
* Suppression automatique d'anciennes reservations
* @param d java.util.Date qui signifie la date du jour.<br /><br />
* Si d null, on utilise la date actuelle du Calendar.
* @throws SQLException Si probleme de connexion a la base de donnees.
*/
public void annulerAnciennesReservations(java.util.Date d) throws SQLException{
if(d == null){
d = Calendar.getInstance().getTime();
}
Collection anciennesRes = this.getAnciennesReservations(d);
for(Iterator itARes = anciennesRes.iterator(); itARes.hasNext();){
//Reservation r = (Reservation)itARes.next();
String idReservation = (String)itARes.next();
this.supprimerReservation(idReservation/*r.getIdReserv()*/);
}
}
/**
* Verification de l'existence d'une Reservation a partir de son identifiant
* @param id String Identifiant de la Reservation recherchee
* @return boolean Vrai si une Reservation correspond a cet identifiant
* @throws SQLException Si probleme de connexion a la base de donnees.
*/
public boolean reservationExiste(String id)
throws SQLException,NumberFormatException{
int idR = this.extractIDReservation(id);
pFindReservation.clearParameters();
pFindReservation.setInt(1, idR);
ResultSet rsFind = pFindReservation.executeQuery();
if(!rsFind.next()){
// si la reservation n'existe pas, on lance une exception.
return false;
}
return true;
}
/**
* Confirmation d'une reservation.
* @param idReservation String identifiant la reservation
* @param d Date de confirmation de la Reservation
* @throws SQLException Si probleme de connexion a la base
* @throws ReservationInexistanteException Si l'identifiant de Reservation
* n'existe pas dans la Base de Donnees.
*/
public void confirmerReservation(String idReservation, java.util.Date d)
throws SQLException, ReservationInexistanteException,NumberFormatException{
int idR = this.extractIDReservation(idReservation);
/* verification d'existence de la reservation */
if(!this.reservationExiste(idReservation)){
// si la reservation n'existe pas, on lance une exception.
throw new ReservationInexistanteException("Reservation "
+idReservation+" n'existe pas!");
}
/*
* Si la reservation donnee existe, on met a jour la date
* de confirmation.
*/
java.sql.Date dateConfirm = new java.sql.Date(d.getTime());
pConfirmReservation.clearParameters();
pConfirmReservation.setDate(1, dateConfirm);
pConfirmReservation.setInt(2, idR);
pConfirmReservation.executeUpdate();
// et le tour est joue.
}
/**
* Renvoie la date de validation d'une réservation ou null si la réservation n'as pas été
* validée
* @param idReservation
* @return
* @throws SQLException
*/
public Date reservationValidee(String idReservation)
throws SQLException, NumberFormatException{
int idR = this.extractIDReservation(idReservation);
pSelectDateConfirmation.clearParameters();
pSelectDateConfirmation.setInt(1, idR);
ResultSet rsDateConf = pSelectDateConfirmation.executeQuery();
if(rsDateConf.next()){
return rsDateConf.getDate(1);
}
//La réservation n'a pas été validée
return null;
}
/**
* Recuperation du numero de reservation sous forme d'entier
* @param id String identifiant la reservation.
* Soit sous forme complete: XXXX-9999,
* soit sous forme numerique: 9999
* @return int Valeur en int du numero de reservation
* @throws NumberFormatException Si l'identifiant de la reservation n'est pas correct
*/
private int extractIDReservation(String id)
throws NumberFormatException{
String[] parts = id.trim().split("-");
String idReservAsString = parts[parts.length -1];
Integer idAsInteger = new Integer(idReservAsString);
return idAsInteger.intValue();
}
}