Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package jmupen; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import org.apache.commons.io.FileUtils; /** * * @author xela92 */ public class JMupenUpdater { private static final String JarURL = "http://xela92.linuxzogno.org/JMupen/JMupen.jar"; private static final String Md5URL = "http://xela92.linuxzogno.org/JMupen/JMupen.md5"; private static boolean update_available = false; private static File jarFile = null; private static File updatePackage = null; private static final int tenmin = 600000; private static final File tmpDir = new File(System.getProperty("java.io.tmpdir") + "\\jmupen"); public static void checkForUpdates() { try { jarFile = getJarFile(); } catch (URISyntaxException ex) { System.err.println("Error getting jarfile path. " + ex.getLocalizedMessage()); return; } try { if (jarFile != null) { // Get URL connection and lastModified time URL url = new URL(JarURL); URLConnection connection = url.openConnection(); long localMod = jarFile.lastModified(), onlineMod = connection.getLastModified(); updatePackage = new File( JMupenUtils.getConfigDir().concat(JMupenUtils.getBar()).concat("jmupen-update.jar")); if (updatePackage.exists()) { JMupenUpdater.setUpdateAvailable(true); JMupenGUI.getInstance().showUpdateDialog(); return; } if (localMod >= onlineMod - tenmin) { System.out.println("No update available at " + JarURL + '(' + localMod + '>' + onlineMod + ')'); JMupenUpdater.setUpdateAvailable(false); return; } else { JMupenUpdater.setUpdateAvailable(true); } System.out.println("Loading update from " + JarURL); byte bytes[] = getBytes(connection); System.out.println("Update loaded"); writeBytes(updatePackage, bytes); System.out.println("Update saved: " + updatePackage.getAbsolutePath()); jarFile.setLastModified(onlineMod); JMupenGUI.getInstance().showUpdateDialog(); } } catch (Exception e) { System.err.println("Error updating JMupen. " + e.getLocalizedMessage()); } } /** * Returns bytes for connection. * * @param aConnection * @return bytes * @throws java.io.IOException */ public static byte[] getBytes(URLConnection aConnection) throws IOException { InputStream stream = aConnection.getInputStream(); // Get stream for connection byte bytes[] = getBytes(stream); // Get bytes for stream stream.close(); // Close stream return bytes; // Return bytes } /** * Returns bytes for an input stream. * * @param aStream * @return bytes * @throws java.io.IOException */ public static byte[] getBytes(InputStream aStream) throws IOException { ByteArrayOutputStream bs = new ByteArrayOutputStream(); byte chunk[] = new byte[8192]; for (int len = aStream.read(chunk, 0, 8192); len > 0; len = aStream.read(chunk, 0, 8192)) { bs.write(chunk, 0, len); } return bs.toByteArray(); } private static File getJarFile() throws URISyntaxException { System.out .println(JMupenUpdater.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()); return new File(JMupenUpdater.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()); } public static boolean getUpdateAvailable() { return update_available; } public static void installUpdate() { try { String digest = MD5ForFile.getDigest(new FileInputStream(updatePackage), 2048); System.out.println("DIGEST UPDATED PACK: " + digest); System.out.println("DIGEST ONLINE: " + MD5ForFile.getMd5FromUrl(new URL(Md5URL).openConnection())); if (!digest.trim().equals(MD5ForFile.getMd5FromUrl(new URL(Md5URL).openConnection()).trim())) { System.err.println("Download failed, removing update file."); JMupenGUI.getInstance().showError("Download failed - MD5 Check", "MD5 Check failed, not installing the update."); boolean isDeleted = updatePackage.delete(); if (!isDeleted) { JMupenGUI.getInstance().showError("Can't delete temp file", "Please manually delete file at " + updatePackage.getAbsolutePath()); } return; } } catch (FileNotFoundException e) { System.err.println("File not found. Nothing to install."); return; } catch (Exception e) { System.err.println( "Almost impossible error (malformed MD5 url or IO problem). " + e.getLocalizedMessage()); } boolean deleted = jarFile.delete(); System.out.println("Deleted jar? " + deleted); if (!deleted) { JMupenUtils.extractJar(jarFile, tmpDir); JMupenUpdater.startWinUpdaterApplication(); } try { FileUtils.moveFile(updatePackage, jarFile); JMupenUpdater.restartApplication(); } catch (IOException ex) { System.err.println("Error moving file. You can find updated file at " + JMupenUtils.getConfigDir() + " Full mess: " + ex.getLocalizedMessage()); JMupenGUI.getInstance().showError("Error updating JMupen.", "I couldn't move update file in place. You can find the app file in " + JMupenUtils.getConfigDir() + " folder."); } } public static void restartApplication() { final String javaBin; if (JMupenUtils.getOs().equalsIgnoreCase("win")) { javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java.exe"; } else { javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; } File currentJar = null; try { currentJar = getJarFile(); } catch (URISyntaxException ex) { System.err.println("Malformed JAR URL " + ex.getLocalizedMessage()); } if (currentJar == null) { return; } /* is it a jar file? */ if (!currentJar.getName().endsWith(".jar")) { return; } /* Build command: java -jar application.jar */ final ArrayList<String> command = new ArrayList<String>(); command.add(javaBin); command.add("-jar"); command.add(currentJar.getPath()); final ProcessBuilder builder = new ProcessBuilder(command); try { builder.start(); } catch (IOException ex) { System.err.println("Error restarting app. " + ex.getLocalizedMessage()); } System.exit(0); } public static void startWinUpdaterApplication() { final String javaBin; javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java.exe"; File updaterJar = new File(tmpDir.getAbsolutePath() + File.separator + "bin" + File.separator + "win" + File.separator + "JMupenWinupdater.jar"); File currentJarPathTxt = new File( tmpDir.getAbsolutePath() + File.separator + "bin" + File.separator + "currentjar.txt"); try { FileUtils.writeStringToFile(currentJarPathTxt, getJarFile().getAbsolutePath()); } catch (IOException e) { System.err.println("Error writing jar filepath " + e.getLocalizedMessage()); JMupenGUI.getInstance().showError("Error writing jar filepath to txt", e.getLocalizedMessage()); } catch (URISyntaxException ex) { System.err.println("Error writing jar filepath " + ex.getLocalizedMessage()); } if (!updaterJar.exists()) { JMupenGUI.getInstance().showError("WinUpdater not found", "in folder: " + updaterJar.getAbsolutePath()); return; } /* is it a jar file? */ if (!updaterJar.getName().endsWith(".jar")) { JMupenGUI.getInstance().showError("WinUpdater does not end with .jar????", updaterJar.getAbsolutePath()); return; } /* Build command: java -jar application.jar */ final ArrayList<String> command = new ArrayList<String>(); command.add(javaBin); command.add("-jar"); command.add(updaterJar.getPath()); final ProcessBuilder builder = new ProcessBuilder(command); try { builder.start(); } catch (IOException ex) { System.err.println("Error starting updater. " + ex.getLocalizedMessage()); JMupenGUI.getInstance().showError("Error starting updater", ex.getLocalizedMessage()); } System.gc(); System.exit(0); } private static void setUpdateAvailable(boolean b) { update_available = b; } /** * Writes the given bytes (within the specified range) to the given file. * * @param aFile File where bytes will be written to * @param theBytes The bytes to write * @throws java.io.IOException */ public static void writeBytes(File aFile, byte theBytes[]) throws IOException { if (theBytes == null) { aFile.delete(); return; } FileOutputStream fileStream = new FileOutputStream(aFile); fileStream.write(theBytes); fileStream.close(); } }