All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.jts.CosTransactions.ControlImpl Maven / Gradle / Ivy

/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1995-1997 IBM Corp. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

//----------------------------------------------------------------------------
//
// Module:      ControlImpl.java
//
// Description: Transaction Control object implementation.
//
// Product:     com.sun.jts.CosTransactions
//
// Author:      Simon Holdsworth
//
// Date:        March, 1997
//----------------------------------------------------------------------------

package com.sun.jts.CosTransactions;

// Import required classes.

import java.util.*;

import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.CosTransactions.*;
import org.omg.PortableServer.POAPackage.ServantNotActive;
import org.omg.PortableServer.POAPackage.ServantAlreadyActive;

import com.sun.jts.codegen.otsidl.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import com.sun.logging.LogDomains;
import com.sun.jts.utils.LogFormatter;
/**The ControlImpl interface is our implementation of the standard Control
 * interface. It provides operations to set and subsequently obtain the
 * Terminator and Coordinator objects from the given context. Our
 * implementation also provides a method to obtain the corresponding
 * transaction identifiers, and stacking methods.
 *
 * @version 0.01
 *
 * @author Simon Holdsworth, IBM Corporation
 *
 * @see
 */
//----------------------------------------------------------------------------
// CHANGE HISTORY
//
// Version By     Change Description
//   0.01  SAJH   Initial implementation.
//------------------------------------------------------------------------------

public class ControlImpl extends JControlPOA implements Control {

    private static POA poa = null;
    private Control thisRef = null;

    protected boolean         temporary = false;
    protected boolean         inSuspended = false;
    protected Status          tranState = Status.StatusActive;
    protected CoordinatorImpl coord = null;
    protected Coordinator     coordRef = null;
    protected TerminatorImpl  term = null;
    protected Terminator      termRef = null;
    protected ControlImpl     stacked = null;
    protected GlobalTID       globalTID = null;
    protected Long            localTID = null;
    protected boolean         representsRemote = false;
    protected PropagationContext cachedContext = null;

    // Transaction checking values

    protected int outgoing = 0;
    protected int association = 0;

    /**
     * Logger to log transaction messages
     */
    static Logger _logger = LogDomains.getLogger(Configuration.class, LogDomains.TRANSACTION_LOGGER);

    /**Default ControlImpl constructor.
     *
     * @param
     *
     * @return
     *
     * @see
     */
    ControlImpl() {

        tranState = Status.StatusActive;

        // Add the Control object to the set of
        // suspended ones for this process.
        inSuspended = true;
        CurrentTransaction.addSuspended(this);

    }

    /**Creates and initialises a new ControlImpl, given the TerminatorImpl and
     * CoordinatorImpl objects, and the corresponding global and local identifiers.
     *
     * @param term       The Terminator for the transaction.
     * @param coord      The Coordinator for the transaction.
     * @param globalTID  The global identifier for the transaction.
     * @param localTID   The local identifier for the transaction.
     *
     * @return
     *
     * @see
     */
    ControlImpl( TerminatorImpl  term,
    CoordinatorImpl coord,
    GlobalTID       globalTID,
    Long            localTID ) {


        // Set up the instance variables.

        this.term = term;
        this.coord = coord;
        this.globalTID = globalTID;
        this.localTID = localTID;
        tranState = Status.StatusActive;

        // Add the Control object to the set of suspended ones for this process.

        inSuspended = true;
        CurrentTransaction.addSuspended(this);

        // pass this control obj to the terminator to cleanup properly (Ram J)
        if (term != null) {
            term.setControl(this);
        }
    }

    /**Creates and initialises a new ControlImpl, given a Control object.
     * This constructor is used to create a local ControlImpl when a remote factory
     * has been used to create the Control object.
     *
     * @param ref  The Control object for the transaction.
     *
     * @return
     *
     * @exception Unavailable  The required information to set up the Control object
     *   is not available.
     *
     * @see
     */
    ControlImpl( Control ref )
    throws Unavailable {

        // Set up the instance variables.

        thisRef = ref;
        representsRemote = true;
        coordRef = ref.get_coordinator();
        termRef = ref.get_terminator();

        // Get a PropagationContext from the Coordinator, which will contain the
        // global TID for the transaction.

        try {
            cachedContext = coordRef.get_txcontext();
            globalTID = new GlobalTID(cachedContext.current.otid);
        } catch( Throwable exc ) {
        }

        tranState = Status.StatusActive;

        // Don't add the Control object to the set of suspended ones for this process,
        // as we may never get the opportunity to remove it.

        //$ CurrentTransaction.addSuspended(this);

    }

    /**Cleans up the state of the object.
     *
     * @param
     *
     * @return
     *
     * @see
     */
    synchronized public void doFinalize() {

        // Ensure that this object does not appear in the suspended set.

        if( inSuspended )
            CurrentTransaction.removeSuspended(this);
        inSuspended = false;

        // If there is a Terminator reference, destroy the Terminator.

        if( term != null ) term.destroy();

        // Remove the reference from the map.

        /* TN - do not nullify the references yet
        thisRef = null;
        coord = null;
        coordRef = null;
        term = null;
        termRef = null;
        stacked = null;
        globalTID = null;
        localTID = null;
         */

    }

    /**Returns the identifier that globally represents the transaction
     *
     * @param
     *
     * @return  The global identifier.
     *
     * @see
     */
    public GlobalTID getGlobalTID() {
        return globalTID;
    }

    /**Returns the identifier that globally represents the transaction, and a
     * value that indicates the state of the transaction.
     *
     * @param status  An object to hold the status value, or null.
     *
     * @return  The global identifier.
     *
     * @exception SystemException  An error occurred.  The minor code indicates
     *                             the reason for the exception.
     *
     * @see
     */
    synchronized public otid_t getGlobalTID( StatusHolder status )
    throws SystemException {

        otid_t result = null;

        // Return the transaction state.

        if( status != null )
            status.value = tranState;

        // If the object is asked for its OMGtid and has none, raise an exception.

        if( globalTID == null ) {

            INTERNAL exc = new INTERNAL(MinorCode.NoGlobalTID,
            CompletionStatus.COMPLETED_NO);
            throw exc;
        }
        else
            result = globalTID.realTID;

        return result;
    }

    /**Returns the identifier that locally represents the transaction, and a value
     * that indicates the state of the transaction.
     * 

* If the transaction represented by the Control object has been completed, * the identifier is still returned if possible. * * @param status An object to hold the status value, or null. * * @return The local transaction identifier. * * @exception SystemException An error occurred. The minor code indicates * the reason for the exception. * * @see */ synchronized public long getLocalTID( StatusHolder status ) throws SystemException { long result = 0; // Return the transaction state. if( status != null ) status.value = tranState; // If the internal id has not been defined, raise an exception. if( localTID == null ) { INTERNAL exc = new INTERNAL(MinorCode.NoGlobalTID, CompletionStatus.COMPLETED_NO); throw exc; } else { result = localTID.longValue(); } return result; } /**Returns a reference to the stacked ControlImpl if there is one, otherwise * returns a NULL reference. *

* A value is returned that indicates the state of the transaction. *

* If the transaction represented by the Control object has been completed, * the reference is still returned if possible. * The stacked Control object is removed from the stack. * * @param status An object to hold the status value, or null. * * @return The stacked Control object. * * @see */ synchronized ControlImpl popControl( StatusHolder status ) { ControlImpl result = null; // Return the transaction state. if( status != null ) status.value = tranState; // Get the value of the stacked Control object. // Remove the stacked Control object (if any). result = stacked; stacked = null; return result; } /**Stacks the given ControlImpl on the target of the operation, so that it can * later be restored, and returns a value that indicates the state of the * transaction. * If there is already a stacked ControlImpl object, the operation throws an * exception. If the transaction has already completed, no stacking is done. * * @param control The Control object to be stacked. * @param status An object to hold the status value, or null. * * @return * * @exception SystemException An error occurred. The minor code indicates * the reason for the exception. * * @see */ synchronized void pushControl( ControlImpl control, StatusHolder status ) throws SystemException { if( tranState == Status.StatusActive ) { // If a Control object is already stacked on this one, raise an exception. if( stacked != null ) { INTERNAL exc = new INTERNAL(MinorCode.AlreadyStacked, CompletionStatus.COMPLETED_NO); throw exc; } // Make the stacked Control object the given one. else stacked = control; } // Return the transaction state. if( status != null ) status.value = tranState; } /**Returns the Terminator object for the transaction. * We raise the Unavailable exception when there is no Terminator. * If the transaction has been completed, an appropriate exception is raised. * * This operation is part of the OMG interface and must not return any * exceptions other than those defined in the OMG interface. * * @param * * @return The Terminator for the transaction. * * @exception Unavailable The Terminator object is not available. * @exception SystemException The operation failed. * * @see */ synchronized public Terminator get_terminator() throws Unavailable, SystemException { Terminator result = termRef; // If the transaction has been completed, then raise an exception. // Raise either TRANSACTION_ROLLEDBACK or INVALID_TRANSACTION depending on // whether the transaction has aborted. if( tranState == Status.StatusCommitted ) { INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.Completed, CompletionStatus.COMPLETED_NO); throw exc; } if( tranState == Status.StatusRolledBack ) { TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO); throw exc; } // If there is no Terminator reference, but a local Terminator, then get its // reference and remember it. if( termRef == null && term != null ) { termRef = term.object(); result = termRef; } // If there is no reference available, throw the Unavailable exception. if( result == null ) { Unavailable exc = new Unavailable(); throw exc; } return result; } synchronized public Terminator get_localTerminator() throws Unavailable, SystemException { Terminator result = (Terminator) term; // If the transaction has been completed, then raise an exception. // Raise either TRANSACTION_ROLLEDBACK or INVALID_TRANSACTION depending on // whether the transaction has aborted. if( tranState == Status.StatusCommitted ) { INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.Completed, CompletionStatus.COMPLETED_NO); throw exc; } if( tranState == Status.StatusRolledBack ) { TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO); throw exc; } // If there is no reference available, throw the Unavailable exception. if (result == null) { Unavailable exc = new Unavailable(); throw exc; } return result; } /** * Returns the Coordinator for the transaction. * If the transaction has been completed, an appropriate exception is raised. * * This operation is part of the OMG interface and must not return * any exceptions other than those defined in the OMG interface. * * @param * * @return The Coordinator for the transaction. * * @exception Unavailable The Coordinator is not available. * @exception SystemException The operation failed. * * @see */ synchronized public Coordinator get_coordinator() throws Unavailable, SystemException { Coordinator result = coordRef; // If the transaction has been completed, then raise an exception. // Raise either TRANSACTION_ROLLEDBACK or INVALID_TRANSACTION depending on // whether the transaction has aborted. if( tranState == Status.StatusCommitted ) { INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.Completed, CompletionStatus.COMPLETED_NO); throw exc; } if( tranState == Status.StatusRolledBack ) { TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO); throw exc; } // If there is no Coordinator reference, but a local Coordinator, then get its // reference and remember it. if( coordRef == null && coord != null ) { coordRef = coord.object(); result = coordRef; } // If there is no reference available, throw the Unavailable exception. if( result == null ) { Unavailable exc = new Unavailable(); throw exc; } return result; } /** * Returns the Coordinator for the transaction. * If the transaction has been completed, an appropriate exception is raised. * * This operation is part of the OMG interface and must not return * any exceptions other than those defined in the OMG interface. * * @param * * @return The Coordinator for the transaction. * * @exception Unavailable The Coordinator is not available. * @exception SystemException The operation failed. * * @see */ synchronized public Coordinator get_localCoordinator() throws Unavailable, SystemException { Coordinator result = (Coordinator) coord; // If the transaction has been completed, then raise an exception. // Raise either TRANSACTION_ROLLEDBACK or INVALID_TRANSACTION depending on // whether the transaction has aborted. if( tranState == Status.StatusCommitted ) { INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.Completed, CompletionStatus.COMPLETED_NO); throw exc; } if( tranState == Status.StatusRolledBack ) { TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO); throw exc; } // If there is no reference available, throw the Unavailable exception. if( result == null ) { Unavailable exc = new Unavailable(); throw exc; } return result; } /**This operation returns a value indicating that asynchonrous requests issued * within the context of the current ControlImpl instance have not yet * completed. * * @param * * @return Indicates there are outgoing requests. * * @see */ synchronized boolean isOutgoing() { boolean result = (outgoing != 0); return result; } /**This operation returns a value which indicates that this ControlImpl instance * is associated with one or more threads. * * @param * * @return Indicates an exisiting association. * * @see */ synchronized boolean isAssociated() { boolean result = (association != 0); return result; } /**This operation returns the number of thread associations * * @param * * @return Indicates the number of thread associations. * * @see */ synchronized int numAssociated() { int result = association; return result; } /**Increment the thread association count. * * @param * * @return * * @see */ synchronized void incrementAssociation() { association++; } /**Decrement the thread association count. * * @param * * @return Indicates the association count was above zero. * * @see */ synchronized boolean decrementAssociation() { boolean result = (association > 0); if( result ) association--; return result; } /**Increment the incomplete asynchronous request counter. * * @param * * @return * * @see */ synchronized void incrementOutgoing() { outgoing++; } /**Decrement the incomplete asynchronous request counter. * * @param * * @return Indicates the request counter was above zero. * * @see */ synchronized boolean decrementOutgoing() { boolean result = (outgoing > 0); if( result ) outgoing--; return result; } /**Returns the state of the transaction as the Control object knows it. * * @param * * @return The transaction state. * * @see */ synchronized public Status getTranState(){ Status result = tranState; return result; } /**Sets the state of the transaction as the Control object knows it. * No checking is done to verify the state change is valid. * * @param int The new state. * * @return * * @see */ synchronized public void setTranState( Status newState ) { tranState = newState; } /**Locates the first stacked ancestor which has not aborted. If there is no * such ancestor the operation returns null. * * @param * * @return The first stacked Control which does not represent an aborted * transaction. * * @see */ synchronized ControlImpl popAborted() { // Start with this object's stacked Control. ControlImpl result = stacked; boolean validTID = false; StatusHolder outStatus = new StatusHolder(); while( result != null && !validTID ) { // Get the local transaction identifier for the stacked Control object, // and ask the RecoveryManager if it represents a valid transaction. Long localTID = null; try { localTID = result.getLocalTID(outStatus); validTID = RecoveryManager.validLocalTID(localTID); } catch( Throwable exc ) {} // If the transaction identifier is not valid, then the transaction must have // rolled back, so discard it and get its stacked Control object, if any. if( !validTID ) { // Get the stacked Control object from the one that represents a rolled // back transaction, and try to resume that one instead. ControlImpl stacked = result.popControl(outStatus); result.destroy(); // Discard the rolled-back Control object and continue until a valid one, or // no stacked Control is found. result = stacked; } } return result; } /**Determines whether the ControlImpl object represents a remote Control object * or a local one. * * @param * * @return Indicates whether the ControlImpl represents a remote Control. * * @see */ synchronized boolean representsRemoteControl() { boolean result = representsRemote; return result; } /**Returns the transaction context for the Coordinator. * * @param * * @return The transaction context. * * @exception Unavailable No transaction context is available. * * @see */ synchronized PropagationContext getTXContext() throws Unavailable { PropagationContext result = null; // If the ControlImpl represents a remote transaction, then use the cached // context, or get one from the Coordinator if there is no cached context. if( representsRemote ) { if( cachedContext == null ) try { cachedContext = coordRef.get_txcontext(); } catch( OBJECT_NOT_EXIST exc ) { TRANSACTION_ROLLEDBACK ex2 = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO); throw ex2; } result = cachedContext; } // For local transactions, get the context from the Coordinator. else result = coord.get_txcontext(); return result; } /**Dumps the state of the object. * * @param * * @return * * @see */ void dump() { } /**Returns the CORBA Object which represents this object. * * @param * * @return The CORBA object. * * @see */ synchronized final Control object() { if( thisRef == null ) { if( poa == null ) poa = Configuration.getPOA("transient"/*#Frozen*/); try { poa.activate_object(this); thisRef = ControlHelper.narrow(poa.servant_to_reference(this)); } catch( ServantAlreadyActive sexc ) { _logger.log(Level.SEVERE,"jts.create_control_object_error",sexc); String msg = LogFormatter.getLocalizedMessage(_logger, "jts.create_control_object_error"); throw new org.omg.CORBA.INTERNAL(msg); } catch( ServantNotActive snexc ) { _logger.log(Level.SEVERE,"jts.create_control_object_error",snexc); String msg = LogFormatter.getLocalizedMessage(_logger, "jts.create_control_object_error"); throw new org.omg.CORBA.INTERNAL(msg); } catch( Exception exc ) { _logger.log(Level.SEVERE,"jts.create_control_object_error",exc); String msg = LogFormatter.getLocalizedMessage(_logger, "jts.create_control_object_error"); throw new org.omg.CORBA.INTERNAL(msg); } } return thisRef; } /**Returns the ControlImpl which serves the given object. * * @param The CORBA Object. * * @return The ControlImpl object which serves it. * * @see */ synchronized public static final ControlImpl servant( JControl control ) { ControlImpl result = null; // GDH we will not be able to obtain the // servant from our local POA for a proxy control object. // so return null if ( control != null && Configuration.getProxyChecker().isProxy(control)) { return result; } if( control instanceof ControlImpl ) { result = (ControlImpl)control; } else if( poa != null ) try { result = (ControlImpl)poa.reference_to_servant(control); if( result.thisRef == null ) result.thisRef = control; } catch( Exception exc ) { _logger.log(Level.WARNING,"jts.cannot_locate_servant","Control"); } return result; } /**Destroys the ControlImpl object. * * @param * * @return * * @see */ synchronized final void destroy() { // GDH: We have no desire to destroy an underlying remote control object, instead we // release it. We will finalise the local control wrapper below if ( thisRef != null && Configuration.getProxyChecker().isProxy(thisRef)) { thisRef._release(); } else { if( poa != null && thisRef != null ) try { poa.deactivate_object(poa.reference_to_id(thisRef)); thisRef = null; } catch( Exception exc ) { _logger.log(Level.WARNING,"jts.object_destroy_error","Control"); } } doFinalize(); } /**Added to prevent null delegate problem. * * @param * * @return * * @see */ public boolean equals(java.lang.Object o) { return this == o; } /**Added because this class overrides equals() method. * */ @Override public int hashCode() { return System.identityHashCode(this); } /* * These methods are there to satisy the compiler. At some point * when we move towards a tie based model, the org.omg.Corba.Object * interface method implementation below shall be discarded. */ public org.omg.CORBA.Object _duplicate() { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public void _release() { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public boolean _is_a(String repository_id) { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public boolean _is_equivalent(org.omg.CORBA.Object that) { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public boolean _non_existent() { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public int _hash(int maximum) { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public Request _request(String operation) { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public Request _create_request(Context ctx, String operation, NVList arg_list, NamedValue result) { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public Request _create_request(Context ctx, String operation, NVList arg_list, NamedValue result, ExceptionList exceptions, ContextList contexts) { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public org.omg.CORBA.Object _get_interface_def() { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public org.omg.CORBA.Policy _get_policy(int policy_type) { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public org.omg.CORBA.DomainManager[] _get_domain_managers() { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } public org.omg.CORBA.Object _set_policy_override( org.omg.CORBA.Policy[] policies, org.omg.CORBA.SetOverrideType set_add) { throw new org.omg.CORBA.NO_IMPLEMENT("This is a locally constrained object."); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy