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 UpdateSequence
    28  
    29  	@description :
    30  	Gère la mise à jour des données d'une Table.
    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 : 17/01/05
    38  			- Portage en actionscript 2 pour le
    39  			compile time type checking
    40  -------------------------------------------
    41  */
    42  
    43  import org.omus.data.TableDefinition;
    44  import org.omus.data.Table;
    45  import org.omus.data.ClearTable;
    46  import org.omus.data.RemoveRow;
    47  import org.omus.data.UpdateRow;
    48  import org.omus.data.AddRow;
    49  import org.omus.data.DataTransformer;
    50  
    51  /**
    52   *	Se charge de mettre à jour uniquement des données d'une Table ayant été modifiées.
    53   *	Facade de petites classes représentant des portions de la séquence de mise à jour.
    54   *
    55   *	@see org.omus.data.ClearTable
    56   *	@see org.omus.data.RemoveRow
    57   *
    58   *	@author Jens Halm copyright http://www.spicefactory.org/
    59   *	@author erixtekila copyleft http://www.v-i-a.net 
    60   *	@version 1.2.0
    61   */
    62  class org.omus.data.UpdateSequence
    63  {
    64  	//--------------------
    65  	// PROPRIETES
    66  	//--------------------
    67  	/**
    68  	 *	Liste des propriétés à rajouter ou supprimer.
    69  	 */
    70  	public var addOrRemove:Array;
    71  	
    72  	/**
    73  	 *	Tableau associatif des mises à jours.
    74  	 */
    75  	public var updates:Object;
    76  	
    77  	/**
    78  	 *	Référence à TableDefinition.
    79  	 */
    80  	private var def:TableDefinition;
    81  	
    82  	/**
    83  	 *	Constante.
    84  	 */
    85  	public static var CLEAR_TABLE:Number = 0;
    86  	
    87  	/**
    88  	 *	Constante.
    89  	 */
    90  	public static var REMOVE_ROW:Number = 1;
    91  	
    92  	/**
    93  	 *	Constante.
    94  	 */
    95  	public static var ADD_ROW:Number = 2;
    96  	
    97  	/**
    98  	 *	Constante.
    99  	 */
   100  	public static var UPDATE_ROW:Number = 3;
   101  	
   102  	//--------------------
   103  	// CONSTRUCTEUR
   104  	//--------------------
   105  	/**
   106  	 *	Ne devrait pas être utilisé en dehors de la création d'une Table.
   107  	 */
   108  	public function UpdateSequence(def:TableDefinition)
   109  	{
   110  		// trace(this+ " installé.");
   111  		
   112  		def = def; // undefined in incoming UpdateSequence, will be set in execute()
   113  		reset();
   114  	}
   115  	
   116  	//--------------------
   117  	// METHODES PUBLIQUES
   118  	//--------------------
   119  	/**
   120  	 *	Utilisé dans un contexte littéral
   121  	 *	@return	Une chaine définissant l'objet
   122  	 */
   123  	public function toString ():String
   124  	{
   125  		return format(0);
   126  	}
   127  	
   128  	/**
   129  	 *	Définit et renvoie un nouvel objet UpdateSequence à partir des propriétés de celui-ci.
   130  	 *	TODO : utilisation ? cf MarshalledProperties
   131  	 *
   132  	 *	@return		Une nouvelle UpdateSequence basée sur celle-ci.
   133  	 *	@see org.omus.data.MarshalledProperties
   134  	 */
   135  	public function clear ():UpdateSequence
   136  	{
   137  		var us = new UpdateSequence(def);
   138  		us.addOrRemove = addOrRemove;
   139  		us.updates = updates;
   140  		reset();
   141  		return us;
   142  	}
   143  	
   144  	//*** recording & unmarshalling ***\\
   145  	/**
   146  	 *	Supprime les enregistrements de la Table.
   147  	 */
   148  	public function clearTable ():Void
   149  	{
   150  		addOrRemove = new Array();
   151  		updates = new Object();
   152  		addOrRemove.push(new ClearTable());
   153  	}
   154  	
   155  	/**
   156  	 *	Supprime un enregistrement.
   157  	 *
   158  	 *	@param rowID		Identifiant de l'enregistrement.
   159  	 */
   160  	public function removeRow (rowID:Number):Void
   161  	{
   162  		delete updates["r" + rowID];
   163  		if (checkIfRemoved(rowID))
   164  		{
   165  			// Logs internes
   166  			_global.oregano.iLog.error("clj-037","");
   167  			return;
   168  		}
   169  		addOrRemove.push(new RemoveRow(rowID));
   170  	}
   171  	
   172  	/**
   173  	 *	Met à jour un enregistrement.
   174  	 *
   175  	 *	@param rowID		Identifiant de la ligne.
   176  	 *	@param row			Enregistrement.
   177  	 */
   178  	public function updateRow (rowID:Number, row:Object):Void
   179  	{
   180  		//!! TODO : ur.rowID n'est pas défini !!
   181  		//!! TODO : Syntaxe !! if (checkIfRemoved(ur.rowID)) 
   182  		if (checkIfRemoved(rowID))
   183  		{
   184  			// Logs internes
   185  			_global.oregano.iLog.error("clj-038","");
   186  			return;
   187  		}
   188  		// TODO : Accès Singleton
   189  		var transformer = DataTransformer.getInstance ();
   190  		var marshRow = transformer.marshal_row(row, def);
   191  		updates["r" + rowID] = new UpdateRow(rowID, marshRow); // overwrites older updates of same row
   192  	}
   193  	
   194  	/**
   195  	 *	Rajoute un enregistrement.
   196  	 *
   197  	 *	@param row		Référence à l'enregistrement.
   198  	 */
   199  	public function addRow (row:Object):Void
   200  	{
   201  		// TODO : Accès Singleton.
   202  		var transformer = DataTransformer.getInstance();
   203  		var marshRow = transformer.marshal_row(row, def);
   204  		addOrRemove.push(new AddRow(0, marshRow));
   205  	}
   206  	//*** fin recording & unmarshalling ***\\
   207  	
   208  	//*** marshalling ***\\
   209  	/**
   210  	 *	Encodage.
   211  	 *
   212  	 *	@return		Une chaîne encodée.
   213  	 */
   214  	public function getMarshalledSequence ():String
   215  	{
   216  		var s = "#x";
   217  		var aor = addOrRemove;
   218  		var cnt = aor.length;
   219  		// ADD or REMOVE encodage.
   220  		for (var i = 0; i < cnt; i++)
   221  		{
   222  			s += aor[i].getMarshalledSequence();
   223  		}
   224  		// Updates Encodage
   225  		var up = this.updates;
   226  		for (var each:String in up) {
   227  			s += up[each].getMarshalledSequence();
   228  			cnt++;
   229  		}
   230  		s += "#z";
   231  		return "#u" + cnt + s;
   232  	}	
   233  
   234  	//*** execution ***\\\
   235  	/**
   236  	 *	Initialisation des valeurs de la Table à mettre à jour.
   237  	 *
   238  	 *	@param table		Référence à la Tbale à mettre à jour.
   239  	 *	@param clientReq	true si c'est le client qui effectue la requette, false si cela vient d'un autre utilisateur.
   240  	 */
   241  	public function execute (table:Table, clientReq:Boolean):Void
   242  	{
   243  		def = table.getDefinition();
   244  		table.enableRecording(false); // may be obsolete
   245  		// ADD or REMOVE
   246  		var aor = addOrRemove;
   247  		var long = aor.length;
   248  		for (var i = 0; i < long ; i++)
   249  		{
   250  			// Amorçe toutes les portions de la séquence de mise à jour.
   251  			aor[i].execute(table, clientReq);
   252  		}
   253  		// UPDATE
   254  		var upd = updates;
   255  		for (var each:String in upd) {
   256  			upd[each].execute(table, clientReq);
   257  		}
   258  		
   259  		table.enableRecording(true); // may be obsolete
   260  	}
   261  	
   262  	//--------------------
   263  	// METHODES PRIVEES
   264  	//--------------------
   265  	/**
   266  	 *	Réinitialisation.
   267  	 */
   268  	private function reset ():Void
   269  	{
   270  		addOrRemove = new Array();
   271  		updates = new Object();
   272  	}
   273  	
   274  	/**
   275  	 *	Vérifie le bon effacement de données à supprimer.
   276  	 *
   277  	 *	@param rowID		Identifiant de l'enregistrement.
   278  	 *	@return				Un boolean selon le résultat de l'opération.
   279  	 */
   280  	private function checkIfRemoved (rowID:Number):Boolean
   281  	{
   282  		var aor = addOrRemove;
   283  		for (var i = aor.length; i >= 0 ; i--)
   284  		{
   285  			var up = aor[i];
   286  			if ((up instanceof org.omus.data.RemoveRow) && up.rowID == rowID) 
   287  			{
   288  				return true;
   289  			}
   290  		}
   291  		return false;
   292  	}
   293  	
   294  	/**
   295  	 *	Renvoie une chaîne de présenattion de l'objet.
   296  	 */
   297  	private function format (indent:Number):String
   298  	{
   299  		var s= "org.omus.data.UpdateSequence:";
   300  		var arr = addOrRemove;
   301  		var len = arr.length;
   302  		for (var i = 0; i < len; i++)
   303  		{
   304  			s += "\n";
   305  			for (var idx = 0; idx < indent; idx++) s += "  ";
   306  			s += "UpdatePart = " + arr[i].format(indent+1);
   307  		}
   308  		
   309  		var map = updates;
   310  		for (var each:String in map) {
   311  			s += "\n";
   312  			for (var idx = 0; idx < indent; idx++) s += "  ";
   313  			s += "UpdatePart = " + map[each].format(indent+1);
   314  		}
   315  		return s;
   316  	}
   317  	
   318  	//--------------------
   319  	// METHODES STATIQUES
   320  	//--------------------
   321  	/**
   322  	 *	Utilisé dans un contexte littéral
   323  	 *	@return	Une chaine définissant l'objet
   324  	 */
   325  	public static function toLog():String
   326  	{
   327  		return "[Object UpdateSequence]";
   328  	}
   329  }
   330