-
Couldn't load subscription status.
- Fork 0
Create a new Framesoc tool
This page describes how to create a new Framesoc tool. Within this tutorial we also provide some usage example of the Framesoc Bus and the query API. The tutorial has been developed using Eclipse Luna and Framesoc v1.0.6. The corresponding source code is available in the fr.inria.soctrace.framesoc.tutorials.tool plugin of this repository.
- Configure a working Framesoc development environment, as described here.
A Framesoc tool is an Eclipse plugin extending the fr.inria.soctrace.framesoc.core.tool extension point defined in the fr.inria.soctrace.framesoc.core plugin. A Framesoc tool can be launched by Framesoc, perform an analysis and produce analysis results. These results can be stored in the Framesoc database. More details about tool and analysis result representation in the Framesoc datamodel are available in the Technical Report RT-427 .
-
Create a new plugin: File -> New -> Plug-in Project.
- Specify as project name
fr.inria.soctrace.framesoc.tutorials.tooland press Next. - Do not change anything and press Next again.
- Uncheck the Create a plug-in using one of the templates option, then press Finish.
- Specify as project name
-
Open the file
META-INF/MANIFEST.MF, if not already opened automatically, to add the required dependencies.-
This file is normally opened using the Plug-in Manifest Editor.
-
In this editor, select the Dependencies tab and press Add.
-
A dialog is shown: in the text field write
fr.inria.soctrace.liband add all the plugins of the Framesoc library. -
Press Add again, and this time write
fr.inria.soctrace.framesocin order to add the pluginsfr.inria.soctrace.framesoc.coreandfr.inria.soctrace.framesoc.ui. -
At this point your list of required plugins should contain:
org.eclipse.ui org.eclipse.core.runtime fr.inria.soctrace.lib.model fr.inria.soctrace.lib.query fr.inria.soctrace.lib.search fr.inria.soctrace.lib.slf4j fr.inria.soctrace.lib.storage fr.inria.soctrace.lib.utils fr.inria.soctrace.framesoc.core fr.inria.soctrace.framesoc.ui
-
-
Create the tool extension.
- Open the Extensions tab and press Add.
- Write
fr.inria.soctrace.framesoc.core.toolin the filter, and select the corresponding extension point. - Press Finish
- Right-click on the extension you just created, then New -> tool.
-
The documentation of the extension point fields can be accessed selecting the
fr.inria.soctrace.framesoc.core.toolline and clicking on Show extension point description on the right.id - The ID of the tool. This is NOT the database ID. It is an identificator having the same format of java packages (i.e., x.y.z.k). Note that each tool must have a globally unique id in the system. class - The main class of the tool, extending the FramesocTool abstract class. See its documentation for more details. type - The type of the tool. name - The name of the tool. Note that each tool must have a globally unique name in the system. doc - Launching documentation. Optional. -
Fill the the extension element details as follow:
- id:
fr.inria.soctrace.framesoc.tutorials.tool.example - class:
fr.inria.soctrace.framesoc.tutorials.tool.ExampleTool - type:
ANALYSIS - name:
Framesoc Tutorial Tool - doc:
Launch the tool and enjoy.
- id:
-
Create the class needed by the extension.
-
Click on the
classlink. -
Do not change anything and press Finish
-
The following class should be automatically created:
package fr.inria.soctrace.framesoc.tutorials.tool; import fr.inria.soctrace.framesoc.core.tools.model.FramesocTool; import fr.inria.soctrace.framesoc.core.tools.model.IFramesocToolInput; public class ExampleTool extends FramesocTool { public ExampleTool() { // TODO Auto-generated constructor stub } @Override public void launch(IFramesocToolInput input) { // TODO Auto-generated method stub } }
-
Add the following line to the
launch()method body:System.out.println("Hello World!");
-
Try to launch the Eclipse Application and test the tool.
- Right-click on the tool plugin, Run as -> Eclipse Application.
- Framesoc -> Trace Analysis -> Launch Analysis Tool.
- Select the Framesoc Tutorial Tool and press OK.
- In the console of the development Eclipse, you should see
Hello World!.
-
Up to this point, our tool is simply launched by Framesoc with no input. A plugin tool can specify the form of is input by extending the extension point fr.inria.soctrace.framesoc.ui.input.toolInput. This extension point enables to specify a factory class that will be used to create a graphical composite that extends a given base class. This composite will contain the graphical elements that the user will use to specify the input.
-
Create an extension to the
fr.inria.soctrace.framesoc.ui.input.toolInputextension point, following the same procedure as before for thetoolextension point. -
Fill the extension element details as follow:
- toolId:
fr.inria.soctrace.framesoc.tutorials.tool.example - compositeFactory:
fr.inria.soctrace.framesoc.tutorials.tool.ExampleToolInputCompositeFactory
- toolId:
-
As done before, click on the link corresponding to the class (
compositeFactorythis time) and press Finish. The factory class is automatically created and has the following form:package fr.inria.soctrace.framesoc.tutorials.tool; import org.eclipse.swt.widgets.Composite; import fr.inria.soctrace.framesoc.ui.input.AbstractToolInputComposite; import fr.inria.soctrace.framesoc.ui.input.AbstractToolInputCompositeFactory; public class ExampleToolInputCompositeFactory extends AbstractToolInputCompositeFactory { public ExampleToolInputCompositeFactory() { // TODO Auto-generated constructor stub } @Override public AbstractToolInputComposite getComposite(Composite parent, int style) { // TODO Auto-generated method stub return null; } }
The API of this factory requires to provide a graphical composite for the input. This composite extends the
AbstractToolInputCompositebase class. -
Modify the factory
getComposite()method as follows:@Override public AbstractToolInputComposite getComposite(Composite parent, int style) { return new ExampleToolInputComposite(parent, style); }
-
Create the composite class
fr.inria.soctrace.framesoc.tutorials.tool.ExampleToolInputComposite, using the following code:package fr.inria.soctrace.framesoc.tutorials.tool; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import fr.inria.soctrace.framesoc.core.tools.model.IFramesocToolInput; import fr.inria.soctrace.framesoc.tutorials.tool.ExampleToolInput.QueryEntity; import fr.inria.soctrace.framesoc.ui.input.AbstractToolInputComposite; public class ExampleToolInputComposite extends AbstractToolInputComposite { // Tool input that will be passed to the tool by Framesoc when the tool is launched private ExampleToolInput input = new ExampleToolInput(); public ExampleToolInputComposite(Composite parent, int style) { super(parent, style); setLayout(new GridLayout(1, false)); final Button types = new Button(this, SWT.RADIO); types.setText("Event Types"); types.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (types.getSelection()) { update(QueryEntity.TYPES); } } }); // default value: types types.setSelection(true); input.setQueryEntity(QueryEntity.TYPES); final Button producers = new Button(this, SWT.RADIO); producers.setText("Event Producers"); producers.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (producers.getSelection()) { update(QueryEntity.PRODUCERS); } } }); } private void update(QueryEntity entity) { // react to input change input.setQueryEntity(entity); // ask the Framesoc dialog to update the OK button dialog.updateOk(); } @Override public IFramesocToolInput getToolInput() { return input; } }
-
Create the input class
fr.inria.soctrace.framesoc.tutorials.tool.ExampleToolInputusing the following code:package fr.inria.soctrace.framesoc.tutorials.tool; import fr.inria.soctrace.framesoc.core.tools.model.IFramesocToolInput; public class ExampleToolInput implements IFramesocToolInput { public enum QueryEntity { PRODUCERS, TYPES; } private QueryEntity queryEntity; @Override public String getCommand() { return ""; } public QueryEntity getQueryEntity() { return queryEntity; } public void setQueryEntity(QueryEntity queryEntity) { this.queryEntity = queryEntity; } @Override public String toString() { return "ExampleToolInput [queryEntity=" + queryEntity + "]"; } }
-
Validate the input.
-
The composite reacts to changes in the GUI (
widgetSelected()methods), updating the current input (seeExampleToolInputbelow) and notifying the Framesoc launch dialog that a change has been done. The Framesoc dialog, in theupdateOk()method, asks the tool to validate the input, to enable/disable the OK button (launch button). The implementation ofupdateOK()calls thecanLaunch()method defined by theIFramesocToolinterface. The base implementation of this method (provided by theFramesocToolabstract class) always says that the input is OK. To customize this behavior we have to override thecanLaunch()method in our tool implementation. -
Add the
canLaunch()method to theExampleToolimplementation:@Override public ParameterCheckStatus canLaunch(IFramesocToolInput input) { if (input instanceof ExampleToolInput) { ExampleToolInput exampleInput = (ExampleToolInput) input; if (exampleInput.getQueryEntity() != null ) { System.out.println("Input is OK: " + exampleInput); return new ParameterCheckStatus(true, ""); } } return new ParameterCheckStatus(false, "Wrong input"); }
-
-
Just for the fun, modify the tool
launch()method as follow, to use the input:@Override public void launch(IFramesocToolInput input) { System.out.println("Hello World!"); ExampleToolInput exampleInput = (ExampleToolInput) input; System.out.println("My input is valid: " + exampleInput); }
A Framesoc tool typically opens a view in its launch() method, to provide the analyst with a GUI to perform a specific analysis. For the sake of this tutorial, we will create an Eclipse view displaying some information related to the trace currently selected in the Framesoc trace explorer.
-
Create an extension for the
org.eclipse.ui.viewsextension point, following the same procedure as before for thetoolandtoolInputextension points. -
Fill the extension element details as follow:
- id:
fr.inria.soctrace.framesoc.tutorials.tool.ExampleView - name:
Framesoc Tutorial Tool - class:
fr.inria.soctrace.framesoc.tutorials.tool.ExampleView
- id:
-
As done before, click on the link corresponding to the class and press Finish.
-
Replace the content of the view class that has been automatically created with the following:
package fr.inria.soctrace.framesoc.tutorials.tool; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.part.ViewPart; import fr.inria.soctrace.framesoc.tutorials.tool.ExampleToolInput.QueryEntity; import fr.inria.soctrace.framesoc.ui.utils.TraceSelection; import fr.inria.soctrace.lib.model.EventProducer; import fr.inria.soctrace.lib.model.EventType; import fr.inria.soctrace.lib.model.Trace; import fr.inria.soctrace.lib.model.utils.SoCTraceException; import fr.inria.soctrace.lib.query.EventProducerQuery; import fr.inria.soctrace.lib.query.EventTypeQuery; import fr.inria.soctrace.lib.storage.DBObject; import fr.inria.soctrace.lib.storage.TraceDBObject; public class ExampleView extends ViewPart { public final static String ID = "fr.inria.soctrace.framesoc.tutorials.tool.ExampleView"; //$NON-NLS-1$ private Text txtTrace; private Text txtEntity; private QueryEntity queryEntity; private ListViewer listViewer; /** * The listener we register with the selection service */ private ISelectionListener listener = new ISelectionListener() { public void selectionChanged(IWorkbenchPart sourcepart, ISelection selection) { // we ignore our own selections if (sourcepart != ExampleView.this) { if (!TraceSelection.isSelectionValid(selection)) return; List<Trace> traces = TraceSelection.getTracesFromSelection(selection); if (traces.isEmpty()) return; updateView(traces.get(0)); } } }; @Override public void createPartControl(Composite parent) { /** Layout */ parent.setLayout(new GridLayout(2, false)); /** Selected trace */ Label lblSelectedTrace = new Label(parent, SWT.NONE); lblSelectedTrace.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblSelectedTrace.setText("Selected Trace"); txtTrace = new Text(parent, SWT.BORDER); txtTrace.setEditable(false); txtTrace.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); /** Selected Entity */ Label lblQueryEntity = new Label(parent, SWT.NONE); lblQueryEntity.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblQueryEntity.setText("Query Entity"); txtEntity = new Text(parent, SWT.BORDER); txtEntity.setEditable(false); txtEntity.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); // init default values queryEntity = QueryEntity.TYPES; txtEntity.setText(queryEntity.toString()); /** Entities */ new Label(parent, SWT.NONE); listViewer = new ListViewer(parent, SWT.BORDER | SWT.V_SCROLL); listViewer.getList().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); // we use an array content provider, since the input is a list of string listViewer.setContentProvider(new ArrayContentProvider()); // use a base label provider, which simply calls the toString() methods on the // elements of the input listViewer.setLabelProvider(new LabelProvider()); // register the selection listener getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(listener); } /** * Updates the view with the current selected traces and the list of entities corresponding to * the 'query entity'. * * @param trace * selected trace */ private void updateView(Trace trace) { txtTrace.setText(trace.getAlias()); List<String> input = new ArrayList<>(); TraceDBObject traceDB = null; try { traceDB = TraceDBObject.openNewIstance(trace.getDbName()); if (queryEntity.equals(QueryEntity.TYPES)) { EventTypeQuery etq = new EventTypeQuery(traceDB); List<EventType> etl = etq.getList(); for (EventType et : etl) { input.add(et.getName()); } } else if (queryEntity.equals(QueryEntity.PRODUCERS)) { EventProducerQuery epq = new EventProducerQuery(traceDB); List<EventProducer> epl = epq.getList(); for (EventProducer ep : epl) { input.add(ep.getName()); } } } catch (SoCTraceException e) { e.printStackTrace(); } finally { DBObject.finalClose(traceDB); } listViewer.setInput(input); } /** * Set the tool input in the view * * @param exampleInput * tool input */ public void setInput(ExampleToolInput exampleInput) { queryEntity = exampleInput.getQueryEntity(); txtEntity.setText(queryEntity.toString()); } @Override public void setFocus() { // nothing to do } @Override public void dispose() { getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(listener); super.dispose(); } }
TODO
- pub sub to display selected trace in text box
- create layout
- create textbox
- handle event and modify text
TODO
- perform query on event type or producers and display them in list
- explain query objects (write another tutorial)