/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.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.4.4.8 $
 *          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();
   }
}
