package fr.iutfbleau.projetIHM2022FI2.MNP; import fr.iutfbleau.projetIHM2022FI2.API.*; 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; import java.util.*; /** * Usine abstraite gérant l'ensemble des groupes. * */ public class AbstractGroupeFactoryNP implements AbstractGroupeFactory { // la racine (promotion) private Groupe promo; //la fentre pour les fenetre modale private JFrame fenetre; // 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 brain; /** * Le constructeur fabrique le groupe promotion déja plein (utilisé en Modèle persistant de donné). */ public AbstractGroupeFactoryNP(Groupe promo, JFrame fenetre){ this.promo=promo; this.fenetre=fenetre; this.brain=new HashMap(); this.addSousGroupe(this.promo); } /** * 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(); this.brain.put(Integer.valueOf(this.promo.getId()),this.promo); this.saveGroupe(promo); } /** * 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){ this.brain.put(g.getId(), g); for(Groupe s:g.getSousGroupes()){ this.addSousGroupe(s); } } /** * Test plutôt optimiste. Si la clé est identique alors on fait comme si c'était le bon groupe. * * @return true si le groupe est connu */ public Boolean knows(Groupe g){ return this.brain.containsKey(Integer.valueOf(g.getId())); } 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; } /** * 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é"); if (!this.knows(g)){ throw new IllegalArgumentException("Impossible d'enlever un groupe inconnu"); } g.getPointPoint().removeSousGroupe(g); this.brain.remove(Integer.valueOf(g.getId())); this.suprGroupe(g); } /** * 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"); if (!this.knows(pere)){ throw new IllegalArgumentException("Interdit d'ajouter un fils à un groupe inconnu"); } 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"); } Groupe g = new GroupeNP(pere,name,min,max); pere.addSousGroupe(g); this.brain.put(Integer.valueOf(g.getId()),g); this.saveGroupe(g); } /** * 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"); if (!this.knows(pere)){ throw new IllegalArgumentException("Impossible de partitionner ce groupe inconnu"); } 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; List groupes = new ArrayList(n); for(int i = 0; i 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 getEtudiants(String nomEtu){ Set s=new LinkedHashSet<>(); for(Etudiant e:this.getPromotion().getEtudiants()){ if((e.getNom()).equals(nomEtu.toString())){ s.add(e); } } return s; } /** * 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 getGroupesOfEtudiant(Etudiant etu){ Collection s= this.brain.values(); Set ret=new LinkedHashSet(); for(Groupe g: s){ for(Etudiant e: g.getEtudiants()){ if(e==etu){ ret.add(g); break; } } } return ret; } // ********************** // 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()); this.deleteEtu(pst, cnx, g); pst.close(); }catch(SQLException e){ System.out.println(e.toString()); if(this.erreurSQL()){ this.deleteEtu(et, g); } } this.close(cnx); } private void deleteEtu(PreparedStatement pst, Connection cnx, Groupe g){ try{ pst.setInt(1, g.getId()); pst.executeUpdate(); for(Groupe sous: g.getSousGroupes()){ this.deleteEtu(pst, cnx, sous); } }catch(SQLException e){ System.out.println(e.toString()); if(this.erreurSQL()){ this.deleteEtu(pst, cnx, g); } } } 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; } }