Skip to content

Commit ce9868c

Browse files
author
mgricken
committed
Added automatic update feature.
git-svn-id: file:///tmp/test-svn/trunk@4864 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent 6cb46de commit ce9868c

File tree

5 files changed

+587
-33
lines changed

5 files changed

+587
-33
lines changed

drjava/src/edu/rice/cs/drjava/DrJava.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ else if (arg.startsWith("-X") || arg.startsWith("-D")) {
287287

288288
else if (arg.equals("-new")) _forceNewInstance = true;
289289

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

drjava/src/edu/rice/cs/drjava/ui/MainFrame.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ public void actionPerformed(ActionEvent e) {
10681068

10691069
/** Quits DrJava. Optionally displays a prompt before quitting. */
10701070
private final Action _quitAction = new AbstractAction("Quit") {
1071-
public void actionPerformed(ActionEvent ae) { _quit(); }
1071+
public void actionPerformed(ActionEvent ae) { quit(); }
10721072
};
10731073

10741074

@@ -2794,7 +2794,7 @@ public void actionPerformed(ActionEvent ae) {
27942794
private final WindowListener _windowCloseListener = new WindowAdapter() {
27952795
public void windowActivated(WindowEvent ev) { }
27962796
public void windowClosed(WindowEvent ev) { }
2797-
public void windowClosing(WindowEvent ev) { _quit(); }
2797+
public void windowClosing(WindowEvent ev) { quit(); }
27982798
public void windowDeactivated(WindowEvent ev) { }
27992799
public void windowDeiconified(WindowEvent ev) {
28002800
try { _model.getActiveDocument().revertIfModifiedOnDisk(); }
@@ -5119,7 +5119,7 @@ private void _revertAll() {
51195119
}
51205120
*/
51215121

5122-
private void _quit() {
5122+
void quit() {
51235123
// AbstractGlobalModel._log.log("MainFrame.quit() called");
51245124
if (_promptBeforeQuit) {
51255125
String title = "Quit DrJava?";

0 commit comments

Comments
 (0)