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);
                             }

Reply via email to