Rev 30 | Rev 39 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
package org.tela_botanica.client.image;import java.util.HashMap;import java.util.Iterator;import java.util.Vector;import org.tela_botanica.client.interfaces.Rafraichissable;import org.tela_botanica.client.modeles.ImageAsynchroneDAO;import org.tela_botanica.client.modeles.ImageCarnet;import org.tela_botanica.client.modeles.ImageUploaderAsynchroneDAO;import org.tela_botanica.client.modeles.ListeImageCarnet;import org.tela_botanica.client.modeles.ListeImageAsynchroneDAO;import org.tela_botanica.client.modeles.MotsClesAsynchroneDAO;import org.tela_botanica.client.modeles.NombreImageAsynchroneDAO;import com.google.gwt.json.client.JSONArray;import com.google.gwt.json.client.JSONObject;import com.gwtext.client.core.Ext;import com.gwtext.client.core.ExtElement;import com.gwtext.client.data.ArrayReader;import com.gwtext.client.data.FieldDef;import com.gwtext.client.data.IntegerFieldDef;import com.gwtext.client.data.MemoryProxy;import com.gwtext.client.data.Node;import com.gwtext.client.data.NodeTraversalCallback;import com.gwtext.client.data.RecordDef;import com.gwtext.client.data.Store;import com.gwtext.client.data.StringFieldDef;import com.gwtext.client.data.Tree;import com.gwtext.client.widgets.tree.TreeNode;/*** Modèle d'accès aux données pour les images.* C'est un singleton* @author aurelien**/public class ImageModele implements Rafraichissable {/*** Booleen indiquant si le médiateur est instancié (l'instance doit être unique donc le booleen est static)*/private static boolean estInstancie = false ;/*** Le médiateur associé au modèle*/private ImageMediateur iMediateur = null ;/*** La liste des image affichées en cours*/private ListeImageCarnet cacheImage = new ListeImageCarnet(0) ;/*** Table de correspondance entre les mots clés et leurs identifiants*/private HashMap motsCles = new HashMap(0) ;/*** Le store contenant les données à afficher, que le modèle transmet au médiateur quand il le demande*/private Store st = null ;/*** Arbre des mots clés*/private com.gwtext.client.data.Tree arbreMotsCles = new Tree() ;/*** Numéro de page en cours*/private int pageEncours = 0 ;/*** Nombre de pages totales*/private int pageMax = 1 ;/*** Taille de page (par défaut 50)*/private int taillePage = 50 ;/*** Nombre d'éléments total correspondant à la requete*/private int nbElements = 0 ;/*** Retourne une instance de manière unique* @param im le médiateur à associer* @return l'instance du modèle*/static ImageModele Instance(ImageMediateur im){// si le modèle n'est pas encore instanciéif(!estInstancie){// on en crée un nouveaureturn new ImageModele(im);}else{// sinon on renvoit null, interdisant explicitement la création d'un autre exemplairereturn null ;}}/*** Le constructeur est privé et seule la méthode instance y accède* @param im le médiateur à associé*/private ImageModele(ImageMediateur im) {iMediateur = im ;}/*** Accesseur pour le médiateur* @return*/public ImageMediateur getIMediateur(){return iMediateur ;}/*** Appelle le DAO asynchrone pour obtenir la liste des images* @param r le rafraichissable auxquel on enverra les données*/public void obtenirPhotoGalerie(Rafraichissable r){// on rassemble les critèresString[][] criteres = {{"ci_ce_utilisateur", ""+getIMediateur().getIdentifiant()} } ;// on les crée un DAO auquel on les transmet et qui demande le nombre d'images correspondantes (pour les pages)NombreImageAsynchroneDAO niaDAO = new NombreImageAsynchroneDAO() ;niaDAO.obtenirNombreImages(this, criteres) ;// ensuite on demande la page correspondante avec les mêmes critèresString[][] criteres2 = { {"ci_limite" ,""+taillePage },{"ci_numero_page",""+pageEncours} } ;// et on crée un DAO auquel on les transmet et qui envoie une requete pour recevoir les imagesListeImageAsynchroneDAO liaDAO = new ListeImageAsynchroneDAO();liaDAO.ObtenirListeImages(this, criteres2);}/*** Appelle le DAO d'upload qui va choisir la methode d'upload adaptée* et lancer l'interface appropriée*/public void uploaderImages(){ImageUploaderAsynchroneDAO IuADaO = new ImageUploaderAsynchroneDAO() ;IuADaO.setIMediateur(getIMediateur());IuADaO.choisirMethodeUpload() ;}/*** Met à jour la liste des images à partir d'un objet* @param o la nouvelle liste d'image*/public void rafraichirListeImage(Object o){cacheImage = (ListeImageCarnet)o ;}/*** Met à jour l'arbre des mots clés à partir d'un objet* @param o le nouvel arbre de mots clés*/public void rafraichirArbreMotsCles(Object o){arbreMotsCles = (com.gwtext.client.data.Tree)o ;}/*** Met à jour la table de correspondance mots clés / ids* à partir d'un objet* @param o la nouvelle table des mots clés*/public void rafraichirMotsCles(Object o){motsCles = (HashMap)o ;}/*** Va chercher les métadonnées associées à une image dans la liste* des images chargée dans le modèle* @param r le rafraichissable auquel on enverra les informations* @param id l'identifiant de l'image*/public void obtenirMetadonnees(Rafraichissable r, String id){ImageCarnet im = (ImageCarnet)cacheImage.get(id) ;Object meta[] = new Object[3] ;meta[0] = im.getMetadonnesExif() ;meta[1] = im.getMetadonnesIptc() ;meta[2] = im.getInfoGenerales() ;r.rafraichir(meta,false) ;}/*** Va chercher les mots clés associés à une image dans la liste* des images chargée dans le modèle* @param r le rafraichissable auquel on enverra les informations* @param id l'identifiant de l'image*/public void obtenirMotsClesId(Rafraichissable r, String id){ImageCarnet im = (ImageCarnet)cacheImage.get(id) ;String motsClesId = im.getMotsCles() ;String[] motsClesIdTab = motsClesId.split(",") ;r.rafraichir(motsClesIdTab, false) ;}/*** Met à jour la liste des images en local et appelle le DAO de mise* à jour pour les commentaires et la date des images selectionnées* @param commentaires le commentaire à appliquer* @param date la date à appliquer* @param ids les identifiants des images selectionnées*/public void mettreAJourCacheImage(String commentaires, String date, String ids[]){for (int i = 0; i < ids.length; i++){String key = ids[i] ;ImageCarnet ic = (ImageCarnet)cacheImage.get(key) ;ic.miseAJourInfoGenerales(commentaires, date) ;mettreAjourBaseDeDonneesImageCarnet(ic) ;}}/*** Ajoute un nouveau mot clés à la liste des mots clés locale* @param text le mot clé* @param id l'identifiant du mot clé*/public void mettreAjourMotsClesId(String text, String id){motsCles.put(id, text) ;}/*** Appelle le DAO chargé de mettre à jour la base de données avec* les toutes les informations des images modifiées par l'utilisateur*/public void mettreAJourBaseDeDonneesListeImageCarnet(){ListeImageAsynchroneDAO liDaO = new ListeImageAsynchroneDAO();liDaO.setIMediateur(iMediateur);liDaO.SynchroniserBaseDeDonnees(cacheImage);}/*** Appelle le DAO chargé de mettre à jour la base de données avec* les toutes les informations d'une image donnée* @param ic l'image à synchroniser avec la base*/public void mettreAjourBaseDeDonneesImageCarnet(ImageCarnet ic){ImageAsynchroneDAO iaDaO = new ImageAsynchroneDAO();iaDaO.setIMediateur(iMediateur);iaDaO.SynchroniserBaseDeDonnees(ic) ;}/*** Supprime les images données du cache local et appelle le DAO* qui les supprime de la base de données* @param ids les identifiants des images selectionnées*/public void supprimerImages(String[] ids){String rids[] = new String[ids.length] ;ListeImageAsynchroneDAO liDao = new ListeImageAsynchroneDAO() ;liDao.setIMediateur(iMediateur);for (int i = 0; i < ids.length; i++){String key = ids[i] ;ImageCarnet ic = (ImageCarnet)cacheImage.get(key) ;rids[i] = ic.getId() ;cacheImage.remove(key) ;}if(rids.length != 0){liDao.supprimerBaseDeDonnees(rids);}}/*** Met à jour les données locales suivant le type des nouvelles données* et appelle le médiateur pour le notifier de la mise à jour*/public void rafraichir(Object nouvelleDonnees, boolean repandreRafraichissement){// si l'on a reçu une liste d'imagesif(nouvelleDonnees instanceof ListeImageCarnet){ListeImageCarnet data = (ListeImageCarnet) nouvelleDonnees ;Object[][] photoData = new Object[data.size()][7];int i = 0 ;// on la parse et on récupère les informations quiç nous interessentfor (Iterator it = data.keySet().iterator(); it.hasNext();){ImageCarnet im = (ImageCarnet) data.get(it.next());photoData[i][0] = im.getOrdre() ;photoData[i][1] = im.getDate() ;photoData[i][2] = im.getIptcCity() ;photoData[i][3] = im.getMake()+" "+im.getModel() ;photoData[i][4] = im.getSUrl() ;photoData[i][5] = im.getMUrl() ;photoData[i][6] = im.getUrl() ;i++ ;}// creation du store qui les contientFieldDef defNumImage = new IntegerFieldDef("num_image");FieldDef defDatImage = new StringFieldDef("dat_image");FieldDef defLieImage = new StringFieldDef("lie_image");FieldDef defAppImage = new StringFieldDef("app_image");FieldDef defUrlImageS = new StringFieldDef("url_image_S");FieldDef defUrlImageM = new StringFieldDef("url_image_M");FieldDef defUrlImage = new StringFieldDef("url_image");FieldDef[] defTab = {defNumImage,defDatImage,defLieImage,defAppImage,defUrlImageS,defUrlImageM,defUrlImage};RecordDef rd = new RecordDef(defTab) ;final MemoryProxy dataProxy = new MemoryProxy(photoData);final ArrayReader reader = new ArrayReader(rd);final Store photoStore = new Store(dataProxy, reader);rafraichirListeImage(nouvelleDonnees);st = photoStore ;st.load() ;// par défaut le store est trié sur le numéro d'imagest.sort("num_image") ;// si on doit répandre les données, on notifie le médiateur qui les distribuera à son tourif(repandreRafraichissement){getIMediateur().synchroniserDonneesZoomListeGalerie(st, this) ;}}// si on reçoit un tableau JSONif(nouvelleDonnees instanceof JSONArray){// alors on a reçu les informations sur les mots clésJSONArray reponse = (JSONArray)nouvelleDonnees ;final int taillemax = reponse.size();// si le tableau est videif(taillemax == 0){// on crée un arbre videTreeNode root = new TreeNode() ;root.setId("racine") ;root.setText("Tags") ;root.setIcon("tela.png") ;String[] usObj = {"Tags","racine"} ;root.setUserObject(usObj) ;arbreMotsCles.setRootNode(root) ;}// pour chacun des élements du tableaufor (int j = 0; j < taillemax ; j++){// on extrait les élements du tableauif(reponse.get(j).isObject() != null){JSONObject noeud = (JSONObject)reponse.get(j) ;String id_noeud = noeud.get("cmc_id_mot_cle_utilisateur").isString().stringValue() ;String mot_cle = noeud.get("cmc_mot_cle").isString().stringValue() ;String parent = noeud.get("cmc_id_parent").isString().stringValue() ;String[] usObj = {mot_cle, id_noeud} ;// et on construit l'arbre à partir de la racine (qui est toujoursl e premier élément)if(id_noeud.equals("racine")){TreeNode root = new TreeNode() ;root.setId(id_noeud) ;root.setText(mot_cle) ;root.setIcon("tela.png") ;root.setUserObject(usObj) ;arbreMotsCles.setRootNode(root) ;}else{// et en ajoutant les noeuds un à un (qui sont renvoyé dans l'ordre hierarchique de leur niveau// ce qui permet de les traiter séquentiellement)TreeNode node = new TreeNode() ;node.setId(id_noeud) ;node.setText(mot_cle) ;node.setChecked(false) ;Node parentNode = arbreMotsCles.getNodeById(parent) ;node.setIcon("tela.png") ;node.setUserObject(usObj) ;parentNode.appendChild(node) ;}}}// enfin on met à jour l'arbre des mots clés contenu dans le modèlerafraichirArbreMotsCles(arbreMotsCles) ;// et on notifie le médiateur de la mise à jour en lui passant une copie des donnéesgetIMediateur().rafraichirArbreMotsCles(arbreMotsCles) ;}// Si on reçoit un tableau d'entiers// c'est un tableau d'un seul entier qui est le nombre d'images correspondant aux critèresif(nouvelleDonnees instanceof int[]){int[] pages = (int[])nouvelleDonnees ;// on calcule le nombre de pages nécessaires et on les met à jour dans le modèlepageMax = calculerNbPages(pages[0]) ;nbElements = pages[0] ;// et on notifie de le mediateur du changement des valeursgetIMediateur().changerPageMaxEtCourante(pageMax,pageEncours,taillePage,pages[0]) ;}}/*** Affiche les paires / valeur de tous les mots clés stockés*/public void afficherMotsCles(){for(Iterator it = motsCles.keySet().iterator() ; it.hasNext() ;){String key = (String)it.next() ;String valeur = (String)motsCles.get(key) ;System.out.println("clé : "+key+" valeur : "+valeur);}}/*** Met à jour les mots clés associés à une image et appelle le DAO pour synchroniser la base de données* @param ids les identifiants des images selectionnées* @param motsClesEnCours les mots clés à appliquer aux images* @param arbreMC l'arbre de mots clés en cours*/public void mettreAjourMotsCles(String[] ids, String motsClesEnCours, com.gwtext.client.data.Tree arbreMC){for (int i = 0; i < ids.length; i++){if(cacheImage.containsKey(ids[i])){ImageCarnet ic = (ImageCarnet)cacheImage.get(ids[i]) ;ic.mettreAjourMotsCles(motsClesEnCours) ;ImageAsynchroneDAO imgDao = new ImageAsynchroneDAO() ;imgDao.setIMediateur(getIMediateur()) ;imgDao.SynchroniserMotsClesImageBaseDeDonnees(ic) ;}}rafraichirArbreMotsCles(arbreMC) ;}/*** Appelle le DAO des mots clés pour obtenir l'arbre complet stocké dans la base de données*/public void initialiserArbreMotsCles(){MotsClesAsynchroneDAO MCDao = new MotsClesAsynchroneDAO() ;MCDao.setIMediateur(getIMediateur()) ;MCDao.obtenirListeMotsCles(this) ;}/*** Envoie l'arbre des mots clés stocké localement à l'élément rafrachissable donné, qui le demande* @param r le rafraichissable demandeur de l'arbre*/public void obtenirArbreMotCle(Rafraichissable r){r.rafraichir(arbreMotsCles, false) ;}/*** Ajoute un mot clé à l'arbre des mots clés local et appelle le DAO qui fait la mise* à jour de l'arbre des mots clés dans la base* @param n le nouveau noeud contenant le mot clé* @param arbreMC l'arbre des mots cles en cours*/public void ajouterMotCleDansArbre(TreeNode n, com.gwtext.client.data.Tree arbreMC){MotsClesAsynchroneDAO MCDao = new MotsClesAsynchroneDAO() ;MCDao.setIMediateur(getIMediateur()) ;String[] usObj = (String[])n.getUserObject() ;String motCle = usObj[0] ;String id = usObj[1] ;String parentId = "" ;if(!id.equals("racine")){String[] parentUsObj = (String[])n.getParentNode().getUserObject() ;parentId = parentUsObj[1] ;}else{parentId = "racine" ;}rafraichirArbreMotsCles(arbreMC) ;String nouveauMotCle = "&motcle="+motCle+"&id="+id+"&parent="+parentId ;MCDao.ajouterBaseDeDonnees(nouveauMotCle) ;}/*** Supprime un noeud de l'arbre des mots clés et appelle le DAO qui va supprimer* les mots clés associés dans la base* @param n le noeud à supprimer* @param arbreMC l'arbre des mots clés en cours*/public void supprimerMotCleDansArbre(TreeNode n, Tree arbreMC){MotsClesAsynchroneDAO MCDao = new MotsClesAsynchroneDAO() ;MCDao.setIMediateur(getIMediateur()) ;String[] usObj = (String[])n.getUserObject() ;String motCle = usObj[0] ;String id = usObj[1] ;String motCleASupprimer = id ;MCDao.supprimerBaseDeDonnees(id) ;}/*** Modifie le noeud donné dans l'arbre des mots clés en cours et appelle le DAO* qui synchronise la modification dans la base de données* @param n le noeud modifié* @param arbreMC l'arbre des mots clés en cours*/public void modifierMotCleDansArbre(TreeNode n, Tree arbreMC){MotsClesAsynchroneDAO MCDao = new MotsClesAsynchroneDAO() ;MCDao.setIMediateur(getIMediateur()) ;String[] usObj = (String[])n.getUserObject() ;String motCle = usObj[0] ;String id = usObj[1] ;String parentId = "" ;if(!id.equals("racine")){String[] parentUsObj = (String[])n.getParentNode().getUserObject() ;parentId = parentUsObj[1] ;}else{parentId = "racine" ;}rafraichirArbreMotsCles(arbreMC) ;String motCleModifie = "&motcle="+motCle+"&id="+id+"&parent="+parentId ;MCDao.modifierBaseDeDonnees(motCleModifie) ;}/*** Deplace un noeud dans l'arbre des mots cles et appelle le DAO qui reorganise l'arbre* dans la base de donnees suivant le changement* @param n le noeud deplace (et son sous arbre associe)* @param arbreMC l'arbre des mots cles en cours*/public void deplacerMotCleDansArbre(TreeNode n, Tree arbreMC){MotsClesAsynchroneDAO MCDao = new MotsClesAsynchroneDAO() ;MCDao.setIMediateur(getIMediateur()) ;String[] usObj = (String[])n.getUserObject() ;String motCle = usObj[0] ;String id = usObj[1] ;String parentId = "" ;if(!id.equals("racine")){String[] parentUsObj = (String[])n.getParentNode().getUserObject() ;parentId = parentUsObj[1] ;}else{parentId = "racine" ;}rafraichirArbreMotsCles(arbreMC) ;String motCleModifie = "&motcle="+motCle+"&id="+id+"&parent="+parentId ;MCDao.deplacerBaseDeDonnees(motCleModifie) ;}/*** Change le numéro de la page en cours et envoie une demande de mise à jour des données* @param nouvellePageCourante la nouvelle page à afficher*/public void changerNumeroPage(int nouvellePageCourante){pageEncours = nouvellePageCourante ;obtenirPhotoGalerie(this) ;}/*** Calcule le nombre de pages nécessaires pour afficher un nombre d'élements donnés en fonction de la taille de page* en cours* @param nbElements le nombre d'élements total* @return le nombre de pages*/public int calculerNbPages(int nbElements){// A cause de la betise de java pour les conversion implicite on fait quelques conversions manuellement// pour eviter qu'il arrondisse mal la division// nombre de pages = (nombre d'element / taille de la page) arrondie à l'entier superieurdouble nPage = (1.0*nbElements)/(1.0*taillePage) ;double nPageRound = Math.ceil(nPage) ;Double nPageInt = new Double(nPageRound) ;// on convertit en entierreturn nPageInt.intValue() ;}/*** Recalcule la page en cours lors du changement du nombre d'élements* @param nbElements le nombre d'élements total* @return la nouvelle page encours*/public int calculerPageCourante(int nbElements){// on calcule le nombre de pageint nouvelNbPages = calculerNbPages(nbElements) ;// la nouvelle page en coursdouble nPageCourante = (1.0*pageEncours)/(1.0*pageMax) * (1.0*nouvelNbPages) ;// on arrondit au supérieurdouble nPageRound = Math.ceil(nPageCourante) ;Double nPageInt = new Double(nPageRound) ;// on convertit en entierreturn nPageInt.intValue() ;}/*** Change la taille de page et recalcule la page encours* @param nouvelleTaillePage la nouvelle taille de page à utiliser*/public void changerTaillePage(int nouvelleTaillePage){taillePage = nouvelleTaillePage ;pageEncours = calculerPageCourante(nbElements) ;obtenirPhotoGalerie(this) ;}}