Subversion Repositories eFlore/Archives.cel-v2

Compare Revisions

Ignore whitespace Rev 31 → Rev 36

/trunk/src/org/tela_botanica/client/modeles/ImageUploaderAsynchroneDAO.java
1,6 → 1,7
package org.tela_botanica.client.modeles;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.image.ImageModele;
import org.tela_botanica.client.interfaces.iMediateur;
 
import com.google.gwt.core.client.JavaScriptObject;
25,19 → 26,30
*/
public class ImageUploaderAsynchroneDAO {
private static ImageMediateur iMediateur ;
/**
* Modele associé au DAO
*/
private static ImageModele iModele ;
public void setIMediateur(ImageMediateur im)
/**
* Setteur pour le modele
* @param im le modèle à associer au DAO
*/
public void setIModele(ImageModele im)
{
iMediateur = im ;
iModele = im ;
}
/**
* Crée un panel d'upload simple aux fonctions réduites mais utilisant uniquement javascript
* (pour les utilisateurs qui n'ont pas java)
*/
private static void appelerUploadSimple()
{
UploadDialog up = new UploadDialog("Upload simple de fichiers") ;
up.setUrl("jrest/InventoryImage");
UrlParam id = new UrlParam("identifiant",iMediateur.getIdentifiant()) ;
UrlParam id = new UrlParam("identifiant",iModele.getIdentifiant()) ;
UrlParam[] params = {id} ;
up.setBaseParams(params);
46,7 → 58,7
 
public void onClose(Panel panel) {
iMediateur.rafraichirToutesVues() ;
iModele.requeteTerminee() ;
}
});
55,6 → 67,10
}
/**
* Crée une fenêtre contenant une applet java pour uploader plusieurs fichiers à la fois avec quelques
* fonctions avancées (nécessite le plugin java pour le navigateur)
*/
private static void appelerUploadMultiple()
{
final Window nPan = new Window("Upload multiple");
88,7 → 104,7
final String htmlForm =
"<form method=\"post\" name=\"postid\">"
+"<input type=\"hidden\" name=\"identifiant\" value=\""+iMediateur.getIdentifiant()+"\">"
+"<input type=\"hidden\" name=\"identifiant\" value=\""+iModele.getIdentifiant()+"\">"
+"</form>" ;
 
nPan.setHtml(appelApplet+htmlForm);
98,7 → 114,7
 
public void onClose(Panel panel) {
iMediateur.rafraichirToutesVues() ;
iModele.requeteTerminee() ;
}
108,6 → 124,10
nPan.show();
}
/**
* Fonction javascript native qui détecte la présence du plugin java pour le navigateur
* et appelle la méthode d'upload adaptée (appelerUploadSimple ou appelerUploadMultiple)
*/
public static native void choisirMethodeUpload() /*-{
var agt=navigator.userAgent.toLowerCase();
/trunk/src/org/tela_botanica/client/modeles/ImageCarnet.java
10,18 → 10,26
*
* Classe representant une image du carnet,
* elle ne contient pas d'image à proprement parler mais
* plutôt les informations associées ainsi que l'url distante
* plutôt les informations associées ainsi que l'url distante.
* C'est une table de hachage qui contient des paires propriété/valeur
*
*/
public class ImageCarnet extends HashMap {
 
/**
* Constructeur avec un objet JSON
* @param image
*/
public ImageCarnet(JSONObject image)
{
// l'objet JSON est une table de hachage
Set im = image.keySet() ;
// on la parcourt pour chaque clé
for (Iterator iterator = im.iterator(); iterator.hasNext();) {
// si elle est associée à une valeur, on l'ajoute
String key = (String) iterator.next();
if(image.get(key).isString() != null)
{
30,6 → 38,7
}
else
{
// sinon on ajoute la clé avec une valeur vide
String valeur = " " ;
this.put(key, valeur) ;
}
38,6 → 47,9
 
}
/**
* Surcharge de toString qui affiche toutes les propriétés de l'image
*/
public String toString()
{
String valeur = " ";
56,6 → 68,13
return valeur ;
}
/**
* Pour éviter que l'on traite des valeurs nulles à l'affichage
* on passe par cette fonction qui retire les charactères nuls qui font planter
* l'affichage, il ne faut pas utiliser get directement
* @param cle
* @return la valeur associée à la clé
*/
public String renvoyerValeurCorrecte(String cle)
{
if(this.containsKey((cle)))
63,7 → 82,7
String valeur = (String)this.get(cle) ;
if(valeur.equals("null") || valeur == null)
{
return "null" ;
return " " ;
}
else
{
75,65 → 94,114
}
else
{
return "null" ;
return " " ;
}
}
 
/**
* Acesseur pour l'id de l'image
* @return l'id de l'image
*/
public String getId() {
return renvoyerValeurCorrecte("ci_id_image") ;
}
/**
* Acesseur pour le numero d'ordre de l'image
* @return l'ordre de l'image
*/
public String getOrdre() {
return renvoyerValeurCorrecte("ci_ordre") ;
}
/**
* Base de l'url serveur pour les images
* @return url racine pour les images
*/
public String getBaseUrl()
{
return "http://162.38.234.9/Documents/images_serveur/" ;
}
 
/**
* Renvoie le chemin et nom du fichier grand format
* @return le chemin du fichier grand format
*/
public String getUrl() {
return getBaseUrl()+(String)this.get("ci_id_image")+".jpg" ;
}
/**
* Renvoie le chemin et nom du fichier petit format
* @return le chemin du fichier petit format
*/
public String getSUrl() {
return getBaseUrl()+(String)this.get("ci_id_image")+"_S.jpg" ;
}
/**
* Renvoie le chemin et nom du fichier moyen format
* @return le chemin du fichier moyen format
*/
public String getMUrl() {
return getBaseUrl()+(String)this.get("ci_id_image")+"_M.jpg" ;
}
 
 
/**
* Renvoie la taille de l'image
* @return un tableau de deux string contenant la hauteur puis la largeur
*/
public String[] getTailleImage()
{
String[] XY = { renvoyerValeurCorrecte("ci_meta_height") , renvoyerValeurCorrecte("ci_meta_width") } ;
return XY ;
}
/**
* Renvoie la date exif associée à l'image
* @return la date associée à l'image
*/
public String getDate() {
return renvoyerValeurCorrecte("ci_meta_date_time") ;
}
 
 
/**
* Renvoie la ville associée à l'image
* @return la ville iptc
*/
public Object getIptcCity() {
return renvoyerValeurCorrecte("ci_meta_iptc_city") ;
}
 
 
/**
* Renvoie le fabricant de l'appareil
* @return le fabricant
*/
public String getMake() {
return renvoyerValeurCorrecte("ci_meta_make") ;
}
 
 
/**
* Renvoie le modele de l'appareil
* @return le modele
*/
public String getModel() {
return renvoyerValeurCorrecte("ci_meta_model") ;
}
/**
* Renvoie un tableau nom / valeur de toutes les metadonnées Iptc
* @return les métadonnées iptc
*/
public String[][] getMetadonnesIptc() {
String[][] metaIptc = new String[12][2] ;
167,7 → 235,11
return metaIptc ;
}
public Object[][] getMetadonnesExif() {
/**
* Renvoie un tableau nom / valeur de toutes les metadonnées Exif
* @return les métadonnées Exif
*/
public String[][] getMetadonnesExif() {
String[][] metaExif = new String[31][2] ;
int elem = 0 ;
201,7 → 273,11
}
public Object[][] getInfoGenerales() {
/**
* Renvoie un tableau nom / valeur contenant les infos générales
* @return les infos générales
*/
public String[][] getInfoGenerales() {
String[][] metaGen = new String[2][2] ;
214,11 → 290,20
return metaGen ;
}
/**
* Renvoie une string contenant les mots clés séparés par des ','
* @return les mots clés
*/
public String getMotsCles() {
return renvoyerValeurCorrecte("ci_meta_mots_cles") ;
}
/**
* Met à jour le commenentaire et la date
* @param commentaires le nouveau commentaire
* @param date la nouvelle date
*/
public void miseAJourInfoGenerales(String commentaires, String date)
{
put("ci_meta_comment",commentaires) ;
225,7 → 310,11
put("ci_meta_date",date) ;
}
 
/**
* Met à jour les mots clés
* @param motsClesEnCours la liste de mots clés séparés par des ','
*/
public void mettreAjourMotsCles(String motsClesEnCours) {
put("ci_meta_mots_cles",motsClesEnCours) ;
/trunk/src/org/tela_botanica/client/modeles/ImageAsynchroneDAO.java
8,20 → 8,23
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.user.client.Window;
 
/**
* DAO d'accès à une image, n'est utilisé que pour l'écriture et pas pour la lecture des images
* qui se fait par paquet
* @author aurelien
*
*/
public class ImageAsynchroneDAO {
 
ImageMediateur iMediateur = null ;
public void setIMediateur(ImageMediateur im)
{
iMediateur = im ;
}
/**
* Met à jour la base de données avec toutes les données d'une image
* @param ic l'image à mettre à jour
*/
public void SynchroniserBaseDeDonnees(final ImageCarnet ic)
{
String postData = "" ;
// on construit le post avec toutes les valeur de l'image
for(Iterator imgIt = ic.keySet().iterator();imgIt.hasNext();)
{
31,10 → 34,11
 
}
 
 
// et on envoie une requête asynchrone
HTTPRequest.asyncPost("jrest/inventoryImage/0/", postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
//TODO: ajouter une vérification de la mise à jour
}
41,17 → 45,24
}) ;
}
/**
* Met à jour la base de données avec les mots clés associés à l'image
* @param ic l'image à mettre à jour
*/
public void SynchroniserMotsClesImageBaseDeDonnees(final ImageCarnet ic)
{
String postData = "" ;
// on récupère les mots clés de l'image et on fabrique le post
String motsCles = ic.getMotsCles() ;
String id = ic.getId() ;
postData += "&ci_id_image="+id+"&ci_meta_mots_cles="+motsCles ;
 
// on envoie une requête asynchrone
HTTPRequest.asyncPost("jrest/inventoryImage/0/", postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
//TODO: ajouter une vérification de la mise à jour
}
58,15 → 69,21
}) ;
}
/**
* Supprime une image de la base de données
* @param ic l'image à supprimer
*/
public void supprimerBaseDeDonnees(final ImageCarnet ic)
{
// le post contient l'action delete pour JREST (qui ne gère pas DELETE comme une requête à part entière)
String postData = "" ;
postData += "&action=DELETE" ;
// on envoie un post avec l'id de l'image à supprimer
HTTPRequest.asyncPost("jrest/inventoryImage/0/"+ic.getId(), postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
Window.alert(responseText) ;
//TODO: ajouter une vérification de la mise à jour
}
}) ;
/trunk/src/org/tela_botanica/client/modeles/ListeImageCarnet.java
4,23 → 4,38
import java.util.Vector;
 
/**
* vecteur composé d'ImageCarnet, renvoyé par les objets de type DAO
* pour les images
* table de hachage composée d'ImageCarnet, renvoyé par les objets de type DAO
* pour les images.
* La clé est l'identifiant de l'image dans la base de données, et la valeur un objet
* de type ImageCarnet.
* GWT ne supporte pas encore les type paramètres mais quand il le fera il faudra créer la HashMap
* avec <String,ImageCarnet>
* @author aurelien
*
*/
public class ListeImageCarnet extends HashMap {
/**
* Constructeur sans paramètres
*/
public ListeImageCarnet()
{
super();
}
/**
* Constructeur avec paramètre
* @param taille la taille de la table de hachage
*/
public ListeImageCarnet(int taille)
{
super(taille);
}
/**
* Constructeur avec paramètre
* @param ic un tableau d'ImageCarnet
*/
public ListeImageCarnet(ImageCarnet[] ic)
{
super() ;
/trunk/src/org/tela_botanica/client/modeles/ListeImageAsynchroneDAO.java
3,6 → 3,7
import java.util.Iterator;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.image.ImageModele;
import org.tela_botanica.client.interfaces.Rafraichissable;
 
import com.google.gwt.json.client.JSONArray;
28,18 → 29,31
*/
public class ListeImageAsynchroneDAO {
ImageMediateur iMediateur = null ;
/**
* Le modèle associé au DAO
*/
ImageModele iModele = null ;
public void setIMediateur(ImageMediateur im)
/**
* Setteur pour le modèle
* @param im le modèle à associer
*/
public void setIModele(ImageModele im)
{
iMediateur = im ;
iModele = im ;
}
/**
* Envoie une requete au serveur jrest pour obtenir une liste d'images correspondant à des critères demandés
* @param r le rafraichissable qui a demandé les données
* @param criteres un tableau contenant les critères de selections
*/
public void ObtenirListeImages(final Rafraichissable r, String[][] criteres)
{
String requete = "" ;
// on construit les paramètres du get
if(criteres != null)
{
for (int i = 0; i < criteres.length; i++) {
52,12 → 66,16
}
}
// on envoie le get asynchrone
HTTPRequest.asyncGet("jrest/InventoryImageList/0/"+requete, new ResponseTextHandler() {
// si tout se passe bien on reçoit une réponse JSON
public void onCompletion(String responseText) {
final ListeImageCarnet photoData ;
 
final JSONValue responseValue = JSONParser.parse(responseText);
// si c'est un tableau
if (responseValue.isArray() != null) {
final JSONArray reponse = responseValue.isArray();
65,7 → 83,7
final int taillemax = reponse.size();
photoData = new ListeImageCarnet(taillemax);
// on le parcourt
for (int j = 0; j < taillemax ; j++) {
JSONObject image = (JSONObject)reponse.get(j) ;
72,6 → 90,7
ImageCarnet im = new ImageCarnet(image) ;
// et on en extrait les données pour construire la liste d'image
photoData.put(im.getOrdre(),im) ;
}
78,25 → 97,35
}
else
{
// si c'est un objet alors il n'y a qu'une réponse
if(responseValue.isObject() != null)
{
photoData = new ListeImageCarnet(1);
ImageCarnet im = new ImageCarnet(responseValue.isObject()) ;
// on crée une liste de 1 élement auquel on ajoute ce qui a été reçu
photoData.put(im.getOrdre(),im) ;
}
else
{
// sinon on crée une liste vide
photoData = new ListeImageCarnet(0) ;
}
}
// dans tous les cas on transmet la liste crée au rafraichissable en lui demandant de répandre les données car il est
// le premier à les recevoir
r.rafraichir(photoData,true);
}
});
}
/**
* Met à jour les valeurs d'une liste d'image donnée dans la base de données
* @param li la liste d'image à synchroniser avec la base
*/
public void SynchroniserBaseDeDonnees(ListeImageCarnet li)
{
// on parcourt toute la liste d'image
for(Iterator listIt = li.keySet().iterator() ; listIt.hasNext() ;)
{
String postData = "" ;
103,8 → 132,10
ImageCarnet enCours = (ImageCarnet)li.get(listIt.next()) ;
// pour chaque image on extrait les informations
for(Iterator imgIt = enCours.keySet().iterator();imgIt.hasNext();)
{
// qu'on place dans le poste
String key = (String)imgIt.next() ;
String valeur = enCours.renvoyerValeurCorrecte(key) ;
valeur.replaceAll("'", "\'") ;
112,9 → 143,11
}
HTTPRequest.asyncPost("jrest/inventoryImage/0/", postData, new ResponseTextHandler() {
// on fait un post asynchrone et on les envoie à jrest
HTTPRequest.asyncPost("jrest/inventoryImage/0/", postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
//TODO: vérifier mieux le succès del a requête
}
122,23 → 155,31
}
}
/**
* Supprime des image sur le serveur par rapport à leur identifant
* @param ids un tableau d'identifiants d'images à supprimer
*/
public void supprimerBaseDeDonnees(String[] ids)
{
String postData = "" ;
// on fait un delete dans le post (jrest ne gère pas delete comme une action à part entière)
postData += "&action=DELETE" ;
String uid = "" ;
// on concatène les ids
for (int i = 0; i < ids.length; i++) {
uid += ids[i]+"," ;
}
HTTPRequest.asyncPost("jrest/inventoryImageList/"+iMediateur.getIdentifiant()+"/"+uid, postData, new ResponseTextHandler() {
// et on envoie ça au serveur
HTTPRequest.asyncPost("jrest/inventoryImageList/"+iModele.getIdentifiant()+"/"+uid, postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
iMediateur.rafraichirToutesVues() ;
// quand la requête est éxecutée on le signale au modèle poru qu'il mette à jour les données
// et en notifie le médiateur
iModele.requeteTerminee() ;
}
}) ;
/trunk/src/org/tela_botanica/client/modeles/NombreImageAsynchroneDAO.java
1,6 → 1,7
package org.tela_botanica.client.modeles;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.image.ImageModele;
import org.tela_botanica.client.interfaces.Rafraichissable;
 
import com.google.gwt.json.client.JSONArray;
11,16 → 12,35
import com.google.gwt.user.client.HTTPRequest;
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Image;
 
/**
* DAO qui renvoie le nombre d'image associées à différents critères donnés (utile pour la pagination)
* @author aurelien
*
*/
public class NombreImageAsynchroneDAO {
 
private ImageMediateur iMediateur = null ;
/**
* Le modèle associé au DAO
*/
private ImageModele iModele = null ;
public void setImediateur(ImageMediateur im)
/**
* Setteur pour le modèle
* @param im le modèlme à associer
*/
public void setIModele(ImageModele im)
{
iMediateur = im ;
iModele = im ;
}
/**
* Envoie une requete au serveur jrest pour obtenir le nombre d'images correspondant
* à des critères données en paramètres
* @param r le rafraichissable qui demande la mise à jour
* @param criteres un tableau nom/valeur des critères pour les images
*/
public void obtenirNombreImages(final Rafraichissable r, String[][] criteres)
{
String requete = "" ;
27,6 → 47,7
if(criteres != null)
{
// on construit les paramètres du get avec les critères (&critere1=valeur1&critere2=valeur2 etc...)
for (int i = 0; i < criteres.length; i++) {
if(!criteres[i][0].equals("ci_ordre"))
44,17 → 65,21
}
}
HTTPRequest.asyncGet("jrest/InventoryImageCount/0/"+requete, new ResponseTextHandler() {
// on fait un get asynchrone
HTTPRequest.asyncGet("jrest/InventoryImageCount/"+iModele.getIdentifiant()+"/"+requete, new ResponseTextHandler() {
public void onCompletion(String responseText) {
final JSONValue responseValue = JSONParser.parse(responseText);
// si la requete se passe bien on reçoit un tableau JSON
if(responseValue.isArray() != null)
{
// qui contient une valeur : le nombre d'images correspondant au critères
JSONValue res = responseValue.isArray().get(0) ;
JSONString reponseNombre = res.isString() ;
int maxImages = (int)Integer.parseInt(reponseNombre.stringValue()) ;
int[] nbImages = {maxImages} ;
// on le met dans un tableau d'entiers qu'on tranmset au demandeur de la mise à jour
r.rafraichir(nbImages, true) ;
}
/trunk/src/org/tela_botanica/client/modeles/MotsClesAsynchroneDAO.java
1,42 → 1,54
package org.tela_botanica.client.modeles;
 
import java.util.HashMap;
import java.util.Iterator;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.image.ImageModele;
import org.tela_botanica.client.interfaces.Rafraichissable;
 
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.HTTPRequest;
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.user.client.Window;
import com.gwtext.client.data.Node;
import com.gwtext.client.data.Tree;
import com.gwtext.client.widgets.tree.TreeNode;
 
/**
* DAO d'accès à l'arbre de mots clés
* @author aurelien
*
*/
public class MotsClesAsynchroneDAO {
private ImageMediateur iMediateur = null ;
/**
* Le modele associé au DAO
*/
private ImageModele iModele = null ;
public void setIMediateur(ImageMediateur im)
/**
* Setteur pour le modèle
* @param im le modèle à associer
*/
public void setIModele(ImageModele im)
{
iMediateur = im ;
iModele = im ;
}
/**
* Envoie une requete au serveur jrest pour obtenir l'arbre des mots clés
* @param r le rafraichissable qui demande les données
*/
public void obtenirListeMotsCles(final Rafraichissable r)
{
HTTPRequest.asyncGet("jrest/InventoryKeyWordList/"+iMediateur.getIdentifiant(), new ResponseTextHandler() {
// on demande tous les mots clés associés à l'utilisateur
HTTPRequest.asyncGet("jrest/InventoryKeyWordList/"+iModele.getIdentifiant(), new ResponseTextHandler() {
 
public void onCompletion(String responseText) {
final JSONValue responseValue = JSONParser.parse(responseText);
// si la requête est un succès on reçoit un tableau
if (responseValue.isArray() != null) {
final JSONArray reponse = responseValue.isArray();
 
// et on met à jour le demandeur des données
r.rafraichir(reponse, true) ;
}
}
43,7 → 55,10
});
}
/**
* Envoie requete au serveur jrest pour ajouter un mot clé
* @param motcle le mots clés à ajouter avec son parent et son identifiant
*/
public void ajouterBaseDeDonnees(String motcle)
{
if(!motcle.equals(""))
50,11 → 65,12
{
String postData = motcle ;
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/","&identifiant="+iMediateur.getIdentifiant()+postData, new ResponseTextHandler() {
// on fait un post asynchrone
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/","&identifiant="+iModele.getIdentifiant()+postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
// si on reçoit une erreur d'ajout, on affiche un message d'erreur
if(responseText.equals("ERROR"))
{
Window.alert("Attention, la base de données des mots clés n'est plus synchronisée avec l'application," +
66,6 → 82,10
}
}
/**
* Envoie requete au serveur jrest pour supprimer un mot clé
* @param motcle le mots clés à supprimer
*/
public void supprimerBaseDeDonnees(String motcle)
{
if(!motcle.equals(""))
73,7 → 93,7
String postData = "" ;
postData += "&action=DELETE" ;
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iMediateur.getIdentifiant()+"/"+motcle,postData, new ResponseTextHandler() {
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iModele.getIdentifiant()+"/"+motcle,postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
88,6 → 108,10
}
}
 
/**
* Envoie requete au serveur jrest pour modifier un mot clé
* @param motcle le mots clés à modifier avec son parent et son identifiant
*/
public void modifierBaseDeDonnees(String motcle) {
if(!motcle.equals(""))
96,7 → 120,7
String postData = "" ;
postData += "&action=modification"+motcle ;
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iMediateur.getIdentifiant() ,postData, new ResponseTextHandler() {
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iModele.getIdentifiant() ,postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
108,6 → 132,10
}
/**
* Envoie requete au serveur jrest pour modifier un mot clé
* @param motcle le mots clés à ajouter avec son ancien parent, son nouveau et son identifiant
*/
public void deplacerBaseDeDonnees(String motcle) {
if(!motcle.equals(""))
116,7 → 144,7
String postData = "" ;
postData += "&action=deplacement"+motcle ;
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iMediateur.getIdentifiant() ,postData, new ResponseTextHandler() {
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iModele.getIdentifiant() ,postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {