/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache;


import java.io.Serializable;
import java.util.Map;


/**
 * Represents a modification in the cache. Contains the nature of the modification
 * (e.g. PUT, REMOVE), the fqn of the node, the new value and the previous value.
 * A list of modifications will be sent to all nodes in a cluster when a transaction
 * has been committed (PREPARE phase). A Modification is also used to roll back changes,
 * e.g. since we know the previous value, we can reconstruct the previous state by
 * applying the changes in a modification listin reverse order.
 *
 * @author <a href="mailto:bela@jboss.org">Bela Ban</a> Apr 12, 2003
 * @version $Revision: 1.9.4.2 $
 *          todo: implement Externalizable
 */
public class Modification implements Serializable {
   public static final int PUT_KEY_VALUE=1;
   public static final int PUT_DATA=2;
   public static final int PUT_DATA_ERASE=3;
   public static final int REMOVE_NODE=4;
   public static final int REMOVE_KEY_VALUE=5;
   public static final int REMOVE_DATA=6;

   int     type=0;
   Fqn     fqn=null;
   Object  key=null;
   Object  value=null;
   Object  old_value=null;
   Map     data=null;
   Map     old_data=null;


   public Modification() {
      ;
   }

   public Modification(int type, Fqn fqn, Object key,
                       Object value, Object old_value,
                       Map data, Map old_data) {
      this.type=type;
      this.fqn=fqn;
      this.key=key;
      this.value=value;
      this.old_value=old_value;
      this.data=data;
      this.old_data=old_data;
   }

   public Modification(int type, Fqn fqn, Object key, Object value) {
      this.type=type;
      this.fqn=fqn;
      this.key=key;
      this.value=value;
   }

   public Modification(int type, Fqn fqn, Object key) {
      this.type=type;
      this.fqn=fqn;
      this.key=key;
   }

   public Modification(int type, Fqn fqn, Map data) {
      this.type=type;
      this.fqn=fqn;
      this.data=data;
   }

   public Modification(int type, Fqn fqn) {
      this.type=type;
      this.fqn=fqn;
   }


   public int getType() {
      return type;
   }

   public void setType(int type) {
      this.type=type;
   }

   public Fqn getFqn() {
      return fqn;
   }

   public void setFqn(Fqn fqn) {
      this.fqn=fqn;
   }

   public Object getKey() {
      return key;
   }

   public void setKey(Object key) {
      this.key=key;
   }

   public Object getValue() {
      return value;
   }

   public void setValue(Object value) {
      this.value=value;
   }

   public Object getOldValue() {
      return old_value;
   }

   public void setOldValue(Object old_value) {
      this.old_value=old_value;
   }

   public Map getData() {
      return data;
   }

   public void setData(Map data) {
      this.data=data;
   }

   public Map getOldData() {
      return old_data;
   }

   public void setOldData(Map old_data) {
      this.old_data=old_data;
   }


   String typeToString(int type) {
      switch(type) {
         case PUT_KEY_VALUE:
            return "PUT_KEY_VALUE";
         case PUT_DATA:
            return "PUT_DATA";
         case PUT_DATA_ERASE:
            return "PUT_DATA_ERASE";
         case REMOVE_NODE:
            return "REMOVE_NODE";
         case REMOVE_KEY_VALUE:
            return "REMOVE_KEY_VALUE";
         case REMOVE_DATA:
            return "REMOVE_DATA";
         default:
            return "<unknown>";
      }
   }

   public String toString() {
      StringBuffer sb=new StringBuffer();
      sb.append(typeToString(type)).append(": ").append(fqn);
      if(key != null)
         sb.append("\nkey=").append(key);
      if(value != null)
         sb.append("\nvalue=").append(value);
      if(old_value != null)
         sb.append("\nold_value=").append(old_value);
      if(data != null)
         sb.append("\ndata=").append(data);
      if(old_data != null)
         sb.append("\nold_data=").append(old_data);
      return sb.toString();
   }
}