Revision: 3378
Author: ferguson.sebastian
Date: Mon Mar 15 12:14:01 2010
Log: Added the ability to refresh a server session (which reopens the
session, and display's a dialog). Also added a list of listeners to the
updater so that it can notify other objects when it receives an update.
(this was used to close the dialog once a session was refreshed).
http://code.google.com/p/power-architect/source/detail?r=3378
Added:
/trunk/src/ca/sqlpower/architect/swingui/action/enterprise
/trunk/src/ca/sqlpower/architect/swingui/action/enterprise/RefreshProjectAction.java
Modified:
/trunk/src/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
/trunk/src/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
/trunk/src/ca/sqlpower/architect/swingui/ArchitectFrame.java
/trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java
/trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
/trunk/src/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
=======================================
--- /dev/null
+++
/trunk/src/ca/sqlpower/architect/swingui/action/enterprise/RefreshProjectAction.java
Mon Mar 15 12:14:01 2010
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, SQL Power Group Inc.
+ *
+ * This file is part of Power*Architect.
+ *
+ * Power*Architect is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Power*Architect is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package ca.sqlpower.architect.swingui.action.enterprise;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+
+import ca.sqlpower.architect.ArchitectSession;
+import ca.sqlpower.architect.swingui.ArchitectSwingSessionImpl;
+
+public class RefreshProjectAction extends AbstractAction {
+
+ //TODO: Find/Create this image!
+ private static final ImageIcon REFRESH_ICON = new
ImageIcon(RefreshProjectAction.class.getResource("/icons/arrow_refresh16.png"));
+
+ final ArchitectSession session;
+
+ public RefreshProjectAction(ArchitectSession session) {
+ super("Refresh", REFRESH_ICON);
+ putValue(Action.SHORT_DESCRIPTION, "Refresh");
+
+ if (session.isEnterpriseSession()) {
+ setEnabled(true);
+ } else {
+ setEnabled(false);
+ }
+
+ this.session = session;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ ((ArchitectSwingSessionImpl) session).refresh();
+ }
+}
=======================================
---
/trunk/src/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
Fri Mar 12 13:32:07 2010
+++
/trunk/src/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
Mon Mar 15 12:14:01 2010
@@ -178,7 +178,6 @@
try {
//TODO: Figure out how to de-register the session &c.
- getContext().getSessions().remove(this);
} catch (Exception e) {
try {
logger.error(e);
@@ -721,6 +720,9 @@
public void createRevisionSession(int revisionNo,
ArchitectSwingSession swingSession) {
// TODO Auto-generated method stub
-
- }
-}
+ }
+
+ public NetworkConflictResolver getUpdater() {
+ return updater;
+ }
+}
=======================================
---
/trunk/src/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
Fri Mar 12 13:32:07 2010
+++
/trunk/src/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
Mon Mar 15 12:14:01 2010
@@ -19,6 +19,7 @@
package ca.sqlpower.architect.enterprise;
import java.net.URI;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -91,6 +92,8 @@
private List<PersistedPropertiesEntry>
outboundPropertiesToChangeRollbackList = new
LinkedList<PersistedPropertiesEntry>();
private List<RemovedObjectEntry> outboundObjectsToRemoveRollbackList =
new LinkedList<RemovedObjectEntry>();
+ private List<UpdateListener> updateListeners = new
ArrayList<UpdateListener>();
+
public NetworkConflictResolver(
ProjectLocation projectLocation,
SPJSONMessageDecoder jsonDecoder,
@@ -120,6 +123,10 @@
public void setPersister(SPSessionPersister persister) {
this.persister = persister;
}
+
+ public List<UpdateListener> getListeners() {
+ return updateListeners;
+ }
public void flush() {
flush(false);
@@ -197,7 +204,7 @@
if (reflush) {
inboundObjectsToAdd.clear();
- inboundPropertiesToChange.clear();
+ inboundPropertiesToChange.clear(); // XXX does this cause
lists to retain old objects?
inboundObjectsToRemove.clear();
outboundObjectsToAdd.clear();
@@ -274,7 +281,15 @@
// Now we can apply the update ...
jsonDecoder.decode(jsonArray);
currentRevision = newRevision;
- }
+
+ List<UpdateListener> listenersToRemove = new
ArrayList<UpdateListener>();
+ for (UpdateListener listener : updateListeners) {
+ if (listener.updatePerformed(this)) {
+ listenersToRemove.add(listener);
+ }
+ }
+ updateListeners.removeAll(listenersToRemove);
+ }
} catch (Exception e) {
throw new RuntimeException("Failed to decode the message: " +
jsonArray, e);
}
@@ -417,4 +432,17 @@
throw new RuntimeException("Unable to get json from server: "
+ ex.getMessage());
}
}
-}
+
+ public int getRevision() {
+ return currentRevision;
+ }
+
+ public void addListener(UpdateListener listener) {
+ updateListeners.add(listener);
+ }
+
+ public static interface UpdateListener {
+ // true indicates that the updater should be removed from the list.
+ public boolean updatePerformed(NetworkConflictResolver resolver);
+ }
+}
=======================================
--- /trunk/src/ca/sqlpower/architect/swingui/ArchitectFrame.java Thu Mar 4
08:08:10 2010
+++ /trunk/src/ca/sqlpower/architect/swingui/ArchitectFrame.java Mon Mar 15
12:14:01 2010
@@ -117,6 +117,7 @@
import ca.sqlpower.architect.swingui.action.ZoomAction;
import ca.sqlpower.architect.swingui.action.ZoomResetAction;
import ca.sqlpower.architect.swingui.action.ZoomToFitAction;
+import
ca.sqlpower.architect.swingui.action.enterprise.RefreshProjectAction;
import ca.sqlpower.architect.swingui.enterprise.RevisionListPanel;
import ca.sqlpower.architect.swingui.enterprise.ServerProjectsManagerPanel;
import ca.sqlpower.architect.swingui.olap.action.ImportSchemaAction;
@@ -210,6 +211,8 @@
private CutSelectedAction cutAction;
private PasteSelectedAction pasteAction;
+ private RefreshProjectAction refreshProjectAction;
+
/**
* Closes all sessions and terminates the JVM.
*/
@@ -428,6 +431,8 @@
}
}
});
+
+ refreshProjectAction = new RefreshProjectAction(session);
}
/**
@@ -558,6 +563,10 @@
projectBar.add(openProjectAction);
projectBar.add(saveProjectAction);
projectBar.addSeparator();
+
+ projectBar.add(refreshProjectAction);
+ projectBar.addSeparator();
+
projectBar.add(printAction);
projectBar.addSeparator();
projectBar.add(undoAction);
@@ -751,6 +760,7 @@
enterpriseMenu.add(openProjectManagerAction);
openRevisionListAction.setEnabled(session.isEnterpriseSession());
enterpriseMenu.add(openRevisionListAction);
+ enterpriseMenu.add(refreshProjectAction);
menuBar.add(enterpriseMenu);
JMenu toolsMenu = new
JMenu(Messages.getString("ArchitectFrame.toolsMenu")); //$NON-NLS-1$
=======================================
---
/trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java
Thu Feb 25 09:46:15 2010
+++
/trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java
Mon Mar 15 12:14:01 2010
@@ -221,7 +221,7 @@
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);
+ ArchitectSession clientSession = new
ArchitectClientSideSession(this, projectLocation.getName(),
projectLocation);
ArchitectSwingSession swingSession = new
ArchitectSwingSessionImpl(this, clientSession);
getSessions().add(swingSession);
swingSession.addSessionLifecycleListener(sessionLifecycleListener);
@@ -233,10 +233,15 @@
return swingSession;
}
- public ArchitectSwingSession createServerSession(ProjectLocation
projectLocation, boolean initGUI) throws SQLObjectException {
+ public ArchitectSwingSession createServerSession(ProjectLocation
projectLocation, boolean initGUI, boolean autoStartUpdater) throws
SQLObjectException {
+
ArchitectClientSideSession clientSession = new
ArchitectClientSideSession(this, projectLocation.getName(),
projectLocation);
ArchitectSwingSession swingSession = new
ArchitectSwingSessionImpl(this, clientSession);
- clientSession.startUpdaterThread();
+
+ if (autoStartUpdater) {
+ clientSession.startUpdaterThread();
+ }
+
getSessions().add(swingSession);
swingSession.addSessionLifecycleListener(sessionLifecycleListener);
=======================================
--- /trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
Fri Mar 12 15:01:53 2010
+++ /trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
Mon Mar 15 12:14:01 2010
@@ -39,9 +39,12 @@
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
+import javax.swing.JProgressBar;
import javax.swing.ProgressMonitor;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
@@ -56,6 +59,7 @@
import ca.sqlpower.architect.UserSettings;
import ca.sqlpower.architect.ddl.DDLGenerator;
import ca.sqlpower.architect.enterprise.ArchitectClientSideSession;
+import ca.sqlpower.architect.enterprise.NetworkConflictResolver;
import ca.sqlpower.architect.etl.kettle.KettleJob;
import ca.sqlpower.architect.olap.OLAPRootObject;
import ca.sqlpower.architect.olap.OLAPSession;
@@ -96,6 +100,9 @@
import ca.sqlpower.util.UserPrompter.UserPromptOptions;
import ca.sqlpower.util.UserPrompter.UserPromptResponse;
+import com.jgoodies.forms.builder.DefaultFormBuilder;
+import com.jgoodies.forms.layout.FormLayout;
+
public class ArchitectSwingSessionImpl implements ArchitectSwingSession {
private static final Logger logger =
Logger.getLogger(ArchitectSwingSessionImpl.class);
@@ -580,19 +587,24 @@
* shutting down running threads, and so on.
*/
public boolean close() {
-
- // IMPORTANT NOTE: If the GUI hasn't been initialized, frame will
be null.
-
- if (getProjectLoader().isSaveInProgress()) {
- // project save is in progress, don't allow exit
- JOptionPane.showMessageDialog(frame,
-
Messages.getString("ArchitectSwingSessionImpl.cannotExitWhileSaving"),
//$NON-NLS-1$
-
Messages.getString("ArchitectSwingSessionImpl.cannotExitWhileSavingDialogTitle"),
JOptionPane.WARNING_MESSAGE); //$NON-NLS-1$
- return false;
- }
-
- if (!promptForUnsavedModifications()) {
- return false;
+ return close(true);
+ }
+
+ private boolean close(boolean promptForSave) {
+ // IMPORTANT NOTE: If the GUI hasn't been initialized, frame will be
null.
+
+ if (promptForSave) {
+ if (getProjectLoader().isSaveInProgress()) {
+ // project save is in progress, don't allow exit
+ JOptionPane.showMessageDialog(frame,
+
Messages.getString("ArchitectSwingSessionImpl.cannotExitWhileSaving"),
//$NON-NLS-1$
+
Messages.getString("ArchitectSwingSessionImpl.cannotExitWhileSavingDialogTitle"),
JOptionPane.WARNING_MESSAGE); //$NON-NLS-1$
+ return false;
+ }
+
+ if (!promptForUnsavedModifications()) {
+ return false;
+ }
}
if (!delegateSession.close()) {
@@ -1148,4 +1160,56 @@
void setUserPrompterFactory(UserPrompterFactory newUPF) {
swinguiUserPrompterFactory = newUPF;
}
-}
+
+ public void refresh() {
+ if (isEnterpriseSession()) {
+ try {
+ // Save the frame's position so that the new session's
frame is in the same place.
+ if (frame != null) {
+ frame.saveSettings();
+ }
+
+ ArchitectSession newSession =
((ArchitectSwingSessionContextImpl) getContext())
+ .createServerSession(((ArchitectClientSideSession)
delegateSession).getProjectLocation(), true, false);
+
+ JFrame newFrame = ((ArchitectSwingSessionImpl)
newSession).getArchitectFrame();
+ JLabel messageLabel = new JLabel("Refreshing");
+ JProgressBar progressBar = new JProgressBar();
+ progressBar.setIndeterminate(true);
+
+ final JDialog dialog = new JDialog(newFrame, "Refreshing");
+ DefaultFormBuilder builder = new DefaultFormBuilder(new
FormLayout("pref:grow, 5dlu, pref"));
+ builder.setDefaultDialogBorder();
+ builder.append(messageLabel, 3);
+ builder.nextLine();
+ builder.append(progressBar, 3);
+ dialog.add(builder.getPanel());
+
+ dialog.pack();
+ dialog.setLocation(newFrame.getX() + (newFrame.getWidth()
- dialog.getWidth())/2,
+ newFrame.getY() + (newFrame.getHeight()
- dialog.getHeight())/2);
+ dialog.setAlwaysOnTop(true);
+ dialog.setVisible(true);
+
+ close(false);
+
+ ((ArchitectClientSideSession) ((ArchitectSwingSessionImpl)
newSession).getDelegateSession())
+ .getUpdater().addListener(new
NetworkConflictResolver.UpdateListener() {
+ public boolean updatePerformed(NetworkConflictResolver
updater) {
+ dialog.dispose();
+ return true; // true indicates that the listener
should be removed
+ }
+ });
+
+ ((ArchitectClientSideSession) ((ArchitectSwingSessionImpl)
newSession).getDelegateSession()).startUpdaterThread();
+
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to refresh", e);
+ }
+ }
+ }
+
+ public ArchitectSession getDelegateSession() {
+ return delegateSession;
+ }
+}
=======================================
---
/trunk/src/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
Tue Mar 2 10:33:08 2010
+++
/trunk/src/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
Mon Mar 15 12:14:01 2010
@@ -32,17 +32,23 @@
import javax.swing.Action;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
+import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
+import ca.sqlpower.architect.ArchitectSession;
import ca.sqlpower.architect.ArchitectSessionContext;
import ca.sqlpower.architect.enterprise.ArchitectClientSideSession;
+import ca.sqlpower.architect.enterprise.NetworkConflictResolver;
import ca.sqlpower.architect.enterprise.ProjectLocation;
import ca.sqlpower.architect.swingui.ArchitectSwingSessionContextImpl;
+import ca.sqlpower.architect.swingui.ArchitectSwingSessionImpl;
import ca.sqlpower.enterprise.client.SPServerInfo;
import com.jgoodies.forms.builder.DefaultFormBuilder;
@@ -103,7 +109,38 @@
if (obj instanceof ProjectLocation) {
ProjectLocation location = (ProjectLocation)
obj;
try {
- ((ArchitectSwingSessionContextImpl)
context).createServerSession(location, true);
+
+ ArchitectSession newSession =
((ArchitectSwingSessionContextImpl) context).createServerSession(location,
true, false);
+ JFrame frame =
((ArchitectSwingSessionImpl) newSession).getArchitectFrame();
+
+ JLabel messageLabel = new
JLabel("Opening");
+ JProgressBar progressBar = new
JProgressBar();
+ progressBar.setIndeterminate(true);
+
+ final JDialog dialog = new
JDialog(frame, "Opening");
+ DefaultFormBuilder builder = new
DefaultFormBuilder(new FormLayout("pref:grow, 5dlu, pref"));
+ builder.setDefaultDialogBorder();
+ builder.append(messageLabel, 3);
+ builder.nextLine();
+ builder.append(progressBar, 3);
+ dialog.add(builder.getPanel());
+
+ dialog.pack();
+ dialog.setLocation(frame.getX() +
(frame.getWidth() - dialog.getWidth())/2,
+ frame.getY() +
(frame.getHeight() - dialog.getHeight())/2);
+ dialog.setAlwaysOnTop(true);
+ dialog.setVisible(true);
+
+ ((ArchitectClientSideSession)
((ArchitectSwingSessionImpl) newSession).getDelegateSession())
+ .getUpdater().addListener(new
NetworkConflictResolver.UpdateListener() {
+ public boolean
updatePerformed(NetworkConflictResolver resolver) {
+ dialog.dispose();
+ return true;
+ }
+ });
+
+ ((ArchitectClientSideSession)
((ArchitectSwingSessionImpl)
newSession).getDelegateSession()).startUpdaterThread();
+
} catch (Exception ex) {
throw new RuntimeException("Unable to open
project", ex);
}