| XidFactory.java |
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
*/
package org.jboss.tm;
import java.net.InetAddress;
import javax.transaction.xa.Xid;
import java.net.UnknownHostException;
/**
* XidFactory.java
*
*
* Created: Sat Jun 15 19:01:18 2002
*
* @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
* @version
*
* @jmx.mbean
*/
public class XidFactory implements XidFactoryMBean
{
/**
* The default value of baseGlobalId is the host name of this host,
* followed by a slash.
*
* This is used for building globally unique transaction identifiers.
* It would be safer to use the IP address, but a host name is better
* for humans to read and will do for now.
* This must be set individually if multiple jboss instances are
* running on the same machine.
*/
private String baseGlobalId;
/**
* The next transaction id to use on this host.
*/
private long globalIdNumber = 0;
/**
* The variable <code>pad</code> says whether the byte[] should be their
* maximum 64 byte length or the minimum.
* The max length is required for Oracle..
*/
private boolean pad = false;
/**
* The variable <code>noBranchQualifier</code> is the 1 or 64 byte zero
* array used for initial xids.
*/
private byte[] noBranchQualifier = new byte[1]; // len > 0, per the XA spec
/**
* This field stores the byte reprsentation of baseGlobalId
* to avoid the expensive getBytes() call on this String object
* when we create a new Xid, which we do VERY often!
*/
private byte[] baseGlobalIdBytes;
public XidFactory()
{
try
{
baseGlobalId = InetAddress.getLocalHost().getHostName();
// Ensure room for 14 digits of serial no.
if (baseGlobalId.length() > Xid.MAXGTRIDSIZE - 15)
baseGlobalId = baseGlobalId.substring(0, Xid.MAXGTRIDSIZE - 15);
baseGlobalId = baseGlobalId + "/";
}
catch (UnknownHostException e)
{
baseGlobalId = "localhost/";
}
baseGlobalIdBytes = baseGlobalId.getBytes();
}
/**
* mbean get-set pair for field BaseGlobalId
* Get the value of BaseGlobalId
* @return value of BaseGlobalId
*
* @jmx:managed-attribute
*/
public String getBaseGlobalId()
{
return baseGlobalId;
}
/**
* Set the value of BaseGlobalId
* @param BaseGlobalId Value to assign to BaseGlobalId
*
* @jmx:managed-attribute
*/
public void setBaseGlobalId(final String baseGlobalId)
{
this.baseGlobalId = baseGlobalId;
baseGlobalIdBytes = baseGlobalId.getBytes();
}
/**
* mbean get-set pair for field globalIdNumber
* Get the value of globalIdNumber
* @return value of globalIdNumber
*
* @jmx:managed-attribute
*/
public synchronized long getGlobalIdNumber()
{
return globalIdNumber;
}
/**
* Set the value of globalIdNumber
* @param globalIdNumber Value to assign to globalIdNumber
*
* @jmx:managed-attribute
*/
public synchronized void setGlobalIdNumber(final long globalIdNumber)
{
this.globalIdNumber = globalIdNumber;
}
/**
* mbean get-set pair for field pad
* Get the value of pad
* @return value of pad
*
* @jmx:managed-attribute
*/
public boolean isPad()
{
return pad;
}
/**
* Set the value of pad
* @param pad Value to assign to pad
*
* @jmx:managed-attribute
*/
public void setPad(boolean pad)
{
this.pad = pad;
if (pad)
noBranchQualifier = new byte[Xid.MAXBQUALSIZE];
else
noBranchQualifier = new byte[1]; // length > 0, per the XA spec
}
/**
* mbean get-set pair for field instance
* Get the value of instance
* @return value of instance
*
* @jmx:managed-attribute
*/
public XidFactoryMBean getInstance()
{
return this;
}
/**
* Describe <code>newXid</code> method here.
*
* @return a <code>XidImpl</code> value
* @jmx.managed-operation
*/
public XidImpl newXid()
{
long localId = getNextId();
String id = Long.toString(localId);
int len = pad?Xid.MAXGTRIDSIZE:id.length()+baseGlobalIdBytes.length;
byte[] globalId = new byte[len];
System.arraycopy(baseGlobalIdBytes, 0, globalId, 0, baseGlobalIdBytes.length);
// this method is deprecated, but does exactly what we need in a very fast way
// the default conversion from String.getBytes() is way too expensive
id.getBytes(0, id.length(), globalId, baseGlobalIdBytes.length);
return new XidImpl(globalId, noBranchQualifier, (int)localId, localId);
}
/**
* Describe <code>newBranch</code> method here.
*
* @param xid a <code>XidImpl</code> value
* @param branchIdNum a <code>long</code> value
* @return a <code>XidImpl</code> value
* @jmx.managed-operation
*/
public XidImpl newBranch(XidImpl xid, long branchIdNum)
{
String id = Long.toString(branchIdNum);
int len = pad?Xid.MAXBQUALSIZE:id.length();
byte[] branchId = new byte[len];
// this method is deprecated, but does exactly what we need in a very fast way
// the default conversion from String.getBytes() is way too expensive
id.getBytes(0, id.length(), branchId, 0);
return new XidImpl(xid, branchId);
}
/**
* Extracts the local id contained in a global id.
*
* @param globalId a global id
* @return the local id extracted from the global id
* @jmx:managed-operation
*/
public long extractLocalIdFrom(byte[] globalId)
{
int i, start, stop;
int len = globalId.length;
for (i = 0; globalId[i++] != (byte)'/'; )
;
start = i;
while (i < len && globalId[i] != 0)
i++;
String globalIdNumber = new String(globalId, 0, start, i - start);
return Long.parseLong(globalIdNumber);
}
/**
* Describe <code>toString</code> method here.
*
* @param xid a <code>Xid</code> value
* @return a <code>String</code> value
* @jmx.managed-operation
*/
public String toString(Xid xid)
{
if (xid instanceof XidImpl)
return XidImpl.toString(xid);
else
return xid.toString();
}
private synchronized long getNextId()
{
return ++globalIdNumber;
}
}
| XidFactory.java |