package ij.plugin; import ij.*; import ij.gui.*; import ij.util.Tools; import java.io.*; import java.net.*; import java.util.*; import java.lang.reflect.*; /** This plugin implements the Help/Update ImageJ command. */ public class ImageJ_Updater implements PlugIn { public void run(String arg) { if (arg.equals("menus")) {updateMenus(); return;} if (IJ.getApplet()!=null) return; //File file = new File(Prefs.getHomeDir() + File.separator + "ij.jar"); //if (isMac() && !file.exists()) // file = new File(Prefs.getHomeDir() + File.separator + "ImageJ.app/Contents/Resources/Java/ij.jar"); URL url = getClass().getResource("/ij/IJ.class"); String ij_jar = url == null ? null : url.toString().replaceAll("%20", " "); if (ij_jar==null || !ij_jar.startsWith("jar:file:")) { error("Could not determine location of ij.jar"); return; } int exclamation = ij_jar.indexOf('!'); ij_jar = ij_jar.substring(9, exclamation); if (IJ.debugMode) IJ.log("Updater: "+ij_jar); File file = new File(ij_jar); if (!file.exists()) { error("File not found: "+file.getPath()); return; } if (!file.canWrite()) { String msg = "No write access: "+file.getPath(); if (IJ.isVista()) msg += Prefs.vistaHint; error(msg); return; } String[] list = openUrlAsList(IJ.URL+"/download/jars/list.txt"); int count = list.length + 2; String[] versions = new String[count]; String[] urls = new String[count]; String uv = getUpgradeVersion(); if (uv==null) return; versions[0] = "v"+uv; urls[0] = IJ.URL+"/upgrade/ij.jar"; if (versions[0]==null) return; for (int i=1; i<count-1; i++) { String version = list[i-1]; versions[i] = version.substring(0,version.length()-1); // remove letter urls[i] = IJ.URL+"/download/jars/ij" +version.substring(1,2)+version.substring(3,6)+".jar"; } versions[count-1] = "daily build"; urls[count-1] = IJ.URL+"/ij.jar"; int choice = showDialog(versions); if (choice==-1) return; if (!versions[choice].startsWith("daily") && versions[choice].compareTo("v1.39")<0 && Menus.getCommands().get("ImageJ Updater")==null) { String msg = "This command is not available in versions of ImageJ prior\n"+ "to 1.39 so you will need to install the plugin version at\n"+ "<"+IJ.URL+"/plugins/imagej-updater.html>."; if (!IJ.showMessageWithCancel("Update ImageJ", msg)) return; } byte[] jar = getJar(urls[choice]); if (jar==null) { error("Unable to download ij.jar from "+urls[choice]); return; } //file.renameTo(new File(file.getParent()+File.separator+"ij.bak")); if (version().compareTo("1.37v")>=0) Prefs.savePreferences(); // if (!renameJar(file)) return; // doesn't work on Vista saveJar(file, jar); if (choice<count-1) // force macro Function Finder to download fresh list new File(IJ.getDirectory("macros")+"functions.html").delete(); System.exit(0); } int showDialog(String[] versions) { GenericDialog gd = new GenericDialog("ImageJ Updater"); gd.addChoice("Upgrade To:", versions, versions[0]); String msg = "You are currently running v"+version()+".\n"+ " \n"+ "If you click \"OK\", ImageJ will quit\n"+ "and you will be running the upgraded\n"+ "version after you restart ImageJ.\n"; gd.addMessage(msg); gd.showDialog(); if (gd.wasCanceled()) return -1; else return gd.getNextChoiceIndex(); } String getUpgradeVersion() { String url = IJ.URL+"/notes.html"; String notes = openUrlAsString(url, 20); if (notes==null) { error("Unable to connect to "+IJ.URL+". You\n" +"may need to use the Edit>Options>Proxy Settings\n" +"command to configure ImageJ to use a proxy server."); return null; } int index = notes.indexOf("Version "); if (index==-1) { error("Release notes are not in the expected format"); return null; } String version = notes.substring(index+8, index+13); return version; } String openUrlAsString(String address, int maxLines) { StringBuffer sb; try { URL url = new URL(address); InputStream in = url.openStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); sb = new StringBuffer(); int count = 0; String line; while ((line=br.readLine())!=null && count++<maxLines) sb.append (line + "\n"); in.close (); } catch (IOException e) {sb = null;} return sb!=null?new String(sb):null; } byte[] getJar(String address) { byte[] data; boolean gte133 = version().compareTo("1.33u")>=0; try { URL url = new URL(address); IJ.showStatus("Connecting to "+IJ.URL); URLConnection uc = url.openConnection(); int len = uc.getContentLength(); if (len<=0) return null; String name = address.endsWith("ij/ij.jar")?"daily build":"ij.jar"; IJ.showStatus("Downloading ij.jar ("+IJ.d2s((double)len/1048576,1)+"MB)"); InputStream in = uc.getInputStream(); data = new byte[len]; int n = 0; while (n < len) { int count = in.read(data, n, len - n); if (count<0) throw new EOFException(); n += count; if (gte133) IJ.showProgress(n, len); } in.close(); } catch (IOException e) { return null; } return data; } /*Changes the name of ij.jar to ij-old.jar boolean renameJar(File f) { File backup = new File(Prefs.getHomeDir() + File.separator + "ij-old.jar"); if (backup.exists()) { if (!backup.delete()) { error("Unable to delete backup: "+backup.getPath()); return false; } } if (!f.renameTo(backup)) { error("Unable to rename to ij-old.jar: "+f.getPath()); return false; } return true; } */ void saveJar(File f, byte[] data) { try { FileOutputStream out = new FileOutputStream(f); out.write(data, 0, data.length); out.close(); } catch (IOException e) { } } String[] openUrlAsList(String address) { IJ.showStatus("Connecting to "+IJ.URL); Vector v = new Vector(); try { URL url = new URL(address); InputStream in = url.openStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line; while (true) { line = br.readLine(); if (line==null) break; if (!line.equals("")) v.addElement(line); } br.close(); } catch(Exception e) { } String[] lines = new String[v.size()]; v.copyInto((String[])lines); IJ.showStatus(""); return lines; } // Use reflection to get version since early versions // of ImageJ do not have the IJ.getVersion() method. String version() { String version = ""; try { Class ijClass = ImageJ.class; Field field = ijClass.getField("VERSION"); version = (String)field.get(ijClass); }catch (Exception ex) {} return version; } boolean isMac() { String osname = System.getProperty("os.name"); return osname.startsWith("Mac"); } void error(String msg) { IJ.error("ImageJ Updater", msg); } void updateMenus() { if (IJ.debugMode) { long start = System.currentTimeMillis(); Menus.updateImageJMenus(); IJ.log("Refresh Menus: "+(System.currentTimeMillis()-start)+" ms"); } else Menus.updateImageJMenus(); } }