diff SMART/Java/Installer/SmartInstallerTask.java @ 31:0ab839023fe4

Uploaded
author m-zytnicki
date Tue, 30 Apr 2013 14:33:21 -0400
parents 769e306b7933
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SMART/Java/Installer/SmartInstallerTask.java	Tue Apr 30 14:33:21 2013 -0400
@@ -0,0 +1,419 @@
+import java.util.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+import java.net.*;
+import java.util.Stack;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class SmartInstallerTask extends SwingWorker<Boolean, String> {
+
+  int BUFFER = 1024;
+
+  int       architecture         = 0;
+  String    installDirectoryName = null;
+  JTextArea logArea              = null;
+  boolean[] selectedPrograms     = null;
+
+  // program chooser buttons
+  String    programChoosers[] = {"R", "R Color Brewer Package", "R HMisc Package", "Python 2.6", "S-MART"};
+
+  // Web addresses for the tools
+  String packageAddresses[][] = {
+    {"http://cran.cict.fr/bin/windows/base/R-2.11.0-win32.exe", "http://cran.cict.fr/bin/windows64/base/R-2.11.0-win64.exe"},
+    {"", ""},
+    {"", ""},
+    {"http://www.python.org/ftp/python/2.6.5/python-2.6.5.msi", "http://www.python.org/ftp/python/2.6.5/python-2.6.5.amd64.msi"},
+    {"http://urgi.versailles.inra.fr/content/download/1929/17848/file/s-mart-1.0.15.zip", "http://urgi.versailles.inra.fr/content/download/1929/17848/file/s-mart-1.0.15.zip"}
+  };
+
+  // Packages to install
+  String rPackages[] = {"RColorBrewer", "Hmisc"};
+
+  // Script lines
+  String scriptLines[][] = {
+    {"\"<INSTALLDIR>\\R-2.11.0-win32.exe\"", "\"<INSTALLDIR>\\R-2.11.0-win64.exe\""},
+    {"\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installRColorBrewer.R\"", "\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installRColorBrewer.R\""},
+    {"\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installHmisc.R\"", "\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installHmisc.R\""},
+    {"msiexec /i \"<INSTALLDIR>\\python-2.6.5.msi\"", "msiexec /i \"<INSTALLDIR>\\python-2.6.5.amd64.msi\""},
+    {"", ""}
+  };
+
+  // Files to uncompress
+  String compressedFiles[][] = {
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"<INSTALLDIR>\\s-mart-1.0.15.zip", "<INSTALLDIR>\\s-mart-1.0.15.zip"}
+  };
+
+
+  public SmartInstallerTask(JTextArea ta, boolean[] b, String s, int a) {
+    logArea              = ta;
+    selectedPrograms     = b;
+    installDirectoryName = s;
+    architecture         = a;
+  }
+
+
+  @Override
+  public Boolean doInBackground() {
+    boolean installOk;
+    publish("Starting install\n");
+    writeFiles();
+    for (int i = 0; i < selectedPrograms.length; i++) {
+      if (selectedPrograms[i]) {
+        if (! install(i)) {
+          return Boolean.FALSE;
+        }
+      }
+    }
+    removeFiles();
+    setEnvironmentVariables();
+    publish("Ending install\n");
+    return Boolean.TRUE;
+  }
+
+
+  @Override
+  protected void process(List<String> chunks) {
+    for (String chunk: chunks) {
+      logArea.append(chunk);
+    }
+  }
+
+
+  private boolean launch(String command) {
+    return realLaunch(new ProcessBuilder(command), command);
+  }
+
+  private boolean launch(String[] command) {
+    return realLaunch(new ProcessBuilder(command), Arrays.toString(command));
+  }
+
+  private boolean realLaunch(ProcessBuilder pb, String command) {
+    BufferedReader outputReader;
+    pb                          = pb.redirectErrorStream(true);
+    Process        process      = null;
+    publish("      Starting command '" + command + "'\n");
+    try {
+      process = pb.start();
+      BufferedInputStream outputStream = new BufferedInputStream(process.getInputStream());
+      InputStream is        = process.getInputStream();
+      InputStreamReader isr = new InputStreamReader(is);
+      outputReader          = new BufferedReader(isr);
+    }
+    catch (Exception exception) {
+      publish("      !Process cannot be started (command is '" + command + "')!\n");
+      exception.printStackTrace();
+      return false;
+    }
+    if (outputReader == null) {
+      publish("      !Problem in the output of the command!\n");
+      return false;
+    }
+    else {
+      publish("      Output is:\n");
+      try {
+        publish("        ---\n");
+        String line;
+        while ((line = outputReader.readLine()) != null) {
+          publish("        " + line + "\r\n");
+        }
+        publish("        ---\n");
+      }
+      catch (IOException e) {
+        publish("      !Cannot get the output of the command!\n");
+        return false;
+      }
+    }
+    int exitValue = process.exitValue();
+    if (exitValue != 0) {
+      publish("      !Problem during the execution of the command '" + command + "'!\n");
+      return false;
+    }
+    publish("      Ending command '" + command + "'\n");
+    return true;
+  }
+
+
+  private File lookForFile(String fileName, String[] putativePlaces) {
+    publish("      Looking for file " + fileName + "\n");
+    for (String place: putativePlaces) {
+      File file = new File(place, fileName);
+      publish("      Look at " + file.getAbsolutePath() + "\n");
+      if (file.exists()) {
+        publish("      Found it in expected place " + file.getAbsolutePath() + "\n");
+        return file;
+      }
+    }
+    Stack<File> files = new Stack<File>();
+    files.push(new File("\\"));
+    while (! files.empty()) {
+      File file = files.pop();
+      for (File childFile: file.listFiles()) {
+        if (childFile.isDirectory()) {
+          files.push(childFile);
+        }
+        else {
+          if (fileName.compareToIgnoreCase(childFile.getName()) == 0) {
+            publish("      Found it in unexpected place " + childFile.getAbsolutePath() + "\n");
+            return childFile;
+          }
+        }
+      }
+    }
+    publish("      !Cannot file file '" + fileName + "'!\n");
+    return null;
+  }
+
+
+  private boolean writeFile(String fileName, String content) {
+    try {
+      FileWriter     fw = new FileWriter(fileName);
+      BufferedWriter bw = new BufferedWriter(fw);
+      bw.write(content);
+      bw.close();
+      fw.close();
+    }
+    catch (Exception e) {
+      publish("      !Cannot write file '" + fileName + "'!\n");
+      return false;
+    }
+    return true;
+  }
+
+
+  private boolean removeFile(String fileName) {
+    File file = new File(fileName);
+    if (file.exists()) {
+      if (! file.delete()) {
+        publish("      !Cannot delete file '" + file.getAbsolutePath() + "'!\n");
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+  private boolean writeFiles() {
+    for (String rPackage: rPackages) {
+      String fileName = installDirectoryName + File.separator + "install" + rPackage + ".R";
+      String content  = "install.packages(\"" + rPackage + "\", repos = \"http://cran.cict.fr\", dependencies = TRUE)\n";
+      if (! writeFile(fileName, content)) {
+        publish("    !Cannot write file for R package '" + rPackage + "'!\n");
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private boolean removeFiles() {
+    for (String rPackage: rPackages) {
+      File file = new File(installDirectoryName + File.separator + "install" + rPackage + ".R");
+      if (! file.delete()) {
+        publish("!Cannot delete R install file for " + rPackage + "!\n");
+        return false;
+      }
+    }
+    File file = new File(installDirectoryName + File.separator + "createUser.sql");
+    if (! file.delete()) {
+      publish("!Cannot delete mySQL configuration file!\n");
+      return false;
+    }
+    return true;
+  }
+
+  private boolean install(int element) {
+    publish("  Starting install of " + programChoosers[element] + "\n");
+    downloadPackage(element);
+    executeInstall(element);
+    uncompressPackage(element);
+    removePackage(element);
+    postProcess(element);
+    publish("  Ending install of " + programChoosers[element] + "\n");
+    return true;
+  }
+
+
+  private String getLocalName(String remoteName) {
+    String localName = installDirectoryName + File.separator + (new File(remoteName)).getName();
+    int    position  = localName.indexOf("?");
+    if (position >= 0) {
+      localName = localName.substring(0, position);
+    }
+    return localName;
+  }
+
+
+  private boolean downloadPackage(int element) {
+    String fileName  = packageAddresses[element][architecture];
+    if (! "".equals(fileName)) {
+      publish("    Starting download of " + programChoosers[element] + "\n");
+      try {
+        BufferedInputStream  bis = new BufferedInputStream(new URL(fileName).openStream());
+        FileOutputStream     fos = new FileOutputStream(getLocalName(fileName));
+        BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
+        byte[] data = new byte[BUFFER];
+        int x       = 0;
+        while((x = bis.read(data, 0, BUFFER)) >= 0) {
+          bos.write(data, 0, x);
+        }
+        bos.close();
+        fos.close();
+        bis.close();
+      }
+      catch (IOException e) {
+        publish("    !Cannot download file '" + fileName + "'!\n");
+        return false;
+      }
+      publish("    Ending download of " + programChoosers[element] + "\n");
+    }
+    return true;
+  }
+
+
+  private String replaceSubstring(String line) {
+    if (line.contains("<INSTALLDIR>")) {
+      String protectedDirectory = installDirectoryName.replaceAll("\\\\", "\\\\\\\\");
+      line = line.replaceAll("<INSTALLDIR>", protectedDirectory);
+    }
+    if (line.contains("<RFILE>")) {
+      String   userName = System.getenv().get("USERNAME");
+      String[] possibleRDirectories = {"C:\\Program Files\\R-2.11.0", "C:\\Documents and Settings\\" + userName + "\\Mes documents\\R\\R-2.11.0\\bin", "C:\\Documents and Settings\\" + userName + "\\My documents\\R\\R-2.11.0\\bin"};
+      String rDirectory = lookForFile("'.exe", possibleRDirectories).getAbsolutePath();
+      rDirectory = rDirectory.replaceAll("\\\\", "\\\\\\\\");
+      line = line.replaceAll("<RFILE>", rDirectory);
+    }
+    return line;
+  }
+
+
+  private boolean executeInstall(int element) {
+    String commands           = scriptLines[element][architecture];
+    if (! "".equals(commands)) {
+      for (String command: commands.split(";")) {
+        command = replaceSubstring(command);
+        publish("    Starting command '" + command + "'\n");
+        Process process = null;
+        try {
+          process = Runtime.getRuntime().exec(command);
+        }
+        catch (IOException e) {
+          publish("    !Cannot execute command '" + command + "'!\n");
+          return false;
+        }
+        try {
+          process.waitFor();
+        }
+        catch (InterruptedException e) {
+          publish("    !Cannot wait for the end of the command '" + command + "'!\n");
+          return false;
+        }
+        int exitValue = process.exitValue();
+        if (exitValue != 0) {
+          publish("    !Problem during the execution of the command '" + command + "'!\n");
+          return false;
+        }
+        publish("    Ending command '" + command + "'\n");
+      }
+    }
+    return true;
+  }
+
+
+  private boolean uncompressPackage(int element) {
+    String file = compressedFiles[element][architecture];
+    if (! "".equals(file)) {
+      file = replaceSubstring(file);
+      publish("    Starting uncompressing file '" + file + "'\n");
+      try {
+        FileInputStream     fis = new FileInputStream(file);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        ZipInputStream      zis = new ZipInputStream(bis);
+        ZipEntry            entry;
+        while ((entry = zis.getNextEntry()) != null) {
+          if (! entry.isDirectory()) {
+            File newFile = new File(installDirectoryName + File.separator + entry.getName());
+            // create parent directories
+            File upDirectory = newFile.getParentFile();
+            while (upDirectory != null){
+              if (! upDirectory.exists()) {
+                upDirectory.mkdir();
+                publish("      Creating directory '" + upDirectory.getAbsolutePath() + "'\n");
+              }
+              upDirectory = upDirectory.getParentFile();
+            }
+            // write the files to the disk
+            publish("      Extracting '" + entry.getName() + "' to '" + newFile.getAbsolutePath() + "'\n");
+            int  count;
+            byte data[] = new byte[BUFFER];
+            FileOutputStream     fos = new FileOutputStream(newFile);
+            BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
+            while ((count = zis.read(data, 0, BUFFER)) != -1){
+              bos.write(data, 0, count);
+            }
+            bos.flush();
+            bos.close();
+            fos.close();
+          }
+        }
+        zis.close();
+        bis.close();
+        fis.close();
+      }
+      catch(FileNotFoundException e) {
+        publish("    !Cannot find file '" + file + "'!\n");
+        return false;
+      }
+      catch(Exception e){
+        publish("    !Cannot uncompress file '" + file + "'!\n");
+        return false;
+      }
+      publish("    Ending uncompressing file '" + file + "'\n");
+    }
+    return true;
+  }
+
+
+  private boolean removePackage(int element) {
+    String packageName = packageAddresses[element][architecture];
+    if ("".equals(packageName)) {
+      return true;
+    }
+    String fileName = getLocalName(packageAddresses[element][architecture]);
+    return removeFile(fileName);
+  }
+
+
+  private boolean postProcess(int element) {
+    switch (element) {
+      case 4:
+        // Move S-MART files to parent directory
+        File installDirectory = new File(installDirectoryName + File.separator + "S-Mart");
+        for (File file: installDirectory.listFiles()) {
+          File destinationFile = new File(file.getParentFile().getParentFile(), file.getName());
+          if (! file.renameTo(destinationFile)) {
+            publish("     !Cannot move '" + file.getAbsolutePath() + "' to '" + destinationFile.getAbsolutePath() + "'!\n");
+          }
+        }
+        if (! installDirectory.delete()) {
+          publish("     !Cannot remove installation S-MART directory '" + installDirectory.getAbsolutePath() + "'!\n");
+        }
+    }
+    return true;
+  }
+
+
+  private boolean setEnvironmentVariables() {
+    String[] command = {"REG", "ADD", "HKCU\\Environment", "/v", "PYTHONPATH", "/t", "REG_SZ", "/d", "\"" + installDirectoryName + "\\Python\"", "/f"};
+    return launch(command);
+  }
+}
+