Expose individual class remapping in JarRemapper

The JarRemapper constructor is now public; you can create a remapper
with a JarMapping and list of IInheritanceProviders, and then use it
to remap an entire jar with remapJar(), or individual classes using
remapClassFile().
This commit is contained in:
Agaricus 2013-01-23 19:32:21 -08:00
parent d6619b5d19
commit 03a418d4b3
2 changed files with 29 additions and 15 deletions

View File

@ -50,7 +50,7 @@ public class JarRemapper extends Remapper {
private final List<IInheritanceProvider> inheritanceProviders;
private final JarMapping jarMapping;
private JarRemapper(JarMapping jarMapping, List<IInheritanceProvider> inheritanceProviders) throws IOException {
public JarRemapper(JarMapping jarMapping, List<IInheritanceProvider> inheritanceProviders) throws IOException {
this.jarMapping = jarMapping;
this.inheritanceProviders = inheritanceProviders;
}
@ -115,15 +115,12 @@ public class JarRemapper extends Remapper {
return mapped == null ? name : mapped;
}
public static void renameJar(Jar jar, File target, JarMapping jarMapping, boolean live) throws IOException {
/**
* Remap all the classes in a jar, writing a new jar to the target
*/
public void remapJar(Jar jar, File target) throws IOException {
JarOutputStream out = new JarOutputStream(new FileOutputStream(target));
try {
List<IInheritanceProvider> inheritanceProviders = new ArrayList<IInheritanceProvider>();
inheritanceProviders.add(new JarInheritanceProvider(jar));
if (live) {
inheritanceProviders.add(new RuntimeInheritanceProvider());
}
JarRemapper self = new JarRemapper(jarMapping, inheritanceProviders);
if (jar == null) {
return;
}
@ -137,12 +134,8 @@ public class JarRemapper extends Remapper {
if (name.endsWith(".class")) {
name = name.substring(0, name.length() - CLASS_LEN);
ClassReader reader = new ClassReader(is);
ClassWriter wr = new ClassWriter(0);
RemappingClassAdapter mapper = new RemappingClassAdapter(wr, self);
reader.accept(mapper, ClassReader.EXPAND_FRAMES);
data = wr.toByteArray();
String newName = self.map(name);
data = remapClassFile(is);
String newName = map(name);
entry = new JarEntry(newName == null ? name : newName + ".class");
@ -167,4 +160,15 @@ public class JarRemapper extends Remapper {
out.close();
}
}
/**
* Remap an individual class given an InputStream to its bytecode
*/
public byte[] remapClassFile(InputStream is) throws IOException {
ClassReader reader = new ClassReader(is);
ClassWriter wr = new ClassWriter(0);
RemappingClassAdapter mapper = new RemappingClassAdapter(wr, this);
reader.accept(mapper, ClassReader.EXPAND_FRAMES);
return wr.toByteArray();
}
}

View File

@ -30,6 +30,7 @@ package net.md_5.specialsource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -145,7 +146,16 @@ public class SpecialSource {
log("Remapping final jar");
Jar jar3 = Jar.init((File) options.valueOf("in-jar"));
JarRemapper.renameJar(jar3, (File) options.valueOf("out-jar"), jarMapping, options.has("live"));
List<IInheritanceProvider> inheritanceProviders = new ArrayList<IInheritanceProvider>();
inheritanceProviders.add(new JarInheritanceProvider(jar3));
if (options.has("live")) {
inheritanceProviders.add(new RuntimeInheritanceProvider());
}
JarRemapper jarRemapper = new JarRemapper(jarMapping, inheritanceProviders);
jarRemapper.remapJar(jar3, (File) options.valueOf("out-jar"));
}
}