![JAR search and dependency download from the Maven repository](/logo.png)
scriptella.driver.janino.CodeCompiler Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2006-2012 The Scriptella Project Team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package scriptella.driver.janino;
import org.codehaus.commons.compiler.LocatedException;
import org.codehaus.janino.ScriptEvaluator;
import scriptella.expression.LineIterator;
import scriptella.spi.Resource;
import scriptella.util.ExceptionUtils;
import scriptella.util.IOUtils;
import java.io.IOException;
import java.io.Reader;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Compiles Janino scripts.
*
* @author Fyodor Kupolov
* @version 1.0
*/
final class CodeCompiler {
private static final Logger LOG = Logger.getLogger(CodeCompiler.class.getName());
private static final boolean DEBUG = LOG.isLoggable(Level.FINE);
//Allowed exceptions to be thrown by a script
private static final Class[] THROWN_EXCEPTIONS = new Class[]{Exception.class};
//Compiled scripts(Static methods) cache
private Map objectCache = new IdentityHashMap();
public JaninoScript compileScript(final Resource resource) {
return (JaninoScript) compile(resource, false);
}
public JaninoQuery compileQuery(final Resource resource) {
return (JaninoQuery) compile(resource, true);
}
private Object compile(final Resource content, final boolean query) {
Object ctx = objectCache.get(content);
if (ctx == null) {
ScriptEvaluator evaluator = new ScriptEvaluator();
//Exception are not required to be handled
evaluator.setThrownExceptions(THROWN_EXCEPTIONS);
evaluator.setParentClassLoader(getClass().getClassLoader());
Class> type = query ? JaninoQuery.class : JaninoScript.class;
evaluator.setExtendedType(type);
evaluator.setStaticMethod(false);
evaluator.setMethodName("execute");
evaluator.setClassName(type.getName() + "_Generated");
if (DEBUG) {
evaluator.setDebuggingInformation(true, true, true);
}
Reader r = null;
try {
r = content.open();
evaluator.cook(content.toString(), r);
} catch (Exception e) {
throw guessErrorStatement(new JaninoProviderException("Compilation failed", e), content);
} finally {
IOUtils.closeSilently(r);
}
Class> cl = evaluator.getMethod().getDeclaringClass();
try {
ctx = cl.newInstance();
} catch (Exception e) {
throw new JaninoProviderException("Unable to instantiate compiled class", e);
}
objectCache.put(content, ctx);
}
return ctx;
}
/**
* Finds error statement which caused compilation error.
*/
private static JaninoProviderException guessErrorStatement(JaninoProviderException pe, Resource r) {
Throwable cause = pe.getCause();
try {
if (cause instanceof LocatedException) {
LocatedException le = (LocatedException) cause;
if (le.getLocation() != null) {
String line = getLine(r, le.getLocation().getLineNumber());
pe.setErrorStatement(line);
}
}
} catch (NoClassDefFoundError e) {
//BUG-36290 Error with Janino 2.6.0
LOG.severe("Error statement cannot be determined due to " + e + ". Try upgrading Janino to version 2.6 or newer.");
}
return pe;
}
static String getLine(Resource resource, int line) {
//Line number can be undefined
if (line < 0) {
return null;
}
LineIterator it = null;
try {
it = new LineIterator(resource.open());
return it.getLineAt(line - 1);
} catch (IOException e) {
ExceptionUtils.ignoreThrowable(e);
} finally {
IOUtils.closeSilently(it);
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy