package org.limewire.ui.swing;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import org.limewire.ui.support.FatalBugManager;
import org.limewire.ui.swing.util.GuiUtils;
class GuiLoader {
/**
* Creates an {@link Initializer} instance that constructs the
* necessary classes for the application.
*
* <p>Invoked by {@link Main} by reflection.
*
* @param args the array of command line arguments
* @param frame the splash screen; null, if no splash is displayed
*/
public void load(String args[], Frame splashFrame, Image splashImage) {
try {
//sanityCheck();
Initializer initializer = new Initializer();
initializer.initialize(args, splashFrame, splashImage);
} catch(StartupFailedException sfe) {
GuiUtils.hideAndDisposeAllWindows();
showCorruptionError(sfe);
System.exit(1);
} catch(Throwable err) {
GuiUtils.hideAndDisposeAllWindows();
try {
FatalBugManager.handleFatalBug(err);
} catch(Throwable t) {
Throwable error = err;
try {
t.initCause(err);
error = t;
} catch(Throwable ignored) {}
showCorruptionError(error);
System.exit(1);
}
}
}
/**
* Display a standardly formatted internal error message
* coming from the backend.
*
* @param err the <tt>Throwable</tt> object containing information
* about the error
*/
private static final void showCorruptionError(Throwable err) {
err.printStackTrace();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println("LimeWire version @version@");
pw.print("Java version ");
pw.print(System.getProperty("java.version", "?"));
pw.print(" from ");
pw.println(System.getProperty("java.vendor", "?"));
pw.print(System.getProperty("os.name", "?"));
pw.print(" v. ");
pw.print(System.getProperty("os.version", "?"));
pw.print(" on ");
pw.println(System.getProperty("os.arch", "?"));
Runtime runtime = Runtime.getRuntime();
pw.println("Free/total memory: "
+runtime.freeMemory()+"/"+runtime.totalMemory());
pw.println();
err.printStackTrace(pw);
pw.println();
pw.println("STARTUP ERROR!");
pw.println();
pw.flush();
displayError(sw.toString());
}
/**
* Displays an internal error with specialized formatting.
*/
private static final void displayError(String error) {
System.out.println("Error: " + error);
final JDialog DIALOG = new JDialog();
DIALOG.setModal(true);
final Dimension DIALOG_DIMENSION = new Dimension(350, 200);
final Dimension INNER_SIZE = new Dimension(300, 150);
DIALOG.setSize(DIALOG_DIMENSION);
JPanel mainPanel = new JPanel();
mainPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
mainPanel.setLayout(new BorderLayout());
String instr0;
String instr1;
String instr2;
String instr3;
String instr4;
String instr5;
instr0 = "One or more necessary files appear to be invalid.";
instr1 = "This is generally caused by a corrupted installation.";
instr2 = "Please try downloading and installing LimeWire again.";
instr3 = "If the problem persists, please visit www.limewire.com ";
instr4 = "and click the 'Support' link. ";
instr5 = "Thank you.";
JLabel label0 = new JLabel(instr0);
JLabel label1 = new JLabel(instr1);
JLabel label2 = new JLabel(instr2);
JLabel label3 = new JLabel(instr3);
JLabel label4 = new JLabel(instr4);
JLabel label5 = new JLabel(instr5);
JPanel labelPanel = new JPanel();
JPanel innerLabelPanel = new JPanel();
labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.X_AXIS));
innerLabelPanel.setLayout(new BoxLayout(innerLabelPanel, BoxLayout.Y_AXIS));
innerLabelPanel.add(label0);
innerLabelPanel.add(label1);
innerLabelPanel.add(label2);
innerLabelPanel.add(label3);
innerLabelPanel.add(label4);
innerLabelPanel.add(label5);
innerLabelPanel.add(Box.createVerticalStrut(6));
labelPanel.add(innerLabelPanel);
labelPanel.add(Box.createHorizontalGlue());
final JTextArea textArea = new JTextArea(error);
textArea.selectAll();
textArea.copy();
textArea.setColumns(50);
textArea.setEditable(false);
JScrollPane scroller = new JScrollPane(textArea);
scroller.setBorder(BorderFactory.createEtchedBorder());
scroller.setPreferredSize(INNER_SIZE);
JPanel buttonPanel = new JPanel();
JButton copyButton = new JButton("Copy Report");
copyButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textArea.selectAll();
textArea.copy();
}
});
JButton quitButton = new JButton("Ok");
quitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
DIALOG.dispose();
}
});
buttonPanel.add(copyButton);
buttonPanel.add(quitButton);
mainPanel.add(labelPanel, BorderLayout.NORTH);
mainPanel.add(scroller, BorderLayout.CENTER);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
DIALOG.getContentPane().add(mainPanel);
DIALOG.pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension dialogSize = DIALOG.getSize();
DIALOG.setLocation((screenSize.width - dialogSize.width)/2,
(screenSize.height - dialogSize.height)/2);
DIALOG.setVisible(true);
}
/**
* Determines whether or not specific files exist and are the correct size.
* If they do not exist or are the incorrect size,
* throws MissingResourceException.
*/
// private static void sanityCheck() throws StartupFailedException {
// File test = new File("gpl.txt");
// boolean isCVS = false;
//
// // If the gpl.txt exists, then we're running off of CVS.
// if( test.exists() && test.isFile() ) {
// isCVS = true;
// }
// // If it doesn't, we're a production version.
// else {
// isCVS = false;
// }
//
// String root = isCVS ? "../lib/jars" : (isWindows() ? "./lib" : ".");
// File themesJar = new File(root, "themes.jar");
//
// if( !isCVS && (!themesJar.exists() || !themesJar.isFile()) )
// throw new StartupFailedException("invalid themes.jar");
//
// // Then do more advanced hash checks.
// try {
// verifyHashes(root);
// } catch(IOException e) {
// throw new StartupFailedException(e.getMessage());
// }
// }
//
// /**
// * Loads up a file 'hashes' and verifies that all the files/hashes
// * in it match the hashes we have.
// */
// private static void verifyHashes(String root) throws IOException, StartupFailedException {
// // Load up the file with the hashes.
// Properties props = new Properties();
// FileInputStream fis = null;
// try {
// fis = new FileInputStream(new File(root, "hashes"));
// props.load(fis);
// } finally {
// if( fis != null ) {
// try {
// fis.close();
// fis = null;
// } catch(IOException ignored) {}
// }
// }
//
// //Iterate through each expected hash to verify that
// //the files on disk are not corrupted.
// Enumeration names = props.propertyNames();
// while(names.hasMoreElements()) {
// String name = (String)names.nextElement();
// String storedHash = props.getProperty(name);
// String realHash = hash(new File(root, name));
// if(!realHash.equals(storedHash)) {
// throw new StartupFailedException(
// "file [" + name + "] has hash of [" + realHash +
// "] instead of expected [" + storedHash + "]");
// }
// }
// }
//
// /**
// * Determines the MD5 hash of the specified file.
// */
// private static String hash(File f) throws IOException {
// FileInputStream fis = null;
// try {
// fis = new FileInputStream(f);
// MessageDigest md = null;
// try {
// md = MessageDigest.getInstance("MD5");
// } catch(NoSuchAlgorithmException e) {
// throw new IOException("Unknown algorithm: MD5");
// }
//
// byte[] buffer = new byte[16384];
// int read;
// while ((read=fis.read(buffer)) != -1) {
// md.update(buffer, 0, read);
// }
//
// return toHexString(md.digest());
// } finally {
// if( fis != null ) {
// try {
// fis.close();
// } catch(IOException ignored) {}
// }
// }
// }
//
// /**
// * Converts a 16-byte array of unsigned bytes
// * to a 32 character hex string.
// */
// private static String toHexString(byte[] data) {
// StringBuilder sb = new StringBuilder(32);
// for(int i = 0; i < data.length; i++) {
// int asInt = data[i] & 0x000000FF;
// String x = Integer.toHexString(asInt);
// if(x.length() == 1)
// sb.append("0");
// sb.append(x);
// }
// return sb.toString().toUpperCase();
// }
//
// /**
// * @return if we're running on windows without using OSUtils.
// */
// private static boolean isWindows() {
// String os = System.getProperty("os.name").toLowerCase(Locale.US);
// return os.contains("windows");
// }
private static class StartupFailedException extends Exception {
StartupFailedException(String msg) {
super(msg);
}
StartupFailedException() {
super();
}
}
}