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.