simplify janino compiler for https://issues.apache.org/jira/browse/JCI-53
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jci/trunk@565501 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompiler.java b/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompiler.java
index 6fcd6c3..3df7c76 100644
--- a/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompiler.java
+++ b/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompiler.java
@@ -17,10 +17,11 @@
package org.apache.commons.jci.compilers;
-import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -33,24 +34,20 @@
import org.apache.commons.jci.utils.ConversionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.codehaus.janino.ClassLoaderIClassLoader;
+import org.codehaus.janino.CachingJavaSourceClassLoader;
import org.codehaus.janino.CompileException;
import org.codehaus.janino.DebuggingInformation;
-import org.codehaus.janino.Descriptor;
-import org.codehaus.janino.IClass;
-import org.codehaus.janino.IClassLoader;
-import org.codehaus.janino.Java;
+import org.codehaus.janino.FilterWarningHandler;
import org.codehaus.janino.Location;
-import org.codehaus.janino.Parser;
-import org.codehaus.janino.Scanner;
-import org.codehaus.janino.UnitCompiler;
import org.codehaus.janino.WarningHandler;
-import org.codehaus.janino.Scanner.LocatedException;
import org.codehaus.janino.UnitCompiler.ErrorHandler;
-import org.codehaus.janino.util.ClassFile;
+import org.codehaus.janino.util.StringPattern;
+import org.codehaus.janino.util.resource.Resource;
+import org.codehaus.janino.util.resource.ResourceCreator;
+import org.codehaus.janino.util.resource.ResourceFinder;
/**
- * @author art@gramlich-net.com
+ * @author tcurdt
*/
public final class JaninoJavaCompiler extends AbstractJavaCompiler {
@@ -66,100 +63,138 @@
defaultSettings = pSettings;
}
- private class CompilingIClassLoader extends IClassLoader {
+ private final static class JciResource implements Resource {
- private final Map types = new HashMap();
- private final ResourceReader resourceReader;
- private final Map classes;
- private final Collection problems = new ArrayList();
+ private final String name;
+ private final byte[] bytes;
+
+ public JciResource( final String pName, final byte[] pBytes ) {
+ name = pName;
+ bytes = pBytes;
+ }
+
+ public String getFileName() {
+ return name;
+ }
- private CompilingIClassLoader(final ResourceReader pResourceReader, final Map pClasses, final ClassLoader classLoader) {
- super( new ClassLoaderIClassLoader( classLoader ) );
- resourceReader = pResourceReader;
- classes = pClasses;
- super.postConstruct();
- }
+ public long lastModified() {
+ return 0;
+ }
- protected Collection getProblems() {
- return problems;
- }
-
- protected IClass findIClass(final String pType) {
- final String className = Descriptor.toClassName(pType);
- if (types.containsKey(pType)) {
- return (IClass) types.get(pType);
- }
-
- // FIXME: should not be tied to the extension
- final String resourceNameFromClass = className.replace('.', '/') + ".java";
-
- final byte[] content = resourceReader.getBytes(resourceNameFromClass);
- if (content == null) {
- return null;
- }
- final Reader reader = new BufferedReader(new StringReader(new String(content)));
- Scanner scanner = null;
- try {
- scanner = new Scanner(resourceNameFromClass, reader);
- final Java.CompilationUnit unit = new Parser(scanner).parseCompilationUnit();
- final UnitCompiler uc = new UnitCompiler(unit, this);
- uc.setCompileErrorHandler(new ErrorHandler() {
- public void handleError(final String pMessage, final Location pOptionalLocation) throws CompileException {
- final CompilationProblem problem = new JaninoCompilationProblem(pOptionalLocation, pMessage, true);
- if (problemHandler != null) {
- problemHandler.handle(problem);
- }
- problems.add(problem);
- }
- });
- uc.setWarningHandler(new WarningHandler() {
- public void handleWarning(final String pHandle, final String pMessage, final Location pOptionalLocation) {
- final CompilationProblem problem = new JaninoCompilationProblem(pOptionalLocation, pMessage, false);
- if (problemHandler != null) {
- problemHandler.handle(problem);
- }
- problems.add(problem);
- }
- });
- log.debug("compile " + className);
- final ClassFile[] classFiles = uc.compileUnit(DebuggingInformation.ALL);
- for (int i = 0; i < classFiles.length; i++) {
- log.debug("compiled " + classFiles[i].getThisClassName());
- classes.put(classFiles[i].getThisClassName(), classFiles[i].toByteArray());
- }
- final IClass ic = uc.findClass(className);
- if (null != ic) {
- types.put(pType, ic);
- }
- return ic;
- } catch (final LocatedException e) {
- problems.add(new JaninoCompilationProblem(e));
- } catch (final IOException e) {
- problems.add(new JaninoCompilationProblem(resourceNameFromClass, "IOException:" + e.getMessage(), true));
- } catch (final Exception e) {
- problems.add(new JaninoCompilationProblem(resourceNameFromClass, "Exception:" + e.getMessage(), true));
- } finally {
- if (scanner != null) {
- try {
- scanner.close();
- } catch (IOException e) {
- log.error("IOException occured while compiling " + className, e);
- }
- }
- }
- return null;
- }
+ public InputStream open() throws IOException {
+ return new ByteArrayInputStream(bytes);
+ }
}
+ private final class JciOutputStream extends ByteArrayOutputStream {
+
+ private final String name;
+ private final ResourceStore store;
+
+ public JciOutputStream( final String pName, final ResourceStore pStore ) {
+ name = pName;
+ store = pStore;
+ }
+
+ public void close() throws IOException {
+ super.close();
+
+ final byte[] bytes = toByteArray();
+
+ log.debug("writing " + name + " (" + bytes.length + ")");
+
+ store.write(name, bytes);
+ }
+ }
+
public CompilationResult compile( final String[] pSourceNames, final ResourceReader pResourceReader, final ResourceStore pStore, final ClassLoader pClassLoader, final JavaCompilerSettings pSettings ) {
+ final Collection problems = new ArrayList();
+
+ final CachingJavaSourceClassLoader cl = new CachingJavaSourceClassLoader(
+ pClassLoader,
+ new ResourceFinder() {
+
+ public Resource findResource( final String pSourceName ) {
+ final String name = pSourceName;
+ final byte[] bytes = pResourceReader.getBytes(name);
+
+ if (bytes == null) {
+ log.debug("failed to find source " + name);
+ return null;
+ }
+
+ log.debug("reading " + name + " (" + bytes.length + ")");
+
+ return new JciResource(pSourceName, bytes);
+ }
+
+ },
+ pSettings.getSourceEncoding(),
+ new ResourceFinder() {
+
+ public Resource findResource( final String pResourceName ) {
+ final String name = pResourceName;
+ final byte[] bytes = pStore.read(name);
+
+ if (bytes == null) {
+ log.debug("failed to find " + name);
+ return null;
+ }
+
+ log.debug("reading " + name + " (" + bytes.length + ")");
+
+ return new JciResource(pResourceName, bytes);
+ }
+
+ },
+ new ResourceCreator() {
+
+ public OutputStream createResource( final String pResourceName ) throws IOException {
+ return new JciOutputStream(pResourceName, pStore);
+ }
+
+ public boolean deleteResource( final String pResourceName ) {
+ log.debug("removing " + pResourceName);
+
+ pStore.remove(pResourceName);
+ return true;
+ }
+
+ },
+ pSettings.isDebug()?DebuggingInformation.ALL:DebuggingInformation.NONE
+ );
+
+
+ cl.setCompileErrorHandler(new ErrorHandler() {
+ public void handleError( final String pMessage, final Location pLocation ) throws CompileException {
+ final CompilationProblem problem = new JaninoCompilationProblem(pLocation.getFileName(), pLocation, pMessage, true);
+ if (problemHandler != null) {
+ problemHandler.handle(problem);
+ }
+ problems.add(problem);
+ }
+ });
+
+ final StringPattern[] pattern = StringPattern.PATTERNS_NONE;
+ cl.setWarningHandler(new FilterWarningHandler(pattern, new WarningHandler() {
+ public void handleWarning( final String pHandle, final String pMessage, final Location pLocation ) {
+ final CompilationProblem problem = new JaninoCompilationProblem(pLocation.getFileName(), pLocation, pMessage, false);
+ if (problemHandler != null) {
+ problemHandler.handle(problem);
+ }
+ problems.add(problem);
+ }
+ }));
+
+
+
final Map classFilesByName = new HashMap();
- final CompilingIClassLoader icl = new CompilingIClassLoader(pResourceReader, classFilesByName, pClassLoader);
for (int i = 0; i < pSourceNames.length; i++) {
- log.debug("compiling " + pSourceNames[i]);
+ log.debug("compiling " + pSourceNames[i]);
try {
- icl.loadIClass(Descriptor.fromClassName(ConversionUtils.convertResourceToClassName(pSourceNames[i])));
+ cl.loadClass(ConversionUtils.convertResourceToClassName(pSourceNames[i]));
} catch (ClassNotFoundException e) {
log.error(e);
}
@@ -172,7 +207,6 @@
pStore.write(ConversionUtils.convertClassToResourcePath(clazzName), (byte[])entry.getValue());
}
- final Collection problems = icl.getProblems();
final CompilationProblem[] result = new CompilationProblem[problems.size()];
problems.toArray(result);
return new CompilationResult(result);
diff --git a/core/src/main/java/org/apache/commons/jci/stores/ResourceStore.java b/core/src/main/java/org/apache/commons/jci/stores/ResourceStore.java
index 912f213..196f146 100644
--- a/core/src/main/java/org/apache/commons/jci/stores/ResourceStore.java
+++ b/core/src/main/java/org/apache/commons/jci/stores/ResourceStore.java
@@ -25,5 +25,6 @@
void write( final String pResourceName, final byte[] pResourceData );
byte[] read( final String pResourceName );
+ //FIXME: return the result of the remove
void remove( final String pResourceName );
}