[jboss-svn-commits] JBL Code SVN: r31494 - in labs/jbosstm/trunk/ArjunaCore: arjuna/classes/com/arjuna/ats/arjuna/tools and 8 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Feb 8 14:29:18 EST 2010


Author: mark.little at jboss.com
Date: 2010-02-08 14:29:18 -0500 (Mon, 08 Feb 2010)
New Revision: 31494

Added:
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/LogBrowser.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/LogEditor.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/EditableAtomicAction.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/EditableTransaction.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/LogEditorUnitTest.java
Modified:
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/resources/CrashRecord.java
   labs/jbosstm/trunk/ArjunaCore/docs/user_guide/ProgrammersGuide.odt
Log:
https://jira.jboss.org/jira/browse/JBTM-699

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java	2010-02-08 14:39:50 UTC (rev 31493)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java	2010-02-08 19:29:18 UTC (rev 31494)
@@ -2873,8 +2873,17 @@
 	protected final synchronized int getHeuristicDecision ()
 	{
 		return heuristicDecision;
-	}
+	}	
 
+        /**
+         * WARNING: use with extreme care!
+         */
+        
+        protected final synchronized void setHeuristicDecision (int p)
+        {
+            heuristicDecision = p;
+        }
+
 	/**
 	 * Add the specified abstract record to the transaction. Does not do any of
 	 * the runtime checking of BasicAction.add, so should be used with care.

Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/LogBrowser.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/LogBrowser.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/LogBrowser.java	2010-02-08 19:29:18 UTC (rev 31494)
@@ -0,0 +1,415 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+
+package com.arjuna.ats.arjuna.tools.log;
+
+import java.io.IOException;
+
+import com.arjuna.ats.arjuna.AtomicAction;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.TxControl;
+import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+import com.arjuna.ats.arjuna.objectstore.ObjectStoreIterator;
+import com.arjuna.ats.arjuna.state.InputObjectState;
+import com.arjuna.ats.internal.arjuna.common.UidHelper;
+import com.arjuna.ats.internal.arjuna.tools.log.EditableAtomicAction;
+
+/**
+ * Commands:
+ * 
+ * ls <type> - list logs for specified type. If no type specified then
+ * must be already attached.
+ * select [<type] - browse a specific type of transaction. Automatically detaches.
+ * attach <log> - cannot be attached to another log
+ * detach - must be attached to log 
+ * forget <pid> - must be attached to log
+ * delete <pid> - must be attached to log 
+ * types - lists supported transaction types
+ * quit - exit
+ * help - help
+ * 
+ * @author marklittle
+ */
+
+/*
+ * WARNING: this currently only supports AtomicActions.
+ * TODO make it support all other transaction types!
+ */
+
+class LogConsole
+{
+    public static final int MAX_COMMAND_LEN = 1024; // bytes
+    public static final String DEFAULT_TYPE = new AtomicAction().type();
+
+    private enum Command
+    {
+        invalid, ls, attach, detach, forget, delete, quit, select, types, help
+    };
+
+    public static final String ls = "ls";
+    public static final String attach = "attach";
+    public static final String detach = "detach";
+    public static final String forget = "forget";
+    public static final String delete = "delete";
+    public static final String quit = "quit";
+    public static final String select = "select";
+    public static final String types = "types";
+    public static final String help = "help";
+    
+    private static final String SPACE = " ";
+    private static final String END = "\n";
+    
+    public void doWork ()
+    {
+        boolean attached = false;  // move these to member variables
+        boolean exit = false;
+        boolean selected = false;
+
+        while (!exit)
+        {
+            byte[] command = new byte[MAX_COMMAND_LEN];
+            
+            try
+            {
+                System.out.print("\n"+_transactionType+" - "+_currentLog+ " > ");
+
+                System.in.read(command);
+
+                String commandString = new String(command);
+
+                Command com = validCommand(commandString);
+
+                switch (com)
+                {
+                case quit:
+                    return;
+                case help:
+                    help();
+                    break;
+                case ls:
+                    if (!selected)
+                        System.err.println("No transaction type selected.");
+                    else
+                    {
+                        if (_currentLog == "")
+                            listLogs(_transactionType);
+                        else
+                            dumpLog(new Uid(_currentLog));
+                    }
+
+                    System.out.println();
+                    
+                    break;
+                case select:
+                    if (attached)
+                    {
+                        System.out.println("Detaching from existing log.");
+                        
+                        attached = false;
+                    }
+
+                    setTransactionType(commandString);
+                    
+                    if ("".equals(_transactionType))
+                    {
+                        System.err.println("Unsupported type.");
+                        
+                        selected = false;
+                    }
+                    else
+                        selected = true;
+                    
+                    break;
+                case attach:
+                    if (attached)
+                        System.err.println("Already attached.");
+                    else
+                    {
+                        setLogId(commandString);
+                        
+                        if ("".equals(_currentLog))
+                        {
+                            System.err.println("Invalid log id.");
+                        }
+                        else
+                            attached = true;
+                    }
+                    break;
+                case detach:
+                    if (!attached)
+                        System.err.println("Not attached.");
+                    
+                    _currentLog = "";
+                    
+                    attached = false;
+                    break;
+                case forget:
+                    if (!attached)
+                        System.err.println("Not attached.");
+                    
+                    Uid u = new Uid(_currentLog);
+                    EditableAtomicAction act = new EditableAtomicAction(u);
+                    
+                    try
+                    {
+                        act.moveHeuristicToPrepared(getIndex(commandString));
+                    }
+                    catch (final IndexOutOfBoundsException ex)
+                    {
+                        System.err.println("Invalid index.");
+                    }
+
+                    dumpLog(u);
+                    break;
+                case delete:
+                    if (!attached)
+                        System.err.println("Not attached.");
+                    
+                    Uid uid = new Uid(_currentLog);
+                    EditableAtomicAction ract = new EditableAtomicAction(uid);
+                    
+                    try
+                    {
+                        ract.deleteHeuristicParticipant(getIndex(commandString));
+                    }
+                    catch (final IndexOutOfBoundsException ex)
+                    {
+                        System.err.println("Invalid index.");
+                    }
+                    
+                    dumpLog(uid);
+                    
+                    break;
+                case types:
+                    printSupportedTypes();
+                    break;
+                default:
+                    System.err
+                            .println("Invalid command " + new String(command));
+                    break;
+                }
+            }
+            catch (final Exception ex)
+            {
+                ex.printStackTrace();
+            }
+        }
+    }
+    
+    private void dumpLog (final Uid u)
+    {
+        EditableAtomicAction act = new EditableAtomicAction(u);
+        
+        System.out.println(act.toString());
+    }
+
+    // should accept AtomicAction instead of /StateManager/../AtomicAction
+    
+    private boolean supportedType (String type)  // need more supported types!
+    {
+        if (DEFAULT_TYPE.endsWith(type))
+            return true;
+        else
+            return false;
+    }
+    
+    private void printSupportedTypes ()
+    {
+        System.out.println(DEFAULT_TYPE);
+    }
+    
+    private final Command validCommand (String command)
+    {
+        if (command == null)
+            return Command.invalid;
+
+        if (!command.startsWith(ls))
+        {
+            if (!command.startsWith(attach))
+            {
+                if (!command.startsWith(detach))
+                {
+                    if (!command.startsWith(forget))
+                    {
+                        if (!command.startsWith(delete))
+                        {
+                            if (!command.startsWith(quit))
+                            {
+                                if (!command.startsWith(select))
+                                {
+                                    if (!command.startsWith(types))
+                                    {
+                                        if (!command.startsWith(help))
+                                            return Command.invalid;
+                                        else
+                                            return Command.help;
+                                    }
+                                    else
+                                        return Command.types;
+                                }
+                                else
+                                    return Command.select;
+                            }
+                            else
+                                return Command.quit;
+                        }
+                        else
+                            return Command.delete;
+                    }
+                    else
+                        return Command.forget;
+                }
+                else
+                    return Command.detach;
+            }
+            else
+                return Command.attach;
+        }
+        else
+            return Command.ls;
+    }
+
+    private final void setTransactionType (String command)
+    {
+        int index = command.indexOf(SPACE);
+        int end = command.indexOf(END);
+        
+        if (index != -1)
+            _transactionType = new String(command.substring(index + 1, end).trim());
+        else
+            _transactionType = DEFAULT_TYPE;
+        
+        if (!supportedType(_transactionType))
+            _transactionType = "";
+    }
+    
+    private final void setLogId (String command)
+    {
+        int index = command.indexOf(SPACE);
+        int end = command.indexOf(END);
+        
+        if (index != -1)
+        {
+            _currentLog = new String(command.substring(index + 1, end).trim());
+
+            if (!supportedLog(_currentLog))
+                _currentLog = "";
+        }
+        else
+            _currentLog = "";
+    }
+    
+    private final int getIndex (String command)
+    {
+        int index = command.indexOf(SPACE);
+        int end = command.indexOf(END);
+        
+        if (index != -1)
+        {
+            try
+            {
+                return Integer.parseInt(command.substring(index+1, end).trim());
+            }
+            catch (final Exception ex)
+            {
+                return -1;
+            }
+        }
+        else
+            return -1;
+    }
+
+    private final void listLogs (String type) throws IOException
+    {
+        InputObjectState buff = new InputObjectState();
+        
+        try
+        {
+            if (TxControl.getStore().allObjUids(type, buff))
+            {
+                Uid u = null;
+
+                do
+                {
+                    u = UidHelper.unpackFrom(buff);
+
+                    if (Uid.nullUid().notEquals(u))
+                    {
+                        System.out.println("Log: " + u);
+                    }
+                }
+                while (Uid.nullUid().notEquals(u));
+            }
+        }
+        catch (final ObjectStoreException ex)
+        {
+            throw new IOException();
+        }
+    }
+    
+    private final boolean supportedLog (String log)
+    {
+        Uid id = new Uid(log);
+        
+        if (id.equals(Uid.nullUid()))
+            return false;
+
+        ObjectStoreIterator iter = new ObjectStoreIterator(TxControl.getStore(), _transactionType);
+        Uid u;
+
+        do
+        {
+            u = iter.iterate();
+
+            if (u.equals(id))
+                return true;
+        }
+        while (Uid.nullUid().notEquals(u));
+
+        return false;
+    }
+    
+    private final void help ()
+    {
+        System.out.println("\nls <type> - list logs for specified type. If no type specified then must be already attached.");
+        System.out.println("select [<type] - browse a specific type of transaction. Automatically detaches.");
+        System.out.println("attach <log> - cannot be attached to another log.");
+        System.out.println("detach <log> - must be attached to log.");
+        System.out.println("forget <pid> - must be attached to log.");
+        System.out.println("delete <pid> - must be attached to log.");
+        System.out.println("types - lists supported transaction types.");
+        System.out.println("quit - exit.");
+        System.out.println("help - print out commands.\n");
+    }
+    
+    private String _currentLog = "";
+    private String _transactionType = "";
+}
+
+public class LogBrowser
+{
+    public static final void main (String[] args)
+    {
+        LogConsole console = new LogConsole();
+
+        console.doWork();
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/LogEditor.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/LogEditor.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/log/LogEditor.java	2010-02-08 19:29:18 UTC (rev 31494)
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+
+package com.arjuna.ats.arjuna.tools.log;
+
+import java.util.HashMap;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.internal.arjuna.tools.log.EditableAtomicAction;
+import com.arjuna.ats.internal.arjuna.tools.log.EditableTransaction;
+
+/**
+ * Only allows the movement of heuristic participants to the prepared list.
+ * Maybe allow general editing of both lists, including bidirectional movement (point?)
+ * and deletion.
+ */
+
+interface TransactionTypeMap
+{
+    public EditableTransaction getTransaction (final Uid u);
+    public String getType ();
+}
+
+class AtomicActionTypeMap implements TransactionTypeMap
+{
+    public EditableTransaction getTransaction (final Uid u)
+    {
+        return new EditableAtomicAction(u);
+    }
+    
+    public String getType ()
+    {
+        return "AtomicAction";  // why not Class name?
+    }
+}
+
+class TransactionTypeManager
+{
+    public EditableTransaction getTransaction (final String type, final Uid u)
+    {
+        if (type == null)
+            throw new IllegalArgumentException();
+        
+        TransactionTypeMap map = _maps.get(type);
+        
+        if (map != null)
+            return map.getTransaction(u);
+        else
+            return null;
+    }
+    
+    public void addTransaction (TransactionTypeMap map)
+    {
+        if (map == null)
+            throw new IllegalArgumentException();
+        
+        _maps.put(map.getType(), map);
+    }
+    
+    public void removeTransaction (String type)
+    {
+        if (type == null)
+            throw new IllegalArgumentException();
+        
+        _maps.remove(type);
+    }
+    
+    public static TransactionTypeManager getInstance ()
+    {
+        return _manager;
+    }
+    
+    private TransactionTypeManager ()
+    {
+    }
+    
+    private HashMap<String, TransactionTypeMap> _maps = new HashMap<String, TransactionTypeMap>();
+    
+    private static final TransactionTypeManager _manager = new TransactionTypeManager();
+}
+
+
+public class LogEditor
+{   
+    public static final void main (String[] args)
+    {
+        String txId = null;
+        String type = "AtomicAction";
+        boolean dump = true;
+        int index = -1;
+        
+        for (int i = 0; i < args.length; i++)
+        {
+            if ("-tx".equals(args[i]))
+                txId = args[i+1];
+            if ("-type".equals(args[i]))
+                type = args[i+1];
+            if ("-dump".equals(args[i]))
+                dump = true;
+            if ("-forget".equals(args[i]))
+            {
+                index = Integer.parseInt(args[i+1]);
+            }
+            if ("-help".equals(args[i]))
+            {
+                System.out.println("Usage: [-tx <id>] [-type <type>] [-dump] [-forget <index>] [-help]");
+                
+                return;
+            }
+        }
+
+        if (txId == null)
+        {
+            System.err.println("Error - no transaction log specified!");
+            
+            return;
+        }
+        
+        if (type == null)
+        {
+            System.err.println("Error - no transaction type specified!");
+            
+            return;
+        }
+        
+        TransactionTypeManager.getInstance().addTransaction(new AtomicActionTypeMap());
+        EditableTransaction act = TransactionTypeManager.getInstance().getTransaction(type, new Uid(txId));
+        
+        System.err.println("Recreated transaction.");
+        
+        if (dump)
+            System.err.println(act.toString());
+        
+        if (index >= 0)
+        {
+            try
+            {
+                act.moveHeuristicToPrepared(index);
+            
+                System.err.println(act.toString());
+            }
+            catch (final NullPointerException ex)
+            {
+                System.err.println("No such participant!");
+            }
+        }
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/EditableAtomicAction.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/EditableAtomicAction.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/EditableAtomicAction.java	2010-02-08 19:29:18 UTC (rev 31494)
@@ -0,0 +1,185 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+
+package com.arjuna.ats.internal.arjuna.tools.log;
+
+import com.arjuna.ats.arjuna.AtomicAction;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.coordinator.ActionStatus;
+import com.arjuna.ats.arjuna.coordinator.RecordListIterator;
+import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
+
+public class EditableAtomicAction extends AtomicAction implements EditableTransaction  // going to have to be one per action type because of state differences
+{
+    public EditableAtomicAction (final Uid u)
+    {
+        super(u);
+   
+        _activated = activate();
+        
+        if (!_activated)
+            System.err.println("Transaction "+u+" and "+type()+" not activated.");
+    }
+    
+    /**
+     * Move a previous heuristic participant back to the prepared list so that recovery
+     * can try again. If it fails again then it may end up back on the heuristic list.
+     */
+    
+    public void moveHeuristicToPrepared (int index) throws IndexOutOfBoundsException
+    {
+        if ((index < 0) || (super.heuristicList.size() < index))
+            throw new IndexOutOfBoundsException();
+        else
+        {
+            if (super.heuristicList.size() == 0)
+                throw new IndexOutOfBoundsException();
+            
+            RecordListIterator iter = new RecordListIterator(super.heuristicList);
+            AbstractRecord rec = iter.iterate();
+            
+            for (int i = 0; i < index; i++)
+                rec = iter.iterate();
+
+            /*
+             * Before we move we need to tell the resource that is can forget about the heuristic.
+             * This assumes that a) the user knows what they are doing, and b) the resource can then
+             * be driven through commit once more. If either of those assumptions is incorrect then
+             * we could be in a world of pain!
+             */
+            
+            if (rec.forgetHeuristic())
+            {
+                /*
+                 * Move from heuristic list to prepared list.
+                 */
+                
+                super.heuristicList.remove(rec);           
+                super.preparedList.insert(rec);
+                
+                /*
+                 * If the list is zero then the heuristic has gone away!
+                 * 
+                 * We don't maintain a per-resource heuristic so we cannot change
+                 * the heuristic each time we remove a resource, i.e., we have to
+                 * assume that the original heuristic applies to all of the remaining
+                 * participants.
+                 */
+                
+                if (super.heuristicList.size() == 0)
+                    super.setHeuristicDecision(TwoPhaseOutcome.FINISH_OK);
+                
+                super.updateState();
+            }
+            else
+                System.err.println("Error - could not get resource to forget heuristic. Left on Heuristic List.");
+        }
+    }
+    
+    /**
+     * Delete a heuristic participant from the list.
+     */
+    
+    public void deleteHeuristicParticipant (int index) throws IndexOutOfBoundsException
+    {
+        if ((index < 0) || (super.heuristicList.size() < index))
+            throw new IndexOutOfBoundsException();
+        else
+        {
+            if (super.heuristicList.size() == 0)
+                throw new IndexOutOfBoundsException();
+            
+            RecordListIterator iter = new RecordListIterator(super.heuristicList);
+            AbstractRecord rec = iter.iterate();
+            
+            for (int i = 0; i < index; i++)
+                rec = iter.iterate();
+
+            super.heuristicList.remove(rec);
+            
+            /*
+             * If the list is zero then the heuristic has gone away!
+             */
+            
+            if (super.heuristicList.size() == 0)
+                super.setHeuristicDecision(TwoPhaseOutcome.FINISH_OK);
+            
+            // if the log is not entry this call will delete the log automatically.
+            
+            super.updateState();
+        }
+    }
+    
+    public String toString ()
+    {
+        if (!_activated)
+            return "RecoveryAction not activated.";
+        else
+        {
+            String printableForm = "ActionStatus: "+ActionStatus.stringForm(super.status());
+            
+            printableForm += "\nHeuristic Decision: "+TwoPhaseOutcome.stringForm(super.getHeuristicDecision());
+            
+            if (super.preparedList.size() == 0)
+                printableForm += "\nNo prepared entries.";
+            else
+            {
+                printableForm += "\nPrepared entries:";
+                
+                RecordListIterator iter = new RecordListIterator(super.preparedList);
+                AbstractRecord rec = iter.iterate();
+                int i = 0;
+                
+                while (rec != null)
+                {
+                    printableForm += "\n["+i+"] "+rec;
+                    
+                    rec = iter.iterate();
+                    i++;
+                }
+            }
+            
+            if (super.heuristicList.size() == 0)
+                printableForm += "\nNo heuristic entries.";
+            else
+            {
+                printableForm += "\nHeuristic entries:";
+                
+                RecordListIterator iter = new RecordListIterator(super.heuristicList);
+                AbstractRecord rec = iter.iterate();
+                int i = 0;
+                
+                while (rec != null)
+                {
+                    printableForm += "\n["+i+"] "+rec;
+                    
+                    rec = iter.iterate();
+                    i++;
+                }
+            }
+            
+            return printableForm;
+        }
+    }
+    
+    private boolean _activated;
+}
\ No newline at end of file

Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/EditableTransaction.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/EditableTransaction.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/tools/log/EditableTransaction.java	2010-02-08 19:29:18 UTC (rev 31494)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
+ * as indicated by the @author tags. 
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors. 
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A 
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2010,
+ * @author JBoss Inc.
+ */
+
+package com.arjuna.ats.internal.arjuna.tools.log;
+
+/**
+ * Only allows the movement of heuristic participants to the prepared list.
+ * Maybe allow general editing of both lists, including bidirectional movement (point?)
+ * and deletion.
+ */
+
+public interface EditableTransaction
+{   
+    public void moveHeuristicToPrepared (int index) throws IndexOutOfBoundsException;
+    
+    public void deleteHeuristicParticipant (int index) throws IndexOutOfBoundsException;
+    
+    public String toString ();
+}
+

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/resources/CrashRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/resources/CrashRecord.java	2010-02-08 14:39:50 UTC (rev 31493)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/resources/CrashRecord.java	2010-02-08 19:29:18 UTC (rev 31494)
@@ -32,15 +32,35 @@
 package com.hp.mwtests.ts.arjuna.resources;
 
 import com.arjuna.ats.arjuna.coordinator.*;
+import com.arjuna.ats.arjuna.coordinator.abstractrecord.RecordTypeMap;
 import com.arjuna.ats.arjuna.common.*;
 import com.arjuna.ats.arjuna.state.*;
 
+class DummyMap2 implements RecordTypeMap
+{
+    @SuppressWarnings("unchecked")
+    public Class getRecordClass ()
+    {
+        return CrashRecord.class;
+    }
 
+    public int getType ()
+    {
+        return RecordType.USER_DEF_FIRST0;
+    }    
+}
+
 public class CrashRecord extends AbstractRecord
 {
     public enum CrashLocation { NoCrash, CrashInPrepare, CrashInCommit, CrashInAbort };
     public enum CrashType { Normal, HeuristicHazard };
 
+    public CrashRecord ()
+    {
+        _cl = CrashLocation.NoCrash;
+        _ct = CrashType.Normal;
+    }
+    
     public CrashRecord (CrashLocation cl, CrashType ct)
     {
         super(new Uid());
@@ -154,6 +174,11 @@
 
     public void alter(AbstractRecord a)
     {
+    }   
+
+    public String toString ()
+    {
+        return "CrashRecord. No state. "+super.toString();
     }
 
     /**

Added: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/LogEditorUnitTest.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/LogEditorUnitTest.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/LogEditorUnitTest.java	2010-02-08 19:29:18 UTC (rev 31494)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+
+package com.hp.mwtests.ts.arjuna.tools;
+
+import com.arjuna.ats.arjuna.AtomicAction;
+import com.arjuna.ats.arjuna.coordinator.ActionStatus;
+import com.hp.mwtests.ts.arjuna.resources.CrashRecord;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class LogEditorUnitTest
+{
+    @Test
+    public void test () throws Exception
+    {
+        // dummy to set up ObjectStore
+
+        AtomicAction A = new AtomicAction();
+
+        A.begin();
+
+        A.add(new CrashRecord(CrashRecord.CrashLocation.NoCrash,
+                CrashRecord.CrashType.Normal));
+        A.add(new CrashRecord(CrashRecord.CrashLocation.CrashInCommit,
+                CrashRecord.CrashType.HeuristicHazard));
+        A.add(new CrashRecord(CrashRecord.CrashLocation.CrashInCommit,
+                CrashRecord.CrashType.HeuristicHazard));
+        A.add(new CrashRecord(CrashRecord.CrashLocation.CrashInCommit,
+                CrashRecord.CrashType.HeuristicHazard));
+
+        int outcome = A.commit();
+
+        System.out.println("Transaction " + A + " committed with "
+                + ActionStatus.stringForm(outcome));
+
+        AtomicAction B = new AtomicAction();
+
+        B.begin();
+
+        B.add(new CrashRecord(CrashRecord.CrashLocation.NoCrash,
+                CrashRecord.CrashType.Normal));
+        B.add(new CrashRecord(CrashRecord.CrashLocation.CrashInCommit,
+                CrashRecord.CrashType.HeuristicHazard));
+        B.add(new CrashRecord(CrashRecord.CrashLocation.CrashInCommit,
+                CrashRecord.CrashType.HeuristicHazard));
+        B.add(new CrashRecord(CrashRecord.CrashLocation.CrashInCommit,
+                CrashRecord.CrashType.HeuristicHazard));
+
+        outcome = B.commit();
+
+        System.out.println("Transaction " + B + " committed with "
+                + ActionStatus.stringForm(outcome));
+    }
+}
\ No newline at end of file

Modified: labs/jbosstm/trunk/ArjunaCore/docs/user_guide/ProgrammersGuide.odt
===================================================================
(Binary files differ)



More information about the jboss-svn-commits mailing list