/* * 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) 2001, 2002, * * Hewlett-Packard Arjuna Labs, * Newcastle upon Tyne, * Tyne and Wear, * UK. * * $Id: FactoryList.java 2342 2006-03-30 13:06:17Z $ */ package com.arjuna.ats.internal.jts.interposition; import java.util.concurrent.locks.ReentrantLock; import org.omg.CORBA.SystemException; import org.omg.CORBA.INVALID_TRANSACTION; import org.omg.CosTransactions.Control; import org.omg.CosTransactions.PropagationContext; import com.arjuna.ats.internal.jts.interposition.resources.arjuna.InterpositionCreator; import com.arjuna.ats.internal.jts.interposition.resources.osi.OSIInterpositionCreator; import com.arjuna.ats.internal.jts.interposition.resources.restricted.RestrictedInterpositionCreator; import com.arjuna.ats.internal.jts.interposition.resources.strict.StrictInterpositionCreator; import com.arjuna.ats.internal.jts.orbspecific.ControlImple; import com.arjuna.ats.jts.extensions.Arjuna; import com.arjuna.ats.jts.logging.jtsLogger; /* * Default visibility. */ class FactoryElement { public FactoryElement (FactoryCreator create, int formatID) { _create = create; _formatID = formatID; _next = null; } public ControlImple recreateLocal (PropagationContext ctx) throws SystemException { return _create.recreateLocal(ctx); } public Control recreate (PropagationContext ctx) throws SystemException { return recreateLocal(ctx).getControl(); } public int _formatID; public FactoryElement _next; private FactoryCreator _create; } /* * Add the Arjuna OTS transaction recreator as a minimum, i.e., no special * action is required to know about JBoss transactions. */ /** * Maintains the list of known transaction interposition factories. */ public class FactoryList { public static final int DEFAULT_ID = 0; public FactoryList () { FactoryList.add(new InterpositionCreator(), Arjuna.XID()); FactoryList.add(new StrictInterpositionCreator(), Arjuna.strictXID()); FactoryList.add(new RestrictedInterpositionCreator(), Arjuna.restrictedXID()); FactoryList.add(new OSIInterpositionCreator(), 0); // 0 is OSI TP! FactoryList.addDefault(new OSIInterpositionCreator(), DEFAULT_ID); // 0 is OSI TP! } public static ControlImple recreateLocal (PropagationContext ctx, int formatID) throws SystemException { ControlImple toReturn = null; if (ctx == null) throw new INVALID_TRANSACTION(); FactoryElement ptr = find(formatID); if (ptr != null) { toReturn = ptr.recreateLocal(ctx); } return toReturn; } public static Control recreate (PropagationContext ctx, int formatID) throws SystemException { Control toReturn = null; if (ctx == null) throw new INVALID_TRANSACTION(); FactoryElement ptr = find(formatID); if (ptr != null) { toReturn = ptr.recreate(ctx); } return toReturn; } public static void add (FactoryCreator create, int formatID) { FactoryElement ptr = find(formatID); _lock.lock(); if (ptr == null) // assume that the create and id always match { ptr = new FactoryElement(create, formatID); ptr._next = _list; _list = ptr; } _lock.unlock(); } public static void remove (int formatID) { _lock.lock(); FactoryElement ptr = _list; FactoryElement trail = null; boolean found = false; while ((ptr != null) && (!found)) { if (ptr._formatID == formatID) found = true; else { trail = ptr; ptr = ptr._next; } } if (found) { if (_list == ptr) _list = ptr._next; else { if (trail != null) trail._next = ptr._next; } ptr._next = null; ptr = null; } _lock.unlock(); } /** * Only allow a default to be added once! */ public static boolean addDefault (FactoryCreator create, int formatID) { boolean res = false; _lock.lock(); if (FactoryList._default == null) { FactoryList._default = new FactoryElement(create, formatID); res = true; } else { jtsLogger.i18NLogger.warn_interposition_fldefault("FactoryList.addDefault"); } _lock.unlock(); return res; } public static boolean removeDefault () { boolean found = false; _lock.lock(); if (FactoryList._default != null) { FactoryList._default = null; found = true; } _lock.unlock(); return found; } protected static FactoryElement find (int formatID) { FactoryElement ptr = _list; FactoryElement toReturn = null; _lock.lock(); while ((ptr != null) && (toReturn == null)) { if (ptr._formatID == formatID) toReturn = ptr; else ptr = ptr._next; } if (toReturn == null) { /* * No ID matches, so use default. */ toReturn = FactoryList._default; } _lock.unlock(); return toReturn; } private static FactoryElement _list = null; private static FactoryElement _default = null; // used if no formatID values match. private static ReentrantLock _lock = new ReentrantLock(); }