[jboss-svn-commits] JBL Code SVN: r13080 - in labs/jbosstm/workspace/maciej.machulak/code/bridge: org and 14 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Jul 4 12:06:44 EDT 2007
Author: maciej.machulak
Date: 2007-07-04 12:06:44 -0400 (Wed, 04 Jul 2007)
New Revision: 13080
Added:
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/JaxWSServerHeaderContextProcessor.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/BridgeParticipantAT.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/DummyParticipantAT.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/InboundBridge.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/JaxWSTransactionBridgeHandler.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/JaxWSTransactionSpecifierHandler.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/TxBridgeManager.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/BATransactionManager.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/SingleTransactionManager.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAAgreement.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAAgreementType.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensatedBy.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationIdentifier.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationManagement.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationType.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAParam.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAProperties.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAResult.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAService.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAServiceType.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/JaxWSBALoggingAspect.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/JaxWSBAProcessingAspect.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager2.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager2Impl.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManagerImpl.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationService.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationServiceImpl.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/ServiceExecutor.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ClassInformation.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationData.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataCustom.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataParam.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataReturn.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/IdentificationType.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/MethodInformation.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ServiceDescription.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ServiceDescriptionImpl.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/SimpleClassInformation.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/SimpleMethodInformation.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/CompensationActionUnsuccessfulException.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/CompensationMethodNotAccessible.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/MethodIncorrectlyAnnotatedException.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/TaskAssociationFailedException.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/CorbaExecution.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/ExecutionInterface.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/LocalExecution.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/LocalServiceExecutor.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/RMIExecution.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/RemoteServiceExecutor.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/ServiceExecutor.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/WSConfiguredDII.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/WSUnconfiguredDII.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/BAServiceVisitor.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ClassBAVisitor.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ClassInformationManager.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ServiceInformationManager.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/IdentifierFactory.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/RandomGetter.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/RandomIdentifierFactory.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UidGetter.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UidIdentifierFactory.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UniqueValueGetter.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JBossServiceAccessFactory.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JaxWSBASpecifierHandler.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JaxWSBusinessActivityHandler.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/SOAPProcessor.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/ServiceAccessFactory.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/CoordinatorCompletionParticipantBA.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/CoordinatorCompletionParticipantBA1.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/Participant.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/ParticipantCompletionParticipantBA.java
labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/ParticipantCompletionParticipantBA1.java
Log:
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/JaxWSServerHeaderContextProcessor.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/JaxWSServerHeaderContextProcessor.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/JaxWSServerHeaderContextProcessor.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,273 @@
+package org.jboss.txbridge;
+
+import org.apache.log4j.Logger;
+
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPHandler;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+import javax.xml.namespace.QName;
+import javax.xml.soap.*;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import com.arjuna.webservices.wscoor.CoordinationConstants;
+import com.arjuna.webservices.wscoor.CoordinationContextType;
+import com.arjuna.webservices.wsat.AtomicTransactionConstants;
+import com.arjuna.webservices.wsba.BusinessActivityConstants;
+import com.arjuna.mw.wst.common.CoordinationContextHelper;
+import com.arjuna.mw.wst.common.SOAPUtil;
+import com.arjuna.mw.wst.*;
+
+
+/**
+ * TODO: make this play nice alongside com.arjuna.mw.wst.service.JaxRPCHeaderContextProcessor
+ * - factor out common base class or suchlike
+ */
+public class JaxWSServerHeaderContextProcessor implements SOAPHandler
+{
+ private static Logger log = Logger.getLogger(JaxWSServerHeaderContextProcessor.class);
+
+ private String handlerName;
+
+ public String getHandlerName()
+ {
+ return handlerName;
+ }
+
+ public void setHandlerName(String handlerName)
+ {
+ this.handlerName = handlerName;
+ }
+
+ public boolean handleMessage(MessageContext msgContext)
+ {
+ Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ if (outbound == null)
+ throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+
+ return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
+ }
+
+
+ public boolean handleFault(MessageContext messagecontext)
+ {
+ suspendTransaction() ;
+ return true;
+ }
+
+ public void close(MessageContext messageContext)
+ {
+ }
+
+ public String toString()
+ {
+ return (handlerName != null ? handlerName : super.toString());
+ }
+
+
+
+ // The header blocks that can be processed by this Handler instance
+ private Set<QName> headers = new HashSet<QName>();
+
+ /** Gets the header blocks that can be processed by this Handler instance.
+ */
+ public Set<QName> getHeaders()
+ {
+ log.info("getHeaders");
+
+ Set<QName> headerSet = new HashSet<QName>();
+ headerSet.add(new QName(CoordinationConstants.WSCOOR_NAMESPACE, CoordinationConstants.WSCOOR_ELEMENT_COORDINATION_CONTEXT));
+
+ return headerSet;
+ }
+
+ /** Sets the header blocks that can be processed by this Handler instance.
+ */
+ public void setHeaders(Set<QName> headers)
+ {
+ this.headers = headers;
+ }
+
+
+
+ protected boolean handleInbound(MessageContext msgContext)
+ {
+ log.info("handleInbound");
+/*
+ try
+ {
+ SOAPMessage soapMessage = ((SOAPMessageContext)msgContext).getMessage();
+ SOAPHeader soapHeader = soapMessage.getSOAPHeader();
+ SOAPBody soapBody = soapMessage.getSOAPBody();
+
+ SOAPFactory soapFactory = SOAPFactory.newInstance();
+ Name headerName = soapFactory.createName("LogHandlerInbound", "ns1", "http://somens");
+ SOAPHeaderElement she = soapHeader.addHeaderElement(headerName);
+ she.setValue("true");
+
+ SOAPBodyElement soapBodyElement = (SOAPBodyElement)soapBody.getChildElements().next();
+ SOAPElement soapElement = (SOAPElement)soapBodyElement.getChildElements().next();
+ String value = soapElement.getValue();
+ soapElement.setValue(value + "|LogIn");
+ }
+ catch (SOAPException e)
+ {
+ throw new WebServiceException(e);
+ }
+*/
+
+ final SOAPMessageContext soapMessageContext = (SOAPMessageContext)msgContext ;
+ final SOAPMessage soapMessage = soapMessageContext.getMessage() ;
+
+ if (soapMessage != null)
+ {
+ try
+ {
+ final SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope() ;
+ final SOAPHeader soapHeader = soapEnvelope.getHeader() ;
+ final SOAPHeaderElement soapHeaderElement = getHeaderElement(soapHeader, CoordinationConstants.WSCOOR_NAMESPACE, CoordinationConstants.WSCOOR_ELEMENT_COORDINATION_CONTEXT) ;
+
+ if (soapHeaderElement != null)
+ {
+ final CoordinationContextType cc = CoordinationContextHelper.deserialise(soapEnvelope, soapHeaderElement) ;
+ final String coordinationType = cc.getCoordinationType().getValue() ;
+ if (AtomicTransactionConstants.WSAT_PROTOCOL.equals(coordinationType))
+ {
+ final TxContext txContext = new com.arjuna.mwlabs.wst.at.context.TxContextImple(cc) ;
+ TransactionManagerFactory.transactionManager().resume(txContext) ;
+ clearMustUnderstand(soapHeader, soapHeaderElement) ;
+ }
+ else if (BusinessActivityConstants.WSBA_PROTOCOL_ATOMIC_OUTCOME.equals(coordinationType))
+ {
+ final TxContext txContext = new com.arjuna.mwlabs.wst.ba.context.TxContextImple(cc);
+ BusinessActivityManagerFactory.businessActivityManager().resume(txContext) ;
+ clearMustUnderstand(soapHeader, soapHeaderElement) ;
+ }
+ else
+ {
+ log.warn("handleInbound: unknown type="+coordinationType);
+ }
+ }
+ }
+ catch (final Throwable th)
+ {
+ log.warn("handleInbound: ", th);
+ }
+ }
+ return true ;
+ }
+
+
+ protected boolean handleOutbound(MessageContext msgContext)
+ {
+ log.info("handleOutbound");
+ suspendTransaction() ;
+/*
+ try
+ {
+ SOAPMessage soapMessage = ((SOAPMessageContext)msgContext).getMessage();
+ SOAPHeader soapHeader = soapMessage.getSOAPHeader();
+ SOAPBody soapBody = soapMessage.getSOAPBody();
+
+ SOAPFactory soapFactory = SOAPFactory.newInstance();
+ Name headerName = soapFactory.createName("LogHandlerOutbound", "ns1", "http://somens");
+ SOAPHeaderElement she = soapHeader.addHeaderElement(headerName);
+ she.setValue("true");
+
+ SOAPBodyElement soapBodyElement = (SOAPBodyElement)soapBody.getChildElements().next();
+ SOAPElement soapElement = (SOAPElement)soapBodyElement.getChildElements().next();
+ String value = soapElement.getValue();
+ soapElement.setValue(value + "|LogOut");
+ }
+ catch (SOAPException e)
+ {
+ throw new WebServiceException(e);
+ }
+*/
+ return true;
+ }
+
+ private void suspendTransaction()
+ {
+ try
+ {
+ /*
+ * There should either be an Atomic Transaction *or* a Business Activity
+ * associated with the thread.
+ */
+ final TransactionManager transactionManager = TransactionManagerFactory.transactionManager() ;
+ final BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager() ;
+
+ if (transactionManager != null)
+ {
+ transactionManager.suspend() ;
+ }
+
+ if (businessActivityManager != null)
+ {
+ businessActivityManager.suspend() ;
+ }
+ }
+ catch (final Throwable th)
+ {
+ log.warn("suspendTransaction", th);
+ }
+ }
+
+ private SOAPHeaderElement getHeaderElement(final SOAPHeader soapHeader, final String uri, final String name)
+ throws SOAPException
+ {
+ if (soapHeader != null)
+ {
+ final Iterator headerIter = SOAPUtil.getChildElements(soapHeader) ;
+ while(headerIter.hasNext())
+ {
+ final SOAPHeaderElement current = (SOAPHeaderElement)headerIter.next() ;
+ final Name currentName = current.getElementName() ;
+ if ((currentName != null) &&
+ match(name, currentName.getLocalName()) &&
+ match(uri, currentName.getURI()))
+ {
+ return current ;
+ }
+ }
+ }
+ return null ;
+ }
+
+ /**
+ * Do the two references match?
+ * @param lhs The first reference.
+ * @param rhs The second reference.
+ * @return true if the references are both null or if they are equal.
+ */
+ private boolean match(final Object lhs, final Object rhs)
+ {
+ if (lhs == null)
+ {
+ return (rhs == null) ;
+ }
+ else
+ {
+ return lhs.equals(rhs) ;
+ }
+ }
+
+ /**
+ * Clear the soap MustUnderstand.
+ * @param soapHeader The SOAP header.
+ * @param soapHeaderElement The SOAP header element.
+ */
+ private void clearMustUnderstand(final SOAPHeader soapHeader, final SOAPHeaderElement soapHeaderElement)
+ throws SOAPException
+ {
+ final Name headerName = soapHeader.getElementName() ;
+
+ final SOAPFactory factory = SOAPFactory.newInstance() ;
+ final Name attributeName = factory.createName("mustUnderstand", headerName.getPrefix(), headerName.getURI()) ;
+
+ soapHeaderElement.removeAttribute(attributeName) ;
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/BridgeParticipantAT.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/BridgeParticipantAT.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/BridgeParticipantAT.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,154 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, 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) 2007,
+ * @author JBoss Inc.
+ */
+package org.jboss.txbridge.at;
+
+import com.arjuna.wst.*;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.XATerminatorImple;
+import org.apache.log4j.Logger;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+
+/**
+ * Provides mapping between WS-AT Participant interface
+ * and an underlying JTA subtransaction coordinator.
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class BridgeParticipantAT implements Durable2PCParticipant
+{
+ private static Logger log = Logger.getLogger(BridgeParticipantAT.class);
+
+ private XATerminatorImple xaTerminator;
+ private Xid xid;
+
+ BridgeParticipantAT(XATerminatorImple xaTerminator, Xid xid)
+ {
+ log.info("BridgeParticipantAT(XATerminatorImple="+xaTerminator+", Xid="+xid+")");
+
+ this.xaTerminator = xaTerminator;
+ this.xid = xid;
+ }
+
+ /**
+ *
+ *
+ * Perform any work necessary to allow it to either commit or rollback
+ * the work performed by the Web service under the scope of the
+ * transaction. The implementation is free to do whatever it needs to in
+ * order to fulfill the implicit contract between it and the coordinator.
+ *
+ * @return an indication of whether it can prepare or not.
+ * @see com.arjuna.wst.Vote
+ */
+ public Vote prepare() throws WrongStateException, SystemException
+ {
+ log.info("prepare(Xid="+xid+")");
+
+ try {
+ // XAResource.XA_OK, XAResource.XA_RDONLY or exception. if RDONLY, don't call commit
+ int result = xaTerminator.prepare(xid);
+ if(result == XAResource.XA_OK) {
+ log.info("prepare on Xid="+xid+" returning Prepared");
+ return new Prepared();
+ } else {
+ log.info("prepare on Xid="+xid+" returning ReadOnly");
+ return new ReadOnly();
+ }
+
+ } catch(XAException e) {
+ log.info("prepare on Xid="+xid+" returning Aborted", e);
+ return new Aborted();
+ }
+ }
+
+ /**
+ *
+ *
+ * The participant should make permanent the work that it controls.
+ *
+ * @throws WrongStateException
+ * @throws SystemException
+ */
+ public void commit() throws WrongStateException, SystemException
+ {
+ log.info("commit(Xid="+xid+")");
+
+ try
+ {
+ xaTerminator.commit(xid, false);
+ log.info("commit on Xid="+xid+" OK");
+ }
+ catch (XAException e)
+ {
+ log.info("commit on Xid="+xid+" failed", e);
+ }
+ }
+
+ /**
+ *
+ *
+ * The participant should undo the work that it controls. The participant
+ * will then return an indication of whether or not it succeeded..
+ *
+ * @throws WrongStateException
+ * @throws SystemException
+ */
+ public void rollback() throws WrongStateException, SystemException
+ {
+ log.info("rollback(Xid="+xid+")");
+
+ try
+ {
+ xaTerminator.rollback(xid);
+ log.info("rollback on Xid="+xid+" OK");
+ }
+ catch (XAException e)
+ {
+ log.info("rollback on Xid="+xid+" failed", e);
+ }
+ }
+
+ /**
+ * During recovery the participant can enquire as to the status of the
+ * transaction it was registered with. If that transaction is no longer
+ * available (has rolled back) then this operation will be invoked by the
+ * coordination service.
+ */
+ public void unknown() throws SystemException
+ {
+ log.info("unknown(Xid="+xid+"): NOT IMPLEMENTED");
+ // used for calbacks during crash recovery. This impl is not recoverable
+ }
+
+ /**
+ * During recovery the participant can enquire as to the status of the
+ * transaction it was registered with. If an error occurs (e.g., the
+ * transaction service is unavailable) then this operation will be invoked.
+ */
+ public void error() throws SystemException
+ {
+ log.info("error(Xid="+xid+"): NOT IMPLEMENTED");
+ // used for calbacks during crash recovery. This impl is not recoverable
+ }
+}
+
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/DummyParticipantAT.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/DummyParticipantAT.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/DummyParticipantAT.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,42 @@
+package org.jboss.txbridge.at;
+
+import com.arjuna.wst.*;
+import org.apache.log4j.Logger;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class DummyParticipantAT implements Durable2PCParticipant {
+
+
+ public DummyParticipantAT() {
+ log.info("constructor");
+ }
+
+ private static Logger log = Logger.getLogger(DummyParticipantAT.class);
+
+ public Vote prepare() throws WrongStateException, SystemException {
+ log.info("prepare()");
+ return new Prepared();
+ }
+
+ public void commit() throws WrongStateException, SystemException {
+ log.info("commit()");
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void rollback() throws WrongStateException, SystemException {
+ log.info("rollback()");
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void unknown() throws SystemException {
+ log.info("unknown()");
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void error() throws SystemException {
+ log.info("error()");
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/InboundBridge.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/InboundBridge.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/InboundBridge.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,110 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, 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) 2007,
+ * @author JBoss Inc.
+ */
+package org.jboss.txbridge.at;
+
+import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TxImporter;
+import com.arjuna.ats.jta.TransactionManager;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.InvalidTransactionException;
+
+
+import org.apache.log4j.Logger;
+
+/**
+ * Manages Thread association of the interposed coordinator.
+ * Typically called from handlers in the WS stack.
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class InboundBridge
+{
+ private static Logger log = Logger.getLogger(InboundBridge.class);
+
+ private Xid xid;
+
+ InboundBridge(Xid xid) throws XAException, SystemException {
+ log.info("InboundBridge(Xid="+xid+")");
+
+ this.xid = xid;
+
+ getTransaction(); // ensures transaction is initialized
+ }
+
+ /**
+ * Associate the JTA transaction to the current Thread.
+ * Typically used by a server side inbound handler.
+ *
+ * @throws XAException
+ * @throws SystemException
+ * @throws InvalidTransactionException
+ */
+ public void start() throws XAException, SystemException, InvalidTransactionException {
+ log.info("start(Xid="+xid+")");
+
+ TransactionImple tx = getTransaction();
+
+ TransactionManager.transactionManager().resume(tx);
+ }
+
+ /**
+ * Disassociate the JTA transaction from the current Thread.
+ * Typically used by a server side outbound handler.
+ *
+ * @throws XAException
+ * @throws SystemException
+ * @throws InvalidTransactionException
+ */
+ public void stop() throws XAException, SystemException, InvalidTransactionException {
+ log.info("stop("+xid+")");
+
+ TransactionImple tx = getTransaction();
+
+ TransactionManager.transactionManager().suspend();
+ }
+
+ /**
+ * Get the JTA Transaction which corresponds to the Xid of the instance.
+ *
+ * @return
+ * @throws XAException
+ * @throws SystemException
+ */
+ private TransactionImple getTransaction()
+ throws XAException, SystemException
+ {
+ // TODO: make jta/jts pluggable - diff TxImporters hence InboundBridges ?
+ TransactionImple tx = TxImporter.importTransaction(xid);
+
+ switch (tx.getStatus())
+ {
+ case Status.STATUS_ACTIVE:
+ break;
+ default:
+ throw new IllegalStateException("Transaction not in state ACTIVE");
+ }
+ return tx;
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/JaxWSTransactionBridgeHandler.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/JaxWSTransactionBridgeHandler.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/JaxWSTransactionBridgeHandler.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,261 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, 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) 2007,
+ * @author JBoss Inc.
+ */
+package org.jboss.txbridge.at;
+
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+
+import org.apache.log4j.Logger;
+
+/**
+ * A handler that sits in the server side processing pipeline between the XTS header context processor
+ * and the web service. Takes the WS transaction context provided by the former and maps
+ * it to a JTA transaction context for use by the latter. Handles Thread association of
+ * the JTA context.
+ *
+ * Note: we assume that their is a web services transaction context present and
+ * that the service needs a JTA context. The handler should not be registered on
+ * methods unless both these conditions hold.
+ * TODO: make this more flexible (ws-at policy and/or lazy init of JTA context.)
+ *
+ * TODO: provide a JAX-RPC version of this handler too?
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class JaxWSTransactionBridgeHandler implements Handler
+{
+ private static Logger log = Logger.getLogger(JaxWSTransactionBridgeHandler.class);
+
+ /**
+ * Process a message. Determins if it's inbound or outbound and dispatches accordingly.
+ *
+ * @param msgContext
+ * @return
+ */
+ public boolean handleMessage(MessageContext msgContext)
+ {
+ log.debug("handleMessage()");
+
+ Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ if (outbound == null)
+ throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+
+ return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
+ }
+
+ /**
+ * Tidy up the Transaction/Thread association before faults are thrown back to the client.
+ *
+ * @param messageContext
+ * @return
+ */
+ public boolean handleFault(MessageContext messageContext)
+ {
+ log.debug("handleFault()");
+ String transactionType = (String) messageContext.get("TransactionAttributeType");
+
+ if (transactionType == null)
+ {
+ log.info("transactionType is null");
+ return true;
+ }
+ else if ( transactionType.equals("MANDATORY"))
+ {
+ log.info("transactionType is mandatory");
+ suspendTransaction();
+ }
+ else if ( transactionType.equals("REQUIRED"))
+ {
+ log.info("transactionType is required");
+ suspendTransaction();
+ }
+ else if ( transactionType.equals("REQUIRES_NEW "))
+ {
+ log.info("transactionType is requires_new");
+ return true;
+ }
+ else if ( transactionType.equals("SUPPORTS"))
+ {
+ log.info("transactionType is supports");
+ suspendTransaction();
+ }
+ else if ( transactionType.equals("NOT_SUPPORTED"))
+ {
+ log.info("transactionType is not_supported");
+ return true;
+ }
+ return true;
+ }
+
+ public void close(MessageContext messageContext)
+ {
+ log.debug("close()");
+ }
+
+ /**
+ * Process inbound messages by mapping the WS transaction context
+ * to a JTA one and associating the latter to the current Thread.
+ *
+ * @param msgContext
+ * @return
+ */
+ protected boolean handleInbound(MessageContext msgContext)
+ {
+ log.debug("handleInbound()");
+ String transactionType = (String) msgContext.get("TransactionAttributeType");
+
+ // If there was no WS transaction
+ if (transactionType == null)
+ {
+ log.info("transactionType is null");
+ return true;
+ }
+
+ // If there is a WS transaction
+
+ // If the method must be executed within a transaction
+ if ( transactionType.equals("MANDATORY"))
+ {
+ log.info("transactionType is mandatory");
+ try
+ {
+ InboundBridge inboundBridge = org.jboss.txbridge.at.TxBridgeManager.getInboundBridge();
+ inboundBridge.start();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ return false;
+ }
+ }
+ // If the method needs a transaction (either by client or its own)
+ else if ( transactionType.equals("REQUIRED"))
+ {
+ log.info("transactionType is required");
+ try
+ {
+ InboundBridge inboundBridge = org.jboss.txbridge.at.TxBridgeManager.getInboundBridge();
+ inboundBridge.start();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ return false;
+ }
+ }
+ // If the method will start a new transaction anyway
+ else if ( transactionType.equals("REQUIRES_NEW "))
+ {
+ log.info("transactionType is requires_new");
+ return true;
+ }
+ // If the method does not care
+ else if ( transactionType.equals("SUPPORTS"))
+ {
+ log.info("transactionType is supports");
+ try
+ {
+ InboundBridge inboundBridge = org.jboss.txbridge.at.TxBridgeManager.getInboundBridge();
+ inboundBridge.start();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ return false;
+ }
+
+ }
+ // If the method does not support a transaction
+ else if ( transactionType.equals("NOT_SUPPORTED"))
+ {
+ log.info("transactionType is not_supported");
+ try
+ {
+ org.jboss.txbridge.at.TxBridgeManager.startDummyTransaction();
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Tidy up the Transaction/Thread association before returning a message to the client.
+ *
+ * @param msgContext
+ * @return
+ */
+ protected boolean handleOutbound(MessageContext msgContext) {
+ log.debug("handleOutbound()");
+ String transactionType = (String) msgContext.get("TransactionAttributeType");
+
+ if (transactionType == null)
+ {
+ log.info("transactionType is null");
+ return true;
+ }
+ else if ( transactionType.equals("MANDATORY"))
+ {
+ suspendTransaction();
+ }
+ else if ( transactionType.equals("REQUIRED"))
+ {
+ log.info("transactionType is required");
+ suspendTransaction();
+ }
+ else if ( transactionType.equals("REQUIRES_NEW "))
+ {
+ log.info("transactionType is requires_new");
+ return true;
+ }
+ else if ( transactionType.equals("SUPPORTS"))
+ {
+ log.info("transactionType is supports");
+ suspendTransaction();
+ }
+ else if ( transactionType.equals("NOT_SUPPORTED"))
+ {
+ log.info("transactionType is not supported");
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Break the association between the JTA transaction context and the calling Thread.
+ */
+ private void suspendTransaction() {
+ log.debug("suspendTransaction()");
+
+ try
+ {
+ InboundBridge inboundBridge = org.jboss.txbridge.at.TxBridgeManager.getInboundBridge();
+ inboundBridge.stop();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ }
+ }
+}
\ No newline at end of file
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/JaxWSTransactionSpecifierHandler.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/JaxWSTransactionSpecifierHandler.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/JaxWSTransactionSpecifierHandler.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,158 @@
+package org.jboss.txbridge.at;
+
+import org.apache.log4j.Logger;
+import org.jboss.ws.core.soap.MessageContextAssociation;
+import org.jboss.ws.core.CommonMessageContext;
+import org.jboss.ws.metadata.umdm.EndpointMetaData;
+
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.soap.SOAPBodyElement;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPException;
+import javax.jws.WebMethod;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.lang.reflect.Method;
+import java.io.IOException;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class JaxWSTransactionSpecifierHandler implements Handler
+{
+ private static Logger log = Logger.getLogger(JaxWSTransactionSpecifierHandler.class);
+ private static List<String> cacheList = new ArrayList<String>();
+ private static HashMap<String,String> methodMappings = new HashMap<String,String>();
+ private static TransactionAttributeType defaultAttribute = TransactionAttributeType.REQUIRED;
+
+ public JaxWSTransactionSpecifierHandler()
+ {
+ }
+
+ public boolean handleMessage(MessageContext msgContext)
+ {
+ log.debug("handleMessage()");
+
+ Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ if (outbound == null)
+ {
+ throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ }
+ return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
+ }
+
+ private boolean handleInbound(MessageContext msgContext)
+ {
+
+ SOAPMessage msg = ((SOAPMessageContext)msgContext).getMessage();
+ try {
+ msg.writeTo(System.out);
+ } catch (SOAPException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (IOException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ log.debug("handleInbound()");
+
+ try
+ {
+
+ CommonMessageContext commonMessageContext = MessageContextAssociation.peekMessageContext();
+ EndpointMetaData emd = commonMessageContext.getEndpointMetaData();
+ Class clazz = emd.getServiceEndpointInterface();
+ log.info("Class name: " + clazz.getName());
+
+ if (!cacheList.contains(clazz.getName()))
+ {
+ // Get all the methods from the class
+ Method[] methodList = clazz.getDeclaredMethods();
+ log.info("Number of methods: " + methodList.length);
+
+ // Loop through all methods
+ for (Method singleMethod : methodList)
+ {
+ // Check what is the name of the method
+ log.info("Single method: " + singleMethod.getName());
+ String webMethodName = singleMethod.getName();
+
+ // Check if there is a WebMethod annotation
+ WebMethod webMethodAnnotation = singleMethod.getAnnotation(WebMethod.class);
+ if (webMethodAnnotation != null)
+ {
+ log.info("WebMethod annotation: " + webMethodAnnotation.operationName());
+ String name = webMethodAnnotation.operationName();
+ if (name != null && !name.equals(""))
+ {
+ webMethodName = name;
+ }
+ }
+
+ // Get the attribute of the transaction
+ String transactionType = defaultAttribute.toString();
+ TransactionAttribute txAttr = singleMethod.getAnnotation(TransactionAttribute.class);
+ if (txAttr != null)
+ {
+ log.info("TransactionAttribute annotation: " + txAttr.value());
+ // Check the type of the transaction attribute
+ TransactionAttributeType txType = txAttr.value();
+
+ if (txType != null)
+ {
+ transactionType = txType.toString();
+ }
+
+ }
+ // Add the method definition to the methodMapping list
+ log.info("Adding: (" + webMethodName + "," + transactionType + ")");
+ methodMappings.put(webMethodName,transactionType);
+
+ }
+ cacheList.add(clazz.getName());
+ }
+
+ // Get the soap method name
+ SOAPMessage soapMessage = ((SOAPMessageContext)msgContext).getMessage();
+ SOAPBody soapBody = soapMessage.getSOAPBody();
+ SOAPBodyElement soapBodyElement = (SOAPBodyElement)soapBody.getChildElements().next();
+ String methodName = soapBodyElement.getElementName().getLocalName();
+
+ String transactionType = (String) methodMappings.get(methodName);
+ log.info("Mapping: (" + methodName + "," + transactionType + ")");
+
+ msgContext.put("TransactionAttributeType",transactionType);
+
+ }
+ catch (SOAPException soape)
+ {
+ soape.printStackTrace();
+ }
+ return true;
+ }
+
+ private boolean handleOutbound(MessageContext msgContext)
+ {
+ if (msgContext.containsKey("TransactionAttributeType"))
+ {
+ msgContext.remove("TransactionAttributeType");
+ }
+ return true;
+ }
+
+
+ public boolean handleFault(MessageContext messageContext)
+ {
+ log.debug("handleFault()");
+ return true;
+ }
+
+ public void close(MessageContext messageContext)
+ {
+ log.debug("close()");
+ }
+}
\ No newline at end of file
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/TxBridgeManager.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/TxBridgeManager.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/at/TxBridgeManager.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,127 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, 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) 2007,
+ * @author JBoss Inc.
+ */
+package org.jboss.txbridge.at;
+
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.XATerminatorImple;
+import com.arjuna.ats.jta.xa.XidImple;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst.UserTransactionFactory;
+
+import com.arjuna.mw.wst.TransactionManagerFactory;
+import com.arjuna.wst.WrongStateException;
+import com.arjuna.wst.UnknownTransactionException;
+import com.arjuna.wsc.AlreadyRegisteredException;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Maintains the mapping data that relates WS transactions to JTA transactions and related objects.
+ *
+ * The mappings are scoped to the singleton instance of this class and its lifetime.
+ * This poses problems where you have more than one instances (classloading, clusters)
+ * or where you need crash recovery. It short, it's rather limited.
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class TxBridgeManager
+{
+ private static Logger log = Logger.getLogger(TxBridgeManager.class);
+
+ // TODO: make this play nice with the TransactionService in AS, particularly w.r.t recovery.
+ private static XATerminatorImple xaTerminatorImple = new XATerminatorImple();
+
+ private static ConcurrentMap<String, Xid> txIdMappings = new ConcurrentHashMap<String, Xid>();
+
+ private static ConcurrentMap<Xid, InboundBridge> inboundBridgeMappings = new ConcurrentHashMap<Xid, InboundBridge>();
+
+ private static String hello;
+ /**
+ * Create an InboundBridge instance that maps the current Thread's WS transaction context
+ * to a JTA context. Control of the latter is provided by the returned instance.
+ *
+ * @return
+ * @throws WrongStateException
+ * @throws UnknownTransactionException
+ * @throws com.arjuna.wst.SystemException
+ * @throws AlreadyRegisteredException
+ */
+ public static InboundBridge getInboundBridge()
+ throws XAException, WrongStateException, UnknownTransactionException,
+ com.arjuna.wst.SystemException, javax.transaction.SystemException, AlreadyRegisteredException
+ {
+ log.info("getInboundBridge()");
+
+ String externalTxId = UserTransactionFactory.userTransaction().toString();
+
+ Xid xid = txIdMappings.get(externalTxId);
+ if(xid == null) {
+ xid = createMappings(externalTxId);
+ }
+
+ return inboundBridgeMappings.get(xid);
+ }
+
+ /**
+ * Create the JTA transaction mapping and support objects for a given WS transaction context.
+ *
+ * @param externalTxId
+ * @return
+ * @throws WrongStateException
+ * @throws UnknownTransactionException
+ * @throws com.arjuna.wst.SystemException
+ * @throws AlreadyRegisteredException
+ */
+ private static synchronized Xid createMappings(String externalTxId)
+ throws XAException, WrongStateException, UnknownTransactionException,
+ com.arjuna.wst.SystemException, javax.transaction.SystemException, AlreadyRegisteredException {
+ log.info("createMappings(externalIxId="+externalTxId+")");
+
+ if(txIdMappings.containsKey(externalTxId)) {
+ return txIdMappings.get(externalTxId);
+ }
+
+ Xid xid = new XidImple(new Uid());
+ txIdMappings.put(externalTxId, xid);
+ inboundBridgeMappings.put(xid, new InboundBridge(xid));
+
+ // TODO: how do we tell if it's AT or BA?
+ // No implementation independent way, it requires parsind the otherwise opaque externalTxId.
+ // Probably better to have the caller (typically an handler) provide this info?
+
+ BridgeParticipantAT bridgeParticipantAT = new BridgeParticipantAT(xaTerminatorImple, xid);
+ TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(bridgeParticipantAT, new Uid().toString());
+
+ return xid;
+ }
+
+ public static synchronized void startDummyTransaction()
+ throws AlreadyRegisteredException, com.arjuna.wst.SystemException,
+ UnknownTransactionException, WrongStateException
+ {
+ DummyParticipantAT dummyParticipantAT = new DummyParticipantAT();
+ TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(dummyParticipantAT,new Uid().toString());
+ }
+}
\ No newline at end of file
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/BATransactionManager.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/BATransactionManager.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/BATransactionManager.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,307 @@
+package org.jboss.txbridge.ba;
+
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.data.MethodInformation;
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.compensation.CompensationService;
+import org.jboss.txbridge.ba.id.IdentifierFactory;
+import org.jboss.txbridge.ba.id.UidIdentifierFactory;
+import org.jboss.txbridge.ba.helper.BAServiceVisitor;
+import org.jboss.txbridge.ba.helper.ServiceInformationManager;
+import com.arjuna.mw.wst.BusinessActivityManager;
+import com.arjuna.wsc.AlreadyRegisteredException;
+import com.arjuna.wst.SystemException;
+import com.arjuna.wst.UnknownTransactionException;
+import com.arjuna.wst.WrongStateException;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Map;
+import java.lang.reflect.Method;
+
+/**
+ * @author: Maciej Machulak
+ * @date:
+ *
+ *
+ */
+public class BATransactionManager
+{
+ // Logger
+ private static Logger log = Logger.getLogger(BATransactionManager.class);
+
+ // BA Transaction Manager instance
+ private volatile static BATransactionManager baTransactionManager = null;
+
+ // Business Activity manager
+ private BusinessActivityManager businessActivityManager;
+
+ // Service information manager
+ private ServiceInformationManager serviceManager;
+
+ // Compensation Manager
+ private CompensationService compensationService;
+
+ // Mappings:
+ // Business Activity ID <-> Transaction Manager
+ private ConcurrentMap<String, SingleTransactionManager> singleTransactionManagers;
+
+
+ // Constructor
+ private BATransactionManager()
+ {
+ log.info("constructor()");
+
+ // Get reference to the business activity manager
+ businessActivityManager = BusinessActivityManager.getBusinessActivityManager();
+
+ // Get reference to the service manager
+ serviceManager = ServiceInformationManager.getSingletonInstance();
+
+ // Initialise mappings
+ singleTransactionManagers = new ConcurrentHashMap<String, SingleTransactionManager>();
+
+ }
+
+ /**
+ * Returns the instance of the BATRansactionManager object.
+ *
+ * @return the instance of the BATransactionManager.
+ */
+ public static BATransactionManager getSingletonInstance()
+ {
+ log.info("getSingletonInstance()");
+ if (baTransactionManager == null)
+ {
+ synchronized (BATransactionManager.class)
+ {
+ if (baTransactionManager == null)
+ {
+ log.info("Creating new instance...");
+ baTransactionManager = new BATransactionManager();
+ }
+ }
+ }
+ return baTransactionManager;
+ }
+
+ /**
+ * This method handles a transaction for this invocation of a method.
+ *
+ * @param method is the method which is being invoked.
+ * @return the task identifier for this method.
+ */
+ public synchronized String handleTransaction(Method method)
+ {
+ log.info("handleTransaction()");
+ String txId = null;
+ try
+ {
+ // Get the transaction identifier
+ txId = businessActivityManager.currentTransaction().toString();
+ log.info("Transaction identifier: " + txId);
+
+ // If there was a transaction then we can proceed...
+
+ // Process this service if necessary
+ String methodName = method.getName();
+ String className = method.getDeclaringClass().getName();
+ log.info("Class: " + className);
+ log.info("Method: " + methodName);
+ log.info("Checking if the service is known...");
+ if (!serviceManager.knowsAboutByName(className+methodName))
+ {
+ log.info("Service unknown... processing...");
+ ServiceDescription sd = BAServiceVisitor.processMethod(method);
+ serviceManager.storeServiceDescription(sd);
+ }
+ else
+ {
+ log.info("Service already known...");
+ }
+ log.info("Getting service ID.");
+ String serviceId = serviceManager.getServiceId(className+methodName);
+ log.info("Service ID: " + serviceId);
+
+ // Get a reference to a single transaction manager. If there is none - create a new one.
+ SingleTransactionManager stm = singleTransactionManagers.get(txId);
+ if (stm == null)
+ {
+ log.info("Transaction unknown...");
+
+ // Create a new single transaction manager
+ stm = new SingleTransactionManager(txId);
+
+ // Remember it
+ singleTransactionManagers.put(txId,stm);
+ }
+ else
+ {
+ log.info("Transaction already known...");
+ }
+
+ // Process invocation of this service
+
+ // 1) Get a unique task identifier
+ log.info("Getting new task identifier...");
+ IdentifierFactory idf = new UidIdentifierFactory();
+ String taskId = idf.getIdentifier();
+ log.info("Task ID: " + taskId);
+
+ // 2) Delegate transaction management to the single transaction manager
+ log.info("Delegating transaction management.");
+ stm.processInvocation(taskId,serviceId);
+
+ // Return the task identifier
+ return taskId;
+ }
+ catch (Exception se)
+ {
+ se.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * This method compensates a transaction with a given ID. It delegates the compensation management
+ * to an appropriate single transaction manager.
+ *
+ * @param txId is the ID of the transaction which should be compensated.
+ */
+ public synchronized void compensateTransaction(String txId)
+ {
+ // Get the single transaction manager for this transaction and remove it from the list
+ SingleTransactionManager singleTransactionManager = singleTransactionManagers.remove(txId);
+ if (singleTransactionManager == null)
+ {
+ return;
+ }
+
+ // Execute compensation
+ singleTransactionManager.compensate();
+ }
+
+ public synchronized void handleTheTransaction(MethodInformation methodInformation,String taskId)
+ {
+ log.info("handleTheTransaction()");
+ String txId = null;
+ try
+ {
+ // Get the transaction identifier
+ txId = businessActivityManager.currentTransaction().toString();
+ log.info("Transaction identifier: " + txId);
+ log.info("Task identifier: " + taskId);
+
+ // Start the participant
+ associateParticipantBA(txId,methodInformation,taskId);
+ }
+ catch (Exception se)
+ {
+ se.printStackTrace();
+ }
+
+ }
+
+ private synchronized void associateParticipantBA(String txId, MethodInformation methodInformation,String taskId) throws AlreadyRegisteredException, SystemException, UnknownTransactionException, WrongStateException
+ {
+ log.info("associateParticipantBA()");
+
+ // Check if the transaction already has an associated bridge
+ // - if not than create one and pass him method's information
+ SingleTransactionManager baBridge = singleTransactionManagers.get(txId);
+ if (baBridge == null)
+ {
+ // If not... create a new participant
+ baBridge = new SingleTransactionManager(txId);
+
+ // Remember the bridge
+ singleTransactionManagers.put(txId,baBridge);
+
+ }
+ // - if yes then tell the bridge about another method
+ baBridge.start(methodInformation,taskId);
+
+ }
+
+ public synchronized void manageReturnObject(String returnName,Object returnObject,String taskId)
+ {
+ log.info("manageReturnObject()");
+ String txId = null;
+ try
+ {
+ txId = businessActivityManager.currentTransaction().toString();
+ SingleTransactionManager baBridge = singleTransactionManagers.get(txId);
+ if (baBridge != null)
+ {
+ baBridge.addReturnObjectNew(taskId,returnName,returnObject);
+ }
+ }
+ catch (SystemException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public synchronized void manageCustomObjects(Map<String,Object> parameterObjects, String taskId)
+ {
+ log.info("manageCustomObjects()");
+ String txId = null;
+ try
+ {
+ txId = businessActivityManager.currentTransaction().toString();
+ SingleTransactionManager baBridge = singleTransactionManagers.get(txId);
+ if (baBridge != null)
+ {
+ baBridge.addCustomObjects(taskId,parameterObjects);
+ }
+ }
+ catch (SystemException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public synchronized void manageParameterObjects(Object[] parameterObjects, String taskId)
+ {
+ log.info("manageParameterObjects()");
+ String txId = null;
+ try
+ {
+ txId = businessActivityManager.currentTransaction().toString();
+ SingleTransactionManager baBridge = singleTransactionManagers.get(txId);
+ if (baBridge != null)
+ {
+ baBridge.addParameterObjects(taskId,parameterObjects);
+ }
+ }
+ catch (SystemException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public synchronized void completeTransaction()
+ {
+ log.info("completeTransaction()");
+ String txId = null;
+ try
+ {
+ // Check the transaction identifier
+ txId = businessActivityManager.currentTransaction().toString();
+
+ // Get the participant manager
+ SingleTransactionManager baBridge = singleTransactionManagers.get(txId);
+ if (baBridge != null)
+ {
+ baBridge.stop();
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/SingleTransactionManager.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/SingleTransactionManager.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/SingleTransactionManager.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,448 @@
+package org.jboss.txbridge.ba;
+
+import com.arjuna.wst.*;
+import com.arjuna.mw.wst.BusinessActivityManager;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.wsc.AlreadyRegisteredException;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.txbridge.ba.data.MethodInformation;
+import org.jboss.txbridge.ba.data.CompensationDataReturn;
+import org.jboss.txbridge.ba.participant.ParticipantCompletionParticipantBA;
+import org.jboss.txbridge.ba.participant.CoordinatorCompletionParticipantBA;
+import org.jboss.txbridge.ba.participant.Participant;
+import org.jboss.txbridge.ba.participant.ParticipantCompletionParticipantBA1;
+import org.jboss.txbridge.ba.compensation.CompensationServiceImpl;
+import org.jboss.txbridge.ba.compensation.CompensationService;
+import org.jboss.txbridge.ba.helper.ServiceInformationManager;
+import org.jboss.txbridge.ba.exception.TaskAssociationFailedException;
+import org.apache.log4j.Logger;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class SingleTransactionManager
+{
+ // Logger
+ Logger log = Logger.getLogger(SingleTransactionManager.class);
+
+ // Business activity manager
+ BusinessActivityManager businessActivityManager;
+
+ // Service information manager
+ private ServiceInformationManager serviceManager;
+
+ // Transaction identifier
+ private String txId;
+
+ // List of tasks for this transaction
+ private List<String> taskList;
+
+ // (task id , service id) mapping
+ private ConcurrentMap<String,String> taskServiceMapping;
+
+ // (service id , participant) mapping
+ private ConcurrentMap<String,Participant> serviceParticipantMapping;
+
+ // (participant , participant manager) mapping
+ private ConcurrentMap<Participant,BAParticipantManager> participantManagerMapping;
+
+
+
+
+
+ // Mappings
+ // (task,participant)
+ private ConcurrentMap<String, Participant> participantList;
+
+ // Method identifiers mappings (method id,participant)
+ // - participant completion participants
+ private ConcurrentMap<String,ParticipantCompletionParticipantBA> pParticipantCompletionList;
+ // - coordinator completion participants
+ private ConcurrentMap<String, CoordinatorCompletionParticipantBA> pCoordinatorCompletionList;
+
+ // Old
+ private Map<String,String> methodIdList;
+ private Map<String,MethodInformation> methodList;
+ private Map<String,ParticipantCompletionParticipantBA> participant2List;
+ private Map<MethodInformation,Object> returnObjects;
+ private Map<String,Object> newReturnObjects;
+ private Map<MethodInformation,Object[]> compensationObjects;
+ private Map<String,Object[]> newCompensationObjects;
+ private Map<String,Object> temporaryObjects;
+ private Map<String,Object> newTemporaryObjects;
+
+ // List of all participant managers
+ private Map<BAParticipantManager,String> participantManagerList;
+
+ public SingleTransactionManager(String txId)
+ {
+ // Remember the transaction identifier
+ this.txId = txId;
+
+ // Get reference to the business activity manager
+ businessActivityManager = BusinessActivityManager.getBusinessActivityManager();
+
+ // Get reference to the service information manager
+ serviceManager = ServiceInformationManager.getSingletonInstance();
+
+ // Initialise the list of tasks for this transaction
+ taskList = new Stack<String>();
+
+ // Initialise (task id , service id) mapping
+ taskServiceMapping = new ConcurrentHashMap<String,String>();
+
+ // Initialise (service id , participant) mapping
+ serviceParticipantMapping = new ConcurrentHashMap<String,Participant>();
+
+ // Initialise (participant , participant manager mapping)
+ participantManagerMapping = new ConcurrentHashMap<Participant,BAParticipantManager>();
+
+ methodIdList = new HashMap<String,String>();
+ methodList = new HashMap<String, MethodInformation>();
+ participant2List = new HashMap<String, ParticipantCompletionParticipantBA>();
+ returnObjects = new HashMap<MethodInformation,Object>();
+ compensationObjects = new HashMap<MethodInformation,Object[]>();
+ participantManagerList = new HashMap<BAParticipantManager,String>();
+ temporaryObjects = new HashMap<String,Object>();
+ newReturnObjects = new HashMap<String,Object>();
+ newCompensationObjects = new HashMap<String,Object[]>();
+ newTemporaryObjects = new HashMap<String,Object>();
+ businessActivityManager = BusinessActivityManager.getBusinessActivityManager();
+
+ // Register itself with the compensation service
+ CompensationService cs = CompensationServiceImpl.getSingletonInstance();
+ cs.registerBridge(txId,this);
+
+ }
+
+ /**
+ * This method processes a single invocation within a scope of a transaction this single transaction
+ * manager is responsible for. It either creates a new participant for the service that is being invoked
+ * or associates this invocation with an existing participant.
+ *
+ * @param taskId is the task identifier.
+ * @param serviceId is the service identifier.
+ */
+ public void processInvocation(String taskId, String serviceId)
+ {
+ log.info("processInvocation()");
+
+ // If the manager is aware of this task simply return
+ if (taskList.contains(taskId) || taskServiceMapping.containsKey(taskId))
+ {
+ log.info("Task is already known. Exiting...");
+ return;
+ }
+
+ // Remember the task and its service
+ log.info("Remember the task and the service...");
+ taskList.add(taskId);
+ taskServiceMapping.put(taskId,serviceId);
+
+ // Check if there is an existing participant associated with this service and transaction
+ log.info("Checking for participant...");
+ Participant participant = serviceParticipantMapping.get(serviceId);
+ if ( participant == null )
+ {
+ log.info("Participant unknown. Creating new one.");
+
+ // Create a new participant
+ participant = new ParticipantCompletionParticipantBA1(txId,serviceId);
+
+ // Remember the participant
+ serviceParticipantMapping.put(serviceId,participant);
+
+ // Enlist the participant
+ try
+ {
+ BAParticipantManager participantManager = businessActivityManager.enlistForBusinessAgreementWithParticipantCompletion((BusinessAgreementWithParticipantCompletionParticipant)participant,new Uid().toString());
+
+ // Remember the participant manager for this specific participant
+ participantManagerMapping.put(participant,participantManager);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Associate the task with the participant
+ try
+ {
+ participant.associateTask(taskId);
+ }
+ catch (TaskAssociationFailedException e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * This method executes compensation for all tasks that are associated with this transaction.
+ * Compensation happens in reverse order.
+ */
+ public void compensate()
+ {
+ log.info("compensate()");
+ // Loop through all the tasks and compensate each task separately
+ while (!taskList.isEmpty())
+ {
+ // Get the task from the top
+ log.info("Getting task from the top.");
+ String taskId = (String) ((Stack)taskList).pop();
+ log.info("Task ID: " + taskId);
+
+ // Get reference to the required participant
+ String serviceId = taskServiceMapping.get(taskId);
+ if ( serviceId != null )
+ {
+ log.info("This task is associated with service ID: " + serviceId);
+ Participant participant = serviceParticipantMapping.get(serviceId);
+ if ( participant != null )
+ {
+ log.info("Participant found for this service. Compensating...");
+ // Order the participant to compensate a given single task
+ participant.compensateTask(taskId);
+
+ }
+ }
+ }
+
+
+ }
+
+ public void start(MethodInformation methodInfo,String taskId)
+ {
+ log.info("start()");
+ try
+ {
+ log.info("creating new participant");
+ ParticipantCompletionParticipantBA participant = new ParticipantCompletionParticipantBA(txId,taskId,methodInfo);
+ log.info("getting participant manager");
+ BAParticipantManager participantManager = businessActivityManager.enlistForBusinessAgreementWithParticipantCompletion(participant,new Uid().toString());
+
+ log.info("remembering mappings");
+ methodIdList.put(taskId,methodInfo.getOriginalMethod());
+ methodList.put(methodInfo.getOriginalMethod(),methodInfo);
+ participant2List.put(taskId,participant);
+ participantManagerList.put(participantManager,methodInfo.getServiceType());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void stop()
+ {
+ log.info("stop()");
+ try
+ {
+ for ( BAParticipantManager pManager : participantManagerList.keySet())
+ {
+ log.info("Using participant manager.");
+ String serviceType = participantManagerList.get(pManager);
+ if (serviceType.equals("READONLY"))
+ {
+ log.info("Service was 'read-only'. Exiting...");
+ pManager.exit();
+ participantManagerList.remove(pManager);
+ }
+ else if (serviceType.equals("MODIFY"))
+ {
+ log.info("Service was 'modify'. Completing...");
+ pManager.completed();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void rollback()
+ {
+ log.info("rollback()");
+ }
+
+ // Add new compensation object
+ public void addReturnObject(String methodName,Object object)
+ {
+ log.info("addReturnObject()");
+ MethodInformation methodInfo = methodList.get(methodName);
+ if (methodInfo != null)
+ {
+ returnObjects.put(methodInfo,object);
+ }
+ }
+
+ // Add new compensation object
+ public void addReturnObjectNew(String id,String returnName,Object object)
+ {
+ log.info("addReturnObjectNew()");
+ ParticipantCompletionParticipantBA participant = participant2List.get(id);
+ if (participant != null)
+ {
+ log.info("participant found");
+ CompensationDataReturn cd = participant.getCompensationData();
+ cd.addReturnObject(returnName,object);
+ participant.setCompensationData(cd);
+ }
+ }
+
+ public void addParameterObjects(String id, Object[] objects)
+ {
+ log.info("addParameterObjects()");
+ ParticipantCompletionParticipantBA participant = participant2List.get(id);
+ if (participant != null)
+ {
+ log.info("participant found");
+ CompensationDataReturn cd = participant.getCompensationData();
+ cd.setParameterObjects(objects);
+ participant.setCompensationData(cd);
+ }
+ }
+
+ public void addCustomObjects(String id, Map<String,Object> objects)
+ {
+ log.info("addCustomObjects()");
+ ParticipantCompletionParticipantBA participant = participant2List.get(id);
+ if (participant != null)
+ {
+ log.info("participant found");
+ CompensationDataReturn cd = participant.getCompensationData();
+ cd.putPrimaryObjects(objects);
+ participant.setCompensationData(cd);
+ }
+ }
+
+ public void addCustomObject(String id, String objectId,Object object)
+ {
+ log.info("addCustomObject()");
+ ParticipantCompletionParticipantBA participant = participant2List.get(id);
+ if (participant != null)
+ {
+ log.info("participant found");
+ CompensationDataReturn cd = participant.getCompensationData();
+ cd.putPrimary(objectId,object);
+ participant.setCompensationData(cd);
+ }
+ }
+
+ // Add new compensation object
+ public void addTemporaryObject(String taskId,String identifier, Object object)
+ {
+ log.info("addTemporaryObject()");
+ newTemporaryObjects.put(taskId+identifier,object);
+ //MethodInformation methodInfo = methodList.get(methodName);
+ //if (methodInfo != null)
+ //{
+ // // Get the name of the compensation method
+ // String compensationMethod = methodInfo.getCompensationMethod();
+ // temporaryObjects.put(compensationMethod+identifier,object);
+ //}
+ }
+
+ // Return a compensation object for a given transaction
+ public Object getTemporaryObject(String taskIdentifier,String identifier)
+ {
+ log.info("getTemporaryObject()");
+ return newTemporaryObjects.get(taskIdentifier+identifier);
+
+ }
+
+ // Return a compensation object for a given transaction
+ public Object getReturnObject(String methodName)
+ {
+ log.info("getReturnObject()");
+ MethodInformation methodInfo = methodList.get(methodName);
+ if (methodInfo != null)
+ {
+ return returnObjects.get(methodInfo);
+ }
+ return null;
+ }
+
+ // Return a compensation object for a given transaction
+ public Object getReturnObjectNew(String id)
+ {
+ log.info("getReturnObjectNew()");
+ ParticipantCompletionParticipantBA participant = participant2List.get(id);
+ if (participant != null)
+ {
+ CompensationDataReturn cd = participant.getCompensationData();
+ return cd.getReturnObject();
+ }
+ return null;
+ }
+
+ public void addCompensationObject(String methodName, Object object)
+ {
+ log.info("addCompensationObject()");
+ MethodInformation methodInfo = methodList.get(methodName);
+ if ( methodInfo == null )
+ {
+ return;
+ }
+ Object[] objects = compensationObjects.get(methodInfo);
+ Integer paramListSize = 1;
+ if (objects != null)
+ {
+ paramListSize = objects.length;
+ Object[] tempObjects = new Object[paramListSize+1];
+ System.arraycopy(objects,0,tempObjects,0,objects.length);
+ tempObjects[paramListSize] = object;
+ compensationObjects.put(methodInfo,tempObjects);
+ }
+ else
+ {
+ objects = new Object[1];
+ objects[0] = object;
+ compensationObjects.put(methodInfo,objects);
+ }
+ }
+
+ public void addCompensationObjectNew(String id, Object object)
+ {
+ Object[] objects = newCompensationObjects.get(id);
+ Integer paramListSize = 1;
+ if (objects != null)
+ {
+ paramListSize = objects.length;
+ Object[] tempObjects = new Object[paramListSize+1];
+ System.arraycopy(objects,0,tempObjects,0,objects.length);
+ tempObjects[paramListSize] = object;
+ newCompensationObjects.put(id,tempObjects);
+ }
+ else
+ {
+ objects = new Object[1];
+ objects[0] = object;
+ newCompensationObjects.put(id,objects);
+ }
+ }
+
+ public Object[] getCompensationObject(String methodName)
+ {
+ log.info("getCompensationObject()");
+ MethodInformation methodInfo = methodList.get(methodName);
+ if (methodInfo == null)
+ {
+ return null;
+ }
+ return compensationObjects.get(methodInfo);
+ }
+
+ public Object[] getCompensationObjectNew(String id)
+ {
+ log.info("getCompensationObject()");
+ return newCompensationObjects.get(id);
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAAgreement.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAAgreement.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAAgreement.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,14 @@
+package org.jboss.txbridge.ba.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Author: Maciej Machulak
+ */
+ at Target(ElementType.METHOD)
+ at Retention(RetentionPolicy.RUNTIME)
+ at Documented
+public @interface BAAgreement
+{
+ public BAAgreementType value() default BAAgreementType.PARTICIPANT_COMPLETION;
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAAgreementType.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAAgreementType.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAAgreementType.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,10 @@
+package org.jboss.txbridge.ba.annotation;
+
+/**
+ * Author: Maciej Machulak
+ */
+public enum BAAgreementType
+{
+ PARTICIPANT_COMPLETION,
+ COORDINATOR_COMPLETION
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensatedBy.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensatedBy.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensatedBy.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,19 @@
+package org.jboss.txbridge.ba.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Author: Maciej Machulak
+ *
+ */
+ at Target(ElementType.METHOD)
+ at Retention(RetentionPolicy.RUNTIME)
+ at Documented
+public @interface BACompensatedBy
+{
+ public String value();
+ public String methodClass() default "";
+ public String url() default "";
+ public String port() default "";
+ public BACompensationType type() default BACompensationType.RETURN_VALUE;
+}
\ No newline at end of file
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationIdentifier.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationIdentifier.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationIdentifier.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,13 @@
+package org.jboss.txbridge.ba.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Author: Maciej Machulak
+ */
+ at Target(ElementType.FIELD)
+ at Retention(RetentionPolicy.RUNTIME)
+ at Documented
+public @interface BACompensationIdentifier
+{
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationManagement.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationManagement.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationManagement.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,13 @@
+package org.jboss.txbridge.ba.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Author: Maciej Machulak
+ */
+ at Target(ElementType.FIELD)
+ at Retention(RetentionPolicy.RUNTIME)
+ at Documented
+public @interface BACompensationManagement
+{
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationType.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationType.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BACompensationType.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,11 @@
+package org.jboss.txbridge.ba.annotation;
+
+/**
+ * Author: Maciej Machulak
+ */
+public enum BACompensationType
+{
+ RETURN_VALUE,
+ PARAMETERS_MATCH,
+ CUSTOM
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAParam.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAParam.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAParam.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,14 @@
+package org.jboss.txbridge.ba.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Author: Maciej Machulak
+ */
+ at Target(ElementType.PARAMETER)
+ at Retention(RetentionPolicy.RUNTIME)
+ at Documented
+public @interface BAParam
+{
+ String value();
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAProperties.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAProperties.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAProperties.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,10 @@
+package org.jboss.txbridge.ba.annotation;
+
+/**
+ * Author: Maciej Machulak
+ */
+public enum BAProperties
+{
+ BAClass,
+ BAMethod
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAResult.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAResult.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAResult.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,14 @@
+package org.jboss.txbridge.ba.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Author: Maciej Machulak
+ */
+ at Target(ElementType.METHOD)
+ at Retention(RetentionPolicy.RUNTIME)
+ at Documented
+public @interface BAResult
+{
+ String value();
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAService.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAService.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAService.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,14 @@
+package org.jboss.txbridge.ba.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Author: Maciej Machulak
+ */
+ at Target(ElementType.METHOD)
+ at Retention(RetentionPolicy.RUNTIME)
+ at Documented
+public @interface BAService
+{
+ public BAServiceType value() default BAServiceType.MODIFY;
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAServiceType.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAServiceType.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/annotation/BAServiceType.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,14 @@
+package org.jboss.txbridge.ba.annotation;
+
+/**
+ * Author: Maciej Machulak
+ */
+public enum BAServiceType
+{
+ READONLY,
+ MODIFY
+}
+
+/*
+READ_ONLY, DELETE, SELF_CONTAINED, STATE_MANAGED
+ */
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/JaxWSBALoggingAspect.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/JaxWSBALoggingAspect.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/JaxWSBALoggingAspect.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,23 @@
+package org.jboss.txbridge.ba.aspect;
+
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.helper.ClassInformationManager;
+import org.jboss.txbridge.ba.helper.ServiceInformationManager;
+import org.jboss.aop.joinpoint.MethodInvocation;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class JaxWSBALoggingAspect
+{
+ // Logger
+ private static Logger log = Logger.getLogger(JaxWSBALoggingAspect.class);
+
+ public Object loginfo(MethodInvocation invocation) throws Throwable
+ {
+ log.info("Log info...");
+ log.info("##### "+invocation.getMethod().getName()+"() #####");
+ return invocation.invokeNext();
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/JaxWSBAProcessingAspect.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/JaxWSBAProcessingAspect.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/aspect/JaxWSBAProcessingAspect.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,298 @@
+package org.jboss.txbridge.ba.aspect;
+
+import org.jboss.aop.joinpoint.MethodInvocation;
+import org.jboss.txbridge.ba.data.ClassInformation;
+import org.jboss.txbridge.ba.data.MethodInformation;
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.BATransactionManager;
+import org.jboss.txbridge.ba.id.IdentifierFactory;
+import org.jboss.txbridge.ba.id.UidIdentifierFactory;
+import org.jboss.txbridge.ba.annotation.BAParam;
+import org.jboss.txbridge.ba.annotation.BACompensationManagement;
+import org.jboss.txbridge.ba.helper.ClassInformationManager;
+import org.jboss.txbridge.ba.helper.ClassBAVisitor;
+import org.jboss.txbridge.ba.helper.ServiceInformationManager;
+import org.jboss.txbridge.ba.helper.BAServiceVisitor;
+import org.jboss.txbridge.ba.compensation.CompensationManager2Impl;
+import org.apache.log4j.Logger;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class JaxWSBAProcessingAspect
+{
+ // Logger
+ private static Logger log = Logger.getLogger(JaxWSBAProcessingAspect.class);
+
+ // Holds information about classes that are used
+ private static ClassInformationManager classInfoManager = ClassInformationManager.getSingletonInstance();
+
+ // Service information manager
+ private static ServiceInformationManager serviceManager = ServiceInformationManager.getSingletonInstance();
+
+ public Object process(MethodInvocation invocation) throws Throwable
+ {
+ log.info("process()");
+
+ // Process this service if necessary
+ Method method = invocation.getMethod();
+ String methodName = method.getName();
+ String className = method.getDeclaringClass().getName();
+ log.info("Class: " + className);
+ log.info("Method: " + methodName);
+ log.info("Checking if the service is known...");
+ if (!serviceManager.knowsAboutByName(className+methodName))
+ {
+ log.info("Service unknown... processing...");
+ ServiceDescription sd = BAServiceVisitor.processMethod(method);
+ serviceManager.storeServiceDescription(sd);
+ }
+ else
+ {
+ log.info("Service already known...");
+ }
+ log.info("Getting service ID.");
+ String serviceId = serviceManager.getServiceId(className+methodName);
+ log.info("Service ID: " + serviceId);
+
+ // Get a new unique task for this invocation
+ log.info("Getting new task identifier...");
+ IdentifierFactory idf = new UidIdentifierFactory();
+ String taskId = idf.getIdentifier();
+ log.info("Task ID: " + taskId);
+
+
+
+ // Inject the transaction identifier
+ Object targetObject = invocation.getTargetObject();
+ Class clazzz = targetObject.getClass();
+ log.info("Injecting task identifier...");
+ Field[] fields = clazzz.getDeclaredFields();
+ for (Field singleField : fields)
+ {
+ BACompensationManagement cm = singleField.getAnnotation(BACompensationManagement.class);
+ if (cm != null)
+ {
+ log.info("CompensationManager2 found...");
+ log.info("Creating new one...");
+ log.info("taskId: " + taskId);
+ singleField.setAccessible(true);
+ singleField.set(targetObject,new CompensationManager2Impl("",taskId));
+ }
+ }
+ invocation.setTargetObject(targetObject);
+
+ // Get method
+ Method theMethod = invocation.getMethod();
+
+ // Get class
+ Class clazz = theMethod.getDeclaringClass();
+
+ // Process the class
+ ClassInformation classInfo = classInfoManager.getClassInformation(clazz.getName());
+
+ // Get original method name
+ methodName = theMethod.getName();
+
+ // Get method information
+ MethodInformation methodInfo = classInfo.getMethodInformation(methodName);
+
+ // Display for logging purposes
+ log.info("Business Activity...");
+ log.info("BAService: " + methodInfo.getServiceType());
+ log.info("BAAgreement: " + methodInfo.getTransactionAttribute());
+ log.info("BACompensatedBy: " + methodInfo.getCompensationMethod());
+ log.info("Return Type: " + methodInfo.getReturnType().getName());
+ log.info("Compensation Type: " + methodInfo.getCompensationType());
+
+ // Remember necessary parameters
+ boolean rememberReturn = true;
+ boolean rememberParameters = false;
+ Object[] parameterObjects = null;
+ Map<String,Object> arguments = new HashMap<String,Object>();
+ String compensationType = methodInfo.getCompensationType();
+ log.info("Processing according to the compensation type...");
+ // If the compensation is by return value we do not have to remember any parameters
+ if (!compensationType.equals("RETURN_VALUE"))
+ {
+ log.info("Must check what parameters we need.");
+ // If the compensation is by parameters that match we just remember the arguments
+ if (compensationType.equals("PARAMETERS_MATCH"))
+ {
+ log.info("Parameters match. Remember all arguments.");
+ // ...and we don't want to remember the return value
+ rememberReturn = false;
+ rememberParameters = true;
+ parameterObjects = invocation.getArguments();
+ }
+ // ...but if the compensation type is custom than we must remember mappings
+ // between identifiers and objects (possibly the return value as well)
+ else if ( compensationType.equals("CUSTOM"))
+ {
+ log.info("Parameters do not match. Checking parameter annotations.");
+ Annotation[][] parameterAnnotations = theMethod.getParameterAnnotations();
+ Object[] parameters = invocation.getArguments();
+ // Check each parameter if it has the @BAParam annotation
+ int i = 0;
+ for (Annotation[] annotationArray : parameterAnnotations)
+ {
+ int j = 0;
+ log.info("Annotation array length: " + annotationArray.length);
+ for (Annotation annotation : annotationArray)
+ {
+ if (annotation instanceof BAParam)
+ {
+ log.info("BAParam annotation present at position: (" + i + "," + j + ")");
+ String value = ((BAParam)annotation).value();
+ log.info("Value: " + value);
+ arguments.put(value,parameters[i]);
+ }
+ j++;
+ }
+
+ i++;
+ }
+ }
+ }
+ else
+ {
+ log.info("Doing nothing with parameters.");
+ }
+
+ // Check the type of transaction
+ if (methodInfo.getTransactionAttribute() == null)
+ {
+
+ }
+ else if (methodInfo.getTransactionAttribute().equals("COORDINATOR_COMPLETION"))
+ {
+
+ }
+ else if (methodInfo.getTransactionAttribute().equals("PARTICIPANT_COMPLETION"))
+ {
+ // Get reference to the BATransactionManager
+ log.info("Getting reference to the BA Bridge Manager");
+ BATransactionManager babridgeManager = BATransactionManager.getSingletonInstance();
+
+ // Starting transaction management
+ log.info("Starting transaction managemenet");
+ babridgeManager.handleTheTransaction(methodInfo,taskId);
+
+ }
+
+ // Invoke the service
+ Object returnObject = invocation.invokeNext();
+ log.info("No exception... proceeding...");
+
+ // Check the type of transaction
+ if (methodInfo.getTransactionAttribute() == null)
+ {
+
+ }
+ else if (methodInfo.getTransactionAttribute().equals("COORDINATOR_COMPLETION"))
+ {
+
+ }
+ else if (methodInfo.getTransactionAttribute().equals("PARTICIPANT_COMPLETION"))
+ {
+ log.info("Getting reference to the bridge manager");
+ BATransactionManager babridgeManager = BATransactionManager.getSingletonInstance();
+
+ // Get the return object if necessary
+ if (rememberReturn)
+ {
+ log.info("Checking return type...");
+ Class returnType = methodInfo.getReturnType();
+ String returnName = methodInfo.getReturnName();
+ log.info("Return type: " + returnType.getName());
+ if (!methodInfo.getReturnType().getName().equals("void"))
+ {
+ log.info("Getting return object");
+ log.info("Return object: " + returnObject.toString());
+ log.info("Return name: " + returnName);
+
+ // Set return object
+ log.info("Remembering return object");
+ babridgeManager.manageReturnObject(returnName,returnObject,taskId);
+ }
+ }
+ if (rememberParameters)
+ {
+ babridgeManager.manageParameterObjects(parameterObjects,taskId);
+ }
+ babridgeManager.manageCustomObjects(arguments,taskId);
+ // Complete the transaction
+ babridgeManager.completeTransaction();
+ }
+
+ return returnObject;
+ }
+
+ public Object specify(MethodInvocation invocation) throws Throwable
+ {
+ log.info("specify()");
+
+ // Get method
+ Method theMethod = invocation.getMethod();
+ log.info("Executing method: " + theMethod.getName());
+
+ // Get class
+ Class clazz = theMethod.getDeclaringClass();
+
+ // Get reference to the class manager
+ ClassInformationManager classInfoManager = ClassInformationManager.getSingletonInstance();
+
+ // Obtain information about the class
+ // - first check if the classInfoManager knows about this class
+ ClassInformation classInfo = classInfoManager.getClassInformation(clazz.getName());
+ // - if not than process this class
+ if (classInfo == null)
+ {
+ // Process class and obtain info
+ classInfo = ClassBAVisitor.processClass(clazz);
+
+ // Remember info about the class
+ classInfoManager.storeClassInformation(classInfo);
+
+ }
+
+ // Get the real name of the method
+ String methodName = theMethod.getName();
+
+ // Display for logging purposes
+ MethodInformation methodInfo = classInfo.getMethodInformation(methodName);
+ String transactionType = methodInfo.getTransactionAttribute();
+ log.info("Mapping: (" + methodName + "," + transactionType + ")");
+ String serviceType = methodInfo.getServiceType();
+ log.info("Mapping: (" + methodName + "," + serviceType + ")");
+ String compensationMethod = methodInfo.getCompensationMethod();
+ log.info("Link: (" + methodName + "," + compensationMethod + ")");
+ Class returnType = methodInfo.getReturnType();
+ log.info("Return type: (" + methodName + "," + returnType.getName() + ")");
+ String compensationType = methodInfo.getCompensationType();
+ log.info("Compensation type: (" + methodName + "," + compensationType + ")");
+
+ return invocation.invokeNext();
+
+ }
+
+ /*
+ public Object access(FieldReadInvocation invocation) throws Throwable
+ {
+ log.info("Reading compensation manager");
+ return compensationManager;
+ }
+
+ public Object access(FieldWriteInvocation invocation) throws Throwable
+ {
+ throw new RuntimeException("Setting an @BACompensationManagement variable is illegal");
+ }
+ */
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,10 @@
+package org.jboss.txbridge.ba.compensation;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ *
+ */
+public interface CompensationManager
+{
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager2.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager2.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager2.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,14 @@
+package org.jboss.txbridge.ba.compensation;
+
+/**
+ * Author: Maciej Machulak
+ */
+public interface CompensationManager2 {
+ void put(String identifier, Object returnObject);
+
+ void storeTemporaryObject(String identifier, Object object);
+
+ Object getTemporaryObject(String identifier);
+
+ Object retrieve(String identifier);
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager2Impl.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager2Impl.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManager2Impl.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,106 @@
+package org.jboss.txbridge.ba.compensation;
+
+import com.arjuna.mw.wst.BusinessActivityManager;
+import com.arjuna.wst.SystemException;
+import org.apache.log4j.Logger;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class CompensationManager2Impl implements CompensationManager2
+{
+ // Logger
+ Logger log = Logger.getLogger(CompensationManager2Impl.class);
+
+ // Compensation service
+ CompensationService cs;
+
+ // Task identifier
+ private String taskIdentifier;
+
+ // Task txId;
+ private String txId;
+
+ public CompensationManager2Impl(String txId,String taskIdentifier)
+ {
+ log.info("constructor()");
+ log.info("txId: " + txId);
+ log.info("taskId: " + taskIdentifier);
+
+ this.txId = txId;
+
+ // Remember task identifier
+ this.taskIdentifier = taskIdentifier;
+
+ // Get compensation service
+ cs = CompensationServiceImpl.getSingletonInstance();
+ }
+
+ public void put(String identifier,Object returnObject)
+ {
+ log.info("put()");
+ log.info("taskId: " + taskIdentifier);
+ // Get transaction identifier
+ try
+ {
+ BusinessActivityManager businessActivityManager = BusinessActivityManager.getBusinessActivityManager();
+ String txId = businessActivityManager.currentTransaction().toString();
+ cs.addCompensationObjectNew(txId,taskIdentifier,identifier,returnObject);
+ }
+ catch (SystemException e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+ public void storeTemporaryObject(String identifier, Object object)
+ {
+ log.info("storeTemporarObjecty()");
+ log.info("taskId: " + taskIdentifier);
+ // Get transaction identifier
+ try
+ {
+ BusinessActivityManager businessActivityManager = BusinessActivityManager.getBusinessActivityManager();
+ String txId = businessActivityManager.currentTransaction().toString();
+ cs.addTemporaryCompensationObject(txId,taskIdentifier,identifier,object);
+ }
+ catch (SystemException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public Object getTemporaryObject(String identifier)
+ {
+ if (txId == null)
+ {
+ return null;
+ }
+ // Get transaction identifier
+ log.info("getTemporaryObject()");
+ log.info("txId: " + txId);
+ log.info("taskId: " + taskIdentifier);
+ return cs.getTemporaryCompensationObject(txId,taskIdentifier,identifier);
+
+ }
+
+ public Object retrieve(String identifier)
+ {
+ log.info("retrieve()");
+ log.info("txId: " + txId);
+ log.info("taskId: " + taskIdentifier);
+ // Get transaction identifier
+ try
+ {
+ BusinessActivityManager businessActivityManager = BusinessActivityManager.getBusinessActivityManager();
+ String txId = businessActivityManager.currentTransaction().toString();
+ return cs.getCompensationObjectNew(txId,identifier);
+ }
+ catch (SystemException e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManagerImpl.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManagerImpl.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationManagerImpl.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,56 @@
+package org.jboss.txbridge.ba.compensation;
+
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.participant.Participant;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ *
+ * This class wraps the participant and provides a lightweight API for the business programmer
+ * to store and retrieve objects. It automatically associates the required task id so that correct
+ * data is stored and retrieved. An object of this class is injected into the business logic so
+ * that the programmer does not have to worry about anything.
+ */
+public class CompensationManagerImpl
+{
+ // Logger
+ private static Logger log = Logger.getLogger(CompensationManagerImpl.class);
+
+ // Task identifier
+ private String taskId;
+
+ // Participant
+ private Participant participant;
+
+ CompensationManagerImpl(String taskId, Participant participant)
+ {
+ this.taskId = taskId;
+ this.participant = participant;
+ }
+
+ /**
+ * This method stores an object with a given ID. It uses the participant it is aware of and
+ * the task identifier.
+ *
+ * @param objectId is the ID of the object.
+ * @param object is the object itself :)
+ */
+ public void put(String objectId, Object object)
+ {
+ participant.put(taskId,objectId,object);
+
+ }
+
+ /**
+ * This method retrieves an object with a given identifier. This method automatically
+ * associates the task id this compensation manager was associated with.
+ *
+ * @param objectId is the ID of the object.
+ * @return the object.
+ */
+ public Object get(String objectId)
+ {
+ return participant.get(taskId,objectId);
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationService.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationService.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationService.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,30 @@
+package org.jboss.txbridge.ba.compensation;
+
+import org.jboss.txbridge.ba.SingleTransactionManager;
+
+/**
+ * Author: Maciej Machulak
+ */
+public interface CompensationService {
+ void registerBridge(String txId, SingleTransactionManager bridge);// Add new compensation object
+
+ void addReturnObject(String txId, String methodName,Object object);// Add new compensation object
+
+ void addReturnObjectNew(String txId, String id,Object object);// Add new compensation object
+
+ void addTemporaryCompensationObject(String txId,String taskId,String identifier,Object object);// Return a compensation object for a given transaction
+
+ Object getTemporaryCompensationObject(String txId,String taskId,String identifier);// Return a compensation object for a given transaction
+
+ Object getReturnObject(String txId,String methodName);// Return a compensation object for a given transaction
+
+ Object getReturnObjectNew(String txId,String id);
+
+ void addCompensationObject(String txId, String methodName, Object object);
+
+ void addCompensationObjectNew(String txId, String taskId, String identifier, Object object);
+
+ Object[] getCompensationObject(String txId, String methodName);
+
+ Object[] getCompensationObjectNew(String txId, String id);
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationServiceImpl.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationServiceImpl.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/CompensationServiceImpl.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,183 @@
+package org.jboss.txbridge.ba.compensation;
+
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.SingleTransactionManager;
+import org.jboss.txbridge.ba.data.SimpleMethodInformation;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class CompensationServiceImpl implements CompensationService {
+ // Logger
+ private static Logger log = Logger.getLogger(CompensationServiceImpl.class);
+
+ // Compensation manager instance
+ private volatile static CompensationService compensationService = null;
+
+ // Mappings
+ // - transaction IDs and Inbound Bridges
+ private static ConcurrentMap<String, SingleTransactionManager> bridges;
+ // - transaction IDs and method information
+ private static ConcurrentMap<String, SimpleMethodInformation> txMethods;
+ // - unique ID and temporary objects
+ private static ConcurrentMap<String,Object> returnObjects;
+ // - transaction IDs and additional compensation objects
+ private static ConcurrentMap<String,Object[]> compensationObjects;
+
+ // Constructor
+ private CompensationServiceImpl()
+ {
+ log.info("constructor()");
+ bridges = new ConcurrentHashMap<String, SingleTransactionManager>();
+ txMethods = new ConcurrentHashMap<String, SimpleMethodInformation>();
+ returnObjects = new ConcurrentHashMap<String,Object>();
+ compensationObjects = new ConcurrentHashMap<String,Object[]>();
+ }
+
+ public void registerBridge(String txId, SingleTransactionManager bridge)
+ {
+ bridges.put(txId,bridge);
+ }
+
+ // Return instance of the compensation manager
+ public static CompensationService getSingletonInstance()
+ {
+ log.info("getSingletonInstance()");
+ if (compensationService == null)
+ {
+ synchronized(CompensationServiceImpl.class)
+ {
+ if (compensationService == null)
+ {
+ log.info("Creating new instance");
+ compensationService = new CompensationServiceImpl();
+ }
+ }
+ }
+ return compensationService;
+ }
+
+ // Add new compensation object
+ public void addReturnObject(String txId, String methodName,Object object)
+ {
+ log.info("addReturnObject()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ bridge.addReturnObject(methodName,object);
+ }
+ }
+
+ // Add new compensation object
+ public void addReturnObjectNew(String txId, String id,Object object)
+ {
+ log.info("addReturnObjectNew()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ //bridge.addReturnObjectNew(id,object);
+ }
+ }
+
+ // Add new compensation object
+ public void addTemporaryCompensationObject(String txId,String taskId,String identifier,Object object)
+ {
+ log.info("addTemporaryCompensationObject()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ bridge.addTemporaryObject(taskId,identifier,object);
+ }
+ }
+
+ // Return a compensation object for a given transaction
+ public Object getTemporaryCompensationObject(String txId,String taskId,String identifier)
+ {
+ log.info("getTemporaryCompensationObject()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ return bridge.getTemporaryObject(taskId,identifier);
+ }
+ return null;
+ }
+
+ // Return a compensation object for a given transaction
+ public Object getReturnObject(String txId,String methodName)
+ {
+ log.info("getReturnObject()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ return bridge.getReturnObject(methodName);
+ }
+ return null;
+ }
+
+ // Return a compensation object for a given transaction
+ public Object getReturnObjectNew(String txId,String id)
+ {
+ log.info("getReturnObjectNew()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ return bridge.getReturnObjectNew(id);
+ }
+ return null;
+ }
+
+ public void addCompensationObject(String txId, String methodName, Object object)
+ {
+ log.info("addCompensationObject()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ bridge.addCompensationObject(methodName,object);
+ }
+ }
+
+ public void addCompensationObjectNew(String txId, String taskId, String identifier,Object object)
+ {
+ log.info("addCompensationObjectNew()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ bridge.addCustomObject(taskId,identifier,object);
+ }
+ }
+
+ public Object[] getCompensationObject(String txId, String methodName)
+ {
+ log.info("getCompensationObject()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ return bridge.getCompensationObject(methodName);
+ }
+ return null;
+ }
+
+ public Object[] getCompensationObjectNew(String txId, String id)
+ {
+ log.info("getCompensationObjectNew()");
+ SingleTransactionManager bridge = bridges.get(txId);
+ if (bridge != null)
+ {
+ log.info("Bridge found...");
+ return bridge.getCompensationObjectNew(id);
+ }
+ return null;
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/ServiceExecutor.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/ServiceExecutor.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/compensation/ServiceExecutor.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,240 @@
+package org.jboss.txbridge.ba.compensation;
+
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.data.MethodInformation;
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.data.CompensationDataReturn;
+import org.jboss.txbridge.ba.annotation.BAParam;
+import org.jboss.txbridge.ba.annotation.BACompensationManagement;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.annotation.Annotation;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class ServiceExecutor {
+ // Logger
+ private static Logger log = Logger.getLogger(ServiceExecutor.class);
+
+ // Instance of the Service Executor
+ private volatile static ServiceExecutor serviceExecutor = null;
+
+ private ServiceExecutor()
+ {
+ log.info("constructor()");
+ }
+
+ public static ServiceExecutor getSingletonInstance()
+ {
+ log.info("getSingletonInstance()");
+ if (serviceExecutor == null)
+ {
+ synchronized(ServiceExecutor.class)
+ {
+ if (serviceExecutor == null)
+ {
+ log.info("Creating new instance...");
+ serviceExecutor = new ServiceExecutor();
+ }
+ }
+ }
+ return serviceExecutor;
+ }
+
+ public synchronized boolean executeMethod(String txId, String taskId, MethodInformation method, CompensationData compensationData)
+ {
+ log.info("executeMethod()");
+ try
+ {
+ // Obtain the return object
+ log.info("Getting the return object");
+ Object returnObject = ((CompensationDataReturn)compensationData).getReturnObject();
+ log.info("Return object that will be used: " + returnObject);
+
+ Object[] parameterObjects = new Object[1];
+ Class[] parameterTypes = new Class[1];
+ if (returnObject != null)
+ {
+ parameterObjects[0] = returnObject;
+ parameterTypes[0] = returnObject.getClass();
+ }
+ else
+ {
+ log.info("Return object was null.");
+ }
+
+ // Obtain the compensation objects if necessary
+ Method theMethod = null;
+ String compensationType = method.getCompensationType();
+ if (!compensationType.equals("RETURN_VALUE"))
+ {
+ if (compensationType.equals("PARAMETERS_MATCH"))
+ {
+ log.info("Compensation type is PARAMETERS_MATCH");
+ log.info("Getting the compensation object");
+ Object[] compensationObjects = ((CompensationDataReturn)compensationData).getParameterObjects();
+ if ( compensationObjects == null )
+ {
+ parameterObjects = null;
+ parameterTypes = null;
+ log.info("No compensation objects will be used.");
+ }
+ else
+ {
+ log.info("Compensation objects found.");
+ for (Object singleObject : compensationObjects)
+ {
+ log.info("Compensation object: " + singleObject);
+ }
+ log.info("Adding compensation objects as parameters.");
+ parameterObjects = new Object[compensationObjects.length];
+ parameterTypes = new Class[compensationObjects.length];
+ System.arraycopy(compensationObjects,0,parameterObjects,0,compensationObjects.length);
+
+ int i = 0;
+ log.info("Adding parameter types.");
+ for (Object singleObject : parameterObjects)
+ {
+ log.info("Link (" + singleObject + "," + singleObject.getClass()+")");
+ parameterTypes[i++] = singleObject.getClass();
+ }
+
+ }
+
+ log.info("Parameter objects:");
+ for (Object parameter : parameterObjects)
+ {
+ log.info(parameter);
+ }
+ log.info("Parameter types:");
+ for (Class clazz : parameterTypes)
+ {
+ log.info(clazz);
+ }
+ }
+ else if (compensationType.equals("CUSTOM"))
+ {
+ // Show all remember objects
+ log.info("Compensation objects:");
+ for (String key : ((CompensationDataReturn)compensationData).getPrimaryObjects().keySet())
+ {
+ log.info(key);
+ }
+
+ // Mapping (annotation,object)
+ Map<String,Object> annoObjects = new HashMap<String,Object>();
+ String returnName = ((CompensationDataReturn)compensationData).getReturnName();
+ if (!returnName.equals(""))
+ {
+ annoObjects.put(returnName,returnObject);
+ }
+ annoObjects.putAll(((CompensationDataReturn)compensationData).getPrimaryObjects());
+
+ // Get reference to the method as we need the annotations
+ // We do not know what the parameters are so we must check its method
+ // and compare its name
+ Class clazz = method.getCompensationClass();
+ log.info("Class: " + clazz.getName());
+ log.info("Getting all methods...");
+ Method[] methods = clazz.getMethods();
+ theMethod = null;
+ log.info("Searching for method: " + method.getOriginalMethod());
+ for (Method oneMethod : methods)
+ {
+ if (oneMethod.getName().equals(method.getCompensationMethod()))
+ {
+ log.info("Method found!");
+ theMethod = oneMethod;
+ break;
+ }
+ }
+ log.info("Getting annotations...");
+ Annotation[][] parameterAnnotations = theMethod.getParameterAnnotations();
+ log.info("Number of parameters for this method: " + parameterAnnotations.length);
+ parameterObjects = new Object[parameterAnnotations.length];
+ parameterTypes = new Class[parameterAnnotations.length];
+
+ // Check each parameter if it has the @BAParam annotation
+ log.info("Searching for @BAParam parameter annotation...");
+ int i = 0;
+ for (Annotation[] annotationArray : parameterAnnotations)
+ {
+ log.info("Annotation array length: " + annotationArray.length);
+ for (Annotation annotation : annotationArray)
+ {
+ if (annotation instanceof BAParam)
+ {
+ log.info("BAParam annotation on parameter: " + i);
+ String value = ((BAParam)annotation).value();
+ log.info("Value: " + value);
+ log.info("Getting compensation object for this parameter.");
+ Object someObject = annoObjects.get(value);
+ if (someObject != null)
+ {
+ log.info("Object found: " + someObject.toString());
+ parameterObjects[i] = someObject;
+ parameterTypes[i] = someObject.getClass();
+ }
+ else
+ {
+ log.info("Object was not found!");
+ // I will throw an exception !!! I need to specify exceptions!
+ return false;
+ }
+ }
+ }
+ i++;
+ }
+ }
+ }
+ else
+ {
+ log.info("Compensation type was RETURN");
+ }
+
+ // Get reference to the method
+ Class clazz = method.getCompensationClass();
+ log.info("Class: " + clazz.getName());
+ if (theMethod == null)
+ {
+ theMethod = clazz.getMethod(method.getCompensationMethod(),parameterTypes);
+ log.info("Method: " + theMethod.getName());
+ }
+ Constructor classConstructor = clazz.getConstructor();
+ log.info("Constructor: " + classConstructor.toString());
+ Object classObject = classConstructor.newInstance();
+
+ // Inject the transaction identifier
+ log.info("Injecting transaction identifier...");
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field singleField : fields)
+ {
+ BACompensationManagement cm = singleField.getAnnotation(BACompensationManagement.class);
+ if (cm != null)
+ {
+ log.info("CompensationManager2 found...");
+ log.info("Creating new one...");
+ log.info("txId: " + txId);
+ log.info("taskId: " + taskId);
+ singleField.setAccessible(true);
+ singleField.set(classObject,new CompensationManager2Impl(txId,taskId));
+ }
+ }
+
+ // Invoke the compensation method
+ log.info("Invoking method...");
+ theMethod.invoke(classObject,parameterObjects);
+ return true;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ return false;
+ }
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ClassInformation.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ClassInformation.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ClassInformation.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,24 @@
+package org.jboss.txbridge.ba.data;
+
+/**
+ * Author: Maciej Machulak
+ */
+public interface ClassInformation
+{
+ // Get the class that is being described
+ Class getTheClass();// Get the name of a compensation method for a given method
+
+ String getCompensationMethod(String originalMethod);// Get return type for a given method
+
+ Class getReturnType(String originalMethod);// Get transaction attribute for a given method
+
+ String getTransactionAttribute(String originalMethod);// Get the service type for the given method
+
+ String getServiceType(String originalMethod);// Get full method information
+
+ MethodInformation getMethodInformation(String methodName);// Get the original method's name
+
+ String getOriginalMethodName(String webMethodName);
+
+ String getCompensationType(String methodName);
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationData.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationData.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationData.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,7 @@
+package org.jboss.txbridge.ba.data;
+
+/**
+ * Author: Maciej Machulak
+ */
+public abstract class CompensationData {
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataCustom.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataCustom.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataCustom.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,8 @@
+package org.jboss.txbridge.ba.data;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class CompensationDataCustom extends CompensationData
+{
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataParam.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataParam.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataParam.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,8 @@
+package org.jboss.txbridge.ba.data;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class CompensationDataParam extends CompensationData
+{
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataReturn.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataReturn.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/CompensationDataReturn.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,117 @@
+package org.jboss.txbridge.ba.data;
+
+import org.apache.log4j.Logger;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class CompensationDataReturn extends CompensationData
+{
+ // Logger
+ private static Logger log = Logger.getLogger(CompensationDataReturn.class);
+
+ // Return object + mapping
+ private String returnName;
+ private Object returnObject;
+
+ private Object[] parameterObjects;
+
+ // Primary compensation objects - parameters
+ private Map<String,Object> primaryObjects;
+
+ // Secondary compensation objects - temporary objects
+ private Map<String,Object> secondaryObjects;
+
+ public CompensationDataReturn()
+ {
+ primaryObjects = new HashMap<String,Object>();
+ secondaryObjects = new HashMap<String,Object>();
+ parameterObjects = null;
+ returnName = "";
+ }
+
+ public void putPrimaryObjects(Map<String,Object> primaryObjects)
+ {
+ this.primaryObjects.putAll(primaryObjects);
+ }
+
+ public void putSecondaryObjects(Map<String,Object> secondaryObjects)
+ {
+ this.secondaryObjects.putAll(secondaryObjects);
+ }
+
+ public void setPrimaryObjects(Map<String, Object> primaryObjects)
+ {
+ this.primaryObjects = primaryObjects;
+ }
+
+ public void setSecondaryObjects(Map<String, Object> secondaryObjects)
+ {
+ this.secondaryObjects = secondaryObjects;
+ }
+
+ public void setParameterObjects(Object[] parameterObjects)
+ {
+ log.info("setting parameter objects");
+ this.parameterObjects = parameterObjects;
+ }
+
+
+ public Object[] getParameterObjects()
+ {
+ log.info("getting parameter objects");
+ return parameterObjects;
+ }
+
+ public void addReturnObject(String returnName, Object returnObject)
+ {
+ log.info("adding return object");
+ this.returnName = returnName;
+ this.returnObject = returnObject;
+ }
+
+ public Object getReturnObject()
+ {
+ log.info("getting return object");
+ return returnObject;
+ }
+
+ public String getReturnName()
+ {
+ return returnName;
+ }
+
+ public Map<String, Object> getPrimaryObjects()
+ {
+ return primaryObjects;
+ }
+
+ public Map<String, Object> getSecondaryObjects()
+ {
+ return secondaryObjects;
+ }
+
+ public Object putPrimary(String key, Object value)
+ {
+ return primaryObjects.put(key, value);
+ }
+
+ public Object getPrimary(String key)
+ {
+ return primaryObjects.get(key);
+ }
+
+
+ public Object getSecondary(String key)
+ {
+ return secondaryObjects.get(key);
+ }
+
+ public Object putSecondary(String key, Object value)
+ {
+ return secondaryObjects.put(key, value);
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/IdentificationType.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/IdentificationType.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/IdentificationType.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,10 @@
+package org.jboss.txbridge.ba.data;
+
+/**
+ * Author: Maciej Machulak
+ */
+public enum IdentificationType
+{
+ BY_NUMBER,
+ BY_NAME
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/MethodInformation.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/MethodInformation.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/MethodInformation.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,32 @@
+package org.jboss.txbridge.ba.data;
+
+/**
+ * Author: Maciej Machulak
+ */
+public interface MethodInformation
+{
+ Class getOriginalClass();
+
+ String getOriginalMethod();
+
+ Class getReturnType();
+
+ Class getCompensationClass();
+
+ String getCompensationMethod();
+
+ Class[] getParameterType();
+
+ void setReturnType(Class returnType);
+
+ String getTransactionAttribute();
+
+ String getServiceType();
+
+ String getWebMethodName();
+
+ String getCompensationType();
+
+ String getReturnName();
+ void setReturnName(String returnName);
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ServiceDescription.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ServiceDescription.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ServiceDescription.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,91 @@
+package org.jboss.txbridge.ba.data;
+
+import org.jboss.txbridge.ba.annotation.BAServiceType;
+import org.jboss.txbridge.ba.annotation.BAAgreementType;
+import org.jboss.txbridge.ba.annotation.BACompensationType;
+
+import java.util.Map;
+import java.io.Serializable;
+
+/**
+ * Author: Maciej Machulak
+ */
+public interface ServiceDescription extends Serializable
+{
+ BAServiceType getServiceType();
+
+ void setServiceType(BAServiceType serviceType);
+
+ BAAgreementType getAgreementType();
+
+ void setAgreementType(BAAgreementType agreementType);
+
+ BACompensationType getCompensationType();
+
+ void setCompensationType(BACompensationType compensationType);
+
+ Class getOriginalClass();
+
+ void setOriginalClass(Class originalClass);
+
+ String getOriginalMethodName();
+
+ void setOriginalMethodName(String originalMethodName);
+
+ String getOriginalWebMethodName();
+
+ void setOriginalWebMethodName(String originalWebMethodName);
+
+ Class getOriginalReturnType();
+
+ void setOriginalReturnType(Class originalReturnType);
+
+ Class getCompensationClass();
+
+ void setCompensationClass(Class compensationClass);
+
+ String getCompensationMethodName();
+
+ void setCompensationMethodName(String compensationMethodName);
+
+ String getCompensationWebMethodName();
+
+ void setCompensationWebMethodName(String compensationWebMethodName);
+
+ Class getCompensationReturnType();
+
+ void setCompensationReturnType(Class compensationReturnType);
+
+ public Class[] getOriginalParameterTypes();
+
+ public void setOriginalParameterTypes(Class[] originalParameterTypes);
+
+ public Class[] getCompensationParameterTypes();
+
+ public void setCompensationParameterTypes(Class[] compensationParameterTypes);
+
+ public Map<String, Integer> getOriginalParameterAnnotations();
+
+ public void setOriginalParameterAnnotations(Map<String, Integer> originalParameterAnnotations);
+
+ public Map<Integer, Integer> getOriginalParameterAnnotations2();
+
+ public void setOriginalParameterAnnotations2(Map<Integer, Integer> originalParameterAnnotations2);
+
+ public Map<String, Integer> getCompensationParameterAnnotations();
+
+ public void setCompensationParameterAnnotations(Map<String, Integer> compensationParameterAnnotations);
+
+ public IdentificationType getIdentificationType();
+
+ public void setIdentificationType(IdentificationType identificationType);
+
+ public String getOriginalReturnName();
+
+ public void setOriginalReturnName(String originalReturnName);
+
+ public Integer getOriginalReturnId();
+
+ public void setOriginalReturnId(Integer originalReturnId);
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ServiceDescriptionImpl.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ServiceDescriptionImpl.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/ServiceDescriptionImpl.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,254 @@
+package org.jboss.txbridge.ba.data;
+
+import org.jboss.txbridge.ba.annotation.BAServiceType;
+import org.jboss.txbridge.ba.annotation.BAAgreementType;
+import org.jboss.txbridge.ba.annotation.BACompensationType;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.io.Serializable;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ *
+ * This class represents a description of a single Web Service related to the
+ * Business Activity model. It contains information about the type of the service,
+ * the agreement protocol the service is willing to participate in, the list of
+ * compensation methods associated with this service.
+ */
+public class ServiceDescriptionImpl implements ServiceDescription
+{
+
+ public ServiceDescriptionImpl()
+ {
+ originalParameterAnnotations = new HashMap<String,Integer>();
+ originalParameterAnnotations2 = new HashMap<Integer,Integer>();
+ compensationParameterAnnotations = new HashMap<String,Integer>();
+ }
+
+ /**
+ * BA-related information.
+ */
+ private BAServiceType serviceType;
+ private BAAgreementType agreementType;
+ private BACompensationType compensationType;
+ private IdentificationType identificationType;
+
+ /**
+ * Information about the original method.
+ */
+ private Class originalClass;
+ private String originalMethodName;
+ private String originalWebMethodName;
+ private Class[] originalParameterTypes;
+ private Map<String,Integer> originalParameterAnnotations;
+ private Map<Integer,Integer> originalParameterAnnotations2;
+ private String originalReturnName;
+ private Integer originalReturnId;
+ private Class originalReturnType;
+
+ /**
+ * Information about the compensation method.
+ */
+ private Class compensationClass;
+ private String compensationMethodName;
+ private String compensationWebMethodName;
+ private Class[] compensationParameterTypes;
+ private Map<String,Integer> compensationParameterAnnotations;
+ private Class compensationReturnType;
+
+
+ public BAServiceType getServiceType()
+ {
+ return serviceType;
+ }
+
+ public void setServiceType(BAServiceType serviceType)
+ {
+ this.serviceType = serviceType;
+ }
+
+ public BAAgreementType getAgreementType()
+ {
+ return agreementType;
+ }
+
+ public void setAgreementType(BAAgreementType agreementType)
+ {
+ this.agreementType = agreementType;
+ }
+
+ public BACompensationType getCompensationType()
+ {
+ return compensationType;
+ }
+
+ public void setCompensationType(BACompensationType compensationType)
+ {
+ this.compensationType = compensationType;
+ }
+
+ public Class getOriginalClass()
+ {
+ return originalClass;
+ }
+
+ public void setOriginalClass(Class originalClass)
+ {
+ this.originalClass = originalClass;
+ }
+
+ public String getOriginalMethodName()
+ {
+ return originalMethodName;
+ }
+
+ public void setOriginalMethodName(String originalMethodName)
+ {
+ this.originalMethodName = originalMethodName;
+ }
+
+ public String getOriginalWebMethodName()
+ {
+ return originalWebMethodName;
+ }
+
+ public void setOriginalWebMethodName(String originalWebMethodName)
+ {
+ this.originalWebMethodName = originalWebMethodName;
+ }
+
+ public Class getOriginalReturnType()
+ {
+ return originalReturnType;
+ }
+
+ public void setOriginalReturnType(Class originalReturnType)
+ {
+ this.originalReturnType = originalReturnType;
+ }
+
+ public Class getCompensationClass()
+ {
+ return compensationClass;
+ }
+
+ public void setCompensationClass(Class compensationClass)
+ {
+ this.compensationClass = compensationClass;
+ }
+
+ public String getCompensationMethodName()
+ {
+ return compensationMethodName;
+ }
+
+ public void setCompensationMethodName(String compensationMethodName)
+ {
+ this.compensationMethodName = compensationMethodName;
+ }
+
+ public String getCompensationWebMethodName()
+ {
+ return compensationWebMethodName;
+ }
+
+ public void setCompensationWebMethodName(String compensationWebMethodName)
+ {
+ this.compensationWebMethodName = compensationWebMethodName;
+ }
+
+ public Class getCompensationReturnType()
+ {
+ return compensationReturnType;
+ }
+
+ public void setCompensationReturnType(Class compensationReturnType)
+ {
+ this.compensationReturnType = compensationReturnType;
+ }
+
+
+ public Class[] getOriginalParameterTypes()
+ {
+ return originalParameterTypes;
+ }
+
+ public void setOriginalParameterTypes(Class[] originalParameterTypes)
+ {
+ this.originalParameterTypes = originalParameterTypes;
+ }
+
+ public Class[] getCompensationParameterTypes()
+ {
+ return compensationParameterTypes;
+ }
+
+ public void setCompensationParameterTypes(Class[] compensationParameterTypes)
+ {
+ this.compensationParameterTypes = compensationParameterTypes;
+ }
+
+
+ public Map<String, Integer> getOriginalParameterAnnotations()
+ {
+ return originalParameterAnnotations;
+ }
+
+ public void setOriginalParameterAnnotations(Map<String, Integer> originalParameterAnnotations)
+ {
+ this.originalParameterAnnotations = originalParameterAnnotations;
+ }
+
+ public Map<Integer, Integer> getOriginalParameterAnnotations2()
+ {
+ return originalParameterAnnotations2;
+ }
+
+ public void setOriginalParameterAnnotations2(Map<Integer, Integer> originalParameterAnnotations2)
+ {
+ this.originalParameterAnnotations2 = originalParameterAnnotations2;
+ }
+
+ public Map<String, Integer> getCompensationParameterAnnotations()
+ {
+ return compensationParameterAnnotations;
+ }
+
+ public void setCompensationParameterAnnotations(Map<String, Integer> compensationParameterAnnotations)
+ {
+ this.compensationParameterAnnotations = compensationParameterAnnotations;
+ }
+
+
+ public IdentificationType getIdentificationType()
+ {
+ return identificationType;
+ }
+
+ public void setIdentificationType(IdentificationType identificationType)
+ {
+ this.identificationType = identificationType;
+ }
+
+ public String getOriginalReturnName()
+ {
+ return originalReturnName;
+ }
+
+ public void setOriginalReturnName(String originalReturnName)
+ {
+ this.originalReturnName = originalReturnName;
+ }
+
+ public Integer getOriginalReturnId()
+ {
+ return originalReturnId;
+ }
+
+ public void setOriginalReturnId(Integer originalReturnId)
+ {
+ this.originalReturnId = originalReturnId;
+ }
+}
\ No newline at end of file
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/SimpleClassInformation.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/SimpleClassInformation.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/SimpleClassInformation.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,94 @@
+package org.jboss.txbridge.ba.data;
+
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class SimpleClassInformation implements ClassInformation
+{
+ // Class
+ private Class clazz;
+
+ // Mappings
+ // (web_method_name,real_method_name)
+ private ConcurrentMap<String,String> webMethodMappings;
+ // (real_method_name,method_information)
+ private ConcurrentMap<String,MethodInformation> methodMappings;
+
+ // Constructor
+ public SimpleClassInformation(Class clazz, ConcurrentMap<String,String> webMethodMappings, ConcurrentMap<String,MethodInformation> methodMappings)
+ {
+ this.clazz = clazz;
+ this.webMethodMappings = webMethodMappings;
+ this.methodMappings = methodMappings;
+ }
+
+ // Get the class that is being described
+ public Class getTheClass()
+ {
+ return clazz;
+ }
+
+ // Get the name of a compensation method for a given method
+ public String getCompensationMethod(String originalMethod)
+ {
+ if (methodMappings.containsKey(originalMethod))
+ {
+ return methodMappings.get(originalMethod).getCompensationMethod();
+ }
+ return null;
+ }
+
+ // Get return type for a given method
+ public Class getReturnType(String originalMethod)
+ {
+ if (methodMappings.containsKey(originalMethod))
+ {
+ return methodMappings.get(originalMethod).getReturnType();
+ }
+ return null;
+ }
+
+ // Get transaction attribute for a given method
+ public String getTransactionAttribute(String originalMethod)
+ {
+ if (methodMappings.containsKey(originalMethod))
+ {
+ return methodMappings.get(originalMethod).getTransactionAttribute();
+ }
+ return null;
+ }
+
+ // Get the service type for the given method
+ public String getServiceType(String originalMethod)
+ {
+ if (methodMappings.containsKey(originalMethod))
+ {
+ return methodMappings.get(originalMethod).getServiceType();
+ }
+ return null;
+ }
+
+ // Get full method information
+ public MethodInformation getMethodInformation(String methodName)
+ {
+ return methodMappings.get(methodName);
+ }
+
+ // Get the original method's name
+ public String getOriginalMethodName(String webMethodName)
+ {
+ return webMethodMappings.get(webMethodName);
+ }
+
+ public String getCompensationType(String methodName)
+ {
+ MethodInformation method = methodMappings.get(methodName);
+ if (method != null)
+ {
+ return method.getCompensationType();
+ }
+ return null;
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/SimpleMethodInformation.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/SimpleMethodInformation.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/data/SimpleMethodInformation.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,116 @@
+package org.jboss.txbridge.ba.data;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class SimpleMethodInformation implements MethodInformation
+{
+ // Web method name
+ private String webMethodName;
+
+ // Original method
+ private Class originalClass;
+ private String originalMethod;
+ private Class returnType;
+ private String returnName;
+
+ // Transaction attribute
+ private String transactionAttribute;
+
+ // Service type
+ private String serviceType;
+
+ // Compensation type
+ private String compensationType;
+
+ // Compensation method
+ private Class compensationClass;
+ private String compensationMethod;
+ private Class[] parameterType;
+
+
+ public SimpleMethodInformation(String webMethodName, Class originalClass, String originalMethod, Class returnType, String transactionAttribute, String serviceType, Class compensationClass, String compensationMethod, Class[] parameterType, String compensationType)
+ {
+ this.webMethodName = webMethodName;
+ this.originalClass = originalClass;
+ this.originalMethod = originalMethod;
+ this.returnType = returnType;
+ this.transactionAttribute = transactionAttribute;
+ this.serviceType = serviceType;
+ this.compensationClass = compensationClass;
+ this.compensationMethod = compensationMethod;
+ this.parameterType = parameterType;
+ this.compensationType = compensationType;
+ this.returnName = "";
+ }
+
+ public Class getOriginalClass()
+ {
+ return originalClass;
+ }
+
+ public String getOriginalMethod()
+ {
+ return originalMethod;
+ }
+
+ public Class getReturnType()
+ {
+ return returnType;
+ }
+
+ public Class getCompensationClass()
+ {
+ return compensationClass;
+ }
+
+ public String getCompensationMethod()
+ {
+ return compensationMethod;
+ }
+
+ public Class[] getParameterType()
+ {
+ return parameterType;
+ }
+
+
+ public void setReturnType(Class returnType)
+ {
+ this.returnType = returnType;
+ }
+
+ public String getTransactionAttribute()
+ {
+ return transactionAttribute;
+ }
+
+
+ public String getServiceType()
+ {
+ return serviceType;
+ }
+
+
+ public String getWebMethodName()
+ {
+ return webMethodName;
+ }
+
+ public String getCompensationType()
+ {
+ return compensationType;
+ }
+
+
+ public void setReturnName(String returnName)
+ {
+ this.returnName = returnName;
+ }
+
+ public String getReturnName()
+ {
+ return returnName;
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/CompensationActionUnsuccessfulException.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/CompensationActionUnsuccessfulException.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/CompensationActionUnsuccessfulException.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,19 @@
+package org.jboss.txbridge.ba.exception;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ */
+public class CompensationActionUnsuccessfulException extends Exception
+{
+
+ public CompensationActionUnsuccessfulException()
+ {
+ super();
+ }
+
+ public CompensationActionUnsuccessfulException(String message)
+ {
+ super(message);
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/CompensationMethodNotAccessible.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/CompensationMethodNotAccessible.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/CompensationMethodNotAccessible.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,23 @@
+package org.jboss.txbridge.ba.exception;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ *
+ * This exception is thrown when the compensation method during a static analysis is
+ * not accessible (i.e. the name is incorrect, parameter types do not match, the specified
+ * class does not exist.
+ */
+public class CompensationMethodNotAccessible extends Exception
+{
+
+ public CompensationMethodNotAccessible()
+ {
+ super();
+ }
+
+ public CompensationMethodNotAccessible(String message)
+ {
+ super(message);
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/MethodIncorrectlyAnnotatedException.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/MethodIncorrectlyAnnotatedException.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/MethodIncorrectlyAnnotatedException.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,21 @@
+package org.jboss.txbridge.ba.exception;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ *
+ * This exception is thrown when we want to process a method which does not contain
+ * all necessary annotations related to Business Activity.
+ */
+public class MethodIncorrectlyAnnotatedException extends Exception
+{
+ public MethodIncorrectlyAnnotatedException()
+ {
+ super();
+ }
+
+ public MethodIncorrectlyAnnotatedException(String message)
+ {
+ super(message);
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/TaskAssociationFailedException.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/TaskAssociationFailedException.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/exception/TaskAssociationFailedException.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,19 @@
+package org.jboss.txbridge.ba.exception;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class TaskAssociationFailedException extends Exception
+{
+
+ public TaskAssociationFailedException()
+ {
+ super();
+ }
+
+ public TaskAssociationFailedException(String message)
+ {
+ super(message);
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/CorbaExecution.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/CorbaExecution.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/CorbaExecution.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,17 @@
+package org.jboss.txbridge.ba.execute;
+
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.exception.CompensationActionUnsuccessfulException;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class CorbaExecution implements ExecutionInterface
+{
+ public void invokeService(String txId, String taskId, ServiceDescription sd, CompensationData cd) throws CompensationActionUnsuccessfulException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/ExecutionInterface.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/ExecutionInterface.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/ExecutionInterface.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,14 @@
+package org.jboss.txbridge.ba.execute;
+
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.exception.CompensationActionUnsuccessfulException;
+
+/**
+ * @author: Maciej Machulak
+ * @date:
+ */
+public interface ExecutionInterface
+{
+ public void invokeService(String txId,String taskId,ServiceDescription sd, CompensationData cd) throws CompensationActionUnsuccessfulException;
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/LocalExecution.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/LocalExecution.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/LocalExecution.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,219 @@
+package org.jboss.txbridge.ba.execute;
+
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.data.CompensationDataReturn;
+import org.jboss.txbridge.ba.exception.CompensationActionUnsuccessfulException;
+import org.jboss.txbridge.ba.annotation.BAParam;
+import org.jboss.txbridge.ba.annotation.BACompensationManagement;
+import org.jboss.txbridge.ba.compensation.CompensationManager2Impl;
+import org.apache.log4j.Logger;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ */
+public class LocalExecution implements ExecutionInterface
+{
+ // Logger
+ private static Logger log = Logger.getLogger(LocalExecution.class);
+
+ public void invokeService(String txId,String taskId,ServiceDescription sd, CompensationData cd) throws CompensationActionUnsuccessfulException
+ {
+
+ log.info("executeMethod()");
+ try
+ {
+ // Obtain the return object
+ log.info("Getting the return object");
+ Object returnObject = ((CompensationDataReturn)cd).getReturnObject();
+ log.info("Return object that will be used: " + returnObject);
+
+ Object[] parameterObjects = new Object[1];
+ Class[] parameterTypes = new Class[1];
+ if (returnObject != null)
+ {
+ parameterObjects[0] = returnObject;
+ parameterTypes[0] = returnObject.getClass();
+ }
+ else
+ {
+ log.info("Return object was null.");
+ }
+
+ // Obtain the compensation objects if necessary
+ Method theMethod = null;
+ String compensationType = sd.getCompensationType().toString();
+ if (!compensationType.equals("RETURN_VALUE"))
+ {
+ if (compensationType.equals("PARAMETERS_MATCH"))
+ {
+ log.info("Compensation type is PARAMETERS_MATCH");
+ log.info("Getting the compensation object");
+ Object[] compensationObjects = ((CompensationDataReturn)cd).getParameterObjects();
+ if ( compensationObjects == null )
+ {
+ parameterObjects = null;
+ parameterTypes = null;
+ log.info("No compensation objects will be used.");
+ }
+ else
+ {
+ log.info("Compensation objects found.");
+ for (Object singleObject : compensationObjects)
+ {
+ log.info("Compensation object: " + singleObject);
+ }
+ log.info("Adding compensation objects as parameters.");
+ parameterObjects = new Object[compensationObjects.length];
+ parameterTypes = new Class[compensationObjects.length];
+ System.arraycopy(compensationObjects,0,parameterObjects,0,compensationObjects.length);
+
+ int i = 0;
+ log.info("Adding parameter types.");
+ for (Object singleObject : parameterObjects)
+ {
+ log.info("Link (" + singleObject + "," + singleObject.getClass()+")");
+ parameterTypes[i++] = singleObject.getClass();
+ }
+
+ }
+
+ log.info("Parameter objects:");
+ for (Object parameter : parameterObjects)
+ {
+ log.info(parameter);
+ }
+ log.info("Parameter types:");
+ for (Class clazz : parameterTypes)
+ {
+ log.info(clazz);
+ }
+ }
+ else if (compensationType.equals("CUSTOM"))
+ {
+ // Show all remember objects
+ log.info("Compensation objects:");
+ for (String key : ((CompensationDataReturn)cd).getPrimaryObjects().keySet())
+ {
+ log.info(key);
+ }
+
+ // Mapping (annotation,object)
+ Map<String,Object> annoObjects = new HashMap<String,Object>();
+ String returnName = ((CompensationDataReturn)cd).getReturnName();
+ if (!returnName.equals(""))
+ {
+ annoObjects.put(returnName,returnObject);
+ }
+ annoObjects.putAll(((CompensationDataReturn)cd).getPrimaryObjects());
+
+ // Get reference to the method as we need the annotations
+ // We do not know what the parameters are so we must check its method
+ // and compare its name
+ Class clazz = sd.getCompensationClass();
+ log.info("Class: " + clazz.getName());
+ log.info("Getting all methods...");
+ Method[] methods = clazz.getMethods();
+ theMethod = null;
+ log.info("Searching for method: " + sd.getOriginalMethodName());
+ for (Method oneMethod : methods)
+ {
+ if (oneMethod.getName().equals(sd.getCompensationMethodName()))
+ {
+ log.info("Method found!");
+ theMethod = oneMethod;
+ break;
+ }
+ }
+ log.info("Getting annotations...");
+ Annotation[][] parameterAnnotations = theMethod.getParameterAnnotations();
+ log.info("Number of parameters for this method: " + parameterAnnotations.length);
+ parameterObjects = new Object[parameterAnnotations.length];
+ parameterTypes = new Class[parameterAnnotations.length];
+
+ // Check each parameter if it has the @BAParam annotation
+ log.info("Searching for @BAParam parameter annotation...");
+ int i = 0;
+ for (Annotation[] annotationArray : parameterAnnotations)
+ {
+ log.info("Annotation array length: " + annotationArray.length);
+ for (Annotation annotation : annotationArray)
+ {
+ if (annotation instanceof BAParam)
+ {
+ log.info("BAParam annotation on parameter: " + i);
+ String value = ((BAParam)annotation).value();
+ log.info("Value: " + value);
+ log.info("Getting compensation object for this parameter.");
+ Object someObject = annoObjects.get(value);
+ if (someObject != null)
+ {
+ log.info("Object found: " + someObject.toString());
+ parameterObjects[i] = someObject;
+ parameterTypes[i] = someObject.getClass();
+ }
+ else
+ {
+ log.info("Object was not found!");
+ // I will throw an exception !!! I need to specify exceptions!
+ throw new CompensationActionUnsuccessfulException("Compensation object not found.");
+ }
+ }
+ }
+ i++;
+ }
+ }
+ }
+ else
+ {
+ log.info("Compensation type was RETURN");
+ }
+
+ // Get reference to the method
+ Class clazz = sd.getCompensationClass();
+ log.info("Class: " + clazz.getName());
+ if (theMethod == null)
+ {
+ theMethod = clazz.getMethod(sd.getCompensationMethodName(),parameterTypes);
+ log.info("Method: " + theMethod.getName());
+ }
+ Constructor classConstructor = clazz.getConstructor();
+ log.info("Constructor: " + classConstructor.toString());
+ Object classObject = classConstructor.newInstance();
+
+ // Inject the transaction identifier
+ log.info("Injecting transaction identifier...");
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field singleField : fields)
+ {
+ BACompensationManagement cm = singleField.getAnnotation(BACompensationManagement.class);
+ if (cm != null)
+ {
+ log.info("CompensationManager2 found...");
+ log.info("Creating new one...");
+ log.info("txId: " + txId);
+ log.info("taskId: " + taskId);
+ singleField.setAccessible(true);
+ singleField.set(classObject,new CompensationManager2Impl(txId,taskId));
+ }
+ }
+
+ // Invoke the compensation method
+ log.info("Invoking method...");
+ theMethod.invoke(classObject,parameterObjects);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new CompensationActionUnsuccessfulException(e.getMessage());
+ }
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/LocalServiceExecutor.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/LocalServiceExecutor.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/LocalServiceExecutor.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,18 @@
+package org.jboss.txbridge.ba.execute;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ *
+ * This class represents a local service executor. This executor uses the LocalExecution
+ * be default.
+ */
+public class LocalServiceExecutor extends ServiceExecutor
+{
+ public LocalServiceExecutor(String txId,String taskId)
+ {
+ super(txId,taskId);
+ execution = new LocalExecution();
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/RMIExecution.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/RMIExecution.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/RMIExecution.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,17 @@
+package org.jboss.txbridge.ba.execute;
+
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.exception.CompensationActionUnsuccessfulException;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class RMIExecution implements ExecutionInterface
+{
+ public void invokeService(String txId, String taskId, ServiceDescription sd, CompensationData cd) throws CompensationActionUnsuccessfulException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/RemoteServiceExecutor.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/RemoteServiceExecutor.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/RemoteServiceExecutor.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,18 @@
+package org.jboss.txbridge.ba.execute;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ *
+ * This class represents a remote service executor. This executor uses the WSConfiguredDII
+ * be default.
+ */
+public class RemoteServiceExecutor extends ServiceExecutor
+{
+ public RemoteServiceExecutor(String txId,String taskId)
+ {
+ super(txId,taskId);
+ execution = new WSConfiguredDII();
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/ServiceExecutor.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/ServiceExecutor.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/ServiceExecutor.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,74 @@
+package org.jboss.txbridge.ba.execute;
+
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.exception.CompensationActionUnsuccessfulException;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ *
+ * This is an abstract class that describes a basic ServiceExecutor. It provides implementation
+ *
+ */
+public abstract class ServiceExecutor
+{
+ // Transaction identifier
+ String txId;
+
+ // Task identifier
+ String taskId;
+
+ ExecutionInterface execution;
+
+ /**
+ * Main constructor.
+ *
+ * @param txId is the transaction identifier.
+ * @param taskId is the task identifier.
+ */
+ public ServiceExecutor(String txId, String taskId)
+ {
+ this.txId = txId;
+ this.taskId = taskId;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param txId is the transaction identifier.
+ * @param taskId is the task identifier.
+ * @param execution is the execution interface that should be used.
+ */
+ public ServiceExecutor(String txId, String taskId, ExecutionInterface execution)
+ {
+ this.txId = txId;
+ this.taskId = taskId;
+ this.execution = execution;
+ }
+
+ /**
+ * This method sets a new execution type.
+ *
+ * @param execution is the execution type which should be set.
+ */
+ public void setExecutionType(ExecutionInterface execution)
+ {
+ this.execution = execution;
+ }
+
+ /**
+ * This method invokes the compensation task which is specified in the service description.
+ * It uses compensation data which are passed as a parameter.
+ *
+ * @param sd represents the service description.
+ * @param cd represents the compensation data.
+ * @throws CompensationActionUnsuccessfulException if it was not possible to execute compensation action.
+ */
+ public void invokeService(ServiceDescription sd, CompensationData cd) throws CompensationActionUnsuccessfulException
+ {
+ execution.invokeService(txId,taskId,sd,cd);
+ }
+
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/WSConfiguredDII.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/WSConfiguredDII.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/WSConfiguredDII.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,17 @@
+package org.jboss.txbridge.ba.execute;
+
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.exception.CompensationActionUnsuccessfulException;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ */
+public class WSConfiguredDII implements ExecutionInterface
+{
+ public void invokeService(String txId, String taskId, ServiceDescription sd, CompensationData cd) throws CompensationActionUnsuccessfulException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/WSUnconfiguredDII.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/WSUnconfiguredDII.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/execute/WSUnconfiguredDII.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,17 @@
+package org.jboss.txbridge.ba.execute;
+
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.exception.CompensationActionUnsuccessfulException;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class WSUnconfiguredDII implements ExecutionInterface
+{
+ public void invokeService(String txId,String taskId,ServiceDescription sd, CompensationData cd) throws CompensationActionUnsuccessfulException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/BAServiceVisitor.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/BAServiceVisitor.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/BAServiceVisitor.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,263 @@
+package org.jboss.txbridge.ba.helper;
+
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.annotation.*;
+import org.jboss.txbridge.ba.data.*;
+import org.jboss.txbridge.ba.exception.MethodIncorrectlyAnnotatedException;
+import org.jboss.txbridge.ba.exception.CompensationMethodNotAccessible;
+
+import javax.ejb.TransactionAttributeType;
+import javax.jws.WebMethod;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.lang.reflect.Method;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ */
+public class BAServiceVisitor
+{
+ // Logger
+ private static Logger log = Logger.getLogger(BAServiceVisitor.class);
+
+ // Default BA Service Type
+ private static BAServiceType defaultBAServiceType = BAServiceType.MODIFY;
+
+ // Default BA Agreement Type
+ private static BAAgreementType defaultBAAgreementType = BAAgreementType.PARTICIPANT_COMPLETION;
+
+ // Default BA Compensation Type
+ private static BACompensationType defaultBACompensationType = BACompensationType.RETURN_VALUE;
+
+ /**
+ * This method processes a single method that
+ *
+ * @param method is the method to be processed.
+ * @return the service description.
+ * @throws org.jboss.txbridge.ba.exception.MethodIncorrectlyAnnotatedException if the method is not annotated correctly.
+ * @throws org.jboss.txbridge.ba.exception.CompensationMethodNotAccessible if the specified compensatiom method is not accessible.
+ */
+ public static synchronized ServiceDescription processMethod(Method method)
+ throws MethodIncorrectlyAnnotatedException, CompensationMethodNotAccessible
+ {
+ log.info("processMethod()");
+
+ // Create new ServiceDescription
+ ServiceDescription serviceDescription = new ServiceDescriptionImpl();
+
+ // Check what is the name of the method...
+ log.info("Method name: " + method.getName());
+ String methodName = method.getName();
+ // ...by default the web method name is the same as the method's name.
+ String webMethodName = methodName;
+
+ // Check if there is a WebMethod annotation
+ WebMethod webMethodAnnotation = method.getAnnotation(WebMethod.class);
+ if (webMethodAnnotation != null)
+ {
+ log.info("WebMethod annotation present!");
+
+ // Check if the operation name has been specified
+ String name = webMethodAnnotation.operationName();
+ if (name != null && !name.equals(""))
+ {
+ log.info("WebMethod operationName: " + name);
+ // If yes... change the name of the web method
+ webMethodName = name;
+ }
+ }
+
+ // Set the class of the method
+ serviceDescription.setOriginalClass(method.getDeclaringClass());
+
+ // Remember names of the method
+ serviceDescription.setOriginalMethodName(methodName);
+ serviceDescription.setOriginalWebMethodName(webMethodName);
+
+ // Set the parameter types of the original method
+ serviceDescription.setOriginalParameterTypes(method.getParameterTypes());
+
+ // Check if this method is a BA service
+ BAService baService = method.getAnnotation(BAService.class);
+ BAServiceType baServiceType;
+ if (baService != null)
+ {
+ log.info("Method " + methodName + " is a BA service.");
+
+ // Get the type of the service
+ baServiceType = baService.value();
+ if (baServiceType != null)
+ {
+ log.info("BAServiceType: " + baServiceType);
+
+ }
+ else
+ {
+ baServiceType = defaultBAServiceType;
+ }
+ serviceDescription.setServiceType(baServiceType);
+ }
+ else
+ {
+ throw new MethodIncorrectlyAnnotatedException("Method does not have @BAService annotation.");
+ }
+
+ // Check the type of the agreement protocol
+ BAAgreement txAttr = method.getAnnotation(BAAgreement.class);
+ BAAgreementType agreementType = defaultBAAgreementType;
+ if (txAttr != null)
+ {
+ log.info("BAAgreement annotation present!");
+ // If there was a transaction attribute check the type of the transaction attribute
+ BAAgreementType txType = txAttr.value();
+ if (txType != null)
+ {
+ log.info("BAAgreementType: " + txType);
+ agreementType = txType;
+ }
+ else
+ {
+ log.info("BAAgreementType missing.");
+ }
+
+ }
+ else
+ {
+ // We do not throw an exception as we assume that by default the agreement
+ // protocol is PARTICIPANT_COMPLETION
+ log.info("BAAgreement annotation missing. Assuming default.");
+ }
+ // Rememeber the agreement type
+ serviceDescription.setAgreementType(agreementType);
+
+ // Check the compensation method
+ BACompensatedBy baComp = method.getAnnotation(BACompensatedBy.class);
+ if (baComp != null)
+ {
+ log.info("BACompensatedBy annotation present!");
+ String compensationMethodName = baComp.value();
+ log.info("Compensation method: " + compensationMethodName);
+ String compensationMethodClassName = baComp.methodClass();
+ Class compensationMethodClass;
+ Method[] methodList = method.getDeclaringClass().getMethods();
+ if (!compensationMethodClassName.equals(""))
+ {
+ log.info("Compensation class name: " + compensationMethodClassName);
+ compensationMethodClassName = method.getClass().getName();
+
+ try
+ {
+ // Get reference to the class
+ compensationMethodClass = Class.forName(compensationMethodClassName);
+
+ // Get all methods from this class
+ methodList = compensationMethodClass.getMethods();
+
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ throw new CompensationMethodNotAccessible("Class of compensation method not found.");
+ }
+ }
+ else
+ {
+ compensationMethodClass = method.getClass();
+ }
+
+ // Checking if the compensation method exists
+ log.info("Checking if compensation method exists...");
+ boolean methodFound = false;
+ for (Method singleMethod : methodList)
+ {
+ log.info("Comparing " + compensationMethodName + " against " + singleMethod.getName() + ".");
+ if (singleMethod.getName().equals(compensationMethodName))
+ {
+ serviceDescription.setCompensationParameterTypes(singleMethod.getParameterTypes());
+ methodFound = true;
+ break;
+ }
+ }
+ if (!methodFound)
+ {
+ throw new CompensationMethodNotAccessible("Compensation method not found.");
+ }
+ log.info("Compensation method found successfully.");
+ serviceDescription.setCompensationMethodName(compensationMethodName);
+ serviceDescription.setCompensationClass(compensationMethodClass);
+
+ // Check the compensation type
+ BACompensationType compType = baComp.type();
+ if (compType != null)
+ {
+ log.info("Compensation type: " + compType);
+ }
+ else
+ {
+ log.info("Compensation type information missing.");
+ compType = defaultBACompensationType;
+ log.info("Assuming default compensation type: " + compType);
+ }
+ serviceDescription.setCompensationType(compType);
+ }
+ else
+ {
+ log.info("BACompensatedBy annotation missing.");
+ log.info("Checking the type of the service.");
+ if (baServiceType != BAServiceType.READONLY)
+ {
+ log.info("Service is read only. BACompensatedBy is not necessary.");
+ }
+ else
+ {
+ throw new MethodIncorrectlyAnnotatedException("BACompensatedBy annotation missing.");
+ }
+ }
+
+
+ // Remember @BAParam annotation values
+
+
+ // Remember @BAResult annotation value
+ BAResult baResult = method.getAnnotation(BAResult.class);
+ String returnName = "";
+ Integer returnId = -1;
+ if (baResult != null)
+ {
+ log.info("BAResult annotation present!");
+ returnName = baResult.value();
+ if (!returnName.equals(""))
+ {
+ // Check if this is a numerical identifier or not
+ try
+ {
+ returnId = new Integer(returnName);
+ if (serviceDescription.getIdentificationType() == IdentificationType.BY_NAME)
+ {
+ throw new MethodIncorrectlyAnnotatedException("BAResult annotation uses numerical identifier.");
+ }
+ log.info("Return identifier: " + returnId);
+ serviceDescription.setOriginalReturnId(returnId);
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (serviceDescription.getIdentificationType() == IdentificationType.BY_NUMBER)
+ {
+ throw new MethodIncorrectlyAnnotatedException("BAResult annotation uses text identifier.");
+ }
+ log.info("Return identifier: " + returnName);
+ serviceDescription.setOriginalReturnName(returnName);
+ }
+ }
+ else
+ {
+ throw new MethodIncorrectlyAnnotatedException("BAResult annotation has a wrong identifier.");
+ }
+
+ }
+
+ // Return the service description
+ return serviceDescription;
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ClassBAVisitor.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ClassBAVisitor.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ClassBAVisitor.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,159 @@
+package org.jboss.txbridge.ba.helper;
+
+import org.jboss.txbridge.ba.data.SimpleClassInformation;
+import org.jboss.txbridge.ba.data.SimpleMethodInformation;
+import org.jboss.txbridge.ba.data.MethodInformation;
+import org.jboss.txbridge.ba.data.ClassInformation;
+import org.jboss.txbridge.ba.annotation.*;
+import org.apache.log4j.Logger;
+
+import javax.jws.WebMethod;
+import javax.ejb.TransactionAttributeType;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.lang.reflect.Method;
+
+
+/**
+ * Author: Maciej Machulak
+ */
+public class ClassBAVisitor
+{
+ // Logger
+ private static Logger log = Logger.getLogger(ClassBAVisitor.class);
+
+ // Other
+ private static TransactionAttributeType defaultTxAttributeType = TransactionAttributeType.REQUIRED;
+ private static BAServiceType defaultBAServiceType = BAServiceType.MODIFY;
+
+ // Create information about a class
+ public static synchronized ClassInformation processClass(Class clazz)
+ {
+ log.info("processClass()");
+
+ // Create new mappings
+ ConcurrentMap<String,MethodInformation> methodMappings = new ConcurrentHashMap<String,MethodInformation>();
+ ConcurrentMap<String,String> methodNameMappings = new ConcurrentHashMap<String,String>();
+
+ // Get all the methods from the class
+ Method[] methodList = clazz.getDeclaredMethods();
+ log.info("Number of methods: " + methodList.length);
+
+ // Loop through all methods
+ for (Method singleMethod : methodList)
+ {
+ // Return class
+ Class<?> returnType = null;
+ Class<?>[] parameterTypes = null;
+
+ // Check what is the name of the method
+ log.info("Single method: " + singleMethod.getName());
+ String methodName = singleMethod.getName();
+ String webMethodName = methodName;
+
+ // Check if there is a WebMethod annotation
+ WebMethod webMethodAnnotation = singleMethod.getAnnotation(WebMethod.class);
+ if (webMethodAnnotation != null)
+ {
+ log.info("WebMethod annotation present!");
+
+ // Check if the operation name has been specified
+ String name = webMethodAnnotation.operationName();
+ if (name != null && !name.equals(""))
+ {
+ log.info("WebMethod operationName: " + name);
+ // If yes... change the name of the web method
+ webMethodName = name;
+ }
+ }
+ // Remember (method,webMethod) association
+ methodNameMappings.put(methodName,webMethodName);
+
+ // Check if this method is a BA service
+ String serviceType = defaultBAServiceType.toString();
+ BAService baService = singleMethod.getAnnotation(BAService.class);
+ if (baService != null)
+ {
+ log.info("Method " + webMethodName + " is a BA service.");
+
+ // Get the type of the service
+ BAServiceType baServiceType = baService.value();
+ if (baServiceType != null)
+ {
+ log.info("BAServiceType: " + baServiceType);
+ serviceType = baServiceType.toString();
+ }
+
+ }
+
+ // Check the transaction attribute
+ String transactionType = defaultTxAttributeType.toString();
+ BAAgreement txAttr = singleMethod.getAnnotation(BAAgreement.class);
+ if (txAttr != null)
+ {
+
+ log.info("BAAgreement annotation present!");
+ // If there was a transaction attribute check the type of the transaction attribute
+ BAAgreementType txType = txAttr.value();
+
+ if (txType != null)
+ {
+ log.info("BAAgreementType: " + txType);
+ transactionType = txType.toString();
+ }
+ }
+
+ // Check the compensation method
+ String compensationMethod = "";
+ String compensationType = "";
+ BACompensatedBy baComp = singleMethod.getAnnotation(BACompensatedBy.class);
+ if (baComp != null)
+ {
+ log.info("BACompensatedBy annotation present!");
+ log.info("Remembering compensation method.");
+ compensationMethod = baComp.value();
+ log.info("Remembering type of compensation.");
+ compensationType = baComp.type().toString();
+ }
+
+ // Check the types of the parameters
+ for (Method theMethod : methodList)
+ {
+ if (theMethod.getName().equals(compensationMethod))
+ {
+ parameterTypes = theMethod.getParameterTypes();
+ break;
+ }
+ }
+
+ // Get the return type
+ returnType = singleMethod.getReturnType();
+
+ // Check BAResult
+ BAResult baResult = singleMethod.getAnnotation(BAResult.class);
+ String returnName = "";
+ if (baResult != null)
+ {
+ log.info("BAResult found!");
+ returnName = baResult.value();
+
+ }
+
+ MethodInformation singleMethodInfo = new SimpleMethodInformation(webMethodName,clazz,methodName,returnType,transactionType,serviceType,clazz,compensationMethod,parameterTypes,compensationType);
+ singleMethodInfo.setReturnName(returnName);
+ methodMappings.putIfAbsent(webMethodName,singleMethodInfo);
+ }
+
+ // Cache all obtained values
+ return new SimpleClassInformation(clazz,methodNameMappings,methodMappings);
+ }
+
+ // This method will be removed - i will have an aspect that injects a compensation
+ // service
+ public static synchronized void injectCompensation(Class clazz)
+ {
+
+
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ClassInformationManager.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ClassInformationManager.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ClassInformationManager.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,84 @@
+package org.jboss.txbridge.ba.helper;
+
+import org.jboss.txbridge.ba.data.SimpleClassInformation;
+import org.jboss.txbridge.ba.data.ClassInformation;
+import org.apache.log4j.Logger;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class ClassInformationManager
+{
+ // Logger
+ private static Logger log = Logger.getLogger(ClassInformationManager.class);
+
+ // Mapping (class name , class information)
+ private ConcurrentMap<String, ClassInformation> classDescriptions;
+
+ // Class information manager instance
+ private volatile static ClassInformationManager cim = null;
+
+ // Constructor
+ private ClassInformationManager()
+ {
+ log.info("constructor()");
+ classDescriptions = new ConcurrentHashMap<String, ClassInformation>();
+ }
+
+ // Get instance of the class information manager
+ public static ClassInformationManager getSingletonInstance()
+ {
+ log.info("getSingletonInstance()");
+ if (cim == null)
+ {
+ synchronized(ClassInformationManager.class)
+ {
+ if (cim == null)
+ {
+ log.info("Creating new instance");
+ cim = new ClassInformationManager();
+ }
+ }
+ }
+ return cim;
+ }
+
+ // Store information about a class
+ public void storeClassInformation(ClassInformation classInformation)
+ {
+ log.info("storeClassInformation(ClassInformation)");
+ storeClassInformation(classInformation.getTheClass().getName(),classInformation);
+ }
+
+ // Store information about a class
+ public void storeClassInformation(String className, ClassInformation classInformation)
+ {
+ log.info("storeClassInformation(String,ClassInformation)");
+ classDescriptions.putIfAbsent(className,classInformation);
+ }
+
+ // Get information about a class of a given name
+ public ClassInformation getClassInformation(String className)
+ {
+ log.info("getClassInformation()");
+ log.info("No. of classes: " + classDescriptions.size());
+ ClassInformation classInfo = classDescriptions.get(className);
+ if (classInfo == null)
+ {
+ log.info("Returning null...");
+ }
+ return classInfo;
+ }
+
+ // Check if a class of a given name has its information object stored
+ public boolean knowsAbout(String className)
+ {
+ log.info("knowsAbout()");
+ return classDescriptions.containsKey(className);
+ }
+
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ServiceInformationManager.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ServiceInformationManager.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/helper/ServiceInformationManager.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,161 @@
+package org.jboss.txbridge.ba.helper;
+
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.id.IdentifierFactory;
+import org.jboss.txbridge.ba.id.RandomIdentifierFactory;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ *
+ * This class is responsible for caching information about service descriptions. It associates
+ * its description with a unique identifier of a service.
+ */
+public class ServiceInformationManager
+{
+ // Logger
+ private static Logger log = Logger.getLogger(ServiceInformationManager.class);
+
+ // Service information manager instance
+ private volatile static ServiceInformationManager cim = null;
+
+ // Identifier factory
+ private IdentifierFactory idf = null;
+
+ // Mappings
+ // - (class name + method name, service id)
+ private ConcurrentMap<String,String> methodServiceIdMapping;
+ // - (service id, service_description)
+ private ConcurrentMap<String,ServiceDescription> serviceDescriptions;
+
+ // Constructor
+ private ServiceInformationManager()
+ {
+ log.info("constructor()");
+ idf = new RandomIdentifierFactory();
+ methodServiceIdMapping = new ConcurrentHashMap<String,String>();
+ serviceDescriptions = new ConcurrentHashMap<String,ServiceDescription>();
+ }
+
+ // Get instance of the class information manager
+ public static ServiceInformationManager getSingletonInstance()
+ {
+ log.info("getSingletonInstance()");
+ if (cim == null)
+ {
+ synchronized(ClassInformationManager.class)
+ {
+ if (cim == null)
+ {
+ log.info("Creating new instance");
+ cim = new ServiceInformationManager();
+ }
+ }
+ }
+ return cim;
+ }
+
+ /**
+ * This method stores a service description. It returns a unique associates service ID.
+ *
+ * @param serviceDescription is the service description that needs to be stored.
+ * @return is the unique service ID.
+ */
+ public String storeServiceDescription(ServiceDescription serviceDescription)
+ {
+ log.info("storeServiceDescription()");
+ String serviceId = idf.getIdentifier();
+ log.info("service id: " + serviceId);
+ String className = serviceDescription.getOriginalClass().getName();
+ String methodName = serviceDescription.getOriginalMethodName();
+ storeServiceDescription(serviceId,className+methodName,serviceDescription);
+ return serviceId;
+ }
+
+ /**
+ * This method stores a service description for a service with a given complete name and
+ * returns a unique associated service ID.
+ *
+ * @param serviceId is the unique service Id.
+ * @param completeMethodName is the complete method's name.
+ * @param serviceDescription is the service description.
+ */
+ public void storeServiceDescription(String serviceId, String completeMethodName,ServiceDescription serviceDescription)
+ {
+ log.info("storeServiceDescription()");
+ methodServiceIdMapping.putIfAbsent(completeMethodName,serviceId);
+ serviceDescriptions.putIfAbsent(completeMethodName,serviceDescription);
+ }
+
+ /**
+ * This method returns the service description for a service with a given identifier.
+ *
+ * @param completeMethodName is the complete method name (classname+methodname)
+ * @return service description.
+ */
+ public ServiceDescription getServiceByName(String completeMethodName)
+ {
+ log.info("getServiceByName()");
+ String serviceId = methodServiceIdMapping.get(completeMethodName);
+ if (serviceId == null)
+ {
+ return null;
+ }
+ return serviceDescriptions.get(serviceId);
+ }
+
+ /**
+ * This method returns the service description for a service with a given identifier.
+ *
+ * @param serviceId is the ID of the service.
+ * @return service description.
+ */
+ public ServiceDescription getServiceById(String serviceId)
+ {
+ log.info("getServiceById");
+ return serviceDescriptions.get(serviceId);
+ }
+
+ /**
+ * This method returns the ID for the service with a given class name and given method name.
+ *
+ * @param completeMethodName is the complete method name (classname+methodname)
+ * @return the service ID.
+ */
+ public String getServiceId(String completeMethodName)
+ {
+ log.info("getServiceId()");
+ return methodServiceIdMapping.get(completeMethodName);
+ }
+
+ /**
+ * This method checks if the service information manager already knows of a service
+ * with a given identifier.
+ *
+ * @param serviceId is the service identifier.
+ * @return true if the service is know, false if not.
+ */
+ public boolean knowsAboutById(String serviceId)
+ {
+ log.info("knowsAboutById()");
+ return serviceDescriptions.containsKey(serviceId);
+ }
+
+ /**
+ * This method checks if the service information manager already knows of a service
+ * with a given identifier.
+ *
+ * @param serviceName is the full name of the service (class name + method name)
+ * @return true if the service is know, false if not.
+ */
+ public boolean knowsAboutByName(String serviceName)
+ {
+ log.info("knowsAboutByName()");
+ return methodServiceIdMapping.containsKey(serviceName);
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/IdentifierFactory.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/IdentifierFactory.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/IdentifierFactory.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,24 @@
+package org.jboss.txbridge.ba.id;
+
+/**
+ * @author: Maciej Machulak
+ * @date:
+ *
+ * This is an abstract class for the
+ */
+public abstract class IdentifierFactory
+{
+ UniqueValueGetter uvg;
+
+ protected IdentifierFactory()
+ {
+ }
+
+
+
+ public String getIdentifier()
+ {
+ return uvg.getUniqueValue();
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/RandomGetter.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/RandomGetter.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/RandomGetter.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,27 @@
+package org.jboss.txbridge.ba.id;
+
+import org.apache.log4j.Logger;
+
+import java.util.Random;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class RandomGetter implements UniqueValueGetter
+{
+ // Identifier uniqueness
+ private static int IDENTIFIER_PRECISION = 24;
+
+ // Random generator
+ private static Random rg = new Random();
+
+ // Randomly generated bytes
+ byte[] id = new byte[IDENTIFIER_PRECISION];
+
+ public String getUniqueValue()
+ {
+ rg.nextBytes(id);
+ return new String(id);
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/RandomIdentifierFactory.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/RandomIdentifierFactory.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/RandomIdentifierFactory.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,14 @@
+package org.jboss.txbridge.ba.id;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class RandomIdentifierFactory extends IdentifierFactory
+{
+
+ public RandomIdentifierFactory()
+ {
+ this.uvg = new RandomGetter();
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UidGetter.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UidGetter.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UidGetter.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,15 @@
+package org.jboss.txbridge.ba.id;
+
+import com.arjuna.ats.arjuna.common.Uid;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class UidGetter implements UniqueValueGetter
+{
+ public String getUniqueValue()
+ {
+ return new Uid().toString();
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UidIdentifierFactory.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UidIdentifierFactory.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UidIdentifierFactory.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,15 @@
+package org.jboss.txbridge.ba.id;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 2, 2007
+ */
+public class UidIdentifierFactory extends IdentifierFactory
+{
+
+ public UidIdentifierFactory()
+ {
+ this.uvg = new UidGetter();
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UniqueValueGetter.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UniqueValueGetter.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/id/UniqueValueGetter.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,9 @@
+package org.jboss.txbridge.ba.id;
+
+/**
+ * Author: Maciej Machulak
+ */
+public interface UniqueValueGetter
+{
+ public String getUniqueValue();
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JBossServiceAccessFactory.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JBossServiceAccessFactory.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JBossServiceAccessFactory.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,26 @@
+package org.jboss.txbridge.ba.old;
+
+import org.jboss.ws.core.CommonMessageContext;
+import org.jboss.ws.core.soap.MessageContextAssociation;
+import org.jboss.ws.metadata.umdm.EndpointMetaData;
+import org.jboss.txbridge.ba.old.ServiceAccessFactory;
+import org.apache.log4j.Logger;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class JBossServiceAccessFactory extends ServiceAccessFactory
+{
+ // Logger
+ private static Logger log = Logger.getLogger(JBossServiceAccessFactory.class);
+
+ // Return a class that's method is being invoked in this context
+ public Class getService()
+ {
+ log.info("getService()");
+ CommonMessageContext commonMessageContext = MessageContextAssociation.peekMessageContext();
+ EndpointMetaData emd = commonMessageContext.getEndpointMetaData();
+ return emd.getServiceEndpointInterface();
+ }
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JaxWSBASpecifierHandler.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JaxWSBASpecifierHandler.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JaxWSBASpecifierHandler.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,126 @@
+package org.jboss.txbridge.ba.old;
+
+import org.apache.log4j.Logger;
+
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+
+
+import org.jboss.txbridge.ba.data.ClassInformation;
+import org.jboss.txbridge.ba.helper.*;
+import org.jboss.txbridge.ba.annotation.BAProperties;
+import org.jboss.txbridge.ba.old.ServiceAccessFactory;
+import org.jboss.txbridge.ba.old.SOAPProcessor;
+import org.jboss.txbridge.ba.old.JBossServiceAccessFactory;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class JaxWSBASpecifierHandler implements Handler
+{
+ // Logger
+ private static Logger log = Logger.getLogger(JaxWSBASpecifierHandler.class);
+
+ // Service factory
+ private static ServiceAccessFactory serviceAccess = new JBossServiceAccessFactory();
+
+ public boolean handleMessage(MessageContext msgContext)
+ {
+ log.debug("handleMessage()");
+
+ Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ if (outbound == null)
+ {
+ throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ }
+ return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
+ }
+
+ private boolean handleInbound(MessageContext msgContext)
+ {
+
+ log.debug("handleInbound()");
+
+ // Get reference to the service which is invoked
+ Class clazz = serviceAccess.getService();
+ String className = clazz.getName();
+ log.info("Class name: " + className);
+
+ // Get reference to the class manager
+ ClassInformationManager classInfoManager = ClassInformationManager.getSingletonInstance();
+
+ // Obtain information about the class
+ // - first check if the classInfoManager knows about this class
+ ClassInformation classInfo = classInfoManager.getClassInformation(className);
+ // - if not than process this class
+ if (classInfo == null)
+ {
+ // Process class and obtain info
+ classInfo = ClassBAVisitor.processClass(clazz);
+
+ // Remember info about the class
+ classInfoManager.storeClassInformation(classInfo);
+
+ }
+
+ // Inject task identifier
+
+
+ // Check the web method's name
+ String methodName = SOAPProcessor.getMethodName(msgContext);
+
+ // Get the real name of the method
+ methodName = classInfo.getOriginalMethodName(methodName);
+
+ // Display for logging purposes
+ String transactionType = classInfo.getTransactionAttribute(methodName);
+ log.info("Mapping: (" + methodName + "," + transactionType + ")");
+ String serviceType = classInfo.getServiceType(methodName);
+ log.info("Mapping: (" + methodName + "," + serviceType + ")");
+ String compensationMethod = classInfo.getCompensationMethod(methodName);
+ log.info("Link: (" + methodName + "," + compensationMethod + ")");
+ Class returnType = classInfo.getReturnType(methodName);
+ log.info("Return type: (" + methodName + "," + returnType.getName() + ")");
+
+ // Set properties
+ msgContext.put(BAProperties.BAClass.toString(),className);
+ msgContext.put(BAProperties.BAMethod.toString(),methodName);
+
+ return true;
+ }
+
+ private boolean handleOutbound(MessageContext msgContext)
+ {
+ log.info("handleOutbound()");
+ // Remove properties
+ if (msgContext.containsKey(BAProperties.BAClass.toString()))
+ {
+ msgContext.remove(BAProperties.BAClass.toString());
+ }
+ if (msgContext.containsKey(BAProperties.BAMethod.toString()))
+ {
+ msgContext.remove(BAProperties.BAMethod.toString());
+ }
+ return true;
+ }
+
+ public boolean handleFault(MessageContext msgContext)
+ {
+ log.info("handleFault()");
+ // Remove properties
+ if (msgContext.containsKey(BAProperties.BAClass.toString()))
+ {
+ msgContext.remove(BAProperties.BAClass.toString());
+ }
+ if (msgContext.containsKey(BAProperties.BAMethod.toString()))
+ {
+ msgContext.remove(BAProperties.BAMethod.toString());
+ }
+ return true;
+ }
+
+ public void close(MessageContext messageContext)
+ {
+ log.info("close()");
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JaxWSBusinessActivityHandler.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JaxWSBusinessActivityHandler.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/JaxWSBusinessActivityHandler.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,185 @@
+package org.jboss.txbridge.ba.old;
+
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.data.ClassInformation;
+import org.jboss.txbridge.ba.data.MethodInformation;
+import org.jboss.txbridge.ba.BATransactionManager;
+import org.jboss.txbridge.ba.old.ServiceAccessFactory;
+import org.jboss.txbridge.ba.old.JBossServiceAccessFactory;
+import org.jboss.txbridge.ba.old.SOAPProcessor;
+import org.jboss.txbridge.ba.annotation.BAProperties;
+import org.jboss.txbridge.ba.helper.*;
+
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class JaxWSBusinessActivityHandler implements Handler
+{
+ // Logger
+ private static Logger log = Logger.getLogger(JaxWSBusinessActivityHandler.class);
+
+ // Service access factory
+ private static ServiceAccessFactory serviceAccess = new JBossServiceAccessFactory();
+
+ // Get access to the class information manager
+ private static ClassInformationManager classInfoManager = ClassInformationManager.getSingletonInstance();
+
+ public boolean handleMessage(MessageContext msgContext)
+ {
+ log.debug("handleMessage()");
+
+ Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+
+ if (outbound == null)
+ {
+ throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ }
+
+ return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
+ }
+
+ public boolean handleFault(MessageContext messageContext)
+ {
+ log.info("handleFault()");
+ return true;
+ }
+
+ public void close(MessageContext messageContext)
+ {
+ log.info("close()");
+ }
+
+ protected boolean handleInbound(MessageContext msgContext)
+ {
+ log.debug("handleInbound()");
+
+ // Get access to the class
+ Class clazz = serviceAccess.getService();
+
+ // Obtain class info
+ ClassInformation classInfo = classInfoManager.getClassInformation(clazz.getName());
+
+ // Get properties
+ String className = (String) msgContext.get(BAProperties.BAClass.toString());
+ log.info("className: " + className);
+ String webMethodName = (String) msgContext.get(BAProperties.BAMethod.toString());
+ log.info("webMethodName: " + webMethodName);
+
+ // Check if those are correct
+ // - check class
+ if (!className.equals(clazz.getName()))
+ {
+ return false;
+ }
+ // - check method
+ // TODO: IMPLEMENT
+
+ // Get original method name
+ String methodName = classInfo.getOriginalMethodName(webMethodName);
+ // Get method information
+ MethodInformation methodInfo = classInfo.getMethodInformation(methodName);
+
+ // Display for logging purposes
+ log.info("Business Activity...");
+ log.info("BAService: " + methodInfo.getServiceType());
+ log.info("BAAgreement: " + methodInfo.getTransactionAttribute());
+ log.info("BACompensatedBy: " + methodInfo.getCompensationMethod());
+ log.info("Return Type: " + methodInfo.getReturnType().getName());
+
+ // Check the type of transaction
+ if (methodInfo.getTransactionAttribute() == null)
+ {
+
+ }
+ else if (methodInfo.getTransactionAttribute().equals("COORDINATOR_COMPLETION"))
+ {
+
+ }
+ else if (methodInfo.getTransactionAttribute().equals("PARTICIPANT_COMPLETION"))
+ {
+ // Get reference to the BATransactionManager
+ log.info("Getting reference to the BA Bridge Manager");
+ BATransactionManager babridgeManager = BATransactionManager.getSingletonInstance();
+
+ // Starting transaction management
+ log.info("Starting transaction managemenet");
+ babridgeManager.handleTheTransaction(methodInfo,"");
+
+ }
+
+ return true;
+ }
+
+ /**
+ * Tidy up the Transaction/Thread association before returning a message to the client.
+ *
+ * @param msgContext
+ * @return
+ */
+ protected boolean handleOutbound(MessageContext msgContext)
+ {
+
+ log.info("handleOutbound()");
+ try
+ {
+ // Get the soap method name
+ String className = (String) msgContext.get(BAProperties.BAClass.toString());
+ log.info("className: " + className);
+ String webMethodName = (String) msgContext.get(BAProperties.BAMethod.toString());
+ log.info("webMethodName: " + webMethodName);
+
+ // Get the methods information
+ ClassInformation classInfo = classInfoManager.getClassInformation(className);
+ String methodName = classInfo.getOriginalMethodName(webMethodName);
+ log.info("originalName: " + methodName);
+ MethodInformation methodInfo = classInfo.getMethodInformation(methodName);
+
+ // Check the type of transaction
+ if (methodInfo.getTransactionAttribute() == null)
+ {
+
+ }
+ else if (methodInfo.getTransactionAttribute().equals("COORDINATOR_COMPLETION"))
+ {
+
+ }
+ else if (methodInfo.getTransactionAttribute().equals("PARTICIPANT_COMPLETION"))
+ {
+ log.info("Getting reference to the bridge manager");
+ BATransactionManager babridgeManager = BATransactionManager.getSingletonInstance();
+
+ // Get the return object if necessary
+ log.info("checking return type...");
+ Class returnType = methodInfo.getReturnType();
+ log.info("return type: " + returnType.getName());
+ if (!methodInfo.getReturnType().getName().equals("void"))
+ {
+ log.info("Getting return object");
+ Object returnObject = SOAPProcessor.getReturnObject(msgContext);
+ log.info("Return object: " + returnObject.toString());
+ // Set compensation object
+
+ log.info("Remembering return object");
+ //babridgeManager.manageReturnObject(methodInfo,returnObject,"");
+ }
+
+ babridgeManager.completeTransaction();
+ }
+
+
+
+ }
+ catch (Exception soape)
+ {
+ soape.printStackTrace();
+ }
+
+ return true;
+ }
+
+
+
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/SOAPProcessor.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/SOAPProcessor.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/SOAPProcessor.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,57 @@
+package org.jboss.txbridge.ba.old;
+
+import org.jboss.ws.core.soap.SOAPContentElement;
+import org.apache.log4j.Logger;
+
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPBodyElement;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class SOAPProcessor
+{
+ // Logger
+ private static Logger log = Logger.getLogger(SOAPProcessor.class);
+
+ // Pull out a method's name from the SOAP message
+ public static synchronized String getMethodName(MessageContext msgContext)
+ {
+ log.info("getMethodName()");
+ try
+ {
+ SOAPMessage soapMessage = ((SOAPMessageContext)msgContext).getMessage();
+ SOAPBody soapBody = soapMessage.getSOAPBody();
+ SOAPBodyElement soapBodyElement = (SOAPBodyElement)soapBody.getChildElements().next();
+ return soapBodyElement.getElementName().getLocalName();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ // Pull out the return object from a message
+ public static synchronized Object getReturnObject(MessageContext msgContext)
+ {
+ log.info("getReturnObject()");
+ try
+ {
+ SOAPMessage soapMessage = ((SOAPMessageContext)msgContext).getMessage();
+ SOAPBody soapBody = soapMessage.getSOAPBody();
+ SOAPBodyElement soapBodyElement = (SOAPBodyElement)soapBody.getChildElements().next();
+ SOAPContentElement parameterElement = (SOAPContentElement) soapBodyElement.getChildElements().next();
+ parameterElement.getObjectValue();
+ return parameterElement.getObjectValue();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/ServiceAccessFactory.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/ServiceAccessFactory.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/old/ServiceAccessFactory.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,15 @@
+package org.jboss.txbridge.ba.old;
+
+/**
+ * Author: Maciej Machulak
+ */
+public abstract class ServiceAccessFactory
+{
+
+ protected ServiceAccessFactory()
+ {
+ Class clazz = getService();
+ }
+
+ public abstract Class getService();
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/CoordinatorCompletionParticipantBA.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/CoordinatorCompletionParticipantBA.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/CoordinatorCompletionParticipantBA.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,42 @@
+package org.jboss.txbridge.ba.participant;
+
+import com.arjuna.wst.*;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class CoordinatorCompletionParticipantBA extends Participant implements BusinessAgreementWithCoordinatorCompletionParticipant
+{
+
+ public void close() throws WrongStateException, SystemException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void cancel() throws WrongStateException, SystemException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void compensate() throws FaultedException, WrongStateException, SystemException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public String status() throws SystemException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void unknown() throws SystemException {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void error() throws SystemException {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void complete() throws WrongStateException, SystemException {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/CoordinatorCompletionParticipantBA1.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/CoordinatorCompletionParticipantBA1.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/CoordinatorCompletionParticipantBA1.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,42 @@
+package org.jboss.txbridge.ba.participant;
+
+import com.arjuna.wst.*;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class CoordinatorCompletionParticipantBA1 extends Participant implements BusinessAgreementWithCoordinatorCompletionParticipant
+{
+
+ public void close() throws WrongStateException, SystemException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void cancel() throws WrongStateException, SystemException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void compensate() throws FaultedException, WrongStateException, SystemException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public String status() throws SystemException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void unknown() throws SystemException {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void error() throws SystemException {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void complete() throws WrongStateException, SystemException {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/Participant.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/Participant.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/Participant.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,193 @@
+package org.jboss.txbridge.ba.participant;
+
+import org.jboss.txbridge.ba.data.CompensationData;
+import org.jboss.txbridge.ba.data.ServiceDescription;
+import org.jboss.txbridge.ba.data.CompensationDataReturn;
+import org.jboss.txbridge.ba.helper.ServiceInformationManager;
+import org.jboss.txbridge.ba.execute.ServiceExecutor;
+import org.jboss.txbridge.ba.execute.RemoteServiceExecutor;
+import org.jboss.txbridge.ba.execute.LocalServiceExecutor;
+import org.jboss.txbridge.ba.exception.CompensationActionUnsuccessfulException;
+import org.jboss.txbridge.ba.exception.TaskAssociationFailedException;
+import org.jboss.txbridge.ba.BATransactionManager;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author: Maciej P. Machulak
+ * @date: Jul 1, 2007
+ *
+ * This is an abstract class for Participant. It gives an implemention of a method that
+ * executes the compensation action for one of the tasks the Participant is responsible
+ * for.
+ */
+public abstract class Participant
+{
+ // Service Information Manager
+ private ServiceInformationManager sim = null;
+
+ // ServiceExecutor
+ protected ServiceExecutor se = null;
+
+ // BA Manager
+ static BATransactionManager baTransactionManager = null;
+
+ // Transaction identifier
+ String txId = null;
+
+ // Service identifier
+ String serviceId = null;
+
+ // List of all tasks
+ private List<String> taskList = null;
+
+ // Mapping (taskId,compensation_data)
+ private ConcurrentMap<String,CompensationData> compensationData = null;
+
+ /**
+ * Main constructor.
+ */
+ public Participant()
+ {
+ // Get reference to the service information manager
+ sim = ServiceInformationManager.getSingletonInstance();
+
+ // Initialise the list of tasks
+ taskList = new ArrayList<String>();
+
+ // Initialise (taskId, compensation data) mapping
+ compensationData = new ConcurrentHashMap<String,CompensationData>();
+
+ // Get reference to the BA Transaction Manager
+ baTransactionManager = BATransactionManager.getSingletonInstance();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param txId is the transaction identifier.
+ * @param serviceId is the service identifier.
+ */
+ public Participant(String txId,String serviceId)
+ {
+ // Remember transaction identifier
+ this.txId = txId;
+
+ // Remember the service identifier
+ this.serviceId = serviceId;
+
+ }
+
+ /**
+ * This method stores an object withing the compensation data for a given task.
+ * The object is assigned an ID.
+ *
+ * @param taskId is the ID of the task.
+ * @param objectId is the ID of the object.
+ * @param object is the object to be stored.
+ */
+ public void put(String taskId,String objectId,Object object)
+ {
+ // TODO: Implementation...
+
+ }
+
+ /**
+ * This method retrieves an object with a given identifier from the compensation data
+ * that is stored for a given task id.
+ *
+ * @param taskId is the ID of the task.
+ * @param objectId is the ID of the object.
+ * @return the object with a given ID.
+ */
+ public Object get(String taskId,String objectId)
+ {
+ // TODO: Implementation...
+ return null;
+ }
+
+ /**
+ * This method associates a new task with the existing participant.
+ *
+ * @param taskId is the task identifier.
+ * @return is the new compensation data object associated with this task.
+ * @throws org.jboss.txbridge.ba.exception.TaskAssociationFailedException if task association fails.
+ */
+ public CompensationData associateTask(String taskId) throws TaskAssociationFailedException
+ {
+ // Check correctness of parameters
+ if (taskList.contains(taskId))
+ {
+ throw new TaskAssociationFailedException("Task already associated.");
+ }
+
+ // Remember the task
+ taskList.add(taskId);
+
+ // Create a new compensation object
+ CompensationData cd = new CompensationDataReturn();
+
+ // Remember the (taskid,compensationdata) association
+ compensationData.put(taskId,cd);
+
+ // Return the compensation data for this task
+ return cd;
+ }
+
+ /**
+ * This method is invoked by the participant object if a transaction should compensate.
+ * It asks the BA Transaction Manager to compensate the transaction.
+ */
+ public void compensateTransaction()
+ {
+ baTransactionManager.compensateTransaction(txId);
+ }
+
+
+ /**
+ * This method provides the implementation for executing the compensation action.
+ * It uses the Executor class for executing a single method/service.
+ *
+ * @param taskId is the ID of the task that is supposed to be compensated.
+ * @return a boolean value if the compensation was successful or not.
+ */
+ public boolean compensateTask(String taskId)
+ {
+ // Obtain information about the service
+ ServiceDescription serviceDescription = sim.getServiceById(serviceId);
+
+ // If the compensation is remote than use remote executor. Otherwise
+ // use the local one.
+ if (serviceDescription.getOriginalClass() != null)
+ {
+ // Use the remote executor.
+ se = new RemoteServiceExecutor(txId,taskId);
+ }
+ else
+ {
+ // Use the local executor.
+ se = new LocalServiceExecutor(txId,taskId);
+ }
+
+ // Try to invoke the compensation action.
+ try
+ {
+ // Get compensation data associated with the task
+ CompensationData cd = compensationData.get(taskId);
+
+ // Invoke the service with the compensation data
+ se.invokeService(serviceDescription,cd);
+ }
+ catch (CompensationActionUnsuccessfulException e)
+ {
+ e.printStackTrace();
+ return false;
+ }
+
+ return true;
+
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/ParticipantCompletionParticipantBA.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/ParticipantCompletionParticipantBA.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/ParticipantCompletionParticipantBA.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,108 @@
+package org.jboss.txbridge.ba.participant;
+
+import com.arjuna.wst.*;
+import org.apache.log4j.Logger;
+import org.jboss.txbridge.ba.SingleTransactionManager;
+import org.jboss.txbridge.ba.compensation.ServiceExecutor;
+import org.jboss.txbridge.ba.data.MethodInformation;
+import org.jboss.txbridge.ba.data.CompensationDataReturn;
+import org.jboss.txbridge.ba.data.CompensationData;
+
+import java.util.List;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class ParticipantCompletionParticipantBA extends Participant implements BusinessAgreementWithParticipantCompletionParticipant
+{
+ // Logger
+ private static Logger log = Logger.getLogger(ParticipantCompletionParticipantBA.class);
+
+ // List of all the tasks associated with this participant
+ private List<String> taskList;
+
+ // Mapp
+
+ // Task identifier
+ String taskId;
+
+ // Reference to the inbound bridge
+ SingleTransactionManager myBridge;
+
+ // Complete information about the original and compensation methods
+ private MethodInformation method;
+
+ // Compensation-data object
+ private CompensationData compensationData = new CompensationDataReturn();
+
+ // Service-executor
+ private ServiceExecutor serviceExecutor = ServiceExecutor.getSingletonInstance();
+
+ public ParticipantCompletionParticipantBA(String txId,String taskId, MethodInformation method)
+ {
+ log.info("constructor()");
+ log.info("txId: " + txId);
+ log.info("taskId: " + taskId);
+ this.txId = txId;
+ this.taskId = taskId;
+ this.method = method;
+ }
+
+
+ public CompensationDataReturn getCompensationData()
+ {
+ log.info("getCompensationData()");
+ return (CompensationDataReturn)compensationData;
+ }
+
+
+ public void setCompensationData(CompensationData compensationData)
+ {
+ log.info("setCompensationData()");
+ this.compensationData = compensationData;
+ }
+
+ public void complete() throws WrongStateException, SystemException
+ {
+ log.info("complete()");
+ }
+
+ public void close() throws WrongStateException, SystemException
+ {
+ log.info("close()");
+ }
+
+ public void cancel() throws WrongStateException, SystemException
+ {
+ log.info("cancel()");
+ }
+
+ public void compensate() throws FaultedException, WrongStateException, SystemException
+ {
+ log.info("compensate()");
+ if (serviceExecutor.executeMethod(txId,taskId,method,compensationData))
+ {
+ log.info("Execution of compensation method was successful!");
+ }
+ else
+ {
+ log.info("Execution of compensation method was not successful.");
+ }
+ }
+
+ public String status() throws SystemException
+ {
+ log.info("status()");
+ return null;
+ }
+
+ public void unknown() throws SystemException
+ {
+ log.info("unknown()");
+ }
+
+ public void error() throws SystemException
+ {
+ log.info("error()");
+ }
+}
Added: labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/ParticipantCompletionParticipantBA1.java
===================================================================
--- labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/ParticipantCompletionParticipantBA1.java (rev 0)
+++ labs/jbosstm/workspace/maciej.machulak/code/bridge/org/jboss/txbridge/ba/participant/ParticipantCompletionParticipantBA1.java 2007-07-04 16:06:44 UTC (rev 13080)
@@ -0,0 +1,50 @@
+package org.jboss.txbridge.ba.participant;
+
+import com.arjuna.wst.*;
+import org.apache.log4j.Logger;
+
+/**
+ * Author: Maciej Machulak
+ */
+public class ParticipantCompletionParticipantBA1 extends Participant implements BusinessAgreementWithParticipantCompletionParticipant
+{
+ // Logger
+ private static Logger log = Logger.getLogger(ParticipantCompletionParticipantBA1.class);
+
+ public ParticipantCompletionParticipantBA1(String txId, String serviceId)
+ {
+ super(txId, serviceId);
+ }
+
+ public void close() throws WrongStateException, SystemException
+ {
+ log.info("close()");
+ }
+
+ public void cancel() throws WrongStateException, SystemException
+ {
+ log.info("cancel()");
+ }
+
+ public void compensate() throws FaultedException, WrongStateException, SystemException
+ {
+ log.info("compensate()");
+ compensateTransaction();
+ }
+
+ public String status() throws SystemException
+ {
+ log.info("status()");
+ return null;
+ }
+
+ public void unknown() throws SystemException
+ {
+ log.info("unknown()");
+ }
+
+ public void error() throws SystemException
+ {
+ log.info("error()");
+ }
+}
More information about the jboss-svn-commits
mailing list