[jboss-svn-commits] JBL Code SVN: r18578 - in labs/jbosstm/trunk/XTS/demo/src: com and 12 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Feb 25 12:45:08 EST 2008


Author: adinn
Date: 2008-02-25 12:45:07 -0500 (Mon, 25 Feb 2008)
New Revision: 18578

Added:
   labs/jbosstm/trunk/XTS/demo/src/com/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/client/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/client/BasicClient.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/IRestaurantServiceAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/IRestaurantServiceBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/RestaurantServiceATService.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/RestaurantServiceBAService.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantManager.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantParticipantAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantParticipantBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantServiceAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantServiceBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantView.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiManager.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiParticipantAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiParticipantBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiServiceAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiServiceBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiView.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreManager.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreParticipantAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreParticipantBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreServiceAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreServiceBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreView.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/ITaxiServiceAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/ITaxiServiceBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/TaxiServiceATService.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/TaxiServiceBAService.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/ITheatreServiceAT.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/ITheatreServiceBA.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/TheatreServiceATService.java
   labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/TheatreServiceBAService.java
Log:
source tree for JaxWS based version of demo

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/client/BasicClient.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/client/BasicClient.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/client/BasicClient.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,558 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * BasicClient.java
+ *
+ * Copyright (c) 2003, 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: BasicClient.java,v 1.10 2004/12/02 16:52:58 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.client;
+
+import com.arjuna.mw.wst.UserBusinessActivity;
+import com.arjuna.mw.wst.UserBusinessActivityFactory;
+import com.arjuna.mw.wst.UserTransaction;
+import com.arjuna.mw.wst.UserTransactionFactory;
+import com.arjuna.mw.wst.client.JaxWSHeaderContextProcessor;
+import com.arjuna.wst.TransactionRolledBackException;
+import com.jboss.jbosstm.xts.demo.restaurant.IRestaurantServiceAT;
+import com.jboss.jbosstm.xts.demo.restaurant.IRestaurantServiceBA;
+import com.jboss.jbosstm.xts.demo.taxi.ITaxiServiceAT;
+import com.jboss.jbosstm.xts.demo.taxi.ITaxiServiceBA;
+import com.jboss.jbosstm.xts.demo.theatre.ITheatreServiceAT;
+import com.jboss.jbosstm.xts.demo.theatre.ITheatreServiceBA;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Service;
+import javax.xml.ws.handler.Handler;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A very basic client application that drives the
+ * (transactional) Web Services to arrange a night out.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Id: BasicClient.java,v 1.10 2004/12/02 16:52:58 kconner Exp $
+ */
+public class BasicClient extends HttpServlet
+{
+    /**
+     * The client serial version UID.
+     */
+    private static final long serialVersionUID = 7728495576623420083L ;
+
+    /**
+     * The servlet context.
+     */
+    private ServletContext context ;
+
+    /***** RESTAURANT SERVICE *****/
+
+    /**
+     * The namespace for the Restaurant webservice.
+     */
+    private static final String RESTAURANT_NS = "http://www.jboss.com/jbosstm/xts/demo/Restaurant" ;
+    /**
+     * The prefix for the Restaurant webservice.
+     */
+    private static final String RESTAURANT_PREFIX = "restaurant";
+    /**
+     * The local name for the AT Restaurant webservice.
+     */
+    private static final String RESTAURANT_SERVICE_AT = "RestaurantServiceATService";
+    /**
+     * The QName for the AT Restaurant webservice.
+     */
+    private static final QName RESTAURANT_SERVICE_AT_QNAME
+            = new QName(RESTAURANT_NS, RESTAURANT_SERVICE_AT, RESTAURANT_PREFIX);
+    /**
+     * The local name for the BA Restaurant webservice.
+     */
+    private static final String RESTAURANT_SERVICE_BA = "RestaurantServiceBAService" ;
+    /**
+     * The QName for the AT Restaurant webservice.
+     */
+    private static final QName RESTAURANT_SERVICE_BA_QNAME
+            = new QName(RESTAURANT_NS, RESTAURANT_SERVICE_BA, RESTAURANT_PREFIX);
+    /**
+     * The local name for the AT Restaurant _.
+     */
+    private static final String RESTAURANT_ENDPOINT_AT = "RestaurantServiceAT";
+    /**
+     * The QName for the AT Restaurant endpoint.
+     */
+    private static final QName RESTAURANT_ENDPOINT_AT_QNAME
+            = new QName(RESTAURANT_NS, RESTAURANT_ENDPOINT_AT, RESTAURANT_PREFIX);
+    /**
+     * The local name for the BA Restaurant endpoint.
+     */
+    private static final String RESTAURANT_ENDPOINT_BA = "RestaurantServiceBA";
+    /**
+     * The QName for the BA Restaurant endpoint.
+     */
+    private static final QName RESTAURANT_ENDPOINT_BA_QNAME
+            = new QName(RESTAURANT_NS, RESTAURANT_ENDPOINT_BA, RESTAURANT_PREFIX);
+
+    /***** THEATRE SERVICE *****/
+
+    /**
+     * The namespace for the Theatre webservice.
+     */
+    private static final String THEATRE_NS = "http://www.jboss.com/jbosstm/xts/demo/Theatre" ;
+    /**
+     * The prefix for the Theatre webservice.
+     */
+    private static final String THEATRE_PREFIX = "theatre";
+    /**
+     * The local name for the AT Theatre webservice.
+     */
+    private static final String THEATRE_SERVICE_AT = "TheatreServiceATService";
+    /**
+     * The QName for the AT Theatre webservice.
+     */
+    private static final QName THEATRE_SERVICE_AT_QNAME
+            = new QName(THEATRE_NS, THEATRE_SERVICE_AT, THEATRE_PREFIX);
+    /**
+     * The local name for the BA Theatre webservice.
+     */
+    private static final String THEATRE_SERVICE_BA = "TheatreServiceBAService" ;
+    /**
+     * The QName for the AT Theatre webservice.
+     */
+    private static final QName THEATRE_SERVICE_BA_QNAME
+            = new QName(THEATRE_NS, THEATRE_SERVICE_BA, THEATRE_PREFIX);
+    /**
+     * The local name for the AT Theatre endpoint.
+     */
+    private static final String THEATRE_ENDPOINT_AT = "TheatreServiceAT";
+    /**
+     * The QName for the AT Theatre endpoint.
+     */
+    private static final QName THEATRE_ENDPOINT_AT_QNAME
+            = new QName(THEATRE_NS, THEATRE_ENDPOINT_AT, THEATRE_PREFIX);
+    /**
+     * The local name for the BA Theatre endpoint.
+     */
+    private static final String THEATRE_ENDPOINT_BA = "TheatreServiceBA";
+    /**
+     * The QName for the BA Theatre endpoint.
+     */
+    private static final QName THEATRE_ENDPOINT_BA_QNAME
+            = new QName(THEATRE_NS, THEATRE_ENDPOINT_BA, THEATRE_PREFIX);
+
+    /***** TAXI SERVICE *****/
+
+    /**
+     * The namespace for the Taxi webservice.
+     */
+    private static final String TAXI_NS = "http://www.jboss.com/jbosstm/xts/demo/Taxi" ;
+    /**
+     * The prefix for the Taxi webservice.
+     */
+    private static final String TAXI_PREFIX = "taxi";
+    /**
+     * The local name for the AT Taxi webservice.
+     */
+    private static final String TAXI_SERVICE_AT = "TaxiServiceATService";
+    /**
+     * The QName for the AT Taxi webservice.
+     */
+    private static final QName TAXI_SERVICE_AT_QNAME
+            = new QName(TAXI_NS, TAXI_SERVICE_AT, TAXI_PREFIX);
+    /**
+     * The local name for the BA Taxi webservice.
+     */
+    private static final String TAXI_SERVICE_BA = "TaxiServiceBAService" ;
+    /**
+     * The QName for the AT Taxi webservice.
+     */
+    private static final QName TAXI_SERVICE_BA_QNAME
+            = new QName(TAXI_NS, TAXI_SERVICE_BA, TAXI_PREFIX);
+    /**
+     * The local name for the AT Taxi endpoint.
+     */
+    private static final String TAXI_ENDPOINT_AT = "TaxiServiceAT";
+    /**
+     * The QName for the AT Taxi endpoint.
+     */
+    private static final QName TAXI_ENDPOINT_AT_QNAME
+            = new QName(TAXI_NS, TAXI_ENDPOINT_AT, TAXI_PREFIX);
+    /**
+     * The local name for the BA Taxi endpoint.
+     */
+    private static final String TAXI_ENDPOINT_BA = "TaxiServiceBA";
+    /**
+     * The QName for the BA Taxi endpoint.
+     */
+    private static final QName TAXI_ENDPOINT_BA_QNAME
+            = new QName(TAXI_NS, TAXI_ENDPOINT_BA, TAXI_PREFIX);
+
+    /***** Client Handles for Service Endpoint Ports *****/
+
+    /**
+     * The atomic transaction restaurant stub.
+     */
+    private IRestaurantServiceAT restaurantAT;
+    /**
+     * The atomic transaction theatre stub.
+     */
+    private ITheatreServiceAT theatreAT;
+    /**
+     * The atomic transaction taxi stub.
+     */
+    private ITaxiServiceAT taxiAT;
+    /**
+     * The business activity restaurant stub.
+     */
+    private IRestaurantServiceBA restaurantBA;
+    /**
+     * The business activity theatre stub.
+     */
+    private ITheatreServiceBA theatreBA;
+    /**
+     * The business activity taxi stub.
+     */
+    private ITaxiServiceBA taxiBA;
+
+    /***** Endpoint Addresses *****/
+
+    /**
+     * URL of restaurant AT
+     */
+    private String restaurantATURL ;
+    /**
+     * URL of restaurant BA
+     */
+    private String restaurantBAURL ;
+    /**
+     * URL of taxi AT
+     */
+    private String taxiATURL ;
+    /**
+     * URL of taxi BA
+     */
+    private String taxiBAURL ;
+    /**
+     * URL of theatre AT
+     */
+    private String theatreATURL ;
+    /**
+     * URL of theatre BA
+     */
+    private String theatreBAURL ;
+
+    /***** WSDL file locations *****/
+
+    /**
+     * URL of restaurant AT
+     */
+    private final String restaurantATWSDL = "wsdl/RestaurantServiceAT.wsdl";
+    /**
+     * URL of restaurant BA
+     */
+    private final String restaurantBAWSDL = "wsdl/RestaurantServiceBA.wsdl";
+    /**
+     * URL of taxi AT                             */
+    private final String taxiATWSDL = "wsdl/TaxiServiceAT.wsdl";
+    /**
+     * URL of taxi BA
+     */
+    private final String taxiBAWSDL = "wsdl/TaxiServiceBA.wsdl";
+    /**
+     * URL of theatre AT
+     */
+    private final String theatreATWSDL = "wsdl/TheatreServiceAT.wsdl";
+    /**
+     * URL of theatre BA
+     */
+    private final String theatreBAWSDL = "wsdl/TheatreServiceBA.wsdl";
+
+    /**
+     * The initialised flag.
+     */
+    private boolean initialised ;
+    
+    /**
+     * Initialise the servlet.
+     * @param config The servlet configuration.
+     */
+    public void init(final ServletConfig config)
+        throws ServletException
+    {
+        final String baseURL = "http://localhost:8080/xtsdemowebservices/" ;
+
+        restaurantATURL = getURL(config, "restaurantATURL", baseURL + RESTAURANT_SERVICE_AT);
+        restaurantBAURL = getURL(config, "restaurantBAURL", baseURL + RESTAURANT_SERVICE_BA);
+        taxiATURL = getURL(config, "taxiATURL", baseURL + TAXI_SERVICE_AT);
+        taxiBAURL = getURL(config, "taxiBAURL", baseURL + TAXI_SERVICE_BA);
+        theatreATURL = getURL(config, "theatreATURL", baseURL + THEATRE_SERVICE_AT);
+        theatreBAURL = getURL(config, "theatreBAURL", baseURL + THEATRE_SERVICE_BA);
+
+        context = config.getServletContext();
+    }
+
+    /**
+     * configure the XTS client handler which manages transaction flow for invocations of the services
+     *
+     * @param bindingProvider
+     */
+    private void configureClientHandler(BindingProvider bindingProvider)
+    {
+        Handler handler = new JaxWSHeaderContextProcessor();
+        List<Handler> handlers = Collections.singletonList(handler);
+        bindingProvider.getBinding().setHandlerChain(handlers);
+    }
+
+    /**
+     * Initialise if necessary
+     */
+    private synchronized void initialise()
+    throws ServletException
+    {
+        if (!initialised)
+        {
+            try
+            {
+                restaurantAT = getService(RESTAURANT_SERVICE_AT_QNAME, RESTAURANT_ENDPOINT_AT_QNAME,
+                        restaurantATURL, restaurantATWSDL, IRestaurantServiceAT.class);
+                configureClientHandler((BindingProvider)restaurantAT);
+
+                restaurantBA = getService(RESTAURANT_SERVICE_BA_QNAME, RESTAURANT_ENDPOINT_BA_QNAME,
+                        restaurantBAURL, restaurantBAWSDL, IRestaurantServiceBA.class);
+                configureClientHandler((BindingProvider)restaurantBA);
+
+                theatreAT = getService(THEATRE_SERVICE_AT_QNAME, THEATRE_ENDPOINT_AT_QNAME,
+                        theatreATURL, theatreATWSDL, ITheatreServiceAT.class);
+                configureClientHandler((BindingProvider)theatreAT);
+
+                theatreBA = getService(THEATRE_SERVICE_BA_QNAME, THEATRE_ENDPOINT_BA_QNAME,
+                        theatreBAURL, theatreBAWSDL, ITheatreServiceBA.class);
+                configureClientHandler((BindingProvider)theatreBA);
+
+                taxiAT = getService(TAXI_SERVICE_AT_QNAME, TAXI_ENDPOINT_AT_QNAME,
+                        taxiATURL, taxiATWSDL, ITaxiServiceAT.class);
+                configureClientHandler((BindingProvider)taxiAT);
+
+                taxiBA = getService(TAXI_SERVICE_BA_QNAME, TAXI_ENDPOINT_BA_QNAME,
+                        taxiBAURL, taxiBAWSDL, ITaxiServiceBA.class);
+                configureClientHandler((BindingProvider)taxiBA);
+            }
+            catch (final Exception ex)
+            {
+                ex.printStackTrace();
+                throw new ServletException(ex);
+            }
+            initialised = true ;
+        }
+    }
+
+    /**
+     * Simple wrapper to allow our test method to be invoked when
+     * running in a servlet container, taking parameters from the
+     * request URL and displaying the outcome on the resulting html page.
+     *
+     * @param request
+     * @param response
+     * @throws ServletException
+     * @throws IOException
+     */
+    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+    {
+        initialise() ;
+
+        // get business logic params from the form submission.
+        int restaurantSeats = Integer.parseInt(request.getParameter("restaurant"));
+        int theatreSeats = Integer.parseInt(request.getParameter("theatrecount"));
+        int theatreArea = Integer.parseInt(request.getParameter("theatrearea"));
+        int taxiCount = Integer.parseInt(request.getParameter("taxi"));
+        boolean bookTaxi = (taxiCount >= 1 ? true : false);
+
+        String result = "Transaction finished OK.";
+        String txType = request.getParameter("txType");
+
+        try
+        {
+            if ("AtomicTransaction".equals(txType))
+            {
+                testAtomicTransaction(restaurantSeats, theatreSeats, theatreArea, bookTaxi);
+            }
+            else if ("BusinessActivity".equals(txType))
+            {
+                testBusinessActivity(restaurantSeats, theatreSeats, theatreArea, bookTaxi);
+            }
+            else
+            {
+                result = "Unknown transaction type " + txType;
+            }
+        }
+        catch (final TransactionRolledBackException tre)
+        {
+            result = "Transaction rolled back" ;
+            System.out.println("Transaction rolled back") ;
+        }
+        catch (Exception e)
+        {
+            result = "Transaction failed! Cause: " + e.toString();
+            System.out.println("CLIENT: problem: ");
+            e.printStackTrace(System.out);
+        }
+
+        request.setAttribute("result", result);
+        context.getRequestDispatcher("/index.jsp").forward(request, response);
+    }
+
+    /**
+     * Run a simple transaction involving three Web Services.
+     * Use the Atomic Transaction type.
+     * <p/>
+     * Note: due to the implementation of the transaction infrastructure,
+     * this method must be invoked with a web application container. It will
+     * not run correctly in a standalone java application.
+     *
+     * @throws Exception for any unexpected errors, such as a failure to commit.
+     */
+    private void testAtomicTransaction(int restaurantSeats, int theatreSeats, int theatreArea, boolean bookTaxi) throws Exception
+    {
+        System.out.println("CLIENT: obtaining userTransaction...");
+
+        UserTransaction ut = UserTransactionFactory.userTransaction();
+
+        System.out.println("CLIENT: starting the transaction...");
+
+        ut.begin();
+
+        System.out.println("CLIENT: transaction ID= " + ut.toString());
+
+        System.out.println("CLIENT: calling business Web Services...");
+
+        restaurantAT.bookSeats(restaurantSeats);
+        theatreAT.bookSeats(theatreSeats, theatreArea);
+        if (bookTaxi)
+        {
+            taxiAT.bookTaxi();
+        }
+
+        System.out.println("CLIENT: calling commit on the transaction...");
+
+        ut.commit();
+
+        System.out.println("done.");
+        System.out.flush();
+    }
+
+    /**
+     * Run a simple transaction involving three Web Services.
+     * Use the Business Activity type.
+     * <p/>
+     * Note: due to the implementation of the transaction infrastructure,
+     * this method must be invoked with a web application container. It will
+     * not run correctly in a standalone java application.
+     *
+     * @throws Exception for any unexpected errors, such as a failure to commit.
+     */
+    private void testBusinessActivity(int restaurantSeats, int theatreSeats, int theatreArea, boolean bookTaxi) throws Exception
+    {
+        System.out.println("CLIENT: obtaining userBusinessActivity...");
+
+        UserBusinessActivity uba = UserBusinessActivityFactory.userBusinessActivity();
+
+        System.out.println("CLIENT: starting the transaction...");
+
+        uba.begin();
+
+        System.out.println("CLIENT: transaction ID= " + uba.toString());
+
+        System.out.println("CLIENT: calling business Web Services...");
+
+        boolean isOK = false ;
+        try
+        {
+            if (restaurantBA.bookSeats(restaurantSeats) && theatreBA.bookSeats(theatreSeats, theatreArea))
+            {
+                isOK = !bookTaxi || taxiBA.bookTaxi() ;
+            }
+        }
+        catch (final Throwable th)
+        {
+            System.out.println("CLIENT: caught exception processing bookings, cancelling (" + th.getMessage() + ")") ;
+        }
+
+        if (isOK)
+        {
+            System.out.println("CLIENT: all OK");
+            System.out.println("CLIENT: calling close on the transaction...");
+            uba.close();
+        }
+        else
+        {
+            System.out.println("CLIENT: one or more services failed, calling cancel.");
+            uba.cancel();
+        }
+
+        System.out.println("CLIENT: done.");
+        System.out.flush();
+    }
+
+    /**
+     * @param config The servlet config
+     * @param property The property name
+     * @param defaultValue The default value.
+     * @return The initialisation property value or the default value if not present. 
+     */
+    private String getURL(final ServletConfig config, final String property, final String defaultValue)
+    {
+        final String value = config.getInitParameter(property) ;
+        return (value == null ? defaultValue : value) ;
+    }
+    
+    /**
+     * Get an endpoint reference for a service so we can create a JaxWS port for it
+     * @param serviceName the QName of the service in question..
+     * @param endpointName the QName of the endpoint associated with the service
+     * @param address a string representation of the service URL. null is ok if this is a service located in the
+     * same app as the client
+     * @return a W3CEndpointReference from which the service port can be obtained.
+     */
+    private <T> T getService(final QName serviceName, final QName endpointName,
+                                            final String address, final String wsdlURL, final Class<T> clazz)
+            throws MalformedURLException
+    {
+        URL url = BasicClient.class.getResource("../../../../../../../" + wsdlURL);
+        Service service = Service.create(url, serviceName);
+        T port = service.getPort(endpointName, clazz);
+        BindingProvider bindingProvider = ((BindingProvider) port);
+        bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
+        return port;
+    }
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/IRestaurantServiceAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/IRestaurantServiceAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/IRestaurantServiceAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,30 @@
+
+package com.jboss.jbosstm.xts.demo.restaurant;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebService(name = "IRestaurantServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Restaurant")
+ at SOAPBinding(style = SOAPBinding.Style.RPC)
+public interface IRestaurantServiceAT {
+
+
+    /**
+     * 
+     * @param howMany
+     */
+    @WebMethod
+    public void bookSeats(
+        @WebParam(name = "how_many", partName = "how_many")
+        int howMany);
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/IRestaurantServiceBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/IRestaurantServiceBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/IRestaurantServiceBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,34 @@
+
+package com.jboss.jbosstm.xts.demo.restaurant;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebService(name = "IRestaurantServiceBA", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Restaurant")
+ at SOAPBinding(style = SOAPBinding.Style.RPC)
+public interface IRestaurantServiceBA {
+
+
+    /**
+     * 
+     * @param howMany
+     * @return
+     *     returns boolean
+     */
+    @WebMethod
+    @WebResult(name = "bookSeatsBAResponse", partName = "bookSeatsBAResponse")
+    public boolean bookSeats(
+        @WebParam(name = "how_many", partName = "how_many")
+        int howMany);
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/RestaurantServiceATService.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/RestaurantServiceATService.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/RestaurantServiceATService.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,58 @@
+
+package com.jboss.jbosstm.xts.demo.restaurant;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.logging.Logger;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebEndpoint;
+import javax.xml.ws.WebServiceClient;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebServiceClient(name = "RestaurantServiceATService", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Restaurant", wsdlLocation = "/WEB-INF/wsdl/RestaurantServiceAT.wsdl")
+public class RestaurantServiceATService
+    extends Service
+{
+
+    private final static URL RESTAURANTSERVICEATSERVICE_WSDL_LOCATION;
+    private final static Logger logger = Logger.getLogger(com.jboss.jbosstm.xts.demo.restaurant.RestaurantServiceATService.class.getName());
+
+    static {
+        URL url = null;
+        try {
+            URL baseUrl;
+            baseUrl = com.jboss.jbosstm.xts.demo.restaurant.RestaurantServiceATService.class.getResource(".");
+            url = new URL(baseUrl, "/WEB-INF/wsdl/RestaurantServiceAT.wsdl");
+        } catch (MalformedURLException e) {
+            logger.warning("Failed to create URL for the wsdl Location: '/WEB-INF/wsdl/RestaurantServiceAT.wsdl', retrying as a local file");
+            logger.warning(e.getMessage());
+        }
+        RESTAURANTSERVICEATSERVICE_WSDL_LOCATION = url;
+    }
+
+    public RestaurantServiceATService(URL wsdlLocation, QName serviceName) {
+        super(wsdlLocation, serviceName);
+    }
+
+    public RestaurantServiceATService() {
+        super(RESTAURANTSERVICEATSERVICE_WSDL_LOCATION, new QName("http://www.jboss.com/jbosstm/xts/demo/Restaurant", "RestaurantServiceATService"));
+    }
+
+    /**
+     * 
+     * @return
+     *     returns IRestaurantServiceAT
+     */
+    @WebEndpoint(name = "RestaurantServiceAT")
+    public IRestaurantServiceAT getRestaurantServiceAT() {
+        return super.getPort(new QName("http://www.jboss.com/jbosstm/xts/demo/Restaurant", "RestaurantServiceAT"), IRestaurantServiceAT.class);
+    }
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/RestaurantServiceBAService.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/RestaurantServiceBAService.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/restaurant/RestaurantServiceBAService.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,58 @@
+
+package com.jboss.jbosstm.xts.demo.restaurant;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.logging.Logger;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebEndpoint;
+import javax.xml.ws.WebServiceClient;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebServiceClient(name = "RestaurantServiceBAService", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Restaurant", wsdlLocation = "/WEB-INF/wsdl/RestaurantServiceBA.wsdl")
+public class RestaurantServiceBAService
+    extends Service
+{
+
+    private final static URL RESTAURANTSERVICEBASERVICE_WSDL_LOCATION;
+    private final static Logger logger = Logger.getLogger(com.jboss.jbosstm.xts.demo.restaurant.RestaurantServiceBAService.class.getName());
+
+    static {
+        URL url = null;
+        try {
+            URL baseUrl;
+            baseUrl = com.jboss.jbosstm.xts.demo.restaurant.RestaurantServiceBAService.class.getResource(".");
+            url = new URL(baseUrl, "/WEB-INF/wsdl/RestaurantServiceBA.wsdl");
+        } catch (MalformedURLException e) {
+            logger.warning("Failed to create URL for the wsdl Location: '/WEB-INF/wsdl/RestaurantServiceBA.wsdl', retrying as a local file");
+            logger.warning(e.getMessage());
+        }
+        RESTAURANTSERVICEBASERVICE_WSDL_LOCATION = url;
+    }
+
+    public RestaurantServiceBAService(URL wsdlLocation, QName serviceName) {
+        super(wsdlLocation, serviceName);
+    }
+
+    public RestaurantServiceBAService() {
+        super(RESTAURANTSERVICEBASERVICE_WSDL_LOCATION, new QName("http://www.jboss.com/jbosstm/xts/demo/Restaurant", "RestaurantServiceBAService"));
+    }
+
+    /**
+     * 
+     * @return
+     *     returns IRestaurantServiceBA
+     */
+    @WebEndpoint(name = "RestaurantServiceBA")
+    public IRestaurantServiceBA getRestaurantServiceBA() {
+        return super.getPort(new QName("http://www.jboss.com/jbosstm/xts/demo/Restaurant", "RestaurantServiceBA"), IRestaurantServiceBA.class);
+    }
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantManager.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantManager.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantManager.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,456 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * RestaurantManager.java
+ *
+ * Copyright (c) 2003 Arjuna Technologies Ltd.
+ *
+ * $Id: RestaurantManager.java,v 1.3 2004/04/21 13:09:18 jhalliday Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.restaurant;
+
+import java.util.Hashtable;
+
+/**
+ * The transactional application logic for the Restaurant Service.
+ * <p/>
+ * Stores and manages seating reservations. Knows nothing about Web Services.
+ * Understands transactional booking lifecycle: unprepared, prepared, finished.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+public class RestaurantManager
+{
+    /**
+     * Create and initialise a new RestaurantManager instance.
+     */
+    public RestaurantManager()
+    {
+        setToDefault();
+    }
+
+    /**
+     * Book a number of seats in the restaurant.
+     *
+     * @param txID   The transaction identifier
+     * @param nSeats The number of seats requested
+     */
+    public void bookSeats(Object txID, int nSeats)
+    {
+        // locate any pre-existing request for the same transaction
+        Integer request = (Integer) unpreparedTransactions.get(txID);
+        if (request == null)
+        {
+            // this is the first request for this transaction
+            // setup the data structure to record it
+            request = new Integer(0);
+        }
+
+        // record the request, keyed to its transaction scope
+        request = new Integer(request.intValue() + nSeats);
+        unpreparedTransactions.put(txID, request);
+
+        // record the increased commitment to provide seating
+        nBookedSeats += nSeats;
+    }
+
+    /**
+     * Attempt to ensure availability of the requested seating.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean prepareSeats(Object txID)
+    {
+        // ensure that we have seen this transaction before
+        Integer request = (Integer) unpreparedTransactions.get(txID);
+        if (request == null)
+        {
+            return false; // error: transaction not registered
+        }
+        else
+        {
+            if (autoCommitMode)
+            {
+                if (request.intValue() <= nFreeSeats)
+                {
+                    // record the prepared transaction
+                    preparedTransactions.put(txID, request);
+                    unpreparedTransactions.remove(txID);
+                    // mark the prepared seats as unavailable
+                    nFreeSeats -= request.intValue();
+                    nPreparedSeats += request.intValue();
+                    return true;
+                }
+                else
+                {
+                    // we don't have enough seats available
+                    return false;
+                }
+            }
+            else
+            {
+                try
+                {
+                    // wait for a user commit/rollback decision
+                    isPreparationWaiting = true;
+                    synchronized (preparation)
+                    {
+                        preparation.wait();
+                    }
+                    isPreparationWaiting = false;
+
+                    // process the user decision
+                    if (isCommit)
+                    {
+                        // record the prepared transaction
+                        preparedTransactions.put(txID, request);
+                        unpreparedTransactions.remove(txID);
+                        // mark the prepared seats as unavailable
+                        nFreeSeats -= request.intValue();
+                        nPreparedSeats += request.intValue();
+                        return true;
+                    }
+                    else
+                    {
+                        return false;
+                    }
+                }
+                catch (Exception e)
+                {
+                    System.err.println("RestaurantManager.prepareSeats(): Unable to stop preparation.");
+                    return false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Release booked or prepared seats.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean cancelSeats(Object txID)
+    {
+        boolean success = false;
+
+        // the transaction may be prepared, unprepared or unknown
+
+        if (preparedTransactions.containsKey(txID))
+        {
+            // undo the prepare operations
+            Integer request = (Integer) preparedTransactions.remove(txID);
+            nFreeSeats += request.intValue();
+            nPreparedSeats -= request.intValue();
+            nBookedSeats -= request.intValue();
+            success = true;
+        }
+        else if (unpreparedTransactions.containsKey(txID))
+        {
+            // undo the booking operations
+            Integer request = (Integer) unpreparedTransactions.remove(txID);
+            nBookedSeats -= request.intValue();
+            success = true;
+        }
+        else
+        {
+            success = false; // error: transaction not registered
+        }
+
+        return success;
+    }
+
+    /**
+     * Commit seat bookings.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean commitSeats(Object txID)
+    {
+        boolean success = false;
+
+        // the transaction may be prepared, unprepared or unknown
+
+        if (preparedTransactions.containsKey(txID))
+        {
+            // complete the prepared transaction
+            Integer request = (Integer) preparedTransactions.remove(txID);
+            nCommittedSeats += request.intValue();
+            nPreparedSeats -= request.intValue();
+            nBookedSeats -= request.intValue();
+            success = true;
+        }
+        else if (unpreparedTransactions.containsKey(txID))
+        {
+            // use one phase commit optimisation, skipping prepare
+            Integer request = (Integer) unpreparedTransactions.remove(txID);
+            nCommittedSeats += request.intValue();
+            nFreeSeats -= request.intValue();
+            nBookedSeats -= request.intValue();
+            success = true;
+        }
+        else
+        {
+            success = false; // error: transaction not registered
+        }
+
+        return success;
+    }
+
+    /**
+     * Determine if a specific transaction is known to the business logic.
+     *
+     * @param txID The uniq id for the transaction
+     * @return true if the business logic is holding state related to the given txID,
+     *         false otherwise.
+     */
+    public boolean knowsAbout(Object txID)
+    {
+        return (unpreparedTransactions.containsKey(txID) || preparedTransactions.containsKey(txID));
+    }
+
+    /**
+     * Change the capacity of the Resaurant.
+     *
+     * @param nSeats The new capacity
+     */
+    public void newCapacity(int nSeats)
+    {
+        nFreeSeats += nSeats - nTotalSeats;
+        nTotalSeats = nSeats;
+    }
+
+    /**
+     * Get the number of free seats.
+     *
+     * @return The number of free seats
+     */
+    public int getNFreeSeats()
+    {
+        return nFreeSeats;
+    }
+
+    /**
+     * Get the total number of seats.
+     *
+     * @return The total number of seats
+     */
+    public int getNTotalSeats()
+    {
+        return nTotalSeats;
+    }
+
+    /**
+     * Get the number of booked seats in the given area.
+     *
+     * @return The number of booked seats
+     */
+    public int getNBookedSeats()
+    {
+        return nBookedSeats;
+    }
+
+    /**
+     * Get the number of prepared seats.
+     *
+     * @return The number of prepared seats
+     */
+    public int getNPreparedSeats()
+    {
+        return nPreparedSeats;
+    }
+
+    /**
+     * Get the number of committed seats in the given area.
+     *
+     * @return The number of committed seats
+     */
+    public int getNCommittedSeats()
+    {
+        return nCommittedSeats;
+    }
+
+    /**
+     * Determine the autoCommit status of the instance.
+     *
+     * @return true if autoCommit mode is active, false otherwise
+     */
+    public boolean isAutoCommitMode()
+    {
+        return autoCommitMode;
+    }
+
+    /**
+     * Set the autoCommit mode of the instance.
+     *
+     * @param autoCommit true for automatic commit, false for manual commit.
+     */
+    public void setAutoCommitMode(boolean autoCommit)
+    {
+        autoCommitMode = autoCommit;
+    }
+
+    /**
+     * Get the preparation object for manual commit wait/notify.
+     *
+     * @return The preparation object
+     */
+    public Object getPreparation()
+    {
+        return preparation;
+    }
+
+    /**
+     * Determine if the instance is waiting for manual commit/rollback.
+     *
+     * @return true if waiting, false otherwise
+     */
+    public boolean getIsPreparationWaiting()
+    {
+        return isPreparationWaiting;
+    }
+
+    /**
+     * Set the waiting status of the instance.
+     *
+     * @param isWaiting The new value to set
+     */
+    public void setIsPreparationWaiting(boolean isWaiting)
+    {
+        isPreparationWaiting = isWaiting;
+    }
+
+    /**
+     * Set the manual commit status.
+     *
+     * @param commit true for commitment, false for rollback
+     */
+    public void setCommit(boolean commit)
+    {
+        isCommit = commit;
+    }
+
+    /**
+     * (re-)initialise the instance data structures.
+     */
+    public void setToDefault()
+    {
+        nTotalSeats = DEFAULT_SEATING_CAPACITY;
+        nFreeSeats = nTotalSeats;
+        nBookedSeats = 0;
+        nPreparedSeats = 0;
+        nCommittedSeats = 0;
+        preparedTransactions = new Hashtable();
+        unpreparedTransactions = new Hashtable();
+        autoCommitMode = true;
+        preparation = new Object();
+        isPreparationWaiting = false;
+        isCommit = true;
+    }
+
+    /**
+     * Allow use of a singleton model for web services demo.
+     *
+     * @return the singleton RestaurantManager instance.
+     */
+    public static RestaurantManager getSingletonInstance()
+    {
+        if (singletonInstance == null)
+        {
+            singletonInstance = new RestaurantManager();
+        }
+
+        return singletonInstance;
+    }
+
+    /**
+     * A singleton instance of this class.
+     */
+    private static RestaurantManager singletonInstance;
+
+    /**
+     * The total seating capacity.
+     */
+    private int nTotalSeats;
+
+    /**
+     * The number of free seats.
+     */
+    private int nFreeSeats;
+
+    /**
+     * The number of booked seats.
+     * <p/>
+     * Note: This may exceed the total seating capacity
+     */
+    private int nBookedSeats;
+
+    /**
+     * The number of prepared (promised) seats.
+     */
+    private int nPreparedSeats;
+    /**
+     * The number of committed seats in each area.
+     */
+    private int nCommittedSeats;
+
+    /**
+     * The auto commit mode.
+     * <p/>
+     * true = automatically commit, false = manually commit
+     */
+    private boolean autoCommitMode;
+
+    /**
+     * The object used for wait/notify in manual commit mode.
+     */
+    private Object preparation;
+
+    /**
+     * The waiting status, when in manual commit mode.
+     */
+    private boolean isPreparationWaiting;
+
+    /**
+     * The user specified outcome when in manual commit mode.
+     */
+    private boolean isCommit;
+
+    /**
+     * The transactions we know about but which have not been prepared.
+     */
+    private Hashtable unpreparedTransactions;
+
+    /**
+     * The transactions we know about and are prepared to commit.
+     */
+    private Hashtable preparedTransactions;
+
+    /**
+     * The default initial capacity of each seating area.
+     */
+    public static final int DEFAULT_SEATING_CAPACITY = 100;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantParticipantAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantParticipantAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantParticipantAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,201 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * RestaurantParticipantAT.java
+ *
+ * Copyright (c) 2003, 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: RestaurantParticipantAT.java,v 1.3 2005/02/23 09:58:01 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.restaurant;
+
+import com.arjuna.wst.*;
+
+/**
+ * An adapter class that exposes the RestaurantManager transaction lifecycle
+ * API as a WS-T Atomic Transaction participant.
+ * Also logs events to a RestaurantView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+public class RestaurantParticipantAT implements Durable2PCParticipant
+{
+    /**
+     * Participant instances are related to transaction instances
+     * in a one to one manner.
+     *
+     * @param txID uniq id String for the transaction instance.
+     */
+    public RestaurantParticipantAT(String txID)
+    {
+        // Binds to the singleton RestaurantView and RestaurantManager
+        restaurantManager = RestaurantManager.getSingletonInstance();
+        restaurantView = RestaurantView.getSingletonInstance();
+        // we need to save the txID for later use when calling
+        // business logic methods in the restaurantManger.
+        this.txID = txID;
+    }
+
+    /**
+     * Invokes the prepare step of the business logic,
+     * reporting activity and outcome.
+     *
+     * @return Prepared where possible, Aborted where necessary.
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public Vote prepare() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the prepare operation
+        // on the backend business logic.
+
+        System.out.println("RestaurantParticipantAT.prepare");
+
+        restaurantView.addPrepareMessage("id:" + txID + ". Prepare called on participant: " + this.getClass().toString());
+
+        boolean success = restaurantManager.prepareSeats(txID);
+
+        // Log the outcome and map the return value from
+        // the business logic to the appropriate Vote type.
+
+        if (success)
+        {
+            restaurantView.addMessage("Seats prepared successfully. Returning 'Prepared'\n");
+            restaurantView.updateFields();
+            return new Prepared();
+        }
+        else
+        {
+            restaurantManager.cancelSeats(txID) ;
+            restaurantView.addMessage("Prepare failed (not enough seats?) Returning 'Aborted'\n");
+            restaurantView.updateFields();
+            return new Aborted();
+        }
+    }
+
+    /**
+     * Invokes the commit step of the business logic,
+     * reporting activity and outcome.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void commit() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the commit operation
+        // on the backend business logic.
+
+        System.out.println("RestaurantParticipantAT.commit");
+
+        restaurantView.addMessage("id:" + txID + ". Commit called on participant: " + this.getClass().toString());
+
+        boolean success = restaurantManager.commitSeats(txID);
+
+        // Log the outcome
+
+        if (success)
+        {
+            restaurantView.addMessage("Seats committed\n");
+        }
+        else
+        {
+            restaurantView.addMessage("Something went wrong (Transaction not registered?)\n");
+        }
+
+        restaurantView.updateFields();
+    }
+
+    /**
+     * Invokes the rollback operation on the business logic,
+     * reporting activity and outcome.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void rollback() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the rollback operation
+        // on the backend business logic.
+
+        System.out.println("RestaurantParticipantAT.rollback");
+
+        restaurantView.addMessage("id:" + txID + ". Rollback called on participant: " + this.getClass().toString());
+
+        boolean success = restaurantManager.cancelSeats(txID);
+
+        // Log the outcome
+
+        if (success)
+        {
+            restaurantView.addMessage("Seats booking cancelled\n");
+        }
+        else
+        {
+            restaurantView.addMessage("Something went wrong (Transaction not registered?)\n");
+        }
+
+        restaurantView.updateFields();
+    }
+
+    /**
+     * Shortcut method which combines the prepare
+     * and commit steps in a single operation.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void commitOnePhase() throws WrongStateException, SystemException
+    {
+        prepare();
+        commit();
+    }
+
+    public void unknown() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    public void error() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    /**
+     * Id for the transaction which this participant instance relates to.
+     * Set by the service (via contrtuctor) at enrolment time, this value
+     * is passed to the backend business logic methods.
+     */
+    protected String txID;
+
+    /**
+     * The RestaurantView object to log events through.
+     */
+    protected static RestaurantView restaurantView;
+
+    /**
+     * The RestaurantManager to perform business logic operations on.
+     */
+    protected static RestaurantManager restaurantManager;
+}
+

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantParticipantBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantParticipantBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantParticipantBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,189 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * RestaurantParticipantBA.java
+ *
+ * Copyright (c) 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: RestaurantParticipantBA.java,v 1.3 2004/09/09 15:18:09 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.restaurant;
+
+import com.arjuna.wst.*;
+import com.arjuna.ats.arjuna.common.Uid;
+
+/**
+ * An adapter class that exposes the RestaurantManager transaction lifecycle
+ * API as a WS-T Business Activity participant.
+ * Also logs events to a RestaurantView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+public class RestaurantParticipantBA implements BusinessAgreementWithParticipantCompletionParticipant
+{
+    /**
+     * Participant instances are related to business method calls
+     * in a one to one manner.
+     *
+     * @param txID     uniq id String for the transaction instance.
+     * @param how_many seats to book/compensate.
+     */
+    public RestaurantParticipantBA(String txID, int how_many)
+    {
+        // Binds to the singleton RestaurantView and RestaurantManager
+        restaurantManager = RestaurantManager.getSingletonInstance();
+        restaurantView = RestaurantView.getSingletonInstance();
+        // we need to save the txID for later use when logging.
+        this.txID = txID;
+        // we also need the business paramater(s) in case of compensation
+        this.seatCount = how_many;
+    }
+
+    /**
+     * The transaction has completed successfully. The participant previously
+     * informed the coordinator that it was ready to complete.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException never in this implementation.
+     */
+
+    public void close() throws WrongStateException, SystemException
+    {
+        // for logging only. This impl does not do anything else here.
+
+        System.out.println("RestaurantParticipantBA.close");
+
+        restaurantView.addMessage("id:" + txID + ". Close called on participant: " + this.getClass());
+        restaurantView.updateFields();
+    }
+
+
+    /**
+     * The transaction has cancelled, and the participant should undo any work.
+     * The participant cannot have informed the coordinator that it has
+     * completed.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException never in this implementation.
+     */
+
+    public void cancel() throws WrongStateException, SystemException
+    {
+        // we will always have called completed or error, so this can be a null op.
+
+        System.out.println("RestaurantParticipantBA.cancel");
+
+        restaurantView.addMessage("id:" + txID + ". Cancel called on participant: " + this.getClass().toString());
+        restaurantView.updateFields();
+    }
+
+    /**
+     * The transaction has cancelled. The participant previously
+     * informed the coordinator that it had finished work but could compensate
+     * later if required, so it is now requested to do so.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException if unable to perform the compensating transaction.
+     */
+
+    public void compensate() throws WrongStateException, SystemException
+    {
+        System.out.println("RestaurantParticipantBA.compensate");
+
+        // Log the event and perform a compensating transaction
+        // on the backend business logic.
+
+        restaurantView.addPrepareMessage("id:" + txID + ". Compensate called on participant: " + this.getClass().toString());
+        restaurantView.updateFields();
+
+        if (seatCount > 0)
+        {
+            String compensatingTxID = new Uid().toString();
+            // use a negative number of seats to 'reverse' the previous booking
+            // This technique (hack) prevents us needing new business logic to support compensation.
+            restaurantManager.bookSeats(compensatingTxID, seatCount * -1);
+            restaurantView.updateFields();
+
+            boolean success = false;
+            if(restaurantManager.prepareSeats(compensatingTxID))
+            {
+                if (restaurantManager.commitSeats(compensatingTxID))
+                {
+                    restaurantView.addMessage("id:" + txID + " Compensating transaction completed sucessfully.");
+                    restaurantView.updateFields();
+                    success = true;
+                }
+            }
+            else
+            {
+                restaurantManager.cancelSeats(compensatingTxID);
+            }
+
+            if(!success)
+            {
+                restaurantView.addMessage("id:" + txID + " Compensation failed. Throwing SystemException\n");
+                restaurantView.updateFields();
+                throw new SystemException("Compensating transaction failed.");
+            }
+        }
+    }
+
+    public String status()
+    {
+        return Status.STATUS_ACTIVE ;
+    }
+    
+    public void unknown() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    public void error() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    /**
+     * Id for the transaction which this participant instance relates to.
+     * Set by the service (via contrtuctor) at enrolment time, this value
+     * is used in informational log messages.
+     */
+    protected String txID;
+
+    /**
+     * Copy of business state information, may be needed during compensation.
+     */
+    protected int seatCount;
+
+    /**
+     * The RestaurantView object to log events through.
+     */
+    protected static RestaurantView restaurantView;
+
+    /**
+     * The RestaurantManager to perform business logic operations on.
+     */
+    protected static RestaurantManager restaurantManager;
+}
+

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantServiceAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantServiceAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantServiceAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * RestaurantServiceAT.java
+ *
+ * Copyright (c) 2003, 2004 Arjuna Technologies Ltd
+ *
+ * $Id: RestaurantServiceAT.java,v 1.3 2004/12/01 16:26:44 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.restaurant;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst.TransactionManagerFactory;
+import com.arjuna.mw.wst.UserTransactionFactory;
+import com.jboss.jbosstm.xts.demo.restaurant.IRestaurantServiceAT;
+
+import javax.jws.HandlerChain;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.jws.WebMethod;
+import javax.jws.soap.SOAPBinding;
+
+/**
+ * An adapter class that exposes the RestaurantManager business API as a
+ * transactional Web Service. Also logs events to a RestaurantView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+ at WebService(serviceName="RestaurantServiceATService", portName="RestaurantServiceAT",
+        name = "IRestaurantServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Restaurant",
+        wsdlLocation = "/WEB-INF/wsdl/RestaurantServiceAT.wsdl")
+ at HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")                  
+ at SOAPBinding(style=SOAPBinding.Style.RPC)
+public class RestaurantServiceAT implements IRestaurantServiceAT
+{
+    /**
+     * Book a number of seats in the restaurant
+     * Enrols a Participant if necessary, then passes
+     * the call through to the business logic.
+     *
+     * @param how_many The number of seats to book
+     */
+    @WebMethod
+    public void bookSeats(
+            @WebParam(name = "how_many", partName = "how_many")
+            int how_many)
+    {
+        RestaurantView restaurantView = RestaurantView.getSingletonInstance();
+        RestaurantManager restaurantManager = RestaurantManager.getSingletonInstance();
+
+        String transactionId = null;
+        try
+        {
+            // get the transaction context of this thread:
+            transactionId = UserTransactionFactory.userTransaction().toString();
+            System.out.println("RestaurantServiceAT transaction id =" + transactionId);
+
+            if (!restaurantManager.knowsAbout(transactionId))
+            {
+                System.out.println("RestaurantServiceAT - enrolling...");
+                // enlist the Participant for this service:
+                RestaurantParticipantAT restaurantParticipant = new RestaurantParticipantAT(transactionId);
+                TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(restaurantParticipant, new Uid().toString());
+            }
+        }
+        catch (Exception e)
+        {
+            System.err.println("bookSeats: Participant enrolment failed");
+            e.printStackTrace(System.err);
+            return;
+        }
+
+        restaurantView.addMessage("******************************");
+
+        restaurantView.addMessage("id:" + transactionId + ". Received a booking request for one table of " + how_many + " people");
+
+        restaurantManager.bookSeats(transactionId, how_many);
+
+        restaurantView.addMessage("Request complete\n");
+        restaurantView.updateFields();
+    }
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantServiceBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantServiceBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantServiceBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,151 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * RestaurantServiceBA.java
+ *
+ * Copyright (c) 2004 Arjuna Technologies Ltd
+ *
+ * $Id: RestaurantServiceBA.java,v 1.5 2004/12/01 16:26:44 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.restaurant;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst.BusinessActivityManagerFactory;
+import com.arjuna.mw.wst.BusinessActivityManager;
+import com.arjuna.wst.BAParticipantManager;
+import com.arjuna.wst.SystemException;
+import com.jboss.jbosstm.xts.demo.restaurant.IRestaurantServiceBA;
+
+import javax.jws.*;
+import javax.jws.soap.SOAPBinding;
+
+/**
+ * An adapter class that exposes the RestaurantManager business API as a
+ * transactional Web Service. Also logs events to a RestaurantView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.5 $
+ */
+ at WebService(serviceName="RestaurantServiceBAService", portName="RestaurantServiceBA",
+        name = "IRestaurantServiceBA", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Restaurant",
+        wsdlLocation = "/WEB-INF/wsdl/RestaurantServiceBA.wsdl")
+ at HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")
+ at SOAPBinding(style=SOAPBinding.Style.RPC)
+public class RestaurantServiceBA implements IRestaurantServiceBA
+{
+    /**
+     * Book a number of seats in the restaurant
+     * Enrols a Participant if necessary and passes
+     * the call through to the business logic.
+     *
+     * @param how_many The number of seats to book.
+     * @return true on success, false otherwise.
+     */
+    @WebMethod
+    @WebResult(name = "bookSeatsBAResponse", partName = "bookSeatsBAResponse")
+    public boolean bookSeats(
+            @WebParam(name = "how_many", partName = "how_many")
+            int how_many)
+    {
+        RestaurantView restaurantView = RestaurantView.getSingletonInstance();
+        RestaurantManager restaurantManager = RestaurantManager.getSingletonInstance();
+
+        BusinessActivityManager activityManager = BusinessActivityManagerFactory.businessActivityManager();
+
+        // get the transaction context of this thread:
+        String transactionId = null;
+        try
+        {
+            transactionId = activityManager.currentTransaction().toString();
+        }
+        catch (SystemException e)
+        {
+            System.err.println("bookSeats: unable to obtain a transaction context!");
+            e.printStackTrace(System.err);
+            return false;
+        }
+
+        // log the event:
+        System.out.println("RestaurantServiceBA transaction id =" + transactionId);
+
+        restaurantView.addMessage("******************************");
+
+        restaurantView.addPrepareMessage("id:" + transactionId + ". Received a booking request for one table of " + how_many + " people");
+        restaurantView.updateFields();
+
+        // invoke the backend business logic:
+        restaurantManager.bookSeats(transactionId, how_many);
+
+        // attempt to finalise the booking
+        // (it will be compensated later if necessary)
+        if (restaurantManager.prepareSeats(transactionId))
+        {
+            restaurantView.addMessage("id:" + transactionId + ". Seats prepared, trying to commit and enlist compensation Participant");
+            restaurantView.updateFields();
+
+            // it worked, so now we need a participant enlisted in case of compensation:
+
+            RestaurantParticipantBA restaurantParticipant = new RestaurantParticipantBA(transactionId, how_many);
+            // enlist the Participant for this service:
+            BAParticipantManager participantManager = null;
+            try
+            {
+                participantManager = activityManager.enlistForBusinessAgreementWithParticipantCompletion(restaurantParticipant, new Uid().toString());
+            }
+            catch (Exception e)
+            {
+                restaurantView.addMessage("id:" + transactionId + ". Participant enrolement failed");
+                System.err.println("bookSeats: Participant enlistment failed");
+                e.printStackTrace(System.err);
+                return false;
+            }
+
+            // finish the booking in the backend:
+            restaurantManager.commitSeats(transactionId);
+
+            try
+            {
+                // tell the manager we have finished our work:
+                participantManager.completed();
+            }
+            catch (Exception e)
+            {
+                System.err.println("bookSeats: 'completed' callback failed");
+                e.printStackTrace(System.err);
+                return false;
+            }
+        }
+        else
+        {
+            restaurantView.addMessage("id:" + transactionId + ". Failed to reserve seats. Cancelling.");
+            restaurantManager.cancelSeats(transactionId);
+            restaurantView.updateFields();
+            return false;
+        }
+
+        restaurantView.addMessage("Request complete\n");
+        restaurantView.updateFields();
+
+        return true;
+    }
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantView.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantView.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/restaurant/RestaurantView.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,470 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * RestaurantView.java
+ *
+ * Copyright (c) 2003 Arjuna Technologies Ltd.
+ *
+ * $Id: RestaurantView.java,v 1.2 2004/04/21 13:09:18 jhalliday Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.restaurant;
+
+/**
+ * The visual interface (GUI) for the Restaurant Service.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.2 $
+ */
+public class RestaurantView extends javax.swing.JFrame
+{
+    // Note: Some parts of this file were auto-generated
+    // by NetBeans 3.3 FormEditor (http://www.netbeans.org)
+
+    /**
+     * Create a new RestaurantView instance.
+     *
+     * @param rManager The {@link RestaurantManager} instance to bind to
+     */
+    public RestaurantView(RestaurantManager rManager)
+    {
+        restManager = rManager;
+        initComponents();
+        updateFields();
+        backButtonColor = jButtonConfirm.getBackground();
+    }
+
+    /**
+     * Initialize the form.
+     * This is called by the constructor
+     * <p/>
+     * WARNING: Automatically generated code, may be overwritten
+     */
+    private void initComponents()
+    {//GEN-BEGIN:initComponents
+        jPanel2 = new javax.swing.JPanel();
+        jLabel5 = new javax.swing.JLabel();
+        jLabelNBookedSeats = new javax.swing.JLabel();
+        jLabel9 = new javax.swing.JLabel();
+        jLabelNPreparedSeats = new javax.swing.JLabel();
+        jLabel2 = new javax.swing.JLabel();
+        jLabelNConfirmedSeats = new javax.swing.JLabel();
+        jLabel6 = new javax.swing.JLabel();
+        jLabelNFreeSeats = new javax.swing.JLabel();
+        jLabel7 = new javax.swing.JLabel();
+        jButtonResetFields = new javax.swing.JButton();
+        jPanel1 = new javax.swing.JPanel();
+        jLabel8 = new javax.swing.JLabel();
+        jLabel1 = new javax.swing.JLabel();
+        jLabelNTotalSeats = new javax.swing.JLabel();
+        jLabel4 = new javax.swing.JLabel();
+        jLabel3 = new javax.swing.JLabel();
+        jTextFieldNewNTotalSeats = new javax.swing.JTextField();
+        jButtonSetNTotalSeats = new javax.swing.JButton();
+        jPanelLeft = new javax.swing.JPanel();
+        jLabel10 = new javax.swing.JLabel();
+        jLabelDisplayMode = new javax.swing.JLabel();
+        jButtonChangeMode = new javax.swing.JButton();
+        jLabelResponse = new javax.swing.JLabel();
+        jButtonConfirm = new javax.swing.JButton();
+        jButtonCancel = new javax.swing.JButton();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        jTextArea = new javax.swing.JTextArea();
+
+        setTitle("Restaurant Service");
+        setName("restaurantView");
+        addWindowListener(new java.awt.event.WindowAdapter()
+        {
+            public void windowClosing(java.awt.event.WindowEvent evt)
+            {
+                exitForm(evt);
+            }
+        });
+
+        jPanel2.setBorder(new javax.swing.border.LineBorder(java.awt.Color.black));
+        jLabel5.setText("Seats: ");
+        jLabel5.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel2.add(jLabel5);
+
+        jLabelNBookedSeats.setText(Integer.toString(restManager.getNBookedSeats()));
+        jLabelNBookedSeats.setForeground(java.awt.Color.gray);
+        jLabelNBookedSeats.setFont(new java.awt.Font("Dialog", 1, 18));
+        jPanel2.add(jLabelNBookedSeats);
+
+        jLabel9.setText("Booked,    ");
+        jPanel2.add(jLabel9);
+
+        jLabelNPreparedSeats.setText(Integer.toString(restManager.getNPreparedSeats()));
+        jLabelNPreparedSeats.setForeground(java.awt.Color.darkGray);
+        jLabelNPreparedSeats.setFont(new java.awt.Font("Dialog", 1, 18));
+        jPanel2.add(jLabelNPreparedSeats);
+
+        jLabel2.setText("Prepared,    ");
+        jPanel2.add(jLabel2);
+
+        jLabelNConfirmedSeats.setText(Integer.toString(restManager.getNCommittedSeats()));
+        jLabelNConfirmedSeats.setForeground(new java.awt.Color(0, 51, 204));
+        jLabelNConfirmedSeats.setFont(new java.awt.Font("Dialog", 1, 18));
+        jPanel2.add(jLabelNConfirmedSeats);
+
+        jLabel6.setText("Confirmed,    ");
+        jPanel2.add(jLabel6);
+
+        jLabelNFreeSeats.setText(Integer.toString(restManager.getNFreeSeats()));
+        jLabelNFreeSeats.setForeground(new java.awt.Color(0, 153, 0));
+        jLabelNFreeSeats.setFont(new java.awt.Font("Dialog", 1, 18));
+        jPanel2.add(jLabelNFreeSeats);
+
+        jLabel7.setText("Free            ");
+        jPanel2.add(jLabel7);
+
+        jButtonResetFields.setText("Reset Fields");
+        jButtonResetFields.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonResetFieldsActionPerformed(evt);
+            }
+        });
+
+        jPanel2.add(jButtonResetFields);
+
+        getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);
+
+        jPanel1.setBorder(new javax.swing.border.LineBorder(java.awt.Color.black));
+        jLabel8.setText("Restaurant              ");
+        jLabel8.setForeground(java.awt.Color.red);
+        jLabel8.setFont(new java.awt.Font("Dialog", 1, 24));
+        jPanel1.add(jLabel8);
+
+        jLabel1.setText("Capacity:");
+        jLabel1.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel1.add(jLabel1);
+
+        jLabelNTotalSeats.setText(Integer.toString(restManager.getNTotalSeats()));
+        jLabelNTotalSeats.setForeground(java.awt.Color.darkGray);
+        jLabelNTotalSeats.setFont(new java.awt.Font("Dialog", 1, 18));
+        jPanel1.add(jLabelNTotalSeats);
+
+        jLabel4.setText("seats");
+        jLabel4.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel1.add(jLabel4);
+
+        jLabel3.setText("                   New capacity:");
+        jLabel3.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel1.add(jLabel3);
+
+        jTextFieldNewNTotalSeats.setFont(new java.awt.Font("Dialog", 0, 18));
+        jTextFieldNewNTotalSeats.setText(Integer.toString(restManager.getNTotalSeats()));
+        jPanel1.add(jTextFieldNewNTotalSeats);
+
+        jButtonSetNTotalSeats.setFont(new java.awt.Font("Dialog", 1, 14));
+        jButtonSetNTotalSeats.setText("Set");
+        jButtonSetNTotalSeats.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonSetNTotalSeatsActionPerformed(evt);
+            }
+        });
+
+        jPanel1.add(jButtonSetNTotalSeats);
+
+        getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);
+
+        jPanelLeft.setLayout(new javax.swing.BoxLayout(jPanelLeft, javax.swing.BoxLayout.Y_AXIS));
+
+        jLabel10.setText("Mode:");
+        jPanelLeft.add(jLabel10);
+
+        jLabelDisplayMode.setText("Automatic");
+        jLabelDisplayMode.setForeground(java.awt.Color.blue);
+        jLabelDisplayMode.setFont(new java.awt.Font("Dialog", 1, 18));
+        jPanelLeft.add(jLabelDisplayMode);
+
+        jButtonChangeMode.setText("Change mode");
+        jButtonChangeMode.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonChangeMode.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonChangeMode.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonChangeModeActionPerformed(evt);
+            }
+        });
+
+        jPanelLeft.add(jButtonChangeMode);
+
+        jLabelResponse.setText("Response:");
+        jPanelLeft.add(jLabelResponse);
+
+        jButtonConfirm.setText("Confirm");
+        jButtonConfirm.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonConfirm.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonConfirm.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonConfirmActionPerformed(evt);
+            }
+        });
+
+        jPanelLeft.add(jButtonConfirm);
+
+        jButtonCancel.setText("Cancel");
+        jButtonCancel.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonCancel.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonCancel.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonCancelActionPerformed(evt);
+            }
+        });
+
+        jPanelLeft.add(jButtonCancel);
+
+        getContentPane().add(jPanelLeft, java.awt.BorderLayout.WEST);
+
+        jScrollPane1.setAutoscrolls(true);
+        jTextArea.setEditable(false);
+        jTextArea.setRows(10);
+        jTextArea.setMargin(new java.awt.Insets(5, 5, 5, 5));
+        jScrollPane1.setViewportView(jTextArea);
+
+        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
+
+        pack();
+    }//GEN-END:initComponents
+
+    /**
+     * Reset event handler.
+     */
+    private void jButtonResetFieldsActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonResetFieldsActionPerformed
+        restManager.setToDefault();
+        updateFields();
+    }//GEN-LAST:event_jButtonResetFieldsActionPerformed
+
+    /**
+     * Cancel event handler.
+     */
+    private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonCancelActionPerformed
+        if (restManager.getIsPreparationWaiting())
+        {
+            Object preparation = restManager.getPreparation();
+            try
+            {
+                restManager.setCommit(false);
+                synchronized (preparation)
+                {
+                    preparation.notify();
+                }
+            }
+            catch (Exception e)
+            {
+                System.err.println("RestaurantView.jButtonCancelActionPerformed(): Unable to notify preparation.");
+            }
+        }
+    }//GEN-LAST:event_jButtonCancelActionPerformed
+
+    /**
+     * Confirm event handler.
+     */
+    private void jButtonConfirmActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonConfirmActionPerformed
+        if (restManager.getIsPreparationWaiting())
+        {
+            Object preparation = restManager.getPreparation();
+            try
+            {
+                restManager.setCommit(true);
+                synchronized (preparation)
+                {
+                    preparation.notify();
+                }
+            }
+            catch (Exception e)
+            {
+                System.err.println("RestaurantView.jButtonCancelActionPerformed(): Unable to notify preparation.");
+            }
+        }
+    }//GEN-LAST:event_jButtonConfirmActionPerformed
+
+    /**
+     * ChangeMode event handler.
+     */
+    private void jButtonChangeModeActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonChangeModeActionPerformed
+        if (restManager.isAutoCommitMode())
+        {
+            restManager.setAutoCommitMode(false);
+        }
+        else
+        {
+            restManager.setAutoCommitMode(true);
+        }
+        updateFields();
+    }//GEN-LAST:event_jButtonChangeModeActionPerformed
+
+    /**
+     * Capacity change event handler.
+     */
+    private void jButtonSetNTotalSeatsActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonSetNTotalSeatsActionPerformed
+        String strNSeats = jTextFieldNewNTotalSeats.getText();
+
+        restManager.newCapacity(Integer.parseInt(strNSeats));
+        int nFreeSeats = restManager.getNFreeSeats();
+
+        jLabelNTotalSeats.setText(strNSeats);
+        jLabelNFreeSeats.setText(Integer.toString(nFreeSeats));
+    }//GEN-LAST:event_jButtonSetNTotalSeatsActionPerformed
+
+    /**
+     * Exit the application.
+     */
+    private void exitForm(java.awt.event.WindowEvent evt)
+    {//GEN-FIRST:event_exitForm
+        //System.exit(0); // disabled for embedding in application servers.
+    }//GEN-LAST:event_exitForm
+
+    /**
+     * Add regular text to the central jTextArea.
+     *
+     * @param text The String to add
+     */
+    public void addMessage(java.lang.String text)
+    {
+        jButtonConfirm.setBackground(backButtonColor);
+        jButtonCancel.setBackground(backButtonColor);
+        jTextArea.append(text + "\n");
+        jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum());
+    }
+
+    /**
+     * Add status (highlighted) text to the central jTextArea.
+     *
+     * @param text The String to add
+     */
+    public void addPrepareMessage(java.lang.String text)
+    {
+        jButtonConfirm.setBackground(java.awt.Color.red);
+        jButtonCancel.setBackground(java.awt.Color.red);
+        jTextArea.append(text + "\n");
+        jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum());
+    }
+
+
+    /**
+     * Synchronise the GUI with the underlying state.
+     */
+    public void updateFields()
+    {
+        jLabelNTotalSeats.setText(Integer.toString(restManager.getNTotalSeats()));
+        jTextFieldNewNTotalSeats.setText(Integer.toString(restManager.getNTotalSeats()));
+        jLabelNPreparedSeats.setText(Integer.toString(restManager.getNPreparedSeats()));
+        jLabelNConfirmedSeats.setText(Integer.toString(restManager.getNCommittedSeats()));
+        jLabelNFreeSeats.setText(Integer.toString(restManager.getNFreeSeats()));
+        jLabelNBookedSeats.setText(Integer.toString(restManager.getNBookedSeats()));
+
+        //update fields related to interactive mode.
+        if (restManager.isAutoCommitMode())
+        {
+            jLabelResponse.setVisible(false);
+            jButtonConfirm.setVisible(false);
+            jButtonCancel.setVisible(false);
+            jLabelDisplayMode.setText("automatic");
+        }
+        else
+        {
+            jLabelResponse.setVisible(true);
+            jButtonConfirm.setVisible(true);
+            jButtonCancel.setVisible(true);
+            jLabelDisplayMode.setText("interactive");
+        }
+    }
+
+    /**
+     * Allow use of a singleton model for web services demo.
+     */
+    public static RestaurantView getSingletonInstance()
+    {
+        if (singletonInstance == null)
+        {
+            singletonInstance = new RestaurantView(RestaurantManager.getSingletonInstance());
+        }
+
+        singletonInstance.show();
+        return singletonInstance;
+    }
+
+    /**
+     * A singleton instance of this class.
+     */
+    private static RestaurantView singletonInstance;
+
+
+    // Variables declaration - automatically generated - do not modify
+
+    private javax.swing.JPanel jPanel2;
+    private javax.swing.JLabel jLabel5;
+    private javax.swing.JLabel jLabelNBookedSeats;
+    private javax.swing.JLabel jLabel9;
+    private javax.swing.JLabel jLabelNPreparedSeats;
+    private javax.swing.JLabel jLabel2;
+    private javax.swing.JLabel jLabelNConfirmedSeats;
+    private javax.swing.JLabel jLabel6;
+    private javax.swing.JLabel jLabelNFreeSeats;
+    private javax.swing.JLabel jLabel7;
+    private javax.swing.JButton jButtonResetFields;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JLabel jLabel8;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabelNTotalSeats;
+    private javax.swing.JLabel jLabel4;
+    private javax.swing.JLabel jLabel3;
+    private javax.swing.JTextField jTextFieldNewNTotalSeats;
+    private javax.swing.JButton jButtonSetNTotalSeats;
+    private javax.swing.JPanel jPanelLeft;
+    private javax.swing.JLabel jLabel10;
+    private javax.swing.JLabel jLabelDisplayMode;
+    private javax.swing.JButton jButtonChangeMode;
+    private javax.swing.JLabel jLabelResponse;
+    private javax.swing.JButton jButtonConfirm;
+    private javax.swing.JButton jButtonCancel;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JTextArea jTextArea;
+
+    // End of automatically generated variables declarations
+
+    /**
+     * The  {@link RestaurantManager} instance this view is bound to.
+     */
+    private RestaurantManager restManager;
+
+    /**
+     * The current color of the back button.
+     */
+    private java.awt.Color backButtonColor;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiManager.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiManager.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiManager.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,347 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TaxiManager.java
+ *
+ * Copyright (c) 2003 Arjuna Technologies Ltd.
+ *
+ * $Id: TaxiManager.java,v 1.3 2004/04/21 13:09:19 jhalliday Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.taxi;
+
+import java.util.Hashtable;
+
+/**
+ * The transactional application logic for the Taxi Service
+ * <p/>
+ * Stores and manages taxi reservations. Knows nothing about Web Services.
+ * Understands transactional booking lifecycle: unprepared, prepared, finished.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+public class TaxiManager
+{
+    /**
+     * Create and initialise a new TaxiManager instance.
+     */
+    public TaxiManager()
+    {
+        setToDefault();
+    }
+
+    /**
+     * Book a taxi.
+     *
+     * @param txID The transaction identifier
+     */
+    public void bookTaxi(Object txID)
+    {
+        // locate any pre-existing request for the same transaction
+        Integer request = (Integer) unpreparedTransactions.get(txID);
+        if (request == null)
+        {
+            // this is the first request for this
+            // transaction - setup a record for it
+            request = new Integer(0);
+        }
+
+        // record the request, keyed to its transaction scope
+        unpreparedTransactions.put(txID, new Integer(request.intValue()));
+    }
+
+    /**
+     * Attempt to ensure availability of the requested taxi.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean prepareTaxi(Object txID)
+    {
+        // ensure that we have seen this transaction before
+        Integer request = (Integer) unpreparedTransactions.get(txID);
+        if (request == null)
+        {
+            return false; // error: transaction not registered
+        }
+        else
+        {
+            if (autoCommitMode)
+            {
+                // record the prepared transaction
+                preparedTransactions.put(txID, request);
+                unpreparedTransactions.remove(txID);
+                return true;
+            }
+            else
+            {
+                try
+                {
+                    // wait for a user commit/rollback decision
+                    isPreparationWaiting = true;
+                    synchronized (preparation)
+                    {
+                        preparation.wait();
+                    }
+                    isPreparationWaiting = false;
+                    if (isCommit)
+                    {
+                        // record the prepared transaction
+                        preparedTransactions.put(txID, request);
+                        unpreparedTransactions.remove(txID);
+                        return true;
+                    }
+                    else
+                    {
+                        return false;
+
+                    }
+                }
+                catch (Exception e)
+                {
+                    System.err.println("TaxiManager.prepareTaxi(): Unable to stop preparation.");
+                    return false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Release a booked or prepared taxi.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean cancelTaxi(Object txID)
+    {
+        boolean success = false;
+
+        // the transaction may be prepared, unprepared or unknown
+
+        if (preparedTransactions.containsKey(txID))
+        {
+            // undo the prepare operations
+            preparedTransactions.remove(txID);
+            success = true;
+        }
+        else if (unpreparedTransactions.containsKey(txID))
+        {
+            // undo the booking operations
+            unpreparedTransactions.remove(txID);
+            success = true;
+        }
+        else
+        {
+            success = false; // error: transaction not registered
+        }
+
+        return success;
+    }
+
+    /**
+     * Commit taxi booking.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean commitTaxi(Object txID)
+    {
+        boolean success = false;
+        hasCommitted = true;
+
+        // the transaction may be prepared, unprepared or unknown
+
+        if (preparedTransactions.containsKey(txID))
+        {
+            // complete the prepared transaction
+            preparedTransactions.remove(txID);
+            success = true;
+        }
+        else if (unpreparedTransactions.containsKey(txID))
+        {
+            // use one phase commit optimisation, skipping prepare
+            unpreparedTransactions.remove(txID);
+            success = true;
+        }
+        else
+        {
+            success = false; // error: transaction not registered
+        }
+
+        return success;
+    }
+
+    /**
+     * Determine if a specific transaction is known to the business logic.
+     *
+     * @param txID The uniq id for the transaction
+     * @return true if the business logic is holding state related to the given txID,
+     *         false otherwise.
+     */
+    public boolean knowsAbout(Object txID)
+    {
+        return (unpreparedTransactions.containsKey(txID) || preparedTransactions.containsKey(txID));
+    }
+
+    /**
+     * Determine the autoCommit status of the instance.
+     *
+     * @return true if autoCommit mode is active, false otherwise
+     */
+    public boolean isAutoCommitMode()
+    {
+        return autoCommitMode;
+    }
+
+    /**
+     * Set the autoCommit mode of the instance.
+     *
+     * @param autoCommit true for automatic commit, false for manual commit.
+     */
+    public void setAutoCommitMode(boolean autoCommit)
+    {
+        autoCommitMode = autoCommit;
+    }
+
+    /**
+     * Get the preparation object for manual commit wait/notify.
+     *
+     * @return The preparation object
+     */
+    public Object getPreparation()
+    {
+        return preparation;
+    }
+
+    /**
+     * Determine if the instance is waiting for manual commit/rollback.
+     *
+     * @return true if waiting, false otherwise
+     */
+    public boolean getIsPreparationWaiting()
+    {
+        return isPreparationWaiting;
+    }
+
+    /**
+     * Set the waiting status of the instance.
+     *
+     * @param isWaiting The new value to set
+     */
+    public void setIsPreparationWaiting(boolean isWaiting)
+    {
+        isPreparationWaiting = isWaiting;
+    }
+
+    /**
+     * Set the manual commit status.
+     */
+    public void setCommit(boolean commit)
+    {
+        isCommit = commit;
+    }
+
+    /**
+     * (re-)initialise the instance data structures.
+     */
+    public void setToDefault()
+    {
+        preparedTransactions = new Hashtable();
+        unpreparedTransactions = new Hashtable();
+        autoCommitMode = true;
+        preparation = new Object();
+        isPreparationWaiting = false;
+        isCommit = false;
+        hasCommitted = false;
+    }
+
+    /**
+     * Allow use of a singleton model for web services demo.
+     */
+    public static TaxiManager getSingletonInstance()
+    {
+        if (singletonInstance == null)
+        {
+            singletonInstance = new TaxiManager();
+        }
+
+        return singletonInstance;
+    }
+
+    public boolean hasBeenCommitted()
+    {
+        return hasCommitted;
+    }
+
+    public Hashtable getPreparedTransactions()
+    {
+        return preparedTransactions;
+    }
+
+    public Hashtable getUnpreparedTransactions()
+    {
+        return unpreparedTransactions;
+    }
+
+    /**
+     * A singleton instance of this class.
+     */
+    private static TaxiManager singletonInstance;
+
+    /**
+     * The transactions we know about but which have not been prepared.
+     */
+    private Hashtable unpreparedTransactions;
+
+    /**
+     * The transactions we know about and are prepared to commit.
+     */
+    private Hashtable preparedTransactions;
+
+    /**
+     * The auto commit mode.
+     * <p/>
+     * true = automatically commit, false = manually commit
+     */
+    private boolean autoCommitMode;
+
+    /**
+     * The user specified outcome when in manual commit mode.
+     */
+    private boolean isCommit;
+
+    /**
+     * If the participant has already been commmitted or not.
+     */
+    private boolean hasCommitted = false;
+
+    /**
+     * The object used for wait/notify in manual commit mode.
+     */
+    private Object preparation;
+
+    /**
+     * The waiting status, when in manual commit mode.
+     */
+    private boolean isPreparationWaiting;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiParticipantAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiParticipantAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiParticipantAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,200 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TaxiParticipantAT.java
+ *
+ * Copyright (c) 2003, 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: TaxiParticipantAT.java,v 1.3 2005/02/23 09:58:02 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.taxi;
+
+import com.arjuna.wst.*;
+
+/**
+ * An adapter class that exposes the TaxiManager transaction lifecycle
+ * API as a WS-T Atomic Transaction participant.
+ * Also logs events to a TaxiView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+public class TaxiParticipantAT implements Durable2PCParticipant
+{
+    /**
+     * Participant instances are related to transaction instances
+     * in a one to one manner.
+     *
+     * @param txID uniq id String for the transaction instance.
+     */
+    public TaxiParticipantAT(String txID)
+    {
+        // Binds to the singleton TaxiView and TaxiManager
+        taxiManager = TaxiManager.getSingletonInstance();
+        taxiView = TaxiView.getSingletonInstance();
+        // we need to save the txID for later use when calling
+        // business logic methods in the taxiManger.
+        this.txID = txID;
+    }
+
+    /**
+     * Invokes the prepare step of the business logic,
+     * reporting activity and outcome.
+     *
+     * @return Prepared where possible, Aborted where necessary.
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public Vote prepare() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the prepare operation
+        // on the backend business logic.
+
+        System.out.println("TaxiParticipantAT.prepare");
+
+        taxiView.addPrepareMessage("id:" + txID + ". Prepare called on participant: " + this.getClass().toString());
+
+        boolean success = taxiManager.prepareTaxi(txID);
+
+        // Log the outcome and map the return value from
+        // the business logic to the appropriate Vote type.
+
+        if (success)
+        {
+            taxiView.addMessage("Taxi prepared successfully. Returning 'Prepared'\n");
+            taxiView.updateFields();
+            return new Prepared();
+        }
+        else
+        {
+            taxiManager.cancelTaxi(txID) ;
+            taxiView.addMessage("Prepare failed (not enough Taxis?) Returning 'Aborted'\n");
+            taxiView.updateFields();
+            return new Aborted();
+        }
+    }
+
+    /**
+     * Invokes the commit step of the business logic,
+     * reporting activity and outcome.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void commit() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the commit operation
+        // on the backend business logic.
+
+        System.out.println("TaxiParticipantAT.commit");
+
+        taxiView.addMessage("id:" + txID + ". Commit called on participant: " + this.getClass().toString());
+
+        boolean success = taxiManager.commitTaxi(txID);
+
+        // Log the outcome
+
+        if (success)
+        {
+            taxiView.addMessage("Taxi committed\n");
+        }
+        else
+        {
+            taxiView.addMessage("Something went wrong (Transaction not registered?)\n");
+        }
+
+        taxiView.updateFields();
+    }
+
+    /**
+     * Invokes the rollback operation on the business logic,
+     * reporting activity and outcome.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void rollback() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the rollback operation
+        // on the backend business logic.
+
+        System.out.println("TaxiParticipantAT.rollback");
+
+        taxiView.addMessage("id:" + txID + ". Rollback called on participant: " + this.getClass().toString());
+
+        boolean success = taxiManager.cancelTaxi(txID);
+
+        // Log the outcome
+
+        if (success)
+        {
+            taxiView.addMessage("Taxi booking cancelled\n");
+        }
+        else
+        {
+            taxiView.addMessage("Something went wrong (Transaction not registered?)\n");
+        }
+
+        taxiView.updateFields();
+    }
+
+    /**
+     * Shortcut method which combines the prepare
+     * and commit steps in a single operation.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void commitOnePhase() throws WrongStateException, SystemException
+    {
+        prepare();
+        commit();
+    }
+
+    public void unknown() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    public void error() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    /**
+     * Id for the transaction which this participant instance relates to.
+     * Set by the service (via contrtuctor) at enrolment time, this value
+     * is passed to the backend business logic methods.
+     */
+    protected String txID;
+
+    /**
+     * The TaxiView object to log events through.
+     */
+    protected static TaxiView taxiView;
+
+    /**
+     * The TaxiManager to perform business logic operations on.
+     */
+    protected static TaxiManager taxiManager;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiParticipantBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiParticipantBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiParticipantBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,152 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TaxiParticipantBA.java
+ *
+ * Copyright (c) 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: TaxiParticipantBA.java,v 1.2 2004/09/09 15:18:11 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.taxi;
+
+import com.arjuna.wst.*;
+
+/**
+ * An adapter class that exposes the TaxiManager transaction lifecycle
+ * API as a WS-T Business Activity participant.
+ * Also logs events to a TaxiView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.2 $
+ */
+public class TaxiParticipantBA implements BusinessAgreementWithParticipantCompletionParticipant
+{
+    /**
+     * Participant instances are related to business method calls
+     * in a one to one manner.
+     *
+     * @param txID uniq id String for the transaction instance.
+     */
+    public TaxiParticipantBA(String txID)
+    {
+        // Binds to the singleton TaxiView and TaxiManager
+        taxiManager = TaxiManager.getSingletonInstance();
+        taxiView = TaxiView.getSingletonInstance();
+        // we need to save the txID for later use when logging.
+        this.txID = txID;
+    }
+
+    /**
+     * The transaction has completed successfully. The participant previously
+     * informed the coordinator that it was ready to complete.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException never in this implementation.
+     */
+
+    public void close() throws WrongStateException, SystemException
+    {
+        // for logging only. This impl does not do anything else here.
+
+        System.out.println("TaxiParticipantBA.close");
+
+        taxiView.addMessage("id:" + txID + ". Close called on participant: " + this.getClass());
+        taxiView.updateFields();
+    }
+
+    /**
+     * The transaction has cancelled, and the participant should undo any work.
+     * The participant cannot have informed the coordinator that it has
+     * completed.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException never in this implementation.
+     */
+
+    public void cancel() throws WrongStateException, SystemException
+    {
+        // we will always have called completed or error, so this can be a null op.
+
+        System.out.println("TaxiParticipantBA.cancel");
+
+        taxiView.addMessage("id:" + txID + ". Cancel called on participant: " + this.getClass().toString());
+        taxiView.updateFields();
+    }
+
+    /**
+     * The transaction has cancelled. The participant previously
+     * informed the coordinator that it had finished work but could compensate
+     * later if required, so it is now requested to do so.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException always, because this implementation does not support compensation.
+     */
+
+    public void compensate() throws WrongStateException, SystemException
+    {
+        System.out.println("TaxiParticipantBA.compensate");
+
+        // This impl does not support compensation, in order
+        // to allow illustration of heuristic outcomes.
+        // It just log the event and throws an exception.
+
+        taxiView.addMessage("id:" + txID + ". Compensate called on participant: " + this.getClass().toString());
+
+        taxiView.addMessage("Compensation not supported by ths implementation!");
+        taxiView.updateFields();
+
+        throw new SystemException("Compensation not supported!");
+    }
+
+    public String status () throws SystemException
+    {
+        return Status.STATUS_ACTIVE;
+    }
+
+    public void unknown() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    public void error() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    /**
+     * Id for the transaction which this participant instance relates to.
+     * Set by the service (via contrtuctor) at enrolment time, this value
+     * is used in informational log messages.
+     */
+    protected String txID;
+
+    /**
+     * The TaxiView object to log events through.
+     */
+    protected static TaxiView taxiView;
+
+    /**
+     * The TaxiManager to perform business logic operations on.
+     */
+    protected static TaxiManager taxiManager;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiServiceAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiServiceAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiServiceAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TaxiServiceAT.java
+ *
+ * Copyright (c) 2003, 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: TaxiServiceAT.java,v 1.3 2004/12/01 16:27:01 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.taxi;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst.TransactionManagerFactory;
+import com.arjuna.mw.wst.UserTransactionFactory;
+import com.jboss.jbosstm.xts.demo.taxi.ITaxiServiceAT;
+
+import javax.jws.WebService;
+import javax.jws.HandlerChain;
+import javax.jws.WebMethod;
+import javax.jws.soap.SOAPBinding;
+
+/**
+ * An adapter class that exposes the TaxiManager business API as a
+ * transactional Web Service. Also logs events to a TaxiView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+ at WebService(serviceName="TaxiServiceATService", portName="TaxiServiceAT",
+        name = "ITaxiServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Taxi",
+        wsdlLocation = "/WEB-INF/wsdl/TaxiServiceAT.wsdl")
+ at HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")
+ at SOAPBinding(style=SOAPBinding.Style.RPC)
+public class TaxiServiceAT implements ITaxiServiceAT
+{
+    /**
+     * Book a taxi
+     * Enrols a Participant if necessary, then passes
+     * the call through to the business logic.
+     */
+    @WebMethod
+    public void bookTaxi()
+    {
+        TaxiView taxiView = TaxiView.getSingletonInstance();
+        TaxiManager taxiManager = TaxiManager.getSingletonInstance();
+
+        String transactionId = null;
+        try
+        {
+            // get the transaction context of this thread:
+            transactionId = UserTransactionFactory.userTransaction().toString();
+            System.out.println("TaxiServiceAT transaction id =" + transactionId);
+
+            if (!taxiManager.knowsAbout(transactionId))
+            {
+                System.out.println("TaxiServiceAT - enrolling...");
+                // enlist the Participant for this service:
+                TaxiParticipantAT taxiParticipant = new TaxiParticipantAT(transactionId);
+                TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(taxiParticipant, new Uid().toString());
+            }
+        }
+        catch (Exception e)
+        {
+            System.err.println("bookTaxi: Participant enrolment failed");
+            e.printStackTrace(System.err);
+            return;
+        }
+
+        taxiView.addMessage("******************************");
+
+        taxiView.addMessage("id:" + transactionId.toString() + ". Received a taxi booking request");
+
+        TaxiManager.getSingletonInstance().bookTaxi(transactionId);
+
+        taxiView.addMessage("Request complete\n");
+        taxiView.updateFields();
+    }
+}
+
+
+
+

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiServiceBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiServiceBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiServiceBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,153 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TaxiServiceBA.java
+ *
+ * Copyright (c) 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: TaxiServiceBA.java,v 1.5 2004/12/01 16:27:01 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.taxi;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst.BusinessActivityManagerFactory;
+import com.arjuna.mw.wst.BusinessActivityManager;
+import com.arjuna.wst.BAParticipantManager;
+import com.arjuna.wst.SystemException;
+import com.jboss.jbosstm.xts.demo.taxi.ITaxiServiceBA;
+
+import javax.jws.HandlerChain;
+import javax.jws.WebMethod;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+/**
+ * An adapter class that exposes the TaxiManager business API as a
+ * transactional Web Service. Also logs events to a TaxiView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.5 $
+ */
+ at WebService(serviceName="TaxiServiceBAService", portName="TaxiServiceBA",
+        name = "ITaxiServiceBA", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Taxi",
+        wsdlLocation = "/WEB-INF/wsdl/TaxiServiceBA.wsdl")
+ at HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")
+ at SOAPBinding(style=SOAPBinding.Style.RPC)
+public class TaxiServiceBA implements ITaxiServiceBA
+{
+    /**
+     * Book a taxi
+     * Enrols a Participant if necessary and passes
+     * the call through to the business logic.
+     *
+     * @return true on success, false otherwise.
+     */
+    @WebMethod
+    @WebResult(name = "bookTaxiBAResponse", partName = "bookTaxiBAResponse")
+    public boolean bookTaxi()
+    {
+        TaxiView taxiView = TaxiView.getSingletonInstance();
+        TaxiManager taxiManager = TaxiManager.getSingletonInstance();
+
+        BusinessActivityManager activityManager = BusinessActivityManagerFactory.businessActivityManager();
+
+        // get the transaction context of this thread:
+        String transactionId = null;
+        try
+        {
+            transactionId = activityManager.currentTransaction().toString();
+        }
+        catch (SystemException e)
+        {
+            System.err.println("bookTaxi: unable to obtain a transaction context!");
+            e.printStackTrace(System.err);
+            return false;
+        }
+
+        // log the event:
+        System.out.println("TaxiServiceBA transaction id =" + transactionId);
+
+        taxiView.addMessage("******************************");
+
+        taxiView.addPrepareMessage("id:" + transactionId.toString() + ". Received a taxi booking request");
+        taxiView.updateFields();
+
+        // invoke the backend business logic:
+        taxiManager.bookTaxi(transactionId);
+
+        // attempt to finalise the booking
+        if (taxiManager.prepareTaxi(transactionId))
+        {
+            taxiView.addMessage("id:" + transactionId + ". Seats prepared, trying to commit and enlist compensation Participant");
+            taxiView.updateFields();
+
+            // it worked, so now we need a participant enlisted in case of compensation:
+            TaxiParticipantBA taxiParticipant = new TaxiParticipantBA(transactionId);
+            // enlist the Participant for this service:
+            BAParticipantManager participantManager = null;
+            try
+            {
+                participantManager = activityManager.enlistForBusinessAgreementWithParticipantCompletion(taxiParticipant, new Uid().toString());
+            }
+            catch (Exception e)
+            {
+                taxiView.addMessage("id:" + transactionId + ". Participant enrolement failed");
+                System.err.println("bookTaxi: Participant enrolment failed");
+                e.printStackTrace(System.err);
+                return false;
+            }
+
+            // finish the booking in the backend:
+            taxiManager.commitTaxi(transactionId);
+
+            try
+            {
+                // tell the manager we have finished our work:
+                participantManager.completed();
+            }
+            catch (Exception e)
+            {
+                System.err.println("bookTaxi: 'completed' callback failed");
+                e.printStackTrace(System.err);
+                return false;
+            }
+        }
+        else
+        {
+            taxiView.addMessage("id:" + transactionId + ". Failed to reserve taxi. Cancelling.");
+            taxiManager.cancelTaxi(transactionId);
+            taxiView.updateFields();
+            return false;
+        }
+
+        taxiView.addMessage("Request complete\n");
+        taxiView.updateFields();
+
+        return true;
+    }
+}
+
+
+
+

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiView.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiView.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/taxi/TaxiView.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,320 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TaxiView.java
+ *
+ * Copyright (c) 2003 Arjuna Technologies Ltd.
+ *
+ * $Id: TaxiView.java,v 1.2 2004/04/21 13:09:20 jhalliday Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.taxi;
+
+/**
+ * The visual interface (GUI) for the Taxi Service.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.2 $
+ */
+public class TaxiView extends javax.swing.JFrame
+{
+    // Note: Some parts of this file were auto-generated
+    // by NetBeans 3.3 FormEditor (http://www.netbeans.org)
+
+    /**
+     * Create a new TaxiView instance.
+     *
+     * @param tManager The {@link TaxiManager} instance to bind to
+     */
+    public TaxiView(TaxiManager tManager)
+    {
+        taxiManager = tManager;
+        initComponents();
+        updateFields();
+        backButtonColor = jButtonConfirm.getBackground();
+    }
+
+    /**
+     * Initialize the form.
+     * This is called by the constructor
+     *
+     * WARNING: Automatically generated code, may be overwritten
+     */
+    private void initComponents()
+    {//GEN-BEGIN:initComponents
+        jPanel2 = new javax.swing.JPanel();
+        jLabel10 = new javax.swing.JLabel();
+        jButtonChangeDefaultAnswer = new javax.swing.JButton();
+        jLabelDefaultAnswer = new javax.swing.JLabel();
+        jPanel3 = new javax.swing.JPanel();
+        jLabel15 = new javax.swing.JLabel();
+        jLabelDisplayMode = new javax.swing.JLabel();
+        jButtonChangeMode = new javax.swing.JButton();
+        jLabelResponse = new javax.swing.JLabel();
+        jButtonConfirm = new javax.swing.JButton();
+        jButtonCancel = new javax.swing.JButton();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        jTextArea = new javax.swing.JTextArea();
+
+        setTitle("Taxi Service");
+        addWindowListener(new java.awt.event.WindowAdapter()
+        {
+            public void windowClosing(java.awt.event.WindowEvent evt)
+            {
+                exitForm(evt);
+            }
+        });
+
+        jPanel2.setBorder(new javax.swing.border.LineBorder(java.awt.Color.black));
+        jLabel10.setText("Taxi                                                                    ");
+        jLabel10.setForeground(java.awt.Color.red);
+        jLabel10.setFont(new java.awt.Font("Dialog", 1, 24));
+        jPanel2.add(jLabel10);
+
+        getContentPane().add(jPanel2, java.awt.BorderLayout.NORTH);
+
+        jPanel3.setLayout(new javax.swing.BoxLayout(jPanel3, javax.swing.BoxLayout.Y_AXIS));
+
+        jLabel15.setText("Mode:");
+        jPanel3.add(jLabel15);
+
+        jLabelDisplayMode.setText("Automatic");
+        jLabelDisplayMode.setForeground(java.awt.Color.blue);
+        jLabelDisplayMode.setFont(new java.awt.Font("Dialog", 1, 18));
+        jPanel3.add(jLabelDisplayMode);
+
+        jButtonChangeMode.setText("Change mode");
+        jButtonChangeMode.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonChangeMode.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonChangeMode.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonChangeModeActionPerformed(evt);
+            }
+        });
+
+        jPanel3.add(jButtonChangeMode);
+
+        jLabelResponse.setText("Response:");
+        jPanel3.add(jLabelResponse);
+
+        jButtonConfirm.setText("Confirm");
+        jButtonConfirm.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonConfirm.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonConfirm.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonConfirmActionPerformed(evt);
+            }
+        });
+
+        jPanel3.add(jButtonConfirm);
+
+        jButtonCancel.setText("Cancel");
+        jButtonCancel.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonCancel.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonCancel.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonCancelActionPerformed(evt);
+            }
+        });
+
+        jPanel3.add(jButtonCancel);
+
+        getContentPane().add(jPanel3, java.awt.BorderLayout.WEST);
+
+        jScrollPane1.setAutoscrolls(true);
+        jTextArea.setEditable(false);
+        jTextArea.setRows(10);
+        jTextArea.setMargin(new java.awt.Insets(5, 5, 5, 5));
+        jScrollPane1.setViewportView(jTextArea);
+
+        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
+
+        pack();
+    }//GEN-END:initComponents
+
+    /**
+     * Cancel event handler.
+     */
+    private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonCancelActionPerformed
+        if (taxiManager.getIsPreparationWaiting())
+        {
+            Object preparation = taxiManager.getPreparation();
+            try
+            {
+                taxiManager.setCommit(false);
+                synchronized (preparation)
+                {
+                    preparation.notify();
+                }
+            }
+            catch (Exception e)
+            {
+                System.err.println("TaxiView.jButtonCancelActionPerformed(): Unable to notify preparation.");
+            }
+        }
+    }//GEN-LAST:event_jButtonCancelActionPerformed
+
+    /**
+     * Confirm event handler.
+     */
+    private void jButtonConfirmActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonConfirmActionPerformed
+        if (taxiManager.getIsPreparationWaiting())
+        {
+            Object preparation = taxiManager.getPreparation();
+            try
+            {
+                taxiManager.setCommit(true);
+                synchronized (preparation)
+                {
+                    preparation.notify();
+                }
+            }
+            catch (Exception e)
+            {
+                System.err.println("TaxiView.jButtonCancelActionPerformed(): Unable to notify preparation.");
+            }
+        }
+    }//GEN-LAST:event_jButtonConfirmActionPerformed
+
+    /**
+     * ChangeMode event handler.
+     */
+    private void jButtonChangeModeActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonChangeModeActionPerformed
+        if (taxiManager.isAutoCommitMode())
+        {
+            taxiManager.setAutoCommitMode(false);
+        }
+        else
+        {
+            taxiManager.setAutoCommitMode(true);
+        }
+        updateFields();
+    }//GEN-LAST:event_jButtonChangeModeActionPerformed
+
+    /**
+     * Exit the application.
+     */
+    private void exitForm(java.awt.event.WindowEvent evt)
+    {//GEN-FIRST:event_exitForm
+        //System.exit(0); // disabled for embedding in application servers.
+    }//GEN-LAST:event_exitForm
+
+    /**
+     * Add status (highlighted) text to the central jTextArea.
+     *
+     * @param text The String to add
+     */
+    public void addMessage(java.lang.String text)
+    {
+        jButtonConfirm.setBackground(backButtonColor);
+        jButtonCancel.setBackground(backButtonColor);
+        jTextArea.append(text + "\n");
+        jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum());
+    }
+
+    /**
+     * Add status (highlighted) text to the central jTextArea.
+     *
+     * @param text The String to add
+     */
+    public void addPrepareMessage(java.lang.String text)
+    {
+        jButtonConfirm.setBackground(java.awt.Color.red);
+        jButtonCancel.setBackground(java.awt.Color.red);
+        jTextArea.append(text + "\n");
+        jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum());
+    }
+
+    /**
+     * Synchronise the GUI with the underlying state.
+     */
+    public void updateFields()
+    {
+        //update fields related to interactive mode.
+        if (taxiManager.isAutoCommitMode())
+        {
+            jLabelResponse.setVisible(false);
+            jButtonConfirm.setVisible(false);
+            jButtonCancel.setVisible(false);
+            jLabelDisplayMode.setText("automatic");
+        }
+        else
+        {
+            jLabelResponse.setVisible(true);
+            jButtonConfirm.setVisible(true);
+            jButtonCancel.setVisible(true);
+            jLabelDisplayMode.setText("interactive");
+        }
+    }
+
+    /**
+     * Allow use of a singleton model for web services demo.
+     */
+    public static TaxiView getSingletonInstance()
+    {
+        if (singletonInstance == null)
+        {
+            singletonInstance = new TaxiView(TaxiManager.getSingletonInstance());
+        }
+        singletonInstance.show();
+        return singletonInstance;
+    }
+
+    /**
+     * A singleton instance of this class.
+     */
+    private static TaxiView singletonInstance;
+
+    // Variables declaration - automatically generated - do not modify
+    private javax.swing.JPanel jPanel2;
+    private javax.swing.JLabel jLabel10;
+    private javax.swing.JButton jButtonChangeDefaultAnswer;
+    private javax.swing.JLabel jLabelDefaultAnswer;
+    private javax.swing.JPanel jPanel3;
+    private javax.swing.JLabel jLabel15;
+    private javax.swing.JLabel jLabelDisplayMode;
+    private javax.swing.JButton jButtonChangeMode;
+    private javax.swing.JLabel jLabelResponse;
+    private javax.swing.JButton jButtonConfirm;
+    private javax.swing.JButton jButtonCancel;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JTextArea jTextArea;
+
+    // End of automatically generated variables declarations
+    /**
+     * The  {@link TaxiManager} instance this view is bound to.
+     */
+    private TaxiManager taxiManager;
+    /**
+     * The current color of the back button.
+     */
+    private java.awt.Color backButtonColor;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreManager.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreManager.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreManager.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,529 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TheatreManager.java
+ *
+ * Copyright (c) 2003 Arjuna Technologies Ltd.
+ *
+ * $Id: TheatreManager.java,v 1.4 2004/04/21 13:09:20 jhalliday Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.theatre;
+
+import java.util.Hashtable;
+
+/**
+ * The transactional application logic for the Theatre Service.
+ * <p/>
+ * Stores and manages seating reservations. Knows nothing about Web Services.
+ * Understands transactional booking lifecycle: unprepared, prepared, finished.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.4 $
+ */
+public class TheatreManager
+{
+    /**
+     * Create and initialise a new TheatreManager instance.
+     */
+    public TheatreManager()
+    {
+        setToDefault();
+    }
+
+    /**
+     * Book a number of seats in a specific area of the theatre.
+     *
+     * @param txID   The transaction identifier
+     * @param nSeats The number of seats requested
+     * @param area   The type of seating requested
+     */
+    public void bookSeats(Object txID, int nSeats, int area)
+    {
+        // locate any pre-existing request for the same transaction
+        Integer[] requests = (Integer[]) unpreparedTransactions.get(txID);
+        if (requests == null)
+        {
+            // this is the first request for this transaction
+            // setup the data structure to record it
+            requests = new Integer[NUM_SEAT_AREAS];
+            for (int i = 0; i < NUM_SEAT_AREAS; i++)
+            {
+                requests[i] = new Integer(0);
+            }
+        }
+
+        // record the request, keyed to its transaction scope
+        requests[area] = new Integer(requests[area].intValue() + nSeats);
+        unpreparedTransactions.put(txID, requests);
+
+        // record the increased commitment to provide seating
+        nBookedSeats[area] += nSeats;
+    }
+
+    /**
+     * Attempt to ensure availability of the requested seating.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean prepareSeats(Object txID)
+    {
+        int[] nSeats = new int[NUM_SEAT_AREAS];
+
+        // ensure that we have seen this transaction before
+        Integer[] requests = (Integer[]) unpreparedTransactions.get(txID);
+        if (requests == null)
+        {
+            return false; // error: transaction not registered
+        }
+        else
+        {
+            // determine the number of seats available
+            for (int i = 0; i < NUM_SEAT_AREAS; i++)
+            {
+                nSeats[i] = nFreeSeats[i];
+                nSeats[i] -= requests[i].intValue();
+            }
+            if (autoCommitMode)
+            {
+                boolean success = true;
+                // check we have enough seats avaiable
+                for (int i = 0; i < NUM_SEAT_AREAS; i++)
+                {
+                    if (nSeats[i] < 0)
+                    {
+                        success = false; // error: not enough seats
+                    }
+                }
+                if (success)
+                {
+                    // record the prepared transaction
+                    preparedTransactions.put(txID, requests);
+                    unpreparedTransactions.remove(txID);
+                    // mark the prepared seats as unavailable
+                    for (int i = 0; i < NUM_SEAT_AREAS; i++)
+                    {
+                        nFreeSeats[i] = nSeats[i];
+                        nPreparedSeats[i] += requests[i].intValue();
+                    }
+                }
+                return success;
+            }
+            else
+            {
+                try
+                {
+                    // wait for a user commit/rollback decision
+                    isPreparationWaiting = true;
+                    synchronized (preparation)
+                    {
+                        preparation.wait();
+                    }
+                    isPreparationWaiting = false;
+
+                    // process the user decision
+                    if (isCommit)
+                    {
+                        // record the prepared transaction
+                        preparedTransactions.put(txID, requests);
+                        unpreparedTransactions.remove(txID);
+                        // mark the prepared seats as unavailable
+                        for (int i = 0; i < NUM_SEAT_AREAS; i++)
+                        {
+                            nFreeSeats[i] = nSeats[i];
+                            nPreparedSeats[i] += requests[i].intValue();
+                        }
+                        return true;
+                    }
+                    else
+                    {
+                        return false;
+                    }
+                }
+                catch (Exception e)
+                {
+                    System.err.println("TheatreManager.prepareSeats(): Unable to stop preparation.");
+                    return false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Release booked or prepared seats.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean cancelSeats(Object txID)
+    {
+        boolean success = false;
+
+        // the transaction may be prepared, unprepared or unknown
+
+        if (preparedTransactions.containsKey(txID))
+        {
+            // undo the prepare operations
+            Integer[] requests = (Integer[]) preparedTransactions.remove(txID);
+            for (int i = 0; i < NUM_SEAT_AREAS; i++)
+            {
+                nFreeSeats[i] += requests[i].intValue();
+                nPreparedSeats[i] -= requests[i].intValue();
+                nBookedSeats[i] -= requests[i].intValue();
+            }
+            success = true;
+        }
+        else if (unpreparedTransactions.containsKey(txID))
+        {
+            // undo the booking operations
+            Integer[] requests = (Integer[]) unpreparedTransactions.remove(txID);
+            for (int i = 0; i < NUM_SEAT_AREAS; i++)
+            {
+                nBookedSeats[i] -= requests[i].intValue();
+            }
+            success = true;
+        }
+        else
+        {
+            success = false; // error: transaction not registered
+        }
+
+        return success;
+    }
+
+    /**
+     * Commit seat bookings.
+     *
+     * @param txID The transaction identifier
+     * @return true on success, false otherwise
+     */
+    public boolean commitSeats(Object txID)
+    {
+        boolean success = false;
+
+        // the transaction may be prepared, unprepared or unknown
+
+        if (preparedTransactions.containsKey(txID))
+        {
+
+            // complete the prepared transaction
+            Integer[] requests = (Integer[]) preparedTransactions.remove(txID);
+            for (int i = 0; i < NUM_SEAT_AREAS; i++)
+            {
+                nCommittedSeats[i] += requests[i].intValue();
+                nPreparedSeats[i] -= requests[i].intValue();
+                nBookedSeats[i] -= requests[i].intValue();
+            }
+            success = true;
+        }
+        else if (unpreparedTransactions.containsKey(txID))
+        {
+            // use one phase commit optimisation, skipping prepare
+            Integer[] requests = (Integer[]) unpreparedTransactions.remove(txID);
+            for (int i = 0; i < NUM_SEAT_AREAS; i++)
+            {
+                nCommittedSeats[i] += requests[i].intValue();
+                nFreeSeats[i] -= requests[i].intValue();
+                nBookedSeats[i] -= requests[i].intValue();
+            }
+            success = true;
+        }
+        else
+        {
+            success = false; // error: transaction not registered
+        }
+
+        return success;
+    }
+
+    /**
+     * Determine if a specific transaction is known to the business logic.
+     *
+     * @param txID The uniq id for the transaction
+     * @return true if the business logic is holding state related to the given txID,
+     *         false otherwise.
+     */
+    public boolean knowsAbout(Object txID)
+    {
+        return (unpreparedTransactions.containsKey(txID) || preparedTransactions.containsKey(txID));
+    }
+
+    /**
+     * Change the capacity of a given seating area.
+     *
+     * @param area   The seating area to change
+     * @param nSeats The new capacity for the area
+     */
+    public void newCapacity(int area, int nSeats)
+    {
+        nFreeSeats[area] += nSeats - nTotalSeats[area];
+        nTotalSeats[area] = nSeats;
+    }
+
+    /**
+     * Get the number of free seats in the given area.
+     *
+     * @param area The area of interest
+     * @return The number of free seats
+     */
+    public int getNFreeSeats(int area)
+    {
+        return nFreeSeats[area];
+    }
+
+    /**
+     * Get the total number of seats in the given area.
+     *
+     * @param area The area of interest
+     * @return The total number of seats
+     */
+    public int getNTotalSeats(int area)
+    {
+        return nTotalSeats[area];
+    }
+
+    /**
+     * Get the number of booked seats in the given area.
+     *
+     * @param area The area of interest
+     * @return The number of booked seats
+     */
+    public int getNBookedSeats(int area)
+    {
+        return nBookedSeats[area];
+    }
+
+    /**
+     * Get the number of prepared seats in the given area.
+     *
+     * @param area The area of interest
+     * @return The number of prepared seats
+     */
+    public int getNPreparedSeats(int area)
+    {
+        return nPreparedSeats[area];
+    }
+
+    /**
+     * Get the number of committed seats in the given area.
+     *
+     * @param area The area of interest
+     * @return The number of committed seats
+     */
+    public int getNCommittedSeats(int area)
+    {
+        return nCommittedSeats[area];
+    }
+
+    /**
+     * Determine the autoCommit status of the instance.
+     *
+     * @return true if autoCommit mode is active, false otherwise
+     */
+    public boolean isAutoCommitMode()
+    {
+        return autoCommitMode;
+    }
+
+    /**
+     * Set the autoCommit mode of the instance.
+     *
+     * @param autoCommit true for automatic commit, false for manual commit.
+     */
+    public void setAutoCommitMode(boolean autoCommit)
+    {
+        autoCommitMode = autoCommit;
+    }
+
+    /**
+     * Get the preparation object for manual commit wait/notify.
+     *
+     * @return The preparation object
+     */
+    public Object getPreparation()
+    {
+        return preparation;
+    }
+
+    /**
+     * Determine if the instance is waiting for manual commit/rollback.
+     *
+     * @return true if waiting, false otherwise
+     */
+    public boolean getIsPreparationWaiting()
+    {
+        return isPreparationWaiting;
+    }
+
+    /**
+     * Set the waiting status of the instance.
+     *
+     * @param isWaiting The new value to set
+     */
+    public void setIsPreparationWaiting(boolean isWaiting)
+    {
+        isPreparationWaiting = isWaiting;
+    }
+
+    /**
+     * Set the manual commit status.
+     */
+    public void setCommit(boolean commit)
+    {
+        isCommit = commit;
+    }
+
+    /**
+     * (re-)initialise the instance data structures.
+     */
+    public void setToDefault()
+    {
+        nTotalSeats = new int[NUM_SEAT_AREAS];
+        nFreeSeats = new int[NUM_SEAT_AREAS];
+        nBookedSeats = new int[NUM_SEAT_AREAS];
+        nPreparedSeats = new int[NUM_SEAT_AREAS];
+        nCommittedSeats = new int[NUM_SEAT_AREAS];
+        for (int i = 0; i < NUM_SEAT_AREAS; i++)
+        {
+            nTotalSeats[i] = DEFAULT_SEATING_CAPACITY;
+            nFreeSeats[i] = nTotalSeats[i];
+            nBookedSeats[i] = 0;
+            nPreparedSeats[i] = 0;
+            nCommittedSeats[i] = 0;
+        }
+        preparedTransactions = new Hashtable();
+        unpreparedTransactions = new Hashtable();
+        autoCommitMode = true;
+        preparation = new Object();
+        isPreparationWaiting = false;
+        isCommit = true;
+    }
+
+    /**
+     * Allow use of a singleton model for web services demo.
+     */
+    public static TheatreManager getSingletonInstance()
+    {
+        if (singletonInstance == null)
+        {
+            singletonInstance = new TheatreManager();
+        }
+
+        return singletonInstance;
+    }
+
+    /**
+     * A singleton instance of this class.
+     */
+    private static TheatreManager singletonInstance;
+
+    /*
+     * The following arrays are indexed by seating type.
+     *
+     * nTotalSeats = ( nFreeSeats + nBookedSeats + nPreparedSeats )
+     */
+
+    /**
+     * The total seating capacity of each area.
+     */
+    private int[] nTotalSeats;
+
+    /**
+     * The number of free seats in each area.
+     */
+    private int[] nFreeSeats;
+
+    /**
+     * The number of booked seats in each area.
+     * <p/>
+     * Note: This may exceed the total size of the area
+     */
+    private int[] nBookedSeats;
+
+    /**
+     * The number of prepared (promised) seats in each area.
+     */
+    private int[] nPreparedSeats;
+
+    /**
+     * The number of committed seats in each area.
+     */
+    private int[] nCommittedSeats;
+
+    /**
+     * The auto commit mode.
+     * <p/>
+     * true = automatically commit, false = manually commit
+     */
+    private boolean autoCommitMode;
+
+    /**
+     * The object used for wait/notify in manual commit mode.
+     */
+    private Object preparation;
+
+    /**
+     * The waiting status, when in manual commit mode.
+     */
+    private boolean isPreparationWaiting;
+
+    /**
+     * The user specified outcome when in manual commit mode.
+     */
+    private boolean isCommit;
+
+    /**
+     * The transactions we know about but which have not been prepared.
+     */
+    private Hashtable unpreparedTransactions;
+
+    /**
+     * The transactions we know about and are prepared to commit.
+     */
+    private Hashtable preparedTransactions;
+
+    /**
+     * Constant (array index) used for the seating area CIRCLE.
+     */
+    public static final int CIRCLE = 0;
+
+    /**
+     * Constant (array index) used for the seating area STALLS.
+     */
+    public static final int STALLS = 1;
+
+    /**
+     * Constant (array index) used for the seating area BALCONY.
+     */
+    public static final int BALCONY = 2;
+
+    /**
+     * The total number (array size) of seating areas.
+     */
+    public static final int NUM_SEAT_AREAS = 3;
+
+    /**
+     * The default initial capacity of each seating area.
+     */
+    public static final int DEFAULT_SEATING_CAPACITY = 100;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreParticipantAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreParticipantAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreParticipantAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,201 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TheatreParticipantAT.java
+ *
+ * Copyright (c) 2003, 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: TheatreParticipantAT.java,v 1.3 2005/02/23 09:58:02 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.theatre;
+
+import com.arjuna.wst.*;
+
+/**
+ * An adapter class that exposes the TheatreManager transaction lifecycle
+ * API as a WS-T Atomic Transaction participant.
+ * Also logs events to a TheatreView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+public class TheatreParticipantAT implements Durable2PCParticipant
+{
+    /**
+     * Participant instances are related to transaction instances
+     * in a one to one manner.
+     *
+     * @param txID uniq id String for the transaction instance.
+     */
+    public TheatreParticipantAT(String txID)
+    {
+        // Binds to the singleton TheatreView and TheatreManager
+        theatreManager = TheatreManager.getSingletonInstance();
+        theatreView = TheatreView.getSingletonInstance();
+        // we need to save the txID for later use when calling
+        // business logic methods in the theatreManger.
+        this.txID = txID;
+    }
+
+    /**
+     * Invokes the prepare step of the business logic,
+     * reporting activity and outcome.
+     *
+     * @return trus on success, false otherwise.
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public Vote prepare() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the prepare operation
+        // on the backend business logic.
+
+        System.out.println("TheatreParticipantAT.prepare");
+
+        theatreView.addPrepareMessage("id:" + txID + ". Prepare called on participant: " + this.getClass().toString());
+
+        boolean success = theatreManager.prepareSeats(txID);
+
+        // Log the outcome and map the return value from
+        // the business logic to the appropriate Vote type.
+
+
+        if (success)
+        {
+            theatreView.addMessage("Theatre prepared successfully. Returning 'Prepared'\n");
+            theatreView.updateFields();
+            return new Prepared();
+        }
+        else
+        {
+            theatreManager.cancelSeats(txID) ;
+            theatreView.addMessage("Prepare failed (not enough seats?) Returning 'Aborted'\n");
+            theatreView.updateFields();
+            return new Aborted();
+        }
+    }
+
+    /**
+     * Invokes the commit step of the business logic,
+     * reporting activity and outcome.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void commit() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the commit operation
+        // on the backend business logic.
+
+        System.out.println("TheatreParticipantAT.commit");
+
+        theatreView.addMessage("id:" + txID + ". Commit called on participant: " + this.getClass().toString());
+
+        boolean success = theatreManager.commitSeats(txID);
+
+        // Log the outcome
+
+        if (success)
+        {
+            theatreView.addMessage("Theatre tickets committed\n");
+        }
+        else
+        {
+            theatreView.addMessage("Something went wrong (Transaction not registered?)\n");
+        }
+
+        theatreView.updateFields();
+    }
+
+    /**
+     * Invokes the rollback operation on the business logic,
+     * reporting activity and outcome.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void rollback() throws WrongStateException, SystemException
+    {
+        // Log the event and invoke the rollback operation
+        // on the backend business logic.
+
+        System.out.println("TheatreParticipantAT.rollback");
+
+        theatreView.addMessage("id:" + txID + ". Rollback called on participant: " + this.getClass().toString());
+
+        boolean success = theatreManager.cancelSeats(txID);
+
+        // Log the outcome
+
+        if (success)
+        {
+            theatreView.addMessage("Theatre booking cancelled\n");
+        }
+        else
+        {
+            theatreView.addMessage("Something went wrong (Transaction not registered?)\n");
+        }
+
+        theatreView.updateFields();
+    }
+
+    /**
+     * Shortcut method which combines the prepare
+     * and commit steps in a single operation.
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void commitOnePhase() throws WrongStateException, SystemException
+    {
+        prepare();
+        commit();
+    }
+
+    public void unknown() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    public void error() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    /**
+     * Id for the transaction which this participant instance relates to.
+     * Set by the service (via contrtuctor) at enrolment time, this value
+     * is passed to the backend business logic methods.
+     */
+    protected String txID;
+
+    /**
+     * The TheatreView object to log events through.
+     */
+    protected static TheatreView theatreView;
+
+    /**
+     * The TheatreManager to perform business logic operations on.
+     */
+    protected static TheatreManager theatreManager;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreParticipantBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreParticipantBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreParticipantBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,194 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TheatreParticipantBA.java
+ *
+ * Copyright (c) 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: TheatreParticipantBA.java,v 1.3 2004/09/09 15:18:10 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.theatre;
+
+import com.arjuna.wst.*;
+import com.arjuna.ats.arjuna.common.Uid;
+
+/**
+ * An adapter class that exposes the TheatreManager transaction lifecycle
+ * API as a WS-T Business Activity participant.
+ * Also logs events to a TheatreView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+public class TheatreParticipantBA implements BusinessAgreementWithParticipantCompletionParticipant
+{
+    /**
+     * Participant instances are related to business method calls
+     * in a one to one manner.
+     *
+     * @param txID       uniq id String for the transaction instance.
+     * @param how_many   seats to book/compensate.
+     * @param which_area of the theatre the seats are in.
+     */
+    public TheatreParticipantBA(String txID, int how_many, int which_area)
+    {
+        // Binds to the singleton TheatreView and TheatreManager
+        theatreManager = TheatreManager.getSingletonInstance();
+        theatreView = TheatreView.getSingletonInstance();
+        // we need to save the txID for later use when logging
+        this.txID = txID;
+        // we also need the business paramater(s) in case of compensation
+        this.seatCount = how_many;
+        this.seatingArea = which_area;
+    }
+
+    /**
+     * The transaction has completed successfully. The participant previously
+     * informed the coordinator that it was ready to complete.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException never in this implementation.
+     */
+
+    public void close() throws WrongStateException, SystemException
+    {
+        // for logging only. This impl does not do anything else here.
+
+        System.out.println("TheatreParticipantBA.close");
+
+        theatreView.addMessage("id:" + txID + ". Close called on participant: " + this.getClass());
+        theatreView.updateFields();
+    }
+
+    /**
+     * The transaction has cancelled, and the participant should undo any work.
+     * The participant cannot have informed the coordinator that it has
+     * completed.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException never in this implementation.
+     */
+
+    public void cancel() throws WrongStateException, SystemException
+    {
+        // we will always have called completed or error, so this can be a null op.
+
+        System.out.println("TheatreParticipantBA.cancel");
+
+        theatreView.addMessage("id:" + txID + ". Cancel called on participant: " + this.getClass().toString());
+        theatreView.updateFields();
+    }
+
+    /**
+     * The transaction has cancelled. The participant previously
+     * informed the coordinator that it had finished work but could compensate
+     * later if required, so it is now requested to do so.
+     *
+     * @throws WrongStateException never in this implementation.
+     * @throws SystemException if unable to perform the compensating transaction.
+     */
+
+    public void compensate() throws WrongStateException, SystemException
+    {
+        System.out.println("TheatreParticipantBA.compensate");
+
+        // Log the event and perform a compensating transaction
+        // on the backend business logic if needed.
+
+        theatreView.addPrepareMessage("id:" + txID + ". Compensate called on participant: " + this.getClass().toString());
+        theatreView.updateFields();
+
+        if (seatCount > 0)
+        {
+            String compensatingTxID = new Uid().toString();
+            // use a negative number of seats to 'reverse' the previous booking
+            // This technique (hack) prevents us needing new business logic to support compensation.
+            theatreManager.bookSeats(compensatingTxID, seatCount * -1, seatingArea);
+            theatreView.updateFields();
+
+            boolean success = false;
+            if(theatreManager.prepareSeats(compensatingTxID))
+            {
+                if (theatreManager.commitSeats(compensatingTxID))
+                {
+                    theatreView.addMessage("id:" + txID + " Compensating transaction completed sucessfully.");
+                    theatreView.updateFields();
+                    success = true;
+                }
+            }
+            else
+            {
+                theatreManager.cancelSeats(compensatingTxID);
+            }
+
+            if(!success)
+            {
+                theatreView.addMessage("id:" + txID + " Compensation failed. Throwing SystemException\n");
+                theatreView.updateFields();
+                throw new SystemException("Compensating transaction failed.");
+            }
+        }
+    }
+    
+    public String status()
+    {
+        return Status.STATUS_ACTIVE ;
+    }
+
+    public void unknown() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    public void error() throws SystemException
+    {
+        // used for calbacks during crash recovery. This impl is not recoverable
+    }
+
+    /**
+     * Id for the transaction which this participant instance relates to.
+     * Set by the service (via contrtuctor) at enrolment time, this value
+     * is used in informational log messages.
+     */
+    protected String txID;
+
+    /**
+     * Copy of business state information, may be needed during compensation.
+     */
+    protected int seatCount;
+
+    /**
+     * Copy of business state information, may be needed during compensation.
+     */
+    protected int seatingArea;
+
+    /**
+     * The TheatreView object to log events through.
+     */
+    protected static TheatreView theatreView;
+
+    /**
+     * The TheatreManager to perform business logic operations on.
+     */
+    protected static TheatreManager theatreManager;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreServiceAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreServiceAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreServiceAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,106 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TheatreServiceAT.java
+ *
+ * Copyright (c) 2003, 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: TheatreServiceAT.java,v 1.3 2004/12/01 16:27:21 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.theatre;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst.TransactionManagerFactory;
+import com.arjuna.mw.wst.UserTransactionFactory;
+import com.jboss.jbosstm.xts.demo.theatre.ITheatreServiceAT;
+
+import javax.jws.WebService;
+import javax.jws.WebParam;
+import javax.jws.HandlerChain;
+import javax.jws.WebMethod;
+import javax.jws.soap.SOAPBinding;
+
+/**
+ * An adapter class that exposes the TheatreManager business API as a
+ * transactional Web Service. Also logs events to a TheatreView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+ at WebService(serviceName="TheatreServiceATService", portName="TheatreServiceAT",
+        name = "ITheatreServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Theatre",
+        wsdlLocation = "/WEB-INF/wsdl/TheatreServiceAT.wsdl")
+ at HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")
+ at SOAPBinding(style=SOAPBinding.Style.RPC)
+public class TheatreServiceAT implements ITheatreServiceAT
+{
+    /**
+     * Book a number of seats in the Theatre
+     * Enrols a Participant if necessary, then passes
+     * the call through to the business logic.
+     *
+     * @param how_many   The number of seats to book
+     * @param which_area The area of the theatre to book seats in
+     */
+    @WebMethod
+    public void bookSeats(
+        @WebParam(name = "how_many", partName = "how_many")
+        int how_many,
+        @WebParam(name = "which_area", partName = "which_area")
+        int which_area)
+    {
+        TheatreView theatreView = TheatreView.getSingletonInstance();
+        TheatreManager theatreManager = TheatreManager.getSingletonInstance();
+
+        String transactionId = null;
+        try
+        {
+            // get the transaction context of this thread:
+            transactionId = UserTransactionFactory.userTransaction().toString();
+            System.out.println("TheatreServiceAT transaction id =" + transactionId);
+
+            if (!theatreManager.knowsAbout(transactionId))
+            {
+                System.out.println("theatreService - enrolling...");
+                // enlist the Participant for this service:
+                TheatreParticipantAT theatreParticipant = new TheatreParticipantAT(transactionId);
+                TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(theatreParticipant, new Uid().toString());
+            }
+        }
+        catch (Exception e)
+        {
+            System.err.println("bookSeats: Participant enrolment failed");
+            e.printStackTrace(System.err);
+            return;
+        }
+
+        theatreView.addMessage("******************************");
+
+        theatreView.addMessage("id:" + transactionId.toString() + ". Received a theatre booking request for " + how_many + " seats in area " + which_area);
+
+        TheatreManager.getSingletonInstance().bookSeats(transactionId, how_many, which_area);
+
+        theatreView.addMessage("Request complete\n");
+        theatreView.updateFields();
+    }
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreServiceBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreServiceBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreServiceBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,147 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TheatreServiceBA.java
+ *
+ * Copyright (c) 2004 Arjuna Technologies Ltd.
+ *
+ * $Id: TheatreServiceBA.java,v 1.5 2004/12/01 16:27:21 kconner Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.theatre;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst.BusinessActivityManagerFactory;
+import com.arjuna.mw.wst.BusinessActivityManager;
+import com.arjuna.wst.BAParticipantManager;
+import com.arjuna.wst.SystemException;
+import com.jboss.jbosstm.xts.demo.theatre.ITheatreServiceBA;
+
+import javax.jws.*;
+import javax.jws.soap.SOAPBinding;
+
+/**
+ * An adapter class that exposes the TheatreManager business API as a
+ * transactional Web Service. Also logs events to a TheatreView object.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.5 $
+ */
+ at WebService(serviceName="TheatreServiceBAService", portName="TheatreServiceBA",
+        name = "ITheatreServiceBA", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Theatre",
+        wsdlLocation = "/WEB-INF/wsdl/TheatreServiceBA.wsdl")
+ at SOAPBinding(style=SOAPBinding.Style.RPC)
+ at HandlerChain(file = "../context-handlers.xml", name = "Context Handlers")
+public class TheatreServiceBA implements ITheatreServiceBA
+{
+    /**
+     * Book a number of seats in the Theatre
+     * Enrols a Participant if necessary, then passes
+     * the call through to the business logic.
+     *
+     * @param how_many   The number of seats to book.
+     * @param which_area The area of the theatre to book seats in.
+     * @return true on success, false otherwise.
+     */
+    @WebMethod
+    @WebResult(name = "bookSeatsBAResponse", partName = "bookSeatsBAResponse")
+    public boolean bookSeats(
+            @WebParam(name = "how_many", partName = "how_many")
+            int how_many,
+            @WebParam(name = "which_area", partName = "which_area")
+            int which_area)
+
+    {
+        TheatreView theatreView = TheatreView.getSingletonInstance();
+        TheatreManager theatreManager = TheatreManager.getSingletonInstance();
+
+        BusinessActivityManager activityManager = BusinessActivityManagerFactory.businessActivityManager();
+
+        // get the transaction context of this thread:
+        String transactionId = null;
+        try
+        {
+            transactionId = activityManager.currentTransaction().toString();
+        }
+        catch (SystemException e)
+        {
+            System.err.println("bookSeats: unable to obtain a transaction context!");
+            e.printStackTrace(System.err);
+            return false;
+        }
+
+        System.out.println("TheatreServiceBA transaction id =" + transactionId);
+
+        theatreView.addMessage("******************************");
+
+        theatreView.addPrepareMessage("id:" + transactionId + ". Received a theatre booking request for " + how_many + " seats in area " + which_area);
+        theatreView.updateFields();
+
+        theatreManager.bookSeats(transactionId, how_many, which_area);
+
+        if (theatreManager.prepareSeats(transactionId))
+        {
+            theatreView.addMessage("id:" + transactionId + ". Seats prepared, trying to commit and enlist compensation Participant");
+            theatreView.updateFields();
+
+            TheatreParticipantBA theatreParticipant = new TheatreParticipantBA(transactionId, how_many, which_area);
+            // enlist the Participant for this service:
+            BAParticipantManager participantManager = null;
+            try
+            {
+                participantManager = activityManager.enlistForBusinessAgreementWithParticipantCompletion(theatreParticipant, new Uid().toString());
+            }
+            catch (Exception e)
+            {
+                theatreView.addMessage("id:" + transactionId + ". Participant enrolement failed");
+                System.err.println("bookSeats: Participant enrolement failed");
+                e.printStackTrace(System.err);
+                return false;
+            }
+
+            theatreManager.commitSeats(transactionId);
+
+            try
+            {
+                participantManager.completed();
+            }
+            catch (Exception e)
+            {
+                System.err.println("bookSeats: 'completed' callback failed");
+                e.printStackTrace(System.err);
+                return false;
+            }
+        }
+        else
+        {
+            theatreView.addMessage("id:" + transactionId + ". Failed to reserve seats. Cancelling.");
+            theatreManager.cancelSeats(transactionId);
+            theatreView.updateFields();
+            return false;
+        }
+
+        theatreView.addMessage("Request complete\n");
+        theatreView.updateFields();
+
+        return true;
+    }
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreView.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreView.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/services/theatre/TheatreView.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,608 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a full listing 
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * TheatreView.java
+ *
+ * Copyright (c) 2003 Arjuna Technologies Ltd.
+ *
+ * $Id: TheatreView.java,v 1.3 2004/04/21 13:09:21 jhalliday Exp $
+ *
+ */
+
+package com.jboss.jbosstm.xts.demo.services.theatre;
+
+/**
+ * The visual interface (GUI) for the Theatre Service.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at arjuna.com)
+ * @version $Revision: 1.3 $
+ */
+public class TheatreView extends javax.swing.JFrame
+{
+
+    // Note: Some parts of this file were auto-generated
+    // by NetBeans 3.3 FormEditor (http://www.netbeans.org)
+
+    /**
+     * Create a new TheatreView instance.
+     *
+     * @param tManager The {@link TheatreManager} instance to bind to
+     */
+    public TheatreView(TheatreManager tManager)
+    {
+        theatreManager = tManager;
+        initComponents();
+        updateFields();
+        backButtonColor = jButtonConfirm.getBackground();
+    }
+
+
+    /**
+     * Initialize the form.
+     * This is called by the constructor
+     * <p/>
+     * WARNING: Automatically generated code, may be overwritten
+     */
+    private void initComponents()
+    {//GEN-BEGIN:initComponents
+        jPanel1 = new javax.swing.JPanel();
+        jLabel1 = new javax.swing.JLabel();
+        jLabel3 = new javax.swing.JLabel();
+        jLabel29 = new javax.swing.JLabel();
+        jLabel30 = new javax.swing.JLabel();
+        jLabel25 = new javax.swing.JLabel();
+        jLabelNBookedSeatsCircle = new javax.swing.JLabel();
+        jLabelNConfirmedSeatsCircle = new javax.swing.JLabel();
+        jLabelNFreeSeatsCircle = new javax.swing.JLabel();
+        jLabel35 = new javax.swing.JLabel();
+        jLabelNBookedSeatsStalls = new javax.swing.JLabel();
+        jLabelNConfirmedSeatsStalls = new javax.swing.JLabel();
+        jLabelNFreeSeatsStalls = new javax.swing.JLabel();
+        jLabel28 = new javax.swing.JLabel();
+        jLabelNBookedSeatsBalcony = new javax.swing.JLabel();
+        jLabelNConfirmedSeatsBalcony = new javax.swing.JLabel();
+        jLabelNFreeSeatsBalcony = new javax.swing.JLabel();
+        jLabel34 = new javax.swing.JLabel();
+        jButtonResetFields = new javax.swing.JButton();
+        jPanel2 = new javax.swing.JPanel();
+        jLabel10 = new javax.swing.JLabel();
+        jLabel13 = new javax.swing.JLabel();
+        jLabel18 = new javax.swing.JLabel();
+        jLabelNTotalSeatsCircle = new javax.swing.JLabel();
+        jLabel19 = new javax.swing.JLabel();
+        jLabelNTotalSeatsStalls = new javax.swing.JLabel();
+        jLabel20 = new javax.swing.JLabel();
+        jLabelNTotalSeatsBalcony = new javax.swing.JLabel();
+        jTextFieldNewNTotalSeats = new javax.swing.JTextField();
+        jButtonSetCircle = new javax.swing.JButton();
+        jButtonSetSalls = new javax.swing.JButton();
+        jButtonSetBalcony = new javax.swing.JButton();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        jTextArea = new javax.swing.JTextArea();
+        jPanelLeft = new javax.swing.JPanel();
+        jLabel15 = new javax.swing.JLabel();
+        jLabelDisplayMode = new javax.swing.JLabel();
+        jButtonChangeMode = new javax.swing.JButton();
+        jLabelResponse = new javax.swing.JLabel();
+        jButtonConfirm = new javax.swing.JButton();
+        jButtonCancel = new javax.swing.JButton();
+
+        setTitle("Theatre Service");
+        addWindowListener(new java.awt.event.WindowAdapter()
+        {
+            public void windowClosing(java.awt.event.WindowEvent evt)
+            {
+                exitForm(evt);
+            }
+        });
+
+        jPanel1.setBorder(new javax.swing.border.LineBorder(java.awt.Color.black));
+        jLabel1.setText("SEATS");
+        jLabel1.setForeground(java.awt.Color.darkGray);
+        jLabel1.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel1.add(jLabel1);
+
+        jLabel3.setText("(booked, ");
+        jLabel3.setForeground(java.awt.Color.gray);
+        jPanel1.add(jLabel3);
+
+        jLabel29.setText("confirmed, ");
+        jLabel29.setForeground(new java.awt.Color(0, 51, 204));
+        jPanel1.add(jLabel29);
+
+        jLabel30.setText("free)       ");
+        jLabel30.setForeground(new java.awt.Color(0, 153, 0));
+        jPanel1.add(jLabel30);
+
+        jLabel25.setText("Circle (");
+        jLabel25.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel1.add(jLabel25);
+
+        jLabelNBookedSeatsCircle.setText(Integer.toString(theatreManager.getNBookedSeats(theatreManager.CIRCLE)));
+        jLabelNBookedSeatsCircle.setForeground(java.awt.Color.gray);
+        jLabelNBookedSeatsCircle.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNBookedSeatsCircle);
+
+        jLabelNConfirmedSeatsCircle.setText(Integer.toString(theatreManager.getNCommittedSeats(theatreManager.CIRCLE)));
+        jLabelNConfirmedSeatsCircle.setForeground(new java.awt.Color(0, 51, 204));
+        jLabelNConfirmedSeatsCircle.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNConfirmedSeatsCircle);
+
+        jLabelNFreeSeatsCircle.setText(Integer.toString(theatreManager.getNFreeSeats(theatreManager.CIRCLE)));
+        jLabelNFreeSeatsCircle.setForeground(new java.awt.Color(0, 153, 0));
+        jLabelNFreeSeatsCircle.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNFreeSeatsCircle);
+
+        jLabel35.setText("),  Stalls (");
+        jLabel35.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel1.add(jLabel35);
+
+        jLabelNBookedSeatsStalls.setText(Integer.toString(theatreManager.getNBookedSeats(theatreManager.STALLS)));
+        jLabelNBookedSeatsStalls.setForeground(java.awt.Color.gray);
+        jLabelNBookedSeatsStalls.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNBookedSeatsStalls);
+
+        jLabelNConfirmedSeatsStalls.setText(Integer.toString(theatreManager.getNCommittedSeats(theatreManager.STALLS)));
+        jLabelNConfirmedSeatsStalls.setForeground(new java.awt.Color(0, 51, 204));
+        jLabelNConfirmedSeatsStalls.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNConfirmedSeatsStalls);
+
+        jLabelNFreeSeatsStalls.setText(Integer.toString(theatreManager.getNFreeSeats(theatreManager.STALLS)));
+        jLabelNFreeSeatsStalls.setForeground(new java.awt.Color(0, 153, 0));
+        jLabelNFreeSeatsStalls.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNFreeSeatsStalls);
+
+        jLabel28.setText("),  Balcony (");
+        jLabel28.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel1.add(jLabel28);
+
+        jLabelNBookedSeatsBalcony.setText(Integer.toString(theatreManager.getNBookedSeats(theatreManager.BALCONY)));
+        jLabelNBookedSeatsBalcony.setForeground(java.awt.Color.gray);
+        jLabelNBookedSeatsBalcony.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNBookedSeatsBalcony);
+
+        jLabelNConfirmedSeatsBalcony.setText(Integer.toString(theatreManager.getNCommittedSeats(theatreManager.BALCONY)));
+        jLabelNConfirmedSeatsBalcony.setForeground(new java.awt.Color(51, 0, 204));
+        jLabelNConfirmedSeatsBalcony.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNConfirmedSeatsBalcony);
+
+        jLabelNFreeSeatsBalcony.setText(Integer.toString(theatreManager.getNFreeSeats(theatreManager.BALCONY)));
+        jLabelNFreeSeatsBalcony.setForeground(new java.awt.Color(0, 153, 0));
+        jLabelNFreeSeatsBalcony.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel1.add(jLabelNFreeSeatsBalcony);
+
+        jLabel34.setText(")     ");
+        jLabel34.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel1.add(jLabel34);
+
+        jButtonResetFields.setText("Reset Fields");
+        jButtonResetFields.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonResetFieldsActionPerformed(evt);
+            }
+        });
+
+        jPanel1.add(jButtonResetFields);
+
+        getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH);
+
+        jPanel2.setBorder(new javax.swing.border.LineBorder(java.awt.Color.black));
+        jLabel10.setText("Theatre      ");
+        jLabel10.setForeground(java.awt.Color.red);
+        jLabel10.setFont(new java.awt.Font("Dialog", 1, 24));
+        jPanel2.add(jLabel10);
+
+        jLabel13.setText("TOTAL SEATS   ");
+        jLabel13.setForeground(java.awt.Color.darkGray);
+        jLabel13.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel2.add(jLabel13);
+
+        jLabel18.setText("Circle:");
+        jLabel18.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel2.add(jLabel18);
+
+        jLabelNTotalSeatsCircle.setText(Integer.toString(theatreManager.getNTotalSeats(theatreManager.CIRCLE)));
+        jLabelNTotalSeatsCircle.setForeground(java.awt.Color.darkGray);
+        jLabelNTotalSeatsCircle.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel2.add(jLabelNTotalSeatsCircle);
+
+        jLabel19.setText("Stalls:");
+        jLabel19.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel2.add(jLabel19);
+
+        jLabelNTotalSeatsStalls.setText(Integer.toString(theatreManager.getNTotalSeats(theatreManager.STALLS)));
+        jLabelNTotalSeatsStalls.setForeground(java.awt.Color.darkGray);
+        jLabelNTotalSeatsStalls.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel2.add(jLabelNTotalSeatsStalls);
+
+        jLabel20.setText("Balcony:");
+        jLabel20.setFont(new java.awt.Font("Dialog", 1, 14));
+        jPanel2.add(jLabel20);
+
+        jLabelNTotalSeatsBalcony.setText(Integer.toString(theatreManager.getNTotalSeats(theatreManager.BALCONY)));
+        jLabelNTotalSeatsBalcony.setForeground(java.awt.Color.darkGray);
+        jLabelNTotalSeatsBalcony.setFont(new java.awt.Font("Dialog", 0, 14));
+        jPanel2.add(jLabelNTotalSeatsBalcony);
+
+        jTextFieldNewNTotalSeats.setFont(new java.awt.Font("Dialog", 0, 18));
+        jTextFieldNewNTotalSeats.setText(Integer.toString(theatreManager.getNTotalSeats(theatreManager.CIRCLE)));
+        jPanel2.add(jTextFieldNewNTotalSeats);
+
+        jButtonSetCircle.setFont(new java.awt.Font("Dialog", 0, 14));
+        jButtonSetCircle.setText("Set Circle");
+        jButtonSetCircle.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonSetCircleActionPerformed(evt);
+            }
+        });
+
+        jPanel2.add(jButtonSetCircle);
+
+        jButtonSetSalls.setFont(new java.awt.Font("Dialog", 0, 14));
+        jButtonSetSalls.setText(" Set Stalls");
+        jButtonSetSalls.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonSetSallsActionPerformed(evt);
+            }
+        });
+
+        jPanel2.add(jButtonSetSalls);
+
+        jButtonSetBalcony.setFont(new java.awt.Font("Dialog", 0, 14));
+        jButtonSetBalcony.setText("Set Balcony");
+        jButtonSetBalcony.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonSetBalconyActionPerformed(evt);
+            }
+        });
+
+        jPanel2.add(jButtonSetBalcony);
+
+        getContentPane().add(jPanel2, java.awt.BorderLayout.NORTH);
+
+        jScrollPane1.setAutoscrolls(true);
+        jTextArea.setEditable(false);
+        jTextArea.setRows(10);
+        jTextArea.setMargin(new java.awt.Insets(5, 5, 5, 5));
+        jScrollPane1.setViewportView(jTextArea);
+
+        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
+
+        jPanelLeft.setLayout(new javax.swing.BoxLayout(jPanelLeft, javax.swing.BoxLayout.Y_AXIS));
+
+        jLabel15.setText("Mode:");
+        jPanelLeft.add(jLabel15);
+
+        jLabelDisplayMode.setText("Automatic");
+        jLabelDisplayMode.setForeground(java.awt.Color.blue);
+        jLabelDisplayMode.setFont(new java.awt.Font("Dialog", 1, 18));
+        jPanelLeft.add(jLabelDisplayMode);
+
+        jButtonChangeMode.setText("Change mode");
+        jButtonChangeMode.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonChangeMode.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonChangeMode.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonChangeModeActionPerformed(evt);
+            }
+        });
+
+        jPanelLeft.add(jButtonChangeMode);
+
+        jLabelResponse.setText("Response:");
+        jPanelLeft.add(jLabelResponse);
+
+        jButtonConfirm.setText("Confirm");
+        jButtonConfirm.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonConfirm.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonConfirm.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonConfirmActionPerformed(evt);
+            }
+        });
+
+        jPanelLeft.add(jButtonConfirm);
+
+        jButtonCancel.setText("Cancel");
+        jButtonCancel.setPreferredSize(new java.awt.Dimension(119, 27));
+        jButtonCancel.setMaximumSize(new java.awt.Dimension(119, 27));
+        jButtonCancel.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                jButtonCancelActionPerformed(evt);
+            }
+        });
+
+        jPanelLeft.add(jButtonCancel);
+
+        getContentPane().add(jPanelLeft, java.awt.BorderLayout.WEST);
+
+        pack();
+    }//GEN-END:initComponents
+
+    /**
+     * Reset event handler.
+     */
+    private void jButtonResetFieldsActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonResetFieldsActionPerformed
+        theatreManager.setToDefault();
+        updateFields();
+    }//GEN-LAST:event_jButtonResetFieldsActionPerformed
+
+    /**
+     * Cancel event handler.
+     */
+    private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonCancelActionPerformed
+        if (theatreManager.getIsPreparationWaiting())
+        {
+            Object preparation = theatreManager.getPreparation();
+            try
+            {
+                theatreManager.setCommit(false);
+                synchronized (preparation)
+                {
+                    preparation.notify();
+                }
+            }
+            catch (Exception e)
+            {
+                System.err.println("TheatreView.jButtonCancelActionPerformed(): Unable to notify preparation.");
+            }
+        }
+    }//GEN-LAST:event_jButtonCancelActionPerformed
+
+    /**
+     * Confirm event handler.
+     */
+    private void jButtonConfirmActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonConfirmActionPerformed
+        if (theatreManager.getIsPreparationWaiting())
+        {
+            Object preparation = theatreManager.getPreparation();
+            try
+            {
+                theatreManager.setCommit(true);
+                synchronized (preparation)
+                {
+                    preparation.notify();
+                }
+            }
+            catch (Exception e)
+            {
+                System.err.println("TheatreView.jButtonCancelActionPerformed(): Unable to notify preparation.");
+            }
+        }
+    }//GEN-LAST:event_jButtonConfirmActionPerformed
+
+    /**
+     * ChangeMode event handler.
+     */
+    private void jButtonChangeModeActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonChangeModeActionPerformed
+        if (theatreManager.isAutoCommitMode())
+            theatreManager.setAutoCommitMode(false);
+        else
+            theatreManager.setAutoCommitMode(true);
+        updateFields();
+    }//GEN-LAST:event_jButtonChangeModeActionPerformed
+
+    /**
+     * Seat reservation event handler.
+     */
+    private void jButtonSetCircleActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonSetCircleActionPerformed
+        String strNSeats = jTextFieldNewNTotalSeats.getText();
+
+        theatreManager.newCapacity(theatreManager.CIRCLE, Integer.parseInt(strNSeats));
+        int nFreeSeats = theatreManager.getNFreeSeats(theatreManager.CIRCLE);
+
+        jLabelNTotalSeatsCircle.setText(strNSeats);
+        jLabelNFreeSeatsCircle.setText(Integer.toString(nFreeSeats));
+    }//GEN-LAST:event_jButtonSetCircleActionPerformed
+
+    /**
+     * Seat reservation event handler.
+     */
+    private void jButtonSetSallsActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonSetSallsActionPerformed
+        String strNSeats = jTextFieldNewNTotalSeats.getText();
+
+        theatreManager.newCapacity(theatreManager.STALLS, Integer.parseInt(strNSeats));
+        int nFreeSeats = theatreManager.getNFreeSeats(theatreManager.STALLS);
+
+        jLabelNTotalSeatsStalls.setText(strNSeats);
+        jLabelNFreeSeatsStalls.setText(Integer.toString(nFreeSeats));
+    }//GEN-LAST:event_jButtonSetSallsActionPerformed
+
+    /**
+     * Seat reservation event handler.
+     */
+    private void jButtonSetBalconyActionPerformed(java.awt.event.ActionEvent evt)
+    {//GEN-FIRST:event_jButtonSetBalconyActionPerformed
+        String strNSeats = jTextFieldNewNTotalSeats.getText();
+
+        theatreManager.newCapacity(theatreManager.BALCONY, Integer.parseInt(strNSeats));
+        int nFreeSeats = theatreManager.getNFreeSeats(theatreManager.BALCONY);
+
+        jLabelNTotalSeatsBalcony.setText(strNSeats);
+        jLabelNFreeSeatsBalcony.setText(Integer.toString(nFreeSeats));
+    }//GEN-LAST:event_jButtonSetBalconyActionPerformed
+
+    /**
+     * Exit the application.
+     */
+    private void exitForm(java.awt.event.WindowEvent evt)
+    {//GEN-FIRST:event_exitForm
+        //System.exit(0); // disabled for embedding in application servers.
+    }//GEN-LAST:event_exitForm
+
+    /**
+     * Add regular text to the central jTextArea.
+     *
+     * @param text The String to add
+     */
+    public void addMessage(java.lang.String text)
+    {
+        jButtonConfirm.setBackground(backButtonColor);
+        jButtonCancel.setBackground(backButtonColor);
+        jTextArea.append(text + "\n");
+        jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum());
+    }
+
+    /**
+     * Add status (highlighted) text to the central jTextArea.
+     *
+     * @param text The String to add
+     */
+    public void addPrepareMessage(java.lang.String text)
+    {
+        jButtonConfirm.setBackground(java.awt.Color.red);
+        jButtonCancel.setBackground(java.awt.Color.red);
+        jTextArea.append(text + "\n");
+        jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum());
+    }
+
+    /**
+     * Synchronise the GUI with the underlying state.
+     */
+    public void updateFields()
+    {
+        jLabelNTotalSeatsCircle.setText(Integer.toString(theatreManager.getNTotalSeats(theatreManager.CIRCLE)));
+        jLabelNTotalSeatsStalls.setText(Integer.toString(theatreManager.getNTotalSeats(theatreManager.STALLS)));
+        jLabelNTotalSeatsBalcony.setText(Integer.toString(theatreManager.getNTotalSeats(theatreManager.BALCONY)));
+        jTextFieldNewNTotalSeats.setText(jLabelNTotalSeatsCircle.getText());
+        jLabelNBookedSeatsCircle.setText(Integer.toString(theatreManager.getNBookedSeats(theatreManager.CIRCLE)));
+        jLabelNBookedSeatsStalls.setText(Integer.toString(theatreManager.getNBookedSeats(theatreManager.STALLS)));
+        jLabelNBookedSeatsBalcony.setText(Integer.toString(theatreManager.getNBookedSeats(theatreManager.BALCONY)));
+        jLabelNConfirmedSeatsCircle.setText(Integer.toString(theatreManager.getNCommittedSeats(theatreManager.CIRCLE)));
+        jLabelNConfirmedSeatsStalls.setText(Integer.toString(theatreManager.getNCommittedSeats(theatreManager.STALLS)));
+        jLabelNConfirmedSeatsBalcony.setText(Integer.toString(theatreManager.getNCommittedSeats(theatreManager.BALCONY)));
+        jLabelNFreeSeatsCircle.setText(Integer.toString(theatreManager.getNFreeSeats(theatreManager.CIRCLE)));
+        jLabelNFreeSeatsStalls.setText(Integer.toString(theatreManager.getNFreeSeats(theatreManager.STALLS)));
+        jLabelNFreeSeatsBalcony.setText(Integer.toString(theatreManager.getNFreeSeats(theatreManager.BALCONY)));
+
+
+        //update fields related to interactive mode
+        if (theatreManager.isAutoCommitMode())
+        {
+            jLabelResponse.setVisible(false);
+            jButtonConfirm.setVisible(false);
+            jButtonCancel.setVisible(false);
+            jLabelDisplayMode.setText("automatic");
+        }
+        else
+        {
+            jLabelResponse.setVisible(true);
+            jButtonConfirm.setVisible(true);
+            jButtonCancel.setVisible(true);
+            jLabelDisplayMode.setText("interactive");
+        }
+    }
+
+    /**
+     * Allow use of a singleton model for web services demo.
+     */
+    public static TheatreView getSingletonInstance()
+    {
+        if (singletonInstance == null)
+        {
+            singletonInstance = new TheatreView(TheatreManager.getSingletonInstance());
+        }
+
+        singletonInstance.show();
+        return singletonInstance;
+    }
+
+    /**
+     * A singleton instance of this class.
+     */
+    private static TheatreView singletonInstance;
+
+    // Variables declaration - automatically generated - do not modify
+
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel3;
+    private javax.swing.JLabel jLabel29;
+    private javax.swing.JLabel jLabel30;
+    private javax.swing.JLabel jLabel25;
+    private javax.swing.JLabel jLabelNBookedSeatsCircle;
+    private javax.swing.JLabel jLabelNConfirmedSeatsCircle;
+    private javax.swing.JLabel jLabelNFreeSeatsCircle;
+    private javax.swing.JLabel jLabel35;
+    private javax.swing.JLabel jLabelNBookedSeatsStalls;
+    private javax.swing.JLabel jLabelNConfirmedSeatsStalls;
+    private javax.swing.JLabel jLabelNFreeSeatsStalls;
+    private javax.swing.JLabel jLabel28;
+    private javax.swing.JLabel jLabelNBookedSeatsBalcony;
+    private javax.swing.JLabel jLabelNConfirmedSeatsBalcony;
+    private javax.swing.JLabel jLabelNFreeSeatsBalcony;
+    private javax.swing.JLabel jLabel34;
+    private javax.swing.JButton jButtonResetFields;
+    private javax.swing.JPanel jPanel2;
+    private javax.swing.JLabel jLabel10;
+    private javax.swing.JLabel jLabel13;
+    private javax.swing.JLabel jLabel18;
+    private javax.swing.JLabel jLabelNTotalSeatsCircle;
+    private javax.swing.JLabel jLabel19;
+    private javax.swing.JLabel jLabelNTotalSeatsStalls;
+    private javax.swing.JLabel jLabel20;
+    private javax.swing.JLabel jLabelNTotalSeatsBalcony;
+    private javax.swing.JTextField jTextFieldNewNTotalSeats;
+    private javax.swing.JButton jButtonSetCircle;
+    private javax.swing.JButton jButtonSetSalls;
+    private javax.swing.JButton jButtonSetBalcony;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JTextArea jTextArea;
+    private javax.swing.JPanel jPanelLeft;
+    private javax.swing.JLabel jLabel15;
+    private javax.swing.JLabel jLabelDisplayMode;
+    private javax.swing.JButton jButtonChangeMode;
+    private javax.swing.JLabel jLabelResponse;
+    private javax.swing.JButton jButtonConfirm;
+    private javax.swing.JButton jButtonCancel;
+
+    // End of automatically generated variables declarations
+
+    /**
+     * The  {@link TheatreManager} instance this view is bound to.
+     */
+    private TheatreManager theatreManager;
+
+    /**
+     * The current color of the back button.
+     */
+    private java.awt.Color backButtonColor;
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/ITaxiServiceAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/ITaxiServiceAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/ITaxiServiceAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,26 @@
+
+package com.jboss.jbosstm.xts.demo.taxi;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebService(name = "ITaxiServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Taxi")
+ at SOAPBinding(style = SOAPBinding.Style.RPC)
+public interface ITaxiServiceAT {
+
+
+    /**
+     * 
+     */
+    @WebMethod
+    public void bookTaxi();
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/ITaxiServiceBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/ITaxiServiceBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/ITaxiServiceBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,30 @@
+
+package com.jboss.jbosstm.xts.demo.taxi;
+
+import javax.jws.WebMethod;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebService(name = "ITaxiServiceBA", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Taxi")
+ at SOAPBinding(style = SOAPBinding.Style.RPC)
+public interface ITaxiServiceBA {
+
+
+    /**
+     * 
+     * @return
+     *     returns boolean
+     */
+    @WebMethod
+    @WebResult(name = "bookTaxiBAResponse", partName = "bookTaxiBAResponse")
+    public boolean bookTaxi();
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/TaxiServiceATService.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/TaxiServiceATService.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/TaxiServiceATService.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,58 @@
+
+package com.jboss.jbosstm.xts.demo.taxi;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.logging.Logger;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebEndpoint;
+import javax.xml.ws.WebServiceClient;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebServiceClient(name = "TaxiServiceATService", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Taxi", wsdlLocation = "/WEB-INF/wsdl/TaxiServiceAT.wsdl")
+public class TaxiServiceATService
+    extends Service
+{
+
+    private final static URL TAXISERVICEATSERVICE_WSDL_LOCATION;
+    private final static Logger logger = Logger.getLogger(com.jboss.jbosstm.xts.demo.taxi.TaxiServiceATService.class.getName());
+
+    static {
+        URL url = null;
+        try {
+            URL baseUrl;
+            baseUrl = com.jboss.jbosstm.xts.demo.taxi.TaxiServiceATService.class.getResource(".");
+            url = new URL(baseUrl, "/WEB-INF/wsdl/TaxiServiceAT.wsdl");
+        } catch (MalformedURLException e) {
+            logger.warning("Failed to create URL for the wsdl Location: '/WEB-INF/wsdl/TaxiServiceAT.wsdl', retrying as a local file");
+            logger.warning(e.getMessage());
+        }
+        TAXISERVICEATSERVICE_WSDL_LOCATION = url;
+    }
+
+    public TaxiServiceATService(URL wsdlLocation, QName serviceName) {
+        super(wsdlLocation, serviceName);
+    }
+
+    public TaxiServiceATService() {
+        super(TAXISERVICEATSERVICE_WSDL_LOCATION, new QName("http://www.jboss.com/jbosstm/xts/demo/Taxi", "TaxiServiceATService"));
+    }
+
+    /**
+     * 
+     * @return
+     *     returns ITaxiServiceAT
+     */
+    @WebEndpoint(name = "TaxiServiceAT")
+    public ITaxiServiceAT getTaxiServiceAT() {
+        return super.getPort(new QName("http://www.jboss.com/jbosstm/xts/demo/Taxi", "TaxiServiceAT"), ITaxiServiceAT.class);
+    }
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/TaxiServiceBAService.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/TaxiServiceBAService.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/taxi/TaxiServiceBAService.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,58 @@
+
+package com.jboss.jbosstm.xts.demo.taxi;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.logging.Logger;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebEndpoint;
+import javax.xml.ws.WebServiceClient;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebServiceClient(name = "TaxiServiceBAService", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Taxi", wsdlLocation = "/WEB-INF/wsdl/TaxiServiceBA.wsdl")
+public class TaxiServiceBAService
+    extends Service
+{
+
+    private final static URL TAXISERVICEBASERVICE_WSDL_LOCATION;
+    private final static Logger logger = Logger.getLogger(com.jboss.jbosstm.xts.demo.taxi.TaxiServiceBAService.class.getName());
+
+    static {
+        URL url = null;
+        try {
+            URL baseUrl;
+            baseUrl = com.jboss.jbosstm.xts.demo.taxi.TaxiServiceBAService.class.getResource(".");
+            url = new URL(baseUrl, "/WEB-INF/wsdl/TaxiServiceBA.wsdl");
+        } catch (MalformedURLException e) {
+            logger.warning("Failed to create URL for the wsdl Location: '/WEB-INF/wsdl/TaxiServiceBA.wsdl', retrying as a local file");
+            logger.warning(e.getMessage());
+        }
+        TAXISERVICEBASERVICE_WSDL_LOCATION = url;
+    }
+
+    public TaxiServiceBAService(URL wsdlLocation, QName serviceName) {
+        super(wsdlLocation, serviceName);
+    }
+
+    public TaxiServiceBAService() {
+        super(TAXISERVICEBASERVICE_WSDL_LOCATION, new QName("http://www.jboss.com/jbosstm/xts/demo/Taxi", "TaxiServiceBAService"));
+    }
+
+    /**
+     * 
+     * @return
+     *     returns ITaxiServiceBA
+     */
+    @WebEndpoint(name = "TaxiServiceBA")
+    public ITaxiServiceBA getTaxiServiceBA() {
+        return super.getPort(new QName("http://www.jboss.com/jbosstm/xts/demo/Taxi", "TaxiServiceBA"), ITaxiServiceBA.class);
+    }
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/ITheatreServiceAT.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/ITheatreServiceAT.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/ITheatreServiceAT.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,33 @@
+
+package com.jboss.jbosstm.xts.demo.theatre;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebService(name = "ITheatreServiceAT", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Theatre")
+ at SOAPBinding(style = SOAPBinding.Style.RPC)
+public interface ITheatreServiceAT {
+
+
+    /**
+     * 
+     * @param howMany
+     * @param whichArea
+     */
+    @WebMethod
+    public void bookSeats(
+        @WebParam(name = "how_many", partName = "how_many")
+        int howMany,
+        @WebParam(name = "which_area", partName = "which_area")
+        int whichArea);
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/ITheatreServiceBA.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/ITheatreServiceBA.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/ITheatreServiceBA.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,37 @@
+
+package com.jboss.jbosstm.xts.demo.theatre;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebService(name = "ITheatreServiceBA", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Theatre")
+ at SOAPBinding(style = SOAPBinding.Style.RPC)
+public interface ITheatreServiceBA {
+
+
+    /**
+     * 
+     * @param howMany
+     * @param whichArea
+     * @return
+     *     returns boolean
+     */
+    @WebMethod
+    @WebResult(name = "bookSeatsBAResponse", partName = "bookSeatsBAResponse")
+    public boolean bookSeats(
+        @WebParam(name = "how_many", partName = "how_many")
+        int howMany,
+        @WebParam(name = "which_area", partName = "which_area")
+        int whichArea);
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/TheatreServiceATService.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/TheatreServiceATService.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/TheatreServiceATService.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,58 @@
+
+package com.jboss.jbosstm.xts.demo.theatre;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.logging.Logger;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebEndpoint;
+import javax.xml.ws.WebServiceClient;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebServiceClient(name = "TheatreServiceATService", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Theatre", wsdlLocation = "/WEB-INF/wsdl/TheatreServiceAT.wsdl")
+public class TheatreServiceATService
+    extends Service
+{
+
+    private final static URL THEATRESERVICEATSERVICE_WSDL_LOCATION;
+    private final static Logger logger = Logger.getLogger(com.jboss.jbosstm.xts.demo.theatre.TheatreServiceATService.class.getName());
+
+    static {
+        URL url = null;
+        try {
+            URL baseUrl;
+            baseUrl = com.jboss.jbosstm.xts.demo.theatre.TheatreServiceATService.class.getResource(".");
+            url = new URL(baseUrl, "/WEB-INF/wsdl/TheatreServiceAT.wsdl");
+        } catch (MalformedURLException e) {
+            logger.warning("Failed to create URL for the wsdl Location: '/WEB-INF/wsdl/TheatreServiceAT.wsdl', retrying as a local file");
+            logger.warning(e.getMessage());
+        }
+        THEATRESERVICEATSERVICE_WSDL_LOCATION = url;
+    }
+
+    public TheatreServiceATService(URL wsdlLocation, QName serviceName) {
+        super(wsdlLocation, serviceName);
+    }
+
+    public TheatreServiceATService() {
+        super(THEATRESERVICEATSERVICE_WSDL_LOCATION, new QName("http://www.jboss.com/jbosstm/xts/demo/Theatre", "TheatreServiceATService"));
+    }
+
+    /**
+     * 
+     * @return
+     *     returns ITheatreServiceAT
+     */
+    @WebEndpoint(name = "TheatreServiceAT")
+    public ITheatreServiceAT getTheatreServiceAT() {
+        return super.getPort(new QName("http://www.jboss.com/jbosstm/xts/demo/Theatre", "TheatreServiceAT"), ITheatreServiceAT.class);
+    }
+
+}

Added: labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/TheatreServiceBAService.java
===================================================================
--- labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/TheatreServiceBAService.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/demo/src/com/jboss/jbosstm/xts/demo/theatre/TheatreServiceBAService.java	2008-02-25 17:45:07 UTC (rev 18578)
@@ -0,0 +1,58 @@
+
+package com.jboss.jbosstm.xts.demo.theatre;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.logging.Logger;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebEndpoint;
+import javax.xml.ws.WebServiceClient;
+
+
+/**
+ * This class was generated by the JAX-WS RI.
+ * JAX-WS RI 2.1.2-hudson-182-RC1
+ * Generated source version: 2.0
+ * 
+ */
+ at WebServiceClient(name = "TheatreServiceBAService", targetNamespace = "http://www.jboss.com/jbosstm/xts/demo/Theatre", wsdlLocation = "/WEB-INF/wsdl/TheatreServiceBA.wsdl")
+public class TheatreServiceBAService
+    extends Service
+{
+
+    private final static URL THEATRESERVICEBASERVICE_WSDL_LOCATION;
+    private final static Logger logger = Logger.getLogger(com.jboss.jbosstm.xts.demo.theatre.TheatreServiceBAService.class.getName());
+
+    static {
+        URL url = null;
+        try {
+            URL baseUrl;
+            baseUrl = com.jboss.jbosstm.xts.demo.theatre.TheatreServiceBAService.class.getResource(".");
+            url = new URL(baseUrl, "/WEB-INF/wsdl/TheatreServiceBA.wsdl");
+        } catch (MalformedURLException e) {
+            logger.warning("Failed to create URL for the wsdl Location: '/WEB-INF/wsdl/TheatreServiceBA.wsdl', retrying as a local file");
+            logger.warning(e.getMessage());
+        }
+        THEATRESERVICEBASERVICE_WSDL_LOCATION = url;
+    }
+
+    public TheatreServiceBAService(URL wsdlLocation, QName serviceName) {
+        super(wsdlLocation, serviceName);
+    }
+
+    public TheatreServiceBAService() {
+        super(THEATRESERVICEBASERVICE_WSDL_LOCATION, new QName("http://www.jboss.com/jbosstm/xts/demo/Theatre", "TheatreServiceBAService"));
+    }
+
+    /**
+     * 
+     * @return
+     *     returns ITheatreServiceBA
+     */
+    @WebEndpoint(name = "TheatreServiceBA")
+    public ITheatreServiceBA getTheatreServiceBA() {
+        return super.getPort(new QName("http://www.jboss.com/jbosstm/xts/demo/Theatre", "TheatreServiceBA"), ITheatreServiceBA.class);
+    }
+
+}




More information about the jboss-svn-commits mailing list