Package Express.services

Source Code of Express.services.ConcurrencyMgr

package Express.services;

import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Hashtable;

import org.apache.log4j.Logger;

import Framework.Constants;
import Framework.ErrorMgr;
import Framework.EventManager;
import Framework.ImplementationException;
import Framework.IntegerData;
import Framework.RemoteEvent;
import Framework.RemoteEventProxy;
import Framework.RuntimeProperties;
import Framework.ServiceObjectContext;
import Framework.TextData;
import Framework.anchored.Anchorable;
import Framework.anchored.AnchoredProxy;
import Framework.anchored.ServiceInvoker;
import Framework.remoting.parameters.CopyInput;
import Framework.remoting.parameters.Input;

/**
* The ConcurrencyMgr class is an internal class and none of its members are documented, except for some of its constants, which are used by two BusinessClient methods: Select and Update.
* <p>
* @author ITerative Consulting
* @since  26-Feb-2008
*/
@SuppressWarnings("deprecation")
@RuntimeProperties(isDistributed=true, isAnchored=true, isShared=true, isTransactional=false)
public class ConcurrencyMgr
        implements Serializable, Anchorable
{

    // ---------
    // Constants
    // ---------
    public static final int CA_NONE = 0;
    public static final int CA_WRITETHRU = 1;
    public static final int CO_DB_EXPLICIT = 3;
    public static final int CO_DB_NATIVE = 1;
    public static final int CO_MASK_CUSTOM = 8;
    public static final int CO_MASK_DB = 1;
    public static final int CO_MASK_LOCK = 2;
    public static final int CO_MASK_OPTIMISTIC = 4;
    public static final int CO_NONE = 0;
    public static final int CO_OPT_EXPRESS = 20;
    public static final int CO_OPT_VERIFY = 4;
    public static final int TR_CONTINUE = 0;
    public static final int TR_END = 2;
    public static final int TR_SINGLETON = 3;
    public static final int TR_START = 1;
    public static final int TRACE_COMMIT = 30;
    public static final int TRACE_ID = 1;
    public static final int TRACE_LOAD = 50;
    public static final int TRACE_READY = 40;
    public static final int TRACE_ROLLBACK = 20;
    public static final int TRACE_START = 60;
    public static final int TS_ACTIVE = 1;
    public static final int TS_INACTIVE = 0;

    // ----------
    // Attributes
    // ----------
    private int cacheMode;
    private int cacheSize;
    private int concurrencyMode;
    private int freeUserCBhead;
    private ConcurrencyKeys keys;
    private int oldestTimeIndex;
    private int timeIndex;
    private Trace trace;
    private int updateDelay;
    private Array_Of_ConcurrencyUserCB<ConcurrencyUserCB> users;
    /**
     * The flag to use for "isAnchored" and the listener for remote requests
     */
    protected ServiceInvoker invoker = null;

    // ------------
    // Constructors
    // ------------
    public ConcurrencyMgr() {
        this(true);

        this.setTrace(new Trace());
        this.getTrace().setDefaultServiceID(Constants.SP_ST_EX);

        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_INIT, 1, this, "Init")) {
            Logger.getLogger("task.part.logmgr").info("Address = ");
            Logger.getLogger("task.part.logmgr").info(this);
        }

    }

    public ConcurrencyMgr(ServiceObjectContext pContext) {
    }

    public ConcurrencyMgr(boolean pIsAnchored) {
        this.setIsAnchored(pIsAnchored);
    }

    // ----------------------
    // Accessors and Mutators
    // ----------------------
    public synchronized int getCacheMode() {
        return this.cacheMode;
    }

    public synchronized int getConcurrencyMode() {
        return this.concurrencyMode;
    }

    public synchronized void setFreeUserCBhead(int freeUserCBhead) {
        this.freeUserCBhead = freeUserCBhead;
    }

    public synchronized int getFreeUserCBhead() {
        return this.freeUserCBhead;
    }

    public synchronized void setTrace(Trace trace) {
        this.trace = trace;
    }

    public synchronized Trace getTrace() {
        return this.trace;
    }

    public boolean getIsAnchored() {
        return invoker != null;
    }

    public void setIsAnchored(boolean isAnchored) {
        if (isAnchored && invoker == null) {
            // Anchor the object, creating an invoker for it.
            this.invoker = new ServiceInvoker(this);
        }
        else if (!isAnchored && invoker != null) {
            this.invoker = null;
        }
    }

    /**
     * Get the invoker for this class. This method should only be called from the proxy, hence the protected level visibility.
     */
    protected ServiceInvoker getInvoker(ConcurrencyMgr pService) {
        return pService.invoker;
    }

    // -------
    // Methods
    // -------
    /**
     * commitTrans<p>
     * <p>
     * @param clientID Type: int
     * @param transactionMode Type: int
     */
    public synchronized void commitTrans(@CopyInput int clientID, @CopyInput int transactionMode) {
        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_CM, ConcurrencyMgr.TRACE_COMMIT, this, "CommitTrans")) {
            Logger.getLogger("task.part.logmgr").info("clientID = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(clientID));
            Logger.getLogger("task.part.logmgr").info(", transactionMode = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(transactionMode));
        }

        ConcurrencyUserCB userCB = this.getUserCB(clientID);

        if (userCB.getStamp() == 0) {

            throw new Error(Error.CM_NO_TRANSACTION, "CommitTrans", this, new IntegerData(clientID), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();

        }
        else {

            userCB.setStamp(this.getTimestamp());

            Array_Of_ConcurrencyKeyCB<ConcurrencyKeyCB> qq_localVector = userCB.getLockedKeys();
            if (qq_localVector != null) {
                for (ConcurrencyKeyCB keyCB : qq_localVector) {

                    keyCB.setLocked(false);
                    keyCB.setStamp(userCB.getStamp());
                    keyCB.setUpdateStamp(userCB.getStamp());

                }
            }

            userCB.setLockedKeys(null);

            if ((transactionMode&ConcurrencyMgr.TR_END) > 0) {
                this.endTrans(userCB);
            }

        }
    }

    /**
     * endTrans<p>
     * <p>
     * @param userCB Type: ConcurrencyUserCB
     */
    private synchronized void endTrans(@Input ConcurrencyUserCB userCB) {
        Array_Of_ConcurrencyKeyCB<ConcurrencyKeyCB> qq_localVector = userCB.getKeys();
        if (qq_localVector != null) {
            for (ConcurrencyKeyCB keyCB : qq_localVector) {
                this.keys.drop(keyCB, this.oldestTimeIndex);
            }
        }

        //
        //  We need to keep certain information for all transactions currently active.
        //  This is identified by the attribute OldestTimeIndex.  Everything since
        //  then needs to be saved.  If we are ending the transaction that started
        //  at OldestTimeIndex it (OldestTimeIndex) is now older than it needs to
        //  be.  The problem is figuring out the new OldestTimeIndex.  It requires
        //  looking at every transaction.  We don't want to do that too often, and
        //  it doesn't hurt to have OldestTimeIndex a little older than it needs to
        //  be, we will just use a little more memory saving things we don't need to.
        //  So we delay Updating the OldestTimeIndex until we've committed as many
        //  transactions as we have room in the cache.  Then we scan the Users table
        //  and look for the oldest transaction currently active.
        //
        if (userCB.getStamp() == this.oldestTimeIndex || this.updateDelay > 0) {
            this.updateDelay = this.updateDelay+1;
            if (this.updateDelay > this.cacheSize) {
                this.updateDelay = 0;
                userCB.setStamp(0);
                this.oldestTimeIndex = 2147483647;
                // 2**31-1
                if (this.users != null) {
                    for (ConcurrencyUserCB u : this.users) {
                        if ((u.getStamp() > 0) && (u.getStamp() < this.oldestTimeIndex)) {
                            this.oldestTimeIndex = u.getStamp();
                        }
                    }
                }
                if (this.oldestTimeIndex == 2147483647) {
                    //
                    //  Since we seem to have no active transactions right now we'll
                    //  have set update delay now to start the counter going until
                    //  we check again.
                    //
                    this.updateDelay = 1;
                }
            }
        }

        userCB.setStamp(0);
        userCB.setKeys(null);
    }

    /**
     * fetch<p>
     * <p>
     * @param key Type: BusinessKey
     * @return BusinessClass
     */
  public synchronized BusinessClass fetch(@Input BusinessKey key) {
        ImplementationException e = new ImplementationException();

        e.setWithParams(Constants.SP_ER_ERROR, new TextData("The method Cache.Fetch is unimplemented."));
        ErrorMgr.addError(e);

        throw e;
    }

    // Method GetCacheMode() : integer skipped because it is replaced by accessor / mutator.
    /**
     * getClientID<p>
     * <p>
     * @return int
     */
    public synchronized int getClientID() {
        if (this.users == null) {
            this.setup();
        }

        ConcurrencyUserCB userCB = null;
        int id = this.getFreeUserCBhead();

        if (id == ConcurrencyUserCB.END_OF_LIST) {
            userCB = new ConcurrencyUserCB();
            userCB.setNext(ConcurrencyUserCB.IN_USE);
            this.users.add(userCB);
            id = this.users.size();
        }
        else {
            userCB = this.users.get(this.getFreeUserCBhead()-1);
            this.setFreeUserCBhead(userCB.getNext());
            userCB.initialise();
            userCB.setNext(ConcurrencyUserCB.IN_USE);
        }

        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_CM, ConcurrencyMgr.TRACE_ID, this, "GetClientID")) {
            Logger.getLogger("task.part.logmgr").info("clientID = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(id));
        }

        return id;
    }

    // Method GetConcurrencyMode() : integer skipped because it is replaced by accessor / mutator.
    /**
     * getTimestamp<p>
     * <p>
     * @return int
     */
    private synchronized int getTimestamp() {
        this.timeIndex = this.timeIndex+1;

        return this.timeIndex;
    }

    /**
     * getUserCB<p>
     * <p>
     * @param clientID Type: int
     * @return ConcurrencyUserCB
     */
    private synchronized ConcurrencyUserCB getUserCB(@Input int clientID) {
        if (clientID <= 0 || clientID > this.users.size()) {

            throw new Error(Error.CM_ILLEGAL_CLIENT_ID, "GetUserCB", this, new IntegerData(clientID), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();

        }
        else {

            ConcurrencyUserCB userCB = this.users.get(clientID-1);

            if (userCB.getNext() != ConcurrencyUserCB.IN_USE) {
                throw new Error(Error.CM_ILLEGAL_CLIENT_ID, "GetUserCB", this, new IntegerData(clientID), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();
            }

            return userCB;

        }
    }

    /**
     * load<p>
     * <p>
     * @param clientID Type: int
     * @param transactionMode Type: int
     * @param source Type: Array_Of_BusinessKey<BusinessKey>
     */
    public synchronized void load(@CopyInput int clientID, @CopyInput int transactionMode, @CopyInput Array_Of_BusinessKey<BusinessKey> source) {
        ConcurrencyUserCB userCB = this.getUserCB(clientID);

        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_CM, ConcurrencyMgr.TRACE_LOAD, this, "Load")) {
            Logger.getLogger("task.part.logmgr").info("clientID = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(clientID));
            Logger.getLogger("task.part.logmgr").info(", transactionMode = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(transactionMode));
            Logger.getLogger("task.part.logmgr").info(", keys = ");
            if (source != null) {
                for (BusinessKey i : source) {
                    Logger.getLogger("task.part.logmgr").info(i.asTextData());
                    Logger.getLogger("task.part.logmgr").info(", ");
                }
            }
            Logger.getLogger("task.part.logmgr").info("");
        }

        if (userCB.getStamp() == 0) {

            throw new Error(Error.CM_NO_TRANSACTION, "Load", this, new IntegerData(clientID), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();

        }
        else {

            ConcurrencyKeyCB keyCB = null;

            if (source != null) {
                for (BusinessKey i : source) {

                    keyCB = this.keys.get(i);

                    if (keyCB == null) {
                        keyCB = new ConcurrencyKeyCB();
                        keyCB.setKey(i);
                        keyCB.setStamp(userCB.getStamp());
                        this.keys.add(keyCB);
                    }
                    else if (keyCB.getStamp() > userCB.getStamp() && keyCB.getUpdateStamp() == 0 && !(keyCB.getLocked())) {
                        //
                        //  This is one case in which we can safely back up the timestamp
                        //  associated with the record.  If we don't do this then we won't
                        //  be able to update it eventhough it is the same in the DB as
                        //  what we selected.  The fact the someone with a later starting
                        //  transacton timestamp selected it first would spoof us. 
                        //  NOTE:  doing this requires that we not remove keyCBs that have
                        //  been updated until all transactions started before the update
                        //  have completed.
                        //
                        keyCB.setStamp(userCB.getStamp());
                    }

                    userCB.getKeys().add(keyCB);
                    keyCB.setCount(keyCB.getCount()+1);

                }
            }

        }
    }

    /**
     * load<p>
     * <p>
     * @param clientID Type: int
     * @param transactionMode Type: int
     * @param source Type: Array_Of_BusinessClass<BusinessClass>
     */
    public synchronized void load(@CopyInput int clientID, @CopyInput int transactionMode, @CopyInput Array_Of_BusinessClass<BusinessClass> source) {
        ConcurrencyUserCB userCB = this.getUserCB(clientID);

        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_CM, ConcurrencyMgr.TRACE_LOAD, this, "Load")) {
            Logger.getLogger("task.part.logmgr").info("clientID = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(clientID));
            Logger.getLogger("task.part.logmgr").info(", transactionMode = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(transactionMode));
            Logger.getLogger("task.part.logmgr").info(", keys = ");
            if (source != null) {
                for (BusinessClass i : source) {
                    Logger.getLogger("task.part.logmgr").info(i.getInstanceKey().asTextData());
                    Logger.getLogger("task.part.logmgr").info(", ");
                }
            }
            Logger.getLogger("task.part.logmgr").info("");
        }

        if (userCB.getStamp() == 0) {

            throw new Error(Error.CM_NO_TRANSACTION, "Load", this, new IntegerData(clientID), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();

        }
        else {

            ConcurrencyKeyCB keyCB = null;

            if (source != null) {
                for (BusinessClass i : source) {

                    keyCB = this.keys.get(i.getInstanceKey());

                    if (keyCB == null) {
                        keyCB = new ConcurrencyKeyCB();
                        keyCB.setKey(i.getInstanceKey());
                        keyCB.setObj(i);
                        keyCB.setStamp(userCB.getStamp());
                        this.keys.add(keyCB);
                    }
                    else if (keyCB.getStamp() > userCB.getStamp() && keyCB.getUpdateStamp() == 0 && !(keyCB.getLocked())) {
                        //
                        //  This is one case in which we can safely back up the timestamp
                        //  associated with the record.  If we don't do this then we won't
                        //  be able to update it eventhough it is the same in the DB as
                        //  what we selected.  The fact the someone with a later starting
                        //  transacton timestamp selected it first would spoof us. 
                        //  NOTE:  doing this requires that we not remove keyCBs that have
                        //  been updated until all transactions started before the update
                        //  have completed.
                        //
                        keyCB.setStamp(userCB.getStamp());
                    }

                    userCB.getKeys().add(keyCB);
                    keyCB.setCount(keyCB.getCount()+1);

                }
            }

        }
    }

    /**
     * readyToCommit<p>
     * <p>
     * @param clientID Type: int
     * @param transactionMode Type: int
     * @param source Type: Array_Of_BusinessKey<BusinessKey>
     */
    public synchronized void readyToCommit(@CopyInput int clientID, @CopyInput int transactionMode, @CopyInput Array_Of_BusinessKey<BusinessKey> source) {
        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_CM, ConcurrencyMgr.TRACE_READY, this, "ReadyToCommit")) {
            Logger.getLogger("task.part.logmgr").info("clientID = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(clientID));
            Logger.getLogger("task.part.logmgr").info(", transactionMode = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(transactionMode));
        }

        ConcurrencyUserCB userCB = this.getUserCB(clientID);

        if (userCB.getStamp() == 0) {

            userCB.setStamp(this.getTimestamp());
            userCB.setKeys(new Array_Of_ConcurrencyKeyCB<ConcurrencyKeyCB>());

            if (source.size() <= 0) {
                return;
                //  efficiency for updates that are just inserts.
            }
            else {
                //  This allows Updates that are singletons.
                //raise Error(Originator=self, MethodName='ReadyToCommit', Error=Error.CM_NO_TRANSACTION, Param1=IntegerData(value=clientID)).GetException;
            }

        }

        ConcurrencyKeyCB keyCB = null;

        userCB.setLockedKeys(new Array_Of_ConcurrencyKeyCB<ConcurrencyKeyCB>());

        if (source != null) {
            for (BusinessKey key : source) {

                keyCB = this.keys.get(key);

                if (keyCB == null) {
                    keyCB = new ConcurrencyKeyCB();
                    keyCB.setKey(key);
                    keyCB.setStamp(userCB.getStamp());
                    this.keys.add(keyCB);
                }

                if (keyCB.getLocked() || keyCB.getStamp() > userCB.getStamp()) {
                    Array_Of_ConcurrencyKeyCB<ConcurrencyKeyCB> qq_localVector = userCB.getLockedKeys();
                    if (qq_localVector != null) {
                        for (ConcurrencyKeyCB k : qq_localVector) {
                            k.setLocked(false);
                        }
                    }
                    userCB.setLockedKeys(null);
                    this.endTrans(userCB);
                    throw new Error(Error.CM_CLASS_CHANGED, "ReadyToCommit", this, key, Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();
                }

                userCB.getLockedKeys().add(keyCB);
                keyCB.setLocked(true);

            }
        }

        userCB.setStamp(this.getTimestamp());
    }

    /**
     * relClientID<p>
     * <p>
     * @param clientID Type: int
     */
    public synchronized void relClientID(@CopyInput int clientID) {
        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_CM, ConcurrencyMgr.TRACE_ID, this, "RelClientID")) {
            Logger.getLogger("task.part.logmgr").info("clientID = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(clientID));
        }

        ConcurrencyUserCB userCB = this.getUserCB(clientID);

        this.endTrans(userCB);

        userCB.setNext(this.getFreeUserCBhead());
        this.setFreeUserCBhead(clientID);
    }

    /**
     * rollback<p>
     * <p>
     * @param clientID Type: int
     * @param transactionMode Type: int (Copy Input) (default in Forte: 0)
     */
    public synchronized void rollback(@CopyInput int clientID, @CopyInput int transactionMode) {
        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_CM, ConcurrencyMgr.TRACE_ROLLBACK, this, "Rollback")) {
            Logger.getLogger("task.part.logmgr").info("clientID = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(clientID));
            Logger.getLogger("task.part.logmgr").info(", transactionMode = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(transactionMode));
        }

        ConcurrencyUserCB userCB = this.getUserCB(clientID);

        if (userCB.getStamp() == 0) {

            throw new Error(Error.CM_NO_TRANSACTION, "Rollback", this, new IntegerData(clientID), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();

        }
        else {

            Array_Of_ConcurrencyKeyCB<ConcurrencyKeyCB> qq_localVector = userCB.getLockedKeys();
            if (qq_localVector != null) {
                for (ConcurrencyKeyCB keyCB : qq_localVector) {

                    keyCB.setLocked(false);

                }
            }

            userCB.setLockedKeys(null);

            if ((transactionMode&ConcurrencyMgr.TR_END) > 0) {
                this.endTrans(userCB);
            }

        }
    }

    /**
     * qq_setCacheMode<p>
     * Method renamed by jcTOOL from SetCacheMode to qq_setCacheMode
     * because it conflicted with an attribute<p>
     * <p>
     * @param mode Type: int
     */
    public synchronized void qq_setCacheMode(@Input int mode) {
        switch (mode) {

            case ConcurrencyMgr.CA_NONE: {
                this.cacheMode = ConcurrencyMgr.CA_NONE;

                break;
            }
            case ConcurrencyMgr.CA_WRITETHRU: {
                this.cacheMode = ConcurrencyMgr.CA_WRITETHRU;

                break;
            }

            default: {
                throw new Error(Error.CM_ILLEGAL_CACHE_MODE, "SetCacheMode", this, new IntegerData(mode), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();

            }
        }
    }

    /**
     * qq_setCacheSize<p>
     * Method renamed by jcTOOL from SetCacheSize to qq_setCacheSize
     * because it conflicted with an attribute<p>
     * <p>
     * @param size Type: int
     */
  public synchronized void qq_setCacheSize(@Input int size) {
        ImplementationException e = new ImplementationException();

        e.setWithParams(Constants.SP_ER_ERROR, new TextData("The method CacheMgr.SetCacheSize is umimplemented."));
        ErrorMgr.addError(e);
        throw e;
    }

    /**
     * qq_setConcurrencyMode<p>
     * Method renamed by jcTOOL from SetConcurrencyMode to qq_setConcurrencyMode
     * because it conflicted with an attribute<p>
     * <p>
     * @param mode Type: int
     */
    public synchronized void qq_setConcurrencyMode(@Input int mode) {
        if (this.concurrencyMode != mode) {

            if (this.concurrencyMode != ConcurrencyMgr.CO_NONE) {
                throw new Error(Error.CM_CANNOT_CHANGE_MODE, "SetConcurrencyMode", this, new IntegerData(this.concurrencyMode), new IntegerData(mode)).getException();
            }

            switch (mode) {

                case ConcurrencyMgr.CO_NONE: {
                    this.concurrencyMode = ConcurrencyMgr.CO_NONE;

                    break;
                }
                case ConcurrencyMgr.CO_DB_NATIVE: {
                    this.concurrencyMode = ConcurrencyMgr.CO_DB_NATIVE;

                    break;
                }
                case ConcurrencyMgr.CO_DB_EXPLICIT: {
                    this.concurrencyMode = ConcurrencyMgr.CO_DB_EXPLICIT;

                    break;
                }
                case ConcurrencyMgr.CO_OPT_VERIFY: {
                    this.concurrencyMode = ConcurrencyMgr.CO_OPT_VERIFY;

                    break;
                }
                case ConcurrencyMgr.CO_OPT_EXPRESS: {
                    this.concurrencyMode = ConcurrencyMgr.CO_OPT_EXPRESS;

                    break;
                }

                default: {
                    throw new Error(Error.CM_ILLEGAL_CONCURRENCY_MODE, "SetConcurrencyMode", this, new IntegerData(mode), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();

                }
            }

        }
    }

    /**
     * setup<p>
     * <p>
     */
    public synchronized void setup() {
        if (this.cacheSize == 0) {
            this.cacheSize = 1000;
        }

        this.users = new Array_Of_ConcurrencyUserCB<ConcurrencyUserCB>();
        this.keys = new ConcurrencyKeys();
        this.keys.setup(this.cacheSize);
        this.setFreeUserCBhead(ConcurrencyUserCB.END_OF_LIST);
        this.updateDelay = 1;

        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_INIT, 1, this, "Setup")) {
            Logger.getLogger("task.part.logmgr").info("Address = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toHexString(this.hashCode()));
            Logger.getLogger("task.part.logmgr").info(", Size = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(this.cacheSize));
        }
    }

    /**
     * startTrans<p>
     * <p>
     * @param clientID Type: int
     * @param transactionMode Type: int
     */
    public synchronized void startTrans(@CopyInput int clientID, @CopyInput int transactionMode) {
        if (this.getTrace().getOn() && this.getTrace().test(0, 0, Trace.ES_CM, ConcurrencyMgr.TRACE_START, this, "StartTrans")) {
            Logger.getLogger("task.part.logmgr").info("clientID = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(clientID));
            Logger.getLogger("task.part.logmgr").info(", transactionMode = ");
            Logger.getLogger("task.part.logmgr").info( Integer.toString(transactionMode));
        }

        ConcurrencyUserCB userCB = this.getUserCB(clientID);

        if (transactionMode == ConcurrencyMgr.TR_CONTINUE) {

            if (userCB.getStamp() == 0) {
                throw new Error(Error.CM_NO_TRANSACTION, "StartTrans", this, new IntegerData(clientID), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();
            }

        }
        else {

            if (userCB.getStamp() > 0) {

                if (userCB.getLockedKeys() == null) {

                    this.endTrans(userCB);

                }
                else {

                    Array_Of_ConcurrencyKeyCB<ConcurrencyKeyCB> qq_localVector = userCB.getLockedKeys();
                    if (qq_localVector != null) {
                        for (ConcurrencyKeyCB keyCB : qq_localVector) {

                            keyCB.setLocked(false);
                            keyCB.setStamp(userCB.getStamp());
                            keyCB.setUpdateStamp(userCB.getStamp());

                        }
                    }

                    userCB.setLockedKeys(null);

                    this.endTrans(userCB);

                    throw new Error(Error.CM_TRANSACTION_IN_PROGRESS, "StartTrans", this, new IntegerData(clientID), Error.qq_Resolver.cERROR_METHODNAME_ORIGINATOR_PARAM1).getException();

                }

            }

            if (transactionMode == ConcurrencyMgr.TR_START) {
                userCB.setStamp(this.getTimestamp());
                userCB.setKeys(new Array_Of_ConcurrencyKeyCB<ConcurrencyKeyCB>());
            }

        }
    }

    /**
     * Get the proxy class which will forwards remote requests to this class. This
     * must be kept as a method so it can be overridden in all subclasses, ensuring
     * a proxy to the lowest level subclass is returned.
     */
    public AnchoredProxy getProxy() {
        return new ConcurrencyMgrProxy(this);
    }

    /**
     * Override the writeReplace method to replace this class with a proxy to it (if it's anchored)
     */
    public Object writeReplace() throws ObjectStreamException {
        if (getIsAnchored()) {
            AnchoredProxy proxy = this.getProxy();
            //System.out.println("Replacing " + this + " with " + proxy + " in writeReplace");
            return proxy;
        }
        else {
            return this;
        }
    }

    /**
     * Satisfy the {@link RemoteEventProxy} interface
     */
    public String registerInterest(String pHostName, RemoteEvent pAnchoredObject, String pEvent)  {
        return EventManager.registerInterest(pHostName, pAnchoredObject, this, pEvent);
    }

    public void postEvent(String pEventName, Hashtable<String, Object> pParameters) {
        EventManager.postEvent(this, pEventName, pParameters);
    }

    public void deregisterInterest(String pHostName, RemoteEvent pAnchoredObject, String pEvent)  {
        EventManager.deregisterInterest(pHostName, pAnchoredObject, this, pEvent);
    }
// end class ConcurrencyMgr
// c Pass 2 Conversion Time: 3282 milliseconds
TOP

Related Classes of Express.services.ConcurrencyMgr

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.