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

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