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