sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/AnalyserDataProcessor.java
/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.carbide.cpp.internal.pi.analyser;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.progress.IProgressService;
import com.nokia.carbide.cpp.internal.pi.manager.PluginInitialiser;
import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
import com.nokia.carbide.cpp.internal.pi.model.RefinableTrace;
import com.nokia.carbide.cpp.internal.pi.model.TraceDataRepository;
import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable;
import com.nokia.carbide.cpp.internal.pi.test.AnalysisInfoHandler;
import com.nokia.carbide.cpp.internal.pi.test.IProvideTraceAdditionalInfo;
import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest;
import com.nokia.carbide.cpp.internal.pi.visual.PICompositePanel;
import com.nokia.carbide.cpp.pi.PiPlugin;
import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
import com.nokia.carbide.cpp.pi.importer.SampleImporter;
import com.nokia.carbide.cpp.pi.util.GeneralMessages;
import com.nokia.carbide.cpp.pi.util.PIExceptionRuntime;
import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
/*
* Class for abstracting data processing core routine for open and import
*/
public class AnalyserDataProcessor {
protected static final int MAX_CPU = 4;
// whether the profile file was read correctly
public static int STATE_OK = 0;
public static int STATE_IMPORTING = 1;
public static int STATE_OPENING = 2;
public static int STATE_TIMESTAMP = 3;
public static int STATE_CANCELED = 4;
public static int STATE_INVALID = 5;
public static int TOTAL_PROGRESS_COUNT = 10000;
static AnalyserDataProcessor instance = null;
// following states should be cleanup for every run
// There should be only one progress monitor used by data processor
// regardless the task, and we don't want to expose public interface
// that juggle around progress monitor, to avoid messy situation of
// multiple progress indicator
static IProgressMonitor mp = null;
static Exception lastException = null;
private static int analyserDataProcessorState = STATE_INVALID;
private AnalyserDataProcessor() {
// singleton
}
public static AnalyserDataProcessor getInstance() {
if (instance == null) {
instance = new AnalyserDataProcessor();
}
return instance;
}
// return whether the processed data file was successfully read
public int getState() {
return analyserDataProcessorState;
}
public void setImportFailed() {
analyserDataProcessorState = STATE_INVALID;
}
private void setProgressMonitor (IProgressMonitor progressMonitor) {
mp = progressMonitor;
}
private IProgressMonitor getProgressMonitor() {
return mp;
}
public Exception getLastException() {
return lastException;
}
private void importNewAnalysis(Hashtable<Integer,String> traceFileNames, int uid, List<ITrace> pluginsToUse) throws InterruptedException, InvocationTargetException {
analyserDataProcessorState = STATE_IMPORTING;
final int workUnitsForImport = TOTAL_PROGRESS_COUNT * 60 / 100;
int workUnitsLeft = workUnitsForImport * 99 / 100;
checkCancelledThrowIE();
// loop through all the plugins associated with traces
int numberOfPlugins = pluginsToUse.size();
for (ITrace plugin : pluginsToUse) {
int traceId = plugin.getTraceId();
AbstractPiPlugin p = (AbstractPiPlugin)plugin;
// map trace plugins to this analysis data
NpiInstanceRepository.getInstance().addPlugin(uid, p);
if (traceId != -1)
{
if (traceId == 1){ //support SMP by expecting one file per CPU
List<File> files = new ArrayList<File>();
for (int i = 0; i < MAX_CPU; i++) {
int smpTraceId = traceId + i * 20;
{
String fileName = traceFileNames.get(smpTraceId);
if (fileName != null && fileName.endsWith(".dat")) //$NON-NLS-1$
{
File traceFile = new File(fileName);
if (traceFile.exists()){
files.add(traceFile);
}
}
}
}
ProfileReader.getInstance().readTraceFile(plugin, files.toArray(new File[files.size()]), this,uid);
} else {
String fileName = traceFileNames.get(traceId);
if (fileName != null)
{
File traceFile = new File(fileName);
if (traceFile.exists())
if (traceFile.getName().endsWith(".dat")) //$NON-NLS-1$
ProfileReader.getInstance().readTraceFile(plugin, traceFile, this,uid);
}
}
}
// assume this load takes 39%
getProgressMonitor().worked((workUnitsForImport * 39 / 100) / numberOfPlugins);
checkCancelledThrowIE();
workUnitsLeft -= (workUnitsForImport * 39 / 100) / numberOfPlugins;
}
getProgressMonitor().worked((workUnitsForImport * 60 / 100) - workUnitsLeft);
checkCancelledThrowIE();
workUnitsLeft = (workUnitsForImport * 60 / 100);
// refine any traces whose addresses can be refined
Iterator<ParsedTraceData> traces = TraceDataRepository.getInstance().getTraceCollectionIter(uid);
if (traces == null) {
throw new InvocationTargetException(new PIExceptionRuntime(Messages.getString("AnalyserDataProcessor.0") + uid + Messages.getString("AnalyserDataProcessor.1"))); //$NON-NLS-1$ //$NON-NLS-2$
}
while (traces.hasNext())
{
ParsedTraceData trace = (ParsedTraceData)traces.next();
// for those trace data items that can be refined
if (trace.traceData instanceof RefinableTrace)
{
Iterator<ParsedTraceData> traces2 = TraceDataRepository.getInstance().getTraceCollectionIter(uid);
while (traces2.hasNext())
{
ParsedTraceData trace2 = traces2.next();
// refine with other resolvers but not with own (which has been used already)
if (!trace2.equals(trace) && trace2.functionResolvers != null)
{
for (int i = 0; i < trace2.functionResolvers.length; i++)
{
FunctionResolver fr = trace2.functionResolvers[i];
System.out.println(Messages.getString("AnalyserDataProcessor.2") + trace.traceData.getClass().getName() + Messages.getString("AnalyserDataProcessor.3") + fr.getResolverString()); //$NON-NLS-1$ //$NON-NLS-2$
((RefinableTrace)trace.traceData).refineTrace(fr);
}
}
checkCancelledThrowIE();
}
// after all refinement is done, do any final touches to the samples
((RefinableTrace)trace.traceData).finalizeTrace();
}
getProgressMonitor().worked(workUnitsLeft / 2);
checkCancelledThrowIE();
workUnitsLeft -= workUnitsLeft / 2;
}
// Should move resolver out of trace, PI only need resolver in import phase, trace is more of a
// core data in NPI file; before that, we would just strip all resolvers here
Iterator<ParsedTraceData> tracesItr = TraceDataRepository.getInstance().getTraceCollectionIter(uid);
while (tracesItr.hasNext()) {
ParsedTraceData ptd = tracesItr.next();
ptd.functionResolvers = null;
}
System.gc();
}
private void loadExistingAnalysis(final Composite parent, final String analysisFilename, final String displayName, final int uid) throws InvocationTargetException, InterruptedException {
assertThrowITE(NpiInstanceRepository.getInstance().activeUid() == uid, Messages.getString("AnalyserDataProcessor.4")); //$NON-NLS-1$
// do the loading part with indicator in non-UI thread
final IProgressMonitor pm = getProgressMonitor();
pm.worked(1);
class LoadRunnable implements Runnable {
IOException myIOE = null;
InterruptedException myIE =null;
public void handleException () throws InvocationTargetException, InterruptedException {
if (myIOE != null) {
String reason = Messages.getString("AnalyserDataProcessor.12") + analysisFilename; //$NON-NLS-1$
if (myIOE.getMessage() != null) {
reason += " " + myIOE.getMessage(); //$NON-NLS-1$
}
assertThrowITE(myIOE, reason);
}
if (myIE != null) {
throw myIE;
}
}
public void run() {
try {
ProfileReader.getInstance().loadAnalysisFile(analysisFilename, displayName, pm, uid);
} catch (IOException e) {
myIOE = e;
} catch (InterruptedException e) {
myIE = e;
}
}
}
LoadRunnable loadRunnable = new LoadRunnable();
new Thread(loadRunnable).run();
loadRunnable.handleException();
checkCancelledThrowIE();
processTraceDrawAndResize(parent, false);
}
// called by createPage() of PIPageEditor
public void openNpiForPIPageEditor(final URI analysisFileURI, final Composite parent, final int uid) {
boolean isImport = analyserDataProcessorState == STATE_IMPORTING;
final String displayName = new java.io.File(analysisFileURI).getName();
if (isImport && getProgressMonitor() != null) {
//import is already wrapped in runnable, and we should have progressmonitor
getProgressMonitor().setTaskName(Messages.getString("AnalyserDataProcessor.5") + displayName); //$NON-NLS-1$
try {
analyserDataProcessorState = STATE_OPENING;
// by saying isImport true, we assume trace is set up proper in repository
processTraceDrawAndResize(parent, true);
analyserDataProcessorState = STATE_OK;
if (false)
internalOpenNPI (analysisFileURI, parent, uid);
} catch (InvocationTargetException e) {
analyserDataProcessorState = STATE_INVALID;
String error = Messages.getString("AnalyserDataProcessor.6") + e.getTargetException().getMessage() + Messages.getString("AnalyserDataProcessor.7"); //$NON-NLS-1$ //$NON-NLS-2$
if (e.getTargetException().getStackTrace() != null) {
StringWriter sw = new StringWriter ();
PrintWriter pw = new PrintWriter(sw);
e.getTargetException().printStackTrace(pw);
error += sw.toString() + "\n"; //$NON-NLS-1$
}
GeneralMessages.showErrorMessage(error);
} catch (InterruptedException e) {
String error = Messages.getString("AnalyserDataProcessor.8") + e.getMessage() + Messages.getString("AnalyserDataProcessor.9"); //$NON-NLS-1$ //$NON-NLS-2$
analyserDataProcessorState = STATE_CANCELED;
} catch (Exception e) {
analyserDataProcessorState = STATE_INVALID;
String error = Messages.getString("AnalyserDataProcessor.6") + e.getMessage() + Messages.getString("AnalyserDataProcessor.7"); //$NON-NLS-1$ //$NON-NLS-2$
if (e.getStackTrace() != null) {
StringWriter sw = new StringWriter ();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
error += sw.toString() + "\n"; //$NON-NLS-1$
}
GeneralMessages.showErrorMessage(error);
}
} else {
setUp();
//open need to be wrapped in runnable, and we should set progressmonitor
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
IRunnableWithProgress runnable= new IRunnableWithProgress() {
public void run(IProgressMonitor progressMonitor)
throws InvocationTargetException, InterruptedException {
setProgressMonitor(progressMonitor);
progressMonitor.beginTask(Messages.getString("AnalyserDataProcessor.10") + displayName, AnalyserDataProcessor.TOTAL_PROGRESS_COUNT * 20 / 100); //$NON-NLS-1$
internalOpenNPI (analysisFileURI, parent, uid);
}
};
try {
progressService.busyCursorWhile(runnable);
} catch (InvocationTargetException e) {
analyserDataProcessorState = STATE_INVALID;
} catch (InterruptedException e) {
analyserDataProcessorState = STATE_CANCELED;
}
}
getProgressMonitor().done();
}
private void internalOpenNPI(final URI analysisFileURI, final Composite parent, final int uid) throws InvocationTargetException, InterruptedException {
analyserDataProcessorState = STATE_OPENING;
if (analysisFileURI == null) {
assertThrowITE(false, Messages.getString("AnalyserDataProcessor.11")); //$NON-NLS-1$
return;
}
String filePath = null;
String displayName = null;
filePath = analysisFileURI.getPath();
displayName = new java.io.File(analysisFileURI).getName();
loadExistingAnalysis(parent, filePath, displayName, uid);
analyserDataProcessorState = STATE_OK;
}
public void importSaveAndOpen(final IFile analysisFile, boolean pollTillNpiSaved, final List<ITrace> pluginsToUse) {
analyserDataProcessorState = STATE_IMPORTING;
setProgressMonitor(null);
final int uid = NpiInstanceRepository.getInstance().register(null);
setUp();
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
IRunnableWithProgress runnableImportAndSave = new IRunnableWithProgress() {
public void run(IProgressMonitor progressMonitor)
throws InvocationTargetException, InterruptedException {
importAndSave(analysisFile, uid, pluginsToUse, null,progressMonitor);
}
};
IRunnableWithProgress runnableOpen = new IRunnableWithProgress() {
public void run(IProgressMonitor arg0)
throws InvocationTargetException, InterruptedException {
// open the saved file
openFile(analysisFile);
}
};
try {
progressService.busyCursorWhile(runnableImportAndSave);
final WorkspaceJob saveNpi = new WorkspaceJob (Messages.getString("AnalyserDataProcessor.savingImportedFile")) { //$NON-NLS-1$
public IStatus runInWorkspace(IProgressMonitor monitor)
throws CoreException {
try {
ProfileReader.getInstance().writeAnalysisFile(analysisFile.getLocation().toString(), monitor, null, uid);
} catch (InvocationTargetException e) {
return new Status(IStatus.ERROR, PiPlugin.PLUGIN_ID, Messages.getString("AnalyserDataProcessor.invocationTargetException"), e); //$NON-NLS-1$ //$NON-NLS-2$
} catch (InterruptedException e) {
return new Status(IStatus.CANCEL, PiPlugin.PLUGIN_ID, Messages.getString("AnalyserDataProcessor.interruptedException"), e); //$NON-NLS-1$ //$NON-NLS-2$
}
return new Status(IStatus.OK, PiPlugin.PLUGIN_ID, Messages.getString("AnalyserDataProcessor.ok"), null); //$NON-NLS-1$ //$NON-NLS-2$
}
};
progressService.busyCursorWhile(runnableOpen);
saveNpi.setPriority(Job.DECORATE);
saveNpi.addJobChangeListener(new IJobChangeListener () {
public void aboutToRun(IJobChangeEvent event) {
}
public void awake(IJobChangeEvent event) {
}
public void done(IJobChangeEvent event) {
if (saveNpi.getResult().getSeverity() != IStatus.OK) {
handleRunnableException (saveNpi.getResult().getException(), uid, analysisFile);
}
}
public void running(IJobChangeEvent event) {
}
public void scheduled(IJobChangeEvent event) {
}
public void sleeping(IJobChangeEvent event) {
}
});
saveNpi.schedule();
if (pollTillNpiSaved) {
while (saveNpi.getState() != Job.NONE) {
// until it's done
}
}
} catch (InvocationTargetException e) {
handleRunnableException(e, uid, analysisFile);
} catch (InterruptedException e) {
handleRunnableException(e, uid, analysisFile);
}
}
public void importSave(final IFile analysisFile, final List<ITrace> pluginsToUse, String suffixTaskName, IProgressMonitor monitor) {
analyserDataProcessorState = STATE_IMPORTING;
setUp();
setProgressMonitor(monitor);
final int uid = NpiInstanceRepository.getInstance().register(null);
try{
importAndSave(analysisFile, uid, pluginsToUse, suffixTaskName, monitor);
ProfileReader.getInstance().writeAnalysisFile(analysisFile.getLocation().toString(), monitor, suffixTaskName, uid);
analyserDataProcessorState = STATE_OK;
}catch (Exception e) {
handleRunnableException(e, uid, analysisFile);
monitor.setCanceled(true);
}
}
private void importAndSave(final IFile analysisFile, final int uid, List<ITrace> pluginsToUse, String suffixTaskName,IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException{
if(progressMonitor == null){
progressMonitor = new NullProgressMonitor();
}
setProgressMonitor(progressMonitor);
String taskName = Messages.getString("AnalyserDataProcessor.17") + analysisFile.getName();; //$NON-NLS-1$
if(suffixTaskName != null){
taskName += " "+suffixTaskName; //$NON-NLS-1$
}
progressMonitor.beginTask(taskName, TOTAL_PROGRESS_COUNT); //$NON-NLS-1$
progressMonitor.setTaskName(taskName);
// open a profile data file that should contain at least thread/address information
// import new .dat
assertThrowITE(SampleImporter.getInstance().validate(), Messages.getString("AnalyserDataProcessor.18")); //$NON-NLS-1$
// invoke analysis-specific plugin instances
PluginInitialiser.invokePluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
StreamFileParser stp;
try {
stp = new StreamFileParser(new File(SampleImporter.getInstance().getDatFileName()));
Hashtable<Integer,String> traceFileNames = new Hashtable<Integer,String>();
ArrayList<File> tracesForCleanUp = new ArrayList<File>();
// loop through all the plugins associated with traces and note their trace IDs names
for (ITrace plugin : pluginsToUse) {
File tempFile;
int traceId = plugin.getTraceId();
if (traceId != -1)
{
try {
if (traceId == 1) {// the SMP change; separate temp data files for each CPU
for (int i = 0; i < MAX_CPU; i++) {
int smpTraceId = traceId + i * 20;
tempFile = stp.getTempFileForTraceType(smpTraceId);
if (tempFile != null) {
tempFile.deleteOnExit();
traceFileNames.put(smpTraceId, tempFile.getAbsolutePath());
tracesForCleanUp.add(tempFile);
}
}
} else {
tempFile = stp.getTempFileForTraceType(traceId);
if (tempFile != null)
{
tempFile.deleteOnExit();
traceFileNames.put(traceId, tempFile.getAbsolutePath());
tracesForCleanUp.add(tempFile);
}
}
} catch (IOException e) {
throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.25")); //$NON-NLS-1$
}
}
}
// import a new analysis
importNewAnalysis(traceFileNames, uid, pluginsToUse);
// clean up temp file for each trace
for (File traceFile : tracesForCleanUp) {
traceFile.delete();
}
} catch (IOException e) {
throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.26") + SampleImporter.getInstance().getDatFileName()); //$NON-NLS-1$
}
if (progressMonitor.isCanceled()) {
throw new InterruptedException(Messages.getString("AnalyserDataProcessor.19")); //$NON-NLS-1$
}
// give the .NPI file null contents
byte[] b = new byte[0];
try {
analysisFile.create(new ByteArrayInputStream(b), true, null);
// make sure we can open an input stream to the trace file
analysisFile.getContents();
} catch (CoreException e) {
throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.14") + analysisFile.getName()); //$NON-NLS-1$
}
// extract additional info from importer
int numberOfTraces = 0;
Iterator<ParsedTraceData> enuTraces = TraceDataRepository.getInstance().getTraceCollectionIter(uid);
AnalysisInfoHandler handler = NpiInstanceRepository.getInstance().activeUidGetAnalysisInfoHandler();
// for all traces exist in .dat set up their additional info
while (enuTraces.hasNext()) {
Object object = enuTraces.next();
numberOfTraces++;
if (object instanceof ParsedTraceData) {
ParsedTraceData parsedTraceData = (ParsedTraceData) object;
if (parsedTraceData.traceData != null) {
Class traceClass = parsedTraceData.traceData.getClass();
// this code is clumsy because the plugin, not the trace, has the trace ID info
Enumeration<AbstractPiPlugin> enuPlugins = PluginInitialiser.getPluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
while (enuPlugins.hasMoreElements())
{
ITrace plugin = (ITrace)enuPlugins.nextElement();
// only do when trace exist in .data
if (traceClass == plugin.getTraceClass()) {
if (plugin instanceof IProvideTraceAdditionalInfo) {
((IProvideTraceAdditionalInfo)plugin).setupInfoHandler(handler);
}
}
}
}
}
}
// refresh so project know the update done by Java(non-Eclipse API)
try {
analysisFile.refreshLocal(0, null);
} catch (CoreException e) {
throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.15") + analysisFile.getName()); //$NON-NLS-1$
}
}
private void openFile(final IFile analysisFile) {
// open the saved file
if (analysisFile.exists() && AnalyserDataProcessor.getInstance().getState() == STATE_IMPORTING ) {
// open the file itself
// need to open in UI context
Display.getDefault().syncExec(new Runnable() {
public void run() {
IEditorPart editor = null;
try {
editor = IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() , analysisFile, true);
} catch (PartInitException e) {
try {
assertThrowITE(e, analysisFile.getName() + Messages.getString("AnalyserDataProcessor.24")); //$NON-NLS-1$
} catch (InvocationTargetException e1) {
//already set data structure proper, do nothing
}
}
if (AnalyserDataProcessor.getInstance().getState() == STATE_CANCELED) {
// close the editor file view
editor.getSite().getPage().closeEditor(editor, false);
} else if (AnalyserDataProcessor.getInstance().getState() != STATE_OK ) {
// close the editor file view
editor.getSite().getPage().closeEditor(editor, false);
}
}
});
}
}
private void handleRunnableException(Throwable throwable, final int uid, IFile analysisFile) {
NpiInstanceRepository.getInstance().unregister(uid);
if (throwable instanceof InvocationTargetException) {
String error = Messages.getString("AnalyserDataProcessor.20"); //$NON-NLS-1$
if (throwable.getMessage() != null) {
error += throwable.getMessage() + "\n"; //$NON-NLS-1$
}
error += Messages.getString("AnalyserDataProcessor.21"); //$NON-NLS-1$ //$NON-NLS-2$
if (((InvocationTargetException)throwable).getTargetException().getStackTrace() != null) {
StringWriter sw = new StringWriter ();
PrintWriter pw = new PrintWriter(sw);
((InvocationTargetException)throwable).printStackTrace(pw);
error += sw.toString() + "\n"; //$NON-NLS-1$
}
GeneralMessages.showErrorMessage(error);
analyserDataProcessorState = STATE_INVALID;
} else if (throwable instanceof InterruptedException) {
GeneralMessages.showErrorMessage(Messages.getString("AnalyserDataProcessor.22")); //$NON-NLS-1$
analyserDataProcessorState = STATE_CANCELED;
} else {
String error = Messages.getString("AnalyserDataProcessor.20"); //$NON-NLS-1$
if (throwable.getStackTrace() != null) {
StringWriter sw = new StringWriter ();
PrintWriter pw = new PrintWriter(sw);
((InvocationTargetException)throwable).printStackTrace(pw);
error += sw.toString() + "\n"; //$NON-NLS-1$
}
GeneralMessages.showErrorMessage(error);
analyserDataProcessorState = STATE_INVALID;
}
// don't leave any garbage behind if we failed or bailed
if (analysisFile != null && AnalyserDataProcessor.getInstance().getState() != STATE_OK ) {
java.io.File javaFile = new java.io.File(analysisFile.getLocation().toString());
boolean deleted = javaFile.delete();
if (deleted == false){
try {
analysisFile.delete(true, null);
} catch (CoreException ce) {
ce.printStackTrace();
}
}
try {
// force Eclipse to be aware of the removed file by doing an IFile refresh
analysisFile.refreshLocal(0, null);
} catch (CoreException ce) {
ce.printStackTrace();
}
}
}
// standalone for save as
public void saveAnalysis(final String filename, final int uid) throws InvocationTargetException, InterruptedException {
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
IRunnableWithProgress runnable= new IRunnableWithProgress() {
public void run(IProgressMonitor progressMonitor)
throws InvocationTargetException, InterruptedException {
saveAnalysisInternal(filename, uid);
}
};
try {
progressService.busyCursorWhile(runnable);
} catch (InvocationTargetException e) {
analyserDataProcessorState = STATE_INVALID;
} catch (InterruptedException e) {
analyserDataProcessorState = STATE_CANCELED;
}
}
// save profiling data to NPI file
private void saveAnalysisInternal(final String filename, final int uid) throws InvocationTargetException, InterruptedException {
ProfileReader.getInstance().writeAnalysisFile(filename, getProgressMonitor(), null,uid);
}
private void processVisualizableItem(ITrace plugin)
{
IVisualizable visualizable = (IVisualizable)plugin;
if (!visualizable.arePagesCreated())
{
// create any editor pages
for (int i = 0; i < visualizable.getCreatePageCount(); i++)
{
int index = visualizable.getCreatePageIndex(i);
ArrayList<ProfileVisualiser> pages = NpiInstanceRepository.getInstance().activeUidGetProfilePages();
if (pages != null) {
// if we don't care what the page index is, or the index is too big, add it to the end
if ((index == PIPageEditor.NEXT_AVAILABLE_PAGE) || (index > pages.size())) {
index = pages.size();
// let the plugin know what index we assigned
visualizable.setPageIndex(i, index);
}
ProfileVisualiser pV = visualizable.createPage(index);
// add the page to the editor
if (pV != null)
pages.add(index, pV);
}
}
}
int uid = NpiInstanceRepository.getInstance().activeUid();
// determine how many graphs to draw (several may get added to the same page)
for (int i = 0; i < visualizable.getGraphCount(); i++)
{
GraphDrawRequest gdr = visualizable.getDrawRequest(i);
IGenericTraceGraph gtg = visualizable.getTraceGraph(i);
int pageNumber = visualizable.getPageNumber(i);
ProfileVisualiser page = NpiInstanceRepository.getInstance().getProfilePage(uid, pageNumber);
if (gtg != null)
{
page.getTopComposite().addGraphComponent(gtg, visualizable.getClass(), gdr);
}
Integer lastSample = visualizable.getLastSample(i);
if (lastSample != null)
{
page.setLastSampleX(lastSample.intValue());
}
}
}
private void processTraceDrawAndResize(final Composite parent, boolean isImport) {
// if it is import, everything is already read in place, otherwise
// setup those from object file read
if (!isImport) {
ProfileReader.getInstance().processDataReadFromNpiFile(this);
}
int uid = NpiInstanceRepository.getInstance().activeUid();
// initialize trace and do visual
ArrayList<AbstractPiPlugin> plugins = NpiInstanceRepository.getInstance().getPlugins(uid);
for (final AbstractPiPlugin plugin : plugins) {
if (plugin instanceof ITrace) {
final ParsedTraceData parsedData = TraceDataRepository.getInstance().getTrace(uid, ((ITrace)plugin).getTraceClass());
if (parsedData != null) {
final ITrace pluginTrace = (ITrace)plugin;
pluginTrace.initialiseTrace(parsedData.traceData);
// do the graphic painting with indicator, SWT require it to be in UI thread
if (plugin instanceof IVisualizable) {
Display.getDefault().syncExec( new Runnable() {
public void run() {
processVisualizableItem(pluginTrace);
}
});
}
}
}
}
if (!isImport) {
ProfileReader.getInstance().setAddtionalDataForRecordable();
}
ProfileReader.getInstance().setTraceMenus(NpiInstanceRepository.getInstance().getPlugins(uid), uid);
// do the graphic painting with indicator, SWT require it to be in UI thread
Display.getDefault().syncExec( new Runnable() {
public void run() {
parent.addPaintListener( new PaintListener () {
public void paintControl(PaintEvent arg0) {
if(parent.getBounds().width > 0) {
ArrayList<ProfileVisualiser> pages = NpiInstanceRepository.getInstance().activeUidGetProfilePages();
// make sure we are called after the pages have been created?
if (pages.size() > 0) {
for (final ProfileVisualiser page : pages) {
// NOTE: This assumes that the first profile page has a graph
final PICompositePanel visibleComposite = page.getTopComposite();
visibleComposite.performZoomToGraph(visibleComposite, parent.getBounds().width);
//TODO uncomment when performance issues relating to fcc are solved
//Select whole graph
//visibleComposite.selectWholeGraph();
}
// scale to whole trace only once
parent.removePaintListener(this);
}
}
}
});
}
});
}
// This is for test automation, removing time stamps, so we can diff .npi
public void importForStrippingTimeStamp(final Composite parent) {
if (SampleImporter.getInstance().isStrippingTimeStamp()) {
// had to do this monkey business for pi validation because
// serialization is an untestable format
// read file
final SampleImporter sampleImporter = SampleImporter.getInstance();
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
IRunnableWithProgress runnable= new IRunnableWithProgress() {
public void run(IProgressMonitor progressMonitor)
throws InvocationTargetException,
InterruptedException {
setProgressMonitor(progressMonitor);
progressMonitor.beginTask(Messages.getString("AnalyserDataProcessor.23"), 100); //$NON-NLS-1$
try {
int uid = NpiInstanceRepository.getInstance().activeUid();
loadExistingAnalysis(parent, sampleImporter.getDatFileName(), sampleImporter.getDatFileName(), uid);
// time stample differs for every save, take it out
AnalysisInfoHandler infoHandler = NpiInstanceRepository.getInstance().activeUidGetAnalysisInfoHandler();
if (infoHandler != null) {
infoHandler.eraseTimeStamp();
}
// write file
saveAnalysisInternal(sampleImporter.getPiFileName(), uid);
} catch (Exception e) {
e.printStackTrace();
}
}
};
try {
progressService.busyCursorWhile(runnable);
} catch (InvocationTargetException e) {
analyserDataProcessorState = STATE_INVALID;
e.printStackTrace();
} catch (InterruptedException e) {
analyserDataProcessorState = STATE_CANCELED;
e.printStackTrace();
}
setProgressMonitor(null);
}
}
// catch all for any exception, so we can print an error stack trace page later
private void assertThrowITE(boolean cond, String message) throws InvocationTargetException {
if (!cond) {
PIExceptionRuntime pire = new PIExceptionRuntime(message); //$NON-NLS-1$
InvocationTargetException ite = new InvocationTargetException(pire);
lastException = ite;
analyserDataProcessorState = STATE_INVALID;
if (getProgressMonitor() != null) {
getProgressMonitor().done();
}
GeneralMessages.showErrorMessage(message);
throw ite;
}
}
private void assertThrowITE(Exception e, String message) throws InvocationTargetException {
InvocationTargetException ite;
if (message != null) {
ite = new InvocationTargetException(e, message);
} else {
ite = new InvocationTargetException(e);
}
lastException = ite;
analyserDataProcessorState = STATE_INVALID;
if (getProgressMonitor() != null) {
getProgressMonitor().done();
}
GeneralMessages.showErrorMessage(message);
throw ite;
}
// General handling for Cancel operation
public void checkCancelledThrowIE() throws InterruptedException {
if (getProgressMonitor() != null && getProgressMonitor().isCanceled()) {
InterruptedException ie = new InterruptedException();
analyserDataProcessorState = STATE_CANCELED;
throw ie;
}
}
private void setUp() {
if (getProgressMonitor() != null) {
getProgressMonitor().done();
setProgressMonitor(null);
}
lastException = null;
analyserDataProcessorState = STATE_OK;
}
}