001//
002// Name
003//  $RCSfile: CompensationTrigger.java,v $
004// 
005//      Copyright 2009-2013 Cloud Software Group, Inc. ALL RIGHTS RESERVED.
006//      Cloud Software Group, Inc. Confidential Information
007//
008// History
009//  $Revision: 1.1.2.4 $ $Date: 2013/04/10 22:16:40 $
010//
011
012package com.kabira.platform;
013
014import java.io.ObjectInputStream;
015
016/**
017 * Indicate that this class implements a compensation trigger.
018 * Compensation triggers are invoked on the active node for an instance
019 * when a conflict has been detected when restoring a node, and the
020 * JOIN_CLUSTER_RESTORE enable action is used. This interface can only
021 * be implemented by Managed types.
022 */
023public interface CompensationTrigger
024{
025    /**
026     * Possible conflicts that are detected.
027     */
028    enum ConflictType
029    {
030        /**
031         * The same instance exists on the remote node, and updates have
032         * been applied to either the active node or the remote node,
033         * resulting in a conflict.
034         */
035        STATE_CONFLICT,
036        /**
037         * A different instance exists on the remote node with the same key
038         * indexes. 
039         */
040        KEY_CONFLICT,
041        /**
042         * The instance exists on the remote node but does not exist on the
043         * active node.
044         */
045        ADDED_INSTANCE
046    }
047
048    /**
049     * The conflict information passed into the uponConflict() trigger.
050     */
051    public class ConflictInfo
052    {
053        /**
054         * Get the conflict type.
055         * @return Enumeration containing conflict type.
056         */
057        public ConflictType getConflictType()
058        {
059            return m_conflictType;
060        }
061
062        /**
063         * Returns whether the remote class was mismatched.
064         *
065         * If true, the Managed class on the remote node differs from the
066         * class on the local node. In this case, the stream should be
067         * decoded with the assumption that fields in the local class may not
068         * be present in the stream. It is recommended that applications use
069         * the java.io.ObjectInputStream.GetField class to access the data,
070         * and catch IllegalArgumentException for missing fields.
071         *
072         * @return true if the remote class was mismatched.
073         * @see ObjectMismatchTrigger
074         */
075        public boolean isMismatched()
076        {
077            return m_isMismatched;
078        }
079        
080        //
081        // Package private
082        //
083        ConflictInfo(int conflictType, boolean isMismatched)
084        {
085            m_conflictType = ConflictType.values()[conflictType];
086            m_isMismatched = isMismatched;
087        }
088
089        //
090        // Private vars
091        //
092        private ConflictType    m_conflictType;
093        private boolean         m_isMismatched;
094    }
095
096    /**
097     * Compensation trigger callback method.
098     *
099     * The conflictedDataStream is a Serializable stream containing the
100     * object data from the remote node. To access the data, see the
101     * documentation for the java.io.ObjectInputStream class.
102     *
103     * @param conflictInfo Information for this conflict.
104     * @param conflictedDataStream The conflicting instance serialized
105     *      into a Stream. Will be null for
106     *      {@link ConflictType#ADDED_INSTANCE}.
107     */
108    public void uponConflict(
109        ConflictInfo conflictInfo,
110        ObjectInputStream conflictedDataStream);
111}