2022-10-26 15:10:08 +02:00
package fr.iutfbleau.projetIHM2022FI2.MNP ;
import fr.iutfbleau.projetIHM2022FI2.API.* ;
2022-11-26 18:09:08 +01:00
import java.sql.Connection ;
import org.mariadb.jdbc.* ;
import java.sql.DriverManager ;
import java.sql.ResultSet ;
import java.sql.PreparedStatement ;
import java.sql.SQLException ;
import javax.swing.JFrame ;
import javax.swing.JOptionPane ;
2022-10-26 15:10:08 +02:00
import java.util.* ;
/ * *
* Usine abstraite gérant l ' ensemble des groupes .
*
* /
public class AbstractGroupeFactoryNP implements AbstractGroupeFactory {
// la racine (promotion)
private Groupe promo ;
2022-11-26 18:09:08 +01:00
//la fentre pour les fenetre modale
private JFrame fenetre ;
2022-10-26 15:10:08 +02:00
// On utilise une table de hachage pour retrouver facilement un groupe (à partir de son id).
// Si il y a beaucoup de groupes c'est plus rapide que de parcourir toute une liste.
private HashMap < Integer , Groupe > brain ;
2022-11-12 22:11:05 +01:00
/ * *
* Le constructeur fabrique le groupe promotion déja plein ( utilisé en Modèle persistant de donné ) .
* /
2022-11-26 18:09:08 +01:00
public AbstractGroupeFactoryNP ( Groupe promo , JFrame fenetre ) {
2022-11-12 22:11:05 +01:00
this . promo = promo ;
2022-11-26 18:09:08 +01:00
this . fenetre = fenetre ;
2022-11-12 22:11:05 +01:00
this . brain = new HashMap < Integer , Groupe > ( ) ;
2022-11-13 15:00:55 +01:00
this . addSousGroupe ( this . promo ) ;
}
2022-11-26 18:09:08 +01:00
/ * *
* Le constructeur fabrique le groupe promotion vide .
* Il faut ensuite y ajouter les étudiants .
* /
public AbstractGroupeFactoryNP ( String name , int min , int max , JFrame fenetre ) {
Objects . requireNonNull ( name , " On ne peut pas créer une promotion dont le nom est null " ) ;
this . promo = new GroupeNP ( name , min , max ) ;
this . fenetre = fenetre ;
this . brain = new HashMap < Integer , Groupe > ( ) ;
this . brain . put ( Integer . valueOf ( this . promo . getId ( ) ) , this . promo ) ;
this . saveGroupe ( promo ) ;
}
2022-11-13 15:00:55 +01:00
/ * *
* permet d ' ajouter les sous groupe lors de l ' initialisation de la promo
* avec un groupe déja créer
*
* @param g le groupe ( methode récursive )
* /
private void addSousGroupe ( Groupe g ) {
2022-11-13 19:50:53 +01:00
this . brain . put ( g . getId ( ) , g ) ;
2022-11-13 15:00:55 +01:00
for ( Groupe s : g . getSousGroupes ( ) ) {
this . addSousGroupe ( s ) ;
}
2022-11-12 22:11:05 +01:00
}
2022-10-26 15:10:08 +02:00
/ * *
2022-10-31 12:53:56 +01:00
* Test plutôt optimiste . Si la clé est identique alors on fait comme si c ' était le bon groupe .
2022-11-13 00:37:08 +01:00
*
* @return true si le groupe est connu
2022-10-26 15:10:08 +02:00
* /
2022-10-31 12:53:56 +01:00
public Boolean knows ( Groupe g ) {
2022-10-26 15:10:08 +02:00
return this . brain . containsKey ( Integer . valueOf ( g . getId ( ) ) ) ;
}
2022-11-26 18:09:08 +01:00
public boolean changeNameGroupe ( Groupe g , String name ) {
if ( ! this . knows ( g ) ) {
throw new IllegalArgumentException ( " Groupe inconu " ) ;
}
Connection cnx = this . cnx ( ) ;
try {
PreparedStatement pst = cnx . prepareStatement (
" UPDATE `Groupe` SET `nom` = ? WHERE `Groupe`.`id` = ? "
) ;
pst . setString ( 1 , name ) ;
pst . setInt ( 2 , g . getId ( ) ) ;
pst . executeUpdate ( ) ;
pst . close ( ) ;
} catch ( SQLException e ) {
System . out . println ( e . toString ( ) ) ;
if ( this . erreurSQL ( ) ) {
this . changeNameGroupe ( g , name ) ;
} else {
return false ;
}
}
this . close ( cnx ) ;
g . setName ( name ) ;
return true ;
}
2022-10-26 15:10:08 +02:00
/ * *
* permet de récupérer le Groupe qui contient les étudiants de toute la promotion
* @return la promo .
* /
public Groupe getPromotion ( ) {
return this . promo ;
}
/ * *
* permet de supprimer un groupe connu de l ' usine abstraite qui ne contient pas de groupes .
* Pour détruire un groupe connu qui en contient d ' autres il faut le faire récursivement .
*
* @throws java . lang . NullPointerException si un argument est null
* @throws java . lang . IllegalStateException si le groupe contient des groupes
* @throws java . lang . IllegalArgumentException si le groupe n ' est pas connu de l ' usine abstraite ou bien si le groupe est celui de toute la promotion ( renvoyé par getPromotion )
* /
public void deleteGroupe ( Groupe g ) {
Objects . requireNonNull ( g , " On ne peut pas enlever un groupe null car null n'est pas un groupe autorisé " ) ;
2022-11-28 10:29:52 +01:00
//if (!this.knows(g)){
//throw new IllegalArgumentException("Impossible d'enlever un groupe inconnu");
//possible maintenant
//}
2022-10-26 15:10:08 +02:00
g . getPointPoint ( ) . removeSousGroupe ( g ) ;
this . brain . remove ( Integer . valueOf ( g . getId ( ) ) ) ;
2022-11-26 18:09:08 +01:00
this . suprGroupe ( g ) ;
2022-10-26 15:10:08 +02:00
}
/ * *
* permet d ' ajouter un groupe vide de type FREE comme sous - groupe d ' un groupe donné .
* @param pere le groupe père du groupe à créer
* @param name le nom du groupe à créer
* @param min , max bornes indicatives sur la taille du groupe à créer
*
* @throws java . lang . NullPointerException si un argument est null
* @throws java . lang . IllegalArgumentException si le groupe pere est de type PARTITION
* ou si il n ' y a pas 0 < min < = max
* /
public void createGroupe ( Groupe pere , String name , int min , int max ) {
Objects . requireNonNull ( pere , " Le groupe pere ne peut pas être null " ) ;
Objects . requireNonNull ( name , " Le nouveau groupe ne peut pas avoir null comme nom " ) ;
2022-11-26 18:09:08 +01:00
2022-11-28 10:29:52 +01:00
//if (!this.knows(pere)){
// throw new IllegalArgumentException("Interdit d'ajouter un fils à un groupe inconnu");
//Possible maintenant
//}
2022-10-26 15:10:08 +02:00
if ( pere . getType ( ) . equals ( TypeGroupe . PARTITION ) ) {
throw new IllegalArgumentException ( " Impossible d'ajouter un groupe à une parition. Il faut utiliser createPartition pour créer une partition " ) ;
}
if ( min < = 0 | | max < min ) {
throw new IllegalArgumentException ( " Il faut que 0 < min <= max " ) ;
}
2022-11-26 18:09:08 +01:00
2022-10-26 15:10:08 +02:00
Groupe g = new GroupeNP ( pere , name , min , max ) ;
pere . addSousGroupe ( g ) ;
this . brain . put ( Integer . valueOf ( g . getId ( ) ) , g ) ;
2022-11-26 18:09:08 +01:00
this . saveGroupe ( g ) ;
2022-10-26 15:10:08 +02:00
}
/ * *
* permet de créer une partition automatiquement sous un groupe donné .
*
* @param pere le groupe père du groupe à partitionner
* @param name le nom des groupe à créer ( on ajoute à la suite un numéro de 1 à n pour distinguer chaque groupe formant la partition )
* @param n le nombre de partitions
* @throws java . lang . NullPointerException si un argument est null
* @throws java . lang . IllegalArgumentException si le groupe pere est de type PARTITION
* ou n négatif ou nul
*
* NB . doit créer une " copie " de pere
* sous pere de type Partition et ajouter sous ce groupe , n groupes de type " FREE " .
* les valeurs min et max de ces n groupes sont
* min = 0 et
* max = partie entière de N / n plus 1 , où N est le nombre max du groupe pere .
* /
public void createPartition ( Groupe pere , String name , int n ) {
Objects . requireNonNull ( pere , " Le groupe pere ne peut pas être null " ) ;
Objects . requireNonNull ( name , " Le nouveau groupe ne peut pas avoir null comme nom " ) ;
2022-11-28 10:29:52 +01:00
//if (!this.knows(pere)){
//throw new IllegalArgumentException("Impossible de partitionner ce groupe inconnu");
//possible maintenant
//}
2022-10-26 15:10:08 +02:00
if ( pere . getType ( ) . equals ( TypeGroupe . PARTITION ) ) {
throw new IllegalArgumentException ( " Impossible de créer une partition à ce niveau. Il faut soit repartitionner le groupe au dessus, soit partitionner une partition en dessous. " ) ;
}
if ( n < = 0 ) {
throw new IllegalArgumentException ( " Le nombre de partitions doit être strictement positif " ) ;
}
//Création de la racine de la partition.
Groupe copiePereRacinePartition = new GroupeNP ( pere ) ;
pere . addSousGroupe ( copiePereRacinePartition ) ;
this . brain . put ( Integer . valueOf ( copiePereRacinePartition . getId ( ) ) , copiePereRacinePartition ) ;
// création des sous-groupes
int min = 0 ;
int max = ( ( int ) Math . floor ( pere . getSize ( ) / n ) ) + 1 ;
2022-10-31 12:53:56 +01:00
List < Groupe > groupes = new ArrayList < Groupe > ( n ) ;
2022-10-26 15:10:08 +02:00
for ( int i = 0 ; i < n ; i + + ) {
Groupe g = new GroupeNP ( copiePereRacinePartition , name + " _ " + i , min , max ) ;
2022-10-31 12:53:56 +01:00
groupes . add ( i , g ) ; // ajout dans le tableau des groupes
2022-10-26 15:10:08 +02:00
copiePereRacinePartition . addSousGroupe ( g ) ;
this . brain . put ( Integer . valueOf ( g . getId ( ) ) , g ) ;
}
2022-10-31 12:53:56 +01:00
// Partage des étudiants (on ne prête pas attention aux min et max)
int i = 0 ;
for ( Etudiant s : pere . getEtudiants ( ) ) {
copiePereRacinePartition . addEtudiant ( s ) ;
groupes . get ( i ) . addEtudiant ( s ) ;
i = ( i + 1 ) % n ;
}
2022-11-26 18:09:08 +01:00
this . saveGroupe ( copiePereRacinePartition ) ;
2022-10-26 15:10:08 +02:00
}
/ * *
* permet d ' ajouter un étudiant à un groupe .
*
* @param g le groupe dans lequel il faut ajouter l ' étudiant
* @param e l ' étudiant à ajouter
*
* @throws java . lang . NullPointerException si un argument est null
* @throws java . lang . IllegalArgumentException la factory ne connaît pas g
* @throws java . lang . IllegalStateException le père de g ne contient pas e
* /
public void addToGroupe ( Groupe g , Etudiant e ) {
Objects . requireNonNull ( g , " Le groupe ne peut pas être null " ) ;
Objects . requireNonNull ( e , " L'étudiant ne peut pas être null " ) ;
2022-11-28 10:29:52 +01:00
//if (!this.knows(g)){
//throw new IllegalArgumentException("Impossible d'ajouter l'étudiant car le est groupe inconnu");
//rendu possible maintenant par la syncronisation en temps réel
//}
2022-10-26 15:10:08 +02:00
g . addEtudiant ( e ) ;
2022-11-26 18:09:08 +01:00
this . saveEtu ( e , g ) ;
2022-10-26 15:10:08 +02:00
}
/ * *
* permet d ' enlever un étudiant d ' un groupe .
*
* @param g le groupe dans lequel il faut enlever l ' étudiant
* @param e l ' étudiant à enlever
*
* @throws java . lang . NullPointerException si un argument est null
* @throws java . lang . IllegalStateException g ne contient pas e
* @throws java . lang . IllegalArgumentException la factory ne connaît pas g
* /
public void dropFromGroupe ( Groupe g , Etudiant e ) {
2022-10-31 12:53:56 +01:00
Objects . requireNonNull ( g , " Le groupe ne peut pas être null " ) ;
Objects . requireNonNull ( e , " L'étudiant ne peut pas être null " ) ;
2022-11-28 10:29:52 +01:00
//if (!this.knows(g)){
//throw new IllegalArgumentException("Impossible de suprimer l'étudiant car le est groupe inconnu");
//Possible maintenant
//}
2022-10-31 12:53:56 +01:00
g . removeEtudiant ( e ) ;
2022-11-26 18:09:08 +01:00
this . deleteEtu ( e , g ) ;
2022-10-26 15:10:08 +02:00
}
/ * *
* permet de retrouver un étudiant à partir d ' un String .
*
* NB . dans une version simple il doit s ' agir du nom exact .
* dans une version un peu plus complexe , il s ' agit des premières lettres du nom
* dans une version avancée , on peut autoriser une expression régulière plus ou moins complexe qui est générée si la première recherche n ' a pas renvoyé de candidat .
*
* @param String nomEtu le nom approximmatif de l ' étudiant
* @return Set < Etudiant > l ' ensemble des étudiants connus de la factory ayant un nom " proche " de ce string au sens de la remarque ci - dessus .
*
* @throws java . lang . NullPointerException si le String est null .
* /
public Set < Etudiant > getEtudiants ( String nomEtu ) {
2022-11-13 04:01:11 +01:00
Set < Etudiant > s = new LinkedHashSet < > ( ) ;
for ( Etudiant e : this . getPromotion ( ) . getEtudiants ( ) ) {
if ( ( e . getNom ( ) ) . equals ( nomEtu . toString ( ) ) ) {
s . add ( e ) ;
}
2022-10-26 15:10:08 +02:00
}
2022-11-13 04:01:11 +01:00
return s ;
2022-10-26 15:10:08 +02:00
}
/ * *
* permet de retrouver les groupes d ' un étudiant .
*
* @param Etu un étudiant
* @return Etudiant l ' étudiant connu de la factory ayant cet identifiant
*
* @throws java . lang . NullPointerException si le String est null .
* /
public Set < Groupe > getGroupesOfEtudiant ( Etudiant etu ) {
2022-11-12 23:27:30 +01:00
Collection < Groupe > s = this . brain . values ( ) ;
Set < Groupe > ret = new LinkedHashSet < Groupe > ( ) ;
for ( Groupe g : s ) {
for ( Etudiant e : g . getEtudiants ( ) ) {
if ( e = = etu ) {
ret . add ( g ) ;
break ;
}
}
}
return ret ;
2022-10-26 15:10:08 +02:00
}
2022-11-26 18:09:08 +01:00
// **********************
// FONCTION POUR SIMPLIFIER LES Modification BD
// ***********************
private Connection cnx ( ) {
//On se Connecte a la BD
try {
Class . forName ( " org.mariadb.jdbc.Driver " ) ;
Connection cnx = DriverManager . getConnection (
" jdbc:mariadb://dwarves.iut-fbleau.fr/chaignea " ,
" chaignea " , " Chaigneauphpmyadmin " ) ;
return cnx ;
} catch ( Exception e ) {
if ( this . erreurCO ( ) = = true ) {
return this . cnx ( ) ;
}
}
return null ;
}
private boolean erreurCO ( ) {
if ( JOptionPane . showConfirmDialog ( this . fenetre , " erreur connection a la BD reassayer? " , " erreur connection " , JOptionPane . YES_NO_OPTION ) = = JOptionPane . YES_OPTION ) {
return true ;
} else {
this . fenetre . dispose ( ) ;
return false ;
}
}
private boolean erreurSQL ( ) {
if ( JOptionPane . showConfirmDialog ( this . fenetre , " erreur lors de la modification, reasssayer? " , " erreur SQL " , JOptionPane . YES_NO_OPTION ) = = JOptionPane . YES_OPTION ) {
return true ;
} else {
return false ;
}
}
private void deleteEtu ( Etudiant et , Groupe g ) {
Connection cnx = this . cnx ( ) ;
try {
PreparedStatement pst = cnx . prepareStatement (
" DELETE FROM CONTIENT WHERE idGroupe=? AND idEt=?; "
) ;
pst . setInt ( 2 , et . getId ( ) ) ;
2022-11-28 10:29:52 +01:00
this . deleteEtu ( pst , cnx , g . getId ( ) ) ;
2022-11-26 18:09:08 +01:00
pst . close ( ) ;
} catch ( SQLException e ) {
System . out . println ( e . toString ( ) ) ;
if ( this . erreurSQL ( ) ) {
2022-11-28 10:29:52 +01:00
this . deleteEtu ( et , brain . get ( g . getId ( ) ) ) ;
2022-11-26 18:09:08 +01:00
}
}
this . close ( cnx ) ;
}
2022-11-28 10:29:52 +01:00
private void deleteEtu ( PreparedStatement pst , Connection cnx , int id ) {
2022-11-26 18:09:08 +01:00
try {
2022-11-28 10:29:52 +01:00
pst . setInt ( 1 , id ) ;
2022-11-26 18:09:08 +01:00
pst . executeUpdate ( ) ;
2022-11-28 10:29:52 +01:00
PreparedStatement sous = cnx . prepareStatement (
" SELECT * FROM Groupe WHERE `id-parent`=? AND `id-parent`!=id; "
) ;
sous . setInt ( 1 , id ) ;
ResultSet rs = sous . executeQuery ( ) ;
while ( rs . next ( ) ) {
this . deleteEtu ( pst , cnx , rs . getInt ( 1 ) ) ;
2022-11-26 18:09:08 +01:00
}
} catch ( SQLException e ) {
System . out . println ( e . toString ( ) ) ;
if ( this . erreurSQL ( ) ) {
2022-11-28 10:29:52 +01:00
this . deleteEtu ( pst , cnx , id ) ;
2022-11-26 18:09:08 +01:00
}
}
}
private void close ( AutoCloseable clos ) {
try {
clos . close ( ) ;
} catch ( Exception e ) {
if ( this . erreurCO ( ) = = true )
this . close ( clos ) ;
}
}
private boolean saveEtu ( Etudiant etudiant , Groupe g ) {
Connection cnx = this . cnx ( ) ;
try {
PreparedStatement pst = cnx . prepareStatement (
" Select id from Etudiant where id=?; " ) ;
pst . setString ( 1 , String . valueOf ( etudiant . getId ( ) ) ) ;
ResultSet rs = pst . executeQuery ( ) ;
if ( rs . next ( ) ) {
//L'etudiant est déja connu de la BD
pst . close ( ) ;
pst = cnx . prepareStatement (
" INSERT INTO `CONTIENT` (`idGroupe`, `idEt`) VALUES (?, ?); " ) ;
pst . setInt ( 2 , etudiant . getId ( ) ) ;
pst . setInt ( 1 , g . getId ( ) ) ;
pst . executeUpdate ( ) ;
} else {
pst . close ( ) ;
pst = cnx . prepareStatement (
" INSERT INTO `Etudiant` (`id`, `nom`, `prenom`) VALUES (?, ?, ?) ; " ) ;
pst . setInt ( 1 , etudiant . getId ( ) ) ;
pst . setString ( 2 , etudiant . getNom ( ) ) ;
pst . setString ( 3 , etudiant . getPrenom ( ) ) ;
pst . executeUpdate ( ) ;
}
rs . close ( ) ;
pst . close ( ) ;
} catch ( SQLException e ) {
System . out . println ( e . toString ( ) ) ;
if ( this . erreurSQL ( ) ) {
this . saveEtu ( etudiant , g ) ;
} else {
return false ;
}
}
this . close ( cnx ) ;
return true ;
}
private boolean saveGroupe ( Groupe g ) {
Connection cnx = this . cnx ( ) ;
try {
PreparedStatement pst = cnx . prepareStatement (
" INSERT INTO `Groupe` (`id`, `nom`, `min`, `max`, `Type`, `id-parent`) VALUES (?, ?, ?, ?, ?, ?); "
) ;
pst . setInt ( 1 , g . getId ( ) ) ;
pst . setString ( 2 , g . getName ( ) ) ;
pst . setInt ( 3 , g . getMin ( ) ) ;
pst . setInt ( 4 , g . getMax ( ) ) ;
pst . setString ( 5 , g . getType ( ) . name ( ) ) ;
pst . setInt ( 6 , g . getPointPoint ( ) . getId ( ) ) ;
pst . executeUpdate ( ) ;
pst . close ( ) ;
for ( Etudiant e : g . getEtudiants ( ) ) {
this . saveEtu ( e , g ) ;
}
for ( Groupe sous : g . getSousGroupes ( ) ) {
this . saveGroupe ( sous ) ;
}
} catch ( SQLException e ) {
System . out . println ( e . toString ( ) ) ;
if ( this . erreurSQL ( ) ) {
this . saveGroupe ( g ) ;
} else {
return false ;
}
}
this . close ( cnx ) ;
return true ;
}
private boolean suprGroupe ( Groupe g ) {
Connection cnx = this . cnx ( ) ;
try {
PreparedStatement pst = cnx . prepareStatement ( " Delete FROM Groupe where id=?; " ) ;
pst . setInt ( 1 , g . getId ( ) ) ;
pst . executeUpdate ( ) ;
pst . close ( ) ;
pst = cnx . prepareStatement ( " Delete FROM CONTIENT where idGroupe=?; " ) ;
pst . setInt ( 1 , g . getId ( ) ) ;
pst . executeUpdate ( ) ;
pst . close ( ) ;
} catch ( SQLException e ) {
System . out . println ( e . toString ( ) ) ;
if ( this . erreurSQL ( ) ) {
this . suprGroupe ( g ) ;
} else {
return false ;
}
}
this . close ( cnx ) ;
return true ;
}
2022-10-26 15:10:08 +02:00
}