Mercurial > repos > yufei-luo > s_mart
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); + } +} +