IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Récupérer une instance non statique


Sujet :

Langage Java

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Points : 199
    Points
    199
    Par défaut Récupérer une instance non statique
    Bonjour,

    Je ne sais pas trop comment expliquer mon problème, alors me tapez pas si c'est pas très clair.

    J'ai fais des classes permettant de lire des données depuis une base. Chaque instance représente une ligne. Pour des problèmes de mise à jour, ces instances ne sont pas gardée (non statique). Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Personne {
      public Personne (String identifiant){
        //Lecture de la ligne dans la base
      }
      //etc ...
    }
    Dans l'application, j'ai des écrans utilisateurs qui pointent vers une certaine instance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public class EcranPersonne {
      private Personne personneAffichée;
      //etc ...
    }
    Maintenant, dans une autre classe indépendante, je voudrais savoir si une personne avec tel identifiant est déjà en cours d'utilisation quelque pars, du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class Traitement{
      public void mettreAJour(){
        // Trouver si un objet ayant cet identifiant existe
        if (Personne.getInstance(identifiant) != null)
          Personne.getInstance(identifiant).faireUnTraitement();
      }
    }
    Est-ce possible sans passer par des champs statiques, et sans faire de lien entre les classes "EcranPersonne" et "Traitement" ?

    Je préfère éviter un champ statique, car celà m'obligerait à vérifier qu'elle n'a pas besoin d'être mise à jour, et je ne trouve pas comment assurer que cette instance est supprimée lorsqu'elle n'est plus utilisée.
    Pensez au tag quand votre problème est réglé !

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 43
    Points : 52
    Points
    52
    Par défaut
    Je pense comprendre ton problème qui peut, à mon avis, être solutionné avec le pattern DAO et le pattern d'observateur (cherche avec google, cela regorge d'explications sur internet).

    En gros, tu as une classe "PersonneDAO" (ou ObjectDAO<Personne>) qui est un singleton (via une instance static ou lié à un singleton si tu as plusieurs classes persistantes).
    Cette classe contient une méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Personne getById(int id)
    .

    Ensuite, EcranPersonne est un observateur de certaines instances de Personne. Lorsqu'une instance observée est modifiée, celle-ci prévient ces observateurs et ceux-ci réagissent.

    Bon courage.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Points : 199
    Points
    199
    Par défaut
    Merci pour ce renseignement, j'en ai appris pas mal !

    Mais ça ne correspond pas vraiment à ce que j'aimerais, puisque les classes d'utilisation ("EcranPersonne" et "Traitement") n'ont pas de traitement en réaction à la modification de la classe de données ("Personne").

    En fait, ce que je voudrais éviter, ce sont les singletons (par exemple, c'est pour le principe) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class Personne {
      // Stockage des instances
      private static HashMap instances = new HashMap();
     
      // Récupération d'instance
      public static Personne getPersonne(String identifiant){
        // En résumé
        if ( instances.get(identifiant) != null )
          return instances.get(identifiant);
        else
          return new Personne(identifiant);
      }
     
      private Personne (String identifiant){
        // Lecture de la ligne dans la base
        Select selection = new [...]
        // Stockage
        instances.put(identifiant,this);
      }
      //etc ...
    }
    Je veux l'éviter, parce que si j'ai bien compris, le gc ne l'effacera jamais puisque présent dans la HashMap statique. Ceci m'oblige à ajouter une méthode "delInstance", et à la gérer correctement (ce qui dans certaines classes ne serait pas évident).
    Ou alors, il faudrait que j'ajoute une notion de durée à l'instance, pour forcer son rechargement lorsqu'un traitement est terminé. Existe-t-il une telle notion ?
    En cherchant le pattern DAO et Observer, j'ai vu d'autres pattern (dont le singleton), mais je suis un peu perdu. Y en a-t-il un qui correspondrait à ce que je souhaiterais ?
    Pensez au tag quand votre problème est réglé !

  4. #4
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par JohnNC Voir le message
    Est-ce possible sans passer par des champs statiques, et sans faire de lien entre les classes "EcranPersonne" et "Traitement" ?
    Non, je ne pense pas.

    Mais, autant je comprends ton souhait d'éviter des champs statiques, autant je ne comprends pas pourquoi tu voudrais éviter des liens entre EcranPersonne et Traitement ?

    En java il n'existe pas d'accès central à l'ensemble des objets. Il faut donc que tu fasses, selon tes besoins, une telle chose ; et, si tu as besoin de suivre l'ensemble des identifiants de traitements affichés par l'ensemble des utilisateurs, pourquoi ne le fais-tu pas ?
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Points : 199
    Points
    199
    Par défaut
    Je ne fais pas de lien entre les classes d'écran et celles de traitement, car il y en a beaucoup, et faire de tels liens entres elles ne serait pas simple à maintenir (et dans mon cas, à mettre à jour).

    Citation Envoyé par gifffftane Voir le message
    si tu as besoin de suivre l'ensemble des identifiants de traitements affichés par l'ensemble des utilisateurs, pourquoi ne le fais-tu pas ?
    J'ai peut-être mal compris, mais justement c'est ce que je voudrais faire. Non pas dans le sens d'un suivi des objets provenant de la base, mais plutot dans celui de la récupération de ces objets (sans pour autant les stocker de façon statique).
    L'application tourne sur un environnement Client-Serveur : S'il faut minimiser le nombre de requête dans un traitement, il faudrait éviter de stocker des instances, puisque je pense qu'il ne peut pas y avoir de communication entre les JVM de 2 postes distinct (et donc aucune information de mise à jour).

    Eventuellement, pour palier à ces problèmes, j'ai créé une classe de traitement, qui stocke les objets de base pour un traitement. Mais là aussi, je ne suis pas sur de moi, étant donné qu'un traitement peut quelques fois en déclencher un autre.
    Pensez au tag quand votre problème est réglé !

  6. #6
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Si je comprends bien, tu as de nombreux clients, qui regardent des traitements, et tu voudrais suivre la visualisation de tous les traitements sur tous les postes par tous les postes ?

    Je pense que cela se résoud avec les techniques habituelles du client-serveur (bon courage). Je ne sais pas quel protocole tu utilises, mais enfin je présume que tu vois la chose et que le modèle Observer/Observable pourra t'aider.

    Maintenant, à part te dire des généralités... (désolé )

    Pour éviter de stocker les objets, j'imagine que tu as un identifiant quelconque ?... tu pourrais aussi t'aider tu UUID.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Points : 199
    Points
    199
    Par défaut
    Peut être un jour, mais pour l'instant non, je ne veux pas développer de partie Client-Serveur. C'est aussi à ça que sert la base de données.
    C'était juste une explication sur le fait de ne pas stocker d'instance statiques (les données en base pouvant changer par les manipulations d'un autre utilisateur sur un autre poste). Ou du moins, après réflexion, de les limiter.

    Il y a effectivement des identifiants (au mieux, TABLE.Identifiant), permettant l'unicité des objets correspondant. La class UUID pourrait effectivement m'aider (d'après une lecture très rapide ), je vais regarder ça de plus près.

    Sinon, plus simplement, j'aurais voulu le même système que le Garbage collector : Lorsqu'un objet n'est plus utilisé, il est supprimé. Je résume un peu, d'après ce que j'ai compris autour de la méthode "finalize()". C'est un peu mon cas, sauf qu'il reste dans un champ statique, et n'est donc jamais supprimé.
    Il me faudrait donc un système pour savoir si un objet est utilisé quelque part, ailleurs que dans ces champs statiques. Si c'est le cas, l'objet est récupéré, sinon il est rechargé. Peut être que pour ça, le pattern Observable correspond à ce que je voulais finalement.
    Pensez au tag quand votre problème est réglé !

  8. #8
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Si j'ai bien compris tu voudrais mettre en place un système de cache :
    • Si l'objet existe déjà en mémoire tu le réutilises.
    • Sinon tu le crées et tu conserves sa référence pour la réutiliser.

    Le tout en permettant au Gabage Collector de faire son travail, c'est à dire que si la référence n'est plus utilisé (mis à part par ton cache), alors elle pourra être librement supprimé...


    La solution existe et cela consiste à utiliser les References du package java.lang.ref ! Et plus particulièrement les WeakReferences !

    Grosso-modo il s'agit de classe qui englobe la référence à une instance, qui peut être récupéré à tout moment via une méthode get() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    WeakReference<MyObject> weak = new WeakReference<MyObject>(new MyObject());
     
    MyObject instance = weak.get();
    L'intérêt vient du fait qu'elles sont traités de manière particulières par le GC, qui ne les prend pas en compte de la même manière.

    Ainsi, lorsqu'il n'y a aucune autre référence à notre instance de MyObject, mis à par notre WeakReference, le GC s'autorise à libérer l'instance de MyObject. La méthode get() renverra ainsi null.

    Donc : cela te permet de conserver une référence tant qu'elle n'est pas libérée par le GC, sans gêner ce dernier dans son travail.

    Plus d'info sur le blog : Comprendre les Références en Java




    Avec cela il est possible d'utiliser une sorte de Map qui libèrera "automatiquement" ses objets, par exemple avec cette classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    public abstract class Cache<K,V> {
     
    	/**
             * On utilise une Map synchronisée pour stocker les couples clefs/valeurs.
             * Les valeurs de la Map sont englobé dans une Reference.
             */
    	private final Map<K,Reference<V>> map = Collections.synchronizedMap(new HashMap<K, Reference<V>>());
    	/**
             * Cette ReferenceQueue recevra les References mortes, et nous permettra de 'nettoyer' la Map.
             */
    	private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
     
     
     
    	/*
    	 * Méthode privée permettant d'encapsuler une valeur dans une Reference,
    	 * en gérant le cas particulier des valeurs null.
    	 */
    	private Reference<V> reference(V value) {
    		if (value==null) return null;
    		return new WeakReference<V>(value, this.queue);
    	}
     
    	/*
    	 * Méthode privée permettant de 'décapsuler' une valeur de la Reference,
    	 * en gérant le cas particulier des valeurs null.
    	 */
    	private V value(Reference<V> ref) {
    		if (ref==null) return null;
    		return ref.get(); // peut renvoyer null aussi
    	}
     
     
    	/**
             * Retourne simplement une valeur selon sa clef, si elle existe.
             */
    	public final V get(K key) {
    		trim();
    		return value(this.map.get(key));
    	}
     
    	/**
             * Associe une valeur à une clef, en écransant les éventuelles valeurs précédentes.
             */
    	public final void put(K key, V value) {
    		trim();
    		this.map.put(key, reference(value));
    	}
     
    	/**
             * Recherche la valeur associé dans le cache (si elle existe),
             * ou recharche la valeur selon la clef via doLoad().
             */
    	public final V load(K key) {
    		V value = get(key);
    		if (value==null) {
    			value = doLoad(key);
    			put(key, value);
    		}
    		return value;
    	}
     
    	/**
             * A implémenter : Méthode permettant de charger la valeur associé à la clef.
             */
    	protected abstract V doLoad(K key);
     
    	/**
             * 'Nettoie' la Map en supprimant les couples K/Reference<V>
             * dont la référence est invalide.
             */
    	public final void trim() {
    		Reference<?> ref;
    		while ( (ref=this.queue.poll()) != null) {
    			// Supprimer la valeur supprimera le couple clef/valeur dans la Map
    			this.map.values().remove(ref);
    		}
    	}
    }
    Note : ce code n'est qu'une base rapide surement améliorable. Notamment au niveau de la gestion de la synchronisation...

    La ReferenceQueue et la méthode trim() permettent de récupérer les références invalides afin de supprimer les couples clef/valeur associé (si on ne fait pas cela, le contenu de la WeakReference est bel et bien libéré par le GC, mais des couples clef/valeurs vides pourraient "encombrer" la Map).


    En utilisant la méthode load(), on récupérera la valeur depuis la Map si elle existe, ou on recréera une nouvelle...

    Exemple d'utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    	// On crée notre cache, qui pour un int 'n' renvoit un objet de 'n' Mb
    	Cache<Integer, Object> cache = new Cache<Integer, Object>() {
    		@Override
    		protected Object doLoad(final Integer n) {
    			// Crée un tableau de 'n' Mb
    			return new byte[n*1024*1024];
    		}
    	};
     
    	// On récupère le MemoryMXBean qui permet d'afficher
    	MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
     
     
    	System.out.println(memory.getHeapMemoryUsage());
    	System.out.println();
     
    	// On conserve une référence forte pour n==8 (il restera dans la Map)
    	Object n8 = cache.load(8);
     
    	// On tente de récupérer chacune des valeurs suivantes
    	int[] values = { 10, 5, 10, 8, 30, 5, 10, 15, 30, 8, 30, 5, 10, 5, 30, 5, 10, 8 };
    	for (int n : values) {
    		// Pour chaque valeur, on affiche les valeurs renvoyé par get() et load() :
    		System.out.printf("Pour n = %d  (present=%s) (load=%s)%n",
    				n, cache.get(n), cache.load(n));
    		System.out.println(memory.getHeapMemoryUsage());
    		System.out.println();
    	}
    Ce qui me donne comme résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    init = 0(0K) used = 203712(198K) committed = 5177344(5056K) max = 66650112(65088K)
     
    Pour n = 10  (present=null) (load=[B@e102dc)
    init = 0(0K) used = 19100760(18653K) committed = 25853952(25248K) max = 66650112(65088K)
     
    Pour n = 5  (present=null) (load=[B@82c01f)
    init = 0(0K) used = 24343656(23773K) committed = 25853952(25248K) max = 66650112(65088K)
     
    Pour n = 10  (present=[B@e102dc) (load=[B@e102dc)
    init = 0(0K) used = 24343656(23773K) committed = 25853952(25248K) max = 66650112(65088K)
     
    Pour n = 8  (present=[B@133796) (load=[B@133796)
    init = 0(0K) used = 24343656(23773K) committed = 25853952(25248K) max = 66650112(65088K)
     
    Pour n = 30  (present=null) (load=[B@1e4cbc4)
    init = 0(0K) used = 40029064(39090K) committed = 58036224(56676K) max = 66650112(65088K)
     
    Pour n = 5  (present=null) (load=[B@1fdc96c)
    init = 0(0K) used = 45271960(44210K) committed = 58036224(56676K) max = 66650112(65088K)
     
    Pour n = 10  (present=null) (load=[B@b2fd8f)
    init = 0(0K) used = 55757736(54450K) committed = 58036224(56676K) max = 66650112(65088K)
     
    Pour n = 15  (present=null) (load=[B@a20892)
    init = 0(0K) used = 24342200(23771K) committed = 60395520(58980K) max = 66650112(65088K)
     
    Pour n = 30  (present=null) (load=[B@1e0bc08)
    init = 0(0K) used = 55799496(54491K) committed = 60395520(58980K) max = 66650112(65088K)
     
    Pour n = 8  (present=[B@133796) (load=[B@133796)
    init = 0(0K) used = 55799496(54491K) committed = 60395520(58980K) max = 66650112(65088K)
     
    Pour n = 30  (present=[B@1e0bc08) (load=[B@1e0bc08)
    init = 0(0K) used = 55799496(54491K) committed = 60395520(58980K) max = 66650112(65088K)
     
    Pour n = 5  (present=null) (load=[B@1546e25)
    init = 0(0K) used = 13853832(13529K) committed = 57434112(56088K) max = 66650112(65088K)
     
    Pour n = 10  (present=null) (load=[B@b66cc)
    init = 0(0K) used = 24339608(23769K) committed = 57434112(56088K) max = 66650112(65088K)
     
    Pour n = 5  (present=[B@1546e25) (load=[B@1546e25)
    init = 0(0K) used = 24339608(23769K) committed = 57434112(56088K) max = 66650112(65088K)
     
    Pour n = 30  (present=null) (load=[B@173831b)
    init = 0(0K) used = 40055120(39116K) committed = 46751744(45656K) max = 66650112(65088K)
     
    Pour n = 5  (present=null) (load=[B@1e4457d)
    init = 0(0K) used = 13820984(13497K) committed = 30687232(29968K) max = 66650112(65088K)
     
    Pour n = 10  (present=null) (load=[B@18e2b22)
    init = 0(0K) used = 24306760(23737K) committed = 30687232(29968K) max = 66650112(65088K)
     
    Pour n = 8  (present=[B@133796) (load=[B@133796)
    init = 0(0K) used = 24306760(23737K) committed = 30687232(29968K) max = 66650112(65088K)
    (bien sûr le résultat n'est pas fixe et peut changer d'une exécution à l'autre selon le GC).



    A noter que tu pourrais également utiliser des SoftReference à la place des WeakReference, dans ce cas le GC conservera les objets encore plus longtemps. En fait, même s'il n'y a plus de référence standard, il conservera les objets autant que possible et ne les supprimera que si la mémoire se fait vraiment sentir (avant de générer un OutOfMemory).
    Cela génèrera une consommation mémoire plus importante, mais permet de réutiliser plus d'instance...


    a++

  9. #9
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Oui mais attention que les références ne concernent que la JVM d'un poste ; j'avais compris que l'on voulait savoir si un objet - je veux dire un truc donné par une ligne dans la base de données à ce que je comprends - était utilisé sur l'un des postes clients. Et ceci sans partie serveur, si je comprends bien.

    S'il n'y a pas de partie serveur, c'est tout simplement impossible.

    Si on ne cherche à le faire que pour le poste courant, alors la proposition d'adiGuba fonctionne.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Points : 199
    Points
    199
    Par défaut
    Merci !

    J'ai donc pas mal de recherche devant moi . Je vais donc regarder dans les References.

    @gifffftane : Oui, pour l'instant la "communication" entre les différents poste n'est pas prévu (pour l'instant), donc ca ne concerne qu'un seul et même poste. Mais comme indiqué, la base de données bouge constament, d'où la volonté de ne pas garder les objets en fin de traitement.

    Je met le tag Résolu, mes prochaines questions concerneront tout ce que j'ai "appris" aujourd'hui. Merci encore à tous !
    Pensez au tag quand votre problème est réglé !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/01/2008, 16h54
  2. Réponses: 1
    Dernier message: 28/09/2007, 09h42
  3. Réponses: 4
    Dernier message: 27/07/2007, 20h34
  4. Récupérer une instance d'un objet
    Par MDiabolo dans le forum MFC
    Réponses: 9
    Dernier message: 26/01/2007, 10h41
  5. Comment récupérer une instance de Graphics::TGraphic ?
    Par Invité dans le forum C++Builder
    Réponses: 2
    Dernier message: 11/12/2006, 15h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo