/*
- * JIMS ( http://forge.scilab.org/index.php/p/JIMS/ ) - This file is a part of JIMS
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2010 - 2011 - Calixte DENIZET <calixte@contrib.scilab.org>
*
* This file must be used under the terms of the CeCILL.
package org.scilab.modules.external_objects_java;
import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
-import java.net.URLClassLoader;
import java.net.URI;
+import java.net.URLClassLoader;
import java.net.URL;
import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
import java.util.ServiceLoader;
import java.util.logging.Level;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
public class ScilabJavaCompiler {
private static final String JAVACOMPILER = "javax.tools.JavaCompiler";
- private static final String binpath = System.getProperty("java.io.tmpdir") + File.separator + "JIMS" + File.separator + "bin";
+ private static final String BINPATH = System.getProperty("java.io.tmpdir") + File.separator + "JIMS" + File.separator + "bin";
private static JavaCompiler compiler;
static {
new File(System.getProperty("java.io.tmpdir") + File.separator + "JIMS").mkdir();
- new File(binpath).mkdir();
+ new File(BINPATH).mkdir();
try {
- URL binURL = new File(binpath).toURI().toURL();
+ URL binURL = new File(BINPATH).toURI().toURL();
addURLToClassPath(binURL);
} catch (MalformedURLException e) {
System.err.println(e);
}
if (compiler == null) {
- throw new ScilabJavaException("No java compiler in the classpath\nCheck for tools.jar (comes from JDK) or ecj-3.6.x.ajr (Eclipse Compiler for Java)");
+ throw new ScilabJavaException("No java compiler in the classpath\nCheck for tools.jar (comes from JDK) or ecj-3.6.x.jar (Eclipse Compiler for Java)");
}
}
}
public static int compileCode(String className, String[] code) throws ScilabJavaException {
findCompiler();
- if (ScilabJavaObject.debug) {
- ScilabJavaObject.logger.log(Level.INFO, "Compilation of class \'" + className + "\'");
+ DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
+ StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), null);
+ ClassFileManager manager = new ClassFileManager(stdFileManager);
+ List<SimpleJavaFileObject> compilationUnits = new ArrayList<SimpleJavaFileObject>();
+ boolean isFile = true;
+ SourceString sourceString = null;
+ for (String s : code) {
+ File f = new File(s);
+ if (!f.exists() || !f.canRead()) {
+ isFile = false;
+ break;
+ }
}
- DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
+ if (isFile) {
+ for (String s : code) {
+ File f = new File(s);
+ compilationUnits.add(new SourceFile(f));
+ }
+ } else {
+ sourceString = new SourceString(className, code);
+ compilationUnits.add(sourceString);
+ }
- SourceString file = new SourceString(className, code);
- StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), null);
- Iterable <? extends JavaFileObject > compilationUnits = Arrays.asList(file);
- String[] compileOptions = new String[] {"-d", binpath} ;
+ String[] compileOptions = new String[] {"-d", BINPATH} ;
Iterable<String> options = Arrays.asList(compileOptions);
- CompilationTask task = compiler.getTask(null, stdFileManager, diagnostics, options, null, compilationUnits);
-
+ CompilationTask task = compiler.getTask(null, manager, diagnostics, options, null, compilationUnits);
boolean success = task.call();
- StringBuffer buf = new StringBuffer();
- for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
- buf.append(diagnostic.toString());
- buf.append("\n");
- }
if (success) {
- return ScilabClassLoader.loadJavaClass(className, true);
+ if (isFile) {
+ return -1;
+ } else {
+ return ScilabClassLoader.loadJavaClass(manager.className, true);
+ }
} else {
+ StringBuffer buf = new StringBuffer();
+ for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
+ buf.append(diagnostic.toString());
+ buf.append("\n");
+ }
+
throw new ScilabJavaException(buf.toString());
}
}
private final String code;
private SourceString(String className, String[] code) {
- super(new File(binpath + "/" + className.replace('.', '/') + Kind.SOURCE.extension).toURI(), Kind.SOURCE);
+ super(new File(BINPATH + "/" + className.replace('.', '/') + Kind.SOURCE.extension).toURI(), Kind.SOURCE);
StringBuffer buf = new StringBuffer();
for (String str : code) {
return code;
}
}
+
+ /**
+ * Inner class to handle String as File
+ */
+ private static class SourceFile extends SimpleJavaFileObject {
+
+ final File f;
+
+ private SourceFile(File f) {
+ super(f.toURI(), Kind.SOURCE);
+ this.f = f;
+ }
+
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ try {
+ FileReader reader = new FileReader(f);
+ char[] buffer = new char[1024];
+ StringBuffer sb = new StringBuffer();
+ int r;
+
+ while ((r = reader.read(buffer, 0, 1024)) != -1) {
+ sb.append(buffer, 0, r);
+ }
+
+ reader.close();
+
+ return sb;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ }
+
+ private static class ClassFileManager extends ForwardingJavaFileManager {
+
+ String className;
+
+ public ClassFileManager(StandardJavaFileManager standardManager) {
+ super(standardManager);
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
+ if (sibling instanceof SourceString) {
+ this.className = className.replace('/', '.');
+ }
+
+ if (ScilabJavaObject.debug) {
+ ScilabJavaObject.logger.log(Level.INFO, "Compilation of class \'" + className + "\'");
+ }
+
+ return super.getJavaFileForOutput(location, className, kind, sibling);
+ }
+ }
}