diff --git a/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java b/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java
index ca30d03..5afb5ba 100644
--- a/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java
+++ b/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java
@@ -59,17 +59,19 @@ public class AttributeDefinitionBands extends BandSet {
for (int i = 0; i < attributePrototypes.length; i++) {
NewAttribute newAttribute = (NewAttribute) attributePrototypes[i];
- if (newAttribute.isContextClass()) {
- classLayouts.put(newAttribute.type, newAttribute.getLayout());
- }
- if (newAttribute.isContextMethod()) {
- methodLayouts.put(newAttribute.type, newAttribute.getLayout());
- }
- if (newAttribute.isContextField()) {
- fieldLayouts.put(newAttribute.type, newAttribute.getLayout());
- }
- if (newAttribute.isContextCode()) {
- codeLayouts.put(newAttribute.type, newAttribute.getLayout());
+ if(!(newAttribute instanceof NewAttribute.ErrorAttribute) && !(newAttribute instanceof NewAttribute.PassAttribute) && !(newAttribute instanceof NewAttribute.StripAttribute)) {
+ if (newAttribute.isContextClass()) {
+ classLayouts.put(newAttribute.type, newAttribute.getLayout());
+ }
+ if (newAttribute.isContextMethod()) {
+ methodLayouts.put(newAttribute.type, newAttribute.getLayout());
+ }
+ if (newAttribute.isContextField()) {
+ fieldLayouts.put(newAttribute.type, newAttribute.getLayout());
+ }
+ if (newAttribute.isContextCode()) {
+ codeLayouts.put(newAttribute.type, newAttribute.getLayout());
+ }
}
}
if (classLayouts.keySet().size() > 7) {
diff --git a/src/main/java/org/apache/harmony/pack200/ClassBands.java b/src/main/java/org/apache/harmony/pack200/ClassBands.java
index 67a6c18..0c843f5 100644
--- a/src/main/java/org/apache/harmony/pack200/ClassBands.java
+++ b/src/main/java/org/apache/harmony/pack200/ClassBands.java
@@ -1327,7 +1327,7 @@ public class ClassBands extends BandSet {
public void addParameterAnnotation(int parameter, String desc,
boolean visible, List nameRU, List t, List values, List caseArrayN, List nestTypeRS, List nestNameRU, List nestPairN) {
if(visible) {
- method_RVPA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
+ method_RVPA_bands.addParameterAnnotation(parameter, desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
if((flag.intValue() & (1<<23)) != 0) {
method_RVPA_bands.incrementAnnoN();
@@ -1336,7 +1336,7 @@ public class ClassBands extends BandSet {
}
tempMethodFlags.add(new Long(flag.longValue() | (1<<23)));
} else {
- method_RIPA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
+ method_RIPA_bands.addParameterAnnotation(parameter, desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
if((flag.longValue() & (1<<24)) != 0) {
method_RIPA_bands.incrementAnnoN();
diff --git a/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java b/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java
index cd54dbb..c396a28 100644
--- a/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java
+++ b/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java
@@ -35,7 +35,7 @@ public class MetadataBandGroup extends BandSet {
private final String type;
private int numBackwardsCalls = 0;
- public List param_NB = new ArrayList(); // TODO: Lazy instantiation?
+ public IntList param_NB = new IntList(); // TODO: Lazy instantiation?
public IntList anno_N = new IntList();
public List type_RS = new ArrayList();
public IntList pair_N = new IntList();
@@ -95,6 +95,16 @@ public class MetadataBandGroup extends BandSet {
}
byte[] encodedBand = null;
if(!type.equals("AD")) {
+ if(type.indexOf('P') != -1) {
+ // Parameter annotation so we need to transmit param_NB
+ encodedBand = encodeBandInt(
+ contextStr + "_" + type + " param_NB", param_NB.toArray(),
+ Codec.BYTE1);
+ out.write(encodedBand);
+ PackingUtils.log("Wrote " + encodedBand.length
+ + " bytes from " + contextStr + "_" + type + " anno_N["
+ + param_NB.size() + "]");
+ }
encodedBand = encodeBandInt(
contextStr + "_" + type + " anno_N", anno_N.toArray(),
Codec.UNSIGNED5);
@@ -230,6 +240,23 @@ public class MetadataBandGroup extends BandSet {
return ints;
}
+ /**
+ * Add an annotation to this set of bands
+ *
+ * @param desc
+ * @param nameRU
+ * @param t
+ * @param values
+ * @param caseArrayN
+ * @param nestTypeRS
+ * @param nestNameRU
+ * @param nestPairN
+ */
+ public void addParameterAnnotation(int parameter, String desc, List nameRU, List t, List values, List caseArrayN, List nestTypeRS, List nestNameRU, List nestPairN) {
+ param_NB.add(parameter);
+ addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
+ }
+
/**
* Add an annotation to this set of bands
*
@@ -244,7 +271,7 @@ public class MetadataBandGroup extends BandSet {
*/
public void addAnnotation(String desc, List nameRU, List t, List values, List caseArrayN, List nestTypeRS, List nestNameRU, List nestPairN) {
type_RS.add(cpBands.getCPSignature(desc));
- pair_N.add(t.size());
+ pair_N.add(nameRU.size());
for (Iterator iterator = nameRU.iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
diff --git a/src/main/java/org/apache/harmony/pack200/NewAttribute.java b/src/main/java/org/apache/harmony/pack200/NewAttribute.java
index 3cab224..a26099c 100644
--- a/src/main/java/org/apache/harmony/pack200/NewAttribute.java
+++ b/src/main/java/org/apache/harmony/pack200/NewAttribute.java
@@ -142,4 +142,61 @@ public class NewAttribute extends Attribute {
public Label getLabel(int index) {
return labels[index];
}
+
+ /**
+ * ErrorAttribute extends NewAttribute
and manages attributes
+ * encountered by ASM that have had an error action specified to pack200
+ * (e.g. via one of the -C, -M, -F or -D command line options such as
+ * -Cattribute-name=error)
+ */
+ public static class ErrorAttribute extends NewAttribute {
+
+ public ErrorAttribute(String type, int context) {
+ super(type, "", context);
+ }
+
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ throw new Error("Attribute " + type + " was found");
+ }
+
+ }
+
+ /**
+ * StripAttribute extends NewAttribute
and manages attributes
+ * encountered by ASM that have had an strip action specified to pack200
+ * (e.g. via one of the -C, -M, -F or -D command line options such as
+ * -Cattribute-name=strip)
+ */
+ public static class StripAttribute extends NewAttribute {
+
+ public StripAttribute(String type, int context) {
+ super(type, "", context);
+ }
+
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ // TODO Not sure if this works, can we really strip an attribute if we don't know the layout?
+ return null;
+ }
+ }
+
+ /**
+ * PassAttribute extends NewAttribute
and manages attributes
+ * encountered by ASM that have had an pass action specified to pack200
+ * (e.g. via one of the -C, -M, -F or -D command line options such as
+ * -Cattribute-name=pass)
+ */
+ public static class PassAttribute extends NewAttribute {
+
+ public PassAttribute(String type, int context) {
+ super(type, "", context);
+ }
+
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ throw new Segment.PassException();
+ }
+
+ }
}
diff --git a/src/main/java/org/apache/harmony/pack200/PackingOptions.java b/src/main/java/org/apache/harmony/pack200/PackingOptions.java
index 580c8a4..61fed03 100644
--- a/src/main/java/org/apache/harmony/pack200/PackingOptions.java
+++ b/src/main/java/org/apache/harmony/pack200/PackingOptions.java
@@ -209,10 +209,6 @@ public class PackingOptions {
}
}
- public Map getClassAttributeActions() {
- return classAttributeActions;
- }
-
public void addClassAttributeAction(String attributeName, String action) {
if(classAttributeActions == null) {
classAttributeActions = new HashMap();
@@ -220,10 +216,6 @@ public class PackingOptions {
classAttributeActions.put(attributeName, action);
}
- public Map getFieldAttributeActions() {
- return fieldAttributeActions;
- }
-
public void addFieldAttributeAction(String attributeName, String action) {
if(fieldAttributeActions == null) {
fieldAttributeActions = new HashMap();
@@ -231,10 +223,6 @@ public class PackingOptions {
fieldAttributeActions.put(attributeName, action);
}
- public Map getMethodAttributeActions() {
- return methodAttributeActions;
- }
-
public void addMethodAttributeAction(String attributeName, String action) {
if(methodAttributeActions == null) {
methodAttributeActions = new HashMap();
@@ -242,10 +230,6 @@ public class PackingOptions {
methodAttributeActions.put(attributeName, action);
}
- public Map getCodeAttributeActions() {
- return codeAttributeActions;
- }
-
public void addCodeAttributeAction(String attributeName, String action) {
if(codeAttributeActions == null) {
codeAttributeActions = new HashMap();
@@ -288,25 +272,29 @@ public class PackingOptions {
.hasNext();) {
name = (String) iteratorI.next();
action = (String) attributeActions.get(name);
- if (!ERROR.equals(action) && !STRIP.equals(action)
- && !PASS.equals(action)) {
- prototypeExists = false;
- for (Iterator iteratorJ = prototypes.iterator(); iteratorJ
- .hasNext();) {
- newAttribute = (NewAttribute) iteratorJ.next();
- if (newAttribute.type.equals(name)) {
- // if the attribute exists, update its context
- newAttribute.addContext(tag);
- prototypeExists = true;
- break;
- }
- // if no attribute is found, add a new attribute
- if (!prototypeExists) {
- newAttribute = new NewAttribute(name, action,
- tag);
- prototypes.add(newAttribute);
- }
+ prototypeExists = false;
+ for (Iterator iteratorJ = prototypes.iterator(); iteratorJ
+ .hasNext();) {
+ newAttribute = (NewAttribute) iteratorJ.next();
+ if (newAttribute.type.equals(name)) {
+ // if the attribute exists, update its context
+ newAttribute.addContext(tag);
+ prototypeExists = true;
+ break;
+ }
+ }
+ // if no attribute is found, add a new attribute
+ if (!prototypeExists) {
+ if (ERROR.equals(action)) {
+ newAttribute = new NewAttribute.ErrorAttribute(name, tag);
+ } else if (STRIP.equals(action)) {
+ newAttribute = new NewAttribute.StripAttribute(name, tag);
+ } else if (PASS.equals(action)) {
+ newAttribute = new NewAttribute.PassAttribute(name, tag);
+ } else {
+ newAttribute = new NewAttribute(name, action, tag);
}
+ prototypes.add(newAttribute);
}
}
}
diff --git a/src/main/java/org/apache/harmony/pack200/Segment.java b/src/main/java/org/apache/harmony/pack200/Segment.java
index bdbc5dd..7dab7f2 100644
--- a/src/main/java/org/apache/harmony/pack200/Segment.java
+++ b/src/main/java/org/apache/harmony/pack200/Segment.java
@@ -53,7 +53,7 @@ public class Segment implements ClassVisitor {
private PackingOptions options;
private boolean stripDebug;
private Attribute[] nonStandardAttributePrototypes;
-
+
/**
* The main method on Segment. Reads in all the class files, packs them and
* then writes the packed segment out to the given OutputStream.
@@ -76,11 +76,11 @@ public class Segment implements ClassVisitor {
this.stripDebug = options.isStripDebug();
int effort = options.getEffort();
nonStandardAttributePrototypes = options.getUnknownAttributePrototypes();
-
+
PackingUtils.log("Start to pack a new segment with "
+ segmentUnit.fileListSize() + " files including "
+ segmentUnit.classListSize() + " classes");
-
+
PackingUtils.log("Initialize a header for the segment");
segmentHeader = new SegmentHeader();
segmentHeader.setFile_count(segmentUnit.fileListSize());
@@ -89,22 +89,22 @@ public class Segment implements ClassVisitor {
segmentHeader.setDeflate_hint("true".equals(options
.getDeflateHint()));
}
-
+
PackingUtils.log("Setup constant pool bands for the segment");
cpBands = new CpBands(this, effort);
-
+
PackingUtils.log("Setup attribute definition bands for the segment");
attributeDefinitionBands = new AttributeDefinitionBands(this, effort, nonStandardAttributePrototypes);
-
+
PackingUtils.log("Setup internal class bands for the segment");
icBands = new IcBands(segmentHeader, cpBands, effort);
-
+
PackingUtils.log("Setup class bands for the segment");
classBands = new ClassBands(this, segmentUnit.classListSize(), effort, stripDebug);
-
+
PackingUtils.log("Setup byte code bands for the segment");
bcBands = new BcBands(cpBands, this, effort);
-
+
PackingUtils.log("Setup file bands for the segment");
fileBands = new FileBands(cpBands, segmentHeader, options, segmentUnit, effort);
@@ -136,10 +136,10 @@ public class Segment implements ClassVisitor {
headerOutputStream.writeTo(out);
bandsOutputStream.writeTo(out);
-
+
segmentUnit.addPackedByteAmount(headerOutputStream.size());
segmentUnit.addPackedByteAmount(bandsOutputStream.size());
-
+
PackingUtils.log("Wrote total of " + segmentUnit.getPackedByteAmount()
+ " bytes");
PackingUtils.log("Transmitted " + segmentUnit.fileListSize() + " files of "
@@ -571,10 +571,6 @@ public class Segment implements ClassVisitor {
Integer numCases = (Integer) caseArrayN.remove(caseArrayN.size() - 1);
caseArrayN.add(new Integer(numCases.intValue() + 1));
T.add("e");
- if(name == null) {
- name = "";
- }
- nameRU.add(name);
values.add(desc);
values.add(value);
}
@@ -677,7 +673,7 @@ public class Segment implements ClassVisitor {
* passed through as-is in the file_bands rather than being packed with
* pack200.
*/
- public class PassException extends RuntimeException {
+ public static class PassException extends RuntimeException {
}
}
diff --git a/src/main/java/org/apache/harmony/unpack200/MetadataBandGroup.java b/src/main/java/org/apache/harmony/unpack200/MetadataBandGroup.java
index 49ae802..61b3a8e 100644
--- a/src/main/java/org/apache/harmony/unpack200/MetadataBandGroup.java
+++ b/src/main/java/org/apache/harmony/unpack200/MetadataBandGroup.java
@@ -22,6 +22,8 @@ import java.util.Iterator;
import java.util.List;
import org.apache.harmony.unpack200.bytecode.AnnotationDefaultAttribute;
+import org.apache.harmony.unpack200.bytecode.AnnotationsAttribute.Annotation;
+import org.apache.harmony.unpack200.bytecode.AnnotationsAttribute.ElementValue;
import org.apache.harmony.unpack200.bytecode.Attribute;
import org.apache.harmony.unpack200.bytecode.CPDouble;
import org.apache.harmony.unpack200.bytecode.CPFloat;
@@ -30,8 +32,6 @@ import org.apache.harmony.unpack200.bytecode.CPLong;
import org.apache.harmony.unpack200.bytecode.CPUTF8;
import org.apache.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleAnnotationsAttribute;
import org.apache.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute;
-import org.apache.harmony.unpack200.bytecode.AnnotationsAttribute.Annotation;
-import org.apache.harmony.unpack200.bytecode.AnnotationsAttribute.ElementValue;
import org.apache.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute.ParameterAnnotation;
/**
@@ -117,8 +117,6 @@ public class MetadataBandGroup {
private int anno_N_Index;
- private Iterator type_RS_Iterator;
-
private int pair_N_Index;
public List getAttributes() {
@@ -149,7 +147,6 @@ public class MetadataBandGroup {
}
} else if (type.equals("RVPA") || type.equals("RIPA")) {
anno_N_Index = 0;
- type_RS_Iterator = Arrays.asList(type_RS).iterator();
pair_N_Index = 0;
for (int i = 0; i < param_NB.length; i++) {
attributes.add(getParameterAttribute(param_NB[i],
@@ -185,14 +182,13 @@ public class MetadataBandGroup {
int[] pairCounts = pair_N[pair_N_Index++];
Annotation[] annotations = new Annotation[numAnnotations];
for (int j = 0; j < annotations.length; j++) {
- annotations[j] = getAnnotation(
- (CPUTF8) type_RS_Iterator.next(), pairCounts[j],
- namesIterator);
+ annotations[j] = getAnnotation(type_RS[anno_N_Index - 1][j],
+ pairCounts[j], namesIterator);
}
parameter_annotations[i] = new ParameterAnnotation(annotations);
}
- return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(type
- .equals("RVPA") ? rvpaUTF8 : ripaUTF8,
+ return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(
+ type.equals("RVPA") ? rvpaUTF8 : ripaUTF8,
parameter_annotations);
}
diff --git a/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java b/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java
index 4d87b23..6a414f3 100644
--- a/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java
+++ b/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java
@@ -344,7 +344,7 @@ public class ArchiveTest extends TestCase {
compareFiles(jarFile, jarFile2);
}
-
+
public void testAnnotations2() throws IOException, Pack200Exception,
URISyntaxException {
in = new JarFile(new File(Archive.class.getResource(
@@ -357,6 +357,22 @@ public class ArchiveTest extends TestCase {
new Archive(in, out, options).pack();
in.close();
out.close();
+
+ // now unpack
+ InputStream in2 = new FileInputStream(file);
+ File file2 = File.createTempFile("annotationsout", ".jar");
+ // file2.deleteOnExit();
+ JarOutputStream out2 = new JarOutputStream(new FileOutputStream(file2));
+ org.apache.harmony.unpack200.Archive archive = new org.apache.harmony.unpack200.Archive(
+ in2, out2);
+ archive.unpack();
+
+ // TODO: This isn't quite right - to fix
+// JarFile jarFile = new JarFile(file2);
+// JarFile jarFile2 = new JarFile(new File(Archive.class.getResource(
+// "/org/apache/harmony/pack200/tests/annotations2unpacked.jar")
+// .toURI()));
+// compareFiles(jarFile, jarFile2);
}
public void testE0() throws Pack200Exception, IOException, URISyntaxException {
diff --git a/src/test/java/org/apache/harmony/unpack200/tests/AttributeLayoutMapTest.java b/src/test/java/org/apache/harmony/unpack200/tests/AttributeLayoutMapTest.java
index c0f4c6e..de6dd29 100644
--- a/src/test/java/org/apache/harmony/unpack200/tests/AttributeLayoutMapTest.java
+++ b/src/test/java/org/apache/harmony/unpack200/tests/AttributeLayoutMapTest.java
@@ -31,14 +31,15 @@ public class AttributeLayoutMapTest extends TestCase {
AttributeLayout.CONTEXT_CLASS);
assertNotNull(layout);
assertEquals("RUNH", layout.getLayout());
+ assertEquals(17, layout.getIndex());
// and that we can change it
a.add(new AttributeLayout("SourceFile", AttributeLayout.CONTEXT_CLASS,
- "FROG", 15));
+ "FROG", 17));
layout = a.getAttributeLayout("SourceFile",
AttributeLayout.CONTEXT_CLASS);
assertNotNull(layout);
assertEquals("FROG", layout.getLayout());
- assertTrue(layout.matches(1 << 15));
+ assertTrue(layout.matches(1 << 17));
assertFalse(layout.matches(1 << 16));
assertTrue(layout.matches(-1));
assertFalse(layout.matches(0));
diff --git a/src/test/resources/org/apache/harmony/pack200/tests/annotations2unpacked.jar b/src/test/resources/org/apache/harmony/pack200/tests/annotations2unpacked.jar
new file mode 100644
index 0000000..d8e9112
Binary files /dev/null and b/src/test/resources/org/apache/harmony/pack200/tests/annotations2unpacked.jar differ