package esmska; import esmska.gui.ThemeManager; import esmska.update.LegacyUpdater; import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.UIManager; import esmska.data.Config; import esmska.data.CountryPrefix; import esmska.gui.MainFrame; import esmska.gui.ExceptionDialog; import esmska.gui.InitWizardDialog; import esmska.persistence.PersistenceManager; import esmska.transfer.ProxyManager; import esmska.update.Statistics; import esmska.utils.L10N; import esmska.utils.LogSupport; import esmska.utils.RuntimeUtils; import java.awt.EventQueue; import java.io.File; import java.io.IOException; import java.text.MessageFormat; import java.util.ResourceBundle; import javax.swing.JLabel; import javax.swing.SwingUtilities; import org.apache.commons.lang.ArrayUtils; /** Starter class for the whole program * * @author ripper */ public class Main { private static final Logger logger = Logger.getLogger(Main.class.getName()); private static final ResourceBundle l10n = L10N.l10nBundle; private static String configPath; //path to config files /** Program starter method * @param args the command line arguments */ public static void main(String[] args) { //initialize logging LogSupport.init(); //store records for pushing it to logfile later LogSupport.storeRecords(true); //handle uncaught exceptions Thread.setDefaultUncaughtExceptionHandler(ExceptionDialog.getExceptionHandler()); //workaround for Java 6 to process uncaught exceptions from modal dialogs //read more at http://code.google.com/p/esmska/issues/detail?id=256 System.setProperty("sun.awt.exception.handler", ExceptionDialog.AwtHandler.class.getName()); //detect JVM and warn if not not supported if (!RuntimeUtils.isSupportedJava()) { logger.warning("You are probably running the program on an unsupported " + "Java version! Program might not work correctly with it! " + "The tested Java versions are: Oracle Java 6 and 7, OpenJDK 6 and 7, Apple Java 6 and 7."); } //parse commandline arguments CommandLineParser clp = new CommandLineParser(); if (! clp.parseArgs(args)) { System.exit(1); } //log some basic stuff for debugging logger.log(Level.FINE, "Esmska {0} starting...", Config.getLatestVersion()); logger.log(Level.FINER, "System info: {0}", RuntimeUtils.getSystemInfo()); //portable mode configPath = clp.getConfigPath(); if (clp.isPortable() && configPath == null) { logger.fine("Entering portable mode"); try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { logger.log(Level.WARNING, "Could not set system Look and Feel", ex); } JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setApproveButtonText(l10n.getString("Select")); chooser.setDialogTitle(l10n.getString("Main.choose_config_files")); chooser.setFileHidingEnabled(false); chooser.setMultiSelectionEnabled(false); int result = chooser.showOpenDialog(null); if (result == JFileChooser.APPROVE_OPTION) { configPath = chooser.getSelectedFile().getPath(); logger.log(Level.CONFIG, "New config path: {0}", configPath); } } }); } catch (Exception e) { logger.log(Level.SEVERE, "Can't display file chooser for portable mode", e); } } //get persistence manager try { if (configPath != null) { PersistenceManager.setCustomDirs(configPath, configPath); } PersistenceManager.instantiate(); } catch (Exception ex) { logger.log(Level.SEVERE, "Could not create program dir or read config files", ex); try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { JOptionPane.showMessageDialog(null, new JLabel(MessageFormat.format(l10n.getString("Main.cant_read_config"), PersistenceManager.getConfigDir().getAbsolutePath(), PersistenceManager.getDataDir().getAbsolutePath())), null, JOptionPane.ERROR_MESSAGE); } }); } catch (Exception e) { logger.log(Level.SEVERE, "Can't display error message", e); } finally { //if it is not possible to access config dir, we don't want to //run anymore System.exit(5); } } PersistenceManager pm = Context.persistenceManager; //backup files try { pm.backupConfigFiles(); } catch (IOException ex) { logger.log(Level.SEVERE, "Could not back up configuration", ex); } //initialize file logging File logFile = pm.getLogFile(); try { LogSupport.initFileHandler(logFile); } catch (IOException ex) { logger.log(Level.SEVERE, "Could not start logging into " + logFile.getAbsolutePath(), ex); } finally { //no need to store records anymore LogSupport.storeRecords(false); } //load config file try { pm.loadConfig(); } catch (Exception ex) { logger.log(Level.SEVERE, "Could not load config file", ex); } //load rest of user files try { pm.loadContacts(); } catch (Exception ex) { logger.log(Level.SEVERE, "Could not load contacts file", ex); } try { pm.loadQueue(); } catch (Exception ex) { logger.log(Level.SEVERE, "Could not load queue file", ex); } try { pm.loadHistory(); } catch (Exception ex) { logger.log(Level.SEVERE, "Could not load history file", ex); } try { pm.loadKeyring(); } catch (Exception ex) { logger.log(Level.SEVERE, "Could not load keyring file", ex); } //initialize logging if set from Config if (Config.getInstance().isDebugMode()) { //set "full" logging, but don't log to console LogSupport.enableHttpClientLogging(); LogSupport.getEsmskaLogger().setLevel(Level.ALL); } //quit if other program instance is already running if (!pm.isFirstInstance()) { logger.warning("Esmska is already running. Quitting."); try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { String quitOption = l10n.getString("Quit"); String[] options = new String[]{quitOption}; JOptionPane.showOptionDialog(null, l10n.getString("Main.already_running"), null, JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, quitOption); } }); } catch (Exception e) { logger.log(Level.SEVERE, "Can't display error message", e); } finally { System.exit(15); } } //warn if configuration files are newer than program version (user has //executed an older program version) Config config = Config.getInstance(); final String dataVersion = config.getVersion(); final String programVersion = Config.getLatestVersion(); if (Config.compareProgramVersions(dataVersion, programVersion) > 0) { logger.log(Level.WARNING,"Configuration files are newer ({0}) then " + "current program version ({1})! Data corruption may occur!", new Object[]{dataVersion, programVersion}); try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { String runOption = l10n.getString("Main.run_anyway"); String quitOption = l10n.getString("Quit"); String[] options = new String[]{runOption, quitOption}; options = RuntimeUtils.sortDialogOptions(options); int result = JOptionPane.showOptionDialog(null, new JLabel(MessageFormat.format(l10n.getString("Main.configsNewer"), dataVersion, programVersion)), null, JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, quitOption); if (result != ArrayUtils.indexOf(options, runOption)) { System.exit(0); } } }); } catch (Exception e) { logger.log(Level.SEVERE, "Can't display error message", e); } } //do some initialization if this is the first run if (config.isFirstRun()) { logger.fine("First run, doing initialization..."); //set country prefix from locale config.setCountryPrefix( CountryPrefix.getCountryPrefix(Locale.getDefault().getCountry())); //set suggested LaF for this platform config.setLookAndFeel(ThemeManager.suggestBestLAF()); //show first run wizard InitWizardDialog dialog = new InitWizardDialog(null, true); dialog.setVisible(true); } //update from older versions if (!config.isFirstRun()) { try { LegacyUpdater.update(); } catch (Exception ex) { logger.log(Level.SEVERE, "Updating to a newer version failed", ex); } } //set L&F try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { try { ThemeManager.setLaF(); } catch (Throwable ex) { logger.log(Level.WARNING, "Could not set Look and Feel", ex); } } }); } catch (Exception e) { logger.log(Level.SEVERE, "Setting LaF interrupted", e); } //set proxy if (config.isUseProxy()) { ProxyManager.setProxy(config.getHttpProxy(), config.getHttpsProxy(), config.getSocksProxy()); } //do some changes for unstable version if (!Config.isStableVersion()) { config.setAnnounceUnstableUpdates(true); } // refresh UUID if needed Statistics.refreshUUID(); //start main frame EventQueue.invokeLater(new Runnable() { @Override public void run() { MainFrame.instantiate(); Context.mainFrame.startAndShow(); } }); } }