com.ideaaedi.component.compile.CharSequenceJavaFileObject Maven / Gradle / Ivy
package com.ideaaedi.component.compile;
import org.apache.commons.io.IOUtils;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
/**
* {@link SimpleJavaFileObject}是jdk提供的一个处理类源码的简单实现,源文件是以文件路径的形式输入的。
* 如果你想源文件以{@link InputStream}或byte[]
或{@link String}等形式输入,
* 那么你需要对{@link SimpleJavaFileObject}进行扩展,或者直接实现{@link JavaFileObject}也行
*
*
* 注:事实上,{@link SimpleJavaFileObject}不仅仅能处理.java源文件,还能处理.class、.html等其它文件
* @author JustryDeng
* @since 2021/9/20 15:56:07
*/
public class CharSequenceJavaFileObject extends SimpleJavaFileObject {
public static final String PKG_SEPARATOR = ".";
public static final String DIR_SEPARATOR = "/";
/**
* 全类名
*/
private final String classLongName;
/**
* 源码
*/
private final CharSequence sourceCode;
/**
* 源码编译成功后的class
*/
private ByteArrayOutputStream byteArrayOutputStream;
public CharSequenceJavaFileObject(String classLongName, InputStream sourceCodeInputStream) {
super(URI.create("CharSequence:///" + classLongName.replace(PKG_SEPARATOR, DIR_SEPARATOR)
+ Kind.SOURCE.extension), Kind.SOURCE);
this.classLongName = classLongName;
try {
this.sourceCode = sourceCodeInputStream == null ? null : IOUtils.toString(sourceCodeInputStream, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new UndeclaredThrowableException(e);
}
}
public CharSequenceJavaFileObject(String classLongName, CharSequence sourceCode) {
super(URI.create("CharSequence:///" + classLongName.replace(PKG_SEPARATOR, DIR_SEPARATOR)
+ Kind.SOURCE.extension), Kind.SOURCE);
this.classLongName = classLongName;
this.sourceCode = sourceCode;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return sourceCode;
}
@Override
public String getName() {
return classLongName;
}
/**
* 编译成功后,会将编译出来的.class往此方法开发的OutputStream中写
*/
@Override
public OutputStream openOutputStream() {
if (byteArrayOutputStream == null) {
byteArrayOutputStream = new ByteArrayOutputStream();
}
return byteArrayOutputStream;
}
public byte[] getByteCode() {
return byteArrayOutputStream.toByteArray();
}
}