package net.ayld.facade.bundle.impl; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import java.util.regex.Pattern; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.Sets; import net.ayld.facade.bundle.JarMaker; import net.ayld.facade.model.ClassFile; public class ManualJarMaker implements JarMaker{ private String facadeJarName = "facade.jar"; @Override public JarFile zip(Set<File> classFiles) throws IOException { makeOutputDir(); final JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(new File(facadeJarName))); final Set<String> dirEntries = Sets.newHashSet(); final Set<String> classEntries = Sets.newHashSet(); for (File classFile : classFiles) { final ClassFile clazz = ClassFile.fromFile(classFile); final String simpleName = clazz.qualifiedName().shortName(); final String packages = clazz.qualifiedName().toString().replaceAll(escapeRegexChars(simpleName), ""); final StringBuilder packageDirs = new StringBuilder(); for (String packageName : Splitter.on(".").split(packages)) { if (Strings.isNullOrEmpty(packageName)) { continue; } packageDirs.append(packageName).append(File.separator); if (!dirEntries.contains(packageDirs.toString())) { jarOut.putNextEntry(new JarEntry(packageDirs.toString())); } dirEntries.add(packageDirs.toString()); } final String classEntry = packageDirs.append(classFile.getName()).toString(); if (!classEntries.contains(classEntry)) { jarOut.putNextEntry(new JarEntry(classEntry)); final FileInputStream in = new FileInputStream(classFile); int len; final byte[] buf = new byte[1024]; while ((len = in.read(buf)) > 0) { jarOut.write(buf, 0, len); } jarOut.closeEntry(); in.close(); } classEntries.add(classEntry); } jarOut.close(); return new JarFile(facadeJarName); } private String escapeRegexChars(String str) { return Pattern.quote(str); } private void makeOutputDir() { // ignoring result because it is ok for the parent to exist new File(new File(facadeJarName).getParent()).mkdirs(); } public void setZippedJarName(String zippedJarName) { this.facadeJarName = zippedJarName; } }