From ad9972cc6227f3f6297d40154afd5c37be001b39 Mon Sep 17 00:00:00 2001 From: Patrick-Jeffrey Pollo Guilbert Date: Thu, 2 Apr 2015 23:02:32 -0400 Subject: [PATCH] control: Base code for profile dialog window Modified ILttngControlService to add a loadSession command, also implemented the methods in the appropriate children classes (LTTngControlService and NullControlService). Added ProfileDialog and ProfileHandler, as well as the appropriate modifications to the plugin.xml to allow the execution of the handler as well as the call to the Handler. As for now, pre-selected profiles must be in org.eclipse.tracecompass.internal.lttng2.control.ui/resources/folders.txt. Appropriate .icons, strings and whatnot are externalized and at the appropriate location > messages.properties. Signed-off-by: Patrick-Jeffrey Pollo Guilbert Signed-off-by: William Tri-Khiem Truong Signed-off-by: William Enright Change-Id: Id312708b1907f3dd36fab65da7d96d5f917404a2 Reviewed-on: https://git.eclipse.org/r/45958 Reviewed-by: Hudson CI Reviewed-by: Matthew Khouzam Tested-by: Matthew Khouzam --- .../META-INF/MANIFEST.MF | 5 +- .../plugin.properties | 6 + .../plugin.xml | 31 +- .../resources/cpu.lttng | 73 +++ .../resources/cpu2.lttng | 73 +++ .../dialogs/ConnectionContentProvider.java | 78 +++ .../dialogs/ConnectionTreeLabelProvider.java | 47 ++ .../dialogs/EnableKernelEventComposite.java | 6 + .../ui/views/dialogs/ProfileDialog.java | 537 ++++++++++++++++++ .../ui/views/handlers/ConnectionPage.java | 207 +++++++ .../views/handlers/NewConnectionHandler.java | 25 + .../views/handlers/NewConnectionWizard.java | 181 ++++++ .../ui/views/handlers/ProfileHandler.java | 199 +++++++ .../control/ui/views/messages/Messages.java | 45 +- .../ui/views/messages/messages.properties | 13 + .../views/model/impl/NullControlService.java | 5 + .../views/model/impl/TraceSessionGroup.java | 16 + .../views/service/ILttngControlService.java | 14 + .../ui/views/service/LTTngControlService.java | 12 + .../service/LTTngControlServiceConstants.java | 4 + 20 files changed, 1561 insertions(+), 16 deletions(-) create mode 100644 lttng/org.eclipse.tracecompass.lttng2.control.ui/resources/cpu.lttng create mode 100644 lttng/org.eclipse.tracecompass.lttng2.control.ui/resources/cpu2.lttng create mode 100644 lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ConnectionContentProvider.java create mode 100644 lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ConnectionTreeLabelProvider.java create mode 100644 lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ProfileDialog.java create mode 100644 lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ConnectionPage.java create mode 100644 lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/NewConnectionWizard.java create mode 100644 lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ProfileHandler.java diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/META-INF/MANIFEST.MF b/lttng/org.eclipse.tracecompass.lttng2.control.ui/META-INF/MANIFEST.MF index 8e0ae4575f..4325559b83 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/META-INF/MANIFEST.MF +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/META-INF/MANIFEST.MF @@ -22,7 +22,10 @@ Require-Bundle: org.eclipse.ui, org.eclipse.remote.ui;bundle-version="2.0.0", org.eclipse.tracecompass.tmf.remote.core, org.eclipse.tracecompass.tmf.remote.ui, - org.eclipse.core.filesystem + org.eclipse.core.filesystem, + org.eclipse.jface, + org.eclipse.core.commands, + org.eclipse.ui.workbench Export-Package: org.eclipse.tracecompass.internal.lttng2.control.ui;x-friends:="org.eclipse.tracecompass.lttng2.control.ui.tests", org.eclipse.tracecompass.internal.lttng2.control.ui.relayd;x-internal:=true, org.eclipse.tracecompass.internal.lttng2.control.ui.views;x-friends:="org.eclipse.tracecompass.lttng2.kernel.ui,org.eclipse.tracecompass.lttng2.control.ui.tests,org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests", diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/plugin.properties b/lttng/org.eclipse.tracecompass.lttng2.control.ui/plugin.properties index 44c24c66cd..872e182ada 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/plugin.properties +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/plugin.properties @@ -130,12 +130,18 @@ commands.control.add.context.description=Add Context to Channel(s) and/or Event( commands.control.import=Import... commands.control.import.description=Import Traces to LTTng Project +commands.control.record=Record... +commands.control.record.description=Record a tracing session with basic options + commands.control.calibrate=Calibrate commands.control.calibrate.description=Quantify LTTng overhead commands.control.snapshot=Record Snapshot commands.control.snapshot.description=Record a snapshot +commands.control.wizard=Record... +commands.control.wizard.description=Create automated tracing session + preference.page.control.name=LTTng Tracer Control Preferences commandParameter.remoteServicesId.name = Remote Services ID diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/plugin.xml b/lttng/org.eclipse.tracecompass.lttng2.control.ui/plugin.xml index 2da1f5e96e..f2878a4ff2 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/plugin.xml +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/plugin.xml @@ -204,6 +204,12 @@ id="org.eclipse.linuxtools.internal.lttng2.ui.commands.control.snapshot" name="%commands.control.snapshot"> + + + + - - - - - - + + + + diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/resources/cpu.lttng b/lttng/org.eclipse.tracecompass.lttng2.control.ui/resources/cpu.lttng new file mode 100644 index 0000000000..0df601ee78 --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/resources/cpu.lttng @@ -0,0 +1,73 @@ + + + + + baseCPUtrace + + + KERNEL + GLOBAL + + + channel0 + false + DISCARD + 8388608 + 4 + 0 + 200000 + SPLICE + 0 + 0 + 0 + + + kmem_cache_free + true + TRACEPOINT + + + kmem_kfree + true + TRACEPOINT + + + kmem_cache_alloc_node + true + TRACEPOINT + + + kmem_kmalloc_node + true + TRACEPOINT + + + kmem_cache_alloc + true + TRACEPOINT + + + kmem_kmalloc + true + TRACEPOINT + + + + + + + false + + diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/resources/cpu2.lttng b/lttng/org.eclipse.tracecompass.lttng2.control.ui/resources/cpu2.lttng new file mode 100644 index 0000000000..abc746e33c --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/resources/cpu2.lttng @@ -0,0 +1,73 @@ + + + + + baseCPUtrace + + + KERNEL + GLOBAL + + + channel0 + false + DISCARD + 8388608 + 4 + 0 + 200000 + SPLICE + 0 + 0 + 0 + + + kmem_cache_free + true + TRACEPOINT + + + kmem_kfree + true + TRACEPOINT + + + kmem_cache_alloc_node + true + TRACEPOINT + + + kmem_kmalloc_node + true + TRACEPOINT + + + kmem_cache_alloc + true + TRACEPOINT + + + kmem_kmalloc + true + TRACEPOINT + + + + + + + false + + \ No newline at end of file diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ConnectionContentProvider.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ConnectionContentProvider.java new file mode 100644 index 0000000000..658e345fe0 --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ConnectionContentProvider.java @@ -0,0 +1,78 @@ +/********************************************************************** + * Copyright (c) 2015 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick-Jeffrey Pollo Guilbert, William Enright, + * William Tri-Khiem Truong - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionType; + +/** + * TODO document + * + */ +public final class ConnectionContentProvider implements ITreeContentProvider { + private static final Object[] NO_CHILDREN = {}; + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public void dispose() { + } + + @Override + public Object[] getElements(Object inputElement) { + List children = new ArrayList<>(); + if (inputElement instanceof IRemoteConnectionType) { + IRemoteConnectionType irc = (IRemoteConnectionType) inputElement; + children.addAll(irc.getRemoteServicesManager().getAllRemoteConnections()); + } + return children.toArray(); + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof IRemoteConnectionType) { + return getConnections((IRemoteConnectionType) parentElement); + } + return NO_CHILDREN; + } + + static IRemoteConnection[] getConnections(IRemoteConnectionType parentElement) { + List connectionList = parentElement.getConnections(); + IRemoteConnection[] result = connectionList.toArray(new IRemoteConnection[connectionList.size()]); + Arrays.sort(result); + return result; + } + + @Override + public Object getParent(Object element) { + if (element instanceof IRemoteConnection) { + return ((IRemoteConnection) element).getConnectionType(); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + return getChildren(element).length > 0; + } + +} \ No newline at end of file diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ConnectionTreeLabelProvider.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ConnectionTreeLabelProvider.java new file mode 100644 index 0000000000..7b43ef9e7a --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ConnectionTreeLabelProvider.java @@ -0,0 +1,47 @@ +/********************************************************************** + * Copyright (c) 2015 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick-Jeffrey Pollo Guilbert, William Enright, + * William Tri-Khiem Truong - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs; + +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionType; +import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages; + +/** + * TODO + * + */ +public final class ConnectionTreeLabelProvider extends LabelProvider { + @Override + public String getText(Object element) { + if (element instanceof IRemoteConnection) { + IRemoteConnection rc = (IRemoteConnection) element; + return rc.getName(); + } else if (element instanceof IRemoteConnectionType) { + IRemoteConnectionType rs = (IRemoteConnectionType) element; + return rs.getName(); + } + return Messages.TraceControl_UnknownNode; + } + + @Override + public Image getImage(Object element) { +// if (element instanceof IRemoteConnection) { +// return Activator.getDefault().loadIcon(NewConnectionDialog.CONNECTION_ICON_FILE); +// } +// return Activator.getDefault().loadIcon(NewConnectionDialog.PROVIDERS_ICON_FILE); + return null; + } +} \ No newline at end of file diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/EnableKernelEventComposite.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/EnableKernelEventComposite.java index 483bbeec06..2c175f8adb 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/EnableKernelEventComposite.java +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/EnableKernelEventComposite.java @@ -366,6 +366,12 @@ public class EnableKernelEventComposite extends Composite implements IEnableKern fTracepointsViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH)); return fTracepointsViewer; } + + @Override + protected void updateToolbar(boolean visible) { + super.updateToolbar(visible); + treeViewer.expandAll(); + } }; } diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ProfileDialog.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ProfileDialog.java new file mode 100644 index 0000000000..371affcb2f --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/dialogs/ProfileDialog.java @@ -0,0 +1,537 @@ +/********************************************************************** + * Copyright (c) 2015 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick-Jeffrey Pollo Guilbert, William Enright, + * William Tri-Khiem Truong - Initial API and implementation + **********************************************************************/ + +package org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FilenameFilter; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.HelpEvent; +import org.eclipse.swt.events.HelpListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * + *

+ * Dialog box using profiles + *

+ * + * @author William Enright, Patrick-Jeffrey Pollo Guilbert, William Tri-Khiem + * Truong + * + * + */ +public class ProfileDialog extends TitleAreaDialog { + + private Composite fBase; + private Composite fLabel; + private CheckboxTreeViewer fCbtv; + private Text descriptionText; + private ArrayList fSessionFiles = new ArrayList<>(); + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Constructor + * + * @param parentShell + * - a shell for the display of the dialog + */ + public ProfileDialog(Shell parentShell) { + super(parentShell); + + } + + @Override + protected Control createDialogArea(Composite parent) { + + setTitle(Messages.TraceControl_BasicMode); + setMessage(Messages.TraceControl_SelectBasicProfile); + + Composite parentComp = (Composite) super.createDialogArea(parent); + + fBase = new Composite(parentComp, SWT.NONE); + + // Creating composite for label group + fLabel = new Composite(parentComp, SWT.NONE); + fLabel.setLayout(GridLayoutFactory.swtDefaults().numColumns(1).create()); + fLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + descriptionText = new Text(fLabel, SWT.READ_ONLY | SWT.BORDER | SWT.MULTI); + descriptionText.setText(Messages.TraceControl_NoProfileSelected + "\n\n\n\n\n"); //$NON-NLS-1$ + descriptionText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + descriptionText.setBackground(new Color(null, 255, 255, 255)); + fBase.addHelpListener(new HelpListener() { + + @Override + public void helpRequested(HelpEvent e) { + try { + PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(new URL("http://archive.eclipse.org/tracecompass/doc/org.eclipse.tracecompass.doc.user/LTTng-Tracer-Control.html#Control_View")); //$NON-NLS-1$ + } catch (PartInitException e1) { + + } catch (MalformedURLException e1) { + + } + + } + }); + + fBase.setLayout(GridLayoutFactory.swtDefaults().numColumns(1).create()); + fBase.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + FilteredTree ft = new FilteredTree(fBase, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, new PatternFilter(), true) { + @Override + protected TreeViewer doCreateTreeViewer(Composite aparent, int style) { + fCbtv = new CheckboxTreeViewer(fBase); + fCbtv.getTree().setLayoutData(new GridData(GridData.FILL_BOTH)); + fCbtv.setContentProvider(new BasicContentProvider()); + try { + fCbtv.setInput(initialize()); + } catch (IOException e) { + + } + fCbtv.expandAll(); + return fCbtv; + } + }; + + ft.setBounds(0, 0, 500, 500); + fCbtv.addSelectionChangedListener(new ProfileSelectionChangedListener()); + + return fBase; + } + + // Updates text to be displayed in the textbox for profile description + private void updateSelectionText(IStructuredSelection sel, boolean uncheck) + { + Object[] obj = fCbtv.getCheckedElements(); + obj.getClass(); + + if (fCbtv.getCheckedElements().length == 0) + { + descriptionText.setText(Messages.NoSelectionDescription); + } + else if (fCbtv.getCheckedElements().length != 1 && fCbtv.getCheckedElements().length != 0) + { + descriptionText.setText(Messages.TraceControl_MultipleSelectionDescription); + } else { + + TreeParent checkedElement; + boolean commentFound = false; + if (uncheck) { + checkedElement = (TreeParent) obj[0]; + } else { + checkedElement = (TreeParent) sel.getFirstElement(); + } + + TreeParent currentParent = checkedElement.getParent(); + String parentPath = currentParent.getName(); + + if (fCbtv.getChecked(checkedElement)) + { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + DocumentBuilder builder = factory.newDocumentBuilder(); + factory.setIgnoringComments(false); + String fullPath = parentPath + checkedElement.getName(); + Document document = builder.parse(new File(fullPath)); + document.getDocumentElement().normalize(); + NodeList nl = document.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeType() == Node.COMMENT_NODE) { + commentFound = true; + Comment comment = (Comment) nl.item(i); + descriptionText.setText(comment.getData()); + } + } + + if (!commentFound) { + descriptionText.setText(Messages.TraceControl_SingleSelectionDescription); + } + } catch (ParserConfigurationException e) { + + } catch (SAXException e) { + + } catch (IOException e) { + + } + + } + + } + } + + private List addCustomFolders() throws IOException + { + String basicPath = getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); + basicPath = basicPath + "resources/folders.txt"; //$NON-NLS-1$ + String thisLine = ""; //$NON-NLS-1$ + List folderList = new ArrayList<>(); + + try (BufferedReader reader = new BufferedReader(new FileReader(basicPath))) { + while ((thisLine = reader.readLine()) != null) { + + for (String retval : thisLine.split("\n")) { //$NON-NLS-1$ + if (!retval.equals("")) { //$NON-NLS-1$ + List filesList = new ArrayList<>(); + TreeParent newParent = new TreeParent(thisLine); + filesList = addFilesFromFolder(thisLine); + + for (int i = 0; i < filesList.size(); i++) + { + newParent.addChild(new TreeParent(filesList.get(i).getName())); + } + folderList.add(newParent); + } + } + } + } catch (FileNotFoundException e) { + System.out.printf(Messages.TraceControl_ReadingPathError, basicPath); + } + return folderList; + } + + private List addFilesFromFolder(String folderPath) + { + List fileList = new ArrayList<>(); + File dir = new File(folderPath); + File[] files = dir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir1, String name) { + return name.toLowerCase().endsWith(Messages.TraceControl_LttngSuffix); + } + }); + if (files == null) { + files = new File[0]; + } + for (File f : files) + { + fSessionFiles.add(f); + fileList.add(new TreeParent(f.getName())); + } + + return fileList; + + } + + private TreeParent initialize() throws IOException { + + String absolutePath = getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); + String defaultPath = absolutePath + "resources/"; //$NON-NLS-1$ + + TreeParent root = new TreeParent("Root"); //$NON-NLS-1$ + + List sessionFilesList = new ArrayList<>(); + sessionFilesList = addFilesFromFolder(defaultPath); + + TreeParent defaultTP = new TreeParent(defaultPath); + + for (int i = 0; i < sessionFilesList.size(); i++) + { + defaultTP.addChild(sessionFilesList.get(i)); + } + + root.addChild(defaultTP); + + List customList = new ArrayList<>(); + customList = addCustomFolders(); + + for (TreeParent tp : customList) + { + root.addChild(tp); + } + + return root; + } + + private final class ProfileSelectionChangedListener implements ISelectionChangedListener { + @Override + public void selectionChanged(SelectionChangedEvent event) { + + if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) + { + IStructuredSelection sel = (IStructuredSelection) event.getSelection(); + + updateSelectionText(sel, false); + Object selectedObject = sel.getFirstElement(); + updateCheckedProfiles(sel, selectedObject); + } + } + + private void updateCheckedProfiles(IStructuredSelection sel, Object selectedObject) { + // Check if all the other brothers are checked, if so, check parent + // TreeObject is checked + if (fCbtv.getChecked(selectedObject)) { + ArrayList allParents = ((TreeObject) selectedObject).getAllParents(); + for (TreeObject parentAbove : allParents) { + Boolean brothersChecked = true; + ArrayList allChildren = ((TreeParent) parentAbove).getAllChildren(); + for (TreeObject child : allChildren) { + // TreeParent is checked + if (!fCbtv.getChecked(child)) { + brothersChecked = false; + } + } + if (brothersChecked) { + fCbtv.setChecked(parentAbove, true); + } + } + } + + if (selectedObject.getClass() == TreeParent.class) + { + // TreeParent is checked, must check all children + if (fCbtv.getChecked(selectedObject)) { + ArrayList allChildren = ((TreeParent) selectedObject).getAllChildren(); + for (TreeObject child : allChildren) { + fCbtv.setChecked(child, true); + } + fCbtv.expandToLevel(selectedObject, AbstractTreeViewer.ALL_LEVELS); + } + // TreeParent is unchecked, must uncheck children and parent, + // but not brothers + else { + ArrayList allChildren = ((TreeParent) selectedObject).getAllChildren(); + for (TreeObject child : allChildren) { + fCbtv.setChecked(child, false); + updateSelectionText(sel, true); + } + ArrayList allParents = ((TreeObject) selectedObject).getAllParents(); + for (TreeObject parentAbove : allParents) { + fCbtv.setChecked(parentAbove, false); + updateSelectionText(sel, true); + } + + } + } else if (selectedObject.getClass() == TreeObject.class) { + // TreeObject is checked + if (fCbtv.getChecked(selectedObject)) { + + } + // TreeObject is unchecked + else { + ArrayList allParents = ((TreeObject) selectedObject).getAllParents(); + for (TreeObject parentAbove : allParents) { + fCbtv.setChecked(parentAbove, false); + } + } + } + } + } + + class TreeObject extends PlatformObject { + private String name; + private TreeParent parent; + + public TreeObject(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setParent(TreeParent parent) { + this.parent = parent; + } + + public TreeParent getParent() { + return parent; + } + + public ArrayList getAllParents() { + ArrayList both = new ArrayList<>(); + TreeObject parentTemp = getParent(); + if (parentTemp != null) { // is not root, has more parents + both.add(parentTemp); + both.addAll(parentTemp.getAllParents()); + } + + return both; + } + + @Override + public String toString() { + return getName(); + } + + } + + class TreeParent extends TreeObject { + private ArrayList children; + + public TreeParent(String name) { + super(name); + children = new ArrayList<>(); + } + + public void addChild(TreeObject child) { + children.add(child); + child.setParent(this); + } + + public void removeChild(TreeObject child) { + children.remove(child); + child.setParent(null); + } + + public TreeObject[] getChildren() { + return children.toArray(new TreeObject[children.size()]); + } + + public ArrayList getAllChildren() + { + ArrayList both = new ArrayList<>(); + for (Object child : getChildren()) { + if (child.getClass() == TreeParent.class) { // is a parent + both.add((TreeObject) child); + both.addAll(((TreeParent) child).getAllChildren()); + } else { + both.add((TreeObject) child); + } + } + return both; + } + + public boolean hasChildren() { + return children.size() > 0; + } + } + + class BasicContentProvider implements ITreeContentProvider { + private TreeParent invisibleRoot; + + @Override + public void inputChanged(Viewer v, Object oldInput, Object newInput) { + } + + @Override + public void dispose() { + } + + @Override + public Object[] getElements(Object parent) { + if (parent.equals(null)) { + if (invisibleRoot == null) { + try { + invisibleRoot = initialize(); + } catch (IOException e) { + + } + } + return getChildren(invisibleRoot); + } + return getChildren(parent); + } + + @Override + public Object getParent(Object child) { + if (child instanceof TreeObject) { + return ((TreeObject) child).getParent(); + } + return null; + } + + @Override + public Object[] getChildren(Object parent) { + if (parent instanceof TreeParent) { + return ((TreeParent) parent).getChildren(); + } + return new Object[0]; + } + + @Override + public boolean hasChildren(Object parent) { + if (parent instanceof TreeParent) { + return ((TreeParent) parent).hasChildren(); + } + return false; + } + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected void okPressed() + { + Object[] checkedElements = fCbtv.getCheckedElements(); + + if (checkedElements.length != 0) { + ArrayList temp = new ArrayList<>(); + for (Object checked : checkedElements) { + String sessionName = ((TreeParent) checked).toString(); + if (sessionName.endsWith(Messages.ProfileDialog_LTTNG_Suffix)) { + + for (File f : fSessionFiles) { + if (f.getAbsolutePath().endsWith(sessionName)) { + temp.add(f); + } + } + } + } + fSessionFiles = temp; + } + + super.okPressed(); + } + + /** + * @return the list of checked files + */ + public ArrayList getCheckedFiles() { + return fSessionFiles; + } + +} diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ConnectionPage.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ConnectionPage.java new file mode 100644 index 0000000000..7338da79bc --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ConnectionPage.java @@ -0,0 +1,207 @@ +/********************************************************************** + * Copyright (c) 2015 École Polytechnique de Montréal and others + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick-Jeffrey Pollo Guilbert - Extracted from NewConnectionDialog + **********************************************************************/ + +package org.eclipse.tracecompass.internal.lttng2.control.ui.views.handlers; + +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionType; +import org.eclipse.remote.core.IRemoteConnectionWorkingCopy; +import org.eclipse.remote.core.exception.RemoteConnectionException; +import org.eclipse.remote.ui.IRemoteUIConnectionService; +import org.eclipse.remote.ui.IRemoteUIConnectionWizard; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.tracecompass.internal.lttng2.control.ui.Activator; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs.ConnectionContentProvider; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs.ConnectionTreeLabelProvider; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages; + +final class ConnectionPage extends WizardPage { + /** + * + * + * + */ + + private static final int BUTTONS_NUMBER_OF_COLUMNS = 3; + private Button fNewButton; + private Button fEditButton; + private IRemoteConnection fConnection; + private TreeViewer fConnectionTree = null; + + ConnectionPage(String pageName) { + super(pageName); + } + + @Override + public void createControl(Composite parent) { + GridData gd; + Composite dialogComposite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, true); + dialogComposite.setLayout(layout); + dialogComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Label label = new Label(dialogComposite, SWT.NONE); + label.setText(Messages.TraceControl_NewNodeExistingConnectionGroupName); + gd = new GridData(); + label.setLayoutData(gd); + gd.widthHint = label.computeSize(-1, -1).x + convertWidthInCharsToPixels(NewConnectionWizard.LABEL_WIDTH_CHARS); + // Existing connections group + this.fConnectionTree = new TreeViewer(dialogComposite); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + this.fConnectionTree.getTree().setLayoutData(gd); + gd.widthHint = convertWidthInCharsToPixels(NewConnectionWizard.CONNECTIONTREE_WIDTH_CHARS); + gd.heightHint = convertHeightInCharsToPixels(NewConnectionWizard.CONNECTIONTREE_HEIGHT_CHARS); + fConnectionTree.setLabelProvider(new ConnectionTreeLabelProvider()); + fConnectionTree.setContentProvider(new ConnectionContentProvider()); + fConnectionTree.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + ConnectionPage.this.onSelectionChanged(); + } + }); + fConnectionTree.addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + getWizard().performFinish(); + } + }); + + Composite buttons = new Composite(dialogComposite, SWT.NONE); + layout = new GridLayout(BUTTONS_NUMBER_OF_COLUMNS, true); + layout.marginHeight = 0; + layout.marginWidth = 0; + buttons.setLayout(layout); + buttons.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + + new Label(buttons, SWT.NONE); + + fEditButton = new Button(buttons, SWT.PUSH); + fEditButton.setText(Messages.TraceControl_NewNodeEditButtonName); + setButtonLayoutData(fEditButton); + fEditButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onEditConnection(); + } + }); + + fNewButton = new Button(buttons, SWT.PUSH); + fNewButton.setText(Messages.TraceControl_NewNodeCreateButtonText); + setButtonLayoutData(fNewButton); + fNewButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onNewConnection(); + } + }); + setControl(dialogComposite); + + } + + private void onSelectionChanged() { + setConnection(); + setPageComplete(true); + fEditButton.setEnabled(canEdit(fConnection)); + fNewButton.setEnabled(getServiceForCreation() != null); + } + + private void onEditConnection() { + setConnection(); + if (fConnection != null) { + IRemoteConnectionType connectionType = fConnection.getConnectionType(); + if (connectionType != null) { + IRemoteUIConnectionService connManager = connectionType.getService(IRemoteUIConnectionService.class); + if (connManager != null) { + IRemoteUIConnectionWizard wiz = connManager.getConnectionWizard(getShell()); + wiz.setConnection(fConnection.getWorkingCopy()); + IRemoteConnectionWorkingCopy result = wiz.open(); + if (result != null) { + try { + result.save(); + } catch (RemoteConnectionException e) { + Activator.getDefault().logError(e.toString(), e); + } + fConnectionTree.refresh(); + } + } + } + } + } + + private void setConnection() { + Object o = ((IStructuredSelection) fConnectionTree.getSelection()).getFirstElement(); + fConnection = o instanceof IRemoteConnection ? (IRemoteConnection) o : null; + } + + private static boolean canEdit(IRemoteConnection conn) { + if (conn == null) { + return false; + } + return conn.getConnectionType().canEdit(); + } + + private IRemoteConnectionType getServiceForCreation() { + Object o = ((IStructuredSelection) fConnectionTree.getSelection()).getFirstElement(); + IRemoteConnectionType result = null; + if (o instanceof IRemoteConnectionType) { + result = (IRemoteConnectionType) o; + } else if (o instanceof IRemoteConnection) { + IRemoteConnection iRemoteConnection = (IRemoteConnection) o; + result = iRemoteConnection.getConnectionType(); + } else { + return null; + } + if (!result.canAdd()) { + return null; + } + + return result; + } + + public void onNewConnection() { + IRemoteConnectionType rs = getServiceForCreation(); + if (rs != null) { + IRemoteUIConnectionService uiService = rs.getService(IRemoteUIConnectionService.class); + if (uiService != null) { + IRemoteUIConnectionWizard wiz = uiService.getConnectionWizard(getShell()); + if (wiz != null) { + IRemoteConnectionWorkingCopy wc = wiz.open(); + if (wc != null) { + IRemoteConnection conn = null; + try { + conn = wc.save(); + fConnectionTree.refresh(); + fConnectionTree.setSelection(new StructuredSelection(conn), true); + } catch (RemoteConnectionException e) { + Activator.getDefault().logError(e.toString(), e); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/NewConnectionHandler.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/NewConnectionHandler.java index 368e86fc99..3786c172bd 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/NewConnectionHandler.java +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/NewConnectionHandler.java @@ -17,6 +17,7 @@ import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; import java.util.Map; +import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.jface.window.Window; @@ -32,6 +33,8 @@ import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.services.IServiceLocator; /** *

@@ -98,6 +101,28 @@ public class NewConnectionHandler extends BaseControlViewHandler { fLock.unlock(); } } + + // Obtain IServiceLocator implementer, e.g. from PlatformUI.getWorkbench(): + IServiceLocator serviceLocator = PlatformUI.getWorkbench(); + // or a site from within a editor or view: + // IServiceLocator serviceLocator = getSite(); + + ICommandService commandService = serviceLocator.getService(ICommandService.class); + + + // Lookup commmand with its ID + Command command = commandService.getCommand("org.eclipse.linuxtools.internal.lttng2.ui.commands.control.createSession"); //$NON-NLS-1$ + + // Optionally pass a ExecutionEvent instance, default no-param arg creates blank event + try { + // execute new connection command directly + command.executeWithChecks(new ExecutionEvent()); + // FIX THIS OH GOD THE INHUMANITY + } catch (Exception e) { + + e.printStackTrace(); + } + return null; } diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/NewConnectionWizard.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/NewConnectionWizard.java new file mode 100644 index 0000000000..2d2527df87 --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/NewConnectionWizard.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (c) 2015 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick-Jeffrey Pollo Guilbert - Initial API and implementation + *******************************************************************************/ +package org.eclipse.tracecompass.internal.lttng2.control.ui.views.handlers; + +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +//import org.eclipse.swt.custom.CTabFolder; +//import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +//import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs.INewConnectionDialog; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs.NewConnectionDialog; + + +public class NewConnectionWizard { + + static final int LABEL_WIDTH_CHARS = 4; + private NewConnectionDialog fNewConnectionDialog; + + static final int CONNECTIONTREE_HEIGHT_CHARS = 10; + static final int CONNECTIONTREE_WIDTH_CHARS = 40; + + TreeViewer fConnectionTree = null; + private CheckboxTreeViewer treeViewer; + + + + // TODO: refactor name of class and all classes associated with it + public NewConnectionWizard() + { + + Shell shell = new Shell(); + + shell.setLayout(new GridLayout()); + Composite composite = new Composite(shell, SWT.BORDER); + Composite compositeDescription = new Composite(shell, SWT.BORDER); + composite.setBackground(new Color(null, 255,255,255)); + compositeDescription.setBackground(new Color(null, 255,255,255)); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.horizontalSpan = 2; + + + + + + + + + Group groupProfile = new Group(composite, SWT.SHADOW_ETCHED_IN); + groupProfile.setText("Profiles List"); + + + composite.setLayoutData(gridData); + composite.setLayout(new GridLayout(1, false)); + groupProfile.setLayoutData(gridData); + groupProfile.setLayout(new GridLayout()); + groupProfile.setBackground(new Color(null, 255,255,255)); + + + + + new FilteredTree(groupProfile, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, new PatternFilter(), true){ + @Override + protected TreeViewer doCreateTreeViewer(Composite aparent, int style) { + treeViewer = new CheckboxTreeViewer(aparent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + //TODO: change string to one recorded in Messages class + treeViewer.getTree().setToolTipText("Select one or multiple profiles from the list below."); //$NON-NLS-1$ + ArrayContentProvider test = new ArrayContentProvider(); + + treeViewer.setContentProvider(test); + + test.inputChanged(treeViewer, null, new String[]{"allo", "bye"}); //$NON-NLS-1$ //$NON-NLS-2$ + + treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH)); + return treeViewer; + } + }; + + + + + // TODO: modify the checkbox addition to be based on availble profiles + Button b = new Button(groupProfile, SWT.CHECK); + b.setText("CPU Usage"); + b.setBackground(new Color(null, 255,255,255)); + + Button b2 = new Button(groupProfile, SWT.CHECK); + b2.setText("Memory usage"); + b2.setBackground(new Color(null, 255,255,255)); + + Button b3 = new Button(groupProfile, SWT.CHECK); + b3.setText("Disk Activity"); + b3.setBackground(new Color(null, 255,255,255)); + + + Group groupDescription = new Group(composite, SWT.SHADOW_ETCHED_IN); + groupDescription.setText("Description"); + + groupDescription.setLayoutData(gridData); + groupDescription.setLayout(new GridLayout()); + groupDescription.setBackground(new Color(null, 255,255,255)); + + + groupDescription.pack(); + + Label descriptionLabel = new Label(groupDescription, 0); + descriptionLabel.setText("No description available."); + descriptionLabel.setBackground(new Color(null, 255,255,255)); + + groupProfile.pack(); + + shell.open(); + + + } + + WizardPage wp = new ConnectionPage("Wizard"); + + protected void okPressed() + { + + } + + WizardPage testPage = new WizardPage("Kappa") + { + + @Override + public void createControl(Composite parent) { + // TODO Auto-generated method stub + Composite canvas = new Composite(parent, SWT.NONE); + canvas.setLayout(new GridLayout()); + this.setTitle("Session creation"); + + setControl(canvas); + Button b = new Button(canvas, SWT.RADIO); + b.setText("Local"); + + } + + }; + + public INewConnectionDialog getfNewConnectionDialog() { + return fNewConnectionDialog; + } + + public void setNewConnectionDialog(INewConnectionDialog fNewConnectionDialog) { + this.fNewConnectionDialog = (NewConnectionDialog) fNewConnectionDialog; + } + + public CheckboxTreeViewer getTreeViewer() { + return treeViewer; + } + + public void setTreeViewer(CheckboxTreeViewer treeViewer) { + this.treeViewer = treeViewer; + } + +} diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ProfileHandler.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ProfileHandler.java new file mode 100644 index 0000000000..a3f6bea3b8 --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ProfileHandler.java @@ -0,0 +1,199 @@ +/********************************************************************** + * Copyright (c) 2015 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick-Jeffrey Pollo Guilbert - Added headers, exporting .lttng profiles + * William Enright - Added ProfileHandler implementation + * William Tri-Khiem Truong - Completed documentation + **********************************************************************/ +package org.eclipse.tracecompass.internal.lttng2.control.ui.views.handlers; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.ArrayList; + +import org.eclipse.core.commands.ExecutionEvent; +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.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; +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.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.remote.core.IRemoteConnectionType; +import org.eclipse.remote.core.IRemoteFileService; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tracecompass.internal.lttng2.control.ui.Activator; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.ControlView; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs.ProfileDialog; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TargetNodeComponent; +import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceSessionGroup; +import org.eclipse.tracecompass.tmf.remote.core.proxy.RemoteSystemProxy; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.IHandlerService; + +/** + *

+ * Profile Handler to select and load session profiles for tracing purposes + *

+ * + * @author William Tri-Khiem Truong, William Enright, Patrick-Jeffrey Pollo Guilbert + */ +public class ProfileHandler extends BaseControlViewHandler { + + /** + * Id of the parameter for the remote services id. + * + * @see NewConnectionHandler + * @see IRemoteConnectionType#getId() + */ + public static final String PARAMETER_REMOTE_SERVICES_ID = "org.eclipse.linuxtools.lttng2.control.ui.remoteServicesIdParameter"; //$NON-NLS-1$ + + /** + * (INewConnectionDialog) wd).getConnection() Id of the parameter for the + * name of the remote connection. + * + * @see NewConnectionHandler + * @see IRemoteConnectionType#getName() + */ + public static final String PARAMETER_CONNECTION_NAME = "org.eclipse.linuxtools.lttng2.control.ui.connectionNameParameter"; //$NON-NLS-1$ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + Shell s = new Shell(SWT.CENTER); + + Rectangle screenSize = Display.getCurrent().getPrimaryMonitor().getBounds(); + s.setLocation((screenSize.width - s.getBounds().width) / 2, (screenSize.height - s.getBounds().height) / 2); + s.setMinimumSize(500, 500); + + IWorkbenchPage page = getWorkbenchPage(); + if (page == null) { + return false; + } + + TargetNodeComponent elementParent = null; + + // Check if the session group project is selected + ISelection selection = page.getSelection(ControlView.ID); + if (selection instanceof StructuredSelection) { + Object element = ((StructuredSelection) selection).getFirstElement(); + final TraceSessionGroup sessionGroup = (element instanceof TraceSessionGroup) ? (TraceSessionGroup) element : null; + if (sessionGroup != null) + { + if (sessionGroup.getParent() instanceof TargetNodeComponent) { + elementParent = (TargetNodeComponent) sessionGroup.getParent(); + final ProfileDialog btd = new ProfileDialog(s); + if (btd.open() != Window.OK) { + return null; + } + final String remotePath = sessionGroup.getTargetNode().getRemoteSystemProxy().getRemoteConnection().getProperty("user.home") + "/.lttng/sessions"; //$NON-NLS-1$//$NON-NLS-2$ + + RemoteSystemProxy proxy = elementParent.getRemoteSystemProxy(); + IRemoteFileService fsss = proxy.getRemoteConnection().getService(IRemoteFileService.class); + ArrayList checkedFiles = btd.getCheckedFiles(); + + for (File file : checkedFiles) { + final IFileStore remoteFolder = fsss.getResource(remotePath); + final IFileStore remoteFile = remoteFolder.getFileStore(new Path(file.getName())); + try { + try (OutputStream out = remoteFile.openOutputStream(EFS.NONE, new NullProgressMonitor())) + { + Files.copy(file.toPath(), out); + } + } catch (CoreException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + Job job = new Job(Messages.TraceControl_LoadSessionJob) { + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + sessionGroup.loadSession(remotePath + "/" + remoteFile.getName(), monitor); //$NON-NLS-1$ + } catch (ExecutionException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TraceControl_LoadSessionFailure, e); + } + return Status.OK_STATUS; + } + }; + + job.setUser(true); + job.schedule(); + } + + } + + } + } + // Refreshing the sessions in the control view by calling the refresh + // command + + IWorkbenchPart part = HandlerUtil.getActivePartChecked(event); + + IHandlerService service = part.getSite().getService(IHandlerService.class); + + try { + service.executeCommand("org.eclipse.linuxtools.internal.lttng2.ui.commands.control.refresh", null); //$NON-NLS-1$ + } catch (NotDefinedException e) { + + } catch (NotEnabledException e) { + + } catch (NotHandledException e) { + + } + return null; + } + + @Override + public boolean isEnabled() { + + // Get workbench page for the Control View + IWorkbenchPage page = getWorkbenchPage(); + if (page == null) { + return false; + } + + TraceSessionGroup sessionGroup = null; + + // Check if the session group project is selected + ISelection selection = page.getSelection(ControlView.ID); + if (selection instanceof StructuredSelection) { + Object element = ((StructuredSelection) selection).getFirstElement(); + sessionGroup = (element instanceof TraceSessionGroup) ? (TraceSessionGroup) element : null; + } + + boolean isEnabled = sessionGroup != null; + fLock.lock(); + try { + if (isEnabled) { + } + } finally { + fLock.unlock(); + } + return isEnabled; + } +} \ No newline at end of file diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/messages/Messages.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/messages/Messages.java index a935d19a53..4f5cb91a21 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/messages/Messages.java +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/messages/Messages.java @@ -27,17 +27,14 @@ public final class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.messages"; //$NON-NLS-1$ - public static String EnableChannelDialog_DefaultMessage; - - public static String ImportHandler_LiveTraceElementError; - - public static String ImportHandler_LiveTraceInitError; - // Failures public static String TraceControl_ConnectionFailure; public static String TraceControl_DisconnectionFailure; + public static String TraceControl_LoadSessionFailure; public static String TraceControl_CommandError; + public static String ImportHandler_LiveTraceElementError; + public static String ImportHandler_LiveTraceInitError; public static String TraceControl_UnexpectedCommandOutputFormat; public static String TraceControl_UnexpectedNameError; public static String TraceControl_UnexpectedPathError; @@ -73,6 +70,8 @@ public final class Messages extends NLS { public static String TraceControl_CreateSessionJob; public static String TraceControl_CreateSessionFailure; + public static String TraceControl_LoadSessionJob; + public static String TraceControl_DestroySessionJob; public static String TraceControl_DestroySessionFailure; public static String TraceControl_DestroyConfirmationTitle; @@ -88,6 +87,20 @@ public final class Messages extends NLS { public static String TraceControl_CreateChannelStateJob; public static String TraceControl_CreateChannelStateFailure; + public static String EnableChannelDialog_DefaultMessage; + + + public static String NoSelectionDescription; + + + public static String ProfileDialog_5; + + + public static String ProfileDialog_6; + + + public static String ProfileDialog_LTTNG_Suffix; + public static String TraceControl_ChangeChannelStateJob; public static String TraceControl_ChangeChannelStateFailure; public static String TraceControl_ChangeEventStateJob; @@ -165,6 +178,9 @@ public final class Messages extends NLS { public static String TraceControl_CreateSessionLiveDelayTooltip; public static String TraceControl_InvalidSessionNameError; + public static String TraceControl_SelectBasicProfile; + + public static String TraceControl_SessionAlreadyExistsError; public static String TraceControl_SessionPathAlreadyExistsError; public static String TraceControl_InvalidSessionPathError; @@ -276,7 +292,13 @@ public final class Messages extends NLS { public static String TraceControl_OverwriteModePropertyName; public static String TraceControl_SubBufferSizePropertyName; public static String TraceControl_NbSubBuffersPropertyName; + + + public static String TraceControl_NoProfileSelected; public static String TraceControl_SwitchTimerPropertyName; + public static String TraceControl_ReadingPathError; + + public static String TraceControl_ReadTimerPropertyName; public static String TraceControl_OutputTypePropertyName; public static String TraceControl_TraceFileCountPropertyName; @@ -284,6 +306,9 @@ public final class Messages extends NLS { public static String TraceControl_HostNamePropertyName; public static String TraceControl_HostAddressPropertyName; public static String TraceControl_SessionPathPropertyName; + + + public static String TraceControl_SingleSelectionDescription; public static String TraceControl_SnapshotPathPropertyName; public static String TraceControl_SnapshotNamePropertyName; public static String TraceControl_SnapshotIdPropertyName; @@ -294,12 +319,18 @@ public final class Messages extends NLS { public static String TraceControl_ProbeSymbolPropertyName; public static String TraceControl_MaxSizeTraceFilesPropertyName; public static String TraceControl_MaxNumTraceFilesPropertyName; + + + public static String TraceControl_MultipleSelectionDescription; public static String TraceControl_ConfigureMetadataChannelName; // Preferences public static String TraceControl_TracingGroupPreference; public static String TraceControl_LoggingPreference; public static String TraceControl_LogfilePath; + + + public static String TraceControl_LttngSuffix; public static String TraceControl_AppendLogfilePreference; public static String TraceControl_VerboseLevelsPreference; @@ -317,6 +348,8 @@ public final class Messages extends NLS { public static String TraceControl_UnknownNode; + public static String TraceControl_BasicMode; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/messages/messages.properties b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/messages/messages.properties index 099c66b829..55e9f873e3 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/messages/messages.properties +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/messages/messages.properties @@ -14,6 +14,10 @@ EnableChannelDialog_DefaultMessage=Default ImportHandler_LiveTraceElementError=Could not find trace element ImportHandler_LiveTraceInitError=Error initializing live trace. +NoSelectionDescription="No profile was checked" +ProfileDialog_5= +ProfileDialog_6= +ProfileDialog_LTTNG_Suffix= TraceControl_ConnectionFailure=Connecting to host failed TraceControl_DisconnectionFailure=Disconnection from host failed TraceControl_CommandError=Command failed! Command: @@ -26,6 +30,7 @@ TraceControl_UnexpectedValueError=Unexpected value. Returned {0} Expected: {1} TraceControl_UnsupportedVersionError=Unsupported LTTng Tracer Control version TraceControl_GettingVersionError=Could not get version of LTTng Tracer Control +TraceControl_BasicMode=Basic mode # Xml parsing related failures TraceControl_InvalidSchemaError=Could not open/validate xsd Schema @@ -52,6 +57,8 @@ TraceControl_NewNodeCreateButtonText=Create... TraceControl_NewNodeCreationFailure=Creation of new connection failed TraceControl_CreateSessionJob=Creating Session... TraceControl_CreateSessionFailure=Command to create session failed +TraceControl_LoadSessionJob=Loading Session... +TraceControl_LoadSessionFailure=Command to load session failed TraceControl_DestroySessionJob=Destroying Session... TraceControl_DestroySessionFailure=Command to destroy session failed @@ -151,6 +158,7 @@ TraceControl_CreateSessionLiveConnectionUrlTooltip=The URL for the live connecti TraceControl_CreateSessionLiveConnectionPortTooltip=The port for the live connection (Relayd) TraceControl_InvalidSessionNameError=The session name is invalid +TraceControl_SelectBasicProfile=Select your basic tracing profile and connection type. TraceControl_SessionAlreadyExistsError=The session name already exists TraceControl_SessionPathAlreadyExistsError=Session path already exists TraceControl_InvalidSessionPathError=The session path is invalid @@ -261,7 +269,9 @@ TraceControl_OpenConnectionTo=Opening connection to ''{0}'' TraceControl_OverwriteModePropertyName=Overwrite Mode TraceControl_SubBufferSizePropertyName=Sub Buffer Size TraceControl_NbSubBuffersPropertyName=Number of Sub Buffers +TraceControl_NoProfileSelected=No profile was selected. No description available. TraceControl_SwitchTimerPropertyName=Switch Timer Interval +TraceControl_ReadingPathError=Error reading file in path %s\n TraceControl_ReadTimerPropertyName=Read Timer Interval TraceControl_OutputTypePropertyName=Output Type TraceControl_TraceFileCountPropertyName=Trace File Count @@ -269,6 +279,7 @@ TraceControl_TraceFileSizePropertyName=Trace File Size TraceControl_HostNamePropertyName=Connection Name TraceControl_HostAddressPropertyName=Host Name TraceControl_SessionPathPropertyName=Session Path +TraceControl_SingleSelectionDescription=A profile was selected, but no description was found within the profile. TraceControl_SnapshotPathPropertyName=Snapshot Path TraceControl_SnapshotNamePropertyName=Snapshot Name TraceControl_SnapshotIdPropertyName=Snapshot ID @@ -279,12 +290,14 @@ TraceControl_ProbeOffsetPropertyName=Offset TraceControl_ProbeSymbolPropertyName=Symbol TraceControl_MaxSizeTraceFilesPropertyName=Maximum size of trace files TraceControl_MaxNumTraceFilesPropertyName=Maximum number of trace files +TraceControl_MultipleSelectionDescription=This configuration will attempt to trace with multiple profil1es simultaneously. TraceControl_ConfigureMetadataChannelName=Configure metadata channel # Preferences TraceControl_TracingGroupPreference=&Tracing Group TraceControl_LoggingPreference=&Logging TraceControl_LogfilePath=Log file +TraceControl_LttngSuffix=.lttng TraceControl_AppendLogfilePreference=&Append TraceControl_VerboseLevelsPreference=&Verbose Level TraceControl_VerboseLevelNonePreference=None diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/model/impl/NullControlService.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/model/impl/NullControlService.java index bbb1af306d..48b8a99a4b 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/model/impl/NullControlService.java +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/model/impl/NullControlService.java @@ -142,4 +142,9 @@ class NullControlService implements ILttngControlService { @Override public void runCommands(IProgressMonitor monitor, List commands) throws ExecutionException { } + + @Override + public void loadSession(String sessionName, IProgressMonitor monitor) throws ExecutionException { + + } } diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/model/impl/TraceSessionGroup.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/model/impl/TraceSessionGroup.java index ca91f58eb6..425a1d8673 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/model/impl/TraceSessionGroup.java +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/model/impl/TraceSessionGroup.java @@ -141,6 +141,22 @@ public class TraceSessionGroup extends TraceControlComponent { } } + /** + * Loads a session from a path + * + * @param sessionPath + * + * @param monitor + * - a progress monitor + * @throws ExecutionException + * If the command fails + */ + public void loadSession(String sessionPath, IProgressMonitor monitor) throws ExecutionException { + getControlService().loadSession(sessionPath, monitor); + + + } + /** * Command to execute a list of commands * @param monitor diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/ILttngControlService.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/ILttngControlService.java index 81d9bd51c2..2a0da6c5cf 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/ILttngControlService.java +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/ILttngControlService.java @@ -400,4 +400,18 @@ public interface ILttngControlService { */ void runCommands(IProgressMonitor monitor, List commands) throws ExecutionException; + + /** + * Load a session with given session name. + * + * @param sessionName + * - a session name to start + * @param monitor + * - a progress monitor + * @throws ExecutionException + * If the command fails + */ + void loadSession(String sessionName, IProgressMonitor monitor) + throws ExecutionException; + } diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/LTTngControlService.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/LTTngControlService.java index ba3f32317f..7fd436453b 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/LTTngControlService.java +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/LTTngControlService.java @@ -668,6 +668,16 @@ public class LTTngControlService implements ILttngControlService { } + @Override + public void loadSession(String sessionPath, IProgressMonitor monitor) throws ExecutionException { + + ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_LOAD_SESSION, "-i", sessionPath); //$NON-NLS-1$ + + executeCommand(command, monitor); + + // Session loaded + } + @Override public void enableChannels(String sessionName, List channelNames, boolean isKernel, IChannelInfo info, IProgressMonitor monitor) throws ExecutionException { @@ -1535,4 +1545,6 @@ public class LTTngControlService implements ILttngControlService { return result; } + + } diff --git a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/LTTngControlServiceConstants.java b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/LTTngControlServiceConstants.java index 7190e78631..20060280a6 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/LTTngControlServiceConstants.java +++ b/lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/service/LTTngControlServiceConstants.java @@ -94,6 +94,10 @@ public interface LTTngControlServiceConstants { * Command to destroy a session. */ String COMMAND_START_SESSION = "start"; //$NON-NLS-1$ + /** + * Command to load a session. + */ + String COMMAND_LOAD_SESSION = "load"; //$NON-NLS-1$ /** * Command to destroy a session. */ -- 2.34.1