Revision: 3887
Author: [email protected]
Date: Mon Aug 16 11:37:28 2010
Log: NEW - bug 2914: Reverse engineering can bring user out of sync with server
http://trillian.sqlpower.ca/bugzilla/show_bug.cgi?id=2914

I believe this should fix the issue with reverse engineering. The NetworkConflictResolver, on flush(), will decode the JSON and notify all of the UpdateListeners that an update is going through. This call needs to occur on a foreground thread because if a component is being dragged in the PlayPen, it needs to be interrupted and rolled back correctly before applying the change from the server.

The UpdateListener for PlayPenComponent now rolls back the drag transaction on a preUpdatePerformed call instead of an updatePerformed call, and removes the FloatingContainerPaneListeners from the PlayPen.
http://code.google.com/p/power-architect/source/detail?r=3887

Modified:
/trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
 /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPen.java
 /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPenComponent.java

=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java Thu Aug 12 11:32:38 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java Mon Aug 16 11:37:28 2010
@@ -264,8 +264,8 @@
throw new FriendlyRuntimeSPPersistenceException(response.getBody());
                 }

-                String json;
-                int newRev;
+                final String json;
+                final int newRev;
                 try {
JSONObject jsonObject = new JSONObject(response.getBody());
                     json = jsonObject.getString("data");
@@ -276,34 +276,41 @@
// Try to create inboundPersistedLists for comparison with the outbound. These will be used
                 // for special case collision detection.
                 fillInboundPersistedLists(json);
-                // Try to apply update
-                decodeMessage(json, newRev);
- // We need an additional step here for checking for special case conflicts
-                List<ConflictMessage> conflicts = detectConflicts();
-                if (conflicts.size() == 0) {
- // Try to return the persisted objects to their state pre-update.
-                    try {
- SPSessionPersister.redoForSession(session.getWorkspace(), - new LinkedList<PersistedSPObject>(outboundObjectsToAdd.values()),
-                                outboundPropertiesToChange,
- new LinkedList<RemovedObjectEntry>(outboundObjectsToRemove.values()), converter); - // We want to re-send our changes, but only if we were able to restore them
-                        flush(true);
-                    } catch (Exception ex) {
- throw new RuntimeException("Reflush failed on rollforward", ex);
-                    }
-                } else {
-                    String message = "";
- message += "Your changes have been discarded due to a conflict between you and another user: \n"; - for (int i = 0; i < MAX_CONFLICTS_TO_DISPLAY && i < conflicts.size(); i++) {
-                        message += conflicts.get(i).getMessage() + "\n";
-                    }
-                    session.createUserPrompter(message,
-                            UserPromptType.MESSAGE,
-                            UserPromptOptions.OK,
-                            UserPromptResponse.OK,
-                            "OK", "OK").promptUser("");
-                }
+
+                session.runInForeground(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        // Try to apply update
+                        decodeMessage(json, newRev);
+ // We need an additional step here for checking for special case conflicts + List<ConflictMessage> conflicts = detectConflicts();
+                        if (conflicts.size() == 0) {
+ // Try to return the persisted objects to their state pre-update.
+                            try {
+ SPSessionPersister.redoForSession(session.getWorkspace(), + new LinkedList<PersistedSPObject>(outboundObjectsToAdd.values()),
+                                        outboundPropertiesToChange,
+ new LinkedList<RemovedObjectEntry>(outboundObjectsToRemove.values()), converter); + // We want to re-send our changes, but only if we were able to restore them
+                                flush(true);
+                            } catch (Exception ex) {
+ throw new RuntimeException("Reflush failed on rollforward", ex);
+                            }
+                        } else {
+                            String message = "";
+ message += "Your changes have been discarded due to a conflict between you and another user: \n"; + for (int i = 0; i < MAX_CONFLICTS_TO_DISPLAY && i < conflicts.size(); i++) { + message += conflicts.get(i).getMessage() + "\n";
+                            }
+                            session.createUserPrompter(message,
+                                    UserPromptType.MESSAGE,
+                                    UserPromptOptions.OK,
+                                    UserPromptResponse.OK,
+                                    "OK", "OK").promptUser("");
+                        }
+                    }
+                });
             }
         } finally {
             if (monitor != null) {
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPen.java Wed Aug 11 11:27:52 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPen.java Mon Aug 16 11:37:28 2010
@@ -2637,8 +2637,6 @@
                        pp.addMouseListener(this); // the click that ends this 
operation

                        pp.cursorManager.tableDragStarted();
-                       pp.startCompoundEdit("Move " + ppc.getName()); 
//$NON-NLS-1$
-                       pp.getContentPane().begin("Move " + ppc.getName());
                }

                public void mouseMoved(MouseEvent e) {
@@ -2685,23 +2683,17 @@
                 */
                public void mouseReleased(MouseEvent e) {
                        cleanup();
+                       // normalize changes to table panes are part
+                       // of this compound edit, refer to bug 1592.
+                       pp.normalize();
+                       pp.revalidate();
                }

                protected void cleanup() {
-                       try {
-                   pp.cursorManager.placeModeFinished();
-                   pp.cursorManager.tableDragFinished();
-                   pp.removeMouseMotionListener(this);
-                   pp.removeMouseListener(this);
-
-                   // normalize changes to table panes are part
-                   // of this compound edit, refer to bug 1592.
-                               pp.normalize();
-                               pp.revalidate();
-                       } finally {
- pp.endCompoundEdit("Ending move for table "+ppc.getName()); //$NON-NLS-1$
-                           pp.getContentPane().commit("Ending move for table 
"+ppc.getName());
-                       }
+                   pp.cursorManager.placeModeFinished();
+                   pp.cursorManager.tableDragFinished();
+                   pp.removeMouseMotionListener(this);
+                   pp.removeMouseListener(this);
                }
        }

=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPenComponent.java Tue Aug 10 14:52:03 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPenComponent.java Mon Aug 16 11:37:28 2010
@@ -102,9 +102,6 @@
      */
private final UpdateListener updateWhileMovingListener = new UpdateListener() {
         public boolean updatePerformed(NetworkConflictResolver resolver) {
-            if (isBeingDragged) {
-                doneDragging(false);
-            }
             return true;
         }

@@ -113,7 +110,9 @@
         }

         public void preUpdatePerformed(NetworkConflictResolver resolver) {
-            //do nothing
+            if (isBeingDragged) {
+                doneDragging(false);
+            }
         }

         public void workspaceDeleted() {
@@ -650,7 +649,8 @@
             if (getPlayPen().getSession().isEnterpriseSession()) {
getPlayPen().getSession().getEnterpriseSession().getUpdater().addListener(updateWhileMovingListener);
             }
-            begin("Dragging " + this);
+            getParent().begin("Dragging " + this);
+            getPlayPen().startCompoundEdit("Dragging " + this);
         } else {
throw new IllegalStateException("Component is already in the middle of a drag");
         }
@@ -669,16 +669,18 @@
         if (isBeingDragged) {
             isBeingDragged = false;
             if (ok) {
-                commit();
+                getPlayPen().endCompoundEdit("Done dragging " + this);
+                getParent().commit("Done dragging " + this);
             } else {
-                rollback("Update received while dragging");
-
-                // We need to emulate a mouse released event on all the
- // FloatingContainerPaneListeners since the following message
-                // dialog prompt interrupts the drag.
+ getPlayPen().endCompoundEdit("Update received while dragging.");
+                getParent().rollback("Update received while dragging");
+
+ // We need to cleanup all of the FloatingContainerPaneListeners
+                // on the PlayPen because we no longer want to keep track
+                // of dragging.
for (MouseMotionListener l : getPlayPen().getMouseMotionListeners()) {
                     if (l instanceof FloatingContainerPaneListener) {
- ((FloatingContainerPaneListener) l).mouseReleased(null);
+                        ((FloatingContainerPaneListener) l).cleanup();
                     }
                 }

Reply via email to