/* Copyright (c) 2013-2014 Jesper Öqvist <jesper@llbit.se> * * This file is part of Chunky. * * Chunky 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 3 of the License, or * (at your option) any later version. * * Chunky 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 Chunky. If not, see <http://www.gnu.org/licenses/>. */ package se.llbit.chunky.launcher; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import se.llbit.json.JsonParser; import se.llbit.json.JsonParser.SyntaxError; /** * Check for update and run update dialog (or just update in headless mode). * * @author Jesper Öqvist <jesper@llbit.se> */ public class UpdateChecker extends Thread { private final LauncherSettings settings; private final UpdateListener listener; public UpdateChecker(LauncherSettings settings, UpdateListener listener) { this.settings = settings; this.listener = listener; } @Override public void run() { try { if (!tryUpdate()) { listener.noUpdateAvailable(); } } catch (MalformedURLException e1) { System.err.println("Malformed version info url"); listener.updateError("Failed to fetch latest version info online."); } catch (IOException e1) { System.err.println("Failed to fetch version info " + e1.getMessage()); listener.updateError( "Failed to fetch latest version info online. The server may be down right now."); } catch (SyntaxError e1) { System.err.println("Version info JSON error " + e1.getMessage()); listener.updateError("The downloaded version info was corrupt. Can not update at this time."); } catch (Throwable e1) { System.err.println("Uncaught exception: " + e1.getMessage()); listener.updateError("Can not update at this time."); } } private boolean tryUpdate() throws IOException, SyntaxError { List<VersionInfo> candidates = new LinkedList<>(); candidates.add(getVersion("http://chunkyupdate.llbit.se/latest.json")); if (settings.downloadSnapshots) { candidates.add(getVersion("http://chunkyupdate.llbit.se/snapshot.json")); } // Filter out corrupt versions. Iterator<VersionInfo> iter = candidates.iterator(); while (iter.hasNext()) { if (!iter.next().isValid()) { iter.remove(); } } if (candidates.isEmpty()) { listener .updateError("The downloaded version info was corrupt. Can not update at this moment."); return false; } else { // Find latest candidate. VersionInfo latest = candidates.get(0); for (VersionInfo candidate : candidates) { if (candidate.compareTo(latest) < 0) { latest = candidate; } } // Check if more recent version than candidate is already installed. List<VersionInfo> versions = ChunkyDeployer.availableVersions(); iter = versions.iterator(); while (iter.hasNext()) { VersionInfo available = iter.next(); if (available.compareTo(latest) <= 0 && ChunkyDeployer .checkVersionIntegrity(available.name)) { // More recent version already installed and not corrupt. return false; } } // Install the candidate! listener.updateAvailable(latest); return true; } } private VersionInfo getVersion(String url) throws IOException, SyntaxError { URL latestJson = new URL(url); InputStream in = latestJson.openStream(); JsonParser parser = new JsonParser(in); VersionInfo version = new VersionInfo(parser.parse().object()); in.close(); return version; } }