();
private boolean filesOnly;
protected boolean verbose;
private static final ZipExtraField[] JAR_MARKER = new ZipExtraField[] {
JarMarker.getInstance()
};
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
public abstract void execute() throws BuildException;
public void execute(JarProcessor proc) throws BuildException {
this.proc = proc;
super.execute();
}
public void setFilesonly(boolean f) {
super.setFilesonly(f);
filesOnly = f;
}
protected void zipDir(File dir, ZipOutputStream zOut, String vPath, int mode)
throws IOException {
}
protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath,
long lastModified, File fromArchive, int mode) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IoUtil.pipe(is, baos, buf);
struct.data = baos.toByteArray();
struct.name = vPath;
struct.time = lastModified;
if (proc.process(struct)) {
if (mode == 0)
mode = ZipFileSet.DEFAULT_FILE_MODE;
if (!filesOnly) {
addParentDirs(struct.name, zOut);
}
super.zipFile(new ByteArrayInputStream(struct.data),
zOut, struct.name, struct.time, fromArchive, mode);
}
}
private void addParentDirs(String file, ZipOutputStream zOut) throws IOException {
int slash = file.lastIndexOf('/');
if (slash >= 0) {
String dir = file.substring(0, slash);
if (dirs.add(dir)) {
addParentDirs(dir, zOut);
super.zipDir((File) null, zOut, dir + "/", ZipFileSet.DEFAULT_DIR_MODE, JAR_MARKER);
}
}
}
public void reset() {
super.reset();
cleanHelper();
}
protected void cleanUp() {
super.cleanUp();
cleanHelper();
}
protected void cleanHelper() {
verbose = false;
filesOnly = false;
dirs.clear();
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/RuntimeIOException.java 0000644 0001750 0001750 00000001517 11063020300 027421 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import java.io.IOException;
public class RuntimeIOException extends RuntimeException
{
private static final long serialVersionUID = 0L;
public RuntimeIOException(IOException e) {
super(e);
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/JarTransformer.java 0000644 0001750 0001750 00000003116 11056273442 026646 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import java.io.*;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
abstract public class JarTransformer implements JarProcessor
{
public boolean process(EntryStruct struct) throws IOException {
if (struct.name.endsWith(".class")) {
ClassReader reader;
try {
reader = new ClassReader(struct.data);
} catch (Exception e) {
return true; // TODO?
}
GetNameClassWriter w = new GetNameClassWriter(ClassWriter.COMPUTE_MAXS);
reader.accept(transform(w), ClassReader.EXPAND_FRAMES);
struct.data = w.toByteArray();
struct.name = pathFromName(w.getClassName());
}
return true;
}
abstract protected ClassVisitor transform(ClassVisitor v);
private static String pathFromName(String className) {
return className.replace('.', '/') + ".class";
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/JarProcessor.java 0000644 0001750 0001750 00000002337 11747511453 026333 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import java.io.IOException;
public interface JarProcessor
{
/**
* Process the entry (p.ex. rename the file)
*
* Returns true
if the processor has has changed the entry. In this case, the entry can be removed
* from the jar file in a future time. Return false
for the entries which do not have been changed and
* there fore are not to be deleted
*
* @param struct
* @return true
if he process chain can continue after this process
* @throws IOException
*/
boolean process(EntryStruct struct) throws IOException;
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/EntryStruct.java 0000644 0001750 0001750 00000001415 11056300150 026200 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import java.io.InputStream;
import java.io.File;
public class EntryStruct
{
public byte[] data;
public String name;
public long time;
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/GetNameClassWriter.java 0000644 0001750 0001750 00000002465 11750456242 027422 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
public class GetNameClassWriter extends ClassVisitor
{
private String className;
public GetNameClassWriter(int flags) {
super(Opcodes.ASM4,new ClassWriter(flags));
}
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
className = name;
super.visit(version, access, name, signature, superName, interfaces);
}
public String getClassName() {
return className;
}
public byte[] toByteArray() {
return ((ClassWriter) cv).toByteArray();
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/IoUtil.java 0000644 0001750 0001750 00000010436 11747500723 025121 0 ustar drazzib drazzib /**
* Copyright 2008 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
class IoUtil {
private IoUtil() {}
public static void pipe(InputStream is, OutputStream out, byte[] buf) throws IOException {
for (;;) {
int amt = is.read(buf);
if (amt < 0)
break;
out.write(buf, 0, amt);
}
}
public static void copy(File from, File to, byte[] buf) throws IOException {
InputStream in = new FileInputStream(from);
try {
OutputStream out = new FileOutputStream(to);
try {
pipe(in, out, buf);
} finally {
out.close();
}
} finally {
in.close();
}
}
/**
* Create a copy of an zip file without its empty directories.
* @param inputFile
* @param outputFile
* @throws IOException
*/
public static void copyZipWithoutEmptyDirectories(final File inputFile, final File outputFile) throws IOException
{
final byte[] buf = new byte[0x2000];
final ZipFile inputZip = new ZipFile(inputFile);
final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(outputFile));
try
{
// read a the entries of the input zip file and sort them
final Enumeration extends ZipEntry> e = inputZip.entries();
final ArrayList sortedList = new ArrayList();
while (e.hasMoreElements()) {
final ZipEntry entry = e.nextElement();
sortedList.add(entry);
}
Collections.sort(sortedList, new Comparator()
{
public int compare(ZipEntry o1, ZipEntry o2)
{
return o1.getName().compareTo(o2.getName());
}
});
// treat them again and write them in output, wenn they not are empty directories
for (int i = sortedList.size()-1; i>=0; i--)
{
final ZipEntry inputEntry = sortedList.get(i);
final String name = inputEntry.getName();
final boolean isEmptyDirectory;
if (inputEntry.isDirectory())
{
if (i == sortedList.size()-1)
{
// no item afterwards; it was an empty directory
isEmptyDirectory = true;
}
else
{
final String nextName = sortedList.get(i+1).getName();
isEmptyDirectory = !nextName.startsWith(name);
}
}
else
{
isEmptyDirectory = false;
}
// write the entry
if (isEmptyDirectory)
{
sortedList.remove(inputEntry);
}
else
{
final ZipEntry outputEntry = new ZipEntry(inputEntry);
outputStream.putNextEntry(outputEntry);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final InputStream is = inputZip.getInputStream(inputEntry);
IoUtil.pipe(is, baos, buf);
is.close();
outputStream.write(baos.toByteArray());
}
}
} finally {
outputStream.close();
}
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/RemappingClassTransformer.java 0000644 0001750 0001750 00000002072 11750456242 031044 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.commons.RemappingClassAdapter;
import com.tonicsystems.jarjar.EmptyClassVisitor;
public class RemappingClassTransformer extends RemappingClassAdapter
{
public RemappingClassTransformer(Remapper pr) {
super(new EmptyClassVisitor(), pr);
}
public void setTarget(ClassVisitor target) {
cv = target;
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/JarProcessorChain.java 0000644 0001750 0001750 00000002356 11747511453 027277 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import java.io.IOException;
public class JarProcessorChain implements JarProcessor
{
private final JarProcessor[] chain;
public JarProcessorChain(JarProcessor[] chain)
{
this.chain = chain.clone();
}
/**
* @param struct
* @return true
if the entry has run the complete chain
* @throws IOException
*/
public boolean process(EntryStruct struct) throws IOException
{
for (JarProcessor aChain : chain)
{
if (!aChain.process(struct))
{
return false;
}
}
return true;
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/util/JarTransformerChain.java 0000644 0001750 0001750 00000002166 11750456242 027617 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar.util;
import org.objectweb.asm.ClassVisitor;
public class JarTransformerChain extends JarTransformer
{
private final RemappingClassTransformer[] chain;
public JarTransformerChain(RemappingClassTransformer[] chain) {
this.chain = chain.clone();
for (int i = chain.length - 1; i > 0; i--) {
chain[i - 1].setTarget(chain[i]);
}
}
protected ClassVisitor transform(ClassVisitor v) {
chain[chain.length - 1].setTarget(v);
return chain[0];
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/KeepProcessor.java 0000644 0001750 0001750 00000007317 11774401557 025534 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar;
import com.tonicsystems.jarjar.util.*;
import java.io.*;
import java.util.*;
import org.objectweb.asm.*;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.*;
// TODO: this can probably be refactored into JarClassVisitor, etc.
class KeepProcessor extends Remapper implements JarProcessor
{
private final ClassVisitor cv = new RemappingClassAdapter(new EmptyClassVisitor(), this);
private final List wildcards;
private final List roots = new ArrayList();
private final Map> depend = new HashMap>();
public KeepProcessor(List patterns) {
wildcards = PatternElement.createWildcards(patterns);
}
public boolean isEnabled() {
return !wildcards.isEmpty();
}
public Set getExcludes() {
Set closure = new HashSet();
closureHelper(closure, roots);
Set removable = new HashSet(depend.keySet());
removable.removeAll(closure);
return removable;
}
private void closureHelper(Set closure, Collection process) {
if (process == null)
return;
for (String name : process) {
if (closure.add(name))
closureHelper(closure, depend.get(name));
}
}
private Set curSet;
private byte[] buf = new byte[0x2000];
public boolean process(EntryStruct struct) throws IOException {
try {
if (struct.name.endsWith(".class")) {
String name = struct.name.substring(0, struct.name.length() - 6);
for (Wildcard wildcard : wildcards)
if (wildcard.matches(name))
roots.add(name);
depend.put(name, curSet = new HashSet());
new ClassReader(new ByteArrayInputStream(struct.data)).accept(cv,
ClassReader.EXPAND_FRAMES);
curSet.remove(name);
}
} catch (Exception e) {
System.err.println("Error reading " + struct.name + ": " + e.getMessage());
}
return true;
}
public String map(String key) {
if (key.startsWith("java/") || key.startsWith("javax/"))
return null;
curSet.add(key);
return null;
}
public Object mapValue(Object value) {
if (value instanceof String) {
String s = (String)value;
if (PackageRemapper.isArrayForName(s)) {
mapDesc(s.replace('.', '/'));
} else if (isForName(s)) {
map(s.replace('.', '/'));
}
return value;
} else {
return super.mapValue(value);
}
}
// TODO: use this for package remapping too?
private static boolean isForName(String value) {
if (value.equals(""))
return false;
for (int i = 0, len = value.length(); i < len; i++) {
char c = value.charAt(i);
if (c != '.' && !Character.isJavaIdentifierPart(c))
return false;
}
return true;
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/ResourceProcessor.java 0000644 0001750 0001750 00000002064 10642461000 026407 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar;
import com.tonicsystems.jarjar.util.*;
import java.io.IOException;
import java.util.*;
class ResourceProcessor implements JarProcessor
{
private PackageRemapper pr;
public ResourceProcessor(PackageRemapper pr) {
this.pr = pr;
}
public boolean process(EntryStruct struct) throws IOException {
if (!struct.name.endsWith(".class"))
struct.name = pr.mapPath(struct.name);
return true;
}
}
jarjar-1.4+svn142/src/main/com/tonicsystems/jarjar/Main.java 0000644 0001750 0001750 00000006100 11064074777 023623 0 ustar drazzib drazzib /**
* Copyright 2007 Google Inc.
*
* 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.
*/
package com.tonicsystems.jarjar;
import com.tonicsystems.jarjar.util.*;
import java.io.*;
import java.util.*;
public class Main {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
private static final String HELP;
static {
try {
HELP = readIntoString(Main.class.getResourceAsStream("help.txt"));
} catch (IOException e) {
throw new RuntimeIOException(e);
}
}
private static String readIntoString(InputStream in) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String line = null;
while ((line = r.readLine()) != null)
sb.append(line).append(LINE_SEPARATOR);
return sb.toString();
}
private boolean verbose;
private List patterns;
private int level = DepHandler.LEVEL_CLASS;
public static void main(String[] args) throws Exception {
MainUtil.runMain(new Main(), args, "help");
}
public void help() {
System.err.print(HELP);
}
public void strings(String cp) throws IOException {
if (cp == null) {
throw new IllegalArgumentException("cp is required");
}
new StringDumper().run(cp, new PrintWriter(System.out));
}
// TODO: make level an enum
public void find(String level, String cp1, String cp2) throws IOException {
if (level == null || cp1 == null) {
throw new IllegalArgumentException("level and cp1 are required");
}
if (cp2 == null) {
cp2 = cp1;
}
int levelFlag;
if ("class".equals(level)) {
levelFlag = DepHandler.LEVEL_CLASS;
} else if ("jar".equals(level)) {
levelFlag = DepHandler.LEVEL_JAR;
} else {
throw new IllegalArgumentException("unknown level " + level);
}
PrintWriter w = new PrintWriter(System.out);
DepHandler handler = new TextDepHandler(w, levelFlag);
new DepFind().run(cp1, cp2, handler);
w.flush();
}
public void process(File rulesFile, File inJar, File outJar) throws IOException {
if (rulesFile == null || inJar == null || outJar == null) {
throw new IllegalArgumentException("rulesFile, inJar, and outJar are required");
}
List rules = RulesFileParser.parse(rulesFile);
boolean verbose = Boolean.getBoolean("verbose");
boolean skipManifest = Boolean.getBoolean("skipManifest");
MainProcessor proc = new MainProcessor(rules, verbose, skipManifest);
StandaloneJarProcessor.run(inJar, outJar, proc);
proc.strip(outJar);
}
}
jarjar-1.4+svn142/src/test/ 0000755 0001750 0001750 00000000000 12072651464 015331 5 ustar drazzib drazzib jarjar-1.4+svn142/src/test/Generics.class 0000644 0001750 0001750 00000001077 10162734146 020121 0 ustar drazzib drazzib Êþº¾ 1 '
()V Code LineNumberTable count (Ljava/util/List;)I Signature '(Ljava/util/List;)I
SourceFile
Generics.java
! " # $ java/lang/String % & Generics java/lang/Object java/util/List iterator ()Ljava/util/Iterator; java/util/Iterator hasNext ()Z next ()Ljava/lang/Object; length ()I !
*· ±
L (<*¹ M,¹ ™ ,¹ À N-¶ `<§ÿæ¬ &