Removed javaengine and minor cleanup.
Author: NosBit Source: L2jUnity free release
This commit is contained in:
parent
368bd3defb
commit
f9f769d0ef
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met: Redistributions of source code
|
||||
* must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution. Neither the name of the Sun Microsystems nor the names of
|
||||
* is contributors may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package com.l2jmobius.commons.javaengine;
|
||||
|
||||
public class CompilationException extends Exception
|
||||
{
|
||||
public CompilationException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met: Redistributions of source code
|
||||
* must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution. Neither the name of the Sun Microsystems nor the names of
|
||||
* is contributors may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package com.l2jmobius.commons.javaengine;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.DiagnosticCollector;
|
||||
import javax.tools.JavaCompiler.CompilationTask;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
|
||||
|
||||
/**
|
||||
* Simple interface to Java compiler using JSR 199 Compiler API.
|
||||
* @author A. Sundararajan
|
||||
*/
|
||||
public class JavaCompiler
|
||||
{
|
||||
private final javax.tools.JavaCompiler tool;
|
||||
|
||||
public JavaCompiler()
|
||||
{
|
||||
tool = new EclipseCompiler();
|
||||
}
|
||||
|
||||
public Map<String, byte[]> compile(String source, String fileName)
|
||||
{
|
||||
return compile(source, fileName, new PrintWriter(System.err), null, null);
|
||||
}
|
||||
|
||||
public Map<String, byte[]> compile(String fileName, String source, Writer err)
|
||||
{
|
||||
return compile(fileName, source, err, null, null);
|
||||
}
|
||||
|
||||
public Map<String, byte[]> compile(String fileName, String source, Writer err, String sourcePath)
|
||||
{
|
||||
return compile(fileName, source, err, sourcePath, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* compile given String source and return bytecodes as a Map.
|
||||
* @param fileName source fileName to be used for error messages etc.
|
||||
* @param source Java source as String
|
||||
* @param err error writer where diagnostic messages are written
|
||||
* @param sourcePath location of additional .java source files
|
||||
* @param classPath location of additional .class files
|
||||
* @return
|
||||
*/
|
||||
public Map<String, byte[]> compile(String fileName, String source, Writer err, String sourcePath, String classPath)
|
||||
{
|
||||
// to collect errors, warnings etc.
|
||||
final DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
|
||||
|
||||
// create a new memory JavaFileManager
|
||||
final MemoryJavaFileManager manager = new MemoryJavaFileManager();
|
||||
|
||||
// prepare the compilation unit
|
||||
final List<JavaFileObject> compUnits = new ArrayList<>(1);
|
||||
compUnits.add(MemoryJavaFileManager.makeStringSource(fileName, source));
|
||||
|
||||
// javac options
|
||||
final List<String> options = new ArrayList<>();
|
||||
options.add("-warn:-enumSwitch");
|
||||
options.add("-g");
|
||||
options.add("-deprecation");
|
||||
options.add("-1.8");
|
||||
if (sourcePath != null)
|
||||
{
|
||||
options.add("-sourcepath");
|
||||
options.add(sourcePath);
|
||||
}
|
||||
if (classPath != null)
|
||||
{
|
||||
options.add("-classpath");
|
||||
options.add(classPath);
|
||||
}
|
||||
|
||||
// create a compilation task
|
||||
final CompilationTask task = tool.getTask(err, manager, diagnostics, options, null, compUnits);
|
||||
|
||||
if (!task.call())
|
||||
{
|
||||
final PrintWriter perr = new PrintWriter(err);
|
||||
for (Diagnostic<?> diagnostic : diagnostics.getDiagnostics())
|
||||
{
|
||||
perr.println(diagnostic.getMessage(Locale.getDefault()));
|
||||
}
|
||||
perr.flush();
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, byte[]> classBytes = manager.getClassBytes();
|
||||
manager.close();
|
||||
return classBytes;
|
||||
}
|
||||
}
|
@ -1,447 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met: Redistributions of source code
|
||||
* must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution. Neither the name of the Sun Microsystems nor the names of
|
||||
* is contributors may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package com.l2jmobius.commons.javaengine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.script.AbstractScriptEngine;
|
||||
import javax.script.Bindings;
|
||||
import javax.script.Compilable;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleBindings;
|
||||
|
||||
/**
|
||||
* This is script engine for Java programming language.
|
||||
* @author A. Sundararajan
|
||||
*/
|
||||
public class JavaScriptEngine extends AbstractScriptEngine implements Compilable
|
||||
{
|
||||
// Java compiler
|
||||
private final JavaCompiler compiler;
|
||||
|
||||
public JavaScriptEngine()
|
||||
{
|
||||
compiler = new JavaCompiler();
|
||||
}
|
||||
|
||||
// my factory, may be null
|
||||
private ScriptEngineFactory factory;
|
||||
|
||||
// my implementation for CompiledScript
|
||||
private static class JavaCompiledScript extends CompiledScript implements Serializable
|
||||
{
|
||||
private final transient JavaScriptEngine _engine;
|
||||
private transient Class<?> _class;
|
||||
private final Map<String, byte[]> _classBytes;
|
||||
private final String _classPath;
|
||||
|
||||
JavaCompiledScript(JavaScriptEngine engine, Map<String, byte[]> classBytes, String classPath)
|
||||
{
|
||||
_engine = engine;
|
||||
_classBytes = classBytes;
|
||||
_classPath = classPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptEngine getEngine()
|
||||
{
|
||||
return _engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(ScriptContext ctx) throws ScriptException
|
||||
{
|
||||
if (_class == null)
|
||||
{
|
||||
final Map<String, byte[]> classBytesCopy = new HashMap<>();
|
||||
classBytesCopy.putAll(_classBytes);
|
||||
_class = JavaScriptEngine.parseMain(new MemoryClassLoader(classBytesCopy, _classPath, JavaScriptEngine.getParentLoader(ctx)), ctx);
|
||||
}
|
||||
return JavaScriptEngine.evalClass(_class, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompiledScript compile(String script) throws ScriptException
|
||||
{
|
||||
return compile(script, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompiledScript compile(Reader reader) throws ScriptException
|
||||
{
|
||||
return compile(readFully(reader));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(String str, ScriptContext ctx) throws ScriptException
|
||||
{
|
||||
return evalClass(parse(str, ctx), ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(Reader reader, ScriptContext ctx) throws ScriptException
|
||||
{
|
||||
return eval(readFully(reader), ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptEngineFactory getFactory()
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (factory == null)
|
||||
{
|
||||
factory = new JavaScriptEngineFactory();
|
||||
}
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings createBindings()
|
||||
{
|
||||
return new SimpleBindings();
|
||||
}
|
||||
|
||||
void setFactory(ScriptEngineFactory factory)
|
||||
{
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
// Internals only below this point
|
||||
|
||||
private Class<?> parse(String str, ScriptContext ctx) throws ScriptException
|
||||
{
|
||||
final String fileName = getFileName(ctx);
|
||||
final String sourcePath = getSourcePath(ctx);
|
||||
final String classPath = getClassPath(ctx);
|
||||
|
||||
final Writer err = ctx.getErrorWriter() == null ? new StringWriter() : ctx.getErrorWriter();
|
||||
|
||||
final Map<String, byte[]> classBytes = compiler.compile(fileName, str, err, sourcePath, classPath);
|
||||
|
||||
if (classBytes == null)
|
||||
{
|
||||
throw err instanceof StringWriter ? new ScriptException(((StringWriter) err).toString()) : new ScriptException("compilation failed");
|
||||
}
|
||||
|
||||
// create a ClassLoader to load classes from MemoryJavaFileManager
|
||||
return parseMain(new MemoryClassLoader(classBytes, classPath, getParentLoader(ctx)), ctx);
|
||||
}
|
||||
|
||||
protected static Class<?> parseMain(MemoryClassLoader loader, ScriptContext ctx) throws ScriptException
|
||||
{
|
||||
final String mainClassName = getMainClassName(ctx);
|
||||
if (mainClassName != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Class<?> clazz = loader.load(mainClassName);
|
||||
final Method mainMethod = findMainMethod(clazz);
|
||||
if (mainMethod == null)
|
||||
{
|
||||
throw new ScriptException("no main method in " + mainClassName);
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
catch (ClassNotFoundException cnfe)
|
||||
{
|
||||
cnfe.printStackTrace();
|
||||
throw new ScriptException(cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
// no main class configured - load all compiled classes
|
||||
Iterable<Class<?>> classes;
|
||||
try
|
||||
{
|
||||
classes = loader.loadAll();
|
||||
}
|
||||
catch (ClassNotFoundException exp)
|
||||
{
|
||||
throw new ScriptException(exp);
|
||||
}
|
||||
|
||||
// search for class with main method
|
||||
final Class<?> c = findMainClass(classes);
|
||||
if (c != null)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
// if class with "main" method, then
|
||||
// return first class
|
||||
final Iterator<Class<?>> itr = classes.iterator();
|
||||
return itr.hasNext() ? itr.next() : null;
|
||||
}
|
||||
|
||||
private JavaCompiledScript compile(String str, ScriptContext ctx) throws ScriptException
|
||||
{
|
||||
final String fileName = getFileName(ctx);
|
||||
final String sourcePath = getSourcePath(ctx);
|
||||
final String classPath = getClassPath(ctx);
|
||||
|
||||
final Writer err = ctx.getErrorWriter() == null ? new StringWriter() : ctx.getErrorWriter();
|
||||
final Map<String, byte[]> classBytes = compiler.compile(fileName, str, err, sourcePath, classPath);
|
||||
if (classBytes == null)
|
||||
{
|
||||
throw err instanceof StringWriter ? new ScriptException(((StringWriter) err).toString()) : new ScriptException("compilation failed");
|
||||
}
|
||||
|
||||
return new JavaCompiledScript(this, classBytes, classPath);
|
||||
}
|
||||
|
||||
private static Class<?> findMainClass(Iterable<Class<?>> classes)
|
||||
{
|
||||
// find a public class with public static main method
|
||||
for (Class<?> clazz : classes)
|
||||
{
|
||||
if (Modifier.isPublic(clazz.getModifiers()) && (findMainMethod(clazz) != null))
|
||||
{
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
|
||||
// okay, try to find package private class that
|
||||
// has public static main method
|
||||
for (Class<?> clazz : classes)
|
||||
{
|
||||
if (findMainMethod(clazz) != null)
|
||||
{
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
|
||||
// no main class found!
|
||||
return null;
|
||||
}
|
||||
|
||||
// find public static void main(String[]) method, if any
|
||||
private static Method findMainMethod(Class<?> clazz)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Method mainMethod = clazz.getMethod("main", new Class[]
|
||||
{
|
||||
String[].class
|
||||
});
|
||||
final int modifiers = mainMethod.getModifiers();
|
||||
if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers))
|
||||
{
|
||||
return mainMethod;
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException nsme)
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// find public static void setScriptContext(ScriptContext) method, if any
|
||||
private static Method findSetScriptContextMethod(Class<?> clazz)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Method setCtxMethod = clazz.getMethod("setScriptContext", new Class[]
|
||||
{
|
||||
ScriptContext.class
|
||||
});
|
||||
final int modifiers = setCtxMethod.getModifiers();
|
||||
if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers))
|
||||
{
|
||||
return setCtxMethod;
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException nsme)
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getFileName(ScriptContext ctx)
|
||||
{
|
||||
final int scope = ctx.getAttributesScope("javax.script.filename");
|
||||
return scope != -1 ? ctx.getAttribute("javax.script.filename", scope).toString() : "$unnamed.java";
|
||||
}
|
||||
|
||||
// for certain variables, we look for System properties. This is
|
||||
// the prefix used for such System properties
|
||||
private static final String SYSPROP_PREFIX = "com.sun.script.java.";
|
||||
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
private static final String ARGUMENTS = "arguments";
|
||||
|
||||
private static String[] getArguments(ScriptContext ctx)
|
||||
{
|
||||
final int scope = ctx.getAttributesScope(ARGUMENTS);
|
||||
if (scope != -1)
|
||||
{
|
||||
final Object obj = ctx.getAttribute(ARGUMENTS, scope);
|
||||
if (obj instanceof String[])
|
||||
{
|
||||
return (String[]) obj;
|
||||
}
|
||||
}
|
||||
// return zero length array
|
||||
return EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
private static final String SOURCEPATH = "sourcepath";
|
||||
|
||||
private static String getSourcePath(ScriptContext ctx)
|
||||
{
|
||||
return ctx.getAttributesScope(SOURCEPATH) != -1 ? ctx.getAttribute(SOURCEPATH).toString() : System.getProperty(SYSPROP_PREFIX + SOURCEPATH);
|
||||
}
|
||||
|
||||
private static final String CLASSPATH = "classpath";
|
||||
|
||||
private static String getClassPath(ScriptContext ctx)
|
||||
{
|
||||
final int scope = ctx.getAttributesScope(CLASSPATH);
|
||||
if (scope != -1)
|
||||
{
|
||||
return ctx.getAttribute(CLASSPATH).toString();
|
||||
}
|
||||
|
||||
// look for "com.sun.script.java.classpath"
|
||||
String res = System.getProperty(SYSPROP_PREFIX + CLASSPATH);
|
||||
if (res == null)
|
||||
{
|
||||
res = System.getProperty("java.class.path");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static final String MAINCLASS = "mainClass";
|
||||
|
||||
private static String getMainClassName(ScriptContext ctx)
|
||||
{
|
||||
return ctx.getAttributesScope(MAINCLASS) != -1 ? ctx.getAttribute(MAINCLASS).toString() : System.getProperty("com.sun.script.java.mainClass");
|
||||
}
|
||||
|
||||
private static final String PARENTLOADER = "parentLoader";
|
||||
|
||||
protected static ClassLoader getParentLoader(ScriptContext ctx)
|
||||
{
|
||||
final int scope = ctx.getAttributesScope(PARENTLOADER);
|
||||
if (scope != -1)
|
||||
{
|
||||
final Object loader = ctx.getAttribute(PARENTLOADER);
|
||||
if (loader instanceof ClassLoader)
|
||||
{
|
||||
return (ClassLoader) loader;
|
||||
}
|
||||
}
|
||||
return ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
|
||||
protected static Object evalClass(Class<?> clazz, ScriptContext ctx) throws ScriptException
|
||||
{
|
||||
// JSR-223 requirement
|
||||
ctx.setAttribute("context", ctx, 100);
|
||||
if (clazz == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
final boolean isPublicClazz = Modifier.isPublic(clazz.getModifiers());
|
||||
|
||||
// find the setScriptContext method
|
||||
final Method setCtxMethod = findSetScriptContextMethod(clazz);
|
||||
// call setScriptContext and pass current ctx variable
|
||||
if (setCtxMethod != null)
|
||||
{
|
||||
if (!isPublicClazz)
|
||||
{
|
||||
// try to relax access
|
||||
setCtxMethod.setAccessible(true);
|
||||
}
|
||||
setCtxMethod.invoke(null, new Object[]
|
||||
{
|
||||
ctx
|
||||
});
|
||||
}
|
||||
|
||||
// find the main method
|
||||
final Method mainMethod = findMainMethod(clazz);
|
||||
if (mainMethod != null)
|
||||
{
|
||||
if (!isPublicClazz)
|
||||
{
|
||||
// try to relax access
|
||||
mainMethod.setAccessible(true);
|
||||
}
|
||||
|
||||
// call main method
|
||||
mainMethod.invoke(null, new Object[]
|
||||
{
|
||||
getArguments(ctx)
|
||||
});
|
||||
}
|
||||
|
||||
// return main class as eval's result
|
||||
return clazz;
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
exp.printStackTrace();
|
||||
throw new ScriptException(exp);
|
||||
}
|
||||
}
|
||||
|
||||
// read a Reader fully and return the content as string
|
||||
private String readFully(Reader reader) throws ScriptException
|
||||
{
|
||||
final char[] arr = new char[8 * 1024]; // 8K at a time
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
int numChars;
|
||||
try
|
||||
{
|
||||
while ((numChars = reader.read(arr, 0, arr.length)) > 0)
|
||||
{
|
||||
buf.append(arr, 0, numChars);
|
||||
}
|
||||
}
|
||||
catch (IOException exp)
|
||||
{
|
||||
throw new ScriptException(exp);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met: Redistributions of source code
|
||||
* must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution. Neither the name of the Sun Microsystems nor the names of
|
||||
* is contributors may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package com.l2jmobius.commons.javaengine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
|
||||
/**
|
||||
* This is script engine factory for "Java" script engine.
|
||||
* @author A. Sundararajan
|
||||
*/
|
||||
public class JavaScriptEngineFactory implements ScriptEngineFactory
|
||||
{
|
||||
@Override
|
||||
public String getEngineName()
|
||||
{
|
||||
return "java";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEngineVersion()
|
||||
{
|
||||
return "1.8";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getExtensions()
|
||||
{
|
||||
return extensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLanguageName()
|
||||
{
|
||||
return "java";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLanguageVersion()
|
||||
{
|
||||
return "1.8";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodCallSyntax(String obj, String m, String... args)
|
||||
{
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append(obj);
|
||||
buf.append('.');
|
||||
buf.append(m);
|
||||
buf.append('(');
|
||||
if (args.length != 0)
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < (args.length - 1); i++)
|
||||
{
|
||||
buf.append(args[i] + ", ");
|
||||
}
|
||||
buf.append(args[i]);
|
||||
}
|
||||
buf.append(')');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMimeTypes()
|
||||
{
|
||||
return mimeTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNames()
|
||||
{
|
||||
return names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutputStatement(String toDisplay)
|
||||
{
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("System.out.print(\"");
|
||||
final int len = toDisplay.length();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
final char ch = toDisplay.charAt(i);
|
||||
switch (ch)
|
||||
{
|
||||
case 34: // '"'
|
||||
{
|
||||
buf.append("\\\"");
|
||||
break;
|
||||
}
|
||||
case 92: // '\\'
|
||||
{
|
||||
buf.append("\\\\");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
buf.append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf.append("\");");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String key)
|
||||
{
|
||||
if (key.equals("javax.script.engine"))
|
||||
{
|
||||
return getEngineName();
|
||||
}
|
||||
if (key.equals("javax.script.engine_version"))
|
||||
{
|
||||
return getEngineVersion();
|
||||
}
|
||||
if (key.equals("javax.script.name"))
|
||||
{
|
||||
return getEngineName();
|
||||
}
|
||||
if (key.equals("javax.script.language"))
|
||||
{
|
||||
return getLanguageName();
|
||||
}
|
||||
if (key.equals("javax.script.language_version"))
|
||||
{
|
||||
return getLanguageVersion();
|
||||
}
|
||||
if (key.equals("THREADING"))
|
||||
{
|
||||
return "MULTITHREADED";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProgram(String... statements)
|
||||
{
|
||||
// we generate a Main class with main method
|
||||
// that contains all the given statements
|
||||
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("class ");
|
||||
buf.append(getClassName());
|
||||
buf.append(" {\n");
|
||||
buf.append(" public static void main(String[] args) {\n");
|
||||
if (statements.length != 0)
|
||||
{
|
||||
for (String statement : statements)
|
||||
{
|
||||
buf.append(" ");
|
||||
buf.append(statement);
|
||||
buf.append(";\n");
|
||||
}
|
||||
}
|
||||
buf.append(" }\n");
|
||||
buf.append("}\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine()
|
||||
{
|
||||
final JavaScriptEngine engine = new JavaScriptEngine();
|
||||
engine.setFactory(this);
|
||||
return engine;
|
||||
}
|
||||
|
||||
// used to generate a unique class name in getProgram
|
||||
private String getClassName()
|
||||
{
|
||||
return "com_sun_script_java_Main$" + getNextClassNumber();
|
||||
}
|
||||
|
||||
private static synchronized long getNextClassNumber()
|
||||
{
|
||||
return nextClassNum++;
|
||||
}
|
||||
|
||||
private static long nextClassNum = 0L;
|
||||
private static List<String> names;
|
||||
private static List<String> extensions;
|
||||
private static List<String> mimeTypes;
|
||||
static
|
||||
{
|
||||
names = new ArrayList<>(1);
|
||||
names.add("java");
|
||||
names = Collections.unmodifiableList(names);
|
||||
extensions = names;
|
||||
mimeTypes = new ArrayList<>(0);
|
||||
mimeTypes = Collections.unmodifiableList(mimeTypes);
|
||||
}
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met: Redistributions of source code
|
||||
* must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution. Neither the name of the Sun Microsystems nor the names of
|
||||
* is contributors may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package com.l2jmobius.commons.javaengine;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* ClassLoader that loads .class bytes from memory.
|
||||
* @author A. Sundararajan
|
||||
*/
|
||||
public final class MemoryClassLoader extends URLClassLoader
|
||||
{
|
||||
private final Map<String, byte[]> classBytes;
|
||||
|
||||
public MemoryClassLoader(Map<String, byte[]> classBytes, String classPath, ClassLoader parent)
|
||||
{
|
||||
super(toURLs(classPath), parent);
|
||||
this.classBytes = classBytes;
|
||||
}
|
||||
|
||||
public MemoryClassLoader(Map<String, byte[]> classBytes, String classPath)
|
||||
{
|
||||
this(classBytes, classPath, null);
|
||||
}
|
||||
|
||||
public Class<?> load(String className) throws ClassNotFoundException
|
||||
{
|
||||
return loadClass(className);
|
||||
}
|
||||
|
||||
public Iterable<Class<?>> loadAll() throws ClassNotFoundException
|
||||
{
|
||||
final List<Class<?>> classes = new ArrayList<>(classBytes.size());
|
||||
for (String name : classBytes.keySet())
|
||||
{
|
||||
classes.add(loadClass(name));
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String className) throws ClassNotFoundException
|
||||
{
|
||||
final byte buf[] = classBytes.get(className);
|
||||
if (buf != null)
|
||||
{
|
||||
// clear the bytes in map -- we don't need it anymore
|
||||
classBytes.put(className, null);
|
||||
return defineClass(className, buf, 0, buf.length);
|
||||
}
|
||||
return super.findClass(className);
|
||||
}
|
||||
|
||||
private static URL[] toURLs(String classPath)
|
||||
{
|
||||
if (classPath == null)
|
||||
{
|
||||
return new URL[0];
|
||||
}
|
||||
|
||||
final List<URL> list = new ArrayList<>();
|
||||
final StringTokenizer st = new StringTokenizer(classPath, File.pathSeparator);
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
final String token = st.nextToken();
|
||||
final File file = new File(token);
|
||||
if (file.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
list.add(file.toURI().toURL());
|
||||
}
|
||||
catch (MalformedURLException mue)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
list.add(new URL(token));
|
||||
}
|
||||
catch (MalformedURLException mue)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final URL res[] = new URL[list.size()];
|
||||
list.toArray(res);
|
||||
return res;
|
||||
}
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met: Redistributions of source code
|
||||
* must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution. Neither the name of the Sun Microsystems nor the names of
|
||||
* is contributors may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package com.l2jmobius.commons.javaengine;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
|
||||
import org.eclipse.jdt.internal.compiler.tool.EclipseFileManager;
|
||||
|
||||
/**
|
||||
* JavaFileManager that keeps compiled .class bytes in memory.
|
||||
* @author A. Sundararajan
|
||||
*/
|
||||
public final class MemoryJavaFileManager extends EclipseFileManager
|
||||
{
|
||||
private static final String EXT = ".java";
|
||||
protected Map<String, byte[]> classBytes;
|
||||
|
||||
public MemoryJavaFileManager()
|
||||
{
|
||||
super(null, null);
|
||||
classBytes = new HashMap<>();
|
||||
}
|
||||
|
||||
public Map<String, byte[]> getClassBytes()
|
||||
{
|
||||
return classBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
classBytes = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* A file object used to represent Java source coming from a string.
|
||||
*/
|
||||
private static class StringInputBuffer extends SimpleJavaFileObject
|
||||
{
|
||||
final String code;
|
||||
|
||||
StringInputBuffer(String name, String code)
|
||||
{
|
||||
super(toURI(name), Kind.SOURCE);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharBuffer getCharContent(boolean ignoreEncodingErrors)
|
||||
{
|
||||
return CharBuffer.wrap(code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A file object that stores Java bytecode into the classBytes map.
|
||||
*/
|
||||
private class ClassOutputBuffer extends SimpleJavaFileObject
|
||||
{
|
||||
protected final String name;
|
||||
|
||||
ClassOutputBuffer(String name)
|
||||
{
|
||||
super(toURI(name), Kind.CLASS);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream openOutputStream()
|
||||
{
|
||||
return new FilterOutputStream(new ByteArrayOutputStream())
|
||||
{
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
out.close();
|
||||
classBytes.put(name, ((ByteArrayOutputStream) out).toByteArray());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location, String className, Kind kind, FileObject sibling) throws IOException
|
||||
{
|
||||
if (kind == Kind.CLASS)
|
||||
{
|
||||
return new ClassOutputBuffer(className.replace('/', '.'));
|
||||
}
|
||||
return super.getJavaFileForOutput(location, className, kind, sibling);
|
||||
}
|
||||
|
||||
static JavaFileObject makeStringSource(String name, String code)
|
||||
{
|
||||
return new StringInputBuffer(name, code);
|
||||
}
|
||||
|
||||
static URI toURI(String name)
|
||||
{
|
||||
final File file = new File(name);
|
||||
if (file.exists())
|
||||
{
|
||||
return file.toURI();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final StringBuilder newUri = new StringBuilder();
|
||||
newUri.append("file:///");
|
||||
newUri.append(name.replace('.', '/'));
|
||||
if (name.endsWith(EXT))
|
||||
{
|
||||
newUri.replace(newUri.length() - EXT.length(), newUri.length(), EXT);
|
||||
}
|
||||
return URI.create(newUri.toString());
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
return URI.create("file:///com/sun/script/java/java_source");
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
@ -168,8 +169,8 @@ public final class ScriptEngineManager
|
||||
// throws exception if not exists or not file
|
||||
checkExistingFile("ScriptList", SCRIPT_LIST_FILE);
|
||||
|
||||
final LinkedHashMap<IExecutionContext, LinkedList<Path>> files = new LinkedHashMap<>();
|
||||
final LinkedList<String> extWithoutEngine = new LinkedList<>();
|
||||
final Map<IExecutionContext, List<Path>> files = new LinkedHashMap<>();
|
||||
final List<String> extWithoutEngine = new LinkedList<>();
|
||||
|
||||
Files.lines(SCRIPT_LIST_FILE).forEach(line ->
|
||||
{
|
||||
@ -209,7 +210,7 @@ public final class ScriptEngineManager
|
||||
return;
|
||||
}
|
||||
|
||||
LinkedList<Path> ll = files.get(engine);
|
||||
List<Path> ll = files.get(engine);
|
||||
if (ll == null)
|
||||
{
|
||||
ll = new LinkedList<>();
|
||||
@ -218,7 +219,7 @@ public final class ScriptEngineManager
|
||||
ll.add(sourceFile);
|
||||
});
|
||||
|
||||
for (Entry<IExecutionContext, LinkedList<Path>> entry : files.entrySet())
|
||||
for (Entry<IExecutionContext, List<Path>> entry : files.entrySet())
|
||||
{
|
||||
_currentExecutionContext = entry.getKey();
|
||||
try
|
||||
|
@ -20,6 +20,7 @@ import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
@ -223,13 +224,7 @@ public final class JavaExecutionContext extends AbstractExecutionContext<JavaScr
|
||||
@Override
|
||||
public Entry<Path, Throwable> executeScript(final Path sourcePath) throws Exception
|
||||
{
|
||||
@SuppressWarnings("serial")
|
||||
Map<Path, Throwable> executionFailures = executeScripts(new LinkedList<Path>()
|
||||
{
|
||||
{
|
||||
add(sourcePath);
|
||||
}
|
||||
});
|
||||
final Map<Path, Throwable> executionFailures = executeScripts(Arrays.asList(sourcePath));
|
||||
if (!executionFailures.isEmpty())
|
||||
{
|
||||
return executionFailures.entrySet().iterator().next();
|
||||
|
Loading…
Reference in New Issue
Block a user