/* This file is part of RouteConverter. RouteConverter is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. RouteConverter is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with RouteConverter; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Copyright (C) 2007 Christian Pesch. All Rights Reserved. */ package slash.navigation.converter.gui.helpers; import slash.common.system.Version; import slash.navigation.converter.gui.RouteConverter; import slash.navigation.feedback.domain.RouteFeedback; import java.awt.*; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import java.util.logging.Logger; import static java.lang.System.currentTimeMillis; import static java.text.MessageFormat.format; import static javax.swing.JOptionPane.*; import static javax.swing.SwingUtilities.invokeLater; import static slash.common.io.Transfer.trim; import static slash.common.system.Version.parseVersionFromManifest; import static slash.feature.client.Feature.initializeFeatures; import static slash.feature.client.Feature.initializePreferences; import static slash.navigation.converter.gui.RouteConverter.AUTOMATIC_UPDATE_CHECK_PREFERENCE; import static slash.navigation.converter.gui.RouteConverter.getPreferences; import static slash.navigation.converter.gui.helpers.ExternalPrograms.startBrowserForJava; import static slash.navigation.converter.gui.helpers.ExternalPrograms.startBrowserForUpdateCheck; /** * Knows how to retrieve the information which is the latest version. * * @author Christian Pesch */ public class UpdateChecker { private static final Logger log = Logger.getLogger(UpdateChecker.class.getName()); private static final String START_COUNT_PREFERENCE = "startCount"; private static final String START_TIME_PREFERENCE = "startTime"; private RouteFeedback routeFeedback; static { getPreferences().putInt(START_COUNT_PREFERENCE, getStartCount() + 1); if (getPreferences().getLong(START_TIME_PREFERENCE, -1) == -1) getPreferences().putLong(START_TIME_PREFERENCE, currentTimeMillis()); } public UpdateChecker(RouteFeedback routeFeedback) { this.routeFeedback = routeFeedback; } private static int getStartCount() { return getPreferences().getInt(START_COUNT_PREFERENCE, 0); } private static long getStartTime() { return getPreferences().getLong(START_TIME_PREFERENCE, currentTimeMillis()); } private UpdateResult check() { String myRouteConverterVersion = parseVersionFromManifest().getVersion(); String myJavaVersion = System.getProperty("java.version"); UpdateResult result = new UpdateResult(myRouteConverterVersion, myJavaVersion); try { String parameters = routeFeedback.checkForUpdate(myRouteConverterVersion, RouteConverter.getInstance().getEditionId(), getStartCount(), myJavaVersion, System.getProperty("sun.arch.data.model"), System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"), System.getProperty("javawebstart.version"), getStartTime()); result.setParameters(parameters); } catch (Throwable t) { log.severe("Cannot check for update: " + t); } return result; } private void offerRouteConverterUpdate(Window window, UpdateResult result) { int confirm = showConfirmDialog(window, format(RouteConverter.getBundle().getString("confirm-routeconverter-update"), result.getMyRouteConverterVersion(), RouteConverter.getInstance().getEdition(), result.getLatestRouteConverterVersion()), RouteConverter.getTitle(), YES_NO_OPTION); if (confirm == YES_OPTION) startBrowserForUpdateCheck(window, result.getMyRouteConverterVersion(), getStartTime()); } private void noUpdateAvailable(Window window) { showMessageDialog(window, format(RouteConverter.getBundle().getString("no-update-available"), RouteConverter.getInstance().getEdition()), RouteConverter.getTitle(), INFORMATION_MESSAGE); } private void offerJavaUpdate(Window window, UpdateResult result) { int confirm = showConfirmDialog(window, format(RouteConverter.getBundle().getString("confirm-java-update"), result.getMyJavaVersion(), result.getLatestJavaVersion()), RouteConverter.getTitle(), YES_NO_OPTION); if (confirm == YES_OPTION) startBrowserForJava(window); } public void implicitCheck(final Window window) { if (!getPreferences().getBoolean(AUTOMATIC_UPDATE_CHECK_PREFERENCE, true)) return; new Thread(new Runnable() { public void run() { final UpdateResult result = check(); if (result.existsLaterRouteConverterVersion()) { invokeLater(new Runnable() { public void run() { offerRouteConverterUpdate(window, result); } }); } else if (result.existsLaterJavaVersion()) { invokeLater(new Runnable() { public void run() { offerJavaUpdate(window, result); } }); } } }, "UpdateChecker").start(); } public void explicitCheck(Window window) { UpdateResult result = check(); if (result.existsLaterRouteConverterVersion()) offerRouteConverterUpdate(window, result); else noUpdateAvailable(window); if (result.existsLaterJavaVersion()) offerJavaUpdate(window, result); } static class UpdateResult { private static final String ROUTECONVERTER_VERSION_KEY = "routeconverter.version"; private static final String JAVA6_VERSION_KEY = "java6.version"; private static final String JAVA7_VERSION_KEY = "java7.version"; private static final String JAVA8_VERSION_KEY = "java8.version"; private final String myRouteConverterVersion; private final String myJavaVersion; private Map<String, String> parameters = new HashMap<>(); public UpdateResult(String myRouteConverterVersion, String myJavaVersion) { this.myRouteConverterVersion = myRouteConverterVersion; this.myJavaVersion = myJavaVersion; } public String getMyRouteConverterVersion() { return myRouteConverterVersion; } public String getLatestRouteConverterVersion() { return getValue(ROUTECONVERTER_VERSION_KEY); } public boolean existsLaterRouteConverterVersion() { String latestRouteConverterVersion = getLatestRouteConverterVersion(); return latestRouteConverterVersion != null && new Version(latestRouteConverterVersion).isLaterVersionThan(new Version(getMyRouteConverterVersion())); } public String getMyJavaVersion() { return myJavaVersion; } public String getLatestJavaVersion() { Version version = new Version(myJavaVersion); String latestVersionKey = version.isLaterVersionThan(new Version("1.8.0")) ? JAVA8_VERSION_KEY : version.isLaterVersionThan(new Version("1.7.0")) ? JAVA7_VERSION_KEY : JAVA6_VERSION_KEY; return getValue(latestVersionKey); } public boolean existsLaterJavaVersion() { String latestJavaVersion = getLatestJavaVersion(); return latestJavaVersion != null && new Version(latestJavaVersion).isLaterVersionThan(new Version(getMyJavaVersion())); } String getValue(String key) { return trim(parameters.get(key)); } private Map<String, String> parseParameters(String parameters) { StringTokenizer tokenizer = new StringTokenizer(parameters, ","); Map<String, String> map = new HashMap<>(); while (tokenizer.hasMoreTokens()) { String nv = tokenizer.nextToken(); StringTokenizer nvTokenizer = new StringTokenizer(nv, "="); if (!nvTokenizer.hasMoreTokens()) continue; String key = nvTokenizer.nextToken(); if (!nvTokenizer.hasMoreTokens()) continue; String value = nvTokenizer.nextToken(); map.put(key, value); } return map; } public void setParameters(String parameters) { this.parameters = parseParameters(parameters); initializeFeatures(getValue("features")); initializePreferences(getPreferences()); } } }