]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.workbench/src/org/simantics/workbench/internal/contributions/DumpHeapButtonTrim.java
Index tokenized lowercase versions of name and types for UI searches
[simantics/platform.git] / bundles / org.simantics.workbench / src / org / simantics / workbench / internal / contributions / DumpHeapButtonTrim.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.workbench.internal.contributions;
13
14 import java.io.File;
15 import java.io.IOException;
16 import java.lang.management.ManagementFactory;
17 import java.lang.reflect.InvocationTargetException;
18 import java.lang.reflect.Method;
19
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.Path;
23 import org.eclipse.core.runtime.preferences.InstanceScope;
24 import org.eclipse.jface.dialogs.MessageDialog;
25 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
26 import org.eclipse.jface.operation.IRunnableWithProgress;
27 import org.eclipse.jface.resource.JFaceResources;
28 import org.eclipse.jface.resource.LocalResourceManager;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.events.SelectionAdapter;
31 import org.eclipse.swt.events.SelectionEvent;
32 import org.eclipse.swt.layout.FillLayout;
33 import org.eclipse.swt.widgets.Button;
34 import org.eclipse.swt.widgets.Composite;
35 import org.eclipse.swt.widgets.FileDialog;
36 import org.osgi.service.prefs.BackingStoreException;
37 import org.osgi.service.prefs.Preferences;
38 import org.simantics.utils.ui.ErrorLogger;
39 import org.simantics.utils.ui.ExceptionUtils;
40 import org.simantics.utils.ui.gfx.HSVAdjustmentImageDescriptor;
41 import org.simantics.workbench.internal.Activator;
42
43 /**
44  * @author Tuukka Lehtonen
45  */
46 public class DumpHeapButtonTrim extends Composite {
47
48     private static final String PREF_HEAP_DUMP_PATH = "heap.dump.path";
49     IPath path;
50     LocalResourceManager resourceManager;
51     boolean disabled = false;
52
53     /**
54      * Creates a new heap status control with the given parent, and using
55      * the given preference store to obtain settings such as the refresh
56      * interval.
57      * 
58      * @param parent the parent composite
59      * @param prefStore the preference store
60      */
61     public DumpHeapButtonTrim(Composite parent) {
62         super(parent, SWT.NONE);
63
64         restorePrefs();
65         setLayout(new FillLayout());
66
67         final Button b = new Button(this, SWT.PUSH);
68         this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), b);
69
70         b.setToolTipText("Dump Java heap for debugging");
71         b.setImage(resourceManager.createImage(Activator.getImageDescriptor("img/lorry.png")));
72         b.addSelectionListener(new SelectionAdapter() {
73             @Override
74             public void widgetSelected(SelectionEvent e) {
75                 if (disabled)
76                     return;
77                 dumpHeap();
78             }
79         });
80         if (getBean() == null) {
81             disabled = true;
82             b.setImage(resourceManager.createImage(HSVAdjustmentImageDescriptor.adjustSaturation(
83                     Activator.getImageDescriptor("img/lorry.png"), 0)));
84             b.setToolTipText("Sorry, Java heap dumping not available, JVM does not support HotSpotDiagnosticMXBean.");
85         }
86     }
87
88     private void restorePrefs() {
89         Preferences prefs = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID);
90         String p = prefs.get(PREF_HEAP_DUMP_PATH, null);
91         path = p == null ? null : new Path(p);
92     }
93
94     private void savePrefs() {
95         Preferences prefs = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID);
96         prefs.put(PREF_HEAP_DUMP_PATH, path.toPortableString());
97
98         try {
99             prefs.flush();
100         } catch (BackingStoreException e) {
101             ErrorLogger.defaultLogError(e);
102         }
103     }
104
105     private void dumpHeap() {
106         FileDialog fd = new FileDialog(getShell(), SWT.SAVE);
107         fd.setFilterExtensions(new String[] { "*.hprof" });
108         if (path != null) {
109             fd.setFileName(path.lastSegment());
110             fd.setFilterPath(path.removeLastSegments(1).toOSString());
111         }
112         String result = fd.open();
113         if (result == null)
114             return;
115
116         path = new Path(result);
117         savePrefs();
118
119         try {
120             final File dumpFile = path.toFile();
121             if (dumpFile.exists() && !dumpFile.delete()) {
122                 MessageDialog.openError(getShell(), "Delete Failed", "Could not delete old heap dump file '" + dumpFile + "'.\n\nIs the file still in use?");
123                 return;
124             }
125             new ProgressMonitorDialog(getShell()).run(true, false, new IRunnableWithProgress() {
126                 @Override
127                 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
128                     monitor.beginTask("Creating heap dump '" + dumpFile + "'", IProgressMonitor.UNKNOWN);
129                     try {
130                         Object bean = getBean();
131                         if (bean == null)
132                             return;
133
134                         Method m = bean.getClass().getMethod("dumpHeap", String.class, boolean.class);
135                         m.invoke(bean, path.toOSString(), true);
136                     } catch (IllegalArgumentException e) {
137                         throw new InvocationTargetException(e);
138                     } catch (IllegalAccessException e) {
139                         throw new InvocationTargetException(e);
140                     } catch (SecurityException e) {
141                         throw new InvocationTargetException(e);
142                     } catch (NoSuchMethodException e) {
143                         throw new InvocationTargetException(e);
144                     } finally {
145                         monitor.done();
146                     }
147                 }
148             });
149         } catch (InvocationTargetException e) {
150             Throwable t = e.getTargetException();
151             ExceptionUtils.logAndShowError(t);
152         } catch (InterruptedException e) {
153             ExceptionUtils.logAndShowError(e);
154         }
155     }
156
157     private static Object getBean() {
158         Class<?> beanClass = getBeanClass();
159         if (beanClass == null)
160             return null;
161         try {
162             Object bean = ManagementFactory.newPlatformMXBeanProxy(
163                     ManagementFactory.getPlatformMBeanServer(),
164                     "com.sun.management:type=HotSpotDiagnostic",
165                     beanClass);
166             return bean;
167         } catch (IOException e) {
168             return null;
169         }
170     }
171
172     private static Class<?> getBeanClass() {
173         try {
174             Class<?> clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
175             return clazz;
176         } catch (ClassNotFoundException e) {
177             return null;
178         }
179     }
180
181 }