package org.sinrel.engine.util; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; import javassist.CannotCompileException; import javassist.CtClass; public class VirtualZipModifer { private File file; private ZipFile zipFile; private Map<String, byte[]> virtualEntries; public VirtualZipModifer(File file) throws ZipException, IOException { this.file = file; virtualEntries = new HashMap<String, byte[]>(); } public File getFile() { return file; } public byte[] getBytes(String key) { return virtualEntries.get(key); } public Map<String, byte[]> getEntriesMap() { synchronized (this) { return virtualEntries; } } public void putEntry(String key, byte[] value) { synchronized (this) { virtualEntries.put(key, value); } } public void putClass(CtClass clazz) throws IOException, CannotCompileException { synchronized (this) { virtualEntries.put(clazz.getName().replace('.', '/') + ".class", clazz.toBytecode()); } } public void write() throws IOException, InterruptedException { write(false); } public void write(boolean ignoreMetaInf) throws IOException, InterruptedException { synchronized (this) { Map<String, byte[]> newEntries = new HashMap<String, byte[]>(); zipFile = new ZipFile(file); Enumeration<? extends ZipEntry> numer = zipFile.entries(); while (numer.hasMoreElements()) { ZipEntry entry = numer.nextElement(); String name = entry.getName(); if (!(ignoreMetaInf && name.startsWith("META-INF"))) { if (!virtualEntries.containsKey(name)) newEntries.put(name, toByteArray(zipFile.getInputStream(entry))); } } zipFile.close(); Set<Entry<String, byte[]>> entrySet1 = virtualEntries.entrySet(); for (Entry<String, byte[]> entry : entrySet1) { String name = entry.getKey(); if (!(ignoreMetaInf && name.startsWith("META-INF"))) { newEntries.put(name, entry.getValue()); } } ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file))); try { Set<Entry<String, byte[]>> entrySet2 = newEntries.entrySet(); for (Entry<String, byte[]> entry : entrySet2) { zos.putNextEntry(new ZipEntry(entry.getKey())); zos.write(entry.getValue()); zos.closeEntry(); } Thread.sleep(0, 1); } finally { zos.flush(); zos.close(); } virtualEntries.clear(); } } private byte[] toByteArray(InputStream input) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = new byte[1024 * 4]; int n = 0; while (-1 != (n = input.read(buffer))) output.write(buffer, 0, n); return output.toByteArray(); } }