]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.team.ui/src/org/simantics/team/ui/HistoryView.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.team.ui / src / org / simantics / team / ui / HistoryView.java
index 75ad0bb01ad40077a4a0aa3019751c01fe33981c..2feac0c5daea1a018cdfc045382dd5e4535f5512 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.team.ui;\r
-\r
-import java.util.Collection;\r
-import java.util.Iterator;\r
-\r
-import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.action.GroupMarker;\r
-import org.eclipse.jface.action.IMenuListener;\r
-import org.eclipse.jface.action.IMenuManager;\r
-import org.eclipse.jface.action.MenuManager;\r
-import org.eclipse.jface.layout.TreeColumnLayout;\r
-import org.eclipse.jface.resource.JFaceResources;\r
-import org.eclipse.jface.resource.LocalResourceManager;\r
-import org.eclipse.jface.viewers.ColumnWeightData;\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.eclipse.jface.viewers.TreeViewer;\r
-import org.eclipse.jface.viewers.TreeViewerColumn;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.MouseAdapter;\r
-import org.eclipse.swt.events.MouseEvent;\r
-import org.eclipse.swt.graphics.Point;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Menu;\r
-import org.eclipse.swt.widgets.Tree;\r
-import org.eclipse.swt.widgets.TreeItem;\r
-import org.eclipse.ui.IWorkbenchActionConstants;\r
-import org.eclipse.ui.IWorkbenchPartSite;\r
-import org.eclipse.ui.PlatformUI;\r
-import org.simantics.db.ChangeSetIdentifier;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.CommentMetadata;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.service.XSupport;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.team.Activator;\r
-import org.simantics.team.internal.DebugPolicy;\r
-import org.simantics.team.internal.Images;\r
-import org.simantics.ui.SimanticsUI;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
-import org.simantics.utils.ui.dialogs.ShowError;\r
-\r
-\r
-/**\r
- * @author Kalle Kondelin\r
- */\r
-public class HistoryView extends TreeView {\r
-    public HistoryView() {\r
-    }\r
-    private void createPopupMenu() {\r
-        final MenuManager mm = new MenuManager("Graph History Popup", "#GraphHistoryPopup");\r
-        mm.setRemoveAllWhenShown(true);\r
-        mm.addMenuListener(new IMenuListener() {\r
-             @Override\r
-             public void menuAboutToShow(IMenuManager manager) {\r
-                 manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));\r
-             }\r
-         });\r
-        Menu menu = mm.createContextMenu(treeViewer.getControl());\r
-        treeViewer.getControl().setMenu(menu);\r
-        IWorkbenchPartSite site = getSite();\r
-        if (null != site)\r
-            site.registerContextMenu(mm.getId(), mm, treeViewer);\r
-        treeViewer.getControl().addMouseListener(new GraphHistoryMouseAdapter());\r
-        getSite().setSelectionProvider(treeViewer);\r
-    }\r
-    @Override\r
-    public void createPartControl(Composite parent) {\r
-        this.parent = parent;\r
-        this.treeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.FULL_SELECTION);\r
-        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), treeViewer.getTree());\r
-        Images.getInstance(JFaceResources.getResources());\r
-        TreeColumnLayout ad = new TreeColumnLayout();\r
-        parent.setLayout(ad);\r
-        treeViewer.getTree().setHeaderVisible(true);\r
-        //treeViewer.getTree().setLinesVisible(true);\r
-        //treeViewer.setUseHashlookup(true);\r
-        //treeViewer.setAutoExpandLevel(3);\r
-\r
-        TreeViewerColumn idColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);\r
-        TreeViewerColumn dateColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);\r
-        TreeViewerColumn commentColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);\r
-\r
-        idColumn.setLabelProvider(new IdColumnLabelProvider());\r
-        dateColumn.setLabelProvider(new DateColumnLabelProvider());\r
-        commentColumn.setLabelProvider(new CommentColumnLabelProvider());\r
-\r
-        idColumn.getColumn().setText("Id");\r
-        idColumn.getColumn().setWidth(20);\r
-        ad.setColumnData(idColumn.getColumn(), new ColumnWeightData(50, 20));\r
-        dateColumn.getColumn().setText("Date");\r
-        dateColumn.getColumn().setWidth(20);\r
-        ad.setColumnData(dateColumn.getColumn(), new ColumnWeightData(50, 40));\r
-        commentColumn.getColumn().setText("Comment");\r
-        commentColumn.getColumn().setWidth(20);\r
-        ad.setColumnData(commentColumn.getColumn(), new ColumnWeightData(50, 50));\r
-\r
-        final HistoryContentProvider contentProvider = new HistoryContentProvider(SimanticsUI.getSession());\r
-          treeViewer.setContentProvider(contentProvider);\r
-          //viewer.setSorter(new ViewerSorter());\r
-          treeViewer.setInput(this);\r
-          \r
-          getViewSite().getActionBars().getToolBarManager().add(new Action("Previous", Activator.PREVIOUS_ICON) {\r
-              @Override\r
-              public void run() {\r
-                  contentProvider.previous();\r
-              }\r
-          });\r
-          getViewSite().getActionBars().getToolBarManager().add(new Action("Next", Activator.NEXT_ICON) {\r
-              @Override\r
-              public void run() {\r
-                  contentProvider.next();\r
-              }\r
-          });\r
-          getViewSite().getActionBars().getToolBarManager().add(new Action("Get Graph History", Activator.REFRESH_ICON) {\r
-              @Override\r
-              public void run() {\r
-                  contentProvider.refresh();\r
-              }\r
-          });\r
-          if (DebugPolicy.DEBUG) {\r
-          getViewSite().getActionBars().getToolBarManager().add(new Action("Debug", Activator.DEBUG_ICON) {\r
-              @Override\r
-              public void run() {\r
-                  Session s = SimanticsUI.getSession();\r
-                  try {\r
-                      s.sync(new WriteRequest() {\r
-                          @Override\r
-                          public void perform(WriteGraph graph) throws DatabaseException {\r
-                              for (DebugPolicy.Action da : DebugPolicy.actions) {\r
-                                  switch (da) {\r
-                                      default:\r
-                                          break;\r
-                                      case CorruptClusterAction:\r
-                                          corruptClusterAction(graph);\r
-                                          break;\r
-                                      case DebugCommitAction:\r
-                                          debugCommitAction(graph);\r
-                                          break;\r
-                                  }\r
-                              }\r
-                          }\r
-                      });\r
-                  } catch (DatabaseException e) {\r
-                      ShowError.showError("Debug Action Failed", e.getMessage(), e);\r
-                      Logger.defaultLogError("Debug action failed.", e);\r
-                  }\r
-              }\r
-          });\r
-          getViewSite().getActionBars().getToolBarManager().add(new Action("Exit", Activator.EXIT_ICON) {\r
-              @Override\r
-              public void run() {\r
-                  System.out.println("exit");\r
-                  PlatformUI.getWorkbench().close();\r
-                  System.exit(0);\r
-              }\r
-          });\r
-          }\r
-          new ItemDetailToolTip(treeViewer, treeViewer.getTree(), null);\r
-          createPopupMenu();\r
-    }\r
-    static class HistoryContentProvider extends ChangeSetProvider {\r
-        class HistoryElement extends ChangeSetElement {\r
-            HistoryElement(Session session, ChangeSetIdentifier cs) {\r
-                super(session, cs);\r
-            }\r
-        }\r
-        private long topChangeSet; // Identifies first displayed change set. Zero if head.\r
-        private final int CS_LIMIT = 100; // Max number of change sets per page.\r
-        private HistoryElement[] changeSetIds;\r
-        HistoryContentProvider(Session session) {\r
-            super(session);\r
-            topChangeSet = 0; \r
-        }\r
-        @Override\r
-        public void refresh() {\r
-            topChangeSet = 0;\r
-            super.refresh();\r
-        }\r
-        @Override\r
-        public Object[] getElements(Object inputElement) {\r
-            try {\r
-                if (0 != topChangeSet)\r
-                    return changeSetIds;\r
-                changeSetIds = getElements(managementSupport.getHeadRevisionId());\r
-            } catch (DatabaseException e) {\r
-                ExceptionUtils.logAndShowError(e);\r
-                changeSetIds = new HistoryElement[0];\r
-            }\r
-            return changeSetIds;\r
-        }\r
-        private HistoryElement[] getElements(long head) {\r
-            try {\r
-                if (head < 1)\r
-                    return new HistoryElement[0];\r
-                Collection<ChangeSetIdentifier> cids;\r
-                long min = Math.max(1, head - CS_LIMIT);\r
-                cids = managementSupport.getChangeSetIdentifiers(min, head);\r
-                if (null == cids)\r
-                    changeSetIds = new HistoryElement[0];\r
-                else {\r
-                    changeSetIds = new HistoryElement[cids.size()];\r
-                    Iterator<ChangeSetIdentifier> it = cids.iterator();\r
-                    int i = cids.size();\r
-                    while (it.hasNext()) {\r
-                        changeSetIds[--i] = new HistoryElement(session, it.next());\r
-                    }\r
-                    assert(i == 0);\r
-                }\r
-            } catch (DatabaseException e) {\r
-                ExceptionUtils.logAndShowError(e);\r
-                changeSetIds = new HistoryElement[0];\r
-            }\r
-            return changeSetIds;\r
-        }\r
-        void next() {\r
-            if (0 != topChangeSet) {\r
-                long head = 0;\r
-                try {\r
-                    head = managementSupport.getHeadRevisionId();\r
-                } catch (DatabaseException e) {\r
-                    Logger.defaultLogError(e);\r
-                }\r
-                if (topChangeSet + CS_LIMIT > head)\r
-                    topChangeSet = 0;\r
-                else\r
-                    topChangeSet += CS_LIMIT;\r
-                changeSetIds = getElements(topChangeSet);\r
-            }\r
-            super.refresh();\r
-        }\r
-        void previous() {\r
-            long head = 0;\r
-            try {\r
-                head = managementSupport.getHeadRevisionId();\r
-                if (0 == topChangeSet)\r
-                    topChangeSet = head;\r
-                if (topChangeSet > CS_LIMIT + 1)\r
-                    topChangeSet -= CS_LIMIT;\r
-                changeSetIds = getElements(topChangeSet);\r
-            } catch (DatabaseException e) {\r
-                Logger.defaultLogError(e);\r
-            }\r
-            super.refresh();\r
-        }\r
-    }\r
-    static class GraphHistoryMouseAdapter extends MouseAdapter {\r
-        final boolean DEBUG = false;\r
-        public GraphHistoryMouseAdapter() {\r
-        }\r
-        protected ISelection getClickedContext(MouseEvent e) {\r
-            final Tree tree = (Tree)e.getSource();\r
-            Point point = new Point(e.x, e.y);\r
-            TreeItem item = tree.getItem(point);\r
-            // No selectable item at point?\r
-            if (item == null)\r
-                return null;\r
-            tree.select(item);\r
-            Object data = item.getData();\r
-            if (DEBUG)\r
-                System.out.println("tree item data: " + data);\r
-            return null;\r
-        }\r
-        @Override\r
-        public void mouseUp(MouseEvent e) {\r
-            ISelection context = getClickedContext(e);\r
-            if (context == null)\r
-                return;\r
-//            Tree tree = (Tree)e.getSource();\r
-        }\r
-        @Override\r
-        public void mouseDoubleClick(MouseEvent e) {\r
-            ISelection context = getClickedContext(e);\r
-            if (context == null)\r
-                return;\r
-//            Tree tree = (Tree)e.getSource();\r
-        }\r
-    }\r
-    private static void corruptClusterAction(WriteGraph graph)\r
-    throws DatabaseException {\r
-        XSupport xs = graph.getService(XSupport.class);\r
-        // Layer0 l0 = Layer0.getInstance(graph);\r
-        Resource r = graph.newResource();\r
-        String msg = "Corrupt cluster r=" + r;\r
-        System.out.println(msg);\r
-        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-        cm.add(msg);\r
-        xs.corruptCluster(r);\r
-        Resource rr = graph.newResource();\r
-        msg = "Corrupt cluster rr=" + rr;\r
-        System.out.println(msg);\r
-        cm.add(msg);\r
-        xs.corruptCluster(rr);\r
-        graph.addMetadata(cm); // Add comment to change set.\r
-    }\r
-    private static void debugCommitAction(WriteGraph graph)\r
-    throws DatabaseException {\r
-        Layer0 l0 = Layer0.getInstance(graph);\r
-        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-        graph.addMetadata(cm.add("Debug commit."));\r
-        Resource root = graph.newResource();\r
-        graph.claim(root, l0.InstanceOf, l0.Entity);\r
-        graph.claimLiteral(root, l0.HasName, "Debug Resource Root");\r
-        Resource project = graph.getResource("http://Projects/Development%20Project");\r
-        graph.claim(root, l0.PartOf, project);\r
-        final int N = 1<<20;\r
-        int count = 1; \r
-        for (int i=0; i<N; ++i, ++count) {\r
-            Resource r = graph.newResource();\r
-            graph.claim(r, l0.InstanceOf, l0.Entity);\r
-            graph.claimLiteral(r, l0.HasName, "Debug Resource " + i);\r
-            if (count % 1000 == 0)\r
-                root = r;\r
-            else\r
-                graph.claim(r, l0.PartOf, l0.ConsistsOf, root);\r
-        }\r
-    }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.team.ui;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.layout.TreeColumnLayout;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PlatformUI;
+import org.simantics.db.ChangeSetIdentifier;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.CommentMetadata;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.service.XSupport;
+import org.simantics.layer0.Layer0;
+import org.simantics.team.Activator;
+import org.simantics.team.internal.DebugPolicy;
+import org.simantics.team.internal.Images;
+import org.simantics.ui.SimanticsUI;
+import org.simantics.utils.ui.ExceptionUtils;
+import org.simantics.utils.ui.dialogs.ShowError;
+
+
+/**
+ * @author Kalle Kondelin
+ */
+public class HistoryView extends TreeView {
+    public HistoryView() {
+    }
+    private void createPopupMenu() {
+        final MenuManager mm = new MenuManager("Graph History Popup", "#GraphHistoryPopup");
+        mm.setRemoveAllWhenShown(true);
+        mm.addMenuListener(new IMenuListener() {
+             @Override
+             public void menuAboutToShow(IMenuManager manager) {
+                 manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+             }
+         });
+        Menu menu = mm.createContextMenu(treeViewer.getControl());
+        treeViewer.getControl().setMenu(menu);
+        IWorkbenchPartSite site = getSite();
+        if (null != site)
+            site.registerContextMenu(mm.getId(), mm, treeViewer);
+        treeViewer.getControl().addMouseListener(new GraphHistoryMouseAdapter());
+        getSite().setSelectionProvider(treeViewer);
+    }
+    @Override
+    public void createPartControl(Composite parent) {
+        this.parent = parent;
+        this.treeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.FULL_SELECTION);
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), treeViewer.getTree());
+        Images.getInstance(JFaceResources.getResources());
+        TreeColumnLayout ad = new TreeColumnLayout();
+        parent.setLayout(ad);
+        treeViewer.getTree().setHeaderVisible(true);
+        //treeViewer.getTree().setLinesVisible(true);
+        //treeViewer.setUseHashlookup(true);
+        //treeViewer.setAutoExpandLevel(3);
+
+        TreeViewerColumn idColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
+        TreeViewerColumn dateColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
+        TreeViewerColumn commentColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
+
+        idColumn.setLabelProvider(new IdColumnLabelProvider());
+        dateColumn.setLabelProvider(new DateColumnLabelProvider());
+        commentColumn.setLabelProvider(new CommentColumnLabelProvider());
+
+        idColumn.getColumn().setText("Id");
+        idColumn.getColumn().setWidth(20);
+        ad.setColumnData(idColumn.getColumn(), new ColumnWeightData(50, 20));
+        dateColumn.getColumn().setText("Date");
+        dateColumn.getColumn().setWidth(20);
+        ad.setColumnData(dateColumn.getColumn(), new ColumnWeightData(50, 40));
+        commentColumn.getColumn().setText("Comment");
+        commentColumn.getColumn().setWidth(20);
+        ad.setColumnData(commentColumn.getColumn(), new ColumnWeightData(50, 50));
+
+        final HistoryContentProvider contentProvider = new HistoryContentProvider(SimanticsUI.getSession());
+          treeViewer.setContentProvider(contentProvider);
+          //viewer.setSorter(new ViewerSorter());
+          treeViewer.setInput(this);
+          
+          getViewSite().getActionBars().getToolBarManager().add(new Action("Previous", Activator.PREVIOUS_ICON) {
+              @Override
+              public void run() {
+                  contentProvider.previous();
+              }
+          });
+          getViewSite().getActionBars().getToolBarManager().add(new Action("Next", Activator.NEXT_ICON) {
+              @Override
+              public void run() {
+                  contentProvider.next();
+              }
+          });
+          getViewSite().getActionBars().getToolBarManager().add(new Action("Get Graph History", Activator.REFRESH_ICON) {
+              @Override
+              public void run() {
+                  contentProvider.refresh();
+              }
+          });
+          if (DebugPolicy.DEBUG) {
+          getViewSite().getActionBars().getToolBarManager().add(new Action("Debug", Activator.DEBUG_ICON) {
+              @Override
+              public void run() {
+                  Session s = SimanticsUI.getSession();
+                  try {
+                      s.sync(new WriteRequest() {
+                          @Override
+                          public void perform(WriteGraph graph) throws DatabaseException {
+                              for (DebugPolicy.Action da : DebugPolicy.actions) {
+                                  switch (da) {
+                                      default:
+                                          break;
+                                      case CorruptClusterAction:
+                                          corruptClusterAction(graph);
+                                          break;
+                                      case DebugCommitAction:
+                                          debugCommitAction(graph);
+                                          break;
+                                  }
+                              }
+                          }
+                      });
+                  } catch (DatabaseException e) {
+                      ShowError.showError("Debug Action Failed", e.getMessage(), e);
+                      Logger.defaultLogError("Debug action failed.", e);
+                  }
+              }
+          });
+          getViewSite().getActionBars().getToolBarManager().add(new Action("Exit", Activator.EXIT_ICON) {
+              @Override
+              public void run() {
+                  System.out.println("exit");
+                  PlatformUI.getWorkbench().close();
+                  System.exit(0);
+              }
+          });
+          }
+          new ItemDetailToolTip(treeViewer, treeViewer.getTree(), null);
+          createPopupMenu();
+    }
+    static class HistoryContentProvider extends ChangeSetProvider {
+        class HistoryElement extends ChangeSetElement {
+            HistoryElement(Session session, ChangeSetIdentifier cs) {
+                super(session, cs);
+            }
+        }
+        private long topChangeSet; // Identifies first displayed change set. Zero if head.
+        private final int CS_LIMIT = 100; // Max number of change sets per page.
+        private HistoryElement[] changeSetIds;
+        HistoryContentProvider(Session session) {
+            super(session);
+            topChangeSet = 0; 
+        }
+        @Override
+        public void refresh() {
+            topChangeSet = 0;
+            super.refresh();
+        }
+        @Override
+        public Object[] getElements(Object inputElement) {
+            try {
+                if (0 != topChangeSet)
+                    return changeSetIds;
+                changeSetIds = getElements(managementSupport.getHeadRevisionId());
+            } catch (DatabaseException e) {
+                ExceptionUtils.logAndShowError(e);
+                changeSetIds = new HistoryElement[0];
+            }
+            return changeSetIds;
+        }
+        private HistoryElement[] getElements(long head) {
+            try {
+                if (head < 1)
+                    return new HistoryElement[0];
+                Collection<ChangeSetIdentifier> cids;
+                long min = Math.max(1, head - CS_LIMIT);
+                cids = managementSupport.getChangeSetIdentifiers(min, head);
+                if (null == cids)
+                    changeSetIds = new HistoryElement[0];
+                else {
+                    changeSetIds = new HistoryElement[cids.size()];
+                    Iterator<ChangeSetIdentifier> it = cids.iterator();
+                    int i = cids.size();
+                    while (it.hasNext()) {
+                        changeSetIds[--i] = new HistoryElement(session, it.next());
+                    }
+                    assert(i == 0);
+                }
+            } catch (DatabaseException e) {
+                ExceptionUtils.logAndShowError(e);
+                changeSetIds = new HistoryElement[0];
+            }
+            return changeSetIds;
+        }
+        void next() {
+            if (0 != topChangeSet) {
+                long head = 0;
+                try {
+                    head = managementSupport.getHeadRevisionId();
+                } catch (DatabaseException e) {
+                    Logger.defaultLogError(e);
+                }
+                if (topChangeSet + CS_LIMIT > head)
+                    topChangeSet = 0;
+                else
+                    topChangeSet += CS_LIMIT;
+                changeSetIds = getElements(topChangeSet);
+            }
+            super.refresh();
+        }
+        void previous() {
+            long head = 0;
+            try {
+                head = managementSupport.getHeadRevisionId();
+                if (0 == topChangeSet)
+                    topChangeSet = head;
+                if (topChangeSet > CS_LIMIT + 1)
+                    topChangeSet -= CS_LIMIT;
+                changeSetIds = getElements(topChangeSet);
+            } catch (DatabaseException e) {
+                Logger.defaultLogError(e);
+            }
+            super.refresh();
+        }
+    }
+    static class GraphHistoryMouseAdapter extends MouseAdapter {
+        final boolean DEBUG = false;
+        public GraphHistoryMouseAdapter() {
+        }
+        protected ISelection getClickedContext(MouseEvent e) {
+            final Tree tree = (Tree)e.getSource();
+            Point point = new Point(e.x, e.y);
+            TreeItem item = tree.getItem(point);
+            // No selectable item at point?
+            if (item == null)
+                return null;
+            tree.select(item);
+            Object data = item.getData();
+            if (DEBUG)
+                System.out.println("tree item data: " + data);
+            return null;
+        }
+        @Override
+        public void mouseUp(MouseEvent e) {
+            ISelection context = getClickedContext(e);
+            if (context == null)
+                return;
+//            Tree tree = (Tree)e.getSource();
+        }
+        @Override
+        public void mouseDoubleClick(MouseEvent e) {
+            ISelection context = getClickedContext(e);
+            if (context == null)
+                return;
+//            Tree tree = (Tree)e.getSource();
+        }
+    }
+    private static void corruptClusterAction(WriteGraph graph)
+    throws DatabaseException {
+        XSupport xs = graph.getService(XSupport.class);
+        // Layer0 l0 = Layer0.getInstance(graph);
+        Resource r = graph.newResource();
+        String msg = "Corrupt cluster r=" + r;
+        System.out.println(msg);
+        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+        cm.add(msg);
+        xs.corruptCluster(r);
+        Resource rr = graph.newResource();
+        msg = "Corrupt cluster rr=" + rr;
+        System.out.println(msg);
+        cm.add(msg);
+        xs.corruptCluster(rr);
+        graph.addMetadata(cm); // Add comment to change set.
+    }
+    private static void debugCommitAction(WriteGraph graph)
+    throws DatabaseException {
+        Layer0 l0 = Layer0.getInstance(graph);
+        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+        graph.addMetadata(cm.add("Debug commit."));
+        Resource root = graph.newResource();
+        graph.claim(root, l0.InstanceOf, l0.Entity);
+        graph.claimLiteral(root, l0.HasName, "Debug Resource Root");
+        Resource project = graph.getResource("http://Projects/Development%20Project");
+        graph.claim(root, l0.PartOf, project);
+        final int N = 1<<20;
+        int count = 1; 
+        for (int i=0; i<N; ++i, ++count) {
+            Resource r = graph.newResource();
+            graph.claim(r, l0.InstanceOf, l0.Entity);
+            graph.claimLiteral(r, l0.HasName, "Debug Resource " + i);
+            if (count % 1000 == 0)
+                root = r;
+            else
+                graph.claim(r, l0.PartOf, l0.ConsistsOf, root);
+        }
+    }
+}