6888127: java.util.jar.Pack200.Packer Memory Leak
Reviewed-by: jrose
This commit is contained in:
parent
51e553fe0e
commit
facee61c79
jdk/src/share/classes/com/sun/java/util/jar/pack
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,6 @@ package com.sun.java.util.jar.pack;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import com.sun.java.util.jar.pack.Package.Class;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.*;
|
||||
|
||||
/**
|
||||
@ -96,20 +95,20 @@ class Attribute implements Comparable, Constants {
|
||||
return this.def.compareTo(that.def);
|
||||
}
|
||||
|
||||
static private final byte[] noBytes = {};
|
||||
static private final HashMap canonLists = new HashMap();
|
||||
static private final HashMap attributes = new HashMap();
|
||||
static private final HashMap standardDefs = new HashMap();
|
||||
private static final byte[] noBytes = {};
|
||||
private static final Map<List<Attribute>, List<Attribute>> canonLists = new HashMap<>();
|
||||
private static final Map<Layout, Attribute> attributes = new HashMap<>();
|
||||
private static final Map<Layout, Attribute> standardDefs = new HashMap<>();
|
||||
|
||||
// Canonicalized lists of trivial attrs (Deprecated, etc.)
|
||||
// are used by trimToSize, in order to reduce footprint
|
||||
// of some common cases. (Note that Code attributes are
|
||||
// always zero size.)
|
||||
public static List getCanonList(List al) {
|
||||
public static List getCanonList(List<Attribute> al) {
|
||||
synchronized (canonLists) {
|
||||
List cl = (List) canonLists.get(al);
|
||||
List<Attribute> cl = canonLists.get(al);
|
||||
if (cl == null) {
|
||||
cl = new ArrayList(al.size());
|
||||
cl = new ArrayList<>(al.size());
|
||||
cl.addAll(al);
|
||||
cl = Collections.unmodifiableList(cl);
|
||||
canonLists.put(al, cl);
|
||||
@ -122,7 +121,7 @@ class Attribute implements Comparable, Constants {
|
||||
public static Attribute find(int ctype, String name, String layout) {
|
||||
Layout key = Layout.makeKey(ctype, name, layout);
|
||||
synchronized (attributes) {
|
||||
Attribute a = (Attribute) attributes.get(key);
|
||||
Attribute a = attributes.get(key);
|
||||
if (a == null) {
|
||||
a = new Layout(ctype, name, layout).canonicalInstance();
|
||||
attributes.put(key, a);
|
||||
@ -131,24 +130,29 @@ class Attribute implements Comparable, Constants {
|
||||
}
|
||||
}
|
||||
|
||||
public static Object keyForLookup(int ctype, String name) {
|
||||
public static Layout keyForLookup(int ctype, String name) {
|
||||
return Layout.makeKey(ctype, name);
|
||||
}
|
||||
|
||||
// Find canonical empty attribute with given ctype and name,
|
||||
// and with the standard layout.
|
||||
public static Attribute lookup(Map defs, int ctype, String name) {
|
||||
if (defs == null) defs = standardDefs;
|
||||
return (Attribute) defs.get(Layout.makeKey(ctype, name));
|
||||
public static Attribute lookup(Map<Layout, Attribute> defs, int ctype,
|
||||
String name) {
|
||||
if (defs == null) {
|
||||
defs = standardDefs;
|
||||
}
|
||||
return defs.get(Layout.makeKey(ctype, name));
|
||||
}
|
||||
public static Attribute define(Map defs, int ctype, String name, String layout) {
|
||||
|
||||
public static Attribute define(Map<Layout, Attribute> defs, int ctype,
|
||||
String name, String layout) {
|
||||
Attribute a = find(ctype, name, layout);
|
||||
defs.put(Layout.makeKey(ctype, name), a);
|
||||
return a;
|
||||
}
|
||||
|
||||
static {
|
||||
Map sd = standardDefs;
|
||||
Map<Layout, Attribute> sd = standardDefs;
|
||||
define(sd, ATTR_CONTEXT_CLASS, "Signature", "RSH");
|
||||
define(sd, ATTR_CONTEXT_CLASS, "Synthetic", "");
|
||||
define(sd, ATTR_CONTEXT_CLASS, "Deprecated", "");
|
||||
@ -244,7 +248,7 @@ class Attribute implements Comparable, Constants {
|
||||
+"\n ()[] ]"
|
||||
)
|
||||
};
|
||||
Map sd = standardDefs;
|
||||
Map<Layout, Attribute> sd = standardDefs;
|
||||
String defaultLayout = mdLayouts[2];
|
||||
String annotationsLayout = mdLayouts[1] + mdLayouts[2];
|
||||
String paramsLayout = mdLayouts[0] + annotationsLayout;
|
||||
@ -275,10 +279,6 @@ class Attribute implements Comparable, Constants {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Map getStandardDefs() {
|
||||
return new HashMap(standardDefs);
|
||||
}
|
||||
|
||||
/** Base class for any attributed object (Class, Field, Method, Code).
|
||||
* Flags are included because they are used to help transmit the
|
||||
* presence of attributes. That is, flags are a mix of modifier
|
||||
@ -291,7 +291,7 @@ class Attribute implements Comparable, Constants {
|
||||
protected abstract Entry[] getCPMap();
|
||||
|
||||
protected int flags; // defined here for convenience
|
||||
protected List attributes;
|
||||
protected List<Attribute> attributes;
|
||||
|
||||
public int attributeSize() {
|
||||
return (attributes == null) ? 0 : attributes.size();
|
||||
@ -301,16 +301,15 @@ class Attribute implements Comparable, Constants {
|
||||
if (attributes == null) {
|
||||
return;
|
||||
}
|
||||
if (attributes.size() == 0) {
|
||||
if (attributes.isEmpty()) {
|
||||
attributes = null;
|
||||
return;
|
||||
}
|
||||
if (attributes instanceof ArrayList) {
|
||||
ArrayList al = (ArrayList) attributes;
|
||||
ArrayList<Attribute> al = (ArrayList<Attribute>)attributes;
|
||||
al.trimToSize();
|
||||
boolean allCanon = true;
|
||||
for (Iterator i = al.iterator(); i.hasNext(); ) {
|
||||
Attribute a = (Attribute) i.next();
|
||||
for (Attribute a : al) {
|
||||
if (!a.isCanonical()) {
|
||||
allCanon = false;
|
||||
}
|
||||
@ -330,9 +329,9 @@ class Attribute implements Comparable, Constants {
|
||||
|
||||
public void addAttribute(Attribute a) {
|
||||
if (attributes == null)
|
||||
attributes = new ArrayList(3);
|
||||
attributes = new ArrayList<>(3);
|
||||
else if (!(attributes instanceof ArrayList))
|
||||
attributes = new ArrayList(attributes); // unfreeze it
|
||||
attributes = new ArrayList<>(attributes); // unfreeze it
|
||||
attributes.add(a);
|
||||
}
|
||||
|
||||
@ -340,32 +339,31 @@ class Attribute implements Comparable, Constants {
|
||||
if (attributes == null) return null;
|
||||
if (!attributes.contains(a)) return null;
|
||||
if (!(attributes instanceof ArrayList))
|
||||
attributes = new ArrayList(attributes); // unfreeze it
|
||||
attributes = new ArrayList<>(attributes); // unfreeze it
|
||||
attributes.remove(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
public Attribute getAttribute(int n) {
|
||||
return (Attribute) attributes.get(n);
|
||||
return attributes.get(n);
|
||||
}
|
||||
|
||||
protected void visitRefs(int mode, Collection refs) {
|
||||
protected void visitRefs(int mode, Collection<Entry> refs) {
|
||||
if (attributes == null) return;
|
||||
for (Iterator i = attributes.iterator(); i.hasNext(); ) {
|
||||
Attribute a = (Attribute) i.next();
|
||||
for (Attribute a : attributes) {
|
||||
a.visitRefs(this, mode, refs);
|
||||
}
|
||||
}
|
||||
|
||||
static final List noAttributes = Arrays.asList(new Object[0]);
|
||||
static final List<Attribute> noAttributes = Arrays.asList(new Attribute[0]);
|
||||
|
||||
public List getAttributes() {
|
||||
public List<Attribute> getAttributes() {
|
||||
if (attributes == null)
|
||||
return noAttributes;
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(List attrList) {
|
||||
public void setAttributes(List<Attribute> attrList) {
|
||||
if (attrList.isEmpty())
|
||||
attributes = null;
|
||||
else
|
||||
@ -374,8 +372,7 @@ class Attribute implements Comparable, Constants {
|
||||
|
||||
public Attribute getAttribute(String attrName) {
|
||||
if (attributes == null) return null;
|
||||
for (Iterator i = attributes.iterator(); i.hasNext(); ) {
|
||||
Attribute a = (Attribute) i.next();
|
||||
for (Attribute a : attributes) {
|
||||
if (a.name().equals(attrName))
|
||||
return a;
|
||||
}
|
||||
@ -384,8 +381,7 @@ class Attribute implements Comparable, Constants {
|
||||
|
||||
public Attribute getAttribute(Layout attrDef) {
|
||||
if (attributes == null) return null;
|
||||
for (Iterator i = attributes.iterator(); i.hasNext(); ) {
|
||||
Attribute a = (Attribute) i.next();
|
||||
for (Attribute a : attributes) {
|
||||
if (a.layout() == attrDef)
|
||||
return a;
|
||||
}
|
||||
@ -457,14 +453,8 @@ class Attribute implements Comparable, Constants {
|
||||
public String layout() { return layout; }
|
||||
public Attribute canonicalInstance() { return canon; }
|
||||
|
||||
// Cache of name reference.
|
||||
private Entry nameRef; // name, for use by visitRefs
|
||||
public Entry getNameRef() {
|
||||
Entry nameRef = this.nameRef;
|
||||
if (nameRef == null) {
|
||||
this.nameRef = nameRef = ConstantPool.getUtf8Entry(name());
|
||||
}
|
||||
return nameRef;
|
||||
return ConstantPool.getUtf8Entry(name());
|
||||
}
|
||||
|
||||
public boolean isEmpty() { return layout == ""; }
|
||||
@ -834,14 +824,14 @@ class Attribute implements Comparable, Constants {
|
||||
*/
|
||||
static //private
|
||||
Layout.Element[] tokenizeLayout(Layout self, int curCble, String layout) {
|
||||
ArrayList col = new ArrayList(layout.length());
|
||||
ArrayList<Layout.Element> col = new ArrayList<>(layout.length());
|
||||
tokenizeLayout(self, curCble, layout, col);
|
||||
Layout.Element[] res = new Layout.Element[col.size()];
|
||||
col.toArray(res);
|
||||
return res;
|
||||
}
|
||||
static //private
|
||||
void tokenizeLayout(Layout self, int curCble, String layout, ArrayList col) {
|
||||
void tokenizeLayout(Layout self, int curCble, String layout, ArrayList<Layout.Element> col) {
|
||||
boolean prevBCI = false;
|
||||
for (int len = layout.length(), i = 0; i < len; ) {
|
||||
int start = i;
|
||||
@ -899,7 +889,7 @@ class Attribute implements Comparable, Constants {
|
||||
case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']'
|
||||
kind = EK_UN;
|
||||
i = tokenizeSInt(e, layout, i);
|
||||
ArrayList cases = new ArrayList();
|
||||
ArrayList<Layout.Element> cases = new ArrayList<>();
|
||||
for (;;) {
|
||||
// Keep parsing cases until we hit the default case.
|
||||
if (layout.charAt(i++) != '(')
|
||||
@ -1053,7 +1043,7 @@ class Attribute implements Comparable, Constants {
|
||||
}
|
||||
static //private
|
||||
String[] splitBodies(String layout) {
|
||||
ArrayList bodies = new ArrayList();
|
||||
ArrayList<String> bodies = new ArrayList<>();
|
||||
// Parse several independent layout bodies: "[foo][bar]...[baz]"
|
||||
for (int i = 0; i < layout.length(); i++) {
|
||||
if (layout.charAt(i++) != '[')
|
||||
@ -1132,7 +1122,9 @@ class Attribute implements Comparable, Constants {
|
||||
int parseIntBefore(String layout, int dash) {
|
||||
int end = dash;
|
||||
int beg = end;
|
||||
while (beg > 0 && isDigit(layout.charAt(beg-1))) --beg;
|
||||
while (beg > 0 && isDigit(layout.charAt(beg-1))) {
|
||||
--beg;
|
||||
}
|
||||
if (beg == end) return Integer.parseInt("empty");
|
||||
// skip backward over a sign
|
||||
if (beg >= 1 && layout.charAt(beg-1) == '-') --beg;
|
||||
@ -1145,7 +1137,9 @@ class Attribute implements Comparable, Constants {
|
||||
int end = beg;
|
||||
int limit = layout.length();
|
||||
if (end < limit && layout.charAt(end) == '-') ++end;
|
||||
while (end < limit && isDigit(layout.charAt(end))) ++end;
|
||||
while (end < limit && isDigit(layout.charAt(end))) {
|
||||
++end;
|
||||
}
|
||||
if (beg == end) return Integer.parseInt("empty");
|
||||
return Integer.parseInt(layout.substring(beg, end));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
package com.sun.java.util.jar.pack;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@ -40,20 +39,13 @@ class ConstantPool implements Constants {
|
||||
return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
|
||||
}
|
||||
|
||||
// Uniquification tables for factory methods:
|
||||
private static final HashMap utf8Entries = new HashMap();
|
||||
private static final HashMap classEntries = new HashMap();
|
||||
private static final HashMap literalEntries = new HashMap();
|
||||
private static final HashMap signatureEntries = new HashMap();
|
||||
private static final HashMap descriptorEntries = new HashMap();
|
||||
private static final HashMap memberEntries = new HashMap();
|
||||
|
||||
/** Factory for Utf8 string constants.
|
||||
* Used for well-known strings like "SourceFile", "<init>", etc.
|
||||
* Also used to back up more complex constant pool entries, like Class.
|
||||
*/
|
||||
public static synchronized Utf8Entry getUtf8Entry(String value) {
|
||||
Utf8Entry e = (Utf8Entry) utf8Entries.get(value);
|
||||
Map<String, Utf8Entry> utf8Entries = Utils.getUtf8Entries();
|
||||
Utf8Entry e = utf8Entries.get(value);
|
||||
if (e == null) {
|
||||
e = new Utf8Entry(value);
|
||||
utf8Entries.put(e.stringValue(), e);
|
||||
@ -62,9 +54,10 @@ class ConstantPool implements Constants {
|
||||
}
|
||||
/** Factory for Class constants. */
|
||||
public static synchronized ClassEntry getClassEntry(String name) {
|
||||
ClassEntry e = (ClassEntry) classEntries.get(name);
|
||||
Map<String, ClassEntry> classEntries = Utils.getClassEntries();
|
||||
ClassEntry e = classEntries.get(name);
|
||||
if (e == null) {
|
||||
e = (ClassEntry) new ClassEntry(getUtf8Entry(name));
|
||||
e = new ClassEntry(getUtf8Entry(name));
|
||||
assert(name.equals(e.stringValue()));
|
||||
classEntries.put(e.stringValue(), e);
|
||||
}
|
||||
@ -72,7 +65,8 @@ class ConstantPool implements Constants {
|
||||
}
|
||||
/** Factory for literal constants (String, Integer, etc.). */
|
||||
public static synchronized LiteralEntry getLiteralEntry(Comparable value) {
|
||||
LiteralEntry e = (LiteralEntry) literalEntries.get(value);
|
||||
Map<Object, LiteralEntry> literalEntries = Utils.getLiteralEntries();
|
||||
LiteralEntry e = literalEntries.get(value);
|
||||
if (e == null) {
|
||||
if (value instanceof String)
|
||||
e = new StringEntry(getUtf8Entry((String)value));
|
||||
@ -89,7 +83,8 @@ class ConstantPool implements Constants {
|
||||
|
||||
/** Factory for signature (type) constants. */
|
||||
public static synchronized SignatureEntry getSignatureEntry(String type) {
|
||||
SignatureEntry e = (SignatureEntry) signatureEntries.get(type);
|
||||
Map<String, SignatureEntry> signatureEntries = Utils.getSignatureEntries();
|
||||
SignatureEntry e = signatureEntries.get(type);
|
||||
if (e == null) {
|
||||
e = new SignatureEntry(type);
|
||||
assert(e.stringValue().equals(type));
|
||||
@ -104,8 +99,9 @@ class ConstantPool implements Constants {
|
||||
|
||||
/** Factory for descriptor (name-and-type) constants. */
|
||||
public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) {
|
||||
Map<String, DescriptorEntry> descriptorEntries = Utils.getDescriptorEntries();
|
||||
String key = DescriptorEntry.stringValueOf(nameRef, typeRef);
|
||||
DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key);
|
||||
DescriptorEntry e = descriptorEntries.get(key);
|
||||
if (e == null) {
|
||||
e = new DescriptorEntry(nameRef, typeRef);
|
||||
assert(e.stringValue().equals(key))
|
||||
@ -121,8 +117,9 @@ class ConstantPool implements Constants {
|
||||
|
||||
/** Factory for member reference constants. */
|
||||
public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
|
||||
Map<String, MemberEntry> memberEntries = Utils.getMemberEntries();
|
||||
String key = MemberEntry.stringValueOf(tag, classRef, descRef);
|
||||
MemberEntry e = (MemberEntry) memberEntries.get(key);
|
||||
MemberEntry e = memberEntries.get(key);
|
||||
if (e == null) {
|
||||
e = new MemberEntry(tag, classRef, descRef);
|
||||
assert(e.stringValue().equals(key))
|
||||
@ -489,8 +486,9 @@ class ConstantPool implements Constants {
|
||||
String[] parts = structureSignature(value);
|
||||
formRef = getUtf8Entry(parts[0]);
|
||||
classRefs = new ClassEntry[parts.length-1];
|
||||
for (int i = 1; i < parts.length; i++)
|
||||
classRefs[i-1] = getClassEntry(parts[i]);
|
||||
for (int i = 1; i < parts.length; i++) {
|
||||
classRefs[i - 1] = getClassEntry(parts[i]);
|
||||
}
|
||||
hashCode(); // force computation of valueHash
|
||||
}
|
||||
protected int computeValueHash() {
|
||||
@ -527,8 +525,9 @@ class ConstantPool implements Constants {
|
||||
String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) {
|
||||
String[] parts = new String[1+classRefs.length];
|
||||
parts[0] = formRef.stringValue();
|
||||
for (int i = 1; i < parts.length; i++)
|
||||
parts[i] = classRefs[i-1].stringValue();
|
||||
for (int i = 1; i < parts.length; i++) {
|
||||
parts[i] = classRefs[i - 1].stringValue();
|
||||
}
|
||||
return flattenSignature(parts).intern();
|
||||
}
|
||||
|
||||
@ -543,19 +542,23 @@ class ConstantPool implements Constants {
|
||||
int size = 0;
|
||||
for (int i = min; i < max; i++) {
|
||||
switch (form.charAt(i)) {
|
||||
case 'D':
|
||||
case 'J':
|
||||
if (countDoublesTwice) size++;
|
||||
break;
|
||||
case '[':
|
||||
// Skip rest of array info.
|
||||
while (form.charAt(i) == '[') ++i;
|
||||
break;
|
||||
case ';':
|
||||
continue;
|
||||
default:
|
||||
assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
|
||||
break;
|
||||
case 'D':
|
||||
case 'J':
|
||||
if (countDoublesTwice) {
|
||||
size++;
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
// Skip rest of array info.
|
||||
while (form.charAt(i) == '[') {
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
case ';':
|
||||
continue;
|
||||
default:
|
||||
assert (0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
|
||||
break;
|
||||
}
|
||||
size++;
|
||||
}
|
||||
@ -586,8 +589,9 @@ class ConstantPool implements Constants {
|
||||
s = "/" + formRef.stringValue();
|
||||
}
|
||||
int i;
|
||||
while ((i = s.indexOf(';')) >= 0)
|
||||
s = s.substring(0,i) + s.substring(i+1);
|
||||
while ((i = s.indexOf(';')) >= 0) {
|
||||
s = s.substring(0, i) + s.substring(i + 1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@ -732,11 +736,11 @@ class ConstantPool implements Constants {
|
||||
clearIndex();
|
||||
this.cpMap = cpMap;
|
||||
}
|
||||
protected Index(String debugName, Collection cpMapList) {
|
||||
protected Index(String debugName, Collection<Entry> cpMapList) {
|
||||
this(debugName);
|
||||
setMap(cpMapList);
|
||||
}
|
||||
protected void setMap(Collection cpMapList) {
|
||||
protected void setMap(Collection<Entry> cpMapList) {
|
||||
cpMap = new Entry[cpMapList.size()];
|
||||
cpMapList.toArray(cpMap);
|
||||
setMap(cpMap);
|
||||
@ -756,11 +760,13 @@ class ConstantPool implements Constants {
|
||||
//
|
||||
// As a special hack, if flattenSigs, signatures are
|
||||
// treated as equivalent entries of cpMap. This is wrong
|
||||
// fron a Collection point of view, because contains()
|
||||
// from a Collection point of view, because contains()
|
||||
// reports true for signatures, but the iterator()
|
||||
// never produces them!
|
||||
private int findIndexOf(Entry e) {
|
||||
if (indexKey == null) initializeIndex();
|
||||
if (indexKey == null) {
|
||||
initializeIndex();
|
||||
}
|
||||
int probe = findIndexLocation(e);
|
||||
if (indexKey[probe] != e) {
|
||||
if (flattenSigs && e.tag == CONSTANT_Signature) {
|
||||
@ -832,7 +838,9 @@ class ConstantPool implements Constants {
|
||||
System.out.println("initialize Index "+debugName+" ["+size()+"]");
|
||||
int hsize0 = (int)((cpMap.length + 10) * 1.5);
|
||||
int hsize = 1;
|
||||
while (hsize < hsize0) hsize <<= 1;
|
||||
while (hsize < hsize0) {
|
||||
hsize <<= 1;
|
||||
}
|
||||
indexKey = new Entry[hsize];
|
||||
indexValue = new int[hsize];
|
||||
for (int i = 0; i < cpMap.length; i++) {
|
||||
@ -855,7 +863,7 @@ class ConstantPool implements Constants {
|
||||
return toArray(new Entry[size()]);
|
||||
}
|
||||
public Object clone() {
|
||||
return new Index(debugName, (Entry[]) cpMap.clone());
|
||||
return new Index(debugName, cpMap.clone());
|
||||
}
|
||||
public String toString() {
|
||||
return "Index "+debugName+" ["+size()+"]";
|
||||
@ -901,22 +909,24 @@ class ConstantPool implements Constants {
|
||||
public static
|
||||
Index[] partition(Index ix, int[] keys) {
|
||||
// %%% Should move this into class Index.
|
||||
ArrayList parts = new ArrayList();
|
||||
ArrayList<List<Entry>> parts = new ArrayList<>();
|
||||
Entry[] cpMap = ix.cpMap;
|
||||
assert(keys.length == cpMap.length);
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
int key = keys[i];
|
||||
if (key < 0) continue;
|
||||
while (key >= parts.size()) parts.add(null);
|
||||
ArrayList part = (ArrayList) parts.get(key);
|
||||
while (key >= parts.size()) {
|
||||
parts.add(null);
|
||||
}
|
||||
List<Entry> part = parts.get(key);
|
||||
if (part == null) {
|
||||
parts.set(key, part = new ArrayList());
|
||||
parts.set(key, part = new ArrayList<>());
|
||||
}
|
||||
part.add(cpMap[i]);
|
||||
}
|
||||
Index[] indexes = new Index[parts.size()];
|
||||
for (int key = 0; key < indexes.length; key++) {
|
||||
ArrayList part = (ArrayList) parts.get(key);
|
||||
List<Entry> part = parts.get(key);
|
||||
if (part == null) continue;
|
||||
indexes[key] = new Index(ix.debugName+"/part#"+key, part);
|
||||
assert(indexes[key].indexOf(part.get(0)) == 0);
|
||||
@ -1048,9 +1058,10 @@ class ConstantPool implements Constants {
|
||||
whichClasses[i] = whichClass;
|
||||
}
|
||||
perClassIndexes = partition(allMembers, whichClasses);
|
||||
for (int i = 0; i < perClassIndexes.length; i++)
|
||||
assert(perClassIndexes[i]==null
|
||||
|| perClassIndexes[i].assertIsSorted());
|
||||
for (int i = 0; i < perClassIndexes.length; i++) {
|
||||
assert (perClassIndexes[i] == null ||
|
||||
perClassIndexes[i].assertIsSorted());
|
||||
}
|
||||
indexByTagAndClass[tag] = perClassIndexes;
|
||||
}
|
||||
int whichClass = allClasses.indexOf(classRef);
|
||||
@ -1113,7 +1124,7 @@ class ConstantPool implements Constants {
|
||||
* Also, discard null from cpRefs.
|
||||
*/
|
||||
public static
|
||||
void completeReferencesIn(Set cpRefs, boolean flattenSigs) {
|
||||
void completeReferencesIn(Set<Entry> cpRefs, boolean flattenSigs) {
|
||||
cpRefs.remove(null);
|
||||
for (ListIterator work =
|
||||
new ArrayList(cpRefs).listIterator(cpRefs.size());
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
package com.sun.java.util.jar.pack;
|
||||
|
||||
import java.lang.Error;
|
||||
import java.io.*;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
@ -35,10 +34,11 @@ import java.util.zip.*;
|
||||
/** Command line interface for Pack200.
|
||||
*/
|
||||
class Driver {
|
||||
private static final ResourceBundle RESOURCE= ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
|
||||
private static final ResourceBundle RESOURCE =
|
||||
ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
|
||||
|
||||
public static void main(String[] ava) throws IOException {
|
||||
ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava));
|
||||
ArrayList<String> av = new ArrayList<>(Arrays.asList(ava));
|
||||
|
||||
boolean doPack = true;
|
||||
boolean doUnpack = false;
|
||||
@ -61,7 +61,7 @@ class Driver {
|
||||
}
|
||||
|
||||
// Collect engine properties here:
|
||||
HashMap<String,String> engProps = new HashMap<String,String>();
|
||||
HashMap<String,String> engProps = new HashMap<>();
|
||||
engProps.put(verboseProp, System.getProperty(verboseProp));
|
||||
|
||||
String optionMap;
|
||||
@ -75,7 +75,7 @@ class Driver {
|
||||
}
|
||||
|
||||
// Collect argument properties here:
|
||||
HashMap<String,String> avProps = new HashMap<String,String>();
|
||||
HashMap<String,String> avProps = new HashMap<>();
|
||||
try {
|
||||
for (;;) {
|
||||
String state = parseCommandOptions(av, optionMap, avProps);
|
||||
@ -133,8 +133,9 @@ class Driver {
|
||||
if (engProps.get(verboseProp) != null)
|
||||
fileProps.list(System.out);
|
||||
propIn.close();
|
||||
for (Map.Entry<Object,Object> me : fileProps.entrySet())
|
||||
engProps.put((String)me.getKey(), (String)me.getValue());
|
||||
for (Map.Entry<Object,Object> me : fileProps.entrySet()) {
|
||||
engProps.put((String) me.getKey(), (String) me.getValue());
|
||||
}
|
||||
} else if (state == "--version") {
|
||||
System.out.println(MessageFormat.format(RESOURCE.getString(DriverResource.VERSION), Driver.class.getName(), "1.31, 07/05/05"));
|
||||
return;
|
||||
@ -493,7 +494,7 @@ class Driver {
|
||||
String resultString = null;
|
||||
|
||||
// Convert options string into optLines dictionary.
|
||||
TreeMap<String,String[]> optmap = new TreeMap<String,String[]>();
|
||||
TreeMap<String,String[]> optmap = new TreeMap<>();
|
||||
loadOptmap:
|
||||
for (String optline : options.split("\n")) {
|
||||
String[] words = optline.split("\\p{Space}+");
|
||||
@ -687,7 +688,9 @@ class Driver {
|
||||
// Report number of arguments consumed.
|
||||
args.subList(0, argp.nextIndex()).clear();
|
||||
// Report any unconsumed partial argument.
|
||||
while (pbp.hasPrevious()) args.add(0, pbp.previous());
|
||||
while (pbp.hasPrevious()) {
|
||||
args.add(0, pbp.previous());
|
||||
}
|
||||
//System.out.println(args+" // "+properties+" -> "+resultString);
|
||||
return resultString;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,13 +28,8 @@ package com.sun.java.util.jar.pack;
|
||||
|
||||
import java.nio.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.Date;
|
||||
import java.util.jar.*;
|
||||
import java.util.zip.*;
|
||||
import java.util.*;
|
||||
//import com.sun.java.util.jar.pack.Pack200;
|
||||
|
||||
|
||||
class NativeUnpack {
|
||||
// Pointer to the native unpacker obj
|
||||
@ -91,13 +86,13 @@ class NativeUnpack {
|
||||
NativeUnpack(UnpackerImpl p200) {
|
||||
super();
|
||||
_p200 = p200;
|
||||
_props = p200._props;
|
||||
_props = p200.props;
|
||||
p200._nunp = this;
|
||||
}
|
||||
|
||||
// for JNI callbacks
|
||||
static private Object currentInstance() {
|
||||
UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get();
|
||||
UnpackerImpl p200 = (UnpackerImpl) Utils.getTLGlobals();
|
||||
return (p200 == null)? null: p200._nunp;
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,9 @@
|
||||
|
||||
package com.sun.java.util.jar.pack;
|
||||
|
||||
import com.sun.java.util.jar.pack.Attribute.Layout;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import java.util.jar.*;
|
||||
import java.io.*;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.*;
|
||||
@ -77,10 +77,11 @@ class Package implements Constants {
|
||||
cp = new ConstantPool.IndexGroup();
|
||||
classes.clear();
|
||||
files.clear();
|
||||
BandStructure.nextSeqForDebug = 0;
|
||||
}
|
||||
|
||||
int getPackageVersion() {
|
||||
return (package_majver << 16) + (int)package_minver;
|
||||
return (package_majver << 16) + package_minver;
|
||||
}
|
||||
|
||||
// Special empty versions of Code and InnerClasses, used for markers.
|
||||
@ -89,7 +90,7 @@ class Package implements Constants {
|
||||
public static final Attribute.Layout attrSourceFileSpecial;
|
||||
public static final Map attrDefs;
|
||||
static {
|
||||
HashMap ad = new HashMap(2);
|
||||
HashMap<Layout, Attribute> ad = new HashMap<>(3);
|
||||
attrCodeEmpty = Attribute.define(ad, ATTR_CONTEXT_METHOD,
|
||||
"Code", "").layout();
|
||||
attrInnerClassesEmpty = Attribute.define(ad, ATTR_CONTEXT_CLASS,
|
||||
@ -159,9 +160,9 @@ class Package implements Constants {
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList classes = new ArrayList();
|
||||
ArrayList<Package.Class> classes = new ArrayList<>();
|
||||
|
||||
public List getClasses() {
|
||||
public List<Package.Class> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
@ -186,11 +187,11 @@ class Package implements Constants {
|
||||
ClassEntry[] interfaces;
|
||||
|
||||
// Class parts
|
||||
ArrayList fields;
|
||||
ArrayList methods;
|
||||
ArrayList<Field> fields;
|
||||
ArrayList<Method> methods;
|
||||
//ArrayList attributes; // in Attribute.Holder.this.attributes
|
||||
// Note that InnerClasses may be collected at the package level.
|
||||
ArrayList innerClasses;
|
||||
ArrayList<InnerClass> innerClasses;
|
||||
|
||||
Class(int flags, ClassEntry thisClass, ClassEntry superClass, ClassEntry[] interfaces) {
|
||||
this.magic = JAVA_MAGIC;
|
||||
@ -270,7 +271,7 @@ class Package implements Constants {
|
||||
if (a != olda) {
|
||||
if (verbose > 2)
|
||||
Utils.log.fine("recoding obvious SourceFile="+obvious);
|
||||
List newAttrs = new ArrayList(getAttributes());
|
||||
List<Attribute> newAttrs = new ArrayList<>(getAttributes());
|
||||
int where = newAttrs.indexOf(olda);
|
||||
newAttrs.set(where, a);
|
||||
setAttributes(newAttrs);
|
||||
@ -295,12 +296,12 @@ class Package implements Constants {
|
||||
boolean hasInnerClasses() {
|
||||
return innerClasses != null;
|
||||
}
|
||||
List getInnerClasses() {
|
||||
List<InnerClass> getInnerClasses() {
|
||||
return innerClasses;
|
||||
}
|
||||
|
||||
public void setInnerClasses(Collection ics) {
|
||||
innerClasses = (ics == null) ? null : new ArrayList(ics);
|
||||
public void setInnerClasses(Collection<InnerClass> ics) {
|
||||
innerClasses = (ics == null) ? null : new ArrayList<InnerClass>(ics);
|
||||
// Edit the attribute list, if necessary.
|
||||
Attribute a = getAttribute(attrInnerClassesEmpty);
|
||||
if (innerClasses != null && a == null)
|
||||
@ -318,19 +319,18 @@ class Package implements Constants {
|
||||
* The order of the resulting list is consistent
|
||||
* with that of Package.this.allInnerClasses.
|
||||
*/
|
||||
public List computeGloballyImpliedICs() {
|
||||
HashSet cpRefs = new HashSet();
|
||||
public List<InnerClass> computeGloballyImpliedICs() {
|
||||
HashSet<Entry> cpRefs = new HashSet<>();
|
||||
{ // This block temporarily displaces this.innerClasses.
|
||||
ArrayList innerClassesSaved = innerClasses;
|
||||
ArrayList<InnerClass> innerClassesSaved = innerClasses;
|
||||
innerClasses = null; // ignore for the moment
|
||||
visitRefs(VRM_CLASSIC, cpRefs);
|
||||
innerClasses = innerClassesSaved;
|
||||
}
|
||||
ConstantPool.completeReferencesIn(cpRefs, true);
|
||||
|
||||
HashSet icRefs = new HashSet();
|
||||
for (Iterator i = cpRefs.iterator(); i.hasNext(); ) {
|
||||
Entry e = (Entry) i.next();
|
||||
HashSet<Entry> icRefs = new HashSet<>();
|
||||
for (Entry e : cpRefs) {
|
||||
// Restrict cpRefs to InnerClasses entries only.
|
||||
if (!(e instanceof ClassEntry)) continue;
|
||||
// For every IC reference, add its outers also.
|
||||
@ -345,9 +345,8 @@ class Package implements Constants {
|
||||
// This loop is structured this way so as to accumulate
|
||||
// entries into impliedICs in an order which reflects
|
||||
// the order of allInnerClasses.
|
||||
ArrayList impliedICs = new ArrayList();
|
||||
for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) {
|
||||
InnerClass ic = (InnerClass) i.next();
|
||||
ArrayList<InnerClass> impliedICs = new ArrayList<>();
|
||||
for (InnerClass ic : allInnerClasses) {
|
||||
// This one is locally relevant if it describes
|
||||
// a member of the current class, or if the current
|
||||
// class uses it somehow. In the particular case
|
||||
@ -366,10 +365,11 @@ class Package implements Constants {
|
||||
|
||||
// Helper for both minimizing and expanding.
|
||||
// Computes a symmetric difference.
|
||||
private List computeICdiff() {
|
||||
List impliedICs = computeGloballyImpliedICs();
|
||||
List actualICs = getInnerClasses();
|
||||
if (actualICs == null) actualICs = Collections.EMPTY_LIST;
|
||||
private List<InnerClass> computeICdiff() {
|
||||
List<InnerClass> impliedICs = computeGloballyImpliedICs();
|
||||
List<InnerClass> actualICs = getInnerClasses();
|
||||
if (actualICs == null)
|
||||
actualICs = Collections.EMPTY_LIST;
|
||||
|
||||
// Symmetric difference is calculated from I, A like this:
|
||||
// diff = (I+A) - (I*A)
|
||||
@ -388,8 +388,8 @@ class Package implements Constants {
|
||||
// Diff is A since I is empty.
|
||||
}
|
||||
// (I*A) is non-trivial
|
||||
HashSet center = new HashSet(actualICs);
|
||||
center.retainAll(new HashSet(impliedICs));
|
||||
HashSet<InnerClass> center = new HashSet<>(actualICs);
|
||||
center.retainAll(new HashSet<>(impliedICs));
|
||||
impliedICs.addAll(actualICs);
|
||||
impliedICs.removeAll(center);
|
||||
// Diff is now I^A = (I+A)-(I*A).
|
||||
@ -407,9 +407,9 @@ class Package implements Constants {
|
||||
* to use the globally implied ICs changed.
|
||||
*/
|
||||
void minimizeLocalICs() {
|
||||
List diff = computeICdiff();
|
||||
List actualICs = innerClasses;
|
||||
List localICs; // will be the diff, modulo edge cases
|
||||
List<InnerClass> diff = computeICdiff();
|
||||
List<InnerClass> actualICs = innerClasses;
|
||||
List<InnerClass> localICs; // will be the diff, modulo edge cases
|
||||
if (diff.isEmpty()) {
|
||||
// No diff, so transmit no attribute.
|
||||
localICs = null;
|
||||
@ -439,12 +439,12 @@ class Package implements Constants {
|
||||
* Otherwise, return positive if any IC tuples were added.
|
||||
*/
|
||||
int expandLocalICs() {
|
||||
List localICs = innerClasses;
|
||||
List actualICs;
|
||||
List<InnerClass> localICs = innerClasses;
|
||||
List<InnerClass> actualICs;
|
||||
int changed;
|
||||
if (localICs == null) {
|
||||
// Diff was empty. (Common case.)
|
||||
List impliedICs = computeGloballyImpliedICs();
|
||||
List<InnerClass> impliedICs = computeGloballyImpliedICs();
|
||||
if (impliedICs.isEmpty()) {
|
||||
actualICs = null;
|
||||
changed = 0;
|
||||
@ -490,7 +490,7 @@ class Package implements Constants {
|
||||
protected Entry[] getCPMap() {
|
||||
return cpMap;
|
||||
}
|
||||
protected void visitRefs(int mode, Collection refs) {
|
||||
protected void visitRefs(int mode, Collection<Entry> refs) {
|
||||
if (verbose > 2) Utils.log.fine("visitRefs "+this);
|
||||
// Careful: The descriptor is used by the package,
|
||||
// but the classfile breaks it into component refs.
|
||||
@ -518,7 +518,7 @@ class Package implements Constants {
|
||||
super(flags, descriptor);
|
||||
assert(!descriptor.isMethod());
|
||||
if (fields == null)
|
||||
fields = new ArrayList();
|
||||
fields = new ArrayList<>();
|
||||
boolean added = fields.add(this);
|
||||
assert(added);
|
||||
order = fields.size();
|
||||
@ -543,7 +543,7 @@ class Package implements Constants {
|
||||
super(flags, descriptor);
|
||||
assert(descriptor.isMethod());
|
||||
if (methods == null)
|
||||
methods = new ArrayList();
|
||||
methods = new ArrayList<>();
|
||||
boolean added = methods.add(this);
|
||||
assert(added);
|
||||
}
|
||||
@ -573,7 +573,7 @@ class Package implements Constants {
|
||||
code.strip(attrName);
|
||||
super.strip(attrName);
|
||||
}
|
||||
protected void visitRefs(int mode, Collection refs) {
|
||||
protected void visitRefs(int mode, Collection<Entry> refs) {
|
||||
super.visitRefs(mode, refs);
|
||||
if (code != null) {
|
||||
if (mode == VRM_CLASSIC) {
|
||||
@ -614,7 +614,7 @@ class Package implements Constants {
|
||||
super.strip(attrName);
|
||||
}
|
||||
|
||||
protected void visitRefs(int mode, Collection refs) {
|
||||
protected void visitRefs(int mode, Collection<Entry> refs) {
|
||||
if (verbose > 2) Utils.log.fine("visitRefs "+this);
|
||||
refs.add(thisClass);
|
||||
refs.add(superClass);
|
||||
@ -641,7 +641,7 @@ class Package implements Constants {
|
||||
super.visitRefs(mode, refs);
|
||||
}
|
||||
|
||||
protected void visitInnerClassRefs(int mode, Collection refs) {
|
||||
protected void visitInnerClassRefs(int mode, Collection<Entry> refs) {
|
||||
Package.visitInnerClassRefs(innerClasses, mode, refs);
|
||||
}
|
||||
|
||||
@ -713,16 +713,15 @@ class Package implements Constants {
|
||||
}
|
||||
|
||||
// What non-class files are in this unit?
|
||||
ArrayList files = new ArrayList();
|
||||
ArrayList<File> files = new ArrayList<>();
|
||||
|
||||
public List getFiles() {
|
||||
public List<File> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
public List getClassStubs() {
|
||||
ArrayList classStubs = new ArrayList(classes.size());
|
||||
for (Iterator i = classes.iterator(); i.hasNext(); ) {
|
||||
Class cls = (Class) i.next();
|
||||
public List<File> getClassStubs() {
|
||||
ArrayList<File> classStubs = new ArrayList<>(classes.size());
|
||||
for (Class cls : classes) {
|
||||
assert(cls.file.isClassStub());
|
||||
classStubs.add(cls.file);
|
||||
}
|
||||
@ -840,7 +839,7 @@ class Package implements Constants {
|
||||
public InputStream getInputStream() {
|
||||
InputStream in = new ByteArrayInputStream(append.toByteArray());
|
||||
if (prepend.size() == 0) return in;
|
||||
ArrayList isa = new ArrayList(prepend.size()+1);
|
||||
ArrayList<InputStream> isa = new ArrayList<>(prepend.size()+1);
|
||||
for (Iterator i = prepend.iterator(); i.hasNext(); ) {
|
||||
byte[] bytes = (byte[]) i.next();
|
||||
isa.add(new ByteArrayInputStream(bytes));
|
||||
@ -849,7 +848,7 @@ class Package implements Constants {
|
||||
return new SequenceInputStream(Collections.enumeration(isa));
|
||||
}
|
||||
|
||||
protected void visitRefs(int mode, Collection refs) {
|
||||
protected void visitRefs(int mode, Collection<Entry> refs) {
|
||||
assert(name != null);
|
||||
refs.add(name);
|
||||
}
|
||||
@ -877,8 +876,8 @@ class Package implements Constants {
|
||||
}
|
||||
|
||||
// Is there a globally declared table of inner classes?
|
||||
ArrayList allInnerClasses = new ArrayList();
|
||||
HashMap allInnerClassesByThis;
|
||||
ArrayList<InnerClass> allInnerClasses = new ArrayList<>();
|
||||
HashMap<ClassEntry, InnerClass> allInnerClassesByThis;
|
||||
|
||||
public
|
||||
List getAllInnerClasses() {
|
||||
@ -886,15 +885,14 @@ class Package implements Constants {
|
||||
}
|
||||
|
||||
public
|
||||
void setAllInnerClasses(Collection ics) {
|
||||
void setAllInnerClasses(Collection<InnerClass> ics) {
|
||||
assert(ics != allInnerClasses);
|
||||
allInnerClasses.clear();
|
||||
allInnerClasses.addAll(ics);
|
||||
|
||||
// Make an index:
|
||||
allInnerClassesByThis = new HashMap(allInnerClasses.size());
|
||||
for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) {
|
||||
InnerClass ic = (InnerClass) i.next();
|
||||
allInnerClassesByThis = new HashMap<>(allInnerClasses.size());
|
||||
for (InnerClass ic : allInnerClasses) {
|
||||
Object pic = allInnerClassesByThis.put(ic.thisClass, ic);
|
||||
assert(pic == null); // caller must ensure key uniqueness!
|
||||
}
|
||||
@ -904,7 +902,7 @@ class Package implements Constants {
|
||||
public
|
||||
InnerClass getGlobalInnerClass(Entry thisClass) {
|
||||
assert(thisClass instanceof ClassEntry);
|
||||
return (InnerClass) allInnerClassesByThis.get(thisClass);
|
||||
return allInnerClassesByThis.get(thisClass);
|
||||
}
|
||||
|
||||
static
|
||||
@ -963,7 +961,7 @@ class Package implements Constants {
|
||||
return this.thisClass.compareTo(that.thisClass);
|
||||
}
|
||||
|
||||
protected void visitRefs(int mode, Collection refs) {
|
||||
protected void visitRefs(int mode, Collection<Entry> refs) {
|
||||
refs.add(thisClass);
|
||||
if (mode == VRM_CLASSIC || !predictable) {
|
||||
// If the name can be demangled, the package omits
|
||||
@ -980,7 +978,7 @@ class Package implements Constants {
|
||||
|
||||
// Helper for building InnerClasses attributes.
|
||||
static private
|
||||
void visitInnerClassRefs(Collection innerClasses, int mode, Collection refs) {
|
||||
void visitInnerClassRefs(Collection innerClasses, int mode, Collection<Entry> refs) {
|
||||
if (innerClasses == null) {
|
||||
return; // no attribute; nothing to do
|
||||
}
|
||||
@ -1165,9 +1163,8 @@ class Package implements Constants {
|
||||
}
|
||||
}
|
||||
|
||||
protected void visitRefs(int mode, Collection refs) {
|
||||
for (Iterator i = classes.iterator(); i.hasNext(); ) {
|
||||
Class c = (Class)i.next();
|
||||
protected void visitRefs(int mode, Collection<Entry> refs) {
|
||||
for ( Class c : classes) {
|
||||
c.visitRefs(mode, refs);
|
||||
}
|
||||
if (mode != VRM_CLASSIC) {
|
||||
@ -1259,7 +1256,7 @@ class Package implements Constants {
|
||||
}
|
||||
|
||||
// Use this before writing the package file.
|
||||
void buildGlobalConstantPool(Set requiredEntries) {
|
||||
void buildGlobalConstantPool(Set<Entry> requiredEntries) {
|
||||
if (verbose > 1)
|
||||
Utils.log.fine("Checking for unused CP entries");
|
||||
requiredEntries.add(getRefString("")); // uconditionally present
|
||||
@ -1291,9 +1288,8 @@ class Package implements Constants {
|
||||
|
||||
// Use this before writing the class files.
|
||||
void ensureAllClassFiles() {
|
||||
HashSet fileSet = new HashSet(files);
|
||||
for (Iterator i = classes.iterator(); i.hasNext(); ) {
|
||||
Class cls = (Class) i.next();
|
||||
HashSet<File> fileSet = new HashSet<>(files);
|
||||
for (Class cls : classes) {
|
||||
// Add to the end of ths list:
|
||||
if (!fileSet.contains(cls.file))
|
||||
files.add(cls.file);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,12 +25,11 @@
|
||||
|
||||
package com.sun.java.util.jar.pack;
|
||||
|
||||
import com.sun.java.util.jar.pack.Attribute.Layout;
|
||||
import java.util.*;
|
||||
import java.util.jar.*;
|
||||
import java.util.zip.*;
|
||||
import java.io.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
|
||||
/*
|
||||
@ -41,31 +40,22 @@ import java.beans.PropertyChangeEvent;
|
||||
*/
|
||||
|
||||
|
||||
public class PackerImpl implements Pack200.Packer {
|
||||
public class PackerImpl extends TLGlobals implements Pack200.Packer {
|
||||
|
||||
/**
|
||||
* Constructs a Packer object and sets the initial state of
|
||||
* the packer engines.
|
||||
*/
|
||||
public PackerImpl() {
|
||||
_props = new PropMap();
|
||||
//_props.getProperty() consults defaultProps invisibly.
|
||||
//_props.putAll(defaultProps);
|
||||
}
|
||||
|
||||
|
||||
// Private stuff.
|
||||
final PropMap _props;
|
||||
public PackerImpl() {}
|
||||
|
||||
/**
|
||||
* Get the set of options for the pack and unpack engines.
|
||||
* @return A sorted association of option key strings to option values.
|
||||
*/
|
||||
public SortedMap properties() {
|
||||
return _props;
|
||||
public SortedMap<String, String> properties() {
|
||||
return props;
|
||||
}
|
||||
|
||||
|
||||
//Driver routines
|
||||
|
||||
/**
|
||||
@ -78,21 +68,22 @@ public class PackerImpl implements Pack200.Packer {
|
||||
*/
|
||||
public void pack(JarFile in, OutputStream out) throws IOException {
|
||||
assert(Utils.currentInstance.get() == null);
|
||||
TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
|
||||
TimeZone.getDefault();
|
||||
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
|
||||
? null
|
||||
: TimeZone.getDefault();
|
||||
try {
|
||||
Utils.currentInstance.set(this);
|
||||
if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
|
||||
if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) {
|
||||
Utils.copyJarFile(in, out);
|
||||
} else {
|
||||
(new DoPack()).run(in, out);
|
||||
in.close();
|
||||
}
|
||||
} finally {
|
||||
Utils.currentInstance.set(null);
|
||||
if (tz != null) TimeZone.setDefault(tz);
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,21 +103,20 @@ public class PackerImpl implements Pack200.Packer {
|
||||
*/
|
||||
public void pack(JarInputStream in, OutputStream out) throws IOException {
|
||||
assert(Utils.currentInstance.get() == null);
|
||||
TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
|
||||
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
|
||||
TimeZone.getDefault();
|
||||
try {
|
||||
Utils.currentInstance.set(this);
|
||||
if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||
if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
|
||||
if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) {
|
||||
Utils.copyJarFile(in, out);
|
||||
} else {
|
||||
(new DoPack()).run(in, out);
|
||||
in.close();
|
||||
}
|
||||
} finally {
|
||||
Utils.currentInstance.set(null);
|
||||
if (tz != null) TimeZone.setDefault(tz);
|
||||
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -134,7 +124,7 @@ public class PackerImpl implements Pack200.Packer {
|
||||
* @param listener An object to be invoked when a property is changed.
|
||||
*/
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
_props.addListener(listener);
|
||||
props.addListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,7 +132,7 @@ public class PackerImpl implements Pack200.Packer {
|
||||
* @param listener The PropertyChange listener to be removed.
|
||||
*/
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
_props.removeListener(listener);
|
||||
props.removeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
@ -151,11 +141,11 @@ public class PackerImpl implements Pack200.Packer {
|
||||
|
||||
// The packer worker.
|
||||
private class DoPack {
|
||||
final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
|
||||
final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
|
||||
|
||||
{
|
||||
_props.setInteger(Pack200.Packer.PROGRESS, 0);
|
||||
if (verbose > 0) Utils.log.info(_props.toString());
|
||||
props.setInteger(Pack200.Packer.PROGRESS, 0);
|
||||
if (verbose > 0) Utils.log.info(props.toString());
|
||||
}
|
||||
|
||||
// Here's where the bits are collected before getting packed:
|
||||
@ -163,7 +153,7 @@ public class PackerImpl implements Pack200.Packer {
|
||||
|
||||
final String unknownAttrCommand;
|
||||
{
|
||||
String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
|
||||
String uaMode = props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
|
||||
if (!(Pack200.Packer.STRIP.equals(uaMode) ||
|
||||
Pack200.Packer.PASS.equals(uaMode) ||
|
||||
Pack200.Packer.ERROR.equals(uaMode))) {
|
||||
@ -191,13 +181,12 @@ public class PackerImpl implements Pack200.Packer {
|
||||
};
|
||||
for (int i = 0; i < ctypes.length; i++) {
|
||||
String pfx = keys[i];
|
||||
Map map = _props.prefixMap(pfx);
|
||||
for (Iterator j = map.keySet().iterator(); j.hasNext(); ) {
|
||||
String key = (String) j.next();
|
||||
Map<String, String> map = props.prefixMap(pfx);
|
||||
for (String key : map.keySet()) {
|
||||
assert(key.startsWith(pfx));
|
||||
String name = key.substring(pfx.length());
|
||||
String layout = _props.getProperty(key);
|
||||
Object lkey = Attribute.keyForLookup(ctypes[i], name);
|
||||
String layout = props.getProperty(key);
|
||||
Layout lkey = Attribute.keyForLookup(ctypes[i], name);
|
||||
if (Pack200.Packer.STRIP.equals(layout) ||
|
||||
Pack200.Packer.PASS.equals(layout) ||
|
||||
Pack200.Packer.ERROR.equals(layout)) {
|
||||
@ -222,25 +211,25 @@ public class PackerImpl implements Pack200.Packer {
|
||||
}
|
||||
|
||||
final boolean keepFileOrder
|
||||
= _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
|
||||
= props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
|
||||
final boolean keepClassOrder
|
||||
= _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
|
||||
= props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
|
||||
|
||||
final boolean keepModtime
|
||||
= Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
|
||||
= Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME));
|
||||
final boolean latestModtime
|
||||
= Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
|
||||
= Pack200.Packer.LATEST.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME));
|
||||
final boolean keepDeflateHint
|
||||
= Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT));
|
||||
= Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.DEFLATE_HINT));
|
||||
{
|
||||
if (!keepModtime && !latestModtime) {
|
||||
int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME);
|
||||
int modtime = props.getTime(Pack200.Packer.MODIFICATION_TIME);
|
||||
if (modtime != Constants.NO_MODTIME) {
|
||||
pkg.default_modtime = modtime;
|
||||
}
|
||||
}
|
||||
if (!keepDeflateHint) {
|
||||
boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT);
|
||||
boolean deflate_hint = props.getBoolean(Pack200.Packer.DEFLATE_HINT);
|
||||
if (deflate_hint) {
|
||||
pkg.default_options |= Constants.AO_DEFLATE_HINT;
|
||||
}
|
||||
@ -254,10 +243,10 @@ public class PackerImpl implements Pack200.Packer {
|
||||
final long segmentLimit;
|
||||
{
|
||||
long limit;
|
||||
if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
|
||||
if (props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
|
||||
limit = -1;
|
||||
else
|
||||
limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT);
|
||||
limit = props.getLong(Pack200.Packer.SEGMENT_LIMIT);
|
||||
limit = Math.min(Integer.MAX_VALUE, limit);
|
||||
limit = Math.max(-1, limit);
|
||||
if (limit == -1)
|
||||
@ -265,10 +254,10 @@ public class PackerImpl implements Pack200.Packer {
|
||||
segmentLimit = limit;
|
||||
}
|
||||
|
||||
final List passFiles; // parsed pack.pass.file options
|
||||
final List<String> passFiles; // parsed pack.pass.file options
|
||||
{
|
||||
// Which class files will be passed through?
|
||||
passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX);
|
||||
passFiles = props.getProperties(Pack200.Packer.PASS_FILE_PFX);
|
||||
for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) {
|
||||
String file = (String) i.next();
|
||||
if (file == null) { i.remove(); continue; }
|
||||
@ -283,28 +272,28 @@ public class PackerImpl implements Pack200.Packer {
|
||||
{
|
||||
// Fill in permitted range of major/minor version numbers.
|
||||
int ver;
|
||||
if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
|
||||
if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
|
||||
pkg.min_class_majver = (short) ver;
|
||||
if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
|
||||
if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
|
||||
pkg.min_class_minver = (short) ver;
|
||||
if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
|
||||
if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
|
||||
pkg.max_class_majver = (short) ver;
|
||||
if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
|
||||
if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
|
||||
pkg.max_class_minver = (short) ver;
|
||||
if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
|
||||
if ((ver = props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
|
||||
pkg.package_minver = (short) ver;
|
||||
if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
|
||||
if ((ver = props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
|
||||
pkg.package_majver = (short) ver;
|
||||
}
|
||||
|
||||
{
|
||||
// Hook for testing: Forces use of special archive modes.
|
||||
int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options");
|
||||
int opt = props.getInteger(Utils.COM_PREFIX+"archive.options");
|
||||
if (opt != 0)
|
||||
pkg.default_options |= opt;
|
||||
}
|
||||
|
||||
// (Done collecting options from _props.)
|
||||
// (Done collecting options from props.)
|
||||
|
||||
boolean isClassFile(String name) {
|
||||
if (!name.endsWith(".class")) return false;
|
||||
@ -423,16 +412,18 @@ public class PackerImpl implements Pack200.Packer {
|
||||
Package.File file = null;
|
||||
// (5078608) : discount the resource files in META-INF
|
||||
// from segment computation.
|
||||
long inflen = (isMetaInfFile(name)) ? 0L :
|
||||
inFile.getInputLength();
|
||||
long inflen = (isMetaInfFile(name))
|
||||
? 0L
|
||||
: inFile.getInputLength();
|
||||
|
||||
if ((segmentSize += inflen) > segmentLimit) {
|
||||
segmentSize -= inflen;
|
||||
int nextCount = -1; // don't know; it's a stream
|
||||
flushPartial(out, nextCount);
|
||||
}
|
||||
if (verbose > 1)
|
||||
if (verbose > 1) {
|
||||
Utils.log.fine("Reading " + name);
|
||||
}
|
||||
|
||||
assert(je.isDirectory() == name.endsWith("/"));
|
||||
|
||||
@ -450,18 +441,18 @@ public class PackerImpl implements Pack200.Packer {
|
||||
}
|
||||
|
||||
void run(JarFile in, OutputStream out) throws IOException {
|
||||
List inFiles = scanJar(in);
|
||||
List<InFile> inFiles = scanJar(in);
|
||||
|
||||
if (verbose > 0)
|
||||
Utils.log.info("Reading " + inFiles.size() + " files...");
|
||||
|
||||
int numDone = 0;
|
||||
for (Iterator i = inFiles.iterator(); i.hasNext(); ) {
|
||||
InFile inFile = (InFile) i.next();
|
||||
for (InFile inFile : inFiles) {
|
||||
String name = inFile.name;
|
||||
// (5078608) : discount the resource files completely from segmenting
|
||||
long inflen = (isMetaInfFile(name)) ? 0L :
|
||||
inFile.getInputLength() ;
|
||||
long inflen = (isMetaInfFile(name))
|
||||
? 0L
|
||||
: inFile.getInputLength() ;
|
||||
if ((segmentSize += inflen) > segmentLimit) {
|
||||
segmentSize -= inflen;
|
||||
// Estimate number of remaining segments:
|
||||
@ -530,11 +521,11 @@ public class PackerImpl implements Pack200.Packer {
|
||||
}
|
||||
|
||||
void flushPartial(OutputStream out, int nextCount) throws IOException {
|
||||
if (pkg.files.size() == 0 && pkg.classes.size() == 0) {
|
||||
if (pkg.files.isEmpty() && pkg.classes.isEmpty()) {
|
||||
return; // do not flush an empty segment
|
||||
}
|
||||
flushPackage(out, Math.max(1, nextCount));
|
||||
_props.setInteger(Pack200.Packer.PROGRESS, 25);
|
||||
props.setInteger(Pack200.Packer.PROGRESS, 25);
|
||||
// In case there will be another segment:
|
||||
makeNextPackage();
|
||||
segmentCount += 1;
|
||||
@ -543,10 +534,10 @@ public class PackerImpl implements Pack200.Packer {
|
||||
}
|
||||
|
||||
void flushAll(OutputStream out) throws IOException {
|
||||
_props.setInteger(Pack200.Packer.PROGRESS, 50);
|
||||
props.setInteger(Pack200.Packer.PROGRESS, 50);
|
||||
flushPackage(out, 0);
|
||||
out.flush();
|
||||
_props.setInteger(Pack200.Packer.PROGRESS, 100);
|
||||
props.setInteger(Pack200.Packer.PROGRESS, 100);
|
||||
segmentCount += 1;
|
||||
segmentTotalSize += segmentSize;
|
||||
segmentSize = 0;
|
||||
@ -582,11 +573,11 @@ public class PackerImpl implements Pack200.Packer {
|
||||
pkg.trimStubs();
|
||||
|
||||
// Do some stripping, maybe.
|
||||
if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug");
|
||||
if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile");
|
||||
if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant");
|
||||
if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions");
|
||||
if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
|
||||
if (props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug");
|
||||
if (props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile");
|
||||
if (props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant");
|
||||
if (props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions");
|
||||
if (props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
|
||||
|
||||
// Must choose an archive version; PackageWriter does not.
|
||||
if (pkg.package_majver <= 0) pkg.choosePackageVersion();
|
||||
@ -606,11 +597,10 @@ public class PackerImpl implements Pack200.Packer {
|
||||
}
|
||||
}
|
||||
|
||||
List scanJar(JarFile jf) throws IOException {
|
||||
List<InFile> scanJar(JarFile jf) throws IOException {
|
||||
// Collect jar entries, preserving order.
|
||||
List inFiles = new ArrayList();
|
||||
for (Enumeration e = jf.entries(); e.hasMoreElements(); ) {
|
||||
JarEntry je = (JarEntry) e.nextElement();
|
||||
List<InFile> inFiles = new ArrayList<>();
|
||||
for (JarEntry je : Collections.list(jf.entries())) {
|
||||
InFile inFile = new InFile(jf, je);
|
||||
assert(je.isDirectory() == inFile.name.endsWith("/"));
|
||||
inFiles.add(inFile);
|
||||
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.java.util.jar.pack;
|
||||
|
||||
import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
|
||||
/*
|
||||
* @author ksrini
|
||||
*/
|
||||
|
||||
/*
|
||||
* This class provides a container to hold the global variables, for packer
|
||||
* and unpacker instances. This is typically stashed away in a ThreadLocal,
|
||||
* and the storage is destroyed upon completion. Therefore any local
|
||||
* references to these members must be eliminated appropriately to prevent a
|
||||
* memory leak.
|
||||
*/
|
||||
class TLGlobals {
|
||||
// Global environment
|
||||
final PropMap props;
|
||||
|
||||
// Needed by ConstantPool.java
|
||||
private final Map<String, Utf8Entry> utf8Entries;
|
||||
private final Map<String, ClassEntry> classEntries;
|
||||
private final Map<Object, LiteralEntry> literalEntries;
|
||||
private final Map<String, SignatureEntry> signatureEntries;
|
||||
private final Map<String, DescriptorEntry> descriptorEntries;
|
||||
private final Map<String, MemberEntry> memberEntries;
|
||||
|
||||
TLGlobals() {
|
||||
utf8Entries = new HashMap<>();
|
||||
classEntries = new HashMap<>();
|
||||
literalEntries = new HashMap<>();
|
||||
signatureEntries = new HashMap<>();
|
||||
descriptorEntries = new HashMap<>();
|
||||
memberEntries = new HashMap<>();
|
||||
props = new PropMap();
|
||||
}
|
||||
|
||||
SortedMap<Object, Object> getPropMap() {
|
||||
return props;
|
||||
}
|
||||
|
||||
Map<String, Utf8Entry> getUtf8Entries() {
|
||||
return utf8Entries;
|
||||
}
|
||||
|
||||
Map<String, ClassEntry> getClassEntries() {
|
||||
return classEntries;
|
||||
}
|
||||
|
||||
Map<Object, LiteralEntry> getLiteralEntries() {
|
||||
return literalEntries;
|
||||
}
|
||||
|
||||
Map<String, DescriptorEntry> getDescriptorEntries() {
|
||||
return descriptorEntries;
|
||||
}
|
||||
|
||||
Map<String, SignatureEntry> getSignatureEntries() {
|
||||
return signatureEntries;
|
||||
}
|
||||
|
||||
Map<String, MemberEntry> getMemberEntries() {
|
||||
return memberEntries;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,7 +30,6 @@ import java.util.jar.*;
|
||||
import java.util.zip.*;
|
||||
import java.io.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/*
|
||||
* Implementation of the Pack provider.
|
||||
@ -40,7 +39,7 @@ import java.beans.PropertyChangeEvent;
|
||||
*/
|
||||
|
||||
|
||||
public class UnpackerImpl implements Pack200.Unpacker {
|
||||
public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
|
||||
|
||||
|
||||
/**
|
||||
@ -48,7 +47,7 @@ public class UnpackerImpl implements Pack200.Unpacker {
|
||||
* @param listener An object to be invoked when a property is changed.
|
||||
*/
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
_props.addListener(listener);
|
||||
props.addListener(listener);
|
||||
}
|
||||
|
||||
|
||||
@ -57,25 +56,19 @@ public class UnpackerImpl implements Pack200.Unpacker {
|
||||
* @param listener The PropertyChange listener to be removed.
|
||||
*/
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
_props.removeListener(listener);
|
||||
props.removeListener(listener);
|
||||
}
|
||||
|
||||
public UnpackerImpl() {
|
||||
_props = new PropMap();
|
||||
//_props.getProperty() consults defaultProps invisibly.
|
||||
//_props.putAll(defaultProps);
|
||||
}
|
||||
public UnpackerImpl() {}
|
||||
|
||||
// Private stuff.
|
||||
final PropMap _props;
|
||||
|
||||
|
||||
/**
|
||||
* Get the set of options for the pack and unpack engines.
|
||||
* @return A sorted association of option key strings to option values.
|
||||
*/
|
||||
public SortedMap properties() {
|
||||
return _props;
|
||||
public SortedMap<String, String> properties() {
|
||||
return props;
|
||||
}
|
||||
|
||||
// Back-pointer to NativeUnpacker, when active.
|
||||
@ -101,19 +94,20 @@ public class UnpackerImpl implements Pack200.Unpacker {
|
||||
*/
|
||||
public void unpack(InputStream in0, JarOutputStream out) throws IOException {
|
||||
assert(Utils.currentInstance.get() == null);
|
||||
TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
|
||||
TimeZone.getDefault();
|
||||
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
|
||||
? null
|
||||
: TimeZone.getDefault();
|
||||
|
||||
try {
|
||||
Utils.currentInstance.set(this);
|
||||
if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||
final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
|
||||
final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
|
||||
BufferedInputStream in = new BufferedInputStream(in0);
|
||||
if (Utils.isJarMagic(Utils.readMagic(in))) {
|
||||
if (verbose > 0)
|
||||
Utils.log.info("Copying unpacked JAR file...");
|
||||
Utils.copyJarFile(new JarInputStream(in), out);
|
||||
} else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
|
||||
} else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
|
||||
(new DoUnpack()).run(in, out);
|
||||
in.close();
|
||||
Utils.markJarFile(out);
|
||||
@ -142,36 +136,38 @@ public class UnpackerImpl implements Pack200.Unpacker {
|
||||
// %%% Reconsider if native unpacker learns to memory-map the file.
|
||||
FileInputStream instr = new FileInputStream(in);
|
||||
unpack(instr, out);
|
||||
if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
|
||||
if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
|
||||
in.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private class DoUnpack {
|
||||
final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
|
||||
final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
|
||||
|
||||
{
|
||||
_props.setInteger(Pack200.Unpacker.PROGRESS, 0);
|
||||
props.setInteger(Pack200.Unpacker.PROGRESS, 0);
|
||||
}
|
||||
|
||||
// Here's where the bits are read from disk:
|
||||
final Package pkg = new Package();
|
||||
|
||||
final boolean keepModtime
|
||||
= Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
|
||||
= Pack200.Packer.KEEP.equals(
|
||||
props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
|
||||
final boolean keepDeflateHint
|
||||
= Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
|
||||
= Pack200.Packer.KEEP.equals(
|
||||
props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
|
||||
final int modtime;
|
||||
final boolean deflateHint;
|
||||
{
|
||||
if (!keepModtime) {
|
||||
modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
|
||||
modtime = props.getTime(Utils.UNPACK_MODIFICATION_TIME);
|
||||
} else {
|
||||
modtime = pkg.default_modtime;
|
||||
}
|
||||
|
||||
deflateHint = (keepDeflateHint) ? false :
|
||||
_props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
|
||||
props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
|
||||
}
|
||||
|
||||
// Checksum apparatus.
|
||||
@ -181,7 +177,7 @@ public class UnpackerImpl implements Pack200.Unpacker {
|
||||
|
||||
public void run(BufferedInputStream in, JarOutputStream out) throws IOException {
|
||||
if (verbose > 0) {
|
||||
_props.list(System.out);
|
||||
props.list(System.out);
|
||||
}
|
||||
for (int seg = 1; ; seg++) {
|
||||
unpackSegment(in, out);
|
||||
@ -194,25 +190,26 @@ public class UnpackerImpl implements Pack200.Unpacker {
|
||||
}
|
||||
|
||||
private void unpackSegment(InputStream in, JarOutputStream out) throws IOException {
|
||||
_props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
|
||||
props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
|
||||
// Process the output directory or jar output.
|
||||
new PackageReader(pkg, in).read();
|
||||
|
||||
if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug");
|
||||
if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile");
|
||||
_props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
|
||||
if (props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug");
|
||||
if (props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile");
|
||||
props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
|
||||
pkg.ensureAllClassFiles();
|
||||
// Now write out the files.
|
||||
HashSet classesToWrite = new HashSet(pkg.getClasses());
|
||||
HashSet<Package.Class> classesToWrite = new HashSet<>(pkg.getClasses());
|
||||
for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) {
|
||||
Package.File file = (Package.File) i.next();
|
||||
String name = file.nameString;
|
||||
JarEntry je = new JarEntry(Utils.getJarEntryName(name));
|
||||
boolean deflate;
|
||||
|
||||
deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
|
||||
((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) :
|
||||
deflateHint;
|
||||
deflate = (keepDeflateHint)
|
||||
? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
|
||||
((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0))
|
||||
: deflateHint;
|
||||
|
||||
boolean needCRC = !deflate; // STORE mode requires CRC
|
||||
|
||||
@ -250,7 +247,7 @@ public class UnpackerImpl implements Pack200.Unpacker {
|
||||
Utils.log.info("Writing "+Utils.zeString((ZipEntry)je));
|
||||
}
|
||||
assert(classesToWrite.isEmpty());
|
||||
_props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
|
||||
props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
|
||||
pkg.reset(); // reset for the next segment, if any
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,13 @@
|
||||
|
||||
package com.sun.java.util.jar.pack;
|
||||
|
||||
import com.sun.java.util.jar.pack.Attribute.Layout;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
|
||||
import java.util.*;
|
||||
import java.util.jar.*;
|
||||
import java.util.zip.*;
|
||||
@ -113,17 +120,46 @@ class Utils {
|
||||
*/
|
||||
static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200";
|
||||
|
||||
// Keep a TLS point to the current Packer or Unpacker.
|
||||
// This makes it simpler to supply environmental options
|
||||
// Keep a TLS point to the global data and environment.
|
||||
// This makes it simpler to supply environmental options
|
||||
// to the engine code, especially the native code.
|
||||
static final ThreadLocal currentInstance = new ThreadLocal();
|
||||
static final ThreadLocal<TLGlobals> currentInstance = new ThreadLocal<>();
|
||||
|
||||
// convenience methods to access the TL globals
|
||||
static TLGlobals getTLGlobals() {
|
||||
return currentInstance.get();
|
||||
}
|
||||
|
||||
static Map<String, Utf8Entry> getUtf8Entries() {
|
||||
return getTLGlobals().getUtf8Entries();
|
||||
}
|
||||
|
||||
static Map<String, ClassEntry> getClassEntries() {
|
||||
return getTLGlobals().getClassEntries();
|
||||
}
|
||||
|
||||
static Map<Object, LiteralEntry> getLiteralEntries() {
|
||||
return getTLGlobals().getLiteralEntries();
|
||||
}
|
||||
|
||||
static Map<String, DescriptorEntry> getDescriptorEntries() {
|
||||
return getTLGlobals().getDescriptorEntries();
|
||||
}
|
||||
|
||||
static Map<String, SignatureEntry> getSignatureEntries() {
|
||||
return getTLGlobals().getSignatureEntries();
|
||||
}
|
||||
|
||||
static Map<String, MemberEntry> getMemberEntries() {
|
||||
return getTLGlobals().getMemberEntries();
|
||||
}
|
||||
|
||||
static PropMap currentPropMap() {
|
||||
Object obj = currentInstance.get();
|
||||
if (obj instanceof PackerImpl)
|
||||
return ((PackerImpl)obj)._props;
|
||||
return ((PackerImpl)obj).props;
|
||||
if (obj instanceof UnpackerImpl)
|
||||
return ((UnpackerImpl)obj)._props;
|
||||
return ((UnpackerImpl)obj).props;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user