Bug 548523 - Add application to import serialized performance results

The application can deserialize performance tests results generated from
InternalPerformanceMeter and store them in database for the following
analysis step.

<Sravan>
update pom.xml to use 4.13 i-build

Change-Id: Ic320a07e0deca73b623ca8e6010c457eccc4462b
Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
diff --git a/bundles/org.eclipse.test.performance.ui/plugin.xml b/bundles/org.eclipse.test.performance.ui/plugin.xml
index b67bc04..7ab9919 100644
--- a/bundles/org.eclipse.test.performance.ui/plugin.xml
+++ b/bundles/org.eclipse.test.performance.ui/plugin.xml
@@ -13,6 +13,15 @@
       </application>
    </extension>
    <extension
+         id="importPerformanceData"
+         point="org.eclipse.core.runtime.applications">
+      <application>
+         <run
+               class="org.eclipse.test.performance.ui.ImportDataMain">
+         </run>
+      </application>
+   </extension>
+   <extension
          point="org.eclipse.ui.preferencePages">
       <page
             class="org.eclipse.test.internal.performance.results.ui.PerformanceResultsPreferencePage"
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ImportDataMain.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ImportDataMain.java
new file mode 100644
index 0000000..79e63e2
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ImportDataMain.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Paul Pazderski and others.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which
+ * accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors: Paul Pazderski - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.test.performance.ui;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.test.internal.performance.data.Sample;
+import org.eclipse.test.internal.performance.db.DB;
+import org.eclipse.test.internal.performance.db.Variations;
+
+/**
+ * Helper application for Eclipse releng process. Instead of writing performance test data into a central database they are now
+ * serialized into a file. This application take the part to deserialize the results from file and store them in a local database
+ * for the following result generation step.
+ * <p>
+ * The data files to import are given as command line arguments and will be deleted upon successful import into database.
+ * </p>
+ */
+public class ImportDataMain implements IApplication {
+
+  @Override
+  public Object start(IApplicationContext context) throws Exception {
+    String[] args = (String[]) context.getArguments().get("application.args");
+    if (args.length > 0) {
+      System.out.println("\n\t= = Raw arguments ('application.args') passed to performance import application: = =");
+      for (int i = 0; i < args.length; i++) {
+        System.out.println("\t\t>" + args[i] + "<");
+      }
+    }
+    IStatus result = run(args);
+    (result.isOK() ? System.out : System.err).println(result.getMessage());
+    if (result.getException() != null) {
+      result.getException().printStackTrace();
+    }
+    return result;
+  }
+
+  private IStatus run(String[] args) {
+    try {
+      // parse arguments
+      List<Path> inputFiles = new ArrayList<>();
+      boolean processOpts = true;
+      for (String arg : args) {
+        if (arg.equals("--")) {
+          processOpts = false;
+          continue;
+        }
+        if (processOpts && arg.startsWith("-")) {
+          System.err.println("ERROR: Unrecognized option found, with value of >" + arg + "<");
+          continue;
+        }
+
+        Path inputFile = Paths.get(arg);
+        if (Files.isReadable(inputFile)) {
+          inputFiles.add(inputFile);
+        } else {
+          System.err.println("ERROR: invalid input argument. Cannot read file: " + inputFile);
+        }
+      }
+
+      // check database
+      System.out.println("INFO: Connecting to database...");
+      DB.getConnection();
+      if (!DB.isActive()) {
+        return new Status(IStatus.ERROR, UiPlugin.getDefault().toString(), "Cannot connect to performance database.");
+      }
+
+      // import data
+      IStatus exitStatus = new Status(IStatus.OK, UiPlugin.getDefault().toString(), "Nothing to import.");
+      System.out.println("INFO: Start importing " + inputFiles.size() + " performance data files.");
+      for (Path inputFile : inputFiles) {
+        exitStatus = importData(inputFile);
+        if (exitStatus.isOK()) {
+          Files.delete(inputFile);
+        }
+      }
+      return exitStatus;
+    } catch (Exception ex) {
+      return new Status(IStatus.ERROR, UiPlugin.getDefault().toString(), "Performance data import failed with exception!", ex);
+    }
+    finally {
+      DB.shutdown();
+    }
+  }
+
+  @Override
+  public void stop() {
+    // Do nothing
+  }
+
+  /**
+   * Import performance test results from the given input file into database.
+   *
+   * @param inputFile
+   *          serialized performance data to import
+   * @throws ClassCastException
+   *           if the input file has not the expected content but unknown objects
+   * @throws IOException
+   *           for general problems on reading the input file
+   */
+  private IStatus importData(Path inputFile) throws IOException, ClassNotFoundException {
+    System.out.println("INFO: Reading data from " + inputFile);
+    // Note: the input file can contain multiple data entries
+    // (ID+Variation+Sample) but they are not written consecutive
+    // by one object stream but instead by a new object stream
+    // each time. That's why it's required to use one input stream
+    // but multiple object streams to read them.
+    try (InputStream is = Files.newInputStream(inputFile)) {
+      while (true) { // loop will end on input stream EOF
+        ObjectInputStream ois = new ObjectInputStream(is);
+        String scenarioId = null;
+        Variations variations = null;
+        Sample sample = null;
+        while (scenarioId == null || variations == null || sample == null) {
+          Object o = ois.readObject();
+          if (String.class.equals(o.getClass())) {
+            scenarioId = (String) o;
+          } else if (Variations.class.equals(o.getClass())) {
+            variations = (Variations) o;
+          } else if (Sample.class.equals(o.getClass())) {
+            sample = (Sample) o;
+          } else {
+            System.err.println("WARN: Input contains unexpected object of type " + o.getClass().getCanonicalName());
+          }
+        }
+
+        System.out.println("DEBUG: Store data for scenario " + scenarioId);
+        boolean success = DB.store(variations, sample);
+        if (!success) {
+          System.err.println("ERROR: Failed to import scenario " + scenarioId);
+        }
+      }
+    } catch (EOFException ex) {
+      // EOFException is the intended way to end the loop
+      return new Status(IStatus.OK, UiPlugin.getDefault().toString(), "Everything is OK");
+    }
+  }
+}
diff --git a/features/org.eclipse.releng.build.tools.feature/feature.xml b/features/org.eclipse.releng.build.tools.feature/feature.xml
index 128dea7..e854bfc 100644
--- a/features/org.eclipse.releng.build.tools.feature/feature.xml
+++ b/features/org.eclipse.releng.build.tools.feature/feature.xml
@@ -5,7 +5,7 @@
       version="1.0.101.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.license"
-      license-feature-version="1.0.1.v20140414-1359">
+      license-feature-version="0.0.0">
 
    <description>
       %description
diff --git a/pom.xml b/pom.xml
index 7b8ca36..adca44e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,9 +23,9 @@
   </prerequisites>
 
   <properties>
-    <tycho.version>1.2.0</tycho.version>
-    <tycho-extras.version>1.2.0</tycho-extras.version>
-    <cbi-plugins.version>1.1.5</cbi-plugins.version>
+    <tycho.version>1.4.0</tycho.version>
+    <tycho-extras.version>1.4.0</tycho-extras.version>
+    <cbi-plugins.version>1.1.7</cbi-plugins.version>
     <maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format>
     <buildTimestamp>${maven.build.timestamp}</buildTimestamp>
     <buildType>I</buildType>
@@ -36,18 +36,20 @@
     <buildTimestamp>${maven.build.timestamp}</buildTimestamp>
     <buildType>I</buildType>
     <buildId>${buildType}${buildTimestamp}</buildId>
-    <comparator.repo>http://download.eclipse.org/eclipse/updates/4.9-I-builds</comparator.repo>
+    <comparator.repo>http://download.eclipse.org/eclipse/updates/4.13-I-builds</comparator.repo>
     <egit-repo.url>http://download.eclipse.org/egit/updates</egit-repo.url>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <cbi-jdt-repo.url>https://repo.eclipse.org/content/repositories/eclipse-staging/</cbi-jdt-repo.url>
     <cbi-jdt-version>3.12.0.v20160516-2131</cbi-jdt-version>
     <cbi-jdt-apt-version>1.2.100.v20160418-1457</cbi-jdt-apt-version>
+    <cbi-ecj-version>3.19.0.v20190730-0656</cbi-ecj-version>
+    
 
     <cbi-snapshots-repo.url>https://repo.eclipse.org/content/repositories/cbi-snapshots/</cbi-snapshots-repo.url>
     <eclipse-repo.url>https://repo.eclipse.org/content/repositories/cbi/</eclipse-repo.url>
 
     <!-- CBI provided common license feature. (bug 394793) -->
-    <license-repo.url>http://download.eclipse.org/cbi/updates/license/</license-repo.url>
+    <license-repo.url>https://download.eclipse.org/cbi/updates/license/2.0.1.v20180423-1114/</license-repo.url>
 
 
     <tycho.scmUrl>scm:git:git://git.eclipse.org/gitroot/platform/eclipse.platform.releng.buildtools</tycho.scmUrl>
@@ -96,7 +98,7 @@
       <id>eclipse-platform-repository</id>
       <layout>p2</layout>
       <!-- Normally should be "latest milestone" for stability, once we have one for 4.9. -->
-      <url>http://download.eclipse.org/eclipse/updates/4.9-I-builds/</url>
+      <url>http://download.eclipse.org/eclipse/updates/4.13-I-builds/</url>
     </repository>
     <repository>
       <id>eclipse-derby-buildtools-repository</id>
@@ -168,17 +170,12 @@
           <artifactId>tycho-compiler-plugin</artifactId>
           <version>${tycho.version}</version>
           <dependencies>
-            <dependency>
+           <dependency>
               <groupId>org.eclipse.jdt</groupId>
-              <artifactId>org.eclipse.jdt.core</artifactId>
-              <version>${cbi-jdt-version}</version>
+              <artifactId>ecj</artifactId>
+              <version>${cbi-ecj-version}</version>
             </dependency>
-            <dependency>
-              <groupId>org.eclipse.jdt</groupId>
-              <artifactId>org.eclipse.jdt.compiler.apt</artifactId>
-              <version>${cbi-jdt-apt-version}</version>
-            </dependency>
-          </dependencies>
+           </dependencies>
           <configuration>
             <compilerArgs>
               <args>-verbose</args>