Expose acquire/release stack traces by double clicking on Cache view (fixes #533744)
diff --git a/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/AlphabeticalSorter.java b/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/AlphabeticalSorter.java
deleted file mode 100644
index 555a923..0000000
--- a/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/AlphabeticalSorter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 The University of York.
- * 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:
- * Dimitrios Kolovos - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epsilon.dt.epackageregistryexplorer;
-
-import org.eclipse.jface.viewers.ContentViewer;
-import org.eclipse.jface.viewers.IBaseLabelProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerSorter;
-
-public class AlphabeticalSorter extends ViewerSorter
-{
-
- @Override
- public int category(Object element) {
- return 0;
- }
-
- @Override
- public int compare(Viewer viewer, Object e1, Object e2) {
- String name1, name2;
- if (viewer == null || !(viewer instanceof ContentViewer)) {
- name1 = e1.toString();
- name2 = e2.toString();
- }
- else {
- IBaseLabelProvider prov = ((ContentViewer) viewer).getLabelProvider();
- if (prov instanceof ILabelProvider) {
- ILabelProvider lprov = (ILabelProvider) prov;
- name1 = lprov.getText(e1);
- name2 = lprov.getText(e2);
- }
- else {
- name1 = e1.toString();
- name2 = e2.toString();
- }
- }
- if (name1 == null)
- name1 = "";
- if (name2 == null)
- name2 = "";
- return collator.compare(name1, name2);
- }
-
-
-}
diff --git a/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/CacheItemDialog.java b/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/CacheItemDialog.java
new file mode 100644
index 0000000..deea505
--- /dev/null
+++ b/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/CacheItemDialog.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Aston University.
+ * 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:
+ * Antonio Garcia-Dominguez - initial API and implementation
+******************************************************************************/
+package org.eclipse.epsilon.dt.epackageregistryexplorer;
+
+import org.eclipse.epsilon.emc.emf.CachedResourceSet.Cache.CacheItem;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+public class CacheItemDialog extends TitleAreaDialog {
+
+ private static final class StackTraceLabelProvider extends LabelProvider {
+ @Override
+ public String getText(Object element) {
+ StackTraceElement[] stackTrace = (StackTraceElement[]) element;
+ StringBuilder sb = new StringBuilder();
+ for (StackTraceElement elem : stackTrace) {
+ sb.append(elem.toString());
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+ }
+
+ private final CacheItem cItem;
+
+ public CacheItemDialog(Shell shell, CacheItem cItem) {
+ super(shell);
+ this.cItem = cItem;
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ final Composite area = (Composite) super.createDialogArea(parent);
+
+ final Composite container = new Composite(area, SWT.NONE);
+ container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ final GridLayout containerLayout = new GridLayout();
+ container.setLayout(containerLayout);
+ containerLayout.numColumns = 1;
+
+ final Label lblCheckedIn = new Label(container, SWT.NONE);
+ lblCheckedIn.setText("Checked in from:");
+
+ final ListViewer lstCheckedIn = new ListViewer(container);
+ lstCheckedIn.setContentProvider(new ArrayContentProvider());
+ lstCheckedIn.setLabelProvider(new StackTraceLabelProvider());
+ lstCheckedIn.setInput(cItem.getCheckedInFrom().toArray());
+
+ final Label lblCheckedOut = new Label(container, SWT.NONE);
+ lblCheckedOut.setText("Checked out from:");
+ final ListViewer lstCheckedOut = new ListViewer(container);
+ lstCheckedOut.setContentProvider(new ArrayContentProvider());
+ lstCheckedOut.setLabelProvider(new StackTraceLabelProvider());
+ lstCheckedOut.setInput(cItem.getCheckedOutFrom().toArray());
+
+ return area;
+ }
+
+ @Override
+ public void create() {
+ super.create();
+ setTitle("Cache item details");
+ setMessage("Check where the cache item was acquired and released from");
+ }
+
+}
diff --git a/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/CachedResourceView.java b/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/CachedResourceView.java
index 1cbd74f..a35cdc6 100644
--- a/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/CachedResourceView.java
+++ b/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/CachedResourceView.java
@@ -1,45 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2014-2018 University of York, Aston University.
+ * 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:
+ * Dimitris Kolovos - initial API and implementation
+ * Antonio Garcia-Dominguez - double click to see acquired/released stack traces
+******************************************************************************/
package org.eclipse.epsilon.dt.epackageregistryexplorer;
import org.eclipse.epsilon.emc.emf.CachedResourceSet;
import org.eclipse.epsilon.emc.emf.CachedResourceSet.Cache;
import org.eclipse.epsilon.emc.emf.CachedResourceSet.Cache.CacheItem;
import org.eclipse.jface.action.Action;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
public class CachedResourceView extends ViewPart {
-
+
protected TableViewer cacheViewer = null;
-
+
@Override
public void createPartControl(Composite parent) {
cacheViewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
cacheViewer.setContentProvider(new CachedResourceViewerContentProvider());
cacheViewer.setLabelProvider(new CachedResoureViewerLabelProvider());
- cacheViewer.setSorter(new AlphabeticalSorter());
+ cacheViewer.setComparator(new ViewerComparator((o1, o2) -> o1.compareTo(o2)));
cacheViewer.setInput(CachedResourceSet.getCache());
-
+ cacheViewer.addDoubleClickListener(new IDoubleClickListener() {
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ IStructuredSelection sel = (IStructuredSelection) event.getSelection();
+ CacheItem cItem = (CacheItem) sel.getFirstElement();
+ new CacheItemDialog(
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ cItem).open();
+ }
+ });
+
TableColumn column = new TableColumn(cacheViewer.getTable(), SWT.FULL_SELECTION);
- column.setText("Resource");
- column.setWidth(300);
-
- column = new TableColumn(cacheViewer.getTable(), SWT.FULL_SELECTION);
- column.setText("Garbage-collected");
- column.setWidth(120);
-
- cacheViewer.getTable().setHeaderVisible(true);
- cacheViewer.getTable().setLinesVisible(true);
-
-
+ column.setText("Resource");
+ column.setWidth(300);
+
+ column = new TableColumn(cacheViewer.getTable(), SWT.FULL_SELECTION);
+ column.setText("Garbage-collected");
+ column.setWidth(120);
+
+ cacheViewer.getTable().setHeaderVisible(true);
+ cacheViewer.getTable().setLinesVisible(true);
+
IActionBars bars = getViewSite().getActionBars();
bars.getToolBarManager().add(new RefreshAction());
bars.getToolBarManager().add(new ClearAction());
@@ -47,72 +72,74 @@
@Override
public void setFocus() {
-
+
}
-
+
class RefreshAction extends Action {
-
+
public RefreshAction() {
this.setText("Refresh");
this.setImageDescriptor(Activator.getDefault().getImageDescriptor("icons/refresh.gif"));
}
-
+
@Override
public void run() {
cacheViewer.refresh();
- }
+ }
}
-
+
class ClearAction extends Action {
-
+
public ClearAction() {
this.setText("Clear cache");
this.setImageDescriptor(Activator.getDefault().getImageDescriptor("icons/clear.gif"));
}
-
+
@Override
public void run() {
CachedResourceSet.getCache().clear();
cacheViewer.refresh();
- }
+ }
}
-
+
public class CachedResoureViewerLabelProvider extends LabelProvider implements ITableLabelProvider {
-
+
protected Image image = Activator.getDefault().getImageDescriptor("icons/emfmodel.gif").createImage();
-
@Override
public Image getColumnImage(Object element, int columnIndex) {
- if (columnIndex == 0) return image;
+ if (columnIndex == 0)
+ return image;
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
- if (columnIndex == 0) return ((CacheItem) element).getUri().toString();
- else return (((CacheItem) element).getResource() == null) + "";
+ if (columnIndex == 0)
+ return ((CacheItem) element).getUri().toString();
+ else
+ return (((CacheItem) element).getResource() == null) + "";
}
-
+
}
-
+
public class CachedResourceViewerContentProvider implements IStructuredContentProvider {
@Override
public void dispose() {
-
+
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-
+
}
@Override
public Object[] getElements(Object inputElement) {
- return CachedResourceSet.getCache().getItems().toArray(new Cache.CacheItem[]{});
+ return CachedResourceSet.getCache().getItems().toArray(new Cache.CacheItem[] {});
}
-
+
}
-
+
}
diff --git a/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/PackageRegistryExplorerView.java b/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/PackageRegistryExplorerView.java
index c120346..a3a3b92 100644
--- a/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/PackageRegistryExplorerView.java
+++ b/plugins/org.eclipse.epsilon.dt.epackageregistryexplorer/src/org/eclipse/epsilon/dt/epackageregistryexplorer/PackageRegistryExplorerView.java
@@ -37,6 +37,7 @@
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
@@ -126,7 +127,7 @@
classViewer.setContentProvider(new PackageRegistryContentProvider(this));
classViewer.setLabelProvider(eCoreLabelProvider);
classViewer.addSelectionChangedListener(new ClassViewerSelectionChangedListener());
- classViewer.setSorter(new AlphabeticalSorter());
+ classViewer.setComparator(new ViewerComparator((o1, o2) -> o1.compareTo(o2)));
classViewer.setInput(getViewSite());
getSite().setSelectionProvider(this);
@@ -165,7 +166,7 @@
featureViewerForm.setContent(featureViewer.getControl());
featureViewer.setContentProvider(new FeatureViewerContentProvider(this));
featureViewer.setLabelProvider(eCoreLabelProvider);
- featureViewer.setSorter(new AlphabeticalSorter());
+ featureViewer.setComparator(new ViewerComparator((o1, o2) -> o1.compareTo(o2)));
featureViewer.setInput(null);
featureViewer.addDoubleClickListener(new IDoubleClickListener() {
diff --git a/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/CachedResourceSet.java b/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/CachedResourceSet.java
index b201374..91af0f8 100644
--- a/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/CachedResourceSet.java
+++ b/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/CachedResourceSet.java
@@ -2,6 +2,7 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
@@ -126,9 +127,16 @@
}
public class CacheItem {
- protected WeakReference<Resource> resourceReference;
- public URI uri;
- public int checkedOut = 0;
+ private WeakReference<Resource> resourceReference;
+ private URI uri;
+
+ /**
+ * Track where increments/decrements were done from, to help developers
+ * and integrators track leaks.
+ */
+ private List<StackTraceElement[]> checkedInFrom = new ArrayList<>();
+ private List<StackTraceElement[]> checkedOutFrom = new ArrayList<>();
+ private int checkedOutCount = 0;
public Resource getResource() {
return resourceReference.get();
@@ -147,17 +155,26 @@
}
public void incrementCheckedOut() {
- checkedOut ++;
+ checkedInFrom.add(Thread.currentThread().getStackTrace());
+ checkedOutCount++;
}
public void decrementCheckedOut() {
- checkedOut--;
+ checkedOutFrom.add(Thread.currentThread().getStackTrace());
+ checkedOutCount--;
}
public int getCheckedOut() {
- return checkedOut;
+ return checkedOutCount;
+ }
+
+ public List<StackTraceElement[]> getCheckedInFrom() {
+ return checkedInFrom;
}
+ public List<StackTraceElement[]> getCheckedOutFrom() {
+ return checkedOutFrom;
+ }
}
}
}