Introduce an API to download and import traces from HTTP/HTTPS
authorSimon Delisle <simon.delisle@ericsson.com>
Wed, 12 Apr 2017 15:16:05 +0000 (11:16 -0400)
committerJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Thu, 27 Apr 2017 15:40:05 +0000 (11:40 -0400)
This patch contains two parts:
- A class to download a file from HTTP links
- An import operation that use the download helper to import the
dowloaded traces in the workspace

Change-Id: I1b588b113e352630760a9cab0dfbfd0052368b29
Signed-off-by: Simon Delisle <simon.delisle@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/94940
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Jean-Christian Kouame <jean-christian.kouame@ericsson.com>
Tested-by: Jean-Christian Kouame <jean-christian.kouame@ericsson.com>
tmf/org.eclipse.tracecompass.tmf.ui.tests/META-INF/MANIFEST.MF
tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/actions/DownloadTraceHttpHelperTest.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/actions/HttpTraceImportOperationTest.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/DownloadTraceHttpHelper.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/TraceDownloadStatus.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/actions/HttpTraceImportOperation.java [new file with mode: 0644]

index 802c2cf56974bfd0941471289a06762424eff40a..824a451e56fc8a0aefedb542243ef44a708302c1 100644 (file)
@@ -16,7 +16,8 @@ Require-Bundle: org.junit;bundle-version="4.0.0",
  org.eclipse.tracecompass.common.core,
  org.eclipse.tracecompass.tmf.core,
  org.eclipse.tracecompass.tmf.ui,
- org.eclipse.tracecompass.tmf.core.tests
+ org.eclipse.tracecompass.tmf.core.tests,
+ org.apache.commons.io
 Export-Package: org.eclipse.tracecompass.tmf.ui.tests,
  org.eclipse.tracecompass.tmf.ui.tests.actions,
  org.eclipse.tracecompass.tmf.ui.tests.experiment.type,
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/actions/DownloadTraceHttpHelperTest.java b/tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/actions/DownloadTraceHttpHelperTest.java
new file mode 100644 (file)
index 0000000..ba67f92
--- /dev/null
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ericsson
+ *
+ * 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:
+ *     Simon Delisle - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tracecompass.tmf.ui.tests.actions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.DownloadTraceHttpHelper;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.TraceDownloadStatus;
+import org.eclipse.tracecompass.tmf.ui.tests.TmfUITestPlugin;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test the {@link DownloadTraceHttpHelper} class
+ *
+ * @author Simon Delisle
+ */
+public class DownloadTraceHttpHelperTest {
+
+    private static String fTestTrace1Url = "http://archive.eclipse.org/tracecompass/test-traces/tmf/syslog";
+    private static String fTestTrace2Url = "http://archive.eclipse.org/tracecompass/test-traces/tmf/syslog_collapse";
+    private static String fTraceArchiveUrl = "http://archive.eclipse.org/tracecompass/test-traces/tmf/syslogs.zip";
+    private static String fDestinationDirectory;
+
+    /**
+     * Setup class
+     *
+     * @throws Exception
+     *             if an exception occurs
+     */
+    @BeforeClass
+    public static void beforeClass() throws Exception {
+        fDestinationDirectory = TmfUITestPlugin.getDefault().getStateLocation().append("httpDownloadTestDirectory").toOSString();
+    }
+
+    /**
+     * Cleanup after each test
+     *
+     * @throws IOException
+     *             if an exception occurs
+     */
+    @After
+    public void afterTest() throws IOException {
+        File destFile = new File(fDestinationDirectory);
+        FileUtils.deleteDirectory(destFile);
+    }
+
+    /**
+     * Test the download and import operation for a trace file
+     */
+    @Test
+    public void testTraceDownload() {
+        TraceDownloadStatus status = DownloadTraceHttpHelper.downloadTrace(fTestTrace1Url, fDestinationDirectory);
+        assumeFalse(status.isTimeout());
+        assertTrue(status.isOk());
+        validateSingleDownload(status.getDownloadedFile(), "syslog");
+    }
+
+    /**
+     * Test the download and import operation for a trace file
+     */
+    @Test
+    public void testMutlipleTracesDownload() {
+        List<String> tracesUrl = new ArrayList<>();
+        tracesUrl.add(fTestTrace1Url);
+        tracesUrl.add(fTestTrace2Url);
+
+        TraceDownloadStatus multipleStatus = DownloadTraceHttpHelper.downloadTraces(tracesUrl, fDestinationDirectory);
+        assumeFalse(multipleStatus.isTimeout());
+        assertTrue(multipleStatus.isOk());
+
+        List<File> downloadedTraces = new ArrayList<>();
+        for (TraceDownloadStatus status : multipleStatus.getChildren()) {
+            downloadedTraces.add(status.getDownloadedFile());
+        }
+
+        // Make sure that there is only two traces
+        assertEquals(2, downloadedTraces.size());
+        validateMultipleDownload(downloadedTraces);
+    }
+
+    /**
+     * Test the download and import operation for a trace file
+     */
+    @Test
+    public void testArchiveTraceDownload() {
+        TraceDownloadStatus status = DownloadTraceHttpHelper.downloadTrace(fTraceArchiveUrl, fDestinationDirectory);
+        assumeFalse(status.isTimeout());
+        assertTrue(status.isOk());
+        validateSingleDownload(status.getDownloadedFile(), "syslogs.zip");
+    }
+
+    private static void validateSingleDownload(File downloadedFile, String expectedFileName) {
+        // Make sure that the name was correctly identify
+        assertEquals(expectedFileName, downloadedFile.getName());
+
+        // Check if the directory contains only one trace
+        File dest = new File(fDestinationDirectory);
+        File[] listFiles = dest.listFiles();
+        assertEquals(1, listFiles.length);
+        assertEquals(expectedFileName, listFiles[0].getName());
+        assertTrue(listFiles[0].exists());
+    }
+
+    private static void validateMultipleDownload(List<File> downloadedFile) {
+        // Check if the directory contains two traces
+        File dest = new File(fDestinationDirectory);
+        File[] listFiles = dest.listFiles();
+        assertEquals(2, listFiles.length);
+        for (File file : listFiles) {
+            assertTrue(file.exists());
+        }
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/actions/HttpTraceImportOperationTest.java b/tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/actions/HttpTraceImportOperationTest.java
new file mode 100644 (file)
index 0000000..1bdc8fb
--- /dev/null
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ericsson
+ *
+ * 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:
+ *     Simon Delisle - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tracecompass.tmf.ui.tests.actions;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.tracecompass.tmf.ui.actions.HttpTraceImportOperation;
+import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement;
+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;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test the {@link HttpTraceImportOperation} class
+ *
+ * @author Simon Delisle
+ */
+public class HttpTraceImportOperationTest {
+
+    private static TmfTraceFolder fDestFolder;
+    private static String fTestTrace1Url = "http://archive.eclipse.org/tracecompass/test-traces/tmf/syslog";
+    private static String fTestTrace2Url = "http://archive.eclipse.org/tracecompass/test-traces/tmf/syslog_collapse";
+    private static String fTraceArchiveUrl = "http://archive.eclipse.org/tracecompass/test-traces/tmf/syslogs.zip";
+    private static List<String> fImportedTraceNameList;
+
+    /**
+     * Setup class
+     *
+     * @throws Exception
+     *             if an exception occurs
+     */
+    @BeforeClass
+    public static void beforeClass() throws Exception {
+        // Create the destination folder/project
+        IProject project = TmfProjectRegistry.createProject("Test Project", null, null);
+        final TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
+        TmfTraceFolder tracesFolder = checkNotNull(projectElement.getTracesFolder());
+        tracesFolder.getResource().getFolder("Folder").create(false, true, null);
+        fDestFolder = (TmfTraceFolder) tracesFolder.getChildren().stream()
+                .filter(element -> element.getName().equals("Folder")).findFirst().get();
+
+        fImportedTraceNameList = new ArrayList<>();
+        fImportedTraceNameList.add("syslog");
+        fImportedTraceNameList.add("syslog_collapse");
+    }
+
+    /**
+     * Cleanup class
+     *
+     * @throws CoreException
+     *             if an exception occurs
+     */
+    @AfterClass
+    public static void afterClass() throws CoreException {
+        if (fDestFolder != null) {
+            fDestFolder.getProject().getResource().delete(true, null);
+        }
+    }
+
+    /**
+     * Test the download and import operation for a trace file
+     *
+     * @throws Exception
+     *             if an exception occurs
+     */
+    @Test
+    public void testTraceImport() throws Exception {
+        WorkspaceModifyOperation operation = new HttpTraceImportOperation(fTestTrace1Url, fDestFolder);
+        try {
+            PlatformUI.getWorkbench().getProgressService().run(true, true, operation);
+        } catch (InterruptedException e) {
+            assumeTrue(false);
+        }
+        validateImport(Collections.singletonList("syslog"));
+    }
+
+    /**
+     * Test the download and import operation for multiple traces
+     *
+     * @throws Exception
+     *             if an exception occurs
+     */
+    @Test
+    public void testMultipleTracesImport() throws Exception {
+        List<String> tracesUrl = new ArrayList<>();
+        tracesUrl.add(fTestTrace1Url);
+        tracesUrl.add(fTestTrace2Url);
+        WorkspaceModifyOperation operation = new HttpTraceImportOperation(tracesUrl, fDestFolder);
+        try {
+            PlatformUI.getWorkbench().getProgressService().run(true, true, operation);
+        } catch (InterruptedException e) {
+            assumeTrue(false);
+        }
+        validateImport(fImportedTraceNameList);
+    }
+
+    /**
+     * Test the download and import operation for an archive
+     *
+     * @throws Exception
+     *             if an exception occurs
+     */
+    @Test
+    public void testArchiveImport() throws Exception {
+        WorkspaceModifyOperation operation = new HttpTraceImportOperation(fTraceArchiveUrl, fDestFolder);
+        try {
+            PlatformUI.getWorkbench().getProgressService().run(true, true, operation);
+        } catch (InterruptedException e) {
+            assumeTrue(false);
+        }
+        validateImport(fImportedTraceNameList);
+    }
+
+    private static void validateImport(List<String> expectedImportFiles) {
+        List<ITmfProjectModelElement> destFolderChildren = fDestFolder.getChildren();
+        assertEquals(expectedImportFiles.size(), destFolderChildren.size());
+        for (ITmfProjectModelElement element : destFolderChildren) {
+            assertTrue(expectedImportFiles.contains(element.getName()));
+        }
+    }
+
+}
index 3fd77f549e6915791771b4fa1eeca125b528b524..ada06ae016aa391b8b2ab77ad0ceee242f895e34 100644 (file)
@@ -28,7 +28,9 @@ Require-Bundle: org.eclipse.core.expressions,
  org.apache.commons.compress,
  org.apache.commons.lang3,
  org.eclipse.wst.xml.ui,
- org.eclipse.wst.xsd.core
+ org.eclipse.wst.xsd.core,
+ org.apache.commons.io,
+ com.google.guava
 Export-Package: org.eclipse.tracecompass.internal.tmf.ui;x-friends:="org.eclipse.tracecompass.tmf.ui.tests,org.eclipse.tracecompass.tmf.ctf.ui.tests",
  org.eclipse.tracecompass.internal.tmf.ui.commands;x-internal:=true,
  org.eclipse.tracecompass.internal.tmf.ui.dialogs;x-internal:=true,
@@ -49,7 +51,8 @@ Export-Package: org.eclipse.tracecompass.internal.tmf.ui;x-friends:="org.eclipse
    org.eclipse.tracecompass.tmf.ui,
    org.eclipse.tracecompass.lttng2.control.ui,
    org.eclipse.tracecompass.tmf.remote.ui,
-   org.eclipse.tracecompass.tmf.ui.swtbot.tests",
+   org.eclipse.tracecompass.tmf.ui.swtbot.tests,
+   org.eclipse.tracecompass.tmf.ui.tests",
  org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg;x-friends:="org.eclipse.tracecompass.tmf.remote.ui,org.eclipse.tracecompass.tmf.remote.ui.tests,org.eclipse.tracecompass.lttng2.control.ui",
  org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport;x-friends:="org.eclipse.tracecompass.tmf.remote.ui",
  org.eclipse.tracecompass.internal.tmf.ui.symbols;x-internal:=true,
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/DownloadTraceHttpHelper.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/DownloadTraceHttpHelper.java
new file mode 100644 (file)
index 0000000..3b27d8c
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ericsson 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:
+ *   Simon Delisle - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.util.Collection;
+import org.apache.commons.io.FileUtils;
+import org.eclipse.tracecompass.internal.tmf.ui.Activator;
+
+import com.google.common.net.MediaType;
+
+/**
+ * Helper to download traces from HTTP/HTTPS.
+ *
+ * @author Simon Delisle
+ *
+ */
+public class DownloadTraceHttpHelper {
+    private static final String CONTENT_DISPOSITION = "Content-Disposition"; //$NON-NLS-1$
+
+    /**
+     * Download trace from a HTTP/HTTPS source.
+     *
+     * @param traceUrl
+     *            Trace url you want to download
+     * @param destinationDir
+     *            Directory where the trace will be saved
+     * @return The downloaded trace or null if something went wrong
+     */
+    public static TraceDownloadStatus downloadTrace(String traceUrl, String destinationDir) {
+        File destFile = null;
+
+        try {
+            URL url = new URL(traceUrl);
+            HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
+            httpConnection.setConnectTimeout(120000); // 2 minutes timeout
+            int responseCode = httpConnection.getResponseCode();
+
+            if (responseCode != HttpURLConnection.HTTP_OK) {
+                httpConnection.disconnect();
+                return new TraceDownloadStatus(TraceDownloadStatus.ERROR, destFile, null);
+            }
+
+            String fileName = getFileName(httpConnection);
+            destFile = new File(destinationDir, fileName);
+
+            try {
+                FileUtils.copyURLToFile(url, destFile);
+            } catch (IOException e) {
+                Activator.getDefault().logError("Unable to download from " + url.toString() + " to " + destFile.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+                cleanDirectory(new File(destinationDir));
+                return new TraceDownloadStatus(TraceDownloadStatus.ERROR, destFile, e);
+            } finally {
+                httpConnection.disconnect();
+            }
+        } catch (SocketTimeoutException e) {
+            return new TraceDownloadStatus(TraceDownloadStatus.TIMEOUT, null, e);
+        } catch (IOException e) {
+            return new TraceDownloadStatus(TraceDownloadStatus.ERROR, null, e);
+        }
+
+        return new TraceDownloadStatus(TraceDownloadStatus.OK, destFile, null);
+    }
+
+    /**
+     * Download multiple traces from a list of HTTP/HTTPS sources.
+     *
+     * @param tracesUrl
+     *            Collection of trace url
+     * @param destinationDir
+     *            Directory where the traces will be saved
+     * @return List that contains downloaded traces or null if something went
+     *         wrong
+     */
+    public static TraceDownloadStatus downloadTraces(Collection<String> tracesUrl, String destinationDir) {
+        TraceDownloadStatus status = new TraceDownloadStatus(TraceDownloadStatus.OK, null, null);
+        for (String traceUrl : tracesUrl) {
+            TraceDownloadStatus singleFileStatus = downloadTrace(traceUrl, destinationDir);
+            status.add(singleFileStatus);
+        }
+        return status;
+    }
+
+    /**
+     * Try to find the name of the file by using connection information.
+     *
+     * @param connection
+     *            HTTP connection
+     * @return File name
+     */
+    private static String getFileName(HttpURLConnection connection) {
+        String fileName = getLastSegmentUrl(connection.getURL().toString());
+        String contentType = connection.getContentType();
+
+        if (contentType != null) {
+            MediaType type = MediaType.parse(contentType);
+            if (type.is(MediaType.ANY_APPLICATION_TYPE)) {
+                String contentDisposition = connection.getHeaderField(CONTENT_DISPOSITION);
+                if (contentDisposition != null) {
+                    String[] content = contentDisposition.split(";"); //$NON-NLS-1$
+                    for (String string : content) {
+                        if (string.contains("filename=")) { //$NON-NLS-1$
+                            int index = string.indexOf('"');
+                            fileName = string.substring(index + 1, string.length() - 1);
+                        }
+                    }
+                }
+            }
+        }
+
+        return fileName;
+    }
+
+    /**
+     * Get the last part of a specific url (after the last '/').
+     *
+     * @param url
+     *            The url
+     * @return The last segment of the url
+     */
+    private static String getLastSegmentUrl(String url) {
+        int indexFile = url.lastIndexOf('/');
+        return url.substring(indexFile + 1, url.length());
+    }
+
+    /**
+     * Clean the destination directory in case something went wrong during the
+     * download.
+     *
+     * @param dir
+     *            Directory to delete
+     */
+    private static void cleanDirectory(File dir) {
+        try {
+            FileUtils.deleteDirectory(dir);
+        } catch (IOException e) {
+            Activator.getDefault().logError("Unable to delete: " + dir.toString(), e); //$NON-NLS-1$
+        }
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/TraceDownloadStatus.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/project/wizards/importtrace/TraceDownloadStatus.java
new file mode 100644 (file)
index 0000000..4b4ee62
--- /dev/null
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ericsson 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:
+ *   Simon Delisle - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Status of a trace download operation. Can contain multiple status to track
+ * mutliple download in the same operation.
+ *
+ * @author Simon Delisle
+ *
+ */
+public class TraceDownloadStatus {
+
+    /**
+     * Status type severity indicating this status represents the normal case.
+     */
+    public static final int OK = 0;
+
+    /**
+     * Status type severity indicating this status represents a http/https
+     * connection timeout.
+     */
+    public static final int TIMEOUT = 0x01;
+
+    /**
+     * Status type severity indicating this status represents an error.
+     */
+    public static final int ERROR = 0x02;
+
+    private File fDownloadedFile;
+    private Throwable fException;
+    private int fSeverity;
+    private List<TraceDownloadStatus> fMultipleStatus;
+
+    /**
+     * Constructor.
+     *
+     * @param severity
+     *            Status severity
+     * @param file
+     *            Downloaded file
+     * @param exception
+     *            The exception that describe the problem
+     */
+    public TraceDownloadStatus(int severity, File file, Throwable exception) {
+        fSeverity = severity;
+        fDownloadedFile = file;
+        fException = exception;
+        fMultipleStatus = new ArrayList<>();
+    }
+
+    /**
+     * Get the downloaded file if the operation was successful. Can be null if
+     * something went wrong during the download.
+     *
+     * @return The downloaded file
+     */
+    public File getDownloadedFile() {
+        return fDownloadedFile;
+    }
+
+    /**
+     * Get the wrapped exception.
+     *
+     * @return The exception that describe the problem
+     */
+    public Throwable getException() {
+        return fException;
+    }
+
+    /**
+     * Get the status severity (OK, TIMEOUT or ERROR).
+     *
+     * @return The status severity
+     */
+    public int getSeverity() {
+        return fSeverity;
+    }
+
+    /**
+     * Set the downloaded file.
+     *
+     * @param downloadedFile
+     *            File to wrap in this status
+     */
+    public void setDownloadedFile(File downloadedFile) {
+        fDownloadedFile = downloadedFile;
+    }
+
+    /**
+     * Set the exception for this status.
+     *
+     * @param exception
+     *            Exception to wrap in this status
+     */
+    public void setException(Throwable exception) {
+        fException = exception;
+    }
+
+    /**
+     * Set the status severity (OK, TIMEOUT or ERROR).
+     *
+     * @param severity
+     *            The status severity
+     */
+    public void setSeverity(int severity) {
+        fSeverity = severity;
+    }
+
+    /**
+     * Check if the status as a severity of OK
+     *
+     * @return True if the status is OK
+     */
+    public boolean isOk() {
+        return fSeverity == OK;
+    }
+
+    /**
+     * Check if the status as a severity of TIMEOUT
+     *
+     * @return True if the status is a TIMEOUT
+     */
+    public boolean isTimeout() {
+        return fSeverity == TIMEOUT;
+    }
+
+    /**
+     * Get a list of children status in case it's a multiple status or an empty
+     * list if it's not the case.
+     *
+     * @return All the children status of this status
+     */
+    public List<TraceDownloadStatus> getChildren() {
+        return fMultipleStatus;
+    }
+
+    /**
+     * Add a status to this status and update the severity using the given
+     * status severity
+     *
+     * @param status
+     *            Status to add
+     */
+    public void add(TraceDownloadStatus status) {
+        fMultipleStatus.add(status);
+        if (status.getSeverity() == TIMEOUT) {
+            fSeverity = TIMEOUT;
+            fException = status.getException();
+        } else if (fSeverity == OK && !status.isOk()) {
+            fSeverity = status.getSeverity();
+        }
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/actions/HttpTraceImportOperation.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/actions/HttpTraceImportOperation.java
new file mode 100644 (file)
index 0000000..e703f60
--- /dev/null
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Ericsson 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:
+ *     Simon Delisle - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tracecompass.tmf.ui.actions;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.ArchiveUtil;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.DownloadTraceHttpHelper;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.FileSystemObjectImportStructureProvider;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.IFileSystemObject;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizardPage;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.TraceDownloadStatus;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.TraceFileSystemElement;
+import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace.TraceValidateAndImportOperation;
+import org.eclipse.tracecompass.tmf.core.util.Pair;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
+
+/**
+ * An operation which downloads and imports traces from a http/https source.
+ *
+ * @author Simon Delisle
+ * @since 2.4
+ *
+ */
+public class HttpTraceImportOperation extends WorkspaceModifyOperation {
+
+    private static final String TRACE_HTTP_IMPORT_TEMP_FOLDER = ".traceHttpImport"; //$NON-NLS-1$
+
+    private final Collection<String> fSourceUrl;
+    private final TmfTraceFolder fDestinationFolder;
+
+    /**
+     * Constructor
+     *
+     * @param sourceUrl
+     *            HTTP url for the trace you want to import
+     * @param destFolder
+     *            The destination folder
+     */
+    public HttpTraceImportOperation(String sourceUrl, TmfTraceFolder destFolder) {
+        fSourceUrl = Collections.singletonList(sourceUrl);
+        fDestinationFolder = destFolder;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param sourceUrl
+     *            List of HTTP url for the traces you want to import
+     * @param destFolder
+     *            The destination folder
+     */
+    public HttpTraceImportOperation(Collection<String> sourceUrl, TmfTraceFolder destFolder) {
+        fSourceUrl = sourceUrl;
+        fDestinationFolder = destFolder;
+    }
+
+    @Override
+    protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
+        int importOptionFlags = ImportTraceWizardPage.OPTION_IMPORT_UNRECOGNIZED_TRACES | ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES |
+                ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE;
+
+        // Temporary directory to contain any downloaded files
+        IFolder tempDestination = fDestinationFolder.getProject().getResource().getFolder(TRACE_HTTP_IMPORT_TEMP_FOLDER);
+        String tempDestinationFolderPath = tempDestination.getLocation().toOSString();
+        if (tempDestination.exists()) {
+            tempDestination.delete(true, monitor);
+        }
+        tempDestination.create(IResource.HIDDEN, true, monitor);
+
+        // Download trace/traces
+        List<File> downloadedTraceList = new ArrayList<>();
+        TraceDownloadStatus status = DownloadTraceHttpHelper.downloadTraces(fSourceUrl, tempDestinationFolderPath);
+        if (status.isOk()) {
+            List<TraceDownloadStatus> children = status.getChildren();
+            for (TraceDownloadStatus traceDownloadStatus : children) {
+                downloadedTraceList.add(traceDownloadStatus.getDownloadedFile());
+            }
+        } else if (status.isTimeout()) {
+            if (tempDestination.exists()) {
+                tempDestination.delete(true, monitor);
+            }
+            throw new InterruptedException();
+        }
+
+        boolean isArchive = false;
+        if (!downloadedTraceList.isEmpty()) {
+            isArchive = ArchiveUtil.isArchiveFile(downloadedTraceList.get(0));
+        }
+
+        FileSystemObjectImportStructureProvider provider = null;
+        IFileSystemObject object = null;
+
+        if (isArchive) {
+            // If it's an archive there is only 1 element in this list
+            Pair<IFileSystemObject, FileSystemObjectImportStructureProvider> rootObjectAndProvider = ArchiveUtil.getRootObjectAndProvider(downloadedTraceList.get(0), null);
+            provider = rootObjectAndProvider.getSecond();
+            object = rootObjectAndProvider.getFirst();
+        } else {
+            provider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
+            object = provider.getIFileSystemObject(new File(tempDestinationFolderPath));
+        }
+
+        TraceFileSystemElement root = TraceFileSystemElement.createRootTraceFileElement(object, provider);
+
+        List<TraceFileSystemElement> fileSystemElements = new ArrayList<>();
+        root.getAllChildren(fileSystemElements);
+
+        IPath sourceContainerPath = new Path(tempDestinationFolderPath);
+        IPath destinationContainerPath = fDestinationFolder.getPath();
+
+        TraceValidateAndImportOperation validateAndImportOperation = new TraceValidateAndImportOperation(null, fileSystemElements, null, sourceContainerPath, destinationContainerPath, isArchive, importOptionFlags, fDestinationFolder);
+        validateAndImportOperation.run(monitor);
+
+        // Clean the temporary directory
+        if (tempDestination.exists()) {
+            tempDestination.delete(true, monitor);
+        }
+    }
+
+}
This page took 0.034325 seconds and 5 git commands to generate.