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

Last change on this file since 17792 was 17792, checked in by oranfry, 15 years ago

little fix to unistall sh

File size: 17.7 KB
Line 
1 import 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
24import java.awt.event.ActionEvent;
25import java.awt.event.ActionListener;
26import java.awt.event.MouseAdapter;
27import java.awt.event.MouseEvent;
28import java.io.FileNotFoundException;
29import java.io.FileWriter;
30import java.io.IOException;
31import javax.swing.JMenuItem;
32import javax.swing.JPopupMenu;
33import javax.swing.JTextArea;
34
35public class Uninstaller {
36
37 public static int SCREEN_WIDTH = 600;
38 public static int SCREEN_HEIGHT = 450;
39
40 public static final ResourceBundle bundle = ResourceBundle.getBundle("resources.LanguagePack");
41
42 public static final File gs2InstallProps = new File("etc/installation.properties");
43 public static final File gs3InstallProps = new File("installation.properties");
44
45 boolean keepCollections = true;
46 //boolean keepModifiedFiles = false;
47 boolean ignoreReadOnlys = false;
48
49 JFrame frame;
50 JCheckBox keepCollectionsCheckbox;
51 //JCheckBox keepModifiedFilesCheckbox;
52
53 //panels
54 JPanel progressPanel;
55 JPanel introPanel;
56
57 //toolbars
58 JPanel initialToolbar;
59 JPanel finishToolbar;
60
61
62 JScrollPane logPane;
63 JTextArea log;
64 JButton uninstallButton;
65
66
67 public static void main( String[] args ) {
68 (new Uninstaller()).go();
69 }
70
71 public void go() {
72
73 frame = new JFrame();
74 frame.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
75 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
76 frame.setLocation(screenSize.width/2 - frame.getWidth()/2, screenSize.height/2 - frame.getHeight()/2);
77
78 //The panel to introduce and ask for options
79 introPanel = new JPanel(new BorderLayout());
80 JPanel innerPanel = new JPanel();
81 innerPanel.setLayout( new BoxLayout(innerPanel,BoxLayout.Y_AXIS) );
82 innerPanel.setBorder( new EmptyBorder(10, 10, 5, 10) );
83 introPanel.add( BorderLayout.WEST, innerPanel );
84
85 //The panel to be displayed while the uninstall is happening
86 progressPanel = new JPanel(new BorderLayout());
87 log = new FollowingJTextArea();
88 log.setEditable(false);
89 logPane = new JScrollPane(log);
90 logPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
91 logPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
92 progressPanel.add( BorderLayout.NORTH, new JLabel("Progress") );
93 progressPanel.add( BorderLayout.CENTER, log );
94
95 //initial toolbar
96 initialToolbar = new JPanel();
97 uninstallButton = new JButton(bundle.getString("uninstaller.uninstall"));
98 uninstallButton.addActionListener( new StartUninstallListener() );
99 JButton cancelButton = new JButton(bundle.getString("uninstaller.cancel"));
100 cancelButton.addActionListener( new CancelListener() );
101 initialToolbar.add(uninstallButton);
102 initialToolbar.add(cancelButton);
103
104 //finish toolbar
105 finishToolbar = new JPanel();
106 JButton finishButton = new JButton(bundle.getString("uninstaller.finish"));
107 finishButton.addActionListener( new FinishListener() );
108 finishToolbar.add( finishButton );
109
110
111 String pwd = (new File(".")).getAbsolutePath();
112 if ( pwd.endsWith("/.") ) {
113 pwd = pwd.substring( 0, pwd.length()-2 );
114 }
115
116 JLabel l;
117
118 l = new JLabel(bundle.getString("uninstaller.will.uninstall.from"));
119 innerPanel.add( l );
120 innerPanel.add( Box.createRigidArea(new Dimension(5,5)) );
121
122 l = new JLabel(" " + pwd);
123 l.setFont( new Font( "Monospaced", Font.BOLD, 14 ) );
124 innerPanel.add( l );
125 innerPanel.add( Box.createRigidArea(new Dimension(5,20)) );
126
127 l = new JLabel(bundle.getString("uninstaller.uninstall.options"));
128 innerPanel.add( l );
129
130 keepCollectionsCheckbox = new JCheckBox(bundle.getString("uninstaller.keep.collections"));
131 keepCollectionsCheckbox.setSelected(true);
132 innerPanel.add( keepCollectionsCheckbox );
133
134 //keepModifiedFilesCheckbox = new JCheckBox("Keep Modified Files");
135 //innerPanel.add( keepModifiedFilesCheckbox );
136
137 frame.setTitle( bundle.getString("uninstaller.greenstone.uninstaller") );
138 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
139
140 //the initial screen
141 frame.getContentPane().add( BorderLayout.CENTER, introPanel );
142 frame.getContentPane().add( BorderLayout.SOUTH, initialToolbar );
143
144 frame.setVisible(true);
145
146 boolean ready = precheck();
147 if ( !ready ) {
148 System.exit(0);
149 }
150
151 }
152
153 class CancelListener implements ActionListener {
154 public void actionPerformed( ActionEvent e ) {
155 System.exit(0);
156 }
157 }
158
159 class FinishListener implements ActionListener {
160 public void actionPerformed( ActionEvent e ) {
161 System.exit(0);
162 }
163 }
164
165 class StartUninstallListener implements ActionListener {
166 public void actionPerformed( ActionEvent e ) {
167
168 //The dialog to ask "are you sure"
169 Object[] options = { bundle.getString("uninstaller.uninstall"), bundle.getString("uninstaller.cancel") };
170 int n = JOptionPane.showOptionDialog(
171 frame,
172 bundle.getString("uninstaller.are.you.sure"),
173 bundle.getString("uninstaller.confirmation"),
174 JOptionPane.YES_NO_CANCEL_OPTION,
175 JOptionPane.QUESTION_MESSAGE,
176 null,
177 options,
178 options[0]
179 );
180 if ( n == 1 ) {
181 return;
182 }
183
184 keepCollections = keepCollectionsCheckbox.isSelected();
185 //keepModifiedFiles = keepModifiedFilesCheckbox.isSelected();
186
187 //confirm delete of collections
188 if ( !keepCollections ) {
189 options[0] = bundle.getString("uninstaller.continue");
190 options[1] = bundle.getString("uninstaller.cancel");
191 n = JOptionPane.showOptionDialog(
192 frame,
193 bundle.getString("uninstaller.are.you.sure.collections"),
194 bundle.getString("uninstaller.confirmation"),
195 JOptionPane.YES_NO_CANCEL_OPTION,
196 JOptionPane.WARNING_MESSAGE,
197 null,
198 options,
199 options[0]
200 );
201 if ( n == 1 ) {
202 return;
203 }
204 }
205
206
207 introPanel.setVisible( false );
208 frame.getContentPane().remove(introPanel);
209 frame.getContentPane().add( BorderLayout.CENTER, progressPanel );
210 progressPanel.setVisible( true );
211
212 //start the unstinall
213 doUninstall();
214 }
215 }
216
217 /**
218 * Do some checks
219 */
220 public boolean precheck() {
221
222 if ( !gs2InstallProps.exists() && !gs3InstallProps.exists() ) {
223 log.append( bundle.getString("uninstaller.error.couldnt.find.install.props") + "\n" );
224 JOptionPane.showMessageDialog(frame, bundle.getString("uninstaller.error.couldnt.find.install.props"), bundle.getString("uninstaller.error"), 0);
225 return false;
226 }
227 return true;
228
229 }
230
231 /**
232 * Does the uninstall
233 */
234 public void doUninstall() {
235
236 File startMenuPath = null;
237
238 //delete the start menu group if present
239
240 if ( gs2InstallProps.exists() ) {
241 String smp = null;
242 try {
243 smp = getPropertyValue( "startmenu.path", gs2InstallProps );
244 } catch ( Exception e ) {}
245 if ( smp != null ) {
246 startMenuPath = new File( smp );
247 }
248 } else if ( gs3InstallProps.exists() ) {
249 String smp = null;
250 try {
251 smp = getPropertyValue( "startmenu.path", gs3InstallProps );
252 } catch ( Exception e ) {}
253 if ( smp != null ) {
254 startMenuPath = new File( smp );
255 }
256 }
257
258 if ( startMenuPath == null ) {
259 log.append( bundle.getString("uninstaller.info.no.startmenu") + "\n" );
260 log.repaint();
261 } else {
262 log.append( "StartMenu Path: " + startMenuPath.getAbsolutePath() + "\n" );
263 log.repaint();
264 try {
265 recursiveDelete( startMenuPath, null );
266 } catch ( CancelledException ce ) {
267 log.append( bundle.getString("uninstaller.cancelled") + "\n" );
268 changeToFinishToolbar();
269 JOptionPane.showMessageDialog(frame, bundle.getString("uninstaller.cancelled"), bundle.getString("uninstaller.complete"), 1);
270 return;
271 }
272 }
273
274 //delete the files
275 try {
276 ArrayList exceptions = new ArrayList();
277
278 //never delete the things we are currently running
279 exceptions.add( new File("bin/search4j.exe") );
280 exceptions.add( new File("bin/search4j") );
281
282 exceptions.add( new File("bin/windows/search4j.exe") );
283 exceptions.add( new File("bin/linux/search4j") );
284 exceptions.add( new File("bin/darwin/search4j") );
285
286 exceptions.add( new File("packages/jre") );
287 exceptions.add( new File("uninst.jar") );
288 exceptions.add( new File("Uninstall.bat") );
289 exceptions.add( new File("Uninstall.sh") );
290
291 if ( keepCollections ) {
292 exceptions.add( new File("web/sites/localsite/collect") );
293 exceptions.add( new File("collect") );
294 }
295
296
297 File cd = null;
298 try {
299 cd = new File( new File(".").getCanonicalPath() );
300 } catch ( Exception e ) {
301 JOptionPane.showMessageDialog(frame, bundle.getString("uninstaller.failed.to.figure.cd"), bundle.getString("uninstaller.error") , 0);
302 System.exit(0);
303 }
304
305 File[] ex = new File[exceptions.size()];
306 for ( int i=0; i<exceptions.size(); i++ ) {
307 ex[i] = (File)exceptions.get(i);
308 }
309
310 recursiveDelete( cd , ex );
311 } catch ( CancelledException ce ) {
312 log.append( bundle.getString("uninstaller.cancelled") + "\n" );
313 log.repaint();
314 JOptionPane.showMessageDialog(frame, bundle.getString("uninstaller.cancelled"), bundle.getString("uninstaller.complete"), 1);
315 changeToFinishToolbar();
316 return;
317 }
318
319 //create the flag file to indicate the uninstaller wants jre and uninst.jar to be deleted
320 try {
321 (new File("uninst.flag")).createNewFile();
322 } catch (Exception e) {
323 log.append( bundle.getString("uninstaller.couldnt-create-flagfile") + "\n" );
324 log.repaint();
325 }
326
327 changeToFinishToolbar();
328 JOptionPane.showMessageDialog(frame, bundle.getString("uninstaller.finished"), bundle.getString("uninstaller.complete"), 1);
329 }
330
331 public String getPropertyValue( String propertyName, File file ) throws Exception {
332 String regex = "^" + propertyName.replaceAll("\\.","\\\\.") + "[:=]\\s*(.*)$";
333 Pattern wantedLine = Pattern.compile( regex );
334 BufferedReader in = null;
335 try {
336 in = new BufferedReader(new FileReader( file ));
337 } catch ( Exception e ) {
338 throw new Exception( "Error - couldn't open the properties file " + file );
339 }
340
341 String line, value = null;
342
343 try {
344 boolean found = false;
345 while ( (line = in.readLine()) != null && !found ) {
346
347 Matcher matcher = wantedLine.matcher( line );
348 if ( matcher.matches() ) {
349 //found the property
350 //System.err.println( "found the property" );
351 value = matcher.group(1);
352 value = value.replaceAll( "#.*", "" ).trim();
353 return value;
354 }
355
356 }
357
358 //close the input stream
359 //System.err.println( "close the input stream" );
360 in.close();
361
362 } catch ( Exception e ) {
363 throw new Exception( "Error - couldn't read from the properties file" );
364 }
365 return null;
366
367 }
368
369 public void recursiveDelete( File f, File[] exceptions ) throws CancelledException {
370
371 //log.append( "Processing: " + f.getAbsolutePath() + "\n" );
372
373 // Make sure the file or directory exists
374 if (!f.exists()) {
375 log.append( Strings.replaceAll( bundle.getString("uninstaller.warning.nonexistent"), "{file}", f.getAbsolutePath() ) + "\n" );
376 log.repaint();
377 return;
378 }
379
380 // if this is an exception, return
381 if ( exceptions != null ) {
382 for ( int i=0; i<exceptions.length; i++ ) {
383 //System.out.println( "Comparing '" + f.getAbsolutePath() + "' with '" + exceptions[i].getAbsolutePath() + "'" );
384 try {
385 if ( f.equals( exceptions[i] ) || f.getCanonicalPath().equals(exceptions[i].getCanonicalPath()) ) {
386 log.append( Strings.replaceAll( bundle.getString("uninstaller.info.skipping"), "{file}", f.getAbsolutePath() ) + "\n" );
387 return;
388 }
389 } catch ( Exception e ) {
390 System.err.println("ERROR: Failed to resolve a path");
391 return;
392 }
393 }
394 }
395
396 //check existance
397 if ( !f.exists() ) {
398 log.append( Strings.replaceAll( bundle.getString("uninstaller.error.nonexistent"), "{file}", f.getAbsolutePath() ) + "\n" );
399 log.repaint();
400 return;
401 }
402
403 //if it is a directory, recurse
404 if (f.isDirectory()) {
405 File[] files = f.listFiles();
406 if ( files != null && files.length > 0) {
407 for ( int i=0; i<files.length; i++ ) {
408 try {
409 recursiveDelete( files[i], exceptions );
410 } catch ( CancelledException ce ) {
411 throw new CancelledException();
412 }
413 }
414 }
415 }
416
417 //if this is now an empty directory, or a file, delete it
418 boolean doDelete = true;
419 if ( f.isDirectory() ) {
420 File[] files = f.listFiles();
421 doDelete = ( files == null || files.length == 0 );
422 }
423
424 if ( doDelete ) {
425
426 Object[] options = null;
427 int n = 0;
428 log.append( Strings.replaceAll( bundle.getString("uninstaller.deleting"), "{file}", f.getAbsolutePath() ) + "\n" );
429 log.repaint();
430 try{ Thread.sleep( 50 ); } catch( Exception e ) {}
431/*
432 //disable the uninstall button
433
434 options = new Object[1];
435 options = new Object[1];
436 options[0] = "OK";
437 n = JOptionPane.showOptionDialog(
438 frame,
439 "repainting",
440 "repainting",
441 JOptionPane.OK_OPTION,
442 JOptionPane.INFORMATION_MESSAGE,
443 null,
444 options,
445 options[0]
446 );
447*/
448
449 while ( !f.delete() ) {
450 log.append( Strings.replaceAll( bundle.getString("uninstaller.warning.couldnt.delete"), "{file}", f.getAbsolutePath() ) + "\n" );
451 log.repaint();
452
453 if ( ignoreReadOnlys ) {
454 return;
455 }
456
457 options[0] = bundle.getString("uninstaller.retry");
458 options[1] = bundle.getString("uninstaller.skip");
459 options[2] = bundle.getString("uninstaller.skip.all");
460 options[3] = bundle.getString("uninstaller.cancel");
461 n = JOptionPane.showOptionDialog(
462 frame,
463 Strings.replaceAll( bundle.getString("uninstaller.warning.readonly"), "{file}", f.getAbsolutePath() ),
464 bundle.getString("uninstaller.readonly"),
465 JOptionPane.YES_NO_CANCEL_OPTION,
466 JOptionPane.QUESTION_MESSAGE,
467 null,
468 options,
469 options[2]
470 );
471
472 if ( n == 3 ) {
473 throw new CancelledException();
474 } else if ( n == 1 ) {
475 return;
476 } else if ( n == 2 ) {
477 ignoreReadOnlys = true;
478 return;
479 }
480
481 }
482 }
483
484 }
485
486 class CancelledException extends Exception {}
487
488 public void changeToFinishToolbar() {
489 initialToolbar.setVisible(false);
490 frame.getContentPane().remove(initialToolbar);
491 frame.getContentPane().add( BorderLayout.SOUTH, finishToolbar );
492 finishToolbar.setVisible(true);
493 }
494
495}
496
497class Strings {
498 static String replaceAll( String s, String nugget, String replacement ) {
499 StringBuffer string = new StringBuffer(s);
500 StringBuffer r = new StringBuffer();
501
502 int io = 0;
503 while ( (io=string.toString().indexOf(nugget)) != -1 ) {
504 r.append( string.toString().substring( 0, io ) );
505 r.append( replacement );
506 string.delete( 0, io + nugget.length() );
507 }
508 r.append( string.toString() );
509 return r.toString();
510 }
511}
512
513
514
515
516class FollowingJTextArea extends JTextArea{
517
518 private boolean follow = true;
519
520 public FollowingJTextArea() {
521 jInit();
522 }
523
524
525 private void jInit(){
526 final JPopupMenu popUp = getPopupMenu();
527 this.add(popUp);
528 this.addMouseListener(new MouseAdapter(){
529 public void mouseClicked(MouseEvent e) {
530 if (e.getButton() == e.BUTTON3) {
531 popUp.show(FollowingJTextArea.this,e.getX(),e.getY());
532 }
533 }
534 });
535 }
536
537 public boolean isFollow() {
538 return follow;
539 }
540 public void setFollow(boolean follow) {
541 this.follow = follow;
542 }
543
544 private void scrollToEnd(){
545 setCaretPosition(getDocument().getLength());
546 }
547 private void toggleFollow(){
548 setFollow(!isFollow());
549 }
550
551 /**
552 * Appends the given text to the end of the document.
553 *
554 * @param str the text to insert
555 * @todo Implement this javax.swing.JTextArea method
556 */
557 public void append(String str) {
558 super.append(str);
559 if(follow)scrollToEnd();
560 }
561 private JPopupMenu getPopupMenu() {
562 JPopupMenu contextMenu = new JPopupMenu("Options");
563 JMenuItem saveMenu = new JMenuItem("Save Text");
564/*
565 saveMenu.addActionListener(new ActionListener() {
566 public void actionPerformed(ActionEvent e) {
567 SelectFileAction action = new SelectFileAction("Save Output", null, null);
568 try {
569 action.actionPerformed(new ActionEvent(this, 0, "Save Output"));
570 if (action.selectedFile != null) {
571 FileWriter fos = new FileWriter(action.selectedFile);
572 fos.write(getText());
573 fos.close();
574 }
575
576 }
577 catch (FileNotFoundException ex) {
578 System.err.println("FileNotFoundException");
579 }
580 catch (IOException ex) {
581 System.err.println("IOException");
582 }
583 }
584 });
585 contextMenu.add(saveMenu);
586*/
587
588 JMenuItem toggleFollowMenu = new JMenuItem("Toggle Follow");
589 toggleFollowMenu.addActionListener(new ActionListener() {
590 public void actionPerformed(ActionEvent e) {
591 toggleFollow();
592 }
593 });
594 contextMenu.add(toggleFollowMenu);
595
596 JMenuItem jumpToEndMenu = new JMenuItem("Jump To End");
597 jumpToEndMenu.addActionListener(new ActionListener() {
598 public void actionPerformed(ActionEvent e) {
599 setCaretPosition(getDocument().getLength());
600 }
601 });
602 contextMenu.add(toggleFollowMenu);
603
604 JMenuItem clearTextMenu = new JMenuItem("Clear Text");
605 clearTextMenu.addActionListener(new ActionListener() {
606 public void actionPerformed(ActionEvent e) {
607 setText("");
608 }
609 });
610 contextMenu.add(clearTextMenu);
611 return contextMenu;
612 }
613}
Note: See TracBrowser for help on using the repository browser.