blob: e3570a5b70900a315e58c40c7df0c0f55ddef437 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2019 Red Hat, Inc. and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat - initial API and implementation
*******************************************************************************/
package org.eclipse.linuxtools.internal.callgraph.core;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.NotEnabledException;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ResourceLocator;
import org.eclipse.linuxtools.tools.launch.core.factory.RuntimeProcessFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;
public abstract class SystemTapView extends ViewPart {
private final String NEW_LINE = Messages.getString("SystemTapView.1"); //$NON-NLS-1$
public Composite masterComposite;
private Action kill;
protected String viewID;
private Action helpVersion;
protected Action saveFile;
protected Action openFile;
protected Action openDefault;
protected String sourcePath;
protected IMenuManager file;
private SystemTapParser parser;
/**
* This method will be called from GraphUIJob to load the view
* @param targetDisplay
* @param monitor
* @return Status.OK_STATUS to continue, Status.CANCEL_STATUS to abort
*/
public abstract IStatus initializeView(Display targetDisplay,
IProgressMonitor monitor);
public void layout() {
masterComposite.layout();
}
/**
* If view is not maximized it will be maximized
*/
public void maximizeIfUnmaximized() {
IWorkbenchPage page = this.getViewSite().getWorkbenchWindow().getActivePage();
if (page.getPartState(page.getActivePartReference()) != IWorkbenchPage.STATE_MAXIMIZED) {
IHandlerService handlerService = getSite().getService(IHandlerService.class);
try {
handlerService.executeCommand("org.eclipse.ui.window.maximizePart", null); //$NON-NLS-1$
} catch (ExecutionException | NotDefinedException | NotEnabledException | NotHandledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* Schedules the updateMethod job in a UI Thread. Does not return until
* updateMethod is complete.
*
* @throws InterruptedException
*/
public void update() throws InterruptedException {
ViewUIUpdater updater = new ViewUIUpdater("SystemTapView.update"); //$NON-NLS-1$
updater.schedule();
updater.join();
}
private class ViewUIUpdater extends UIJob {
public ViewUIUpdater(String name) {
super(name);
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
updateMethod();
return Status.OK_STATUS;
}
}
/**
* Method for fetching a parser object. This method should return
* the running parser, or else some features may not work. Create
* your own parser parameter, but please ensure that it extends
* SystemTapParser.
*
* @return
*/
public SystemTapParser getParser() {
return parser;
}
/**
* Method for setting the parser object of the view. Make this method return
* true if the parser is of the expected class, false if it is null or
* unexpected.
*
* @param parser
* @return
*/
public boolean setParser(SystemTapParser parser) {
this.parser = parser;
if (this.parser == null) {
return false;
}
return true;
}
/**
* Perform whatever actions are necessary to 'update' this viewer. It is
* recommended that the update function be called after the setParser method
* is called.
*/
public abstract void updateMethod();
/**
* Implement this method to set the viewID variable to the id of the view
* that extends SystemTapView and uses the core.systemtapview extension
* point.
*/
public abstract void setViewID();
/**
* Implement this method so that the Open button in the file menu created
* by <code>addFileMenu()</code> is able to actually open files. User will
* be prompted for a file to open.
*
* @return True if an open action should be created, false otherwise.
*/
protected abstract boolean createOpenAction();
/**
* Implement this method so that the Open default button in the file menu created
* by <code>addFileMenu()</code> is able to actually open default. The Open
* default button should open from a fixed location, usually the default output
* path if that is accessible..
*
* @return True if an open default action should be created, false otherwise.
*/
protected abstract boolean createOpenDefaultAction();
/**
* Create File menu -- calls the abstract protected methods
* <code>createOpenAction()</code> and <code>createOpenDefaultAction()</code>. Have
* these methods return false if you do not wish to create an Open or Open Default
* option in the File menu of your view.
*/
public void addFileMenu() {
IMenuManager menu = getViewSite().getActionBars().getMenuManager();
if (file == null) {
file = new MenuManager(Messages.getString("SystemTapView.FileMenu")); //$NON-NLS-1$
menu.add(file);
}
if (createOpenAction()) {
file.add(openFile);
}
if (createOpenDefaultAction()) {
file.add(openDefault);
}
createSaveAction();
file.add(saveFile);
}
public void addHelpMenu() {
IMenuManager menu = getViewSite().getActionBars().getMenuManager();
IMenuManager help = new MenuManager(Messages.getString("SystemTapView.Help")); //$NON-NLS-1$
menu.add(help);
createHelpActions();
help.add(helpVersion);
}
private void createHelpActions() {
helpVersion = new Action(Messages.getString("SystemTapView.Version")) { //$NON-NLS-1$
@Override
public void run() {
try {
Process pr = RuntimeProcessFactory.getFactory().exec("stap -V", null); //$NON-NLS-1$
BufferedReader buf = new BufferedReader(
new InputStreamReader(pr.getErrorStream()));
String line = ""; //$NON-NLS-1$
String message = ""; //$NON-NLS-1$
while ((line = buf.readLine()) != null) {
message += line + NEW_LINE;
}
try {
pr.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
Shell sh = new Shell();
MessageDialog.openInformation(sh, Messages
.getString("SystemTapView.StapVersion"), message); //$NON-NLS-1$
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
private void createSaveAction() {
//Save callgraph.out
saveFile = new Action(Messages.getString("SystemTapView.SaveMenu")){ //$NON-NLS-1$
@Override
public void run(){
Shell sh = new Shell();
FileDialog dialog = new FileDialog(sh, SWT.SAVE);
String filePath = dialog.open();
if (filePath != null) {
saveData(filePath);
}
}
};
}
protected void addKillButton() {
IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
kill = new Action(Messages.getString("SystemTapView.StopScript"), //$NON-NLS-1$
ResourceLocator.imageDescriptorFromBundle(CallgraphCorePlugin.PLUGIN_ID, "icons/progress_stop.gif") //$NON-NLS-1$
.get()) {
@Override
public void run() {
getParser().cancelJob();
}
};
mgr.add(kill);
setKillButtonEnabled(false);
}
public void setKillButtonEnabled(boolean val) {
if (kill != null) {
kill.setEnabled(val);
}
}
/**
* Implement this method to save data in whichever format your program
* needs. Keep in mind that the filePath variable should contain the
* filePath of the most recently opened file.
*
* @param sourcePath
*/
public void saveData(String targetFile) {
try {
File file = new File(targetFile);
file.delete();
file.createNewFile();
File sFile = new File(sourcePath);
if (!sFile.exists()) {
return;
}
try (FileInputStream fileIn = new FileInputStream(sFile); FileOutputStream fileOut = new FileOutputStream(file);
FileChannel channelIn = fileIn.getChannel(); FileChannel channelOut = fileOut.getChannel()){
if (channelIn == null || channelOut == null) {
return;
}
long size = channelIn.size();
MappedByteBuffer buf = channelIn.map(
FileChannel.MapMode.READ_ONLY, 0, size);
channelOut.write(buf);
}
} catch (IOException e) {
CallgraphCorePlugin.logException(e);
}
}
public void setSourcePath(String file) {
sourcePath = file;
}
}