root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / com / izforge / izpack / installer / InstallerFrame.java @ 15280
History | View | Annotate | Download (30.5 KB)
1 | 15280 | rgaitan | /*
|
---|---|---|---|
2 | * $Id: InstallerFrame.java,v 1.1 2006/06/14 07:29:07 cesar Exp $
|
||
3 | * IzPack
|
||
4 | * Copyright (C) 2001-2004 Julien Ponge
|
||
5 | *
|
||
6 | * File : InstallerFrame.java
|
||
7 | * Description : The Installer frame class.
|
||
8 | * Author's email : julien@izforge.com
|
||
9 | * Author's Website : http://www.izforge.com
|
||
10 | *
|
||
11 | * Portions are Copyright (C) 2002 Jan Blok (jblok@profdata.nl - PDM - www.profdata.nl)
|
||
12 | *
|
||
13 | * This program is free software; you can redistribute it and/or
|
||
14 | * modify it under the terms of the GNU General Public License
|
||
15 | * as published by the Free Software Foundation; either version 2
|
||
16 | * of the License, or any later version.
|
||
17 | *
|
||
18 | * This program is distributed in the hope that it will be useful,
|
||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
21 | * GNU General Public License for more details.
|
||
22 | *
|
||
23 | * You should have received a copy of the GNU General Public License
|
||
24 | * along with this program; if not, write to the Free Software
|
||
25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
26 | */
|
||
27 | package com.izforge.izpack.installer; |
||
28 | |||
29 | import java.awt.BorderLayout; |
||
30 | import java.awt.Component; |
||
31 | import java.awt.Cursor; |
||
32 | import java.awt.Dimension; |
||
33 | import java.awt.GridBagConstraints; |
||
34 | import java.awt.GridLayout; |
||
35 | import java.awt.Toolkit; |
||
36 | import java.awt.Window; |
||
37 | import java.awt.event.ActionEvent; |
||
38 | import java.awt.event.ActionListener; |
||
39 | import java.awt.event.FocusAdapter; |
||
40 | import java.awt.event.KeyAdapter; |
||
41 | import java.awt.event.MouseAdapter; |
||
42 | import java.awt.event.MouseMotionAdapter; |
||
43 | import java.awt.event.WindowAdapter; |
||
44 | import java.awt.event.WindowEvent; |
||
45 | import java.io.BufferedWriter; |
||
46 | import java.io.ByteArrayOutputStream; |
||
47 | import java.io.File; |
||
48 | import java.io.InputStream; |
||
49 | import java.io.ObjectOutputStream; |
||
50 | import java.io.OutputStream; |
||
51 | import java.io.OutputStreamWriter; |
||
52 | import java.lang.reflect.Constructor; |
||
53 | import java.net.URL; |
||
54 | import java.util.ArrayList; |
||
55 | import java.util.HashSet; |
||
56 | import java.util.Iterator; |
||
57 | import java.util.List; |
||
58 | import java.util.Map; |
||
59 | import java.util.Vector; |
||
60 | import java.util.zip.ZipEntry; |
||
61 | import java.util.zip.ZipException; |
||
62 | import java.util.zip.ZipOutputStream; |
||
63 | |||
64 | import javax.swing.BorderFactory; |
||
65 | import javax.swing.Box; |
||
66 | import javax.swing.BoxLayout; |
||
67 | import javax.swing.ImageIcon; |
||
68 | import javax.swing.JButton; |
||
69 | import javax.swing.JFrame; |
||
70 | import javax.swing.JLabel; |
||
71 | import javax.swing.JOptionPane; |
||
72 | import javax.swing.JPanel; |
||
73 | import javax.swing.UIManager; |
||
74 | import javax.swing.text.JTextComponent; |
||
75 | |||
76 | import net.n3.nanoxml.NonValidator; |
||
77 | import net.n3.nanoxml.StdXMLBuilder; |
||
78 | import net.n3.nanoxml.StdXMLParser; |
||
79 | import net.n3.nanoxml.StdXMLReader; |
||
80 | import net.n3.nanoxml.XMLElement; |
||
81 | import net.n3.nanoxml.XMLWriter; |
||
82 | |||
83 | import com.izforge.izpack.CustomData; |
||
84 | import com.izforge.izpack.ExecutableFile; |
||
85 | import com.izforge.izpack.LocaleDatabase; |
||
86 | import com.izforge.izpack.Panel; |
||
87 | import com.izforge.izpack.gui.ButtonFactory; |
||
88 | import com.izforge.izpack.gui.EtchedLineBorder; |
||
89 | import com.izforge.izpack.gui.IconsDatabase; |
||
90 | import com.izforge.izpack.util.AbstractUIProgressHandler; |
||
91 | import com.izforge.izpack.util.Debug; |
||
92 | import com.izforge.izpack.util.Housekeeper; |
||
93 | import com.izforge.izpack.util.OsConstraint; |
||
94 | import com.izforge.izpack.installer.ResourceNotFoundException; |
||
95 | /**
|
||
96 | * The IzPack installer frame.
|
||
97 | *
|
||
98 | * @author Julien Ponge
|
||
99 | * created October 27, 2002
|
||
100 | */
|
||
101 | public class InstallerFrame extends JFrame |
||
102 | { |
||
103 | /** VM version to use version dependent methods calls */
|
||
104 | private static final float JAVA_SPECIFICATION_VERSION = |
||
105 | Float.parseFloat(System.getProperty("java.specification.version")); |
||
106 | /** The language pack. */
|
||
107 | public LocaleDatabase langpack;
|
||
108 | |||
109 | /** The installation data. */
|
||
110 | protected InstallData installdata;
|
||
111 | |||
112 | /** The icons database. */
|
||
113 | public IconsDatabase icons;
|
||
114 | |||
115 | /** The panels container. */
|
||
116 | protected JPanel panelsContainer; |
||
117 | |||
118 | /** The frame content pane. */
|
||
119 | protected JPanel contentPane; |
||
120 | |||
121 | /** The previous button. */
|
||
122 | protected JButton prevButton; |
||
123 | |||
124 | /** The next button. */
|
||
125 | protected JButton nextButton; |
||
126 | |||
127 | /** The quit button. */
|
||
128 | protected JButton quitButton; |
||
129 | |||
130 | /** The 'made with izpack' label, please KEEP IT THERE. */
|
||
131 | private JLabel madewithLabel; |
||
132 | |||
133 | /** Image */
|
||
134 | private JLabel iconLabel; |
||
135 | |||
136 | |||
137 | /**
|
||
138 | * The constructor (normal mode).
|
||
139 | *
|
||
140 | * @param title The window title.
|
||
141 | * @param installdata The installation data.
|
||
142 | * @exception Exception Description of the Exception
|
||
143 | */
|
||
144 | public InstallerFrame(String title, InstallData installdata) throws Exception |
||
145 | { |
||
146 | super(title);
|
||
147 | this.installdata = installdata;
|
||
148 | this.langpack = installdata.langpack;
|
||
149 | |||
150 | // Sets the window events handler
|
||
151 | addWindowListener(new WindowHandler());
|
||
152 | |||
153 | // Builds the GUI
|
||
154 | loadIcons(); |
||
155 | loadPanels(); |
||
156 | buildGUI(); |
||
157 | |||
158 | // We show the frame
|
||
159 | showFrame(); |
||
160 | switchPanel(0);
|
||
161 | } |
||
162 | |||
163 | /**
|
||
164 | * Loads the panels.
|
||
165 | *
|
||
166 | * @exception Exception Description of the Exception
|
||
167 | */
|
||
168 | private void loadPanels() throws Exception |
||
169 | { |
||
170 | // Initialisation
|
||
171 | java.util.List panelsOrder = installdata.panelsOrder; |
||
172 | int i;
|
||
173 | int size = panelsOrder.size();
|
||
174 | String className;
|
||
175 | Class objectClass;
|
||
176 | Constructor constructor;
|
||
177 | Object object;
|
||
178 | IzPanel panel; |
||
179 | Class[] paramsClasses = new Class[2]; |
||
180 | paramsClasses[0] =
|
||
181 | Class.forName("com.izforge.izpack.installer.InstallerFrame"); |
||
182 | paramsClasses[1] =
|
||
183 | Class.forName("com.izforge.izpack.installer.InstallData"); |
||
184 | Object[] params = { this, installdata }; |
||
185 | |||
186 | // We load each of them
|
||
187 | for (i = 0; i < size; i++) |
||
188 | { |
||
189 | // We add the panel
|
||
190 | Panel p = (Panel) panelsOrder.get(i); |
||
191 | |||
192 | if (!OsConstraint.oneMatchesCurrentSystem(p.osConstraints))
|
||
193 | continue;
|
||
194 | className = (String) p.className;
|
||
195 | String praefix = "com.izforge.izpack.panels."; |
||
196 | if( className.compareTo(".") > -1 ) |
||
197 | // Full qualified class name
|
||
198 | praefix = "";
|
||
199 | objectClass = Class.forName(praefix + className);
|
||
200 | constructor = objectClass.getDeclaredConstructor(paramsClasses); |
||
201 | object = constructor.newInstance(params); |
||
202 | panel = (IzPanel) object; |
||
203 | installdata.panels.add(panel); |
||
204 | |||
205 | // We add the XML data panel root
|
||
206 | XMLElement panelRoot = new XMLElement(className);
|
||
207 | installdata.xmlData.addChild(panelRoot); |
||
208 | } |
||
209 | } |
||
210 | |||
211 | /**
|
||
212 | * Loads the icons.
|
||
213 | *
|
||
214 | * @exception Exception Description of the Exception
|
||
215 | */
|
||
216 | private void loadIcons() throws Exception |
||
217 | { |
||
218 | // Initialisations
|
||
219 | icons = new IconsDatabase();
|
||
220 | URL url;
|
||
221 | ImageIcon img;
|
||
222 | XMLElement icon; |
||
223 | InputStream inXML =
|
||
224 | InstallerFrame.class.getResourceAsStream("/com/izforge/izpack/installer/icons.xml");
|
||
225 | |||
226 | // Initialises the parser
|
||
227 | StdXMLParser parser = new StdXMLParser();
|
||
228 | parser.setBuilder(new StdXMLBuilder());
|
||
229 | parser.setReader(new StdXMLReader(inXML));
|
||
230 | parser.setValidator(new NonValidator());
|
||
231 | |||
232 | // We get the data
|
||
233 | XMLElement data = (XMLElement) parser.parse(); |
||
234 | |||
235 | // We load the icons
|
||
236 | Vector children = data.getChildrenNamed("icon"); |
||
237 | int size = children.size();
|
||
238 | for (int i = 0; i < size; i++) |
||
239 | { |
||
240 | icon = (XMLElement) children.get(i); |
||
241 | url = InstallerFrame.class.getResource(icon.getAttribute("res"));
|
||
242 | img = new ImageIcon(url); |
||
243 | icons.put(icon.getAttribute("id"), img);
|
||
244 | } |
||
245 | |||
246 | // We load the Swing-specific icons
|
||
247 | children = data.getChildrenNamed("sysicon");
|
||
248 | size = children.size(); |
||
249 | for (int i = 0; i < size; i++) |
||
250 | { |
||
251 | icon = (XMLElement) children.get(i); |
||
252 | url = InstallerFrame.class.getResource(icon.getAttribute("res"));
|
||
253 | img = new ImageIcon(url); |
||
254 | UIManager.put(icon.getAttribute("id"), img); |
||
255 | } |
||
256 | } |
||
257 | |||
258 | /** Builds the GUI. */
|
||
259 | private void buildGUI() |
||
260 | { |
||
261 | // Sets the frame icon
|
||
262 | setIconImage(icons.getImageIcon("JFrameIcon").getImage());
|
||
263 | |||
264 | // Prepares the glass pane to block the gui interaction when needed
|
||
265 | JPanel glassPane = (JPanel) getGlassPane(); |
||
266 | glassPane.addMouseListener(new MouseAdapter() |
||
267 | { |
||
268 | }); |
||
269 | glassPane.addMouseMotionListener(new MouseMotionAdapter() |
||
270 | { |
||
271 | }); |
||
272 | glassPane.addKeyListener(new KeyAdapter() |
||
273 | { |
||
274 | }); |
||
275 | glassPane.addFocusListener(new FocusAdapter() |
||
276 | { |
||
277 | }); |
||
278 | |||
279 | // We set the layout & prepare the constraint object
|
||
280 | contentPane = (JPanel) getContentPane();
|
||
281 | contentPane.setLayout(new BorderLayout()); //layout); |
||
282 | |||
283 | // We add the panels container
|
||
284 | panelsContainer = new JPanel(); |
||
285 | panelsContainer.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); |
||
286 | panelsContainer.setLayout(new GridLayout(1, 1)); |
||
287 | contentPane.add(panelsContainer, BorderLayout.CENTER);
|
||
288 | |||
289 | // We put the first panel
|
||
290 | installdata.curPanelNumber = 0;
|
||
291 | IzPanel panel_0 = (IzPanel) installdata.panels.get(0);
|
||
292 | panelsContainer.add(panel_0); |
||
293 | |||
294 | // We add the navigation buttons & labels
|
||
295 | |||
296 | NavigationHandler navHandler = new NavigationHandler();
|
||
297 | |||
298 | JPanel navPanel = new JPanel(); |
||
299 | navPanel.setLayout(new BoxLayout(navPanel, BoxLayout.X_AXIS)); |
||
300 | navPanel.setBorder( |
||
301 | BorderFactory.createCompoundBorder(
|
||
302 | BorderFactory.createEmptyBorder(8, 8, 8, 8), |
||
303 | BorderFactory.createTitledBorder(
|
||
304 | new EtchedLineBorder(),
|
||
305 | langpack.getString("installer.madewith") + " "))); |
||
306 | navPanel.add(Box.createHorizontalGlue());
|
||
307 | |||
308 | prevButton = |
||
309 | ButtonFactory.createButton( |
||
310 | langpack.getString("installer.prev"),
|
||
311 | icons.getImageIcon("stepback"),
|
||
312 | installdata.buttonsHColor); |
||
313 | navPanel.add(prevButton); |
||
314 | prevButton.addActionListener(navHandler); |
||
315 | |||
316 | navPanel.add(Box.createRigidArea(new Dimension(5, 0))); |
||
317 | |||
318 | nextButton = |
||
319 | ButtonFactory.createButton( |
||
320 | langpack.getString("installer.next"),
|
||
321 | icons.getImageIcon("stepforward"),
|
||
322 | installdata.buttonsHColor); |
||
323 | navPanel.add(nextButton); |
||
324 | nextButton.addActionListener(navHandler); |
||
325 | |||
326 | navPanel.add(Box.createRigidArea(new Dimension(5, 0))); |
||
327 | |||
328 | quitButton = |
||
329 | ButtonFactory.createButton( |
||
330 | langpack.getString("installer.quit"),
|
||
331 | icons.getImageIcon("stop"),
|
||
332 | installdata.buttonsHColor); |
||
333 | navPanel.add(quitButton); |
||
334 | quitButton.addActionListener(navHandler); |
||
335 | contentPane.add(navPanel, BorderLayout.SOUTH);
|
||
336 | |||
337 | try
|
||
338 | { |
||
339 | ResourceManager rm = ResourceManager.getInstance(); |
||
340 | ImageIcon icon;
|
||
341 | try
|
||
342 | { |
||
343 | icon = rm.getImageIconResource("Installer.image");
|
||
344 | } |
||
345 | catch (Exception e) // This is not that clean ... |
||
346 | { |
||
347 | icon = rm.getImageIconResource("Installer.image.0");
|
||
348 | } |
||
349 | if (icon != null) |
||
350 | { |
||
351 | JPanel imgPanel = new JPanel(); |
||
352 | imgPanel.setLayout(new BorderLayout()); |
||
353 | imgPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0)); |
||
354 | iconLabel = new JLabel(icon); |
||
355 | iconLabel.setBorder(BorderFactory.createLoweredBevelBorder());
|
||
356 | imgPanel.add(iconLabel, BorderLayout.NORTH);
|
||
357 | contentPane.add(imgPanel, BorderLayout.WEST);
|
||
358 | } |
||
359 | } catch (Exception e) |
||
360 | { |
||
361 | //ignore
|
||
362 | } |
||
363 | |||
364 | loadImage(0);
|
||
365 | getRootPane().setDefaultButton(nextButton); |
||
366 | } |
||
367 | |||
368 | private void loadImage(int panelNo) { |
||
369 | try
|
||
370 | { |
||
371 | ResourceManager rm = ResourceManager.getInstance(); |
||
372 | ImageIcon icon = rm.getImageIconResource("Installer.image." + panelNo); |
||
373 | if (icon != null) |
||
374 | { |
||
375 | iconLabel.setVisible(false);
|
||
376 | iconLabel.setIcon(icon); |
||
377 | iconLabel.setVisible(true);
|
||
378 | } |
||
379 | } catch (Exception e) |
||
380 | { |
||
381 | //ignore
|
||
382 | } |
||
383 | } |
||
384 | |||
385 | /** Shows the frame. */
|
||
386 | private void showFrame() |
||
387 | { |
||
388 | pack(); |
||
389 | setSize(installdata.guiPrefs.width, installdata.guiPrefs.height); |
||
390 | setResizable(installdata.guiPrefs.resizable); |
||
391 | centerFrame(this);
|
||
392 | setVisible(true);
|
||
393 | } |
||
394 | |||
395 | private boolean isBack = false; |
||
396 | /**
|
||
397 | * Switches the current panel.
|
||
398 | *
|
||
399 | * @param last Description of the Parameter
|
||
400 | */
|
||
401 | protected void switchPanel(int last) |
||
402 | { |
||
403 | try
|
||
404 | { |
||
405 | if (installdata.curPanelNumber < last)
|
||
406 | { |
||
407 | isBack = true;
|
||
408 | } |
||
409 | panelsContainer.setVisible(false);
|
||
410 | IzPanel panel = (IzPanel)installdata.panels.get(installdata.curPanelNumber); |
||
411 | IzPanel l_panel = (IzPanel)installdata.panels.get(last); |
||
412 | l_panel.makeXMLData(installdata.xmlData.getChildAtIndex(last)); |
||
413 | |||
414 | if (installdata.curPanelNumber == 0) |
||
415 | { |
||
416 | prevButton.setVisible(false);
|
||
417 | lockPrevButton(); |
||
418 | unlockNextButton(); // if we push the button back at the license panel
|
||
419 | } |
||
420 | else if (installdata.curPanelNumber == installdata.panels.size() - 1) |
||
421 | { |
||
422 | prevButton.setVisible(false);
|
||
423 | nextButton.setVisible(false);
|
||
424 | lockNextButton(); |
||
425 | |||
426 | // Set the default button to the only visible button.
|
||
427 | getRootPane().setDefaultButton(quitButton); |
||
428 | } |
||
429 | else
|
||
430 | { |
||
431 | prevButton.setVisible(true);
|
||
432 | nextButton.setVisible(true);
|
||
433 | unlockPrevButton(); |
||
434 | unlockNextButton(); |
||
435 | } |
||
436 | |||
437 | // Change panels container to the current one.
|
||
438 | panelsContainer.remove(l_panel); |
||
439 | l_panel.panelDeactivate(); |
||
440 | panelsContainer.add(panel); |
||
441 | |||
442 | if(panel.getInitialFocus() != null) |
||
443 | { // Initial focus hint should be performed after current panel
|
||
444 | // was added to the panels container, else the focus hint will
|
||
445 | // be ignored.
|
||
446 | // Give a hint for the initial focus to the system.
|
||
447 | Component inFoc = panel.getInitialFocus();
|
||
448 | if( JAVA_SPECIFICATION_VERSION < 1.35) |
||
449 | { |
||
450 | inFoc.requestFocus(); |
||
451 | } |
||
452 | else
|
||
453 | { |
||
454 | inFoc.requestFocusInWindow(); |
||
455 | } |
||
456 | |||
457 | /* On editable text components position the caret to the end
|
||
458 | of the cust existent text. */
|
||
459 | if( inFoc instanceof JTextComponent ) |
||
460 | { |
||
461 | JTextComponent inText = (JTextComponent) inFoc; |
||
462 | if( inText.isEditable() && inText.getDocument() != null) |
||
463 | { |
||
464 | inText.setCaretPosition( inText.getDocument().getLength()); |
||
465 | } |
||
466 | } |
||
467 | } |
||
468 | panel.panelActivate(); |
||
469 | panelsContainer.setVisible(true);
|
||
470 | loadImage(installdata.curPanelNumber); |
||
471 | isBack = false;
|
||
472 | } |
||
473 | catch (Exception err) |
||
474 | { |
||
475 | err.printStackTrace(); |
||
476 | } |
||
477 | } |
||
478 | |||
479 | /** Writes the uninstalldata. */
|
||
480 | private void writeUninstallData() |
||
481 | { |
||
482 | try
|
||
483 | { |
||
484 | // We get the data
|
||
485 | UninstallData udata = UninstallData.getInstance(); |
||
486 | List files = udata.getFilesList();
|
||
487 | ZipOutputStream outJar = installdata.uninstallOutJar;
|
||
488 | |||
489 | if (outJar == null) |
||
490 | return;
|
||
491 | |||
492 | // We write the files log
|
||
493 | outJar.putNextEntry(new ZipEntry("install.log")); |
||
494 | BufferedWriter logWriter =
|
||
495 | new BufferedWriter(new OutputStreamWriter(outJar)); |
||
496 | logWriter.write(installdata.getInstallPath()); |
||
497 | logWriter.newLine(); |
||
498 | Iterator iter = files.iterator();
|
||
499 | while (iter.hasNext())
|
||
500 | { |
||
501 | logWriter.write((String) iter.next());
|
||
502 | if (iter.hasNext())
|
||
503 | logWriter.newLine(); |
||
504 | } |
||
505 | logWriter.flush(); |
||
506 | outJar.closeEntry(); |
||
507 | |||
508 | // We write the uninstaller jar file log
|
||
509 | outJar.putNextEntry(new ZipEntry("jarlocation.log")); |
||
510 | logWriter = new BufferedWriter(new OutputStreamWriter(outJar)); |
||
511 | logWriter.write(udata.getUninstallerJarFilename()); |
||
512 | logWriter.newLine(); |
||
513 | logWriter.write(udata.getUninstallerPath()); |
||
514 | logWriter.flush(); |
||
515 | outJar.closeEntry(); |
||
516 | |||
517 | // Write out executables to execute on uninstall
|
||
518 | outJar.putNextEntry(new ZipEntry("executables")); |
||
519 | ObjectOutputStream execStream = new ObjectOutputStream(outJar); |
||
520 | iter = udata.getExecutablesList().iterator(); |
||
521 | execStream.writeInt(udata.getExecutablesList().size()); |
||
522 | while (iter.hasNext())
|
||
523 | { |
||
524 | ExecutableFile file = (ExecutableFile) iter.next(); |
||
525 | execStream.writeObject(file); |
||
526 | } |
||
527 | execStream.flush(); |
||
528 | outJar.closeEntry(); |
||
529 | |||
530 | // Write out additional uninstall data
|
||
531 | // Do not "kill" the installation if there is a problem
|
||
532 | // with custom uninstall data. Therefore log it to Debug,
|
||
533 | // but do not throw.
|
||
534 | Map additionalData = udata.getAdditionalData();
|
||
535 | if( additionalData != null && ! additionalData.isEmpty()) |
||
536 | { |
||
537 | Iterator keys = additionalData.keySet().iterator();
|
||
538 | HashSet exist = new HashSet(); |
||
539 | while( keys != null && keys.hasNext()) |
||
540 | { |
||
541 | String key = (String) keys.next(); |
||
542 | Object contents = additionalData.get(key);
|
||
543 | if( key.equals("__uninstallLibs__")) |
||
544 | { |
||
545 | Iterator nativeLibIter = ((List) contents).iterator(); |
||
546 | while( nativeLibIter != null && nativeLibIter.hasNext() ) |
||
547 | { |
||
548 | String nativeLibName = (String) ((List) nativeLibIter.next()).get(0); |
||
549 | byte[] buffer = new byte[5120]; |
||
550 | long bytesCopied = 0; |
||
551 | int bytesInBuffer;
|
||
552 | outJar.putNextEntry(new ZipEntry( "native/" + nativeLibName)); |
||
553 | InputStream in = getClass().getResourceAsStream("/native/" + nativeLibName); |
||
554 | while ((bytesInBuffer = in.read(buffer)) != -1) |
||
555 | { |
||
556 | outJar.write(buffer, 0, bytesInBuffer);
|
||
557 | bytesCopied += bytesInBuffer; |
||
558 | } |
||
559 | outJar.closeEntry(); |
||
560 | } |
||
561 | } |
||
562 | else if( key.equals("uninstallerListeners") || |
||
563 | key.equals("uninstallerJars"))
|
||
564 | { // It is a ArrayList of ArrayLists which contains the full
|
||
565 | // package paths of all needed class files.
|
||
566 | // First we create a new ArrayList which contains only
|
||
567 | // the full paths for the uninstall listener self; thats
|
||
568 | // the first entry of each sub ArrayList.
|
||
569 | ArrayList subContents = new ArrayList(); |
||
570 | |||
571 | // Secound put the class into uninstaller.jar
|
||
572 | Iterator listenerIter = ((List) contents).iterator(); |
||
573 | while( listenerIter.hasNext() )
|
||
574 | { |
||
575 | byte[] buffer = new byte[5120]; |
||
576 | long bytesCopied = 0; |
||
577 | int bytesInBuffer;
|
||
578 | CustomData customData = (CustomData) listenerIter.next(); |
||
579 | // First element of the list contains the listener class path;
|
||
580 | // remind it for later.
|
||
581 | if(customData.listenerName != null ) |
||
582 | subContents.add(customData.listenerName); |
||
583 | Iterator liClaIter = customData.contents.iterator();
|
||
584 | while( liClaIter.hasNext() )
|
||
585 | { |
||
586 | String contentPath = (String) liClaIter.next(); |
||
587 | if( exist.contains(contentPath ))
|
||
588 | continue;
|
||
589 | exist.add(contentPath); |
||
590 | try
|
||
591 | { |
||
592 | outJar.putNextEntry(new ZipEntry( contentPath)); |
||
593 | } |
||
594 | catch(ZipException ze ) |
||
595 | { // Ignore, or ignore not ?? May be it is a exception because
|
||
596 | // a doubled entry was tried, then we should ignore ...
|
||
597 | Debug.trace("ZipException in writing custom data: " + ze.getMessage() );
|
||
598 | continue;
|
||
599 | } |
||
600 | InputStream in = getClass().getResourceAsStream("/" + contentPath); |
||
601 | if( in != null ) |
||
602 | { |
||
603 | while ((bytesInBuffer = in.read(buffer)) != -1) |
||
604 | { |
||
605 | outJar.write(buffer, 0, bytesInBuffer);
|
||
606 | bytesCopied += bytesInBuffer; |
||
607 | } |
||
608 | } |
||
609 | else
|
||
610 | Debug.trace("custom data not found: " + contentPath );
|
||
611 | outJar.closeEntry(); |
||
612 | |||
613 | } |
||
614 | } |
||
615 | // Third we write the list into the
|
||
616 | // uninstaller.jar
|
||
617 | outJar.putNextEntry(new ZipEntry(key)); |
||
618 | ObjectOutputStream objOut = new ObjectOutputStream(outJar); |
||
619 | objOut.writeObject(subContents); |
||
620 | objOut.flush(); |
||
621 | outJar.closeEntry(); |
||
622 | |||
623 | } |
||
624 | else
|
||
625 | { |
||
626 | outJar.putNextEntry(new ZipEntry(key)); |
||
627 | if( contents instanceof ByteArrayOutputStream ) |
||
628 | { |
||
629 | ((ByteArrayOutputStream) contents).writeTo(outJar);
|
||
630 | } |
||
631 | else
|
||
632 | { |
||
633 | ObjectOutputStream objOut = new ObjectOutputStream(outJar); |
||
634 | objOut.writeObject(contents); |
||
635 | objOut.flush(); |
||
636 | } |
||
637 | outJar.closeEntry(); |
||
638 | } |
||
639 | } |
||
640 | } |
||
641 | |||
642 | // Cleanup
|
||
643 | outJar.flush(); |
||
644 | outJar.close(); |
||
645 | } catch (Exception err) |
||
646 | { |
||
647 | err.printStackTrace(); |
||
648 | } |
||
649 | } |
||
650 | |||
651 | /**
|
||
652 | * Gets the stream to a resource.
|
||
653 | *
|
||
654 | * @param res The resource id.
|
||
655 | * @return The resource value, null if not found
|
||
656 | */
|
||
657 | public InputStream getResource(String res) throws Exception |
||
658 | { |
||
659 | InputStream result;
|
||
660 | String basePath = ""; |
||
661 | ResourceManager rm = null;
|
||
662 | |||
663 | try
|
||
664 | { |
||
665 | rm = ResourceManager.getInstance(); |
||
666 | basePath = rm.resourceBasePath; |
||
667 | } |
||
668 | catch(Exception e) |
||
669 | { e.printStackTrace(); } |
||
670 | |||
671 | result = this.getClass().getResourceAsStream( basePath+res );
|
||
672 | |||
673 | if( result == null ) |
||
674 | { |
||
675 | throw new ResourceNotFoundException( "Warning: Resource not found: " + res ); |
||
676 | } |
||
677 | return result;
|
||
678 | } |
||
679 | |||
680 | |||
681 | |||
682 | /**
|
||
683 | * Centers a window on screen.
|
||
684 | *
|
||
685 | * @param frame The window tp center.
|
||
686 | */
|
||
687 | public void centerFrame(Window frame) |
||
688 | { |
||
689 | Dimension frameSize = frame.getSize();
|
||
690 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
||
691 | frame.setLocation( |
||
692 | (screenSize.width - frameSize.width) / 2,
|
||
693 | (screenSize.height - frameSize.height) / 2 - 10); |
||
694 | } |
||
695 | |||
696 | /**
|
||
697 | * Returns the panels container size.
|
||
698 | *
|
||
699 | * @return The panels container size.
|
||
700 | */
|
||
701 | public Dimension getPanelsContainerSize() |
||
702 | { |
||
703 | return panelsContainer.getSize();
|
||
704 | } |
||
705 | |||
706 | /**
|
||
707 | * Sets the parameters of a GridBagConstraints object.
|
||
708 | *
|
||
709 | * @param gbc The constraints object.
|
||
710 | * @param gx The x coordinates.
|
||
711 | * @param gy The y coordinates.
|
||
712 | * @param gw The width.
|
||
713 | * @param wx The x wheight.
|
||
714 | * @param wy The y wheight.
|
||
715 | * @param gh Description of the Parameter
|
||
716 | */
|
||
717 | public void buildConstraints( |
||
718 | GridBagConstraints gbc,
|
||
719 | int gx,
|
||
720 | int gy,
|
||
721 | int gw,
|
||
722 | int gh,
|
||
723 | double wx,
|
||
724 | double wy)
|
||
725 | { |
||
726 | gbc.gridx = gx; |
||
727 | gbc.gridy = gy; |
||
728 | gbc.gridwidth = gw; |
||
729 | gbc.gridheight = gh; |
||
730 | gbc.weightx = wx; |
||
731 | gbc.weighty = wy; |
||
732 | } |
||
733 | |||
734 | /** Makes a clean closing. */
|
||
735 | public void exit() |
||
736 | { |
||
737 | if (installdata.canClose)
|
||
738 | { |
||
739 | // this does nothing if the uninstaller was not included
|
||
740 | writeUninstallData(); |
||
741 | Housekeeper.getInstance().shutDown(0);
|
||
742 | } else
|
||
743 | { |
||
744 | // The installation is not over
|
||
745 | int res =
|
||
746 | JOptionPane.showConfirmDialog(
|
||
747 | this,
|
||
748 | langpack.getString("installer.quit.message"),
|
||
749 | langpack.getString("installer.quit.title"),
|
||
750 | JOptionPane.YES_NO_OPTION);
|
||
751 | if (res == JOptionPane.YES_OPTION) |
||
752 | { |
||
753 | wipeAborted(); |
||
754 | Housekeeper.getInstance().shutDown(0);
|
||
755 | } |
||
756 | } |
||
757 | } |
||
758 | |||
759 | /** Wipes the written files when you abort the installation. */
|
||
760 | protected void wipeAborted() |
||
761 | { |
||
762 | Iterator it;
|
||
763 | |||
764 | // We check for running unpackers
|
||
765 | ArrayList unpackers = Unpacker.getRunningInstances();
|
||
766 | it = unpackers.iterator(); |
||
767 | while (it.hasNext())
|
||
768 | { |
||
769 | Thread t = (Thread) it.next(); |
||
770 | t.interrupt(); |
||
771 | // The unpacker process might keep writing stuffs so we wait :-/
|
||
772 | try
|
||
773 | { |
||
774 | Thread.sleep(3000, 0); |
||
775 | } catch (Exception e) |
||
776 | { |
||
777 | } |
||
778 | } |
||
779 | |||
780 | // Wipes them all in 2 stages
|
||
781 | UninstallData u = UninstallData.getInstance(); |
||
782 | it = u.getFilesList().iterator(); |
||
783 | if (!it.hasNext())
|
||
784 | return;
|
||
785 | while (it.hasNext())
|
||
786 | { |
||
787 | String p = (String) it.next(); |
||
788 | File f = new File(p); |
||
789 | f.delete(); |
||
790 | } |
||
791 | cleanWipe(new File(installdata.getInstallPath())); |
||
792 | } |
||
793 | |||
794 | /**
|
||
795 | * Recursive files wiper.
|
||
796 | *
|
||
797 | * @param file The file to wipe.
|
||
798 | */
|
||
799 | private void cleanWipe(File file) |
||
800 | { |
||
801 | if (file.isDirectory())
|
||
802 | { |
||
803 | File[] files = file.listFiles(); |
||
804 | int size = files.length;
|
||
805 | for (int i = 0; i < size; i++) |
||
806 | cleanWipe(files[i]); |
||
807 | } |
||
808 | file.delete(); |
||
809 | } |
||
810 | |||
811 | /**
|
||
812 | * Launches the installation.
|
||
813 | *
|
||
814 | * @param listener The installation listener.
|
||
815 | */
|
||
816 | public void install(AbstractUIProgressHandler listener) |
||
817 | { |
||
818 | Unpacker unpacker = new Unpacker(installdata, listener);
|
||
819 | unpacker.start(); |
||
820 | } |
||
821 | |||
822 | /**
|
||
823 | * Writes an XML tree.
|
||
824 | *
|
||
825 | * @param root The XML tree to write out.
|
||
826 | * @param out The stream to write on.
|
||
827 | * @exception Exception Description of the Exception
|
||
828 | */
|
||
829 | public void writeXMLTree(XMLElement root, OutputStream out) throws Exception |
||
830 | { |
||
831 | XMLWriter writer = new XMLWriter(out);
|
||
832 | writer.write(root); |
||
833 | } |
||
834 | |||
835 | /**
|
||
836 | * Changes the quit button text. If <tt>text</tt> is null, the default quit
|
||
837 | * text is used.
|
||
838 | */
|
||
839 | public void setQuitButtonText(String text) |
||
840 | { |
||
841 | if (text == null) |
||
842 | text = langpack.getString("installer.quit");
|
||
843 | quitButton.setText(text); |
||
844 | } |
||
845 | |||
846 | /* FocusTraversalPolicy objects to handle
|
||
847 | * keybord blocking; the declaration os Object
|
||
848 | * allows to use a pre version 1.4 VM.
|
||
849 | */
|
||
850 | private Object usualFTP = null; |
||
851 | private Object blockFTP = null; |
||
852 | |||
853 | /** Blocks GUI interaction. */
|
||
854 | public void blockGUI() |
||
855 | { |
||
856 | setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); |
||
857 | getGlassPane().setVisible(true);
|
||
858 | getGlassPane().setEnabled(true);
|
||
859 | // No traversal handling before VM version 1.4
|
||
860 | if( JAVA_SPECIFICATION_VERSION < 1.35) |
||
861 | return;
|
||
862 | if( usualFTP == null) |
||
863 | usualFTP = getFocusTraversalPolicy(); |
||
864 | if (blockFTP == null) |
||
865 | blockFTP = new BlockFocusTraversalPolicy();
|
||
866 | setFocusTraversalPolicy((java.awt.FocusTraversalPolicy) blockFTP); |
||
867 | getGlassPane().requestFocus(); |
||
868 | } |
||
869 | |||
870 | /** Releases GUI interaction. */
|
||
871 | public void releaseGUI() |
||
872 | { |
||
873 | getGlassPane().setEnabled(false);
|
||
874 | getGlassPane().setVisible(false);
|
||
875 | setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); |
||
876 | // No traversal handling before VM version 1.4
|
||
877 | if( JAVA_SPECIFICATION_VERSION < 1.35) |
||
878 | return;
|
||
879 | setFocusTraversalPolicy((java.awt.FocusTraversalPolicy) usualFTP); |
||
880 | } |
||
881 | |||
882 | /** Locks the 'previous' button. */
|
||
883 | public void lockPrevButton() |
||
884 | { |
||
885 | prevButton.setEnabled(false);
|
||
886 | } |
||
887 | |||
888 | /** Locks the 'next' button. */
|
||
889 | public void lockNextButton() |
||
890 | { |
||
891 | nextButton.setEnabled(false);
|
||
892 | } |
||
893 | |||
894 | /** Unlocks the 'previous' button. */
|
||
895 | public void unlockPrevButton() |
||
896 | { |
||
897 | prevButton.setEnabled(true);
|
||
898 | } |
||
899 | |||
900 | /** Unlocks the 'next' button. */
|
||
901 | public void unlockNextButton() |
||
902 | { |
||
903 | nextButton.setEnabled(true);
|
||
904 | nextButton.requestFocus(); |
||
905 | } |
||
906 | |||
907 | /** Allows a panel to ask to be skipped. */
|
||
908 | public void skipPanel() |
||
909 | { |
||
910 | if (installdata.curPanelNumber < installdata.panels.size() - 1) |
||
911 | { |
||
912 | if (isBack)
|
||
913 | { |
||
914 | installdata.curPanelNumber--; |
||
915 | switchPanel(installdata.curPanelNumber + 1);
|
||
916 | }else
|
||
917 | { |
||
918 | installdata.curPanelNumber++; |
||
919 | switchPanel(installdata.curPanelNumber - 1);
|
||
920 | } |
||
921 | |||
922 | } |
||
923 | } |
||
924 | /** This function moves to the next panel */
|
||
925 | public void navigateNext() |
||
926 | { |
||
927 | // If the button is inactive this indicates that we cannot move
|
||
928 | // so we don't do the move
|
||
929 | if( !nextButton.isEnabled())
|
||
930 | return;
|
||
931 | if ((installdata.curPanelNumber < installdata.panels.size() - 1) |
||
932 | && ((IzPanel) installdata.panels.get(installdata.curPanelNumber)) |
||
933 | .isValidated()) |
||
934 | { |
||
935 | installdata.curPanelNumber++; |
||
936 | switchPanel(installdata.curPanelNumber - 1);
|
||
937 | } |
||
938 | } |
||
939 | /** This function moves to the previous panel */
|
||
940 | public void navigatePrevious() |
||
941 | { |
||
942 | // If the button is inactive this indicates that we cannot move
|
||
943 | // so we don't do the move
|
||
944 | if( !prevButton.isEnabled())
|
||
945 | return;
|
||
946 | if ((installdata.curPanelNumber > 0)) |
||
947 | { |
||
948 | installdata.curPanelNumber--; |
||
949 | switchPanel(installdata.curPanelNumber + 1);
|
||
950 | } |
||
951 | } |
||
952 | |||
953 | /**
|
||
954 | * Handles the events from the navigation bar elements.
|
||
955 | *
|
||
956 | * @author Julien Ponge
|
||
957 | */
|
||
958 | class NavigationHandler implements ActionListener |
||
959 | { |
||
960 | /**
|
||
961 | * Actions handler.
|
||
962 | *
|
||
963 | * @param e The event.
|
||
964 | */
|
||
965 | public void actionPerformed(ActionEvent e) |
||
966 | { |
||
967 | Object source = e.getSource();
|
||
968 | if (source == prevButton)
|
||
969 | { |
||
970 | navigatePrevious(); |
||
971 | } else if (source == nextButton) |
||
972 | { |
||
973 | navigateNext(); |
||
974 | } else if (source == quitButton) |
||
975 | exit(); |
||
976 | |||
977 | } |
||
978 | } |
||
979 | |||
980 | /**
|
||
981 | * The window events handler.
|
||
982 | *
|
||
983 | * @author julien
|
||
984 | * created October 27, 2002
|
||
985 | */
|
||
986 | class WindowHandler extends WindowAdapter |
||
987 | { |
||
988 | /**
|
||
989 | * We can't avoid the exit here, so don't call exit anywhere else.
|
||
990 | *
|
||
991 | * @param e The event.
|
||
992 | */
|
||
993 | public void windowClosing(WindowEvent e) |
||
994 | { |
||
995 | // We show an alert anyway
|
||
996 | if (!installdata.canClose)
|
||
997 | JOptionPane.showMessageDialog(
|
||
998 | null,
|
||
999 | langpack.getString("installer.quit.message"),
|
||
1000 | langpack.getString("installer.warning"),
|
||
1001 | JOptionPane.ERROR_MESSAGE);
|
||
1002 | wipeAborted(); |
||
1003 | Housekeeper.getInstance().shutDown(0);
|
||
1004 | } |
||
1005 | } |
||
1006 | |||
1007 | /** A FocusTraversalPolicy that only allows the block panel to have
|
||
1008 | * the focus
|
||
1009 | */
|
||
1010 | private class BlockFocusTraversalPolicy extends java.awt.DefaultFocusTraversalPolicy |
||
1011 | { |
||
1012 | /** Only accepts the block panel
|
||
1013 | * @param aComp the component to check
|
||
1014 | * @return true if aComp is the block panel
|
||
1015 | */
|
||
1016 | protected boolean accept(Component aComp) |
||
1017 | { |
||
1018 | return aComp == getGlassPane();
|
||
1019 | } |
||
1020 | } |
||
1021 | } |