Revision: 3427
Author: [email protected]
Date: Thu Apr  1 12:24:42 2010
Log: NEW - bug 2731: Undoing right after opening a server workspace is broken
http://trillian.sqlpower.ca/bugzilla/show_bug.cgi?id=2731

The UndoManager can be told when it is in a loading state. This lets the UndoManager prevent events of changing the UUID of objects as the UUID can only change when the object is first created or during load and the UndoManager cannot undo a
UUID while connected to a server.

The UndoManager's listener also adds a listener to ancestor nodes of objects it is listening to. This allows the UndoManager to be aware of transaction end-points that are higher than the nodes being listened to (occurred when the root tree fired transaction begin/end events but the UndoManager was only listening to the SQLObjectRoot).
http://code.google.com/p/power-architect/source/detail?r=3427

Modified:
 /trunk
 /trunk/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java
/trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java /trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java /trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
 /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPenComponent.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/SwingUIProjectLoader.java
 /trunk/src/main/java/ca/sqlpower/architect/swingui/action/UndoAction.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
 /trunk/src/main/java/ca/sqlpower/architect/undo/ArchitectUndoManager.java

=======================================
--- /trunk/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java Wed Mar 17 14:29:59 2010 +++ /trunk/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java Thu Apr 1 12:24:42 2010
@@ -662,8 +662,10 @@
                propertiesToIgnore.add("undoEventListeners");
                propertiesToIgnore.add("secondaryChangeMode");

+               session.getUndoManager().setLoading(true);
                Map<String,Object> oldDescription =
                        TestUtils.setAllInterestingProperties(target, 
propertiesToIgnore);
+               session.getUndoManager().setLoading(false);

// need to set sourceColumn manually because it has to exist in the database.
                {
@@ -731,8 +733,10 @@
         Set<String> propertiesToIgnore = getPropertiesToIgnore();
         propertiesToIgnore.add("undoEventListeners");

+        session.getUndoManager().setLoading(true);
         Map<String,Object> oldDescription =
TestUtils.setAllInterestingProperties(target, propertiesToIgnore);
+        session.getUndoManager().setLoading(false);

         File tmp = File.createTempFile("test", ".architect");
         if (deleteOnExit) {
@@ -792,8 +796,11 @@
         propertiesToIgnore.add("undoEventListeners");
         propertiesToIgnore.add("primaryKeyIndex");

+        session.getUndoManager().setLoading(true);
         Map<String,Object> oldDescription =
TestUtils.setAllInterestingProperties(index, propertiesToIgnore);
+        session.getUndoManager().setLoading(false);
+
         propertiesToIgnore.remove("primaryKeyIndex");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
         project.save(byteArrayOutputStream,ENCODING);
@@ -846,8 +853,10 @@

         assertSame(index, table.getPrimaryKeyIndex());

+        session.getUndoManager().setLoading(true);
         Map<String,Object> oldDescription =
TestUtils.setAllInterestingProperties(index, propertiesToIgnore);
+        session.getUndoManager().setLoading(false);

         assertSame(index, table.getPrimaryKeyIndex());

@@ -887,8 +896,10 @@
         Set<String> propertiesToIgnore = getPropertiesToIgnore();
         propertiesToIgnore.add("undoEventListeners");

+        session.getUndoManager().setLoading(true);
         Map<String,Object> oldDescription =
TestUtils.setAllInterestingProperties(index, propertiesToIgnore);
+        session.getUndoManager().setLoading(false);

         File tmp = File.createTempFile("test", ".architect");
         if (deleteOnExit) {
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java Mon Mar 29 14:08:45 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java Thu Apr 1 12:24:42 2010
@@ -282,6 +282,9 @@
     private void decodeMessage(String jsonArray, int newRevision) {
         try {
             if (currentRevision < newRevision) {
+                for (UpdateListener listener : updateListeners) {
+ listener.preUpdatePerformed(NetworkConflictResolver.this);
+                }
                 // Now we can apply the update ...
                 jsonDecoder.decode(jsonArray);
                 currentRevision = newRevision;
@@ -452,5 +455,16 @@
          */
         public boolean updatePerformed(NetworkConflictResolver resolver);
         public boolean updateException(NetworkConflictResolver resolver);
+
+        /**
+         * Called just before an update will be performed by the
+ * {...@link NetworkConflictResolver}. This gives objects the chance to be
+         * aware of incoming changes from the server if necessary.
+         *
+         * @param resolver
+         *            The {...@link NetworkConflictResolver} that received the
+         *            update.
+         */
+        public void preUpdatePerformed(NetworkConflictResolver resolver);
     }
 }
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java Thu Apr 1 08:53:29 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java Thu Apr 1 12:24:42 2010
@@ -27,7 +27,6 @@
 import java.awt.datatransfer.UnsupportedFlavorException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -36,9 +35,7 @@

 import javax.swing.ImageIcon;

-import org.apache.http.client.ClientProtocolException;
 import org.apache.log4j.Logger;
-import org.json.JSONException;

 import ca.sqlpower.architect.ArchitectSession;
 import ca.sqlpower.architect.ArchitectSessionContext;
@@ -219,25 +216,30 @@
public ArchitectSwingSession createSession(ArchitectSwingSession openingSession) throws SQLObjectException { return createSessionImpl(Messages.getString("ArchitectSwingSessionContextImpl.defaultNewProjectName"), true, openingSession); //$NON-NLS-1$
     }
-
- public ArchitectSwingSession createNewServerSession(SPServerInfo serverInfo, boolean initGUI) throws SQLObjectException, ClientProtocolException, URISyntaxException, IOException, JSONException { - ProjectLocation projectLocation = ArchitectClientSideSession.createNewServerSession(serverInfo, "New_Project"); - ArchitectSession clientSession = new ArchitectClientSideSession(this, projectLocation.getName(), projectLocation); - ArchitectSwingSession swingSession = new ArchitectSwingSessionImpl(this, clientSession);
-        getSessions().add(swingSession);
-        swingSession.addSessionLifecycleListener(sessionLifecycleListener);
-
-        if (initGUI) {
-            swingSession.initGUI();
-        }
-
-        return swingSession;
-    }

public ArchitectSwingSession createServerSession(ProjectLocation projectLocation, boolean initGUI, boolean autoStartUpdater) throws SQLObjectException {

final ArchitectClientSideSession clientSession = new ArchitectClientSideSession(this, projectLocation.getName(), projectLocation); - final ArchitectSwingSession swingSession = new ArchitectSwingSessionImpl(this, clientSession); + final ArchitectSwingSessionImpl swingSession = new ArchitectSwingSessionImpl(this, clientSession); + clientSession.getUpdater().addListener(new NetworkConflictResolver.UpdateListener() {
+
+ public void preUpdatePerformed(NetworkConflictResolver resolver) {
+                swingSession.getUndoManager().setLoading(true);
+            }
+
+ public boolean updatePerformed(NetworkConflictResolver resolver) { + //On the first update from the server we must discard all edits + //as it is equivalent to loading from a file and undoing does not
+                //make sense.
+                swingSession.getUndoManager().setLoading(false);
+                return true;
+            }
+
+ public boolean updateException(NetworkConflictResolver resolver) {
+                swingSession.getUndoManager().setLoading(false);
+                return true;
+            }
+        });

         if (autoStartUpdater) {
             clientSession.startUpdaterThread();
@@ -272,6 +274,10 @@
                         createSecuritySession(serverInfo);
                         return true;
                     }
+
+ public void preUpdatePerformed(NetworkConflictResolver resolver) {
+                        //do nothing
+                    }
                 });

                 newSecuritySession.startUpdaterThread();
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java Mon Mar 29 14:08:45 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java Thu Apr 1 12:24:42 2010
@@ -1191,6 +1191,10 @@
                     }

public boolean updateException(NetworkConflictResolver resolver) {return false;}
+
+ public void preUpdatePerformed(NetworkConflictResolver resolver) {
+                        //do nothing
+                    }
                 });

((ArchitectClientSideSession) ((ArchitectSwingSessionImpl) newSession).getDelegateSession()).startUpdaterThread();
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPenComponent.java Mon Mar 29 14:08:45 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/PlayPenComponent.java Thu Apr 1 12:24:42 2010
@@ -93,6 +93,10 @@
         }

public boolean updateException(NetworkConflictResolver resolver) {return false;}
+
+        public void preUpdatePerformed(NetworkConflictResolver resolver) {
+            //do nothing
+        }
     };

     protected PlayPenComponent(String name) {
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/SwingUIProjectLoader.java Wed Mar 17 14:29:59 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/SwingUIProjectLoader.java Thu Apr 1 12:24:42 2010
@@ -173,6 +173,7 @@
Map<OLAPSession, String> sessionDbMap = new HashMap<OLAPSession, String>();

         try {
+            getSession().getUndoManager().setLoading(true);
             if (uin.markSupported()) {
                 uin.mark(Integer.MAX_VALUE);
             } else {
@@ -196,6 +197,7 @@
             super.load(in, dataSources);
         }
         finally {
+            getSession().getUndoManager().setLoading(false);
             uin.forceClose();
         }

=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/action/UndoAction.java Thu Jan 29 12:02:55 2009 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/action/UndoAction.java Thu Apr 1 12:24:42 2010
@@ -70,7 +70,7 @@
         }
        }

-       private void updateSettingsFromManager() {
+       public void updateSettingsFromManager() {
                putValue(SHORT_DESCRIPTION, manager.getUndoPresentationName());
                setEnabled(manager.canUndo());
        }
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java Tue Mar 30 15:36:05 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java Thu Apr 1 12:24:42 2010
@@ -141,6 +141,10 @@
public boolean updateException(NetworkConflictResolver resolver) {
                                         return false;
                                     }
+
+ public void preUpdatePerformed(NetworkConflictResolver resolver) {
+                                        //do nothing
+                                    }
                                 });

((ArchitectClientSideSession) ((ArchitectSwingSessionImpl) newSession).getDelegateSession()).startUpdaterThread();
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/undo/ArchitectUndoManager.java Mon Dec 21 08:27:43 2009 +++ /trunk/src/main/java/ca/sqlpower/architect/undo/ArchitectUndoManager.java Thu Apr 1 12:24:42 2010
@@ -22,6 +22,7 @@
 import ca.sqlpower.architect.swingui.PlayPen;
 import ca.sqlpower.sqlobject.SQLObjectException;
 import ca.sqlpower.sqlobject.SQLObject;
+import ca.sqlpower.sqlobject.SQLObjectRoot;
 import ca.sqlpower.sqlobject.undo.NotifyingUndoManager;
 import ca.sqlpower.sqlobject.undo.SQLObjectUndoManager;

@@ -39,7 +40,10 @@
      */
public ArchitectUndoManager(PlayPen playPen) throws SQLObjectException {
         super(playPen.getSession().getTargetDatabase());
- playPen.getSession().getRootObject().addSPListener(new SQLObjectUndoableEventAdapter(false));
+        SQLObjectRoot rootObject = playPen.getSession().getRootObject();
+ final SQLObjectUndoableEventAdapter undoListener = new SQLObjectUndoableEventAdapter(false);
+        rootObject.addSPListener(undoListener);
+        undoListener.attachToObject(rootObject);
         if (playPen != null) {
             playPen.addUndoEventListener(eventAdapter);
         }


--
To unsubscribe, reply using "remove me" as the subject.

Reply via email to