FileDocCategorySizeDatePackage
NestingInfo.javaAPI DocGlassfish v2 API11808Wed Jun 13 23:03:46 BST 2007com.sun.jts.CosTransactions

NestingInfo

public class NestingInfo extends Object
The NestingInfo interface provides operations that record all nesting information relevant to a Coordinator, that is, the set of children (SubCoordinators) and the sequence of ancestors (Coordinators/global IDs). As an instance of this class may be accessed from multiple threads within a process, serialisation for thread-safety is necessary in the implementation. The information recorded in an instance of this class does not need to be reconstructible in the case of a system failure as subtransactions are not durable.
version
0.01
author
Simon Holdsworth, IBM Corporation
see

Fields Summary
CoordinatorImpl[]
ancestorSeq
Vector
childSet
boolean
removed
Constructors Summary
NestingInfo()
Default NestingInfo constructor.

param
return
see


               
     
NestingInfo(CoordinatorImpl[] ancestors)
Defines the sequence of ancestors and initialises the set of children to be empty.

param
ancestors The ancestors
return
see


        // If the sequence of ancestors is empty, set the removed flag as this
        // NestingInfo is part of a top-level transaction.

        ancestorSeq = (CoordinatorImpl[])ancestors.clone();
        removed = (ancestors.length == 0);
    
Methods Summary
booleanaddChild(CoordinatorImpl child)
Adds the given SubCoordinator as a child.

If the reference is already in the set, the operation returns false.

param
child The child Coordinator.
return
Indicates success of the operation.
see


        boolean result = !childSet.contains(child);
        if( result ) childSet.addElement(child);

        return result;
    
voidempty()
Empties the set of children.

param
return
see

        childSet.removeAllElements();
    
CoordinatorImpl[]getAncestors()
Returns a copy of the sequence of ancestors of the Coordinator.

If the containing Coordinator is the top-level one, an empty sequence is returned.

The caller is responsible for freeing the sequence storage.

param
return
The sequence of ancestors.
see


        CoordinatorImpl[] result = null;

        // If there are no ancestors, return the empty sequence.
        // If we cannot obtain a buffer to copy the sequence, return
        // empty sequence Perhaps an exception should be raised instead ?

        result = (CoordinatorImpl[]) ancestorSeq.clone();

        return result;
    
CoordinatorImplgetParent(boolean forgetting)
Returns a reference to the parent Coordinator.

If there is none, returns null.

The parent Coordinator is the first in the sequence of ancestors.

If the forgetting flag is set, the NestingInfo must not call the parent when the child calls removeFromParent.

param
forgetting Indicates whether the transaction is being forgotten.
return
The parent Coordinator.
see


        CoordinatorImpl result = null;

        // If there are no ancestors, there is no parent,
        // otherwise return the first ancestor.

        if (ancestorSeq.length != 0)
            result = ancestorSeq[0];

        // If the Coordinator is being cleaned up, then we must not
        // call the parent when the child calls removeFromParent.

        if( forgetting ) removed = true;

        return result;
    
CoordinatorImplgetTopLevel()
Returns a reference to the top-level Coordinator.

If the containing Coordinator is the top-level one, a null reference is returned.

The top-level Coordinator is the last in the sequence of ancestors.

param
return
The top-level ancestor.
see


        CoordinatorImpl result = null;

        // If there are no ancestors, there is no top-level,
        // otherwise return the last ancestor.

        if( ancestorSeq.length != 0 )
            result = ancestorSeq[ancestorSeq.length - 1];

        return result;
    
booleanisDescendant(Coordinator other)
Determines whether the Coordinator containing the NestingInfo object is a descendant of the other Coordinator.

This is true if the other Coordinator is the same as one of the ancestors.

param
other The other Coordinator.
return
Indicates success of the operation.
see


        boolean result = false;

        // Go through the ancestors, checking whether the given
        // transaction is the same as any of them.

        try {
            for (int i = 0; i < ancestorSeq.length && !result; i++) {
                result = ancestorSeq[i].is_same_transaction(other);
            }
        } catch(SystemException exc) {
            result = false;
        }

        return result;
    
intnumChildren()
Returns a count of the number of children that have been defined.

If no nesting information has been defined, the operation returns 0.

param
return
The number of children.
see

        return childSet.size();
    
booleanremoveChild(CoordinatorImpl child)
Removes the given SubCoordinator as a child.

If the reference is not in the set, the operation returns false.

param
child The child Coordinator.
return
Indicates success of the operation.
see

        boolean result = childSet.removeElement(child);
        return result;
    
booleanremoveFromParent(CoordinatorImpl child)
Removes the given Coordinator as a child from the parent Coordinator.

If the child could not be removed from the parent, the operation returns false.

param
child The child coordinator.
return
Indicates success of the operation.
see


        // If not already done, remove the child from the set of its parents.
        // If the NestingInfo instance was created for a top-level
        // transaction, the known to parent flag will always be set.
        // NOTE: Assumes parent is a CoordinatorImpl.

        boolean result = true;
        if(!removed) {
            CoordinatorImpl parent = ancestorSeq[0];

            result = parent.removeChild(child);
            removed = true;
        }

        return result;
    
booleanreplyCheck()
Checks whether any child represents an active transaction.

This is used during sending_reply to check for outstanding work.

'active' here means subordinate children that have not registered with their superior, or root children - these represent parts of a transaction that may not be committed or rolled back before the parent completes.

param
return
Indicates if all is OK.
see


        boolean result = false;

        // If there are any children, browse through the set, checking them.

        for (int i = 0; i < childSet.size() && !result; i++) {
            CoordinatorImpl child = (CoordinatorImpl) childSet.elementAt(i);
            result = child.isActive();
        }

        return result;
    
voidrollbackFamily()
Rolls back all children in the set; if there are none the operation does nothing.

param
return
see


        // If there are any children, browse through the set,
        // rolling them back.

        while (childSet.size() > 0) {

            // Note that we browse in a different way here, as each
            // child removes itself from the set when the rollback is
            // complete, so we just keep getting the
            // first element in the set until the set is empty.

            CoordinatorImpl child = (CoordinatorImpl)childSet.elementAt(0);
            try {
                child.rollback(true);
            } catch (Throwable exc) {}
        }