blob: f60ab13a2e0d09eb2c3172cbdb5f49219d920785 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.profiler;
import java.awt.Cursor;
import java.awt.Window;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.lib.profiler.ProfilerClient;
import org.netbeans.lib.profiler.ProfilerEngineSettings;
import org.netbeans.lib.profiler.ProfilerLogger;
import org.netbeans.lib.profiler.TargetAppRunner;
import org.netbeans.lib.profiler.client.ClientUtils;
import org.netbeans.lib.profiler.common.CommonUtils;
import org.netbeans.lib.profiler.common.Profiler;
import org.netbeans.lib.profiler.common.ProfilingSettings;
import org.netbeans.lib.profiler.global.CommonConstants;
import org.netbeans.lib.profiler.results.ProfilingResultsDispatcher;
import org.netbeans.lib.profiler.results.ResultsSnapshot;
import org.netbeans.lib.profiler.results.RuntimeCCTNode;
import org.netbeans.lib.profiler.results.cpu.CPUCCTProvider;
import org.netbeans.lib.profiler.results.cpu.CPUResultsDiff;
import org.netbeans.lib.profiler.results.cpu.CPUResultsSnapshot;
import org.netbeans.lib.profiler.results.jdbc.JdbcResultsDiff;
import org.netbeans.lib.profiler.results.jdbc.JdbcResultsSnapshot;
import org.netbeans.lib.profiler.results.memory.AllocMemoryResultsDiff;
import org.netbeans.lib.profiler.results.memory.AllocMemoryResultsSnapshot;
import org.netbeans.lib.profiler.results.memory.LivenessMemoryResultsDiff;
import org.netbeans.lib.profiler.results.memory.LivenessMemoryResultsSnapshot;
import org.netbeans.lib.profiler.results.memory.MemoryCCTProvider;
import org.netbeans.lib.profiler.results.memory.SampledMemoryResultsDiff;
import org.netbeans.lib.profiler.results.memory.SampledMemoryResultsSnapshot;
import org.netbeans.lib.profiler.ui.swing.ExportUtils;
import org.netbeans.lib.profiler.utils.StringUtils;
import org.netbeans.modules.profiler.api.ProfilerDialogs;
import org.netbeans.modules.profiler.api.ProfilerStorage;
import org.netbeans.modules.profiler.utilities.ProfilerUtils;
import org.openide.cookies.OpenCookie;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.openide.util.lookup.ServiceProviders;
import org.openide.windows.WindowManager;
/** An manager for management/notifications about obtainer profiling results.
*
* @author Tomas Hurka
* @author Ian Formanek
*/
@NbBundle.Messages({
"ResultsManager_SnapshotSaveFailedMsg=Failed to save snapshot: {0}",
"ResultsManager_SnapshotCreateFailedMsg=Failed to create snapshot file: {0}",
"ResultsManager_ProfiledAppTerminatedMsg=Failed to obtain results snapshot. The profiled application terminated.",
"ResultsManager_DataNotAvailableMsg=Failed to obtain results snapshot. Data is not available yet.",
"ResultsManager_OutOfMemoryMsg=Too much data collected - the profiler ran out of memory.\n\nCollected profiling data has been deleted and profiling resumed.\nTo avoid this error, increase the -Xmx value\nin the etc/netbeans.conf file in NetBeans IDE installation\nor decrease the amount of detail in profiling settings.",
"ResultsManager_SnapshotDeleteFailedMsg=Failed to delete the snapshot file: {0}",
"ResultsManager_CantFindSnapshotLocationMsg=Cannot find default location for snapshot in project: {0}",
"ResultsManager_SnapshotCreateInProjectFailedMsg=Failed to create snapshot file in project: {0}",
"ResultsManager_SnapshotLoadFailed=Error while loading snapshot: {0}",
"ResultsManager_SnapshotsLoadFailedMsg=Loading snapshots failed.",
"ResultsManager_ObtainSavedSnapshotsFailedMsg=Failed to obtain list of saved snaphshots for project: {0}",
"ResultsManager_SelectDirDialogCaption=Select Target Directory",
"ResultsManager_SaveButtonName=Save",
"ResultsManager_OverwriteFileDialogCaption=Overwrite Existing File?",
"ResultsManager_OverwriteFileDialogMsg=The target folder already contains file {0}\n Do you want to overwrite this file?",
"ResultsManager_FileDeleteFailedMsg=Cannot delete the existing file: {0}",
"ResultsManager_SnapshotExportFailedMsg=<html><b>Failed to export snapshot:</b><br><br>{0}</html>",
"ResultsManager_ExportSnapshotData=Export Snapshot Data",
"ResultsManager_SelectFileOrDirDialogCaption=Select File or Directory",
"ResultsManager_ProfilerSnapshotFileFilter=Profiler Snapshot File (*.{0})",
"ResultsManager_ProfilerHeapdumpFileFilter=Heap Dump File (*.{0})",
"ResultsManager_OutOfMemorySavingMsg=<html><b>Not enough memory to save the snapshot.</b><br><br>To avoid this error, increase the -Xmx value<br>in the etc/netbeans.conf file in NetBeans IDE installation.</html>",
"ResultsManager_CannotCompareSnapshotsMsg=<html><b>Cannot compare snapshots:</b><br><br> {0}<br> {1}<br><br>Make sure that both snaphots are the same type.</html>",
"ResultsManager_DirectoryDoesntExistCaption=Selected Directory Does Not Exist",
"ResultsManager_DirectoryDoesntExistMsg=The directory you have selected does not exist.\nDo you want to create the directory?",
"ResultsManager_SnapshotLoadFailedMsg=<html><b>Snapshot {0} failed to load.</b><br><br>{1}</html>",
"ResultsManager_CannotOpenSnapshotMsg=<html><b>Cannot open profiler snapshot.</b><br><br>Attempting to open null snapshot.<br>Check the logfile for details.</html>",
"ResultsManager_CpuSnapshotDisplayName=cpu: {0}",
"ResultsManager_MemorySnapshotDisplayName=mem: {0}",
"ResultsManager_HeapSnapshotDisplayName=heap: {0}",
"MSG_SavingSnapshots=Saving Snapshots",
"MSG_SavingSnapshot=Saving Snapshot",
"ResultsManager_CaptionWarning=Warning",
"ResultsManager_DifferentObjectSize=<html><b>Object sizes are different.</b><br><br>Size of the same objects differ for each snapshot and their comparison is invalid.<br>The snapshots have likely been taken on different architectures (32bit vs. 64bit).</html>"
})
public final class ResultsManager {
private static final Logger LOGGER = Logger.getLogger(ResultsManager.class.getName());
//~ Inner Classes ------------------------------------------------------------------------------------------------------------
// /**
// * Resets collected results (either memory or CPU, depending on current mode).
// */
// public void resetCollectors() {
// reset();
// int instr = Profiler.getDefault().getTargetAppRunner().getProfilerClient().getCurrentInstrType();
// ProfilingResultsDispatcher.getDefault().reset();
// if (instr == CommonConstants.INSTR_RECURSIVE_FULL || instr == CommonConstants.INSTR_RECURSIVE_SAMPLED) {
// // TODO reset cpu profiling results collectors
//// CPUCallGraphBuilder.resetCollectors();
// } else if (instr == CommonConstants.INSTR_OBJECT_ALLOCATIONS || instr == CommonConstants.INSTR_OBJECT_LIVENESS) {
// MemoryCallGraphBuilder mcgb = Profiler.getDefault().getTargetAppRunner().getProfilerClient().getMemoryCallGraphBuilder();
// mcgb.resetCollectors();
// }
// fireResultsReset();
// }
static class SelectedFile {
//~ Instance fields ------------------------------------------------------------------------------------------------------
FileObject folder;
String fileExt;
String fileName;
//~ Constructors ---------------------------------------------------------------------------------------------------------
SelectedFile(FileObject folder, String fileName, String fileExt) {
this.folder = folder;
this.fileName = fileName;
this.fileExt = fileExt;
}
}
//~ Static fields/initializers -----------------------------------------------------------------------------------------------
public static final String SNAPSHOT_EXTENSION = "nps"; // NOI18N
public static final String HEAPDUMP_EXTENSION = "hprof"; // NOI18N
/* see org.netbeans.modules.sampler.SampleOutputStream.FILE_EXT */
public static final String STACKTRACES_SNAPSHOT_EXTENSION = "npss"; // NOI18N
static final String HEAPDUMP_PREFIX = "heapdump-"; // NOI18N // should differ from generated OOME heapdumps not to be detected as OOME
private static final String SNAPSHOT_PREFIX = "snapshot-"; // NOI18N
private static final long MINIMAL_TIMESTAMP = 946684800000L; // Sat, 01 Jan 2000 00:00:00 GMT in milliseconds since 01 Jan 1970
//~ Instance fields ----------------------------------------------------------------------------------------------------------
private ArrayList<LoadedSnapshot> loadedSnapshots = new ArrayList<LoadedSnapshot>();
private File exportDir;
private HashMap<FileObject, ProfilingSettings> settingsCache = new HashMap<FileObject, ProfilingSettings>();
private HashMap<FileObject, Integer> typeCache = new HashMap<FileObject, Integer>();
private Window mainWindow;
private boolean resultsAvailable = false;
private Lookup.Result<SnapshotsListener> snapshotListeners;
private Lookup.Result<ResultsListener> resultsListeners;
//~ Constructors -------------------------------------------------------------------------------------------------------------
private ResultsManager() {
Lookup l = Lookup.getDefault();
snapshotListeners = l.lookupResult(SnapshotsListener.class);
resultsListeners = l.lookupResult(ResultsListener.class);
}
private static class Singleton {
private static final ResultsManager INSTANCE = new ResultsManager();
}
//~ Methods ------------------------------------------------------------------------------------------------------------------
public static ResultsManager getDefault() {
return Singleton.INSTANCE;
}
public String getDefaultSnapshotFileName(LoadedSnapshot ls) {
return SNAPSHOT_PREFIX + ls.getSnapshot().getTimeTaken();
}
public String getSnapshotDisplayName(LoadedSnapshot ls) {
String name = ls.getFile() == null ? null : ls.getFile().getName();
if (name == null) {
name = getDefaultSnapshotFileName(ls);
} else {
int dotIndex = name.lastIndexOf('.'); // NOI18N
if (dotIndex > 0 && dotIndex <= name.length() - 2)
name = name.substring(0, dotIndex);
}
return getSnapshotDisplayName(name, ls.getType());
}
public String getSnapshotDisplayName(String fileName, int snapshotType) {
String displayName;
if (fileName.startsWith(SNAPSHOT_PREFIX)) {
String time = fileName.substring(SNAPSHOT_PREFIX.length(), fileName.length());
try {
long timeStamp = Long.parseLong(time);
if (timeStamp > MINIMAL_TIMESTAMP) {
displayName = StringUtils.formatUserDate(new Date(timeStamp));
} else {
// file name is probably customized
displayName = fileName;
}
} catch (NumberFormatException e) {
// file name is probably customized
displayName = fileName;
}
} else {
displayName = fileName;
}
// switch (snapshotType) {
// case LoadedSnapshot.SNAPSHOT_TYPE_CPU:
// return Bundle.ResultsManager_CpuSnapshotDisplayName(displayName);
// case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS:
// case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS:
// case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_SAMPLED:
// return Bundle.ResultsManager_MemorySnapshotDisplayName(displayName);
// default:
// return displayName;
// }
return displayName;
}
public String getDefaultHeapDumpFileName(long time) {
return HEAPDUMP_PREFIX + time;
}
public String getHeapDumpDisplayName(String fileName) {
String displayName;
if (fileName.startsWith(HEAPDUMP_PREFIX)) {
String time = fileName.substring(HEAPDUMP_PREFIX.length(), fileName.length());
try {
long timeStamp = Long.parseLong(time);
if (timeStamp > MINIMAL_TIMESTAMP) {
displayName = StringUtils.formatUserDate(new Date(timeStamp));
} else {
// file name is probably customized
displayName = fileName;
}
} catch (NumberFormatException e) {
// file name is probably customized
displayName = fileName;
}
} else {
displayName = fileName;
}
return displayName;
// return Bundle.ResultsManager_HeapSnapshotDisplayName(displayName);
}
public LoadedSnapshot[] getLoadedSnapshots() {
return loadedSnapshots.toArray(new LoadedSnapshot[0]);
}
public LoadedSnapshot getSnapshotFromFileObject(FileObject fo) {
LoadedSnapshot ls = findAlreadyLoadedSnapshot(fo);
if (ls != null) {
return ls;
}
try {
return loadSnapshotFromFileObject(fo);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, null, e);
return null;
}
}
public ProfilingSettings getSnapshotSettings(FileObject fo) {
ProfilingSettings settings = settingsCache.get(fo);
if ((settings == null) && !settingsCache.containsKey(fo)) {
settings = readSettingsFromFile(fo);
settingsCache.put(fo, settings);
}
return settings;
}
public int getSnapshotType(FileObject fo) {
Integer type = typeCache.get(fo);
if (type == null) {
type = Integer.valueOf(readTypeFromFile(fo));
typeCache.put(fo, type);
}
return type.intValue();
}
@ServiceProviders({@ServiceProvider(service=CPUCCTProvider.Listener.class), @ServiceProvider(service=MemoryCCTProvider.Listener.class)})
public static final class ResultsMonitor implements CPUCCTProvider.Listener, MemoryCCTProvider.Listener {
//~ Methods --------------------------------------------------------------------------------------------------------------
public void cctEstablished(RuntimeCCTNode runtimeCCTNode, boolean empty) {
if (!empty) {
ResultsManager rm = getDefault();
if (!rm.resultsAvailable() && !isSomeResultsAvailable()) {
return;
}
rm.resultsBecameAvailable();
}
}
public void cctReset() {
getDefault().resultsReset();
}
private boolean isSomeResultsAvailable() {
// check that we have data for snapshot, CPU profiling can have non-empty
// batch, but this batch can contain only marker methods
Profiler profiler = Profiler.getDefault();
ProfilerClient client = profiler.getTargetAppRunner().getProfilerClient();
int profilingType = profiler.getLastProfilingSettings().getProfilingType();
if (profilingType == ProfilingSettings.PROFILE_CPU_ENTIRE ||
profilingType == ProfilingSettings.PROFILE_CPU_PART) {
try {
// construct snapshot and check that it has some data
client.getCPUProfilingResultsSnapshot(false);
} catch (CPUResultsSnapshot.NoDataAvailableException ex) {
// we don't have data for snapshot
return false;
} catch (ClientUtils.TargetAppOrVMTerminated ex) {
// target VM is down
return false;
}
}
return true;
}
}
public void closeSnapshot(LoadedSnapshot ls) {
if (ls != null) {
loadedSnapshots.remove(ls);
fireSnapshotRemoved(ls);
}
}
public void compareSnapshots(FileObject snapshot1FO, FileObject snapshot2FO) {
LoadedSnapshot s1 = null;
LoadedSnapshot s2 = null;
FileObject snapshotFO = snapshot1FO;
try {
s1 = findAlreadyLoadedSnapshot(snapshot1FO);
if (s1 == null) {
s1 = loadSnapshotImpl(snapshot1FO);
}
snapshotFO = snapshot2FO;
s2 = findAlreadyLoadedSnapshot(snapshot2FO);
if (s2 == null) {
s2 = loadSnapshotFromFileObject(snapshot2FO);
}
} catch (Exception e) {
LOGGER.log(Level.INFO, Bundle.ResultsManager_SnapshotLoadFailed(snapshotFO.getPath()), e);
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotLoadFailedMsg(snapshotFO.getNameExt(), e.getMessage()));
return;
}
if ((s1 != null) && (s2 != null)) {
compareSnapshots(s1, s2);
} else {
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotsLoadFailedMsg());
}
}
public ResultsSnapshot createDiffSnapshot(LoadedSnapshot s1, LoadedSnapshot s2) {
ResultsSnapshot snap1 = s1.getSnapshot();
ResultsSnapshot snap2 = s2.getSnapshot();
ResultsSnapshot diff = null;
if (snap1 instanceof SampledMemoryResultsSnapshot && snap2 instanceof SampledMemoryResultsSnapshot) {
SampledMemoryResultsSnapshot sn1 = (SampledMemoryResultsSnapshot)snap1;
SampledMemoryResultsSnapshot sn2 = (SampledMemoryResultsSnapshot)snap2;
checkObjectSizes(sn1.getClassNames(), sn1.getObjectsCounts(), sn1.getObjectsSizePerClass(), 1,
sn2.getClassNames(), sn2.getObjectsCounts(), sn2.getObjectsSizePerClass(), 1);
diff = new SampledMemoryResultsDiff((SampledMemoryResultsSnapshot)snap1,
(SampledMemoryResultsSnapshot)snap2);
} else if (snap1 instanceof AllocMemoryResultsSnapshot && snap2 instanceof AllocMemoryResultsSnapshot) {
AllocMemoryResultsSnapshot sn1 = (AllocMemoryResultsSnapshot)snap1;
AllocMemoryResultsSnapshot sn2 = (AllocMemoryResultsSnapshot)snap2;
// Note: instrumented allocations not compared because of #236363
// ProfilingSettings sn1s = s1.getSettings();
// ProfilingSettings sn2s = s2.getSettings();
// checkObjectSizes(sn1.getClassNames(), sn1.getObjectsCounts(), sn1.getObjectsSizePerClass(), sn1s.getAllocTrackEvery(),
// sn2.getClassNames(), sn2.getObjectsCounts(), sn2.getObjectsSizePerClass(), sn2s.getAllocTrackEvery());
checkObjectSizes(sn1.getClassNames(), sn1.getObjectsCounts(), sn1.getObjectsSizePerClass(), Integer.MAX_VALUE,
sn2.getClassNames(), sn2.getObjectsCounts(), sn2.getObjectsSizePerClass(), Integer.MAX_VALUE);
diff = new AllocMemoryResultsDiff((AllocMemoryResultsSnapshot)snap1,
(AllocMemoryResultsSnapshot)snap2);
} else if (snap1 instanceof LivenessMemoryResultsSnapshot && snap2 instanceof LivenessMemoryResultsSnapshot) {
LivenessMemoryResultsSnapshot sn1 = (LivenessMemoryResultsSnapshot)snap1;
LivenessMemoryResultsSnapshot sn2 = (LivenessMemoryResultsSnapshot)snap2;
// Note: using track each 1 object to prevent unnecessary division, the data are always correct for liveness results
// ProfilingSettings sn1s = s1.getSettings();
// ProfilingSettings sn2s = s2.getSettings();
// checkObjectSizes(sn1.getClassNames(), sn1.getNTrackedLiveObjects(), sn1.getTrackedLiveObjectsSize(), sn1s.getAllocTrackEvery(),
// sn2.getClassNames(), sn2.getNTrackedLiveObjects(), sn2.getTrackedLiveObjectsSize(), sn2s.getAllocTrackEvery());
checkObjectSizes(sn1.getClassNames(), sn1.getNTrackedLiveObjects(), sn1.getTrackedLiveObjectsSize(), 1,
sn2.getClassNames(), sn2.getNTrackedLiveObjects(), sn2.getTrackedLiveObjectsSize(), 1);
diff = new LivenessMemoryResultsDiff((LivenessMemoryResultsSnapshot)snap1,
(LivenessMemoryResultsSnapshot)snap2);
} else if (snap1 instanceof CPUResultsSnapshot && snap2 instanceof CPUResultsSnapshot) {
diff = new CPUResultsDiff((CPUResultsSnapshot)snap1, (CPUResultsSnapshot)snap2);
} else if (snap1 instanceof JdbcResultsSnapshot && snap2 instanceof JdbcResultsSnapshot) {
diff = new JdbcResultsDiff((JdbcResultsSnapshot)snap1, (JdbcResultsSnapshot)snap2);
}
return diff;
}
public void compareSnapshots(final LoadedSnapshot s1, final LoadedSnapshot s2) {
CommonUtils.runInEventDispatchThread(new Runnable() {
public void run() {
SnapshotResultsWindow srw = SnapshotResultsWindow.get(s1, 0, false);
if (!srw.setRefSnapshot(s2)) {
ProfilerDialogs.displayError(Bundle.ResultsManager_CannotCompareSnapshotsMsg(
s1.getFile().getName(), s2.getFile().getName()));
} else {
srw.open();
srw.requestActive();
}
}
});
}
static void checkObjectSizes(String[] names1, int[] counts1, long[] sizes1, int n1,
String[] names2, int[] counts2, long[] sizes2, int n2) {
String obj1 = "java.lang.Object"; // NOI18N // Sampled snapshots
String obj2 = "java/lang/Object"; // NOI18N // Instrumented snapshots
int idx1 = -1;
for (int i = 0; i < names1.length; i++)
if (obj1.equals(names1[i]) || obj2.equals(names1[i])) {
idx1 = i;
break;
}
if (idx1 == -1 || counts1[idx1] == 0) return; // Should not happen
int idx2 = -1;
for (int i = 0; i < names2.length; i++)
if (obj1.equals(names2[i]) || obj2.equals(names2[i])) {
idx2 = i;
break;
}
if (idx2 == -1 || counts2[idx2] == 0) return; // Should not happen
// Note: instrumented allocations not compared because of #236363
long objsize1 = n1 == 1 ? sizes1[idx1] / counts1[idx1] : 0;
long objsize2 = n2 == 1 ? sizes2[idx2] / counts2[idx2] : 0;
if (objsize1 != objsize2)
ProfilerDialogs.displayWarningDNSA(Bundle.ResultsManager_DifferentObjectSize(),
Bundle.ResultsManager_CaptionWarning(), null,
"ResultsManager.checkObjectSizes", false); // NOI18N
}
public void deleteSnapshot(FileObject snapshotFile) {
LoadedSnapshot ls = findLoadedSnapshot(FileUtil.toFile(snapshotFile));
try {
snapshotFile.delete();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_SnapshotDeleteFailedMsg(e.getMessage()), e);
return; // do not proceed with removing the snapshot from internal structures
}
if (ls != null) { // if the snapshot has been loaded, remove the internal structures as well
loadedSnapshots.remove(ls);
fireSnapshotRemoved(ls);
}
}
public void exportSnapshots(final FileObject[] selectedSnapshots) {
assert (selectedSnapshots != null);
assert (selectedSnapshots.length > 0);
final String[] fileName = new String[1], fileExt = new String[1];
final FileObject[] dir = new FileObject[1];
if (selectedSnapshots.length == 1) {
SelectedFile sf = selectSnapshotTargetFile(selectedSnapshots[0].getName(),
selectedSnapshots[0].getExt().equals(HEAPDUMP_EXTENSION));
if ((sf != null) && checkFileExists(sf)) {
fileName[0] = sf.fileName;
fileExt[0] = sf.fileExt;
dir[0] = sf.folder;
} else { // dialog cancelled by the user
return;
}
} else {
JFileChooser chooser = new JFileChooser();
if (exportDir != null) {
chooser.setCurrentDirectory(exportDir);
}
chooser.setDialogTitle(Bundle.ResultsManager_SelectDirDialogCaption());
chooser.setApproveButtonText(Bundle.ResultsManager_SaveButtonName());
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setMultiSelectionEnabled(false);
if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
if (!file.exists()) {
if (!ProfilerDialogs.displayConfirmation(
Bundle.ResultsManager_DirectoryDoesntExistMsg(),
Bundle.ResultsManager_DirectoryDoesntExistCaption())) {
return; // cancelled by the user
}
file.mkdir();
}
exportDir = file;
dir[0] = FileUtil.toFileObject(FileUtil.normalizeFile(file));
} else { // dialog cancelled
return;
}
}
final ProgressHandle ph = ProgressHandle.createHandle(Bundle.MSG_SavingSnapshots());
ph.setInitialDelay(500);
ph.start();
ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < selectedSnapshots.length; i++) {
exportSnapshot(selectedSnapshots[i], dir[0], fileName[0] != null ? fileName[0] : selectedSnapshots[i].getName(), fileExt[0] != null ? fileExt[0] : selectedSnapshots[i].getExt());
}
} finally {
ph.finish();
}
}
});
}
public LoadedSnapshot findLoadedSnapshot(ResultsSnapshot snapshot) {
Iterator it = loadedSnapshots.iterator();
while (it.hasNext()) {
LoadedSnapshot ls = (LoadedSnapshot) it.next();
if (ls.getSnapshot() == snapshot) {
return ls;
}
}
return null;
}
public LoadedSnapshot findLoadedSnapshot(File snapshotFile) {
Iterator it = loadedSnapshots.iterator();
while (it.hasNext()) {
LoadedSnapshot ls = (LoadedSnapshot) it.next();
if ((ls.getFile() != null) && ls.getFile().equals(snapshotFile)) {
return ls;
}
}
return null;
}
private static final String HPROF_HEADER = "JAVA PROFILE 1.0"; // NOI18H
private static final long MIN_HPROF_SIZE = 1024*1024L;
public static boolean checkHprofFile(File file) {
try {
if (file.isFile() && file.canRead() && file.length()>MIN_HPROF_SIZE) { // heap dump must be 1M and bigger
byte[] prefix = new byte[HPROF_HEADER.length()+4];
RandomAccessFile raf = new RandomAccessFile(file,"r"); // NOI18H
raf.readFully(prefix);
raf.close();
if (new String(prefix).startsWith(HPROF_HEADER)) {
return true;
}
}
} catch (FileNotFoundException ex) {
return false;
} catch (IOException ex) {
return false;
}
return false;
}
public FileObject[] listSavedHeapdumps(Lookup.Provider project, File directory) {
try {
FileObject snapshotsFolder = null;
if (project == null && directory != null) {
snapshotsFolder = FileUtil.toFileObject(directory);
} else {
snapshotsFolder = ProfilerStorage.getProjectFolder(project, false);
}
if (snapshotsFolder == null) {
return new FileObject[0];
}
snapshotsFolder.refresh();
FileObject[] children = snapshotsFolder.getChildren();
ArrayList /*<FileObject>*/ files = new ArrayList /*<FileObject>*/();
for (int i = 0; i < children.length; i++) {
FileObject child = children[i];
if (checkHprofFile(FileUtil.toFile(children[i])))
files.add(child);
}
Collections.sort(files,
new Comparator() {
public int compare(Object o1, Object o2) {
FileObject f1 = (FileObject) o1;
FileObject f2 = (FileObject) o2;
return f1.getName().compareTo(f2.getName());
}
});
return (FileObject[])files.toArray(new FileObject[0]);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);
return new FileObject[0];
}
}
public FileObject[] listSavedSnapshots(Lookup.Provider project, File directory) {
try {
FileObject snapshotsFolder = null;
if (project == null && directory != null) {
snapshotsFolder = FileUtil.toFileObject(directory);
} else {
snapshotsFolder = ProfilerStorage.getProjectFolder(project, false);
}
if (snapshotsFolder == null) {
return new FileObject[0];
}
snapshotsFolder.refresh();
FileObject[] children = snapshotsFolder.getChildren();
ArrayList /*<FileObject>*/ files = new ArrayList /*<FileObject>*/();
for (int i = 0; i < children.length; i++) {
FileObject child = children[i];
if (child.getExt().equalsIgnoreCase(SNAPSHOT_EXTENSION)) {
files.add(child);
}
}
Collections.sort(files,
new Comparator() {
public int compare(Object o1, Object o2) {
FileObject f1 = (FileObject) o1;
FileObject f2 = (FileObject) o2;
return f1.getName().compareTo(f2.getName());
}
});
return (FileObject[])files.toArray(new FileObject[0]);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);
return new FileObject[0];
}
}
public boolean hasSnapshotsFor(Lookup.Provider project) {
try {
FileObject snapshotsFolder = ProfilerStorage.getProjectFolder(project, false);
FileObject[] children;
if (snapshotsFolder == null) {
return false;
}
snapshotsFolder.refresh();
children = snapshotsFolder.getChildren();
for (FileObject child : children) {
if (child.getExt().equalsIgnoreCase(SNAPSHOT_EXTENSION)) return true;
if (checkHprofFile(FileUtil.toFile(child))) return true;
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);
}
return false;
}
public int getSnapshotsCountFor(Lookup.Provider project) {
int count = 0;
try {
FileObject snapshotsFolder = ProfilerStorage.getProjectFolder(project, false);
FileObject[] children;
if (snapshotsFolder == null) {
return count;
}
snapshotsFolder.refresh();
children = snapshotsFolder.getChildren();
for (FileObject child : children) {
if (child.getExt().equalsIgnoreCase(SNAPSHOT_EXTENSION) ||
checkHprofFile(FileUtil.toFile(child))) count++;
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);
}
return count;
}
public LoadedSnapshot loadSnapshot(FileObject selectedFile) {
try {
return loadSnapshotImpl(selectedFile);
} catch (IOException e) {
LOGGER.log(Level.INFO, Bundle.ResultsManager_SnapshotLoadFailed(selectedFile.getPath()), e);
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotLoadFailedMsg(selectedFile.getNameExt(), e.getMessage()));
return null;
}
}
public LoadedSnapshot[] loadSnapshots(FileObject[] selectedFiles) {
LoadedSnapshot[] ret = new LoadedSnapshot[selectedFiles.length];
for (int i = 0; i < selectedFiles.length; i++) {
try {
if (selectedFiles[i] != null) {
ret[i] = loadSnapshotImpl(selectedFiles[i]);
}
} catch (IOException e) {
LOGGER.log(Level.INFO, Bundle.ResultsManager_SnapshotLoadFailed(selectedFiles[i].getPath()), e);
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotLoadFailedMsg(selectedFiles[i].getNameExt(), e.getMessage()));
}
}
return ret;
}
public void openSnapshot(File snapshot) {
File sf = FileUtil.normalizeFile(snapshot);
FileObject snapshotFo = FileUtil.toFileObject(sf);
openSnapshot(snapshotFo);
}
public void openSnapshot(FileObject snapshotFo) {
try {
DataObject snapshotDo = DataObject.find(snapshotFo);
OpenCookie open = snapshotDo.getCookie(OpenCookie.class);
if (open != null) {
open.open();
}
} catch (DataObjectNotFoundException ex) {
Exceptions.printStackTrace(ex);
}
}
public void openSnapshot(LoadedSnapshot ls) {
openSnapshot(ls, CommonConstants.SORTING_COLUMN_DEFAULT, false); // target component decides which column will be used for sorting
}
public void openSnapshot(final LoadedSnapshot ls, final int sortingColumn, final boolean sortingOrder) {
if (ls == null) ProfilerDialogs.displayError(Bundle.ResultsManager_CannotOpenSnapshotMsg());
else CommonUtils.runInEventDispatchThread(new Runnable() {
public void run() {
SnapshotResultsWindow srw = SnapshotResultsWindow.get(ls, sortingColumn, sortingOrder);
srw.open();
srw.requestActive();
}
});
}
public void openSnapshots(LoadedSnapshot[] loaded) {
LoadedSnapshot loadedSnapshot = null;
try {
SnapshotResultsWindow srw = null;
for (int i = 0; i < loaded.length; i++) {
loadedSnapshot = loaded[i];
if (loaded[i] != null) {
srw = SnapshotResultsWindow.get(loadedSnapshot);
srw.open();
}
}
if (srw != null) {
srw.requestActive(); // activate the last one
}
} catch (Exception e) {
LOGGER.log(Level.INFO, Bundle.ResultsManager_SnapshotLoadFailed(loadedSnapshot.getFile().getAbsoluteFile()), e);
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotLoadFailedMsg(loadedSnapshot.getFile().getName(), e.getMessage()));
}
}
public LoadedSnapshot prepareSnapshot() {
return prepareSnapshot(true);
}
public LoadedSnapshot prepareSnapshot(boolean reqeustData) {
ResultsSnapshot snapshot = null;
if (!resultsAvailable()) {
return null;
}
try {
final Profiler profiler = Profiler.getDefault();
final TargetAppRunner runner = profiler.getTargetAppRunner();
final ProfilerClient client = runner.getProfilerClient();
final int currentProfilingType = profiler.getLastProfilingSettings().getProfilingType();
try {
switch (currentProfilingType) {
case ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS:
case ProfilingSettings.PROFILE_MEMORY_LIVENESS:
case ProfilingSettings.PROFILE_MEMORY_SAMPLING:
snapshot = client.getMemoryProfilingResultsSnapshot(reqeustData);
break;
case ProfilingSettings.PROFILE_CPU_ENTIRE:
case ProfilingSettings.PROFILE_CPU_PART:
case ProfilingSettings.PROFILE_CPU_SAMPLING:
snapshot = client.getCPUProfilingResultsSnapshot(reqeustData);
break;
case ProfilingSettings.PROFILE_CPU_STOPWATCH:
snapshot = client.getCodeRegionProfilingResultsSnapshot();
break;
case ProfilingSettings.PROFILE_CPU_JDBC:
snapshot = client.getJdbcProfilingResultsSnapshot(reqeustData);
break;
}
} catch (ClientUtils.TargetAppOrVMTerminated e1) {
ProfilerDialogs.displayWarning(Bundle.ResultsManager_ProfiledAppTerminatedMsg());
ProfilerLogger.log(e1.getMessage());
} catch (CPUResultsSnapshot.NoDataAvailableException e2) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_DataNotAvailableMsg(), e2);
} catch (OutOfMemoryError e) {
try {
reset(); // reset the client data
runner.resetTimers(); // reset the server data
} catch (ClientUtils.TargetAppOrVMTerminated targetAppOrVMTerminated) {
// the target app has died; clean up all client data
client.resetClientData();
}
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_OutOfMemoryMsg(), e);
}
} finally {
if (snapshot != null) {
ProfilingSettings settings = new ProfilingSettings();
Profiler.getDefault().getLastProfilingSettings().copySettingsInto(settings);
settings.setSettingsName(Profiler.getDefault().getLastProfilingSettings().getSettingsName());
Lookup.Provider profiledProject = NetBeansProfiler.getDefaultNB().getProfiledProject();
return new LoadedSnapshot(snapshot, settings, null, profiledProject);
}
}
return null;
}
/**
* This should be called when the app is restarted or "Reset Collected Results" is invoked (because once this happened,
* there are all sorts of data that's going to be deleted/changed, and an attempt to do something with old results displayed
* here can cause big problems). It should also set the results panel invisible (or is it already happening?) etc.
*/
public void reset() {
ProfilingResultsDispatcher.getDefault().reset();
resultsReset();
}
public boolean resultsAvailable() {
return resultsAvailable;
}
public static interface SnapshotHandle {
public LoadedSnapshot getSnapshot();
}
public ExportUtils.Exportable createSnapshotExporter(final LoadedSnapshot snapshot) {
return createSnapshotExporter(new SnapshotHandle() {
public LoadedSnapshot getSnapshot() { return snapshot; }
});
}
public ExportUtils.Exportable createSnapshotExporter(final SnapshotHandle handle) {
return new ExportUtils.Exportable() {
public String getName() {
return Bundle.ResultsManager_ExportSnapshotData();
}
public boolean isEnabled() {
return true;
}
public ExportUtils.ExportProvider[] getProviders() {
final LoadedSnapshot snapshot = handle.getSnapshot();
return new ExportUtils.ExportProvider[] {
new ExportUtils.AbstractNPSExportProvider(snapshot.getFile()) {
protected void doExport(File targetFile) {
exportSnapshot(snapshot, targetFile);
}
}
};
}
};
}
private boolean exportSnapshot(LoadedSnapshot snapshot, File targetFile) {
File sourceFile = snapshot.getFile();
if (sourceFile != null) {
try {
Files.copy(sourceFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);
return true;
} catch (Throwable t) {
LOGGER.log(Level.INFO, t.getMessage(), t);
String msg = t.getLocalizedMessage().replace("<", "&lt;").replace(">", "&gt;"); // NOI18N
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotExportFailedMsg(msg));
return false;
}
} else {
FileLock lock = null;
FileObject target = null;
DataOutputStream dos = null;
try {
targetFile = FileUtil.normalizeFile(targetFile);
target = targetFile.isFile() ? FileUtil.toFileObject(targetFile) :
FileUtil.createData(targetFile);
lock = target.lock();
OutputStream os = target.getOutputStream(lock);
BufferedOutputStream bos = new BufferedOutputStream(os);
dos = new DataOutputStream(bos);
// System.out.println("Saving snapshot [" + snapshot.getSnapshot().getTimeTaken() + "]");
snapshot.save(dos);
dos.close();
} catch (IOException e) {
try {
if (dos != null) dos.close();
if (lock != null) target.delete(lock);
} catch (Exception e2) {}
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotSaveFailedMsg(e.getMessage()));
return false; // failure => we wont continue with firing the event
} catch (OutOfMemoryError e) {
try {
if (dos != null) dos.close();
if (lock != null) target.delete(lock);
} catch (Exception e2) {}
ProfilerDialogs.displayError(Bundle.ResultsManager_OutOfMemorySavingMsg());
return false; // failure => we wont continue with firing the event
} finally {
if (lock != null) lock.releaseLock();
}
return true;
}
}
public boolean saveSnapshot(LoadedSnapshot snapshot, FileObject profFile) {
FileLock lock = null;
DataOutputStream dos = null;
boolean isSaved = snapshot.isSaved();
snapshot.setSaved(true); // Set the file as saved in advance to prevent saving it again
try {
lock = profFile.lock();
OutputStream os = profFile.getOutputStream(lock);
BufferedOutputStream bos = new BufferedOutputStream(os);
dos = new DataOutputStream(bos);
// System.out.println("Saving snapshot [" + snapshot.getSnapshot().getTimeTaken() + "]");
snapshot.save(dos);
dos.close();
snapshot.setFile(FileUtil.toFile(profFile));
snapshot.setSaved(true);
fireSnapshotSaved(snapshot);
} catch (IOException e) {
snapshot.setSaved(isSaved);
try {
if (dos != null) {
dos.close();
}
if (lock != null) {
profFile.delete(lock);
}
} catch (Exception e2) {
}
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotSaveFailedMsg(e.getMessage()));
return false; // failure => we wont continue with firing the event
} catch (OutOfMemoryError e) {
snapshot.setSaved(isSaved);
try {
if (dos != null) {
dos.close();
}
if (lock != null) {
profFile.delete(lock);
}
} catch (Exception e2) {
}
ProfilerDialogs.displayError(Bundle.ResultsManager_OutOfMemorySavingMsg());
return false; // failure => we wont continue with firing the event
} finally {
if (lock != null) {
lock.releaseLock();
}
}
return true;
}
public boolean saveSnapshot(LoadedSnapshot ls) {
FileObject profFile = null;
Lookup.Provider p = ls.getProject();
FileObject saveDir = null;
try {
saveDir = ProfilerStorage.getProjectFolder(p, true);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_CantFindSnapshotLocationMsg(e.getMessage()), e);
return false;
}
try {
profFile = saveDir.createData(getDefaultSnapshotFileName(ls), SNAPSHOT_EXTENSION);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_SnapshotCreateInProjectFailedMsg(e.getMessage()), e);
return false;
}
return saveSnapshot(ls, profFile);
}
public LoadedSnapshot takeSnapshot() {
CommonUtils.runInEventDispatchThreadAndWait(new Runnable() {
public void run() {
mainWindow = WindowManager.getDefault().getMainWindow();
}
});
final Cursor cursor = mainWindow.getCursor();
mainWindow.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
LoadedSnapshot snapshot = prepareSnapshot();
if (snapshot != null) {
loadedSnapshots.add(snapshot);
fireSnapshotTaken(snapshot);
return snapshot;
}
} finally {
mainWindow.setCursor(cursor);
}
return null;
}
protected void fireResultsAvailable() {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "fireResultsAvailable", new Exception());
}
if (resultsListeners.allClasses().isEmpty()) {
return;
}
CommonUtils.runInEventDispatchThread(new Runnable() {
public void run() {
for(ResultsListener rl : resultsListeners.allInstances()) {
rl.resultsAvailable();
}
}
});
}
protected void fireResultsReset() {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "fireResultsReset", new Exception());
}
if (resultsListeners.allClasses().isEmpty()) {
return;
}
CommonUtils.runInEventDispatchThread(new Runnable() {
public void run() {
for(ResultsListener rl : resultsListeners.allInstances()) {
rl.resultsReset();
}
}
});
}
protected void fireSnapshotLoaded(final LoadedSnapshot snapshot) {
if (snapshotListeners.allClasses().isEmpty()) {
return;
}
CommonUtils.runInEventDispatchThread(new Runnable() {
public void run() {
for(SnapshotsListener sl : snapshotListeners.allInstances()) {
sl.snapshotLoaded(snapshot);
}
}
});
}
protected void fireSnapshotRemoved(final LoadedSnapshot snapshot) {
if (snapshotListeners.allClasses().isEmpty()) {
return;
}
CommonUtils.runInEventDispatchThread(new Runnable() {
public void run() {
for(SnapshotsListener sl : snapshotListeners.allInstances()) {
sl.snapshotRemoved(snapshot);
}
}
});
}
protected void fireSnapshotSaved(final LoadedSnapshot snapshot) {
if (snapshotListeners.allClasses().isEmpty()) {
return;
}
CommonUtils.runInEventDispatchThread(new Runnable() {
public void run() {
for(SnapshotsListener sl : snapshotListeners.allInstances()) {
sl.snapshotSaved(snapshot);
}
}
});
}
protected void fireSnapshotTaken(final LoadedSnapshot snapshot) {
if (snapshotListeners.allClasses().isEmpty()) {
return;
}
CommonUtils.runInEventDispatchThread(new Runnable() {
public void run() {
for(SnapshotsListener sl : snapshotListeners.allInstances()) {
sl.snapshotTaken(snapshot);
}
}
});
}
void resultsBecameAvailable() {
if (Profiler.getDefault().getProfilingState() == Profiler.PROFILING_INACTIVE) return; // Calibration, ignore
resultsAvailable = true;
fireResultsAvailable();
}
void resultsReset() {
// NOTE: originally left as true for memory profiling due to Issue 60432, now seems to work correctly
resultsAvailable = false;
fireResultsReset();
}
// heapdump == true means selecting heapdump (*.hprof)
SelectedFile selectSnapshotTargetFile(final String defaultName, final boolean heapdump) {
String targetName;
FileObject targetDir;
// 1. let the user choose file or directory
JFileChooser chooser = new JFileChooser();
if (exportDir != null) {
chooser.setCurrentDirectory(exportDir);
}
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.setMultiSelectionEnabled(false);
chooser.setDialogTitle(Bundle.ResultsManager_SelectFileOrDirDialogCaption());
chooser.setApproveButtonText(Bundle.ResultsManager_SaveButtonName());
chooser.setAcceptAllFileFilterUsed(false);
chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
return f.isDirectory() || f.getName().endsWith("." + (heapdump ? HEAPDUMP_EXTENSION : SNAPSHOT_EXTENSION)); //NOI18N
}
public String getDescription() {
if (heapdump) {
return Bundle.ResultsManager_ProfilerHeapdumpFileFilter(HEAPDUMP_EXTENSION);
}
return Bundle.ResultsManager_ProfilerSnapshotFileFilter(SNAPSHOT_EXTENSION);
}
});
if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) != JFileChooser.APPROVE_OPTION) {
return null; // cancelled by the user
}
// 2. process both cases and extract file name and extension to use
File file = chooser.getSelectedFile();
String targetExt = heapdump ? HEAPDUMP_EXTENSION : SNAPSHOT_EXTENSION;
if (file.isDirectory()) { // save to selected directory under default name
exportDir = chooser.getCurrentDirectory();
targetDir = FileUtil.toFileObject(FileUtil.normalizeFile(file));
targetName = defaultName;
} else { // save to selected file
exportDir = chooser.getCurrentDirectory();
targetDir = FileUtil.toFileObject(FileUtil.normalizeFile(exportDir));
String fName = file.getName();
// divide the file name into name and extension
int idx = fName.lastIndexOf('.'); // NOI18N
if (idx == -1) { // no extension
targetName = fName;
// extension will be used from source file
} else { // extension exists
if (heapdump || fName.endsWith("." + targetExt)) { // NOI18N
targetName = fName.substring(0, idx);
targetExt = fName.substring(idx + 1);
} else {
targetName = fName;
}
}
}
// 3. return a newly created FileObject
return new SelectedFile(targetDir, targetName, targetExt);
}
private boolean checkFileExists(SelectedFile sf) {
// check if the file already exists and if so prompt the user
FileObject existingFile = sf.folder.getFileObject(sf.fileName, sf.fileExt);
if (existingFile != null) {
if (!ProfilerDialogs.displayConfirmation(Bundle.ResultsManager_OverwriteFileDialogMsg(
sf.fileName + "." //NOI18N
+ sf.fileExt),
Bundle.ResultsManager_OverwriteFileDialogCaption())) {
return false; // cancelled by the user
}
try {
existingFile.delete();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, Bundle.ResultsManager_FileDeleteFailedMsg(e.getMessage()), e);
return false;
}
}
return true;
}
private void exportSnapshot(FileObject selectedSnapshot, FileObject targetFolder, String fileName, String fileExt) {
if (checkFileExists(new SelectedFile(targetFolder, fileName, fileExt))) {
try {
FileUtil.copyFile(selectedSnapshot, targetFolder, fileName, fileExt);
} catch (Throwable t) {
LOGGER.log(Level.INFO, t.getMessage(), t);
String msg = t.getLocalizedMessage().replace("<", "&lt;").replace(">", "&gt;"); // NOI18N
ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotExportFailedMsg(msg));
}
}
}
private LoadedSnapshot findAlreadyLoadedSnapshot(FileObject selectedFile) {
Iterator it = loadedSnapshots.iterator();
File f = FileUtil.toFile(selectedFile);
if (f == null) {
return null;
}
while (it.hasNext()) {
LoadedSnapshot ls = (LoadedSnapshot) it.next();
if ((ls.getFile() != null) && (ls.getFile().equals(f))) {
return ls;
}
}
return null;
}
private Lookup.Provider findProjectForSnapshot(FileObject selectedFile) {
return ProfilerStorage.getProjectFromFolder(selectedFile.getParent());
}
private LoadedSnapshot loadSnapshotFromFileObject(FileObject selectedFile)
throws IOException {
DataInputStream dis = null;
try {
InputStream is = selectedFile.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
dis = new DataInputStream(bis);
LoadedSnapshot ls = LoadedSnapshot.loadSnapshot(dis);
if (ls != null) {
ls.setFile(FileUtil.toFile(selectedFile));
ls.setProject(findProjectForSnapshot(selectedFile));
}
return ls;
} finally {
if (dis != null) {
dis.close();
}
}
}
private LoadedSnapshot loadSnapshotImpl(FileObject selectedFile)
throws IOException {
LoadedSnapshot ls = findAlreadyLoadedSnapshot(selectedFile);
if (ls != null) {
return ls;
}
ls = loadSnapshotFromFileObject(selectedFile);
if (ls != null) {
loadedSnapshots.add(ls);
fireSnapshotLoaded(ls);
}
return ls;
}
private ProfilingSettings readSettingsFromFile(FileObject fo) {
LoadedSnapshot ls = findAlreadyLoadedSnapshot(fo);
if (ls != null) {
return ls.getSettings();
}
DataInputStream dis = null;
try {
InputStream is = fo.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
dis = new DataInputStream(bis);
// data before settings
byte[] magicArray = new byte[LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.length()];
int len = dis.read(magicArray);
if ((len != LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.length())
|| !LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.equals(new String(magicArray))) {
return null;
}
byte majorVersion = dis.readByte();
byte minorVersion = dis.readByte();
int type = dis.readInt();
int compressedDataLen = dis.readInt();
int uncompressedDataLen = dis.readInt();
if (dis.skipBytes(compressedDataLen) != compressedDataLen) {
return null;
}
// settings data
int settingsLen = dis.readInt();
byte[] settingsBytes = new byte[settingsLen];
if (dis.read(settingsBytes) != settingsLen) {
return null;
}
// create settings
Properties props = new Properties();
ProfilingSettings settings = new ProfilingSettings();
ByteArrayInputStream bais2 = new ByteArrayInputStream(settingsBytes);
BufferedInputStream bufBais2 = new BufferedInputStream(bais2);
DataInputStream settingsDis = new DataInputStream(bufBais2);
try {
props.load(settingsDis);
} catch (IOException e) {
ProfilerLogger.log(e);
return null;
} finally {
settingsDis.close();
}
settings.load(props);
return settings;
} catch (Exception e) {
ProfilerLogger.log(e);
return null;
} finally {
try {
if (dis != null) {
dis.close();
}
} catch (IOException e) {
ProfilerLogger.log(e);
}
}
}
private int readTypeFromFile(FileObject fo) {
LoadedSnapshot ls = findAlreadyLoadedSnapshot(fo);
if (ls != null) {
return ls.getType();
}
DataInputStream dis = null;
try {
InputStream is = fo.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
dis = new DataInputStream(bis);
byte[] magicArray = new byte[LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.length()];
int len = dis.read(magicArray);
if ((len != LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.length())
|| !LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.equals(new String(magicArray))) {
return LoadedSnapshot.SNAPSHOT_TYPE_UNKNOWN;
}
byte majorVersion = dis.readByte();
byte minorVersion = dis.readByte();
int type = dis.readInt();
return type;
} catch (Exception e) {
return LoadedSnapshot.SNAPSHOT_TYPE_UNKNOWN;
} finally {
try {
if (dis != null) {
dis.close();
}
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
}