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

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

setting up the flag file system for the uninstaller

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