control: support creating of experiments when importing a trace session
authorBernd Hufmann <Bernd.Hufmann@ericsson.com>
Tue, 23 Feb 2016 20:00:19 +0000 (15:00 -0500)
committerBernd Hufmann <bernd.hufmann@ericsson.com>
Fri, 26 Feb 2016 15:51:18 +0000 (10:51 -0500)
The remote import wizard that is used to import LTTng session has been
updated to to create an experiment using all successfully imported
traces. Unrecognized traces won't be added to the experiment.
Traces that are skipped during the import (name conflict) are not
added to the experiment.

The name of the experiment is by default session root directory or
session name if the session doesn't use the default session path.
The user has the possibility to change the experiment name.

Change-Id: I6a6013511237ceb308fe25bdc42ec342a13ab72d
Signed-off-by: Bernd Hufmann <Bernd.Hufmann@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/67178
Reviewed-by: Hudson CI
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
Tested-by: Patrick Tasse <patrick.tasse@gmail.com>
lttng/org.eclipse.tracecompass.lttng2.control.ui/src/org/eclipse/tracecompass/internal/lttng2/control/ui/views/handlers/ImportHandler.java
tmf/org.eclipse.tracecompass.tmf.remote.ui/src/org/eclipse/tracecompass/internal/tmf/remote/ui/messages/RemoteMessages.java
tmf/org.eclipse.tracecompass.tmf.remote.ui/src/org/eclipse/tracecompass/internal/tmf/remote/ui/messages/messages.properties
tmf/org.eclipse.tracecompass.tmf.remote.ui/src/org/eclipse/tracecompass/internal/tmf/remote/ui/wizards/fetch/RemoteFetchLogWizard.java
tmf/org.eclipse.tracecompass.tmf.remote.ui/src/org/eclipse/tracecompass/internal/tmf/remote/ui/wizards/fetch/RemoteFetchLogWizardRemotePage.java
tmf/org.eclipse.tracecompass.tmf.remote.ui/src/org/eclipse/tracecompass/internal/tmf/remote/ui/wizards/fetch/model/RemoteImportTracesOperation.java

index 0485c6b3dccef9e9fd3e208df0dc4346495c5425..1c22101af00e481dccd379f381820852283ca355 100644 (file)
@@ -152,8 +152,8 @@ public class ImportHandler extends BaseControlViewHandler {
         }
 
         // Generate the profile
-        RemoteImportProfileElement profile = new RemoteImportProfileElement(null, "LTTng Remote Traces"); //$NON-NLS-1$
         TraceSessionComponent session = param.getSession();
+        RemoteImportProfileElement profile = new RemoteImportProfileElement(null, "LTTng Remote Traces"); //$NON-NLS-1$
         RemoteSystemProxy proxy = session.getTargetNode().getRemoteSystemProxy();
         IRemoteConnection rc = proxy.getRemoteConnection();
         String name = rc.getName();
@@ -182,7 +182,12 @@ public class ImportHandler extends BaseControlViewHandler {
         TracePackageElement element = new TracePackageTraceElement(group, "", "");  //$NON-NLS-1$//$NON-NLS-2$
         new TracePackageFilesElement(element, ".*"); //$NON-NLS-1$
 
-        RemoteFetchLogWizard wizard = new RemoteFetchLogWizard(profile);
+        String experimentName = path.lastSegment();
+        if (!experimentName.startsWith(session.getName())) {
+            experimentName = session.getName();
+        }
+
+        RemoteFetchLogWizard wizard = new RemoteFetchLogWizard(profile, experimentName);
         wizard.init(PlatformUI.getWorkbench(), StructuredSelection.EMPTY);
         WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
         dialog.open();
index 658852b9b38c04fe5f3197031203000a93a44179..887b051fa09bfbafe6b825fc817a95411313c6ba 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -50,7 +50,18 @@ public class RemoteMessages extends NLS {
     public static String RemoteFetchLogWizardRemotePage_NoProjectSelectedError;
     /** Error string for invalid tracing project */
     public static String RemoteFetchLogWizardRemotePage_InvalidTracingProject;
-
+    /** Options group label */
+    public static String RemoteFetchLogWizardRemotePage_OptionsGroupName;
+    /** Create experiment button name */
+    public static String RemoteFetchLogWizardRemotePage_CreateExperimentName;
+    /** Error string when experiment already exists*/
+    public static String RemoteFetchLogWizardRemotePage_ErrorExperimentAlreadyExists;
+    /** The error message when a resource in experiment folder already exists */
+    public static String RemoteFetchLogWizardRemotePage_ErrorResourceAlreadyExists;
+    /** The error message when an experiment name is invalid */
+    public static String RemoteFetchLogWizardRemotePage_ErrorExperimentNameInvalid;
+    /** The error message when no experiment name was entered */
+    public static String RemoteFetchLogWizardRemotePage_ErrorEmptyExperimentName;
     /** Label of add button in remote preference page */
     public static String RemoteProfilesPreferencePage_AddButton;
     /** Label of browse button in remote preference page */
index 2076169b5205164a4a379f36b9e2152a5d61706a..1ba44a4468edb552b6440e43af1070c105c1fcc0 100644 (file)
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2015 Ericsson
+# Copyright (c) 2016 Ericsson
 #
 # All rights reserved. This program and the accompanying materials are
 # made available under the terms of the Eclipse Public License v1.0 which
@@ -24,6 +24,12 @@ RemoteFetchLogWizardRemotePage_Title=Remote Traces
 RemoteFetchLogWizardRemotePage_ImportDialogProjectsGroupName=Available Projects
 RemoteFetchLogWizardRemotePage_NoProjectSelectedError=No tracing project selected or available
 RemoteFetchLogWizardRemotePage_InvalidTracingProject=Invalid tracing project. Missing directory
+RemoteFetchLogWizardRemotePage_OptionsGroupName=Options
+RemoteFetchLogWizardRemotePage_CreateExperimentName=Create Experiment
+RemoteFetchLogWizardRemotePage_ErrorExperimentAlreadyExists=Experiment "{0}" already exists
+RemoteFetchLogWizardRemotePage_ErrorResourceAlreadyExists=Resource with same name as experiment "{0}" already exists
+RemoteFetchLogWizardRemotePage_ErrorExperimentNameInvalid=Experiment name "{0}" is not a valid resource name
+RemoteFetchLogWizardRemotePage_ErrorEmptyExperimentName=No experiment name provided
 
 RemoteProfilesPreferencePage_AddButton=Add
 RemoteProfilesPreferencePage_BrowseButton=Browse...
index 13dc2b2f9850f9466e75220a6c25f63befaa11cb..37f34f0c0035206927d270a3b81e5cdaeb9518f2 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -47,6 +47,7 @@ public class RemoteFetchLogWizard extends Wizard implements IImportWizard {
     private RemoteFetchLogWizardRemotePage fFetchLogRemotePage;
 
     private @Nullable RemoteImportProfileElement fRemoteProfile = null;
+    private @Nullable String fExperimentName = null;
 
     // ------------------------------------------------------------------------
     // Constructor(s)
@@ -68,10 +69,14 @@ public class RemoteFetchLogWizard extends Wizard implements IImportWizard {
      * Create wizard with pre-defined remote profile
      * @param profile
      *              a remote profile
+     * @param experimentName
+     *          A name of an experiment to create and add traces to, or null
+     *          for no experiment
      */
-    public RemoteFetchLogWizard(@NonNull RemoteImportProfileElement profile) {
+    public RemoteFetchLogWizard(@NonNull RemoteImportProfileElement profile, @Nullable String experimentName) {
         this();
         fRemoteProfile = profile;
+        fExperimentName = experimentName;
     }
 
     // ------------------------------------------------------------------------
@@ -98,7 +103,7 @@ public class RemoteFetchLogWizard extends Wizard implements IImportWizard {
             fFetchLogWizardPage = new RemoteFetchLogWizardPage(RemoteMessages.RemoteFetchLogWizardPage_Title, fSelection);
             addPage(fFetchLogWizardPage);
         }
-        fFetchLogRemotePage = new RemoteFetchLogWizardRemotePage(RemoteMessages.RemoteFetchLogWizardRemotePage_Title, fSelection, fRemoteProfile);
+        fFetchLogRemotePage = new RemoteFetchLogWizardRemotePage(RemoteMessages.RemoteFetchLogWizardRemotePage_Title, fSelection, fRemoteProfile, fExperimentName);
         addPage(fFetchLogRemotePage);
     }
 
index 8ca83c21b9c0d4438ab9debed27bb04a38e4d4f5..a1b0e394f0285905208a45c9ac094d904cff1859 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -23,6 +23,9 @@ import java.util.Set;
 
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -33,15 +36,20 @@ import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.viewers.CheckboxTreeViewer;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Image;
 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.Text;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
 import org.eclipse.tracecompass.internal.tmf.remote.ui.Activator;
@@ -50,6 +58,8 @@ import org.eclipse.tracecompass.internal.tmf.remote.ui.wizards.fetch.model.Remot
 import org.eclipse.tracecompass.internal.tmf.remote.ui.wizards.fetch.model.RemoteImportConnectionNodeElement;
 import org.eclipse.tracecompass.internal.tmf.remote.ui.wizards.fetch.model.RemoteImportProfileElement;
 import org.eclipse.tracecompass.internal.tmf.remote.ui.wizards.fetch.model.RemoteImportTracesOperation;
+import org.eclipse.tracecompass.internal.tmf.ui.project.operations.NewExperimentOperation;
+import org.eclipse.tracecompass.internal.tmf.ui.project.operations.SelectTracesOperation;
 import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation;
 import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageWizardPage;
 import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement;
@@ -58,6 +68,8 @@ import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePa
 import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement;
 import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport.Messages;
 import org.eclipse.tracecompass.tmf.core.TmfProjectNature;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder;
 import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement;
 import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry;
 import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
@@ -98,7 +110,11 @@ public class RemoteFetchLogWizardRemotePage extends AbstractTracePackageWizardPa
     private boolean fIsVisible = false;
     private String fDefaultProjectName = null;
     private CCombo fCombo;
+    private Button fCreateExperimentCheckbox;
+    private Text fExperimentNameText;
     private List<IProject> fProjects;
+    private @Nullable TmfExperimentFolder fExperimentFolderElement;
+    private @Nullable String fExperimentName;
 
     // ------------------------------------------------------------------------
     // Constructors
@@ -112,8 +128,11 @@ public class RemoteFetchLogWizardRemotePage extends AbstractTracePackageWizardPa
      *          The current selection (trace folder element)
      * @param profile
      *          A profile to use or null
+     * @param experimentName
+     *          A name of an experiment to create and add traces to, or null
+     *          for no experiment
      */
-    protected RemoteFetchLogWizardRemotePage(String title, IStructuredSelection selection, @Nullable RemoteImportProfileElement profile) {
+    protected RemoteFetchLogWizardRemotePage(String title, IStructuredSelection selection, @Nullable RemoteImportProfileElement profile, @Nullable String experimentName) {
         super(PAGE_NAME, title, null, selection);
         setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Activator.PLUGIN_ID, ICON_PATH));
 
@@ -128,6 +147,7 @@ public class RemoteFetchLogWizardRemotePage extends AbstractTracePackageWizardPa
         }
 
         fProfile = profile;
+        fExperimentName = experimentName;
         setDescription(RemoteMessages.RemoteFetchLogWizardRemotePage_Description);
     }
 
@@ -151,6 +171,8 @@ public class RemoteFetchLogWizardRemotePage extends AbstractTracePackageWizardPa
 
         createProjectGroup(composite);
 
+        createOptionGroup(composite);
+
         restoreWidgetValues();
         updatePageCompletion();
 
@@ -159,7 +181,53 @@ public class RemoteFetchLogWizardRemotePage extends AbstractTracePackageWizardPa
 
     @Override
     protected boolean determinePageCompletion() {
-        return getElementViewer().getCheckedElements().length > 0;
+         if (getElementViewer().getCheckedElements().length <= 0) {
+             return false;
+         }
+
+         validateProject();
+
+         if ((fExperimentName != null) && (fCreateExperimentCheckbox.getSelection())) {
+             String name = fExperimentNameText.getText().trim();
+             // verify if experiment name is empty
+             if (name.isEmpty()) {
+                 setMessage(null);
+                 setErrorMessage(RemoteMessages.RemoteFetchLogWizardRemotePage_ErrorEmptyExperimentName);
+                 return false;
+             }
+
+             // verify that name is a valid resource name
+             IWorkspace workspace = ResourcesPlugin.getWorkspace();
+             if ((workspace != null) && (!workspace.validateName(name, IResource.FILE).isOK())) {
+                 setMessage(null);
+                 setErrorMessage(NLS.bind(RemoteMessages.RemoteFetchLogWizardRemotePage_ErrorExperimentNameInvalid, name));
+                 return false;
+             }
+
+             TmfExperimentFolder experimentFolder = fExperimentFolderElement;
+             if (experimentFolder != null) {
+                 TmfExperimentElement element =
+                         experimentFolder.getExperiment(name);
+                 // verify if experiment already exists
+                 if (element != null) {
+                     setMessage(null);
+                     setErrorMessage(NLS.bind(RemoteMessages.RemoteFetchLogWizardRemotePage_ErrorExperimentAlreadyExists, name));
+                     return false;
+                 }
+
+                 // verify if a resource already exists in the experiment folder
+                 IFolder expResource = experimentFolder.getResource();
+                 IResource res = expResource.findMember(name);
+                 if (res != null) {
+                     setMessage(null);
+                     setErrorMessage(NLS.bind(RemoteMessages.RemoteFetchLogWizardRemotePage_ErrorResourceAlreadyExists, name));
+                     return false;
+                 }
+             }
+         }
+
+         return true;
+
     }
 
     @Override
@@ -272,6 +340,45 @@ public class RemoteFetchLogWizardRemotePage extends AbstractTracePackageWizardPa
         }
     }
 
+    private void createOptionGroup(Composite parent) {
+        if (fExperimentName != null) {
+            Group comp = new Group(parent, SWT.SHADOW_NONE);
+            comp.setText(RemoteMessages.RemoteFetchLogWizardRemotePage_OptionsGroupName);
+            GridLayout layout = new GridLayout(2, false);
+            comp.setLayout(layout);
+            GridData data = new GridData(GridData.FILL, GridData.CENTER, true, false);
+            comp.setLayoutData(data);
+
+            fCreateExperimentCheckbox = new Button(comp, SWT.CHECK);
+            fCreateExperimentCheckbox.setFont(comp.getFont());
+            fCreateExperimentCheckbox.setText(RemoteMessages.RemoteFetchLogWizardRemotePage_CreateExperimentName);
+            fCreateExperimentCheckbox.setSelection(false);
+            data = new GridData(GridData.BEGINNING, GridData.CENTER, false, false);
+            fCreateExperimentCheckbox.setLayoutData(data);
+
+            fExperimentNameText = new Text(comp, SWT.BORDER);
+            data = new GridData(GridData.FILL, GridData.CENTER, true, false);
+            fExperimentNameText.setLayoutData(data);
+            fExperimentNameText.setText(fExperimentName);
+            fExperimentNameText.setEnabled(fCreateExperimentCheckbox.getSelection());
+
+            fExperimentNameText.addModifyListener(new ModifyListener() {
+                @Override
+                public void modifyText(ModifyEvent e) {
+                    updatePageCompletion();
+                }
+            });
+
+            fCreateExperimentCheckbox.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    fExperimentNameText.setEnabled(fCreateExperimentCheckbox.getSelection());
+                    updatePageCompletion();
+                }
+            });
+        }
+    }
+
     @Override
     protected Object createElementViewerInput() {
         if (fProfile == null) {
@@ -385,14 +492,59 @@ public class RemoteFetchLogWizardRemotePage extends AbstractTracePackageWizardPa
         Object[] elements = getElementViewer().getCheckedElements();
         final RemoteImportTracesOperation importOperation = new RemoteImportTracesOperation(getContainer().getShell(), fTmfTraceFolder, elements, fOverwriteAll);
 
+        final List<IResource> traceResources = new ArrayList<>();
         try {
             getContainer().run(true, true, new IRunnableWithProgress() {
                 @Override
                 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                     importOperation.run(monitor);
+                    traceResources.addAll(importOperation.getImportedResources());
                     monitor.done();
                 }
             });
+
+            if ((fExperimentName != null) && (traceResources.size() > 0)) {
+                final IFolder[] experimentFolders = new IFolder[1];
+                final TmfExperimentFolder root = fExperimentFolderElement;
+                final IStatus[] operationStatus = new IStatus[1];
+                final String experimentName = fExperimentNameText.getText().trim();
+
+                // just safety guards
+                if ((root == null) || (experimentName == null)) {
+                    return true;
+                }
+                getContainer().run(true, true, new IRunnableWithProgress() {
+                    @Override
+                    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+                        operationStatus[0] = null;
+                        final NewExperimentOperation operation = new NewExperimentOperation(root, experimentName);
+                        operation.run(monitor);
+                        monitor.done();
+                        operationStatus[0] = operation.getStatus();
+                        experimentFolders[0] = operation.getExperimentFolder();
+                    }
+                });
+
+                final IFolder expFolder = experimentFolders[0];
+                final TmfTraceFolder parentTraceFolder = fTmfTraceFolder;
+                // just safety guards
+                if ((expFolder == null) || (parentTraceFolder == null)) {
+                    return true;
+                }
+
+                if ((operationStatus[0] != null) && (operationStatus[0].isOK())) {
+                    getContainer().run(true, true, new IRunnableWithProgress() {
+                        @Override
+                        public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+                            operationStatus[0] = null;
+                            final SelectTracesOperation operation = new SelectTracesOperation(root, expFolder, parentTraceFolder, traceResources);
+                            operation.run(monitor);
+                            monitor.done();
+                            operationStatus[0] = operation.getStatus();
+                        }
+                    });
+                }
+            }
         } catch (InvocationTargetException e) {
             handleError(
                     Messages.TracePackageExtractManifestOperation_ErrorReadingManifest,
@@ -464,6 +616,7 @@ public class RemoteFetchLogWizardRemotePage extends AbstractTracePackageWizardPa
                 if (project.hasNature(TmfProjectNature.ID)) {
                     TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
                     fTmfTraceFolder = projectElement.getTracesFolder();
+                    fExperimentFolderElement = projectElement.getExperimentsFolder();
                 }
             } catch (CoreException ex) {
                 handleError(RemoteMessages.RemoteFetchLogWizardRemotePage_InvalidTracingProject, ex);
index 1790030b55e5ac7333fe1e2e4145b03afd93adbd..a02c0019ac227eb7cecb3da82b82184632dbdcf3 100644 (file)
@@ -92,6 +92,7 @@ public class RemoteImportTracesOperation extends TmfWorkspaceModifyOperation {
     private final TmfTraceFolder fDestination;
     private final Object[] fTraceElements;
     private final ImportConflictHandler fConflictHandler;
+    private final List<IResource> fImportedResources = new ArrayList<>();
 
     // ------------------------------------------------------------------------
     // Constructor(s)
@@ -249,6 +250,7 @@ public class RemoteImportTracesOperation extends TmfWorkspaceModifyOperation {
 
                     if (traceTypeHelper != null) {
                         TmfTraceTypeUIUtils.setTraceType(traceRes, traceTypeHelper);
+                        fImportedResources.add(traceRes);
                     }
 
                     // Set source location
@@ -433,4 +435,18 @@ public class RemoteImportTracesOperation extends TmfWorkspaceModifyOperation {
     public IStatus getStatus() {
         return fStatus;
     }
+
+    /**
+     * Get the list of resources that were imported by this operation. An
+     * example use case would be to use this to open traces that were imported
+     * by this operation.
+     *
+     * Note this includes only valid traces and doesn'tinclude unrecognized
+     * files.
+     *
+     * @return the trace resources that were imported
+     */
+    public List<IResource> getImportedResources() {
+        return fImportedResources;
+    }
 }
This page took 0.033922 seconds and 5 git commands to generate.