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 EnvelopeFactory
    28  
    29  	@description :
    30  	Gestion de la création d'une enveloppe valide.
    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  			- Singleton
    41  			- string.substr(a-1, b) plutôt que substring(str, a, b)
    42  -------------------------------------------
    43  */
    44  
    45  import org.omus.msg.Message;
    46  import org.omus.msg.Envelope;
    47  
    48  /**
    49   *	Gère la création des  enveloppe au départ (OUT).
    50   *	Gère aussi l'interprétation d'enveloppes arrivée (IN).
    51   *
    52   *	Cette classe est implémentée en suivant le modèle Singleton.
    53   *	Un accès global à son instance est obtenu graçe à la méthode getInstance.
    54   *
    55   *	@author Jens Halm copyright http://www.spicefactory.org/
    56   *	@author erixtekila copyleft http://www.v-i-a.net 
    57   *	@version 1.2.0
    58   */
    59  class org.omus.msg.EnvelopeFactory
    60  {
    61  	//--------------------
    62  	// PROPRIETES
    63  	//--------------------
    64  	/**
    65  	 *	Identifiant de la prochaine enveloppe.
    66  	 */
    67  	private var nextMsgID:Number;
    68  	
    69  	/*
    70  	 *	Référence à l'unique instance de la classe permise.
    71  	 */
    72  	private static var _instance:EnvelopeFactory;
    73  	//--------------------
    74  	// CONSTRUCTEUR
    75  	//--------------------
    76  	/**
    77  	 *	Création d'enveloppe par l'intermédiaire de méthodes de validation.
    78  	 */
    79  	private function EnvelopeFactory()
    80  	{
    81  		nextMsgID = 1;
    82  		
    83  		// trace(this+ " installé.");
    84  	}
    85  	
    86  	//--------------------
    87  	// METHODES PUBLIQUES
    88  	//--------------------
    89  	/**
    90  	 *	Utilisé dans un contexte littéral
    91  	 *	@return	Une chaine définissant l'objet
    92  	 */
    93  	public function toString():String
    94  	{
    95  		return "[Object EnvelopeFactory]";
    96  	}
    97  	
    98  	/**
    99  	 *	Interprète et décode (Marshall) une enveloppe arrivée.
   100  	 *	
   101  	 *	@param str		La chaine encodée provenant du serveur.
   102  	 *	@return			Une enveloppe contenant le message décodé ou null si une erreur s'est produite lors du décodage.
   103  	 *
   104  	 *	@see Envelope
   105  	 *	@see Message
   106  	 */
   107  	public function getIncoming (str:String):Envelope
   108  	{
   109  		// split header:
   110  		var head = str.substr(0, 4);
   111  		var type = trimStr(str.substr(4, 12));
   112  		var msgID = parseInt(trimStr(str.substr(16, 4)));
   113  		var senderLen = parseInt(trimStr(str.substr(20, 3)));
   114  		var subjLen = parseInt(trimStr(str.substr(23, 3)));
   115  		var attachLen = parseInt(trimStr(str.substr(26, 6)));
   116  		
   117  		// error check
   118  		if (head != "#msg") {
   119  			// Logs internes
   120  			_global.oregano.iLog.error("clj-052","message = " + str);
   121  			return null;
   122  		}
   123  		if (isNaN(msgID)) {
   124  			// Logs internes
   125  			_global.oregano.iLog.error("clj-053","message = " + str);
   126  			return null;
   127  		}
   128  		if (isNaN(senderLen)) {
   129  			// Logs internes
   130  			_global.oregano.iLog.error("clj-054","message = " + str);
   131  			return null;
   132  		}
   133  		if (isNaN(subjLen)) {
   134  			// Logs internes
   135  			_global.oregano.iLog.error("clj-055","message = " + str);
   136  			return null;
   137  		}
   138  		if (isNaN(attachLen)) {
   139  			// Logs internes
   140  			_global.oregano.iLog.error("clj-056","message = " + str);
   141  			return null;
   142  		}
   143  		
   144  		// Message correctement formaté
   145  		// extract remaining parts:
   146  		// Envoyeur
   147  		var idx = 33; //dernier caractère avant sender+sujet
   148  		var sender = str.substr(idx-1, senderLen);
   149  		idx += senderLen;
   150  		// Sujet du message
   151  		var subject = str.substr(idx-1, subjLen);
   152  		idx += subjLen - 1;
   153  		
   154  		// check length of all parts
   155  		if (sender.length != senderLen) {
   156  			_global.oregano.iLog.error("clj-057","message = " + str);
   157  			return null;
   158  		}
   159  		if (subject.length != subjLen) {
   160  			_global.oregano.iLog.error("clj-058","message = " + str);
   161  			return null;
   162  		}
   163  		if (str.length - idx != attachLen) {
   164  			_global.oregano.iLog.error("clj-059","message = " + str);
   165  			return null;
   166  		}
   167  		
   168  		//** message split **\\ 
   169  		trace("##############");
   170  		trace("message démarshallisé :\nhead : "+head
   171  			  +"\ntype : "+type
   172  			  +"\nmsgID : "+msgID
   173  			  +"\nsender : "+sender
   174  			  +"\nsenderLen : "+senderLen
   175  			  +"\nsubject : "+subject
   176  			  +"\nsubjLen : "+subjLen
   177  			  +"\nattachLen : "+attachLen);
   178  		trace("##############");
   179  		
   180  		
   181  		// create envelope
   182  		var msg = new Message(subject);
   183  		msg.setSender(sender);
   184  		msg.setMarshalledAttachment(str, idx);
   185  		
   186  		return new Envelope(msg, type, null, msgID);
   187  	}
   188  		
   189  	/**
   190  	 *	Prépare une nouvelle enveloppe pour l'envoi.
   191  	 *	Cette méthode est systématiquement utilisée, ne pas instancier directement Envelope.
   192  	 *
   193  	 *	@see Envelope
   194  	 */
   195  	public function getOutgoing  (msg:Message, type:String, recp:String):Envelope
   196  	{
   197  		return new Envelope(msg, type, recp, getNextMsgID());
   198  	}
   199  	
   200  	//--------------------
   201  	// METHODES PRIVEES
   202  	//--------------------
   203  	/**
   204  	 *	Renvoie l'identifiant de la prochaine enveloppe.
   205  	 *
   206  	 *	@return		Un identifiant unique.
   207  	 */
   208  	private function getNextMsgID ():Number
   209  	{
   210  		if (nextMsgID >= 9999) nextMsgID = 1;
   211  		return nextMsgID++;
   212  	}
   213  	
   214  	/**
   215  	 *	Supprime les espaces en fin d'une chaine.
   216  	 *
   217  	 *	@param str		Chaine à découper.
   218  	 *	@return			La chaine découpée.
   219  	 */
   220  	private function trimStr (str:String):String
   221  	{
   222  		var len = str.length;
   223  		for (var i = 0; i < len; i++)
   224  		{
   225  			if (str.charAt(i) == " ") 
   226  			{
   227  				return str.substr(0, i);
   228  			}
   229  		}
   230  		return str;
   231  	}
   232  	
   233  	//--------------------
   234  	// METHODES STATIQUES
   235  	//--------------------
   236  	/**
   237  	 *	Utilisé dans un contexte littéral
   238  	 *	@return	Une chaine définissant l'objet
   239  	 */
   240  	public static function toLog():String
   241  	{
   242  		return "[Object EnvelopeFactory]";
   243  	}
   244  	
   245  	
   246  	/**
   247  	 *	Accès global à la référence du Singleton
   248  	 *
   249  	 *	@param cat		Le niveau de log.
   250  	 *	@return	Une référence à la classe
   251  	 */
   252  	public static function getInstance():EnvelopeFactory
   253  	{
   254  		if(_instance == undefined) _instance = new EnvelopeFactory();
   255  		return _instance;
   256  	}
   257  	
   258  }
   259