/**
* Copyright 2014-2016 yangming.liu<bytefox@126.com>.
*
* 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, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY 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
* along with this distribution; if not, see <http://www.gnu.org/licenses/>.
*/
package org.bytesoft.bytetcc.logging.deserializer;
import java.nio.ByteBuffer;
import javax.transaction.xa.Xid;
import org.bytesoft.bytejta.supports.resource.CommonResourceDescriptor;
import org.bytesoft.bytejta.supports.resource.LocalXAResourceDescriptor;
import org.bytesoft.bytejta.supports.resource.RemoteResourceDescriptor;
import org.bytesoft.bytejta.supports.resource.UnidentifiedResourceDescriptor;
import org.bytesoft.compensable.CompensableBeanFactory;
import org.bytesoft.compensable.aware.CompensableBeanFactoryAware;
import org.bytesoft.transaction.archive.XAResourceArchive;
import org.bytesoft.transaction.logging.ArchiveDeserializer;
import org.bytesoft.transaction.supports.resource.XAResourceDescriptor;
import org.bytesoft.transaction.supports.serialize.XAResourceDeserializer;
import org.bytesoft.transaction.xa.TransactionXid;
import org.bytesoft.transaction.xa.XidFactory;
public class XAResourceArchiveDeserializer implements ArchiveDeserializer, CompensableBeanFactoryAware {
private CompensableBeanFactory beanFactory;
private XAResourceDeserializer deserializer;
public byte[] serialize(TransactionXid xid, Object obj) {
XAResourceArchive archive = (XAResourceArchive) obj;
Xid branchXid = archive.getXid();
byte[] branchQualifier = branchXid.getBranchQualifier();
XAResourceDescriptor descriptor = archive.getDescriptor();
byte[] identifierByteArray = new byte[0];
byte typeByte = 0x0;
if (CommonResourceDescriptor.class.isInstance(descriptor)) {
typeByte = (byte) 0x1;
identifierByteArray = descriptor.getIdentifier().getBytes();
} else if (RemoteResourceDescriptor.class.isInstance(descriptor)) {
typeByte = (byte) 0x2;
identifierByteArray = descriptor.getIdentifier().getBytes();
} else if (LocalXAResourceDescriptor.class.isInstance(descriptor)) {
typeByte = (byte) 0x3;
identifierByteArray = descriptor.getIdentifier().getBytes();
}
byte branchVote = (byte) archive.getVote();
byte readonly = archive.isReadonly() ? (byte) 1 : (byte) 0;
byte committed = archive.isCommitted() ? (byte) 1 : (byte) 0;
byte rolledback = archive.isRolledback() ? (byte) 1 : (byte) 0;
byte completed = archive.isCompleted() ? (byte) 1 : (byte) 0;
byte heuristic = archive.isHeuristic() ? (byte) 1 : (byte) 0;
byte[] byteArray = new byte[XidFactory.BRANCH_QUALIFIER_LENGTH + 2 + identifierByteArray.length + 6];
System.arraycopy(branchQualifier, 0, byteArray, 0, branchQualifier.length);
byteArray[XidFactory.BRANCH_QUALIFIER_LENGTH] = typeByte;
byteArray[XidFactory.BRANCH_QUALIFIER_LENGTH + 1] = (byte) identifierByteArray.length;
if (identifierByteArray.length > 0) {
System.arraycopy(identifierByteArray, 0, byteArray, XidFactory.BRANCH_QUALIFIER_LENGTH + 2,
identifierByteArray.length);
}
byteArray[XidFactory.BRANCH_QUALIFIER_LENGTH + 2 + identifierByteArray.length] = branchVote;
byteArray[XidFactory.BRANCH_QUALIFIER_LENGTH + 2 + identifierByteArray.length + 1] = readonly;
byteArray[XidFactory.BRANCH_QUALIFIER_LENGTH + 2 + identifierByteArray.length + 2] = committed;
byteArray[XidFactory.BRANCH_QUALIFIER_LENGTH + 2 + identifierByteArray.length + 3] = rolledback;
byteArray[XidFactory.BRANCH_QUALIFIER_LENGTH + 2 + identifierByteArray.length + 4] = completed;
byteArray[XidFactory.BRANCH_QUALIFIER_LENGTH + 2 + identifierByteArray.length + 5] = heuristic;
return byteArray;
}
public Object deserialize(TransactionXid xid, byte[] array) {
ByteBuffer buffer = ByteBuffer.wrap(array);
XAResourceArchive archive = new XAResourceArchive();
byte[] branchQualifier = new byte[XidFactory.BRANCH_QUALIFIER_LENGTH];
buffer.get(branchQualifier);
XidFactory xidFactory = this.beanFactory.getCompensableXidFactory();
TransactionXid branchXid = xidFactory.createBranchXid(xid, branchQualifier);
archive.setXid(branchXid);
byte resourceType = buffer.get();
byte length = buffer.get();
byte[] byteArray = new byte[length];
buffer.get(byteArray);
String identifier = new String(byteArray);
XAResourceDescriptor descriptor = null;
if (resourceType == 0x01) {
archive.setIdentified(true);
descriptor = deserializer.deserialize(identifier);
} else if (resourceType == 0x02) {
archive.setIdentified(true);
descriptor = deserializer.deserialize(identifier);
} else if (resourceType == 0x03) {
archive.setIdentified(true);
descriptor = deserializer.deserialize(identifier);
} else {
descriptor = new UnidentifiedResourceDescriptor();
}
if (CommonResourceDescriptor.class.isInstance(descriptor)) {
((CommonResourceDescriptor) descriptor).setRecoverXid(branchXid);
}
archive.setDescriptor(descriptor);
int branchVote = buffer.get();
int readonly = buffer.get();
int committedValue = buffer.get();
int rolledbackValue = buffer.get();
int completedValue = buffer.get();
int heuristicValue = buffer.get();
archive.setVote(branchVote);
archive.setReadonly(readonly != 0);
archive.setCommitted(committedValue != 0);
archive.setRolledback(rolledbackValue != 0);
archive.setCompleted(completedValue != 0);
archive.setHeuristic(heuristicValue != 0);
return archive;
}
public void setBeanFactory(CompensableBeanFactory tbf) {
this.beanFactory = tbf;
}
public XAResourceDeserializer getDeserializer() {
return deserializer;
}
public void setDeserializer(XAResourceDeserializer deserializer) {
this.deserializer = deserializer;
}
}