forked from DrJavaAtRice/drjava
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDrJavaRestart.java
More file actions
216 lines (208 loc) · 9.54 KB
/
DrJavaRestart.java
File metadata and controls
216 lines (208 loc) · 9.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*BEGIN_COPYRIGHT_BLOCK
*
* Copyright (c) 2001-2019, JavaPLT group at Rice University (drjava@rice.edu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
* * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* * Neither the names of DrJava, the JavaPLT group, Rice University, nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software is Open Source Initiative approved Open Source Software. Open Source Initative Approved is a trademark
* of the Open Source Initiative.
*
* This file is part of DrJava. Download the current version of this project from http://www.drjava.org/ or
* http://sourceforge.net/projects/drjava/
*
* END_COPYRIGHT_BLOCK*/
package edu.rice.cs.drjava;
import edu.rice.cs.plt.concurrent.JVMBuilder;
import edu.rice.cs.util.FileOps;
import java.io.*;
import javax.swing.JOptionPane;
/** Helper class for DrJava that copies a file and then starts it. Part of the automatic update
* in NewVersionPopup.
* @version $Id$
*/
public class DrJavaRestart {
/** Number of attempts to delete or rename files. This is necessary since an OS,
* particularly Windows, may still have a write lock on a file.
* Currently, we pause up to 5*1000 ms per operation. */
public static final int ATTEMPTS = 5;
public static final int TIME_BETWEEN_ATTEMPTS = 1000;
public static edu.rice.cs.util.Log LOG = new edu.rice.cs.util.Log("version.txt",false);
public static void message(String message) {
LOG.log(message);
JOptionPane.showMessageDialog(null, message,
"Error Updating DrJava", JOptionPane.ERROR_MESSAGE);
}
public static boolean delete(File f) {
for(int i = 0; i < ATTEMPTS; ++i) {
if (f.delete()) return true;
LOG.log("Failed to delete " + f + ", trying again");
try {
Thread.sleep(TIME_BETWEEN_ATTEMPTS);
}
catch(InterruptedException ie) { /* just wait */ }
}
return false;
}
public static boolean deleteRecursively(File f) {
for(int i = 0; i < ATTEMPTS; ++i) {
if (edu.rice.cs.plt.io.IOUtil.deleteRecursively(f)) return true;
LOG.log("Failed to recursively delete " + f + ", trying again");
try {
Thread.sleep(TIME_BETWEEN_ATTEMPTS);
}
catch(InterruptedException ie) { /* just wait */ }
}
return false;
}
public static boolean rename(File from, File to) {
for(int i = 0; i < ATTEMPTS; ++i) {
if (from.renameTo(to)) return true;
LOG.log("Failed to rename " + from + " to " + to + ", trying again");
try {
Thread.sleep(TIME_BETWEEN_ATTEMPTS);
}
catch(InterruptedException ie) { /* just wait */ }
}
return false;
}
public static void main(final String[] args) {
// args[0] source file
// args[1] destination file (will be started)
// args[2] restart file (should be deleted after the restart)
File source = new File(args[0]);
File dest = new File(args[1]);
File exec = dest;
try {
LOG.log("source: " + source.getAbsolutePath());
LOG.log("dest : " + dest.getAbsolutePath());
if (dest.exists()) {
if (dest.isFile()) {
// is a file, try to delete it
if (delete(dest)) {
// could delete it, rename source to dest
if (!rename(source,dest)) {
// could not rename, keep source as name
exec = source;
message("A new version of DrJava was downloaded. However, it could not be\n" +
"installed in the same place as the old DrJava.\n\n" +
"The new copy is now installed at:\n" +
source.getAbsolutePath() + "\n\n" +
"The old copy has been deleted.");
}
}
else {
// could not delete it, keep source as name
exec = source;
message("A new version of DrJava was downloaded. However, it could not be\n" +
"installed in the same place as the old DrJava.\n\n" +
"The new copy is now installed at:\n" +
source.getAbsolutePath() + "\n\n" +
"The old copy is still installed at:\n" +
dest.getAbsolutePath());
}
LOG.log("Restarting...");
JVMBuilder.DEFAULT.classPath(exec).start(DrJava.class.getName(), "-new", "-delete-after-restart", args[2]);
LOG.log("Done with DrJavaRestart");
System.exit(0);
}
else {
// is a directory, try to rename
// this should only happen with Mac DrJava.app
File old = FileOps.generateNewFileName(dest);
if (rename(dest,old)) {
if (rename(source,dest)) {
// could rename, now delete the directory containing the former source
delete(source.getParentFile());
if (!deleteRecursively(old)) {
message("A new version of DrJava was downloaded. However, the old version" +
"could not be deleted.\n\n" +
"The new copy is now installed at:\n" +
dest.getAbsolutePath() + "\n\n" +
"The old copy is still installed at:\n" +
old.getAbsolutePath());
}
}
else {
// could not rename, keep source as name
exec = source;
// try to rename dest back
if (rename(old,dest)) {
// was at least able to rename back
message("A new version of DrJava was downloaded. However, it could not be\n" +
"installed in the same place as the old DrJava.\n\n" +
"The new copy is now installed at:\n" +
source.getAbsolutePath() + "\n\n" +
"The old copy is still installed at:\n" +
dest.getAbsolutePath());
}
else {
// couldn't even rename back
message("A new version of DrJava was downloaded. However, it could not be\n" +
"installed in the same place as the old DrJava.\n\n" +
"The new copy is now installed at:\n" +
source.getAbsolutePath() + "\n\n" +
"The old copy is still installed at:\n" +
old.getAbsolutePath());
}
}
}
else {
// could not rename keep source as name
exec = source;
message("A new version of DrJava was downloaded. However, it could not be\n" +
"installed in the same place as the old DrJava.\n\n" +
"The new copy is now installed at:\n" +
source.getAbsolutePath() + "\n\n" +
"The old copy is still installed at:\n" +
dest.getAbsolutePath());
}
// check if Mac's open command exists
File macOpenFile = new File("/usr/bin/open");
LOG.log("Searching for " + macOpenFile);
if (!macOpenFile.exists()) {
String path = System.getenv("PATH");
for(String p: path.split(System.getProperty("path.separator"))) {
macOpenFile = new File(p, "tar");
LOG.log("Searching for " + macOpenFile);
if (macOpenFile.exists()) break;
}
}
if (macOpenFile.exists()) {
LOG.log("Restarting using ProcessBuilder...");
new ProcessBuilder()
.command(macOpenFile.getAbsolutePath(), exec.getAbsolutePath())
.redirectErrorStream(true)
.start();
System.exit(0);
}
else {
LOG.log("Restarting using JVMBuilder...");
exec = new File(exec,"Contents/Resources/Java/drjava.jar");
JVMBuilder.DEFAULT.classPath(exec).start(DrJava.class.getName(), "-new", "-delete-after-restart", args[2]);
LOG.log("Done with DrJavaRestart");
System.exit(0);
}
}
}
}
catch(Exception e) {
message("A new version of DrJava was downloaded. However, there was an error" +
"during installation:\n" + e.getMessage());
}
}
}