Package ij.plugin

Source Code of ij.plugin.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 final int TARGET14=0, TARGET15=1, TARGET16=2,  TARGET17=3;
  private static final String[] targets = {"1.4", "1.5", "1.6", "1.7"};
  private static final String TARGET_KEY = "javac.target";
  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;
  private static int target = (int)Prefs.get(TARGET_KEY, TARGET15);

  public void run(String arg) {
    if (arg.equals("edit"))
      edit();
    else if (arg.equals("options"))
      showDialog();
    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 (!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("Unable to find the javac compiler, which comes with the Windows and \n"
          +"Linux versions of ImageJ that include Java in the ImageJ/jre folder.\n"
           +" \n"
           +"   java.home: "+System.getProperty("java.home")
           );
       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.isJava15()) {
      validateTarget();
      v.addElement("-source");
      v.addElement(targets[target]);
      v.addElement("-target");
      v.addElement(targets[target]);
      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||list[i].equals("loci_tools.jar"))) {
        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.indexOf("1 warning")>0 && s.indexOf("[deprecation] show()")>0)
      errors = false;
    //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 = IJ.getDirectory("plugins");
      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")||lcName.endsWith(".js"))) {
          IJ.error("File name must end with \".java\", \".txt\" or \".js\".");
          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);
  }
 
  public void showDialog() {
    validateTarget();
    GenericDialog gd = new GenericDialog("Compile and Run");
    gd.addChoice("Target: ", targets, targets[target]);
    gd.setInsets(15,5,0);
    gd.addCheckbox("Generate debugging info (javac -g)", generateDebuggingInfo);
        gd.addHelp(IJ.URL+"/docs/menus/edit.html#compiler");
    gd.showDialog();
    if (gd.wasCanceled()) return;
    target = gd.getNextChoiceIndex();   
    generateDebuggingInfo = gd.getNextBoolean();
    validateTarget();
  }
 
  void validateTarget() {
    if (target<0 || target>TARGET17)
      target = TARGET15;
    if ((target>TARGET16&&!IJ.isJava17()) || (target>TARGET15&&!IJ.isJava16()))
      target = TARGET15;
    if (!IJ.isJava15())
      target = TARGET14;
    Prefs.set(TARGET_KEY, target);
  }
 
}


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 {
      IJ.resetEscape();
      IJ.runPlugIn("ij.plugin.ClassChecker", "");
      ImageJ ij = IJ.getInstance();
      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;
      IJ.handleException(e);
    }
  }

}
TOP

Related Classes of ij.plugin.Compiler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.