chiark / gitweb /
Initial commit of Yarrg code
[jarrg-owen.git] / src / com / tedpearson / util / update / Updater.java
diff --git a/src/com/tedpearson/util/update/Updater.java b/src/com/tedpearson/util/update/Updater.java
new file mode 100644 (file)
index 0000000..cd396c5
--- /dev/null
@@ -0,0 +1,189 @@
+package com.tedpearson.util.update;
+
+import java.net.*;
+import java.io.*;
+import java.util.prefs.*;
+import java.awt.Component;
+import javax.swing.JOptionPane;
+import javax.swing.*;
+
+/*
+       TODO:
+       show update window with progress bar when updating (optionally)
+*/
+
+public class Updater {
+       private int version = -1;
+       private URL downloadURL;
+       private static Updater updater = new Updater();
+       
+       public static Updater getUpdater() {
+               return updater;
+       }
+       
+       public boolean checkForUpdate(
+                       Component parentComponent,
+                       String updateUrl,
+                       int currentVersion) {
+               return checkForUpdate(parentComponent, updateUrl, "this program", currentVersion, true);
+       }
+       
+       
+       /**
+       * Just check to see if there is an update.
+       */
+       public boolean checkForUpdate(
+                       Component parentComponent,
+                       String updateUrl,
+                       String program,
+                       int currentVersion,
+                       boolean promptUser) {
+               String node = "com/tedpearson/update";
+               Preferences prefs = Preferences.userRoot().node(node);
+               String update = prefs.get(updateUrl,"");
+               if(update.equals("Never")) {
+                       return false;
+               }
+               if(!update.equals("Yes")) {
+                       if(!promptUser) {
+                               return false;
+                       }
+                       // first, confirm user wants to allow updates
+                       int option = JOptionPane.showOptionDialog(parentComponent,
+                               "Do you want to let " + program + " check for updates when it opens?",
+                               "Check for Updates?",
+                               0, JOptionPane.QUESTION_MESSAGE,
+                               null, new String[] {"Yes","This Time","Not Now","Never"},"Yes");
+                       switch(option) {
+                               case 2:
+                                       return false;
+                               case 3:
+                                       prefs.put(updateUrl,"Never");
+                                       return false;
+                               case 0:
+                                       prefs.put(updateUrl,"Yes");
+                               case 1:
+                       }
+               }
+               // query the server to check the version number
+               accessVersion(parentComponent, updateUrl);
+               // System.out.println(version+","+currentVersion);
+               if(version > currentVersion) {
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+       
+       public void checkAndUpdate(
+                       Component parentComponent,
+                       String updateUrl,
+                       String program,
+                       int currentVersion,
+                       boolean promptUser,
+                       String jar) {
+               if(checkForUpdate(parentComponent, updateUrl, program, currentVersion, promptUser)) {
+                       updateJar(parentComponent, updateUrl, currentVersion, promptUser, jar);
+               }
+       }
+       
+       public void checkAndUpdate(
+                       Component parentComponent,
+                       String updateUrl,
+                       int currentVersion) {
+               if(checkForUpdate(parentComponent, updateUrl, currentVersion)) {
+                       updateJar(parentComponent, updateUrl, currentVersion);
+               }
+       }
+       
+       public void updateJar(
+                       Component parentComponent,
+                       String updateUrl,
+                       int currentVersion) {
+               updateJar(parentComponent, updateUrl, currentVersion, true, null);
+       }
+       
+       public void updateJar(
+                       Component parentComponent,
+                       String updateUrl,
+                       int currentVersion,
+                       boolean promptUser,
+                       String jar) {
+               try {
+                       accessVersion(parentComponent, updateUrl);
+                       // download new version
+                       File temp = File.createTempFile("com.tedpearson.updater.download",null);
+                       temp.deleteOnExit();
+                       URLConnection conn = downloadURL.openConnection();
+                       ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(
+                               parentComponent,
+                               "Downloading program update",
+                               conn.getInputStream()
+                       );
+                       ProgressMonitor pm = pmis.getProgressMonitor();
+                       pm.setMillisToDecideToPopup(0);
+                       pm.setMillisToPopup(0);
+                       if(!promptUser) {
+                               pm.setMillisToDecideToPopup(Integer.MAX_VALUE);
+                               pm.setMillisToPopup(Integer.MAX_VALUE);
+                       }
+                       pm.setMaximum(conn.getHeaderFieldInt("Content-Length",0));
+                       copyFile(pmis, new FileOutputStream(temp));
+                       // replace old with new.
+                       if(jar == null) {
+                               jar = getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
+                       }       
+                       jar = jar.replaceAll("%20"," ");
+                       copyFile(new FileInputStream(temp), new FileOutputStream(new File(jar)));
+                       // remove temp file
+                       temp.delete();
+                       // launch new version and quit this one.
+                       ProcessBuilder pb = new ProcessBuilder("java","-jar",jar);
+                       pb.start();
+                       System.exit(0);
+                       // no new version
+               } catch(Exception e) {
+                       // errors.
+                       e.printStackTrace();
+                       // show error here.
+                       if(promptUser) {
+                               JOptionPane.showMessageDialog(parentComponent, "There was an error while trying to update.",
+                                       "Error", JOptionPane.ERROR_MESSAGE);
+                       }
+               }
+       }
+       
+       private void accessVersion(Component parentComponent, String updateUrl) {
+               if(version != -1) return;
+               try {
+                       URL url = new URL(updateUrl);
+                       BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
+                       version = Integer.parseInt(br.readLine());
+                       downloadURL = new URL(br.readLine());
+               } catch(Exception e) {
+                       // errors.
+                       e.printStackTrace();
+                       // show error here.
+                       JOptionPane.showMessageDialog(parentComponent, "There was an error while trying to update.",
+                               "Error", JOptionPane.ERROR_MESSAGE);
+               }
+       }
+       
+       /**
+       *       Utility method to copy a file. I can't believe java doesn't have anything
+       *       built-in to do something this simple with less code. Other than channels, that is.
+       *       
+       *       @param in stream to read file from
+       *       @param out stream to write file to
+       */
+       public static void copyFile(InputStream in, OutputStream out) throws IOException {
+               byte[] buf = new byte[1024];
+               int len;
+               while ((len = in.read(buf)) > 0) {
+                       out.write(buf, 0, len);
+                       
+               }
+               in.close();
+               out.close();
+       }
+}
\ No newline at end of file