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 MessageRouter
    29  
    30  	@description :
    31  	Redirection des messages.
    32  	Singleton
    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 : 05/02/05
    39  			- Portage en actionscript 2 pour le
    40  			compile time type checking
    41  			- Casting des variables
    42  			- Correction de quelques fautes de syntaxe.
    43  			- Singleton.
    44  -------------------------------------------
    45  */
    46  
    47  import org.omus.core.Session;
    48  import org.omus.core.Group;
    49  import org.omus.core.User;
    50  
    51  import org.omus.msg.Messenger;
    52  import org.omus.msg.Envelope;
    53  import org.omus.msg.Mailbox;
    54  
    55  import org.omus.data.PropertySet;
    56  
    57  /**
    58   *	Gestion de la distribution des messages en entrée (serveur) et sortie (client).
    59   *	Pour cela, une table de références est incluse dans MessageRouter : typeMap.
    60   *	Polymorphisme sur une méthode (handleMessage) implémentée par tous les objets disposant d'accusés de récpetion.
    61   *
    62   *	Cette classe est implémentée en suivant le modèle Singleton.
    63   *	Un accès global à son instance est obtenu graçe à la méthode getInstance.
    64   *	@see org.omus.msg.MessageHandler#handleMessage
    65   *
    66   *	@author Jens Halm copyright http://www.spicefactory.org/
    67   *	@author erixtekila copyleft http://www.v-i-a.net 
    68   *	@version 1.2.0
    69   */
    70  class org.omus.msg.MessageRouter
    71  {
    72  	//--------------------
    73  	// PROPRIETES
    74  	//--------------------
    75  	/**
    76  	 *	Mise en cache des messages.
    77  	 */
    78  	private var cache:/*Object*/Array;
    79  	
    80  	/**
    81  	 *	Table de références utilisée pour activer des messages contextuels aux objets concernés.
    82  	 *	Elle contient tous les objets recevant des accusés de réception du serveur.
    83  	 */
    84  	private var typeMap:Object;
    85  	
    86  	/**
    87  	 *	Nombre de messages.
    88  	 */
    89  	private var cnt:Number;
    90  	
    91  	/**
    92  	 *	Référence globale.
    93  	 */
    94  	private static var _instance:MessageRouter;
    95  	
    96  	//--------------------
    97  	// CONSTRUCTEUR
    98  	//--------------------
    99  	/**
   100  	 *	Gère l'encodage des pièces jointes en sortie.
   101  	 */
   102  	private function MessageRouter()
   103  	{
   104  		// Propriétés
   105  		cache = new Array();
   106  		
   107  		var tm = new Object();
   108  		// TODO : Accès Singleton
   109  		var sess = Session.getInstance();
   110  		// Réferences globales.
   111  		tm.session = sess;
   112  		// TODO : Actionne les méthodes statiques handleMessage 
   113  		tm.mailbox = Mailbox;
   114  		tm.syncProps = PropertySet;
   115  		
   116  		typeMap = tm;
   117  		cnt = 0;
   118  		
   119  		// trace(this+ " installé.");
   120  	}
   121  	
   122  	/**
   123  	 *	Initialisation.
   124  	 */
   125  	private function init ():Void
   126  	{
   127  		var tm = typeMap;
   128  		
   129  		// TODO : Accès Singleton
   130  		var grp = Group.getInstance();
   131  		var usr = User.getInstance();
   132  		var msgr = Messenger.getInstance();
   133  		
   134  		tm.group = grp;
   135  		tm.setPassword = usr;
   136  		tm.setPerm = usr;
   137  		tm.setEmail = usr;
   138  		tm.customMsg = msgr;
   139  		tm["msg.toServer"] = msgr;
   140  		tm["adminMsg"] = msgr;
   141  		tm["msg.subscr"] = msgr;
   142  		tm["msg.unsubscr"] = msgr;
   143  		tm["msg.unsubAll"] = msgr;
   144  		tm["buddies"] = usr.getBuddies();
   145  		tm["blackList"] = usr.getBlackList();
   146  		tm.info = _global.info;
   147  		var lockObj = usr.getLocks();
   148  		tm["locks.acq"] = lockObj;
   149  		tm["locks.rel"] = lockObj;
   150  		tm["locks.relAll"] = lockObj;
   151  	}
   152  	
   153  	/**
   154  	 *	Gestion des messages entrants.
   155  	 *
   156  	 *	@param env		Enveloppe transmise.
   157  	 */
   158  	public function handleIncoming (env:Envelope):Void
   159  	{
   160  		var ch = cache["m" + env.getID()];
   161  		var isCached = false;
   162  		var target:Object;
   163  		if (ch != undefined)
   164  		{
   165  			target = ch.src;
   166  			isCached = true;
   167  		} else
   168  		{
   169  			target = typeMap[env.getType()];
   170  		}
   171  		
   172  		if (typeof(target) == "undefined")
   173  		{
   174  			unknownMsgType(env);
   175  			return;
   176  		}
   177  		// TODO : A revoir.
   178  		// Route tout les messages entrants vers les Singletons concernés.
   179  		// sauf vers les méthodes de classe handleMessage de MailBox et PropertySet
   180  		// TODO : Compileur MMC 2004 n'accepte pas une méthode de classe et d'instance ayant le même nom.
   181  		// Tant pis pour le polymorphisme…
   182  		if(target == PropertySet || target == Mailbox)
   183  		{
   184  			target.handleIncomingMessage(env);
   185  		} else
   186  		{
   187  			target.handleMessage(env);
   188  		}
   189  		
   190  		if (isCached) delete cache["m" + env.getID()];
   191  		if (cnt >= 5)
   192  		{
   193  			// check timeouts
   194  			var now = getTimer();
   195  			for (var each:String in cache)
   196  			{
   197  				var c = cache[each];
   198  				if ((now - c.time) > 30000)
   199  				{
   200  					// Logs internes
   201  					_global.oregano.iLog.warn("clj-061","cache = " + org.omus.util.Log.formatObject(c, 0));
   202  					delete cache[each];
   203  				}
   204  			}
   205  		}
   206  	}
   207  	
   208  	/**
   209  	 *	Gestion des messages sortants.
   210  	 *
   211  	 *	@param env				Enveloppe.
   212  	 *	@param sourceObj		Référence à l'objet dont le message émane.
   213  	 *	@param methodName		Méthode d'où le message émane.
   214  	 *	@param args				Liste de paramètres du message.
   215  	 *	@param info				Informations supplémentaires.
   216  	 */
   217  	public function handleOutgoing (env:Envelope, sourceObj:Object, methodName:String, args:Array, info:Object):Void
   218  	{
   219  		cache["m" + env.getID()] = {
   220  									src:sourceObj,
   221  									method:methodName,
   222  									args:args,
   223  									info:info,
   224  									time:getTimer()
   225  									};
   226  		// TODO : Accès Singleton.
   227  		var session:Session = Session.getInstance();
   228  		session.sendMessage(env);
   229  	}
   230  	
   231  	/**
   232  	 *	Renvoie une des propriétés du message conservé en cache.
   233  	 *
   234  	 *	@param msgID		Identifiant du message.
   235  	 *	@param prop			Propriétés disponibles : "src", "method" , "args", "info", "time".
   236  	 */
   237  	public function getCache (msgID:Number, prop:String):Object
   238  	{
   239  		var ch = getCacheObject(msgID);
   240  		// TODO : return cannot be Void
   241  		if (typeof(ch) != "undefined")
   242  		{
   243  			var c = ch[prop];
   244  			if (typeof(c) == "undefined")
   245  			{
   246  				// Logs internes
   247  				_global.oregano.iLog.error("clj-047","cache property name = " + prop);
   248  				return null;
   249  			}
   250  			return c;
   251  		}
   252  	}
   253  	
   254  	/**
   255  	 *	Renvoie une référence à un message conservé en cache.
   256  	 *
   257  	 *	@param msgID		Identifiant du message.
   258  	 *	@return 			Un objet contenant les propriétés du message :
   259  	 *						{@code
   260  	 *								src:Object,
   261  	 *								method:String,
   262  	 *								args:Array,
   263  	 *								info:Object,
   264  	 *								time:Number
   265  	 *						}
   266  	 *						TODO : Typer ces valeurs importantes.
   267  	 */
   268  	public function getCacheObject (msgID:Number):Object
   269  	{
   270  		var ch = cache["m" + msgID];
   271  		if (typeof(ch) == "undefined")
   272  		{
   273  			// Logs internes
   274  			_global.oregano.iLog.error("clj-048","");
   275  			return null;
   276  		}
   277  		return ch;
   278  	}
   279  	
   280  	/**
   281  	 *	Génère une erreur pour message inconnu.
   282  	 *
   283  	 *	@param env		Enveloppe.
   284  	 */
   285  	public function unknownMsgType (env:Envelope):Void
   286  	{
   287  		// Logs internes
   288  		_global.oregano.iLog.error("clj-049","envelope = " + env);
   289  	}
   290  	
   291  	/**
   292  	 *	Réinitialise le cache.
   293  	 */
   294  	public function clearCache ():Void
   295  	{
   296  		cache = new Array();
   297  	}
   298  	
   299  	//--------------------
   300  	// METHODES PUBLIQUES
   301  	//--------------------
   302  	/**
   303  	 *	Utilisé dans un contexte littéral
   304  	 *	@return	Une chaine définissant l'objet
   305  	 */
   306  	public function toString():String
   307  	{
   308  		return "[Object MessageRouter]";
   309  	}
   310  
   311  	
   312  	//--------------------
   313  	// METHODES PRIVEES
   314  	//--------------------
   315  	
   316  	//--------------------
   317  	// METHODES STATIQUES
   318  	//--------------------
   319  	/**
   320  	 *	Utilisé dans un contexte littéral
   321  	 *	@return	Une chaine définissant l'objet
   322  	 */
   323  	public static function toLog():String
   324  	{
   325  		return "[Object MessageRouter]";
   326  	}
   327  	
   328  	/**
   329  	 *	Accès global au Singleton.
   330  	 */
   331  	public static function getInstance():MessageRouter
   332  	{
   333  		if(_instance == undefined) _instance = new MessageRouter();
   334  		return _instance;
   335  	}
   336  }
   337