/* * JBoss, Home of Professional Open Source * Copyright 2006, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * 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, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * (C) 2005-2006, * @author JBoss Inc. */ /* * Copyright (C) 2003, * * Hewlett-Packard Arjuna Labs, Newcastle upon Tyne, Tyne and Wear, UK. * * $Id: SubordinateAtomicAction.java 2342 2006-03-30 13:06:17Z $ */ package com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca; import java.io.IOException; import javax.transaction.xa.Xid; import com.arjuna.ats.arjuna.common.Uid; import com.arjuna.ats.arjuna.coordinator.TxControl; import com.arjuna.ats.arjuna.exceptions.ObjectStoreException; import com.arjuna.ats.arjuna.objectstore.StoreManager; import com.arjuna.ats.arjuna.state.InputObjectState; import com.arjuna.ats.arjuna.state.OutputObjectState; import com.arjuna.ats.arjuna.utils.Utility; import com.arjuna.ats.internal.arjuna.Header; import com.arjuna.ats.internal.jta.xa.XID; import com.arjuna.ats.jta.xa.XATxConverter; import com.arjuna.ats.jta.xa.XidImple; /** * A subordinate JTA transaction; used when importing another transaction * context via JCA. This overrides the basic subordinate transaction simply so * that we can ensure JCA transactions are laid out in the right place in the * object store. * * @author mcl */ public class SubordinateAtomicAction extends com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.SubordinateAtomicAction { /** * @deprecated This is only used by test code */ public SubordinateAtomicAction () { super(); // does start for us _activated = true; _theXid = new XidImple(Uid.nullUid()); } public SubordinateAtomicAction (Uid actId) { super(actId); _activated = activate(); // if this fails, we'll retry later. } /** * Recovery SAA. If the record is removed and peekXidOnly is true then the Xid will be null. * * @param actId * @param peekXidOnly * @throws ObjectStoreException * @throws IOException */ public SubordinateAtomicAction(Uid actId, boolean peekXidOnly) throws ObjectStoreException, IOException { super(actId); if (peekXidOnly) { InputObjectState os = StoreManager.getParticipantStore().read_committed(objectUid, type()); if (os == null) { // This will have been logged by the ObjectStore during ShadowingStore::read_state as an INFO if there was no content return; } unpackHeader(os, new Header()); boolean haveXid = os.unpackBoolean(); if (haveXid) { _theXid = new XidImple(); ((XidImple) _theXid).unpackFrom(os); _parentNodeName = os.unpackString(); } } else { _activated = activate(); } } public SubordinateAtomicAction (int timeout, Xid xid) { super(timeout); // implicit start (done in base class) if (xid != null && xid.getFormatId() == XATxConverter.FORMAT_ID) { XidImple toImport = new XidImple(xid); XID toCheck = toImport.getXID(); _parentNodeName = XATxConverter.getSubordinateNodeName(toCheck); if (_parentNodeName == null) { _parentNodeName = XATxConverter.getNodeName(toCheck); } XATxConverter.setSubordinateNodeName(toImport.getXID(), TxControl.getXANodeName()); _theXid = new XidImple(toImport); } else { _theXid = new XidImple(xid); } _activated = true; } /** * The type of the class is used to locate the state of the transaction log * in the object store. * * Overloads BasicAction.type() * * @return a string representation of the hierarchy of the class for storing * logs in the transaction object store. */ public String type () { return getType(); } public static final String getType () { return "/StateManager/BasicAction/TwoPhaseCoordinator/AtomicAction/SubordinateAtomicAction/JCA"; } /** * If the record was removed Xid will be null * * @return */ public final Xid getXid () { // could be null if activation failed. return _theXid; } public String getParentNodeName() { return _parentNodeName; } public boolean save_state (OutputObjectState os, int t) { try { // pack the header first for the benefit of the tooling packHeader(os, new Header(get_uid(), Utility.getProcessUid())); if (_theXid != null) { os.packBoolean(true); ((XidImple) _theXid).packInto(os); os.packString(_parentNodeName); } else os.packBoolean(false); } catch (IOException ex) { return false; } return super.save_state(os, t); } public boolean restore_state (InputObjectState os, int t) { _theXid = null; try { unpackHeader(os, new Header()); boolean haveXid = os.unpackBoolean(); if (haveXid) { _theXid = new XidImple(); ((XidImple) _theXid).unpackFrom(os); _parentNodeName = os.unpackString(); } } catch (IOException ex) { return false; } return super.restore_state(os, t); } public boolean activated () { return _activated; } private Xid _theXid; private String _parentNodeName; private boolean _activated; }