package repackager;
import static java.util.jar.Pack200.Packer.*;
import java.io.*;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import org.apache.commons.io.FileUtils;
import com.google.common.io.Files;
@SuppressWarnings("Duplicates")
public class RepackJars {
static StringBuilder log = new StringBuilder();
public static void main(String[] args) throws IOException, InterruptedException {
// new RepackJars().execute(rootFile("lib/eclipse44"));
// new RepackJars().execute(rootFile("lib/eclipse"));
new RepackJars().execute(rootFile("support/eclipseLibs/lib"));
System.out.println("-----------------");
System.out.println("-----------------");
System.out.println("-----------------");
System.out.println(log);
}
private static File rootFile(String s) throws IOException {
File file = new File(s);
if (file.exists()) {
return file;
}
file = new File("../", s);
if (file.exists()) {
return file;
}
throw new RuntimeException(file.getCanonicalPath() + " does not exists");
}
private void execute(File sourceDir) throws IOException, InterruptedException {
List<File> files = getJars(sourceDir);
// List<File> files = Arrays.asList(new
// File("F:\\workspace\\_projekty\\Github\\EclipseCodeFormatter4\\lib\\eclipse\\org.eclipse.jdt.core_3.11.1.v20150902-1521.jar"));
File tempDir = new File(sourceDir, "temp");
tempDir.mkdir();
for (File jar : files) {
File destJar = new File(tempDir, jar.getName());
//
removeCrap(jar, destJar, new Condition<JarEntry>() {
@Override
public boolean isCrap(JarEntry entry) {
return !entry.getName().startsWith("org") && !entry.getName().startsWith("com");
}
});
repack(destJar);
moveJar(destJar, jar);
System.out.println("-----------------");
}
}
private void moveJar(File from, File to) throws IOException {
print("moving " + from.getCanonicalPath() + " to " + to.getCanonicalPath());
if (!to.delete()) {
throw new RuntimeException("delete failed: " + to.getCanonicalPath()+ " exists:"+to.exists());
}
FileUtils.copyFile(from, to);
from.delete();
}
private interface Condition<T> {
boolean isCrap(T var1);
}
private void removeCrap(File srcJarFile, File dest, Condition<JarEntry> condition) throws IOException {
print("removing crap from " + srcJarFile);
File tmpJarFile = File.createTempFile("tempJar", ".tmp");
tmpJarFile.deleteOnExit();
JarFile jarFile = new JarFile(srcJarFile);
boolean jarUpdated = false;
try {
JarOutputStream tempJarOutputStream = new JarOutputStream(new FileOutputStream(tmpJarFile));
try {
Enumeration jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry entry = (JarEntry) jarEntries.nextElement();
if (condition.isCrap(entry)) {
System.out.println("\t\tremoving crap: " + entry.getName());
continue;
}
InputStream entryInputStream = jarFile.getInputStream(entry);
tempJarOutputStream.putNextEntry(entry);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = entryInputStream.read(buffer)) != -1) {
tempJarOutputStream.write(buffer, 0, bytesRead);
}
}
jarUpdated = true;
} catch (Exception ex) {
throw new RuntimeException(ex);
} finally {
tempJarOutputStream.close();
}
} finally {
jarFile.close();
if (!jarUpdated) {
tmpJarFile.delete();
}
}
if (jarUpdated) {
dest.delete();
tmpJarFile.renameTo(dest);
print("\tcrap removed: " + dest.getName() + " (" + size(dest) + ", original " + size(srcJarFile) + ")");
} else {
throw new RuntimeException(srcJarFile.getCanonicalPath() + " not updated.");
}
}
private void print(String s) {
log.append(s).append("\n");
System.out.println(s);
}
private List<File> getJars(File dir) throws IOException {
print("searching for jars in " + dir.getCanonicalPath());
List<File> files = new ArrayList<File>();
for (File next : Files.fileTreeTraverser().children(dir)) {
String name = next.getName();
if (name.startsWith("adapter")) {
continue;
}
if (name.endsWith(".jar") || name.endsWith(".zip")) {
files.add(next);
}
}
return files;
}
private void repack(File file) throws IOException {
try {
print("repackaging: " + file.getName());
Pack200Utils.normalize(file, properties());
print("\tcompressed: " + file.getName() + " (" + size(file) + ")");
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
private String size(File file) {
double bytes = file.length();
long kilobytes = (long) (bytes / 1024);
return kilobytes + " kb";
}
private Map<String, String> properties() {
// Create the Packer object
Pack200.Packer packer = Pack200.newPacker();
Map<String, String> p = packer.properties();
p.put(Pack200.Packer.EFFORT, "9"); // default is "5"
p.put(Pack200.Packer.SEGMENT_LIMIT, "-1");
p.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.FALSE);
p.put(Pack200.Packer.MODIFICATION_TIME, Pack200.Packer.LATEST);
p.put(Pack200.Packer.DEFLATE_HINT, Pack200.Packer.TRUE); // compression enabled
// p.put("com.sun.java.util.jar.pack.verbose", Pack200.Packer.FALSE);
// p.put("com.sun.java.util.jar.pack.nolog", Pack200.Packer.TRUE);
String[] attributes = { UNKNOWN_ATTRIBUTE, CLASS_ATTRIBUTE_PFX, FIELD_ATTRIBUTE_PFX, METHOD_ATTRIBUTE_PFX,
CODE_ATTRIBUTE_PFX, };
String[] stripCodeAttributes = { "SourceFile", "LineNumberTable", "LocalVariableTable", "Deprecated" };
for (String attribute : attributes) {
for (String attributeName : stripCodeAttributes) {
p.put(attribute + attributeName, Pack200.Packer.STRIP);
}
}
p.put(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.STRIP);
return p;
}
/*
* Copyright 2001-2016 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
* the specific language governing permissions and limitations under the License.
*/
public static class Pack200Utils {
private Pack200Utils() {
}
public static void normalize(File jar) throws IOException {
normalize(jar, jar, (Map) null);
}
public static void normalize(File jar, Map<String, String> props) throws IOException {
normalize(jar, jar, props);
}
public static void normalize(File from, File to) throws IOException {
normalize(from, to, (Map) null);
}
public static void normalize(File from, File to, Map<String, String> props) throws IOException {
if (props == null) {
props = new HashMap();
}
((Map) props).put("pack.segment.limit", "-1");
File f = File.createTempFile("commons-compress", "pack200normalize");
f.deleteOnExit();
try {
Object os = new FileOutputStream(f);
Object j = null;
try {
Pack200.Packer p = Pack200.newPacker();
p.properties().putAll((Map) props);
p.pack(new JarFile(from), (OutputStream) os);
j = null;
((OutputStream) os).close();
os = null;
Pack200.Unpacker u = Pack200.newUnpacker();
os = new JarOutputStream(new FileOutputStream(to));
u.unpack(f, (JarOutputStream) os);
} finally {
if (j != null) {
((JarFile) j).close();
}
if (os != null) {
((OutputStream) os).close();
}
}
} finally {
f.delete();
}
}
}
}