package bytecode;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public abstract class BaseStreamingZipProcessor {
public void go(String[] args) {
if(args.length != (hasConfig() ? 1 : 0)) {
if(hasConfig())
System.err.println("Usage: java "+getClass().getSimpleName()+" config.txt < infile.jar > outfile.jar");
else
System.err.println("Usage: java "+getClass().getSimpleName()+" < infile.jar > outfile.jar");
System.exit(1);
}
try {
if(hasConfig())
loadConfig(new File(args[0]));
go(System.in, System.out);
} catch(Throwable t) {
t.printStackTrace();
System.exit(1);
}
System.exit(0);
}
public void go(InputStream in, OutputStream out) throws Exception {
try (ZipInputStream zipIn = new ZipInputStream(in)) {
try (ZipOutputStream zipOut = new ZipOutputStream(out)) {
ZipEntry ze;
while((ze = zipIn.getNextEntry()) != null) {
zipOut.putNextEntry(new ZipEntry(ze.getName()));
if(ze.getName().endsWith("/") || !shouldProcess(ze.getName())) {
copyResource(zipIn, zipOut);
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
copyResource(zipIn, baos);
byte[] bytes = baos.toByteArray();
bytes = process(bytes, ze.getName());
zipOut.write(bytes);
}
zipIn.closeEntry();
zipOut.closeEntry();
}
}
}
done();
}
protected void done() throws Exception {}
public abstract boolean hasConfig();
protected abstract boolean shouldProcess(String name);
public abstract void loadConfig(File file) throws Exception;
protected abstract byte[] process(byte[] in, String name) throws Exception;
private static byte[] buffer = new byte[32768];
public static void copyResource(InputStream zipIn, OutputStream zipOut) throws IOException {
while(true) {
int read = zipIn.read(buffer);
if(read <= 0)
break;
zipOut.write(buffer, 0, read);
}
}
}