|
Compiler |
|
package ij.plugin; import java.awt.*; import java.io.*; import java.util.*; import ij.*; import ij.gui.*; import ij.io.*; import ij.util.*; import ij.plugin.frame.Editor; import ij.text.TextWindow; import java.awt.event.KeyEvent; /** Compiles and runs plugins using the javac compiler. */ public class Compiler implements PlugIn, FilenameFilter { private static com.sun.tools.javac.Main javac; private static ByteArrayOutputStream output; private static String dir, name; private static Editor errors; private static boolean generateDebuggingInfo; public void run(String arg) { if (arg.equals("edit")) edit(); else compileAndRun(arg); } void edit() { if (open("", "Open macro or plugin")) { Editor ed = (Editor)IJ.runPlugIn("ij.plugin.frame.Editor", ""); if (ed!=null) ed.open(dir, name); } } void compileAndRun(String path) { if (IJ.altKeyDown()) { IJ.setKeyUp(KeyEvent.VK_ALT); GenericDialog gd = new GenericDialog("Compile and Run"); gd.addCheckbox("Generate Debugging Info (javac -g)", generateDebuggingInfo); gd.showDialog(); if (gd.wasCanceled()) return; generateDebuggingInfo = gd.getNextBoolean(); } if (!open(path, "Compile and Run Plugin...")) return; if (name.endsWith(".class")) { runPlugin(name.substring(0, name.length()-1)); return; } if (!isJavac()) return; if (compile(dir+name)) runPlugin(name); } boolean isJavac() { try { if (javac==null) { output = new ByteArrayOutputStream(4096); javac=new com.sun.tools.javac.Main(); } } catch (NoClassDefFoundError e) { IJ.error("This JVM does not include the javac compiler.\n" +"Javac is included with the Windows and Linux\n" +"versions of ImageJ that are bundled with Java."); return false; } return true; } boolean compile(String path) { IJ.showStatus("compiling: "+path); output.reset(); String classpath = getClassPath(path); Vector v = new Vector(); if (generateDebuggingInfo) v.addElement("-g"); if (IJ.isJava16()) { // needed so plugin will run on Java 1.5 v.addElement("-source"); v.addElement("1.5"); v.addElement("-target"); v.addElement("1.5"); } if (IJ.isJava15()) v.addElement("-Xlint:unchecked"); v.addElement("-deprecation"); v.addElement("-classpath"); v.addElement(classpath); v.addElement(path); String[] arguments = new String[v.size()]; v.copyInto((String[])arguments); if (IJ.debugMode) { String str = "javac"; for (int i=0; i<arguments.length; i++) str += " "+arguments[i]; IJ.log(str); } boolean compiled = javac.compile(arguments, new PrintWriter(output))==0; String s = output.toString(); boolean errors = (!compiled || areErrors(s)); if (errors) showErrors(s); else IJ.showStatus("done"); return compiled; } // Returns a string containing the Java classpath, // the path to the directory containing the plugin, // and paths to any .jar files in the plugins folder. String getClassPath(String path) { long start = System.currentTimeMillis(); StringBuffer sb = new StringBuffer(); sb.append(System.getProperty("java.class.path")); File f = new File(path); if (f!=null) // add directory containing file to classpath sb.append(File.pathSeparator + f.getParent()); String pluginsDir = Menus.getPlugInsPath(); if (pluginsDir!=null) addJars(pluginsDir, sb); return sb.toString(); } // Adds .jar files in plugins folder, and subfolders, to the classpath void addJars(String path, StringBuffer sb) { String[] list = null; File f = new File(path); if (f.exists() && f.isDirectory()) list = f.list(); if (list==null) return; if (!path.endsWith(File.separator)) path += File.separator; for (int i=0; i<list.length; i++) { File f2 = new File(path+list[i]); if (f2.isDirectory()) addJars(path+list[i], sb); else if (list[i].endsWith(".jar")&& list[i].indexOf("_")==-1) { sb.append(File.pathSeparator+path+list[i]); if (IJ.debugMode) IJ.log("javac: "+path+list[i]); } } } boolean areErrors(String s) { boolean errors = s!=null && s.length()>0; //if(errors&&s.startsWith("Note:com.sun.tools.javac")&&s.indexOf("error")==-1) // errors = false; return errors; } void showErrors(String s) { if (errors==null || !errors.isVisible()) { errors = (Editor)IJ.runPlugIn("ij.plugin.frame.Editor", ""); errors.setFont(new Font("Monospaced", Font.PLAIN, 12)); } if (errors!=null) errors.display("Errors", s); IJ.showStatus("done (errors)"); } // open the .java source file boolean open(String path, String msg) { boolean okay; String fileName, directory; if (path.equals("")) { if (dir==null) dir = Prefs.getHomeDir(); OpenDialog od = new OpenDialog(msg, dir, name); directory = od.getDirectory(); fileName = od.getFileName(); okay = fileName!=null; String lcName = okay?fileName.toLowerCase(Locale.US):null; if (okay) { if (msg.startsWith("Compile")) { if (!(lcName.endsWith(".java")||lcName.endsWith(".class"))) { IJ.error("File name must end with \".java\" or \".class\"."); okay = false; } } else if (!(lcName.endsWith(".java")||lcName.endsWith(".txt")||lcName.endsWith(".ijm"))) { IJ.error("File name must end with \".java\" or \".txt\"."); okay = false; } } } else { int i = path.lastIndexOf('/'); if (i==-1) i = path.lastIndexOf('\\'); if (i>0) { directory = path.substring(0, i+1); fileName = path.substring(i+1); } else { directory = ""; fileName = path; } okay = true; } if (okay) { name = fileName; dir = directory; Editor.setDefaultDirectory(dir); } return okay; } // only show files with names ending in ".java" // doesn't work with Windows public boolean accept(File dir, String name) { return name.endsWith(".java")||name.endsWith(".macro")||name.endsWith(".txt"); } // run the plugin using a new class loader void runPlugin(String name) { name = name.substring(0,name.length()-5); // remove ".java" new PlugInExecuter(name); } } class PlugInExecuter implements Runnable { private String plugin; private Thread thread; /** Create a new object that runs the specified plugin in a separate thread. */ PlugInExecuter(String plugin) { this.plugin = plugin; thread = new Thread(this, plugin); thread.setPriority(Math.max(thread.getPriority()-2, Thread.MIN_PRIORITY)); thread.start(); } public void run() { try { ImageJ ij = IJ.getInstance(); IJ.resetEscape(); if (ij!=null) ij.runUserPlugIn(plugin, plugin, "", true); } catch(Throwable e) { IJ.showStatus(""); IJ.showProgress(1.0); ImagePlus imp = WindowManager.getCurrentImage(); if (imp!=null) imp.unlock(); String msg = e.getMessage(); if (e instanceof RuntimeException && msg!=null && e.getMessage().equals(Macro.MACRO_CANCELED)) return; CharArrayWriter caw = new CharArrayWriter(); PrintWriter pw = new PrintWriter(caw); e.printStackTrace(pw); String s = caw.toString(); if (IJ.isMacintosh()) s = Tools.fixNewLines(s); new TextWindow("Exception", s, 350, 250); } } }
|
Compiler |
|