Created
April 10, 2014 03:31
-
-
Save pfmiles/10340430 to your computer and use it in GitHub Desktop.
利用Java compiler API的内存动态编译工具
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xxx; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.io.Reader; | |
import java.io.Writer; | |
import java.net.URI; | |
import javax.tools.FileObject; | |
import xxx.FlyingCompilationException; | |
/** | |
* @author pf-miles 2014-4-6 下午6:14:45 | |
*/ | |
public class DiskJarFile implements FileObject { | |
private File file; | |
private URI uri; | |
public DiskJarFile(String absolutePath){ | |
file = new File(absolutePath); | |
if (!file.exists()) throw new FlyingCompilationException("Disk jar file: '" + absolutePath | |
+ "' does not exist."); | |
this.uri = URI.create("file://" + file.getAbsolutePath()); | |
} | |
public URI toUri() { | |
return uri; | |
} | |
public String getName() { | |
return this.file.getName(); | |
} | |
public InputStream openInputStream() throws IOException { | |
return new FileInputStream(this.file); | |
} | |
public OutputStream openOutputStream() throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public Reader openReader(boolean ignoreEncodingErrors) throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public Writer openWriter() throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public long getLastModified() { | |
return this.file.lastModified(); | |
} | |
public boolean delete() { | |
throw new UnsupportedOperationException(); | |
} | |
/** | |
* 取得磁盘文件绝对路径 | |
*/ | |
public String getAbsolutePath() { | |
return this.file.getAbsolutePath(); | |
} | |
public int hashCode() { | |
final int prime = 31; | |
int result = 1; | |
result = prime * result + ((uri == null) ? 0 : uri.hashCode()); | |
return result; | |
} | |
public boolean equals(Object obj) { | |
if (this == obj) return true; | |
if (obj == null) return false; | |
if (getClass() != obj.getClass()) return false; | |
DiskJarFile other = (DiskJarFile) obj; | |
if (uri == null) { | |
if (other.uri != null) return false; | |
} else if (!uri.equals(other.uri)) return false; | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xxx; | |
import java.io.File; | |
import java.io.IOException; | |
import java.io.StringWriter; | |
import java.util.Arrays; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Set; | |
import javax.tools.Diagnostic; | |
import javax.tools.DiagnosticCollector; | |
import javax.tools.JavaCompiler; | |
import javax.tools.JavaCompiler.CompilationTask; | |
import javax.tools.JavaFileObject; | |
import javax.tools.JavaFileObject.Kind; | |
import javax.tools.StandardLocation; | |
import javax.tools.ToolProvider; | |
import xxx.DiskJarFile; | |
import xxx.JavaSourceFile; | |
/** | |
* 将传入的内存java文件结合内存classpath,编译为内存class文件 | |
* | |
* @author pf-miles 2014-4-3 下午4:29:31 | |
*/ | |
public class FlyingCompileUtil { | |
/** | |
* 传入源码以及classpath中的jar包,编译出class文件(内存文件) | |
* | |
* @param srcs 源码文件 | |
* @param cpJarFiles 准备放入classpath的jar包(存在于硬盘上),可为null | |
* @return 编译结果 | |
*/ | |
public static CompilationResult compile(Set<JavaSourceFile> srcs, Set<DiskJarFile> cpJarFiles) { | |
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); | |
FlyingFileManager fileManager = new FlyingFileManager(compiler.getStandardFileManager(null, null, null)); | |
try { | |
List<String> options = Arrays.asList("-classpath", toClassPathStr(cpJarFiles)); | |
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); | |
StringWriter out = new StringWriter(); | |
CompilationTask task = compiler.getTask(out, fileManager, diagnostics, options, null, srcs); | |
if (!task.call()) { | |
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { | |
out.append("Error on line " + diagnostic.getLineNumber() + " in " + diagnostic).append('\n'); | |
} | |
return new CompilationResult(out.toString()); | |
} else { | |
try { | |
return new CompilationResult(fileManager.list(StandardLocation.CLASS_OUTPUT, null, | |
new HashSet<Kind>(Arrays.asList(Kind.CLASS)), true)); | |
} catch (IOException e) { | |
throw new FlyingCompilationException(e); | |
} | |
} | |
} finally { | |
try { | |
fileManager.close(); | |
} catch (IOException e) { | |
throw new FlyingCompilationException(e); | |
} | |
} | |
} | |
// 生成动编译的classpath,应包括所有传入的jar包 | |
private static String toClassPathStr(Set<DiskJarFile> cpJars) { | |
Set<String> ps = new HashSet<String>(); | |
if (cpJars != null) for (DiskJarFile f : cpJars) { | |
ps.add(f.getAbsolutePath()); | |
} | |
StringBuilder sb = new StringBuilder(); | |
for (String s : ps) { | |
if (sb.length() != 0) sb.append(File.pathSeparator); | |
sb.append(s); | |
} | |
return sb.toString(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xxx; | |
import java.io.IOException; | |
import java.util.ArrayDeque; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import java.util.Deque; | |
import java.util.LinkedHashMap; | |
import java.util.LinkedHashSet; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
import javax.tools.FileObject; | |
import javax.tools.ForwardingJavaFileManager; | |
import javax.tools.JavaFileObject; | |
import javax.tools.JavaFileObject.Kind; | |
import javax.tools.StandardJavaFileManager; | |
import javax.tools.StandardLocation; | |
import org.apache.commons.lang.StringUtils; | |
import xxx.JavaClassFile; | |
import xxx.JavaSourceFile; | |
/** | |
* 虚拟一个内存中的文件系统,用作动态编译,其结构如下: | |
* | |
* <pre> | |
* / | |
* \....src/ | |
* \....target/ | |
* </pre> | |
* | |
* 其中,src是源码目录,target是编译好的class文件目录 | |
* | |
* @author pf-miles 2014-4-6 下午4:29:14 | |
*/ | |
public class FlyingFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> { | |
// all source files, in 'src/ directory' | |
private LinkedHashMap<String, Object> srcs = new LinkedHashMap<String, Object>(); | |
// all compiled class files, in 'target/ directory' | |
private LinkedHashMap<String, Object> classes = new LinkedHashMap<String, Object>(); | |
protected FlyingFileManager(StandardJavaFileManager fileManager){ | |
super(fileManager); | |
} | |
public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) | |
throws IOException { | |
if (location instanceof StandardLocation) { | |
switch ((StandardLocation) location) { | |
case CLASS_OUTPUT: | |
if (!kinds.contains(Kind.CLASS)) return Collections.emptyList(); | |
return listMemFile(this.classes, packageName, recurse); | |
case CLASS_PATH: | |
LinkedHashSet<JavaFileObject> fs = new LinkedHashSet<JavaFileObject>(); | |
if (kinds.contains(Kind.CLASS)) { | |
fs = listMemFile(this.classes, packageName, recurse); | |
} | |
for (JavaFileObject jfo : super.list(location, packageName, kinds, recurse)) { | |
fs.add(jfo); | |
} | |
return fs; | |
case SOURCE_OUTPUT: | |
case SOURCE_PATH: | |
if (!kinds.contains(Kind.SOURCE)) return Collections.emptyList(); | |
return listMemFile(this.srcs, packageName, recurse); | |
case ANNOTATION_PROCESSOR_PATH: | |
case PLATFORM_CLASS_PATH: | |
default: | |
return super.list(location, packageName, kinds, recurse); | |
} | |
} else { | |
return Collections.emptyList(); | |
} | |
} | |
@SuppressWarnings("unchecked") | |
private LinkedHashSet<JavaFileObject> listMemFile(LinkedHashMap<String, Object> memFiles, String pkg, | |
boolean recurse) { | |
LinkedHashSet<JavaFileObject> ret = new LinkedHashSet<JavaFileObject>(); | |
// cd pkgPath | |
Deque<String> pkgPath = resolvePkgPath(pkg); | |
while (!pkgPath.isEmpty()) { | |
Object f = memFiles.get(pkgPath.pop()); | |
if (f == null || !(f instanceof Map)) { | |
return ret; | |
} else { | |
memFiles = (LinkedHashMap<String, Object>) f; | |
} | |
} | |
List<LinkedHashMap<String, Object>> subDirs = new ArrayList<LinkedHashMap<String, Object>>(); | |
for (Map.Entry<String, Object> e : memFiles.entrySet()) { | |
Object f = e.getValue(); | |
if (f instanceof JavaFileObject) { | |
ret.add((JavaFileObject) f); | |
} else { | |
subDirs.add((LinkedHashMap<String, Object>) f); | |
} | |
} | |
if (recurse) ret.addAll(dumpJavaFileObjects(subDirs)); | |
return ret; | |
} | |
@SuppressWarnings("unchecked") | |
private LinkedHashSet<JavaFileObject> dumpJavaFileObjects(List<LinkedHashMap<String, Object>> dirs) { | |
LinkedHashSet<JavaFileObject> ret = new LinkedHashSet<JavaFileObject>(); | |
for (LinkedHashMap<String, Object> dir : dirs) { | |
for (Map.Entry<String, Object> e : dir.entrySet()) { | |
if (e.getValue() instanceof JavaFileObject) { | |
ret.add((JavaFileObject) e.getValue()); | |
} else { | |
ret.addAll(dumpJavaFileObjects(Arrays.asList((LinkedHashMap<String, Object>) e.getValue()))); | |
} | |
} | |
} | |
return ret; | |
} | |
private Deque<String> resolvePkgPath(String pkg) { | |
Deque<String> ret = new ArrayDeque<String>(); | |
if (pkg != null) for (String s : pkg.split("\\.")) { | |
ret.add(s); | |
} | |
return ret; | |
} | |
public String inferBinaryName(Location location, JavaFileObject file) { | |
if (StandardLocation.CLASS_OUTPUT.equals(location) || StandardLocation.CLASS_PATH.equals(location) | |
|| StandardLocation.SOURCE_OUTPUT.equals(location) || StandardLocation.SOURCE_PATH.equals(location)) { | |
if (file instanceof JavaSourceFile) { | |
return null; | |
} else if (file instanceof JavaClassFile) { | |
return ((JavaClassFile) file).getBinaryClassName(); | |
} | |
} | |
return super.inferBinaryName(location, file); | |
} | |
public boolean isSameFile(FileObject a, FileObject b) { | |
if (a == b) return true; | |
Class<?> ac = a.getClass(); | |
Class<?> bc = b.getClass(); | |
if (ac.equals(bc)) { | |
if (JavaClassFile.class.equals(ac) || JavaSourceFile.class.equals(ac)) { | |
return a.equals(b); | |
} else { | |
return super.isSameFile(a, b); | |
} | |
} else { | |
return false; | |
} | |
} | |
public boolean hasLocation(Location location) { | |
if (!(location instanceof StandardLocation)) { | |
return false; | |
} | |
switch ((StandardLocation) location) { | |
case CLASS_OUTPUT: | |
case SOURCE_OUTPUT: | |
case CLASS_PATH: | |
case SOURCE_PATH: | |
return true; | |
case ANNOTATION_PROCESSOR_PATH: | |
case PLATFORM_CLASS_PATH: | |
default: | |
return false; | |
} | |
} | |
public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException { | |
if (Kind.SOURCE != kind && Kind.CLASS != kind) return null; | |
if (!(location instanceof StandardLocation)) return null; | |
switch ((StandardLocation) location) { | |
case CLASS_OUTPUT: | |
return this.getMemFileByClassName(className, classes); | |
case CLASS_PATH: | |
JavaFileObject f = this.getMemFileByClassName(className, classes); | |
if (f == null) { | |
return super.getJavaFileForInput(location, className, kind); | |
} else { | |
return f; | |
} | |
case SOURCE_OUTPUT: | |
case SOURCE_PATH: | |
return this.getMemFileByClassName(className, srcs); | |
case ANNOTATION_PROCESSOR_PATH: | |
case PLATFORM_CLASS_PATH: | |
default: | |
return null; | |
} | |
} | |
// 根据类名获取内存文件,找不到则返回null | |
@SuppressWarnings("unchecked") | |
private JavaFileObject getMemFileByClassName(String className, LinkedHashMap<String, Object> memFiles) { | |
if (className.contains(".")) { | |
String pkg = StringUtils.substringBeforeLast(className, "."); | |
// cd pkgPath | |
Deque<String> pkgPath = resolvePkgPath(pkg); | |
while (!pkgPath.isEmpty()) { | |
Object f = memFiles.get(pkgPath.pop()); | |
if (f == null || !(f instanceof Map)) { | |
return null; | |
} else { | |
memFiles = (LinkedHashMap<String, Object>) f; | |
} | |
} | |
Object o = memFiles.get(StringUtils.substringAfterLast(className, ".")); | |
if (o instanceof JavaFileObject) { | |
return (JavaFileObject) o; | |
} else { | |
return null; | |
} | |
} else { | |
Object o = memFiles.get(className); | |
if (o instanceof JavaFileObject) { | |
return (JavaFileObject) o; | |
} else { | |
return null; | |
} | |
} | |
} | |
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) | |
throws IOException { | |
if (Kind.CLASS != kind && Kind.SOURCE != kind) throw new IOException("Unsupported output kind: " + kind); | |
if (!(location instanceof StandardLocation)) throw new IOException("Unsupported output location: " + location); | |
switch ((StandardLocation) location) { | |
case CLASS_OUTPUT: | |
return getOrCreateMemFileByClassName(className, this.classes, JavaClassFile.class); | |
case SOURCE_OUTPUT: | |
return getOrCreateMemFileByClassName(className, this.srcs, JavaSourceFile.class); | |
case CLASS_PATH: | |
case SOURCE_PATH: | |
case ANNOTATION_PROCESSOR_PATH: | |
case PLATFORM_CLASS_PATH: | |
default: | |
throw new IOException("Unsupported output location: " + location); | |
} | |
} | |
// 获取一个内存文件用作输出,找不到则新建 | |
@SuppressWarnings("unchecked") | |
private JavaFileObject getOrCreateMemFileByClassName(String className, LinkedHashMap<String, Object> memFiles, | |
Class<? extends JavaFileObject> fileType) { | |
if (className.contains(".")) { | |
String pkg = StringUtils.substringBeforeLast(className, "."); | |
// cd pkgPath | |
Deque<String> pkgPath = resolvePkgPath(pkg); | |
while (!pkgPath.isEmpty()) { | |
String cur = pkgPath.pop(); | |
Object f = memFiles.get(cur); | |
if (f != null && !(f instanceof Map)) { | |
throw new FlyingCompilationException("Conflict class & pkg name: " + className + ", at: " + cur); | |
} else if (f == null) { | |
LinkedHashMap<String, Object> dir = new LinkedHashMap<String, Object>(); | |
memFiles.put(cur, dir); | |
memFiles = dir; | |
} else { | |
memFiles = (LinkedHashMap<String, Object>) f; | |
} | |
} | |
String simpleName = StringUtils.substringAfterLast(className, "."); | |
Object o = memFiles.get(simpleName); | |
if (o != null && !(o instanceof JavaFileObject)) { | |
throw new FlyingCompilationException("Conflict class & pkg name: " + className + ", at: " + simpleName); | |
} else if (o == null) { | |
JavaFileObject obj = null; | |
if (JavaSourceFile.class.equals(fileType)) { | |
obj = new JavaSourceFile(simpleName + ".java", pkg, ""); | |
} else { | |
obj = new JavaClassFile(simpleName + ".class", pkg, null); | |
} | |
memFiles.put(simpleName, obj); | |
return obj; | |
} else { | |
return (JavaFileObject) o; | |
} | |
} else { | |
Object o = memFiles.get(className); | |
if (o != null && !(o instanceof JavaFileObject)) { | |
throw new FlyingCompilationException("Conflict class & pkg name: " + className + ", at: " + className); | |
} else if (o == null) { | |
JavaFileObject obj = null; | |
if (JavaSourceFile.class.equals(fileType)) { | |
obj = new JavaSourceFile(className + ".java", "", ""); | |
} else { | |
obj = new JavaClassFile(className + ".class", "", null); | |
} | |
memFiles.put(className, obj); | |
return obj; | |
} else { | |
return (JavaFileObject) o; | |
} | |
} | |
} | |
public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException { | |
if (location instanceof StandardLocation) { | |
switch ((StandardLocation) location) { | |
case CLASS_OUTPUT: | |
if (relativeName.endsWith(".class")) { | |
return this.getJavaFileForInput(location, resolveClassName(packageName, relativeName), | |
Kind.CLASS); | |
} else { | |
return null; | |
} | |
case CLASS_PATH: | |
if (relativeName.endsWith(".class")) { | |
JavaFileObject f = this.getJavaFileForInput(location, | |
resolveClassName(packageName, relativeName), | |
Kind.CLASS); | |
if (f == null) { | |
return super.getFileForInput(location, packageName, relativeName); | |
} else { | |
return f; | |
} | |
} else { | |
return super.getFileForInput(location, packageName, relativeName); | |
} | |
case SOURCE_OUTPUT: | |
case SOURCE_PATH: | |
if (relativeName.endsWith(".java")) { | |
return this.getJavaFileForInput(location, resolveClassName(packageName, relativeName), | |
Kind.SOURCE); | |
} else { | |
return null; | |
} | |
case ANNOTATION_PROCESSOR_PATH: | |
case PLATFORM_CLASS_PATH: | |
default: | |
return super.getFileForInput(location, packageName, relativeName); | |
} | |
} else { | |
return super.getFileForInput(location, packageName, relativeName); | |
} | |
} | |
private String resolveClassName(String pkg, String fileName) { | |
if (StringUtils.isNotBlank(pkg)) { | |
return pkg + "." + StringUtils.substringBeforeLast(fileName, "."); | |
} else { | |
return StringUtils.substringBeforeLast(fileName, "."); | |
} | |
} | |
public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) | |
throws IOException { | |
if (!(location instanceof StandardLocation)) throw new IOException("Unsupported output location: " + location); | |
switch ((StandardLocation) location) { | |
case CLASS_OUTPUT: | |
if (relativeName.endsWith(".class")) { | |
return this.getJavaFileForOutput(location, resolveClassName(packageName, relativeName), Kind.CLASS, | |
sibling); | |
} else { | |
throw new IOException("Unsupported output file type in class output location: " + relativeName); | |
} | |
case SOURCE_OUTPUT: | |
if (relativeName.endsWith(".java")) { | |
return this.getJavaFileForOutput(location, resolveClassName(packageName, relativeName), | |
Kind.SOURCE, sibling); | |
} else { | |
throw new IOException("Unsupported output file type in source output location: " + relativeName); | |
} | |
case CLASS_PATH: | |
case SOURCE_PATH: | |
case ANNOTATION_PROCESSOR_PATH: | |
case PLATFORM_CLASS_PATH: | |
default: | |
throw new IOException("Unsupported output location: " + location); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xxx; | |
import java.io.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.io.Reader; | |
import java.io.Writer; | |
import java.net.URI; | |
import javax.tools.SimpleJavaFileObject; | |
import org.apache.commons.lang.StringUtils; | |
/** | |
* A compiled java class file in memory. | |
* | |
* @author pf-miles 2014-4-3 下午3:20:03 | |
*/ | |
public class JavaClassFile extends SimpleJavaFileObject { | |
private String fileName; | |
private String binaryName; | |
private byte[] data; | |
public JavaClassFile(String fileName, String pkg, byte[] data){ | |
super(genMemFileUri(fileName, pkg), Kind.CLASS); | |
this.fileName = fileName; | |
this.data = data; | |
if (StringUtils.isNotBlank(pkg)) { | |
this.binaryName = pkg + "." + StringUtils.substringBeforeLast(fileName, "."); | |
} else { | |
this.binaryName = StringUtils.substringBeforeLast(fileName, "."); | |
} | |
} | |
private static URI genMemFileUri(String fileName, String pkg) { | |
String pkgPath = ""; | |
if (StringUtils.isNotBlank(pkg)) pkgPath = pkg.replaceAll("\\.", "/") + "/"; | |
return URI.create("mem:///target/" + pkgPath + fileName); | |
} | |
public String getName() { | |
return this.fileName; | |
} | |
public InputStream openInputStream() throws IOException { | |
return new ByteArrayInputStream(this.data); | |
} | |
public OutputStream openOutputStream() throws IOException { | |
return new ByteArrayOutputStream() { | |
public void close() throws IOException { | |
super.close(); | |
JavaClassFile.this.data = this.toByteArray(); | |
} | |
}; | |
} | |
public Reader openReader(boolean ignoreEncodingErrors) throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public Writer openWriter() throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public boolean delete() { | |
throw new UnsupportedOperationException(); | |
} | |
public String toString() { | |
return uri.toString(); | |
} | |
public String getBinaryClassName() { | |
return this.binaryName; | |
} | |
public int hashCode() { | |
final int prime = 31; | |
int result = 1; | |
result = prime * result + ((uri == null) ? 0 : uri.hashCode()); | |
return result; | |
} | |
public boolean equals(Object obj) { | |
if (this == obj) return true; | |
if (obj == null) return false; | |
if (getClass() != obj.getClass()) return false; | |
DiskJarFile other = (DiskJarFile) obj; | |
if (uri == null) { | |
if (other.toUri() != null) return false; | |
} else if (!uri.equals(other.toUri())) return false; | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xxx; | |
import java.io.ByteArrayInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.io.Writer; | |
import java.net.URI; | |
import javax.tools.SimpleJavaFileObject; | |
import org.apache.commons.lang.StringUtils; | |
public class JavaSourceFile extends SimpleJavaFileObject { | |
private String fileName; | |
private String code; | |
/** | |
* 创建内存java源码文件 | |
* | |
* @param fileName 文件名 | |
* @param pkg 包名 | |
* @param code 代码 | |
*/ | |
public JavaSourceFile(String fileName, String pkg, String code){ | |
super(genMemFileUri(fileName, pkg), Kind.SOURCE); | |
this.fileName = fileName; | |
this.code = code; | |
} | |
private static URI genMemFileUri(String fileName, String pkg) { | |
String pkgPath = ""; | |
if (StringUtils.isNotBlank(pkg)) pkgPath = pkg.replaceAll("\\.", "/") + "/"; | |
return URI.create("mem:///src/" + pkgPath + fileName); | |
} | |
public String getName() { | |
return this.fileName; | |
} | |
public InputStream openInputStream() throws IOException { | |
return new ByteArrayInputStream(this.code.getBytes()); | |
} | |
public OutputStream openOutputStream() throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { | |
return this.code; | |
} | |
public Writer openWriter() throws IOException { | |
throw new UnsupportedOperationException(); | |
} | |
public boolean delete() { | |
throw new UnsupportedOperationException(); | |
} | |
public String toString() { | |
return uri.toString(); | |
} | |
public int hashCode() { | |
final int prime = 31; | |
int result = 1; | |
result = prime * result + ((uri == null) ? 0 : uri.hashCode()); | |
return result; | |
} | |
public boolean equals(Object obj) { | |
if (this == obj) return true; | |
if (obj == null) return false; | |
if (getClass() != obj.getClass()) return false; | |
DiskJarFile other = (DiskJarFile) obj; | |
if (uri == null) { | |
if (other.toUri() != null) return false; | |
} else if (!uri.equals(other.toUri())) return false; | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment