1  //!-- UTF8
     2  /*
     3   Oregano Multiuser Server - Version 1.2.0 - January 4th, 2005
     4   
     5  	Web:  www.oregano-server.org
     6  	Mail: info@oregano-server.org
     7   
     8  	Copyright 2003 - 2004 - 2004 Jens Halm / Cologne, Germany
     9   
    10   This library is free software; you can redistribute it and/or
    11   modify it under the terms of the GNU Lesser General Public
    12   License as published by the Free Software Foundation; either
    13   version 2.1 of the License, or (at your option) any later version.
    14   
    15   This library is distributed in the hope that it will be useful,
    16   but WITHOUT ANY WARRANTY; without even the implied warranty of
    17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    18   Lesser General Public License for more details.
    19   
    20   You should have received a copy of the GNU Lesser General Public
    21   License along with this library; if not, write to the Free Software
    22   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23  */
    24  
    25  /*
    26   -------------------------------------------
    27  	Classe PropertyLoader
    28   
    29  	@description :
    30  	Gère la reception de propriétés persistantes externes au groupe courant.
    31   
    32   
    33  	@author Jens Halm copyright http://www.spicefactory.org/
    34  	@author erixtekila copyleft http://www.v-i-a.net  
    35   -------------------------------------------
    36  	version history :
    37  	1.2.0 : 05/02/05
    38  			- Portage en actionscript 2 pour le
    39  			compile time type checking
    40   -------------------------------------------
    41   */
    42  
    43  import org.omus.util.EventDispatcher;
    44  import org.omus.util.iObservable;
    45  import org.omus.util._Error;
    46  import org.omus.util._Class;
    47  
    48  import org.omus.msg.MessageHandler;
    49  import org.omus.msg.iMessageHandler;
    50  import org.omus.msg.Envelope;
    51  import org.omus.msg.EnvelopeFactory;
    52  import org.omus.msg.Message;
    53  import org.omus.msg.MessageRouter;
    54  
    55  
    56  /**
    57   *	Cette classe gère l'interrogation de propriétés persistantes externes au groupe courant.
    58   *
    59   *	<p>
    60   *	Evénements auxquels s'abonner :
    61   *	<ul> 
    62   *	<li>onError(error:_Error)					Invoqué lorsqu'une erreur survient lors de le fermeture/ouverture ou le changement de groupe.
    63   *	</li></ul></p>
    64   *	Elle est aggrémentée par composition des méthodes des sources d'événements (EventDispatcher).
    65   *	Elle est aggrémentée par composition de la classe MessageHandler.
    66   *	@see org.omus.util.EventDispatcher
    67   *	@see org.omus.util.iObservable
    68   *	@see org.omus.msg.MessageHandler
    69   *	@see org.omus.msg.iMessageHandler
    70   *
    71   *	@author Jens Halm copyright http://www.spicefactory.org/
    72   *	@author erixtekila copyleft http://www.v-i-a.net 
    73   *	@version 1.2.0
    74   */
    75  class org.omus.data.PropertyLoader implements iObservable, iMessageHandler
    76  {
    77  	//--------------------
    78  	// PROPRIETES
    79  	//--------------------
    80  	/**
    81  	 *	Référence au système de génération d'événements.
    82  	 */
    83  	private var _eventSource:EventDispatcher;
    84  	
    85  	/**
    86  	 *	Référence à la classe MessageHandler;
    87  	 */
    88  	private var _messageHandler:MessageHandler;
    89  	
    90  	//--------------------
    91  	// CONSTRUCTEUR
    92  	//--------------------
    93  	/**
    94  	 *	L'objet PropertyLoader dispose des méthodes d'EventDispatcher
    95  	 *	et de celles de MessageHandler par composition.
    96  	 *
    97  	 *	@see org.omus.util.EventDispatcher
    98  	 *	@see org.omus.util.iObservable
    99  	 *	@see org.omus.msg.MessageHandler
   100  	 *	@see org.omus.msg.iMessageHandler
   101  	 */
   102  	public function PropertyLoader()
   103  	{
   104  		// Composition avec EventDispatcher
   105  		_eventSource = new EventDispatcher();
   106  		// Composition avec MessageHandler
   107  		_messageHandler = new MessageHandler();
   108  		
   109  		// Initialisation des événements
   110  		_messageHandler.initMessageHandler(this);
   111  		
   112  		// Callbacks des envois de messages.
   113  		addHandler("loadProperties","handleProperties");
   114  
   115  		// trace(this+ " installé.");
   116  	}
   117  	
   118  	
   119  	//--------------------
   120  	// METHODES PUBLIQUES
   121  	//--------------------
   122  	/**
   123  	 *	Utilisé dans un contexte littéral
   124  	 *	@return	Une chaine définissant l'objet
   125  	 */
   126  	public function toString():String
   127  	{
   128  		return "[Objet PropertyLoader]";
   129  	}
   130  
   131  	/**
   132  	 *	Charge les propriétés persistantes d'un utilisateur.
   133  	 *
   134  	 *	@param username			Nom de l'utilsateur.
   135  	 *	@param propNames		Liste des propriétés.
   136  	 */
   137  	public function loadUser (username:String, propNames:Array):Void
   138  	{
   139  		// TODO : Accès Singleton
   140  		var clazz = _Class.getInstance();
   141  		var argCheck = [[username,"string",true],[propNames,Array,true]];
   142  		if (! clazz.checkArguments("org.omus.data.PropertyLoader.loadUser", argCheck)) return;
   143  		load(false, username, propNames);
   144  	}
   145  
   146  	/**
   147  	 *	Charge les propriétés persitantes d'un groupe.
   148  	 *
   149  	 *	@param groupName		Nom du groupe.
   150  	 *	@param propNames		Listes des propriétés.
   151  	 */
   152  	public function loadGroup (groupName:String, propNames:Array):Void
   153  	{
   154  		// TODO : Accès Singleton
   155  		var clazz = _Class.getInstance();
   156  		var argCheck = [[groupName, "string", true], [propNames, Array, true]];
   157  		if (! clazz.checkArguments("org.omus.data.PropertyLoader.loadGroup", argCheck)) return;
   158  		load(true, groupName, propNames);
   159  	}
   160  
   161  	//*** Implémentation de iObservable ***\
   162  	/**
   163  	 *	Notifie les observateurs d'un événement.
   164  	 *
   165  	 *	@param logLevel Une chaine caractérisant le niveau de logging de l'information.
   166  	 *	@param eventName Nom de l'événement.
   167  	 *	@param arg1		[option] Autant de paramêtres de voulu.
   168  	 */
   169  	private function fireEvent (logLevel:String, eventName:String):Void
   170  	{
   171  		_eventSource.fireEvent.apply (_eventSource, arguments);
   172  	}
   173  	
   174  	/**
   175  	 *	Ajoute un nouvel observateur.
   176  	 * 
   177  	 *	@param		listener Référence de l'observateur.
   178  	 *	@return Un booléen indiquant la réussite de l'opération.
   179  	 */
   180  	public function addListener (listener:Object):Boolean
   181  	{
   182  		return _eventSource.addListener(listener);
   183  	}
   184  	
   185  	/**
   186  	 *	Supprime un observateur.
   187  	 *
   188  	 *	@param		listener Référence de l'observateur.
   189  	 *	@return Un booléen indiquant la réussite de l'opération.
   190  	 */
   191  	public function removeListener (listener:Object):Boolean
   192  	{
   193  		return _eventSource.removeListener(listener);
   194  	}
   195  	
   196  	/**
   197  	 *	Supprime tous les abonnés.
   198  	 */
   199  	public function removeAllListeners ():Void
   200  	{
   201  		_eventSource.removeAllListeners();
   202  	}
   203  	
   204  	/**
   205  	 *	Retourne le nombre d'observateurs.
   206  	 *
   207  	 *	@return Le nombre d'observateurs enregistrés.
   208  	 */
   209  	public function countListeners ():Number
   210  	{
   211  		return _eventSource.countListeners();
   212  	}
   213  	
   214  	
   215  	//*** Implémentation de iMessageHandler ***\\
   216  	/**
   217  	 *	Active la gestion d'un type de message par accusé de réception
   218  	 *	en fonction du contenu de son enveloppe.
   219  	 *
   220  	 * @param env		Une référence à l'enveloppe.
   221  	 */
   222  	public function handleMessage (env:Envelope):Void
   223  	{
   224  		_messageHandler.handleMessage(env);
   225  	}
   226  	
   227  	/**
   228  	 *	Rajoute un gestionnaire chargé d'intercepter 
   229  	 *	la réponse du serveur suite à un message soumis.
   230  	 *	Forme d'accusé de réception (callback).
   231  	 *
   232  	 *	@param		subject Le type de message.
   233  	 *	@param		methodName Le nom de l'événement gérant un type de message. 
   234  	 */
   235  	public function addHandler (subject:String, methodName:String):Void
   236  	{
   237  		_messageHandler.addHandler (subject, methodName);
   238  	}
   239  	
   240  	
   241  	// Callbacks des messges Message avec accusés de réception
   242  	/**
   243  	 *	Gestionnaire de l'accusé de réception du message de chargement de la liste des propriétés persistantes.
   244  	 *	Génère un événement onLoadGroup, onLoadUser ou onError aux observateurs.
   245  	 *
   246  	 *	@param env		Enveloppe du message retourné.
   247  	 */
   248  	private function handleProperties (env:Envelope):Void
   249  	{
   250  		var id = env.getID();
   251  		// TODO : Accès Singleton
   252  		var msgRouter = MessageRouter.getInstance();
   253  		// MessageRouter.cache ne défini pas de typage
   254  		var method = String (msgRouter.getCache(id, "method"));
   255  		var args = msgRouter.getCache(id, "args");
   256  		
   257  		var attach = env.getMessage().getAttachment();
   258  		var errCode = attach.error;
   259  		if (errCode == "ok")
   260  		{
   261  			var evtName = (method == "loadGroup") ? "onLoadGroup" : "onLoadUser" ;
   262  			var name = args[0];
   263  			// Broadcast
   264  			fireEvent("info", evtName, name, attach.props);
   265  		} else
   266  		{
   267  			// Broadcast
   268  			// Pour forcer le type de args
   269  			fireEvent("error", "onError", new _Error(errCode, method, args.concat()));
   270  		}
   271  	}
   272  	// Fin des callbacks des messges Message avec accusés de réception
   273  
   274  	
   275  	//--------------------
   276  	// METHODES PRIVEES
   277  	//--------------------
   278  	/**
   279  	 *	Charegement de propriétés persistantes.
   280  	 *	
   281  	 *	@param group		true pour un groupe.
   282  	 *	@param name			Nom du membre ou groupe.
   283  	 *	@param propNames	Liste de propriétés.	
   284  	 */
   285  	private function load (group:Boolean, name:String, propNames:Array):Void
   286  	{
   287  		var len = propNames.length;
   288  		if (len == 0)
   289  		{
   290  			// Logs internes
   291  			_global.oregano.iLog.warn("clj-062","");
   292  			return;
   293  		}
   294  		for (var i = 0; i < len; i++)
   295  		{
   296  			if (typeof(propNames[i]) != "string")
   297  			{
   298  				// Logs internes
   299  				_global.oregano.iLog.error("clj-063","illegal type = " + typeof(propNames[i]));
   300  				return;
   301  			}
   302  		}
   303  		var msg = new Message("loadProperties");
   304  		var attach = msg.getAttachment();
   305  		attach.group = group;
   306  		attach.name = name;
   307  		attach.propNames = propNames;
   308  		// TODO : Accès Singleton.
   309  		var envFactory = EnvelopeFactory.getInstance();
   310  		var msgRouter = MessageRouter.getInstance();
   311  		
   312  		var env = envFactory.getOutgoing(msg,"info");
   313  		var method = (group) ? "loadGroup" : "loadUser";
   314  		msgRouter.handleOutgoing(env, this, method, [name, propNames], null);
   315  	}
   316  	
   317  	
   318  	//--------------------
   319  	// METHODES STATIQUES
   320  	//--------------------
   321  	/**
   322  	 *	Utilisé dans un contexte littéral
   323  	 *
   324  	 *	@return Une chaine définissant l'objet.
   325  	 */
   326  	public static function toLog():String
   327  	{
   328  		return "[Objet PropertyLoader]";
   329  	}
   330  
   331  }
   332