If one command in a sequence fails, we can roll back all the
previously successful ones.

This is always the result of a programming error.  But, it
allows us to recover from such errors gracefully.

---

 core-dave/src/org/openstreetmap/josm/command/AddCommand.java             |    
3 
 core-dave/src/org/openstreetmap/josm/command/ChangeCommand.java          |    
3 
 core-dave/src/org/openstreetmap/josm/command/ChangePropertyCommand.java  |    
3 
 core-dave/src/org/openstreetmap/josm/command/Command.java                |   
13 +++
 core-dave/src/org/openstreetmap/josm/command/ConflictResolveCommand.java |    
3 
 core-dave/src/org/openstreetmap/josm/command/DeleteCommand.java          |    
3 
 core-dave/src/org/openstreetmap/josm/command/MoveCommand.java            |    
3 
 core-dave/src/org/openstreetmap/josm/command/RotateCommand.java          |    
3 
 core-dave/src/org/openstreetmap/josm/command/SequenceCommand.java        |   
33 ++++++++--
 9 files changed, 53 insertions(+), 14 deletions(-)

diff -puN src/org/openstreetmap/josm/command/AddCommand.java~Command 
src/org/openstreetmap/josm/command/AddCommand.java
--- core/src/org/openstreetmap/josm/command/AddCommand.java~Command     
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/AddCommand.java        
2008-05-03 12:08:39.000000000 -0700
@@ -43,8 +43,9 @@ public class AddCommand extends Command 
                this.ds = Main.main.editLayer().data;
        }
 
-       @Override public void executeCommand() {
+       @Override public boolean executeCommand() {
                osm.visit(new AddVisitor(ds));
+               return true;
        }
 
        @Override public void undoCommand() {
diff -puN src/org/openstreetmap/josm/command/ChangeCommand.java~Command 
src/org/openstreetmap/josm/command/ChangeCommand.java
--- core/src/org/openstreetmap/josm/command/ChangeCommand.java~Command  
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/ChangeCommand.java     
2008-05-03 12:08:39.000000000 -0700
@@ -28,10 +28,11 @@ public class ChangeCommand extends Comma
                this.newOsm = newOsm;
     }
 
-       @Override public void executeCommand() {
+       @Override public boolean executeCommand() {
            super.executeCommand();
            osm.cloneFrom(newOsm);
            osm.modified = true;
+               return true;
     }
 
        @Override public void fillModifiedData(Collection<OsmPrimitive> 
modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
diff -puN src/org/openstreetmap/josm/command/ChangePropertyCommand.java~Command 
src/org/openstreetmap/josm/command/ChangePropertyCommand.java
--- core/src/org/openstreetmap/josm/command/ChangePropertyCommand.java~Command  
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/ChangePropertyCommand.java     
2008-05-03 12:08:39.000000000 -0700
@@ -51,7 +51,7 @@ public class ChangePropertyCommand exten
                this.value = value;
        }
        
-       @Override public void executeCommand() {
+       @Override public boolean executeCommand() {
                super.executeCommand(); // save old
                if (value == null) {
                        for (OsmPrimitive osm : objects) {
@@ -64,6 +64,7 @@ public class ChangePropertyCommand exten
                                osm.put(key, value);
                        }
                }
+               return true;
        }
 
        @Override public void fillModifiedData(Collection<OsmPrimitive> 
modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
diff -puN src/org/openstreetmap/josm/command/Command.java~Command 
src/org/openstreetmap/josm/command/Command.java
--- core/src/org/openstreetmap/josm/command/Command.java~Command        
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/Command.java   2008-05-03 
12:08:39.000000000 -0700
@@ -9,6 +9,8 @@ import java.util.Map.Entry;
 
 import javax.swing.tree.MutableTreeNode;
 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -46,16 +48,24 @@ abstract public class Command {
 
        private CloneVisitor orig; 
 
+       protected DataSet ds;
+
+       public Command() {
+               this.ds = Main.main.editLayer().data;
+       }
        /**
         * Executes the command on the dataset. This implementation will 
remember all
         * primitives returned by fillModifiedData for restoring them on undo.
         */
-       public void executeCommand() {
+       public boolean did_execute = false;
+       public boolean executeCommand() {
+               did_execute = true;
                orig = new CloneVisitor();
                Collection<OsmPrimitive> all = new HashSet<OsmPrimitive>();
                fillModifiedData(all, all, all);
                for (OsmPrimitive osm : all)
                        osm.visit(orig);
+               return true;
        }
 
        /**
@@ -70,7 +80,6 @@ abstract public class Command {
                        e.getKey().cloneFrom(e.getValue());
        }
 
-
        /**
         * Called, when a layer has been removed to have the command remove 
itself from
         * any buffer if it is not longer applicable to the dataset (e.g. it 
was part of
diff -puN 
src/org/openstreetmap/josm/command/ConflictResolveCommand.java~Command 
src/org/openstreetmap/josm/command/ConflictResolveCommand.java
--- core/src/org/openstreetmap/josm/command/ConflictResolveCommand.java~Command 
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/ConflictResolveCommand.java    
2008-05-03 12:08:39.000000000 -0700
@@ -35,7 +35,7 @@ public class ConflictResolveCommand exte
                conflictDialog = Main.map.conflictDialog;
        }
 
-       @Override public void executeCommand() {
+       @Override public boolean executeCommand() {
                super.executeCommand();
 
                origAllConflicts = new HashMap<OsmPrimitive, 
OsmPrimitive>(conflictDialog.conflicts);
@@ -56,6 +56,7 @@ public class ConflictResolveCommand exte
                                conflictDialog.conflicts.remove(k);
                        conflictDialog.rebuildList();
                }
+               return true;
        }
 
        @Override public void undoCommand() {
diff -puN src/org/openstreetmap/josm/command/DeleteCommand.java~Command 
src/org/openstreetmap/josm/command/DeleteCommand.java
--- core/src/org/openstreetmap/josm/command/DeleteCommand.java~Command  
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/DeleteCommand.java     
2008-05-03 12:08:39.000000000 -0700
@@ -29,11 +29,12 @@ public class DeleteCommand extends Comma
                this.data = data;
        }
 
-       @Override public void executeCommand() {
+       @Override public boolean executeCommand() {
                super.executeCommand();
                for (OsmPrimitive osm : data) {
                        osm.delete(true);
                }
+               return true;
        }
        
        @Override public void fillModifiedData(Collection<OsmPrimitive> 
modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
diff -puN src/org/openstreetmap/josm/command/MoveCommand.java~Command 
src/org/openstreetmap/josm/command/MoveCommand.java
--- core/src/org/openstreetmap/josm/command/MoveCommand.java~Command    
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/MoveCommand.java       
2008-05-03 12:08:39.000000000 -0700
@@ -94,12 +94,13 @@ public class MoveCommand extends Command
                this.y += y;
        }
        
-       @Override public void executeCommand() {
+       @Override public boolean executeCommand() {
                for (Node n : objects) {
                        n.eastNorth = new EastNorth(n.eastNorth.east()+x, 
n.eastNorth.north()+y);
                        n.coor = Main.proj.eastNorth2latlon(n.eastNorth);
                        n.modified = true;
                }
+               return true;
        }
 
        @Override public void undoCommand() {
diff -puN src/org/openstreetmap/josm/command/RotateCommand.java~Command 
src/org/openstreetmap/josm/command/RotateCommand.java
--- core/src/org/openstreetmap/josm/command/RotateCommand.java~Command  
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/RotateCommand.java     
2008-05-03 12:08:39.000000000 -0700
@@ -112,8 +112,9 @@ public class RotateCommand extends Comma
                }
        }
        
-       @Override public void executeCommand() {
+       @Override public boolean executeCommand() {
                rotateNodes(true);
+               return true;
        }
 
        @Override public void undoCommand() {
diff -puN src/org/openstreetmap/josm/command/SequenceCommand.java~Command 
src/org/openstreetmap/josm/command/SequenceCommand.java
--- core/src/org/openstreetmap/josm/command/SequenceCommand.java~Command        
2008-05-03 12:08:39.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/command/SequenceCommand.java   
2008-05-03 12:08:39.000000000 -0700
@@ -9,6 +9,7 @@ import java.util.Collection;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.MutableTreeNode;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 
 /**
@@ -22,7 +23,9 @@ public class SequenceCommand extends Com
         * The command sequenz to be executed.
         */
        private Command[] sequence;
+       private boolean sequence_complete;
        private final String name;
+       public boolean continueOnError = false;
 
        /**
         * Create the command by specifying the list of commands to execute.
@@ -41,14 +44,34 @@ public class SequenceCommand extends Com
                this(name, Arrays.asList(sequenz));
        }
        
-       @Override public void executeCommand() {
-               for (Command c : sequence)
-                       c.executeCommand();
+       public int executed_commands = 0;
+       @Override public boolean executeCommand() {
+               for (int i=0; i < sequence.length; i++) {
+                       Command c = sequence[i];
+                       boolean result = c.executeCommand();
+                       if (!result)
+                               Main.debug("SequenceCommand, executing 
command[" + i + "] " +  c + " result: " + result);
+                       if (!result && !continueOnError) {
+                               this.undoCommands(i-1);
+                               return false;
+                       }
+               }
+               sequence_complete = true;
+               return true;
        }
 
+       private void undoCommands(int start) {
+               // We probably aborted this halfway though the
+               // execution sequence because of a sub-command
+               // error.  We already undid the sub-commands.
+               if (!sequence_complete)
+                       return;
+               for (int i = start; i >= 0; --i)
+                       sequence[i].undoCommand();
+       }
+
        @Override public void undoCommand() {
-               for (int i = sequence.length-1; i >= 0; --i)
-                       sequence[i].undoCommand();
+               this.undoCommands(sequence.length-1);
        }
 
        @Override public void fillModifiedData(Collection<OsmPrimitive> 
modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
_

_______________________________________________
josm-dev mailing list
[email protected]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev

Reply via email to