/*
 * 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 org.jgroups.blocks.Xid;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Map;

/**
 *
 * @author Bela Ban
 * @version $Revision: 1.1.2.1 $
 */
public class Update implements Externalizable {
    static final int PUT=1;
    static final int PUT_ALL=2;
    static final int REMOVE=3;
    static final int CLEAR=4;

    /** Type of operation, one of PUT, PUT_ALL, REMOVE or CLEAR) */
    int operation=0;

    /** Used when operation == PUT or REMOVE. Needs to be serializable */
    Object key=null;

    /** Used when operation == PUT. Needs to be serializable */
    Object value=null;

    /** Used when operation == PUT_ALL. All keys and values need to be serializable */
    Map map=null;

    /** Update options */
    Options update_options=null;

    /** The transaction with which the update is associated */
    Xid transaction=null;

    /**
     * Constructor for Update. Needed by externalization
     */
    public Update() {
        super();
    }

    public Update(int operation) {
        this.operation=operation;
    }

    public Update(int operation, Options update_options) {
        this(operation);
        this.update_options=update_options;
    }

    public Update(int operation, Object key, Object value) {
        this(operation);
        this.key=key;
        this.value=value;
    }

    public Update(int operation, Object key, Object value, Options update_options) {
        this(operation, key, value);
        this.update_options=update_options;
    }

    public Update(int operation, Map map) {
        this(operation);
        this.map=map;
    }

    public Update(int operation, Map map, Options update_options) {
        this(operation, map);
        this.update_options=update_options;
    }


    /**
     * Returns the operation.
     * @return int
     */
    public int getOperation() {
        return operation;
    }

    /**
     * Sets the operation.
     * @param operation The operation to set
     */
    public void setOperation(int operation) {
        this.operation=operation;
    }

    /**
     * Returns the key.
     * @return Object
     */
    public Object getKey() {
        return key;
    }

    /**
     * Returns the map.
     * @return Map
     */
    public Map getMap() {
        return map;
    }

    /**
     * Returns the update_options.
     * @return Options
     */
    public Options getUpdateOptions() {
        return update_options;
    }

    /**
     * Returns the value.
     * @return Object
     */
    public Object getValue() {
        return value;
    }

    /**
     * Sets the key.
     * @param key The key to set
     */
    public void setKey(Object key) {
        this.key=key;
    }

    /**
     * Sets the map.
     * @param map The map to set
     */
    public void setMap(Map map) {
        this.map=map;
    }

    /**
     * Sets the update_options.
     * @param update_options The update_options to set
     */
    public void setUpdateOptions(Options update_options) {
        this.update_options=update_options;
    }

    /**
     * Sets the value.
     * @param value The value to set
     */
    public void setValue(Object value) {
        this.value=value;
    }

    /**
     * Returns the transaction.
     * @return Xid
     */
    public Xid getTransaction() {
        return transaction;
    }

    /**
     * Sets the transaction.
     * @param transaction The transaction to set
     */
    public void setTransaction(Xid transaction) {
        this.transaction=transaction;
    }


    /**
     * @see java.lang.Object#toString()
     */
    public String toString() {
        StringBuffer sb=new StringBuffer();
        sb.append(operationToString(operation));
        if(key != null)
            sb.append(", key=").append(key);
        if(value != null)
            sb.append(", value=").append(value);
        if(map != null)
            sb.append(", map=").append(map);
        if(update_options != null)
            sb.append(", update_options=").append(update_options);
        if(transaction != null)
            sb.append(", transaction=").append(transaction);
        return sb.toString();
    }

    String operationToString(int op) {
        switch(op) {
            case PUT:
                return "PUT";
            case PUT_ALL:
                return "PUT_ALL";
            case REMOVE:
                return "REMOVE";
            case CLEAR:
                return "CLEAR";
            default :
                return "<unknown>";
        }
    }


    /**
     * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
     */
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt(operation);
        out.writeObject(key);
        out.writeObject(value);
        out.writeObject(map);
        out.writeObject(transaction);
    }

    /**
     * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
     */
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        operation=in.readInt();
        key=in.readObject();
        value=in.readObject();
        map=(Map)in.readObject();
        transaction=(Xid)in.readObject();
    }


}
