001: // This file is part of KeY - Integrated Deductive Software Design
002: // Copyright (C) 2001-2007 Universitaet Karlsruhe, Germany
003: // Universitaet Koblenz-Landau, Germany
004: // Chalmers University of Technology, Sweden
005: //
006: // The KeY system is protected by the GNU General Public License.
007: // See LICENSE.TXT for details.
008: //
009: //
010: package de.uka.ilkd.key.util.install;
011:
012: import java.awt.BorderLayout;
013: import java.awt.Container;
014: import java.awt.Font;
015: import java.awt.event.*;
016: import java.io.File;
017: import java.io.FileNotFoundException;
018: import java.io.IOException;
019: import java.util.jar.JarFile;
020:
021: import javax.swing.*;
022: import javax.swing.event.ChangeEvent;
023: import javax.swing.event.ChangeListener;
024:
025: public class KeYInstallerGUI extends KeYInstallerUI {
026:
027: private JTabbedPane tabbedPane;
028: private JFrame installerFrame;
029:
030: public KeYInstallerGUI(String keyHome, String keyLib,
031: String javaHome, String keyJarPath, String os) {
032:
033: super (keyHome, keyLib, javaHome, keyJarPath, os);
034:
035: installerFrame = new JFrame("KeY-Installation Wizard");
036: installerFrame
037: .setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
038:
039: tabbedPane = new JTabbedPane();
040: installerFrame.getContentPane().setLayout(new BorderLayout());
041: installerFrame.getContentPane().add(tabbedPane,
042: BorderLayout.CENTER);
043: installerFrame.getContentPane().add(setDefaultButtonPanel(),
044: BorderLayout.SOUTH);
045:
046: }
047:
048: public void setHeader(JLabel header) {
049: installerFrame.getContentPane().add(header, BorderLayout.NORTH);
050: }
051:
052: public void addInstallationPane(InstallationPane pane) {
053: tabbedPane.addTab(pane.name(), pane);
054: }
055:
056: public void setVisible(boolean b) {
057: installerFrame.setVisible(b);
058:
059: }
060:
061: public void requestFocus() {
062: installerFrame.requestFocus();
063: }
064:
065: public void pack() {
066: installerFrame.pack();
067: }
068:
069: public void dispose() {
070: installerFrame.dispose();
071: }
072:
073: public int paneCount() {
074: return tabbedPane.getTabCount();
075: }
076:
077: public InstallationPane pane(int index) {
078: return (InstallationPane) tabbedPane.getComponentAt(index);
079: }
080:
081: protected Container setDefaultButtonPanel() {
082: JPanel buttonPanel = new JPanel();
083: buttonPanel.setAlignmentX(SwingConstants.CENTER);
084: Box buttonBox = Box.createHorizontalBox();
085:
086: // create buttons
087: JButton prev = new JButton("<< Back");
088: JButton cancel = new JButton("Cancel");
089: JButton next = new JButton("Next >>");
090: // add to change listeners
091: ChangeListenerWithButton prevListener = new ChangeListenerWithButton(
092: prev) {
093: private void defaultAction() {
094: if (tabbedPane.getSelectedIndex() <= 0) {
095: button.setEnabled(false);
096: } else {
097: button.setEnabled(true);
098: }
099: }
100:
101: public void stateChanged(ChangeEvent ce) {
102: defaultAction();
103: }
104:
105: public void componentAdded(ContainerEvent e) {
106: defaultAction();
107: }
108:
109: public void componentRemoved(ContainerEvent e) {
110: defaultAction();
111: }
112: };
113: tabbedPane.addContainerListener(prevListener);
114: tabbedPane.addChangeListener(prevListener);
115:
116: ChangeListenerWithButton nextListener = new ChangeListenerWithButton(
117: next) {
118: private void defaultAction() {
119: if (tabbedPane.getSelectedIndex() == tabbedPane
120: .getTabCount() - 1) {
121: button.setText("Finish");
122: } else {
123: button.setText("Next >>");
124: }
125: }
126:
127: public void stateChanged(ChangeEvent ce) {
128: defaultAction();
129: }
130:
131: public void componentAdded(ContainerEvent e) {
132: defaultAction();
133: }
134:
135: public void componentRemoved(ContainerEvent e) {
136: defaultAction();
137: }
138: };
139:
140: tabbedPane.addContainerListener(nextListener);
141: tabbedPane.addChangeListener(nextListener);
142:
143: // set action listeners
144: prev.addActionListener(new ActionListener() {
145: public void actionPerformed(ActionEvent e) {
146: if (tabbedPane.getSelectedIndex() > 0) {
147: InstallationPane tab = (InstallationPane) tabbedPane
148: .getSelectedComponent();
149: if (tab.updateModel()) {
150: tabbedPane.setSelectedIndex(tabbedPane
151: .getSelectedIndex() - 1);
152: }
153: }
154: }
155: });
156:
157: cancel.addActionListener(new ActionListener() {
158: public void actionPerformed(ActionEvent e) {
159: cancelled();
160: }
161: });
162:
163: next.addActionListener(new ActionListener() {
164: public void actionPerformed(ActionEvent e) {
165: InstallationPane tab = (InstallationPane) tabbedPane
166: .getSelectedComponent();
167: if (tab.updateModel()) {
168: if (tabbedPane.getSelectedIndex() < tabbedPane
169: .getTabCount() - 1) {
170: tabbedPane.setSelectedIndex(tabbedPane
171: .getSelectedIndex() + 1);
172: } else {
173: try {
174: installerFrame
175: .setCursor(new java.awt.Cursor(
176: java.awt.Cursor.WAIT_CURSOR));
177: finish();
178: if (complete())
179: System.exit(0);
180: } catch (NotCompleteException nce) {
181: ; // let the user take care of it
182: } finally {
183: installerFrame
184: .setCursor(new java.awt.Cursor(
185: java.awt.Cursor.DEFAULT_CURSOR));
186: }
187: }
188: }
189: }
190: });
191:
192: // add buttons
193: buttonBox.add(prev);
194: buttonBox.add(cancel);
195: buttonBox.add(next);
196: buttonPanel.add(buttonBox);
197: return buttonPanel;
198: }
199:
200: private void cancelled() {
201: JOptionPane.showMessageDialog(null, "Installation cancelled.",
202: "Installation cancelled",
203: JOptionPane.INFORMATION_MESSAGE);
204: System.exit(-1);
205: }
206:
207: private boolean complete() {
208:
209: if (!updateModel()) {
210: return false;
211: }
212:
213: File jarFile = new File(keyJarFile());
214:
215: if (!jarFile.exists()) {
216: JOptionPane
217: .showMessageDialog(
218: null,
219: trim(
220: "Could not find 'key.jar' in "
221: + keyJarPath()
222: + ". Please enter the correct part in section "
223: + "'Global Settings | key.jar'",
224: 60), "File Missing",
225: JOptionPane.ERROR_MESSAGE);
226: return false;
227: }
228:
229: String[] missingLibs;
230: int option = 2;
231:
232: missingLibs = checkLibraries();
233: do {
234: if (missingLibs.length > 0) {
235: Object[] options = { "Continue anyway", "Go back",
236: "Check again" };
237: option = JOptionPane
238: .showOptionDialog(
239: null,
240: trim(
241: "Please copy the external libraries to "
242: + keyLib()
243: + ". You can download them from: "
244: + "http://www.key-project.org/download/",
245: 60), "Libraries Missing",
246: JOptionPane.DEFAULT_OPTION,
247: JOptionPane.WARNING_MESSAGE, null,
248: options, options[option]);
249: }
250: missingLibs = checkLibraries();
251: } while (missingLibs.length > 0 && option == 2);
252:
253: return option != 1;
254: }
255:
256: private void abortError(String err) {
257: JOptionPane.showMessageDialog(null, trim(
258: "Installation cannot proceed due to an error:\n" + err,
259: 60), "Installation Not Finished",
260: JOptionPane.ERROR_MESSAGE);
261: throw new NotCompleteException();
262: // System.exit ( -1 );
263: }
264:
265: private class NotCompleteException extends RuntimeException {
266: }
267:
268: private boolean updateModel() {
269: for (int i = 0; i < tabbedPane.getTabCount(); i++) {
270: if (tabbedPane.getComponentAt(i) instanceof InstallationPane) {
271: if (!((InstallationPane) tabbedPane.getComponentAt(i))
272: .updateModel()) {
273: tabbedPane.setSelectedIndex(i);
274: return false;
275: }
276: }
277: }
278: return true;
279: }
280:
281: private void finish() {
282:
283: StringBuffer todo = new StringBuffer("");
284:
285: File keyJar = new File(keyJarFile());
286: JarFile keyJarFile = null;
287:
288: try {
289: keyJarFile = new JarFile(new File(keyJarFile()));
290: } catch (FileNotFoundException fne) {
291: abortError("Did not find a valid jar file at "
292: + keyJarPath()
293: + " Please check its existence and "
294: + "its read and write access permissions.\nDetail: "
295: + fne);
296: } catch (IOException ioe) {
297: abortError("Error when trying to access 'key.jar' at "
298: + keyJarPath() + ".\nDetail: " + ioe);
299: }
300: String[] missingLibs = new String[0];
301:
302: mkdirs();
303:
304: missingLibs = checkLibraries();
305:
306: try {
307: generateScripts(keyJarFile);
308: } catch (KeYInstallerException kie) {
309: abortError("Could not generate the shell scripts. Please "
310: + "resolve the problem first "
311: + "and redo the installation afterwards.\nDetail: "
312: + kie);
313: }
314:
315: try {
316: extractTgScripts(keyJarFile);
317: } catch (KeYInstallerException kie) {
318: abortError("Could not generate the KeY scripts. Please "
319: + "resolve the problem first "
320: + "and redo the installation afterwards.\nDetail:"
321: + kie);
322: }
323:
324: try {
325: extractExamples(keyJarFile);
326: } catch (KeYInstallerException kie) {
327: abortError("Could not unpack the examples. Please "
328: + "resolve the problem first "
329: + "and redo the installation afterwards.\nDetail:"
330: + kie);
331: }
332:
333: if ("linux".equals(os())) {
334: try {
335: Runtime.getRuntime().exec(
336: "chmod a+x " + startScriptFilePath());
337: Runtime.getRuntime().exec(
338: "chmod a+x " + startProverScriptFilePath());
339: } catch (IOException e) {
340: todo.append("Please set " + startScriptFilePath()
341: + " executable : chmod a+x "
342: + startScriptFilePath() + "\n chmod a+x "
343: + startProverScriptFilePath());
344: todo.append("\n");
345: }
346: }
347:
348: try {
349: copy(keyJar, systemPath());
350: } catch (KeYInstallerException kie) {
351: todo
352: .append(" Copy file 'key.jar' from "
353: + keyJar
354: + " to "
355: + systemPath()
356: + "\n\t usually this should be done automatically, "
357: + "but failed due to: " + kie);
358: todo.append("\n");
359: }
360:
361: if (missingLibs.length > 0) {
362: todo.append("Please copy the following libraries to ");
363: todo.append(keyLib());
364: for (int i = 0; i < missingLibs.length; i++) {
365: todo.append("\n");
366: todo.append(i + ". " + missingLibs[i]);
367: }
368: todo.append("\n");
369: }
370:
371: if (todo.length() > 0) {
372: JOptionPane
373: .showMessageDialog(
374: null,
375: trim(
376: "Something is left to do. "
377: + todo.toString()
378: + "After you have done all from above, you can start KeY by"
379: + " changing to "
380: + binaryPath()
381: + " and executing "
382: + startScriptFileName()
383: + " (Together front end) "
384: + " or "
385: + startProverScriptFileName()
386: + " (standalone KeY)", 60),
387: "Please complete installation manually",
388: JOptionPane.INFORMATION_MESSAGE);
389: } else {
390: JOptionPane.showMessageDialog(null, trim(
391: "To start KeY, change directory to " + binaryPath()
392: + " and execute " + startScriptFileName()
393: + " (Together front end) " + " or "
394: + startProverScriptFileName()
395: + " (standalone KeY)", 60),
396: "Installation successfully completed",
397: JOptionPane.INFORMATION_MESSAGE);
398: }
399: }
400:
401: public void start() {
402:
403: JLabel header = new JLabel();
404:
405: header.setFont(new Font("Header Font", Font.PLAIN, 24));
406: header.setText("KeY-Installer");
407: header.setIcon(de.uka.ilkd.key.gui.IconFactory.keyLogo(50, 40));
408: header.setHorizontalAlignment(SwingConstants.CENTER);
409:
410: setHeader(header);
411: addInstallationPane(new WelcomePane(this ));
412: addInstallationPane(new GlobalSettingsPane(this ));
413: addInstallationPane(new LibrarySettingsPane(this ));
414:
415: pack();
416: setVisible(true);
417:
418: }
419:
420: // Change listener for tabbed pane
421: abstract static class ChangeListenerWithButton implements
422: ChangeListener, ContainerListener {
423:
424: protected JButton button;
425:
426: public ChangeListenerWithButton(JButton button) {
427: this .button = button;
428: }
429:
430: public abstract void stateChanged(ChangeEvent ce);
431:
432: public abstract void componentAdded(ContainerEvent e);
433:
434: public abstract void componentRemoved(ContainerEvent e);
435:
436: }
437:
438: }
|