package org.camunda.bpm.extension.osgi.itest.application;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import org.apache.commons.io.FileUtils;
public class JarFileBuilder {
private File file;
private JarOutputStream jarOut;
private List<String> dirEntries = new ArrayList<String>();
private String manifest;
private Map<String, File> files = new HashMap<String, File>();
public JarFileBuilder(String jarFileName) {
this.file = new File(jarFileName);
file.deleteOnExit();
try {
FileOutputStream fout = new FileOutputStream(file);
jarOut = new JarOutputStream(fout);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public JarFileBuilder addDirEntry(String dirName) {
dirEntries.add(dirName);
try {
jarOut.putNextEntry(new ZipEntry(dirName));
jarOut.closeEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
return this;
}
/**
* Splits the dirNames string at the slashes
*
* @param dirNames
* @return
*/
public JarFileBuilder addDirEntries(String dirNames) {
dirEntries.add(dirNames);
return this;
}
public JarFileBuilder addFileEntry(String fileNameInJar, File file) {
files.put(fileNameInJar, file);
return this;
}
/**
* Adds a MANIFEST.MF to the jar in the default location (META-INF). The
* Manifest-String can be one line, separated by \n but no spaces, e.g.
* <p>
* <code>
* Manifest-Version: 1.0\nBundle-SymbolicName: bar.foo\nBundle-Version: 1.0.0\n
* </code>
*
* @param manifest
* @return
*/
public JarFileBuilder addManifest(String manifest) {
this.manifest = manifest;
return this;
}
public File createJarFile() {
// I have to wait till the end to assemble the jar because
// java.util.jar.JarInputStream expects META-INF/MANIFEST.MF
// to be the first directory in the jar
createManifest();
createDirectories();
createFiles();
try {
jarOut.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return file;
}
private void createFiles() {
try {
for (Entry<String, File> entry : files.entrySet()) {
jarOut.putNextEntry(new ZipEntry(entry.getKey()));
jarOut.write(FileUtils.readFileToByteArray(entry.getValue()));
jarOut.closeEntry();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void createDirectories() {
try {
for (String dirName : dirEntries) {
String dirsConcatenated = "";
for (String s : dirName.split("/")) {
dirsConcatenated += s + "/";
jarOut.putNextEntry(new ZipEntry(dirsConcatenated));
jarOut.closeEntry();
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void createManifest() {
if (manifest != null) {
try {
jarOut.putNextEntry(new ZipEntry("META-INF/"));
jarOut.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
jarOut.write(manifest.getBytes());
jarOut.closeEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}