source: release-kits/shared/uninstaller/Uninstaller.java@ 17456

Last change on this file since 17456 was 17456, checked in by oranfry, 16 years ago

created the Uninstall.sh so uninstall can be done on unix too

File size: 13.1 KB
Line 
1import java.util.ResourceBundle;
2import java.awt.*;
3import java.awt.event.*;
4import javax.swing.JFrame;
5import javax.swing.JPanel;
6import javax.swing.JCheckBox;
7import javax.swing.JLabel;
8import javax.swing.JButton;
9import javax.swing.BoxLayout;
10import javax.swing.JTextArea;
11import javax.swing.JScrollPane;
12import javax.swing.border.EmptyBorder;
13import javax.swing.JOptionPane;
14import javax.swing.Box;
15import javax.swing.JDialog;
16import java.io.File;
17import java.io.BufferedReader;
18import java.io.FileReader;
19import java.io.File;
20import java.util.regex.Pattern;
21import java.util.regex.Matcher;
22import java.util.ArrayList;
23
24public class Uninstaller {
25
26 public static int SCREEN_WIDTH = 600;
27 public static int SCREEN_HEIGHT = 450;
28
29 public static final ResourceBundle bundle = ResourceBundle.getBundle("Uninstaller");
30
31 public static final File gs2InstallProps = new File("etc/installation.properties");
32 public static final File gs3InstallProps = new File("installation.properties");
33
34 boolean keepCollections = true;
35 //boolean keepModifiedFiles = false;
36 boolean ignoreReadOnlys = false;
37
38 JFrame frame;
39 JCheckBox keepCollectionsCheckbox;
40 //JCheckBox keepModifiedFilesCheckbox;
41 JPanel progressPanel;
42 JPanel introPanel;
43 JTextArea log;
44 JButton uninstallButton;
45 JPanel initialToolbar;
46 JPanel finishToolbar;
47
48
49 public static void main( String[] args ) {
50 (new Uninstaller()).go();
51 }
52
53 public void go() {
54
55 frame = new JFrame();
56 frame.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
57 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
58 frame.setLocation(screenSize.width/2 - frame.getWidth()/2, screenSize.height/2 - frame.getHeight()/2);
59
60 //The panel to be displayed while the uninstall is happening
61 progressPanel = new JPanel(new BorderLayout());
62 log = new JTextArea();
63 JScrollPane logPane = new JScrollPane(log);
64 logPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
65 logPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
66 progressPanel.add( BorderLayout.NORTH, new JLabel("Progress") );
67 progressPanel.add( BorderLayout.CENTER, logPane );
68
69 //The panel to introduce and ask for options
70 introPanel = new JPanel(new BorderLayout());
71 frame.getContentPane().add( BorderLayout.NORTH, introPanel );
72
73 JPanel innerPanel = new JPanel();
74 innerPanel.setLayout( new BoxLayout(innerPanel,BoxLayout.Y_AXIS) );
75 innerPanel.setBorder( new EmptyBorder(10, 10, 5, 10) );
76 introPanel.add( BorderLayout.WEST, innerPanel );
77
78 //initial toolbar
79 initialToolbar = new JPanel();
80 JButton cancelButton = new JButton(bundle.getString("cancel"));
81 cancelButton.addActionListener( new CancelListener() );
82
83 uninstallButton = new JButton(bundle.getString("uninstall"));
84 uninstallButton.addActionListener( new StartUninstallListener() );
85
86 initialToolbar.add(cancelButton);
87 initialToolbar.add(uninstallButton);
88 frame.getContentPane().add( BorderLayout.SOUTH, initialToolbar );
89
90 //finish toolbar
91 finishToolbar = new JPanel();
92 JButton finishButton = new JButton(bundle.getString("finish"));
93 finishButton.addActionListener( new FinishListener() );
94 finishToolbar.add( finishButton );
95
96 String pwd = (new File(".")).getAbsolutePath();
97 if ( pwd.endsWith("/.") ) {
98 pwd = pwd.substring( 0, pwd.length()-2 );
99 }
100
101 JLabel l;
102
103 l = new JLabel(bundle.getString("will.uninstall.from"));
104 innerPanel.add( l );
105 innerPanel.add( Box.createRigidArea(new Dimension(5,5)) );
106
107 l = new JLabel(" " + pwd);
108 l.setFont( new Font( "Monospaced", Font.BOLD, 14 ) );
109 innerPanel.add( l );
110 innerPanel.add( Box.createRigidArea(new Dimension(5,20)) );
111
112 l = new JLabel(bundle.getString("uninstall.options"));
113 innerPanel.add( l );
114
115 keepCollectionsCheckbox = new JCheckBox(bundle.getString("keep.collections"));
116 keepCollectionsCheckbox.setSelected(true);
117 innerPanel.add( keepCollectionsCheckbox );
118
119 //keepModifiedFilesCheckbox = new JCheckBox("Keep Modified Files");
120 //innerPanel.add( keepModifiedFilesCheckbox );
121
122 frame.setTitle( bundle.getString("greenstone.uninstaller") );
123 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
124 frame.setVisible(true);
125
126 boolean ready = precheck();
127 if ( !ready ) {
128 System.exit(0);
129 }
130
131 }
132
133 class CancelListener implements ActionListener {
134 public void actionPerformed( ActionEvent e ) {
135 System.exit(0);
136 }
137 }
138
139 class FinishListener implements ActionListener {
140 public void actionPerformed( ActionEvent e ) {
141 System.exit(0);
142 }
143 }
144
145 class StartUninstallListener implements ActionListener {
146 public void actionPerformed( ActionEvent e ) {
147
148 //The dialog to ask "are you sure"
149 Object[] options = { bundle.getString("cancel"), bundle.getString("uninstall") };
150 int n = JOptionPane.showOptionDialog(
151 frame,
152 bundle.getString("are.you.sure"),
153 bundle.getString("confirmation"),
154 JOptionPane.YES_NO_CANCEL_OPTION,
155 JOptionPane.QUESTION_MESSAGE,
156 null,
157 options,
158 options[0]
159 );
160 if ( n == 0 ) {
161 return;
162 }
163
164 keepCollections = keepCollectionsCheckbox.isSelected();
165 //keepModifiedFiles = keepModifiedFilesCheckbox.isSelected();
166
167 //confirm delete of collections
168 if ( !keepCollections ) {
169 options[0] = bundle.getString("cancel");
170 options[1] = bundle.getString("continue");
171 n = JOptionPane.showOptionDialog(
172 frame,
173 bundle.getString("are.you.sure.collections"),
174 bundle.getString("confirmation"),
175 JOptionPane.YES_NO_CANCEL_OPTION,
176 JOptionPane.WARNING_MESSAGE,
177 null,
178 options,
179 options[0]
180 );
181 if ( n == 0 ) {
182 return;
183 }
184 }
185
186 //swap to the progress panel
187 introPanel.setVisible(false);
188 frame.getContentPane().remove(introPanel);
189 frame.getContentPane().add( BorderLayout.CENTER, progressPanel);
190 frame.setVisible(true);
191
192 //disable the uninstall button
193 uninstallButton.setEnabled( false );
194
195
196 //start the unstinall
197 doUninstall();
198 }
199 }
200
201 /**
202 * Do some checks
203 */
204 public boolean precheck() {
205
206 if ( !gs2InstallProps.exists() && !gs3InstallProps.exists() ) {
207 log.append( bundle.getString("error.couldnt.find.install.props") + "\n" );
208 JOptionPane.showMessageDialog(frame, bundle.getString("error.couldnt.find.install.props"), bundle.getString("error"), 0);
209 return false;
210 }
211 return true;
212
213 }
214
215 /**
216 * Does the uninstall
217 */
218 public void doUninstall() {
219
220 File startMenuPath = null;
221
222 //delete the start menu group if present
223
224 if ( gs2InstallProps.exists() ) {
225 String smp = null;
226 try {
227 smp = getPropertyValue( "startmenu.path", gs2InstallProps );
228 } catch ( Exception e ) {}
229 if ( smp != null ) {
230 startMenuPath = new File( smp );
231 }
232 } else if ( gs3InstallProps.exists() ) {
233 String smp = null;
234 try {
235 smp = getPropertyValue( "startmenu.path", gs3InstallProps );
236 } catch ( Exception e ) {}
237 if ( smp != null ) {
238 startMenuPath = new File( smp );
239 }
240 }
241
242 if ( startMenuPath == null ) {
243 log.append( bundle.getString("info.no.startmenu") + "\n" );
244 } else {
245 log.append( "StartMenu Path: " + startMenuPath.getAbsolutePath() + "\n" );
246 try {
247 recursiveDelete( startMenuPath, null );
248 } catch ( CancelledException ce ) {
249 log.append( bundle.getString("cancelled") + "\n" );
250 changeToFinishToolbar();
251 JOptionPane.showMessageDialog(frame, bundle.getString("cancelled"), bundle.getString("complete"), 1);
252 return;
253 }
254 }
255
256 //delete the files
257 try {
258 ArrayList exceptions = new ArrayList();
259
260 //never delete the things we are currently running
261 exceptions.add( new File("bin/search4j.exe") );
262 exceptions.add( new File("bin/search4j") );
263 exceptions.add( new File("packages/jre") );
264 exceptions.add( new File("uninst.jar") );
265 exceptions.add( new File("Uninstall.bat") );
266 exceptions.add( new File("Uninstall.sh") );
267
268 if ( keepCollections ) {
269 exceptions.add( new File("web/sites/localsite/collect") );
270 exceptions.add( new File("collect") );
271 }
272
273
274 File cd = null;
275 try {
276 cd = new File( new File(".").getCanonicalPath() );
277 } catch ( Exception e ) {
278 JOptionPane.showMessageDialog(frame, bundle.getString("failed.to.figure.cd"), bundle.getString("error") , 0);
279 System.exit(0);
280 }
281
282 File[] ex = new File[exceptions.size()];
283 for ( int i=0; i<exceptions.size(); i++ ) {
284 ex[i] = (File)exceptions.get(i);
285 }
286
287 recursiveDelete( cd , ex );
288 } catch ( CancelledException ce ) {
289 log.append( bundle.getString("cancelled") + "\n" );
290 JOptionPane.showMessageDialog(frame, bundle.getString("cancelled"), bundle.getString("complete"), 1);
291 changeToFinishToolbar();
292 return;
293 }
294
295 //create the flag file to indicate the uninstaller wants jre and uninst.jar to be deleted
296 try {
297 (new File("uninst.flag")).createNewFile();
298 } catch (Exception e) {
299 log.append( bundle.getString("couldnt-create-flagfile") + "\n" );
300 }
301
302 changeToFinishToolbar();
303 JOptionPane.showMessageDialog(frame, bundle.getString("finished"), bundle.getString("complete"), 1);
304 }
305
306 public String getPropertyValue( String propertyName, File file ) throws Exception {
307 String regex = "^" + propertyName.replaceAll("\\.","\\\\.") + "[:=]\\s*(.*)$";
308 Pattern wantedLine = Pattern.compile( regex );
309 BufferedReader in = null;
310 try {
311 in = new BufferedReader(new FileReader( file ));
312 } catch ( Exception e ) {
313 throw new Exception( "Error - couldn't open the properties file " + file );
314 }
315
316 String line, value = null;
317
318 try {
319 boolean found = false;
320 while ( (line = in.readLine()) != null && !found ) {
321
322 Matcher matcher = wantedLine.matcher( line );
323 if ( matcher.matches() ) {
324 //found the property
325 //System.err.println( "found the property" );
326 value = matcher.group(1);
327 value = value.replaceAll( "#.*", "" ).trim();
328 return value;
329 }
330
331 }
332
333 //close the input stream
334 //System.err.println( "close the input stream" );
335 in.close();
336
337 } catch ( Exception e ) {
338 throw new Exception( "Error - couldn't read from the properties file" );
339 }
340 return null;
341
342 }
343
344 public void recursiveDelete( File f, File[] exceptions ) throws CancelledException {
345
346 //log.append( "Processing: " + f.getAbsolutePath() + "\n" );
347
348 // Make sure the file or directory exists
349 if (!f.exists()) {
350 log.append( Strings.replaceAll( bundle.getString("warning.nonexistent"), "{file}", f.getAbsolutePath() ) + "\n" );
351 return;
352 }
353
354 // if this is an exception, return
355 if ( exceptions != null ) {
356 for ( int i=0; i<exceptions.length; i++ ) {
357 //System.out.println( "Comparing '" + f.getAbsolutePath() + "' with '" + exceptions[i].getAbsolutePath() + "'" );
358 try {
359 if ( f.equals( exceptions[i] ) || f.getCanonicalPath().equals(exceptions[i].getCanonicalPath()) ) {
360 log.append( Strings.replaceAll( bundle.getString("info.skipping"), "{file}", f.getAbsolutePath() ) + "\n" );
361 return;
362 }
363 } catch ( Exception e ) {
364 System.err.println("ERROR: Failed to resolve a path");
365 return;
366 }
367 }
368 }
369
370 //check existance
371 if ( !f.exists() ) {
372 log.append( Strings.replaceAll( bundle.getString("error.nonexistent"), "{file}", f.getAbsolutePath() ) + "\n" );
373 return;
374 }
375
376 //if it is a directory, recurse
377 if (f.isDirectory()) {
378 File[] files = f.listFiles();
379 if ( files != null && files.length > 0) {
380 for ( int i=0; i<files.length; i++ ) {
381 try {
382 recursiveDelete( files[i], exceptions );
383 } catch ( CancelledException ce ) {
384 throw new CancelledException();
385 }
386 }
387 }
388 }
389
390 //if this is now an empty directory, or a file, delete it
391 boolean doDelete = true;
392 if ( f.isDirectory() ) {
393 File[] files = f.listFiles();
394 doDelete = ( files == null || files.length == 0 );
395 }
396
397 if ( doDelete ) {
398
399 log.append( Strings.replaceAll( bundle.getString("deleting"), "{file}", f.getAbsolutePath() ) + "\n" );
400 while ( !f.delete() ) {
401 log.append( Strings.replaceAll( bundle.getString("warning.couldnt.delete"), "{file}", f.getAbsolutePath() ) + "\n" );
402
403 if ( ignoreReadOnlys ) {
404 return;
405 }
406
407 Object[] options = { bundle.getString("cancel"), bundle.getString("retry"), bundle.getString("skip"), bundle.getString("skip.all") };
408 int n = JOptionPane.showOptionDialog(
409 frame,
410 Strings.replaceAll( bundle.getString("warning.readonly"), "{file}", f.getAbsolutePath() ),
411 bundle.getString("readonly"),
412 JOptionPane.YES_NO_CANCEL_OPTION,
413 JOptionPane.QUESTION_MESSAGE,
414 null,
415 options,
416 options[2]
417 );
418
419 if ( n == 0 ) {
420 throw new CancelledException();
421 } else if ( n == 2 ) {
422 return;
423 } else if ( n == 3 ) {
424 ignoreReadOnlys = true;
425 return;
426 }
427
428 }
429 }
430
431 }
432
433 class CancelledException extends Exception {}
434
435 public void changeToFinishToolbar() {
436 initialToolbar.setVisible(false);
437 frame.getContentPane().remove(initialToolbar);
438 frame.getContentPane().add( BorderLayout.SOUTH, finishToolbar );
439 finishToolbar.setVisible(true);
440 }
441
442}
443
444class Strings {
445 static String replaceAll( String s, String nugget, String replacement ) {
446 StringBuffer string = new StringBuffer(s);
447 StringBuffer r = new StringBuffer();
448
449 int io = 0;
450 while ( (io=string.toString().indexOf(nugget)) != -1 ) {
451 r.append( string.toString().substring( 0, io ) );
452 r.append( replacement );
453 string.delete( 0, io + nugget.length() );
454 }
455 r.append( string.toString() );
456 return r.toString();
457 }
458}
459
Note: See TracBrowser for help on using the repository browser.