content: package eu.the5zig.util.io;
  
  import eu.the5zig.util.Callback;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.jar.JarEntry;
  import java.util.jar.JarFile;
  
  /**
   * Created by 5zig.
   * All rights reserved © 2015
   */
  public class NotifiableJarCopier {
  
  	private final File[] jarFiles;
  	private final File destinationJar;
  	private final Callback<Float> callback;
  	private long length;
  
  	private NotifiableJarCopier(File[] jarFiles, File destinationJar, Callback<Float> callback) throws IOException {
  		this.jarFiles = jarFiles;
  		this.destinationJar = destinationJar;
  		this.callback = callback;
  		for (File jarFile : jarFiles) {
  			JarFile file = new JarFile(jarFile);
  			Enumeration entries = file.entries();
  			while (entries.hasMoreElements()) {
  				length += ((JarEntry) entries.nextElement()).getSize();
  			}
  		}
  		run();
  	}
  
  	public static NotifiableJarCopier copy(File[] jarFiles, File destinationJar, Callback<Float> callback) throws IOException {
  		return new NotifiableJarCopier(jarFiles, destinationJar, callback);
  	}
  
  	public static NotifiableJarCopier copy(File[] jarFiles, File destinationJar) throws IOException {
  		return copy(jarFiles, destinationJar, null);
  	}
  
  	public void run() throws IOException {
  		CountingJarOutputStream tempJar = null;
  		try {
  			tempJar = new CountingJarOutputStream(new FileOutputStream(destinationJar));
  			ArrayList<String> entryList = new ArrayList<String>();
  
  			int j = jarFiles.length;
  
  			for (int i = 0; i < j; i++) {
  				File jarFile = jarFiles[i];
  				JarFile jar = null;
  				try {
  					jar = new JarFile(jarFile);
  
  					for (Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); ) {
  						JarEntry entry = new JarEntry(entries.nextElement().getName());
  						if (!entryList.contains(entry.getName())) {
  							entryList.add(entry.getName());
  							if ((i == 0) || (!entry.getName().startsWith("META-INF/"))) {
  
  								InputStream entryStream = jar.getInputStream(entry);
  
  								tempJar.putNextEntry(entry);
  								int bytesRead;
  								byte[] buffer = new byte[1024 * 8];
  								while ((bytesRead = entryStream.read(buffer)) > 0) {
  									tempJar.write(buffer, 0, bytesRead);
  									if (callback != null)
  										callback.call((float) tempJar.getCount() / (float) length);
  								}
  								entryStream.close();
  								tempJar.flush();
  								tempJar.closeEntry();
  							}
  						}
  					}
  				} finally {
  					if (jar != null)
  						jar.close();
  				}
  			}
  		} finally {
  			if (tempJar != null)
  				tempJar.close();
  		}
  	}
  }
  