1  
     2  //!-- UTF8
     3  /*
     4   Oregano Multiuser Server - Version 1.2.0 - January 4th, 2005
     5   
     6  	Web:  www.oregano-server.org
     7  	Mail: info@oregano-server.org
     8   
     9  	Copyright 2003 - 2004 - 2004 Jens Halm / Cologne, Germany
    10   
    11   This library is free software; you can redistribute it and/or
    12   modify it under the terms of the GNU Lesser General Public
    13   License as published by the Free Software Foundation; either
    14   version 2.1 of the License, or (at your option) any later version.
    15   
    16   This library is distributed in the hope that it will be useful,
    17   but WITHOUT ANY WARRANTY; without even the implied warranty of
    18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    19   Lesser General Public License for more details.
    20   
    21   You should have received a copy of the GNU Lesser General Public
    22   License along with this library; if not, write to the Free Software
    23   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24  */
    25  
    26  /*
    27   -------------------------------------------
    28  	Classe Buddies
    29   
    30  	@description :
    31  	Liste des copains.
    32   
    33   
    34  	@author Jens Halm copyright http://www.spicefactory.org/
    35  	@author erixtekila copyleft http://www.v-i-a.net 
    36   -------------------------------------------
    37  	version history :
    38  	1.2.0 : 29/12/04
    39  			- Portage en actionscript 2 pour le
    40  			compile time type checking
    41  			- Implémentation du modèle Singleton 
    42  			(abstraite auparavant)
    43   -------------------------------------------
    44   */
    45  
    46  import org.omus.util.EventDispatcher;
    47  import org.omus.util.iObservable;
    48  import org.omus.util._Error;
    49  import org.omus.util._Class;
    50  
    51  import org.omus.msg.MessageHandler;
    52  import org.omus.msg.iMessageHandler;
    53  import org.omus.msg.Message;
    54  import org.omus.msg.Envelope;
    55  import org.omus.msg.EnvelopeFactory;
    56  import org.omus.msg.MessageRouter;
    57  
    58  import org.omus.core.Session;
    59  
    60  /**
    61   *	Cette classe gère les groupes d'utilisateurs référencés.
    62   *	<p>
    63   *	Evénements auxquels s'abonner :
    64   *	<ul>
    65   *	<li>onLoad(usernames:Array)				Généré lorsque la liste est chargée.
    66   *												_param usernames	Une listes des noms enrtegistrés.
    67   *	</li><li>onRemove(username:String)			Généré lorsqu'un utilisateur a été suprimé de la liste.
    68   *												_param username		Nom de l'utilisateur.
    69   *	</li><li>onRemoveAll()						Généré lorsque tous les utilisateurs ont été suprimés de la liste.
    70   *	</li><li>onError(error:_Error)					Invoqué lorsqu'une erreur survient lors de le fermeture/ouverture ou le changement de groupe.
    71   *	</li></ul><p>
    72   *	Elle est aggrémentée par composition des méthodes des sources d'événements (EventDispatcher).
    73   *	Elle est aggrémentée par composition de la classe MessageHandler.
    74   *	@see org.omus.util.EventDispatcher
    75   *	@see org.omus.util.iObservable
    76   *	@see org.omus.msg.MessageHandler
    77   *	@see org.omus.msg.iMessageHandler
    78   *
    79   *	@author Jens Halm copyright http://www.spicefactory.org/
    80   *	@author erixtekila copyleft http://www.v-i-a.net
    81   *	@version 1.2.0
    82   */
    83  class org.omus.core.Buddies implements iObservable, iMessageHandler
    84  {
    85  	//--------------------
    86  	// PROPRIETES
    87  	//--------------------
    88  	/**
    89  	 *	Liste des amis.
    90  	 */
    91  	private var list:Array;
    92  	
    93  	/**
    94  	 *	Type et nom de la liste.
    95  	 */
    96  	private var msgType:String;
    97  	
    98  	/**
    99  	 *	Nombre de personnes enregistrées.
   100  	 */
   101  	private var cnt:Number;
   102  	
   103  	/**
   104  	 *	Nombre maximal d'enregiustrements dans la liste.
   105  	 */
   106  	private var limit:Number;
   107  	
   108  	/**
   109  	 *	Référence au système de génération d'événements.
   110  	 */
   111  	private var _eventSource:EventDispatcher;
   112  	
   113  	/**
   114  	 *	Référence à la classe MessageHandler;
   115  	 */
   116  	private var _messageHandler:MessageHandler;
   117  	
   118  	//--------------------
   119  	// CONSTRUCTEUR
   120  	//--------------------
   121  	/**
   122  	 *	L'objet Buddies dispose des méthodes d'EventDispatcher
   123  	 *	et de celles de MessageHandler par composition.
   124  	 *
   125  	 *	@param prf		Type de liste : "buddies", "blackList"	
   126  	 *	@param count	Nombre de personnes enregistrées.		
   127  	 *	@param lm		Nombre maximal de personnes enregistrables.
   128  	 *	@see org.omus.util.EventDispatcher
   129  	 *	@see org.omus.util.iObservable
   130  	 *	@see org.omus.msg.MessageHandler
   131  	 *	@see org.omus.msg.iMessageHandler
   132  	 */
   133  	public function Buddies(prf:String, count:Number, lm:Number)
   134  	{
   135  		// Composition avec EventDispatcher
   136  		_eventSource = new EventDispatcher();
   137  		// Composition avec MessageHandler
   138  		_messageHandler = new MessageHandler();
   139  		
   140  		// Initialisation des événements
   141  		_messageHandler.initMessageHandler(this);
   142  		
   143  		// Propriétés
   144  		list = null;
   145  		msgType = prf;
   146  		cnt = count;
   147  		limit = lm;
   148  		
   149  
   150  		// Callbacks des envois de messages.
   151  		addHandler("insert","handleInsert");
   152  		addHandler("load","handleLoad");
   153  		addHandler("remove","handleRemove");
   154  		addHandler("removeAll","handleRemoveAll");
   155  		
   156  		// trace(this+ " installé.");
   157  	}
   158  	
   159  	
   160  	//--------------------
   161  	// METHODES PUBLIQUES
   162  	//--------------------
   163  	/**
   164  	 *	Utilisé dans un contexte littéral
   165  	 *	@return	Une chaine définissant l'objet
   166  	 */
   167  	public function toString():String
   168  	{
   169  		return "[Objet Buddies]\norg.omus.Buddies: number of buddies = " + cnt;
   170  	}
   171  
   172  	/**
   173  	 *	Insère une nouvelle personne.
   174  	 *	Génère un événement onError aux observateur.
   175  	 *
   176  	 *	@param username		Nom de la personne.
   177  	 */
   178  	public function insert (username:String):Void
   179  	{
   180  		// TODO : Accès Singleton
   181  		var clazz = _Class.getInstance();
   182  		if (! clazz.checkArguments("org.omus.core.Buddies.insert", [[username, "string", true]])) return;
   183  		if (cnt >= limit)
   184  		{
   185  			fireEvent("info", "onError", new _Error("bud-003", "insert", arguments));
   186  			return;
   187  		}
   188  		var msg = new Message("insert");
   189  		msg.getAttachment().username = username;
   190  		// TODO : Accès Singleton
   191  		var envFactory = EnvelopeFactory.getInstance();
   192  		var msgRouter = MessageRouter.getInstance();
   193  		var env = envFactory.getOutgoing(msg, msgType);
   194  		msgRouter.handleOutgoing(env, this, "insert", arguments, null);
   195  	}
   196  	
   197  	/**
   198  	 *	Supprime une personne enregistrée.
   199  	 *
   200  	 *	@param username		Nom de la personne.
   201  	 */
   202  	public function remove (username:String):Void
   203  	{
   204  		// TODO : Accès Singleton
   205  		var clazz = _Class.getInstance();
   206  		if (! clazz.checkArguments("org.omus.core.Buddies.remove", [[username, "string", true]])) return;
   207  		// Message
   208  		var msg = new Message("remove");
   209  		msg.getAttachment().username = username;
   210  		// TODO : Accès Singleton
   211  		var envFactory = EnvelopeFactory.getInstance();
   212  		var msgRouter = MessageRouter.getInstance();
   213  		var env = envFactory.getOutgoing(msg, msgType);
   214  		msgRouter.handleOutgoing(env, this, "remove", arguments, null);
   215  	}
   216  	
   217  	/**
   218  	 *	Supprime toutes les personnes enregistrées.
   219  	 */
   220  	public function removeAll ():Void
   221  	{
   222  		// TODO : Accès Singleton
   223  		var envFactory = EnvelopeFactory.getInstance();
   224  		var session = Session.getInstance();
   225  
   226  		var env = envFactory.getOutgoing(new Message("removeAll"), msgType);
   227  		session.sendMessage(env);
   228  	}
   229  	
   230  	/**
   231  	 *	Charge la liste des amis sur le poste client.
   232  	 *	Génère un événement onLoad aux observateurs.
   233  	 */
   234  	public function load ():Void
   235  	{
   236  		if (list != null)
   237  		{
   238  			fireEvent("info", "onLoad", list);
   239  			return;
   240  		}
   241  		// TODO : Accès Singleton
   242  		var envFactory = EnvelopeFactory.getInstance();
   243  		var session = Session.getInstance();
   244  
   245  		var env = envFactory.getOutgoing(new Message("load"), msgType);
   246  		session.sendMessage(env);
   247  	}
   248  	
   249  	//*** Implémentation de iObservable ***\
   250  	/**
   251  	 *	Notifie les observateurs d'un événement.
   252  	 *
   253  	 *	@param logLevel Une chaine caractérisant le niveau de logging de l'information.
   254  	 *	@param eventName Nom de l'événement.
   255  	 *	@param arg1		[option] Autant de paramètres de voulu.
   256  	 */
   257  	private function fireEvent (logLevel:String, eventName:String):Void
   258  	{
   259  		_eventSource.fireEvent.apply (_eventSource, arguments);
   260  	}
   261  	
   262  	/**
   263  	 *	Ajoute un nouvel observateur.
   264  	 * 
   265  	 *	@param		listener Référence de l'observateur.
   266  	 *	@return Un booléen indiquant la réussite de l'opération.
   267  	 */
   268  	public function addListener (listener:Object):Boolean
   269  	{
   270  		return _eventSource.addListener(listener);
   271  	}
   272  	
   273  	/**
   274  	 *	Supprime un observateur.
   275  	 *
   276  	 *	@param		listener Référence de l'observateur.
   277  	 *	@return Un booléen indiquant la réussite de l'opération.
   278  	 */
   279  	public function removeListener (listener:Object):Boolean
   280  	{
   281  		return _eventSource.removeListener(listener);
   282  	}
   283  	
   284  	/**
   285  	 *	Supprime tous les abonnés.
   286  	 */
   287  	public function removeAllListeners ():Void
   288  	{
   289  		_eventSource.removeAllListeners();
   290  	}
   291  	
   292  	/**
   293  	 *	Retourne le nombre d'observateurs.
   294  	 *
   295  	 *	@return Le nombre d'observateurs enregistrés.
   296  	 */
   297  	public function countListeners ():Number
   298  	{
   299  		return _eventSource.countListeners();
   300  	}
   301  	
   302  	
   303  	//*** Implémentation de iMessageHandler ***\\
   304  	/**
   305  	 *	Active la gestion d'un type de message par accusé de réception
   306  	 *	en fonction du contenu de son enveloppe.
   307  	 *
   308  	 * @param env		Une référence à l'enveloppe.
   309  	 */
   310  	public function handleMessage (env:Envelope):Void
   311  	{
   312  		_messageHandler.handleMessage(env);
   313  	}
   314  	
   315  	/**
   316  	 *	Rajoute un gestionnaire chargé d'intercepter 
   317  	 *	la réponse du serveur suite à un message soumis.
   318  	 *	Forme d'accusé de réception (callback).
   319  	 *
   320  	 *	@param		subject Le type de message.
   321  	 *	@param		methodName Le nom de l'événement gérant un type de message. 
   322  	 */
   323  	public function addHandler (subject:String, methodName:String):Void
   324  	{
   325  		_messageHandler.addHandler (subject, methodName);
   326  	}
   327  	
   328  	
   329  	// Callbacks des messges Message avec accusés de réception
   330  	/**
   331  	 *	Gestionnaire de l'accusé de réception du message de chargement de la liste.
   332  	 *	Génère un événement onLoad ou onError aux observateurs.
   333  	 *
   334  	 *	@param env		Enveloppe du message retourné.
   335  	 */
   336  	private function handleLoad (env:Envelope):Void
   337  	{
   338  		var attach = env.getMessage().getAttachment();
   339  		var errCode = attach.error;
   340  		if (errCode == "ok") 
   341  		{
   342  			list = attach.names;
   343  			// Fonction de classement.
   344  			var sortF = function (a,b)
   345  			{
   346  				if (a == b) return 0;
   347  				if (a.toLowerCase() < b.toLowerCase()) return -1;
   348  				return 1;
   349  			};
   350  			list.sort(sortF);
   351  			
   352  			fireEvent("info", "onLoad", list);
   353  		} else {
   354  			fireEvent("error", "onError", new _Error(errCode, "load", new Array()));
   355  		}
   356  	}
   357  	
   358  	/*
   359  	 *	Gestionnaire de l'accusé de réception du message de chargement de la liste.
   360  	 *	Génère un événement onInsert ou onError aux observateurs.
   361  	 *
   362  	 *	@param env		Enveloppe du message retourné.
   363  	 */
   364  	private function handleInsert (env:Envelope):Void
   365  	{
   366  		var errCode = env.getMessage().getAttachment().error;
   367  		// TODO : Accès Singleton
   368  		var msgRouter = MessageRouter.getInstance();
   369  		var args = msgRouter.getCache(env.getID(), "args");
   370  		if (errCode == "ok") 
   371  		{
   372  			var username = args[0];
   373  			if (list != null) 
   374  			{
   375  				var cnt = list.length;
   376  				var l = list;
   377  				//!! TODO : Syntaxe. uname non défini.
   378  				// var Luname = uname.toLowerCase();
   379  				var Luname = username.toLowerCase;
   380  				for (var i = 0; i < cnt; i++)
   381  				{
   382  					if (Luname < l[i].username.toLowerCase())
   383  					{
   384  						l.splice(i, 0, username);
   385  						break;
   386  					}
   387  				}
   388  				if (cnt == l.length) l.push(username);
   389  			}
   390  			cnt++;
   391  			fireEvent("info", "onInsert", username);
   392  		} else 
   393  		{
   394  			// Pour forcer le type de args
   395  			fireEvent("error", "onError", new _Error(errCode, "insert", args.concat ()));
   396  		}
   397  	}
   398  	
   399  	/*
   400  	 *	Gestionnaire de l'accusé de réception du message de suppression d'un enregistrement.
   401  	 *	Génère un événement onRemove ou onError aux observateurs.
   402  	 *
   403  	 *	@param env		Enveloppe du message retourné.
   404  	 */
   405  	private function handleRemove (env:Envelope):Void
   406  	{
   407  		var errCode = env.getMessage().getAttachment().error;
   408  		// TODO : Accès Singleton
   409  		var msgRouter = MessageRouter.getInstance();
   410  		var args = msgRouter.getCache(env.getID(),"args");
   411  		if (errCode == "ok") 
   412  		{
   413  			var username = args[0];
   414  			var cnt = list.length;
   415  			var l = list;
   416  			for (var i = 0; i < cnt; i++)
   417  			{
   418  				if (username == l[i])
   419  				{
   420  					l.splice(i,1);
   421  					break;
   422  				}
   423  			}
   424  			if (cnt > l.length) this.cnt--;
   425  			fireEvent("info", "onRemove", username);
   426  		} else {
   427  			// Pour forcer le type de args
   428  			fireEvent("error", "onError", new _Error(errCode, "remove", args.concat()));
   429  		}
   430  	}
   431  	
   432  	/*
   433  	 *	Gestionnaire de l'accusé de réception du message de suppression de tous les enregistrement.
   434  	 *	Génère un événement onRemoveAll ou onError aux observateurs.
   435  	 *
   436  	 *	@param env		Enveloppe du message retourné.
   437  	 */
   438  	private function handleRemoveAll (env:Envelope):Void
   439  	{
   440  		var errCode = env.getMessage().getAttachment().error;
   441  		if (errCode == "ok")
   442  		{
   443  			list = new Array();
   444  			cnt = 0;
   445  			fireEvent("info", "onRemoveAll");
   446  		} else 
   447  		{
   448  			fireEvent("error", "onError", new _Error(errCode, "removeAll", new Array()));
   449  		}
   450  	}
   451  	// Fin des callbacks des messges Message avec accusés de réception
   452  
   453  	
   454  	//--------------------
   455  	// METHODES PRIVEES
   456  	//--------------------
   457  
   458  	
   459  	//--------------------
   460  	// METHODES STATIQUES
   461  	//--------------------
   462  	/**
   463  	 *	Utilisé dans un contexte littéral
   464  	 *
   465  	 *	@return Une chaine définissant l'objet.
   466  	 */
   467  	public static function toLog():String
   468  	{
   469  		return "[Objet Buddies]";
   470  	}
   471  
   472  }
   473