![JAR search and dependency download from the Maven repository](/logo.png)
com.github.hexffff0.eggs.core.RunCodeHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Eggs Show documentation
Show all versions of Eggs Show documentation
Eggs是一个强大的Intellij IDEA 插件,它允许你在运行时编写Java代码与IDEA进行交互,最终得到你想要的效果,例如生成代码。
The newest version!
package com.github.hexffff0.eggs.core;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.mdkt.compiler.DynamicClassLoader;
import org.mdkt.compiler.InMemoryJavaCompiler;
import com.github.hexffff0.eggs.persistence.ClassBean;
import com.github.hexffff0.eggs.persistence.ExecuteUnit;
import com.github.hexffff0.eggs.utils.SystemInfo;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.expr.Name;
import com.google.common.collect.Sets;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiClass;
import com.intellij.util.PathUtil;
/**
* @author hyc
*/
public class RunCodeHelper {
private static final Logger logger = Logger.getInstance(RunCodeHelper.class);
private static final ClassLoader CLASS_LOADER = RunCodeHelper.class.getClassLoader();
private static final String IMPORT_CLASS = RunCodeHelper.class.getName();
public static void compileAndRunCode(@NotNull ExecuteUnit executeUnit, @NotNull Map context) {
try {
InMemoryJavaCompiler jc = InMemoryJavaCompiler.newInstance();
jc.ignoreWarnings();
jc.useParentClassLoader(new DynamicClassLoader(CLASS_LOADER));
String classPath = parseDependenciesClassPath(executeUnit, context);
jc.useOptions("-classpath", classPath);
for (ClassBean classBean : executeUnit.classBeanList) {
jc.addSource(classBean.getClassName(), classBean.getSourceCode());
}
Class> clazz = jc.compile(executeUnit.className, executeUnit.sourceCode);
Object obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("main", Map.class);
method.invoke(obj, context);
} catch (Exception e) {
logger.error(e);
}
}
private static String parseDependenciesClassPath(ExecuteUnit executeUnit, Map context) {
Set dependenciesPath = Sets.newConcurrentHashSet();
dependenciesPath.addAll(doParseDependenciesClassPath(executeUnit.sourceCode));
executeUnit.classBeanList
.parallelStream()
.map(ClassBean::getSourceCode)
.forEach(sourceCode -> dependenciesPath.addAll(doParseDependenciesClassPath(sourceCode)));
context.values()
.stream()
.filter(Objects::nonNull)
.forEach(obj -> dependenciesPath.add(obj.getClass().getName()));
dependenciesPath.add(System.getProperty("java.class.path"));
dependenciesPath.add(PathUtil.getJarPathForClass(ServiceManager.class));
dependenciesPath.add(PathUtil.getJarPathForClass(PsiClass.class));
parseThirdPartLib(executeUnit.libPath, dependenciesPath);
return String.join(SystemInfo.CLASS_PATH_DELIMITER, dependenciesPath);
}
private static Set doParseDependenciesClassPath(String sourceCode) {
CompilationUnit cu = StaticJavaParser.parse(sourceCode);
cu.addImport(IMPORT_CLASS);
return cu.getImports()
.parallelStream()
.map(ImportDeclaration::getName)
.map(Name::asString)
.filter(fullClassName -> !fullClassName.startsWith("java"))
.distinct()
.map(fullClassName -> {
try {
return Class.forName(fullClassName);
} catch (ClassNotFoundException e) {
Class> clazz = tryInnerClass(fullClassName);
if (clazz == null) {
// logger.error("cannot find class " + fullClassName);
}
return clazz;
}
})
.filter(Objects::nonNull)
.map(PathUtil::getJarPathForClass)
.collect(Collectors.toSet());
}
private static Class> tryInnerClass(String fullClassName) {
int idx = fullClassName.lastIndexOf(".");
if (idx > 0) {
char[] chars = fullClassName.toCharArray();
chars[idx] = '$';
String innerClassName = new String(chars);
try {
return Class.forName(innerClassName);
} catch (ClassNotFoundException e) {
return tryInnerClass(innerClassName);
}
}
return null;
}
private static void parseThirdPartLib(String libPaths, Set jarPaths) {
if (StringUtils.isBlank(libPaths)) {
return;
}
for (String libPath : libPaths.split(":")) {
if (!Files.isDirectory(Paths.get(libPath))) {
jarPaths.add(libPath);
continue;
}
try {
Files.list(Paths.get(libPath))
.map(Path::getFileName)
.map(Path::toString)
.filter(fileName -> fileName.endsWith(".jar"))
.map(fileName -> libPath + fileName)
.forEach(jarPaths::add);
} catch (IOException e) {
logger.error(e);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy