Mercurial > repos > yufei-luo > s_mart
comparison SMART/Java/Installer/Old/SmartInstallerTask.java @ 18:94ab73e8a190
Uploaded
| author | m-zytnicki |
|---|---|
| date | Mon, 29 Apr 2013 03:20:15 -0400 |
| parents | 769e306b7933 |
| children |
comparison
equal
deleted
inserted
replaced
| 17:b0e8584489e6 | 18:94ab73e8a190 |
|---|---|
| 1 import java.util.*; | |
| 2 import java.awt.event.ActionEvent; | |
| 3 import java.awt.event.ActionListener; | |
| 4 import java.io.*; | |
| 5 import javax.swing.*; | |
| 6 import javax.swing.filechooser.*; | |
| 7 import javax.swing.border.*; | |
| 8 import javax.swing.SwingUtilities; | |
| 9 import java.net.*; | |
| 10 import java.util.Stack; | |
| 11 import java.util.zip.ZipEntry; | |
| 12 import java.util.zip.ZipInputStream; | |
| 13 | |
| 14 public class SmartInstallerTask extends SwingWorker<Boolean, String> { | |
| 15 | |
| 16 int BUFFER = 1024; | |
| 17 | |
| 18 int architecture = 0; | |
| 19 String installDirectoryName = null; | |
| 20 JTextArea logArea = null; | |
| 21 boolean[] selectedPrograms = null; | |
| 22 | |
| 23 // program chooser buttons | |
| 24 String programChoosers[] = {"R", "R Color Brewer Package", "R HMisc Package", "MySQL", "MySQL account", "Python 2.6", "Python DB", "S-MART"}; | |
| 25 | |
| 26 // Web addresses for the tools | |
| 27 String packageAddresses[][] = { | |
| 28 {"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"}, | |
| 29 {"", ""}, | |
| 30 {"", ""}, | |
| 31 {"http://mirrors.ircam.fr/pub/mysql/Downloads/MySQL-5.1/mysql-essential-5.1.47-win32.msi", "http://mirrors.ircam.fr/pub/mysql/Downloads/MySQL-5.1/mysql-essential-5.1.47-winx64.msi"}, | |
| 32 {"", ""}, | |
| 33 {"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"}, | |
| 34 {"http://www.technicalbard.com/files/MySQL-python-1.2.2.win32-py2.6.exe", "http://www.technicalbard.com/files/MySQL-python-1.2.2.win32-py2.6.exe"}, | |
| 35 {"http://urgi.versailles.inra.fr/download/s-mart/s-mart.zip", "http://urgi.versailles.inra.fr/download/s-mart/s-mart.zip"} | |
| 36 }; | |
| 37 | |
| 38 // Packages to install | |
| 39 String rPackages[] = {"RColorBrewer", "Hmisc"}; | |
| 40 | |
| 41 // Script lines | |
| 42 String scriptLines[][] = { | |
| 43 {"\"<INSTALLDIR>\\R-2.11.0-win32.exe\"", "\"<INSTALLDIR>\\R-2.11.0-win64.exe\""}, | |
| 44 {"\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installRColorBrewer.R\"", "\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installRColorBrewer.R\""}, | |
| 45 {"\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installHmisc.R\"", "\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installHmisc.R\""}, | |
| 46 {"msiexec /i \"<INSTALLDIR>\\mysql-essential-5.1.47-win32.msi\"", "msiexec /i \"<INSTALLDIR>\\mysql-essential-5.1.47-winx64.msi\""}, | |
| 47 {"", ""}, | |
| 48 {"msiexec /i \"<INSTALLDIR>\\python-2.6.5.msi\"", "msiexec /i \"<INSTALLDIR>\\python-2.6.5.amd64.msi\""}, | |
| 49 {"<INSTALLDIR>\\MySQL-python-1.2.2.win32-py2.6.exe", "<INSTALLDIR>\\MySQL-python-1.2.2.win32-py2.6.exe"}, | |
| 50 {"", ""} | |
| 51 }; | |
| 52 | |
| 53 // Files to uncompress | |
| 54 String compressedFiles[][] = { | |
| 55 {"", ""}, | |
| 56 {"", ""}, | |
| 57 {"", ""}, | |
| 58 {"", ""}, | |
| 59 {"", ""}, | |
| 60 {"", ""}, | |
| 61 {"", ""}, | |
| 62 {"<INSTALLDIR>\\s-mart.zip", "<INSTALLDIR>\\s-mart.zip"} | |
| 63 }; | |
| 64 | |
| 65 | |
| 66 public SmartInstallerTask(JTextArea ta, boolean[] b, String s, int a) { | |
| 67 logArea = ta; | |
| 68 selectedPrograms = b; | |
| 69 installDirectoryName = s; | |
| 70 architecture = a; | |
| 71 } | |
| 72 | |
| 73 | |
| 74 @Override | |
| 75 public Boolean doInBackground() { | |
| 76 boolean installOk; | |
| 77 publish("Starting install\n"); | |
| 78 writeFiles(); | |
| 79 for (int i = 0; i < selectedPrograms.length; i++) { | |
| 80 if (selectedPrograms[i]) { | |
| 81 if (! install(i)) { | |
| 82 return Boolean.FALSE; | |
| 83 } | |
| 84 } | |
| 85 } | |
| 86 removeFiles(); | |
| 87 setEnvironmentVariables(); | |
| 88 publish("Ending install\n"); | |
| 89 return Boolean.TRUE; | |
| 90 } | |
| 91 | |
| 92 | |
| 93 @Override | |
| 94 protected void process(List<String> chunks) { | |
| 95 for (String chunk: chunks) { | |
| 96 logArea.append(chunk); | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 | |
| 101 private boolean launch(String command) { | |
| 102 return realLaunch(new ProcessBuilder(command), command); | |
| 103 } | |
| 104 | |
| 105 private boolean launch(String[] command) { | |
| 106 return realLaunch(new ProcessBuilder(command), Arrays.toString(command)); | |
| 107 } | |
| 108 | |
| 109 private boolean realLaunch(ProcessBuilder pb, String command) { | |
| 110 BufferedReader outputReader; | |
| 111 pb = pb.redirectErrorStream(true); | |
| 112 Process process = null; | |
| 113 publish(" Starting command '" + command + "'\n"); | |
| 114 try { | |
| 115 process = pb.start(); | |
| 116 BufferedInputStream outputStream = new BufferedInputStream(process.getInputStream()); | |
| 117 InputStream is = process.getInputStream(); | |
| 118 InputStreamReader isr = new InputStreamReader(is); | |
| 119 outputReader = new BufferedReader(isr); | |
| 120 } | |
| 121 catch (Exception exception) { | |
| 122 publish(" !Process cannot be started (command is '" + command + "')!\n"); | |
| 123 exception.printStackTrace(); | |
| 124 return false; | |
| 125 } | |
| 126 if (outputReader == null) { | |
| 127 publish(" !Problem in the output of the command!\n"); | |
| 128 return false; | |
| 129 } | |
| 130 else { | |
| 131 publish(" Output is:\n"); | |
| 132 try { | |
| 133 publish(" ---\n"); | |
| 134 String line; | |
| 135 while ((line = outputReader.readLine()) != null) { | |
| 136 publish(" " + line + "\r\n"); | |
| 137 } | |
| 138 publish(" ---\n"); | |
| 139 } | |
| 140 catch (IOException e) { | |
| 141 publish(" !Cannot get the output of the command!\n"); | |
| 142 return false; | |
| 143 } | |
| 144 } | |
| 145 int exitValue = process.exitValue(); | |
| 146 if (exitValue != 0) { | |
| 147 publish(" !Problem during the execution of the command '" + command + "'!\n"); | |
| 148 return false; | |
| 149 } | |
| 150 publish(" Ending command '" + command + "'\n"); | |
| 151 return true; | |
| 152 } | |
| 153 | |
| 154 | |
| 155 private File lookForFile(String fileName, String[] putativePlaces) { | |
| 156 publish(" Looking for file " + fileName + "\n"); | |
| 157 for (String place: putativePlaces) { | |
| 158 File file = new File(place, fileName); | |
| 159 publish(" Look at " + file.getAbsolutePath() + "\n"); | |
| 160 if (file.exists()) { | |
| 161 publish(" Found it in expected place " + file.getAbsolutePath() + "\n"); | |
| 162 return file; | |
| 163 } | |
| 164 } | |
| 165 Stack<File> files = new Stack<File>(); | |
| 166 files.push(new File("\\")); | |
| 167 while (! files.empty()) { | |
| 168 File file = files.pop(); | |
| 169 for (File childFile: file.listFiles()) { | |
| 170 if (childFile.isDirectory()) { | |
| 171 files.push(childFile); | |
| 172 } | |
| 173 else { | |
| 174 if (fileName.compareToIgnoreCase(childFile.getName()) == 0) { | |
| 175 publish(" Found it in unexpected place " + childFile.getAbsolutePath() + "\n"); | |
| 176 return childFile; | |
| 177 } | |
| 178 } | |
| 179 } | |
| 180 } | |
| 181 publish(" !Cannot file file '" + fileName + "'!\n"); | |
| 182 return null; | |
| 183 } | |
| 184 | |
| 185 | |
| 186 private boolean writeFile(String fileName, String content) { | |
| 187 try { | |
| 188 FileWriter fw = new FileWriter(fileName); | |
| 189 BufferedWriter bw = new BufferedWriter(fw); | |
| 190 bw.write(content); | |
| 191 bw.close(); | |
| 192 fw.close(); | |
| 193 } | |
| 194 catch (Exception e) { | |
| 195 publish(" !Cannot write file '" + fileName + "'!\n"); | |
| 196 return false; | |
| 197 } | |
| 198 return true; | |
| 199 } | |
| 200 | |
| 201 | |
| 202 private boolean removeFile(String fileName) { | |
| 203 File file = new File(fileName); | |
| 204 if (file.exists()) { | |
| 205 if (! file.delete()) { | |
| 206 publish(" !Cannot delete file '" + file.getAbsolutePath() + "'!\n"); | |
| 207 return false; | |
| 208 } | |
| 209 } | |
| 210 return true; | |
| 211 } | |
| 212 | |
| 213 | |
| 214 private boolean writeFiles() { | |
| 215 for (String rPackage: rPackages) { | |
| 216 String fileName = installDirectoryName + File.separator + "install" + rPackage + ".R"; | |
| 217 String content = "install.packages(\"" + rPackage + "\", repos = \"http://cran.cict.fr\", dependencies = TRUE)\n"; | |
| 218 if (! writeFile(fileName, content)) { | |
| 219 publish(" !Cannot write file for R package '" + rPackage + "'!\n"); | |
| 220 return false; | |
| 221 } | |
| 222 } | |
| 223 String fileName = installDirectoryName + File.separator + "createUser.sql"; | |
| 224 String content = "CREATE USER 'smart'@'localhost';\nGRANT ALL PRIVILEGES ON *.* TO 'smart'@'localhost' WITH GRANT OPTION;\nCREATE DATABASE smart;\nGRANT ALL ON smart.* TO 'smart'@'localhost';\n"; | |
| 225 if (! writeFile(fileName, content)) { | |
| 226 publish(" !Cannot write mySQL configuration file!\n"); | |
| 227 return false; | |
| 228 } | |
| 229 return true; | |
| 230 } | |
| 231 | |
| 232 private boolean removeFiles() { | |
| 233 for (String rPackage: rPackages) { | |
| 234 File file = new File(installDirectoryName + File.separator + "install" + rPackage + ".R"); | |
| 235 if (! file.delete()) { | |
| 236 publish("!Cannot delete R install file for " + rPackage + "!\n"); | |
| 237 return false; | |
| 238 } | |
| 239 } | |
| 240 File file = new File(installDirectoryName + File.separator + "createUser.sql"); | |
| 241 if (! file.delete()) { | |
| 242 publish("!Cannot delete mySQL configuration file!\n"); | |
| 243 return false; | |
| 244 } | |
| 245 return true; | |
| 246 } | |
| 247 | |
| 248 private boolean install(int element) { | |
| 249 publish(" Starting install of " + programChoosers[element] + "\n"); | |
| 250 downloadPackage(element); | |
| 251 executeInstall(element); | |
| 252 uncompressPackage(element); | |
| 253 removePackage(element); | |
| 254 postProcess(element); | |
| 255 publish(" Ending install of " + programChoosers[element] + "\n"); | |
| 256 return true; | |
| 257 } | |
| 258 | |
| 259 | |
| 260 private String getLocalName(String remoteName) { | |
| 261 String localName = installDirectoryName + File.separator + (new File(remoteName)).getName(); | |
| 262 int position = localName.indexOf("?"); | |
| 263 if (position >= 0) { | |
| 264 localName = localName.substring(0, position); | |
| 265 } | |
| 266 return localName; | |
| 267 } | |
| 268 | |
| 269 | |
| 270 private boolean downloadPackage(int element) { | |
| 271 String fileName = packageAddresses[element][architecture]; | |
| 272 if (! "".equals(fileName)) { | |
| 273 publish(" Starting download of " + programChoosers[element] + "\n"); | |
| 274 try { | |
| 275 BufferedInputStream bis = new BufferedInputStream(new URL(fileName).openStream()); | |
| 276 FileOutputStream fos = new FileOutputStream(getLocalName(fileName)); | |
| 277 BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER); | |
| 278 byte[] data = new byte[BUFFER]; | |
| 279 int x = 0; | |
| 280 while((x = bis.read(data, 0, BUFFER)) >= 0) { | |
| 281 bos.write(data, 0, x); | |
| 282 } | |
| 283 bos.close(); | |
| 284 fos.close(); | |
| 285 bis.close(); | |
| 286 } | |
| 287 catch (IOException e) { | |
| 288 publish(" !Cannot download file '" + fileName + "'!\n"); | |
| 289 return false; | |
| 290 } | |
| 291 publish(" Ending download of " + programChoosers[element] + "\n"); | |
| 292 } | |
| 293 return true; | |
| 294 } | |
| 295 | |
| 296 | |
| 297 private String replaceSubstring(String line) { | |
| 298 if (line.contains("<INSTALLDIR>")) { | |
| 299 String protectedDirectory = installDirectoryName.replaceAll("\\\\", "\\\\\\\\"); | |
| 300 line = line.replaceAll("<INSTALLDIR>", protectedDirectory); | |
| 301 } | |
| 302 if (line.contains("<RFILE>")) { | |
| 303 String userName = System.getenv().get("USERNAME"); | |
| 304 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"}; | |
| 305 String rDirectory = lookForFile("'.exe", possibleRDirectories).getAbsolutePath(); | |
| 306 rDirectory = rDirectory.replaceAll("\\\\", "\\\\\\\\"); | |
| 307 line = line.replaceAll("<RFILE>", rDirectory); | |
| 308 } | |
| 309 if (line.contains("<MYSQLFILE>")) { | |
| 310 String userName = System.getenv().get("USERNAME"); | |
| 311 String[] possibleRDirectories = {"C:\\Program Files\\MySQL\\MySQL Server 5.1\\bin", "C:\\Documents and Settings\\" + userName + "\\Mes documents\\MySQL\\MySQL Server 5.1\\bin", "C:\\Documents and Settings\\" + userName + "\\My documents\\MySQL\\MySQL Server 5.1\\bin"}; | |
| 312 String rDirectory = lookForFile("mysql.exe", possibleRDirectories).getAbsolutePath(); | |
| 313 rDirectory = rDirectory.replaceAll("\\\\", "\\\\\\\\"); | |
| 314 line = line.replaceAll("<MYSQLFILE>", rDirectory); | |
| 315 } | |
| 316 return line; | |
| 317 } | |
| 318 | |
| 319 | |
| 320 private boolean executeInstall(int element) { | |
| 321 String commands = scriptLines[element][architecture]; | |
| 322 if (! "".equals(commands)) { | |
| 323 for (String command: commands.split(";")) { | |
| 324 command = replaceSubstring(command); | |
| 325 publish(" Starting command '" + command + "'\n"); | |
| 326 Process process = null; | |
| 327 try { | |
| 328 process = Runtime.getRuntime().exec(command); | |
| 329 } | |
| 330 catch (IOException e) { | |
| 331 publish(" !Cannot execute command '" + command + "'!\n"); | |
| 332 return false; | |
| 333 } | |
| 334 try { | |
| 335 process.waitFor(); | |
| 336 } | |
| 337 catch (InterruptedException e) { | |
| 338 publish(" !Cannot wait for the end of the command '" + command + "'!\n"); | |
| 339 return false; | |
| 340 } | |
| 341 int exitValue = process.exitValue(); | |
| 342 if (exitValue != 0) { | |
| 343 publish(" !Problem during the execution of the command '" + command + "'!\n"); | |
| 344 return false; | |
| 345 } | |
| 346 publish(" Ending command '" + command + "'\n"); | |
| 347 } | |
| 348 } | |
| 349 return true; | |
| 350 } | |
| 351 | |
| 352 | |
| 353 private boolean uncompressPackage(int element) { | |
| 354 String file = compressedFiles[element][architecture]; | |
| 355 if (! "".equals(file)) { | |
| 356 file = replaceSubstring(file); | |
| 357 publish(" Starting uncompressing file '" + file + "'\n"); | |
| 358 try { | |
| 359 FileInputStream fis = new FileInputStream(file); | |
| 360 BufferedInputStream bis = new BufferedInputStream(fis); | |
| 361 ZipInputStream zis = new ZipInputStream(bis); | |
| 362 ZipEntry entry; | |
| 363 while ((entry = zis.getNextEntry()) != null) { | |
| 364 if (! entry.isDirectory()) { | |
| 365 File newFile = new File(installDirectoryName + File.separator + entry.getName()); | |
| 366 // create parent directories | |
| 367 File upDirectory = newFile.getParentFile(); | |
| 368 while (upDirectory != null){ | |
| 369 if (! upDirectory.exists()) { | |
| 370 upDirectory.mkdir(); | |
| 371 publish(" Creating directory '" + upDirectory.getAbsolutePath() + "'\n"); | |
| 372 } | |
| 373 upDirectory = upDirectory.getParentFile(); | |
| 374 } | |
| 375 // write the files to the disk | |
| 376 publish(" Extracting '" + entry.getName() + "' to '" + newFile.getAbsolutePath() + "'\n"); | |
| 377 int count; | |
| 378 byte data[] = new byte[BUFFER]; | |
| 379 FileOutputStream fos = new FileOutputStream(newFile); | |
| 380 BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER); | |
| 381 while ((count = zis.read(data, 0, BUFFER)) != -1){ | |
| 382 bos.write(data, 0, count); | |
| 383 } | |
| 384 bos.flush(); | |
| 385 bos.close(); | |
| 386 fos.close(); | |
| 387 } | |
| 388 } | |
| 389 zis.close(); | |
| 390 bis.close(); | |
| 391 fis.close(); | |
| 392 } | |
| 393 catch(FileNotFoundException e) { | |
| 394 publish(" !Cannot find file '" + file + "'!\n"); | |
| 395 return false; | |
| 396 } | |
| 397 catch(Exception e){ | |
| 398 publish(" !Cannot uncompress file '" + file + "'!\n"); | |
| 399 return false; | |
| 400 } | |
| 401 publish(" Ending uncompressing file '" + file + "'\n"); | |
| 402 } | |
| 403 return true; | |
| 404 } | |
| 405 | |
| 406 | |
| 407 private boolean removePackage(int element) { | |
| 408 String packageName = packageAddresses[element][architecture]; | |
| 409 if ("".equals(packageName)) { | |
| 410 return true; | |
| 411 } | |
| 412 String fileName = getLocalName(packageAddresses[element][architecture]); | |
| 413 return removeFile(fileName); | |
| 414 } | |
| 415 | |
| 416 | |
| 417 private boolean postProcess(int element) { | |
| 418 switch (element) { | |
| 419 case 4: | |
| 420 // Create mySQL user | |
| 421 PasswordAsker pa = new PasswordAsker(); | |
| 422 if (! pa.waitForPassword()) { | |
| 423 publish("Problem in the password asker!\n"); | |
| 424 return false; | |
| 425 } | |
| 426 String command = "\"<MYSQLFILE>\" --user=root --password=" + pa.getPassword() + " -e \"source <INSTALLDIR>\\createUser.sql\""; | |
| 427 command = replaceSubstring(command); | |
| 428 if (! launch(command)) { | |
| 429 publish(" !Cannot create SQL accounts!\n"); | |
| 430 return false; | |
| 431 } | |
| 432 return true; | |
| 433 case 7: | |
| 434 // Move S-MART files to parent directory | |
| 435 File installDirectory = new File(installDirectoryName + File.separator + "S-Mart"); | |
| 436 for (File file: installDirectory.listFiles()) { | |
| 437 File destinationFile = new File(file.getParentFile().getParentFile(), file.getName()); | |
| 438 if (! file.renameTo(destinationFile)) { | |
| 439 publish(" !Cannot move '" + file.getAbsolutePath() + "' to '" + destinationFile.getAbsolutePath() + "'!\n"); | |
| 440 } | |
| 441 } | |
| 442 if (! installDirectory.delete()) { | |
| 443 publish(" !Cannot remove installation S-MART directory '" + installDirectory.getAbsolutePath() + "'!\n"); | |
| 444 } | |
| 445 } | |
| 446 return true; | |
| 447 } | |
| 448 | |
| 449 | |
| 450 private boolean setEnvironmentVariables() { | |
| 451 String[] command = {"REG", "ADD", "HKCU\\Environment", "/v", "PYTHONPATH", "/t", "REG_SZ", "/d", "\"" + installDirectoryName + "\\Python\"", "/f"}; | |
| 452 return launch(command); | |
| 453 } | |
| 454 } | |
| 455 |
