harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sjanu...@apache.org
Subject svn commit: r784048 [2/2] - in /harmony/enhanced/classlib/trunk/modules/pack200/src: main/java/org/apache/harmony/pack200/ main/java5/org/apache/harmony/pack200/ test/java/org/apache/harmony/pack200/tests/
Date Fri, 12 Jun 2009 09:32:54 GMT
Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PackingOptions.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PackingOptions.java?rev=784048&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PackingOptions.java
(added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PackingOptions.java
Fri Jun 12 09:32:53 2009
@@ -0,0 +1,377 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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 org.apache.harmony.pack200;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.objectweb.asm.Attribute;
+
+/**
+ * Utility class to manage the various options available for pack200
+ */
+public class PackingOptions {
+
+    public static final String STRIP = "strip";
+    public static final String ERROR = "error";
+    public static final String PASS = "pass";
+    public static final String KEEP = "keep";
+
+    // All options are initially set to their defaults
+    private boolean repack = false;
+    private boolean gzip = true;
+    private boolean stripDebug = false;
+    private boolean keepFileOrder = true;
+    private long segmentLimit = 1000000;
+    private int effort = 5;
+    private String deflateHint = KEEP;
+    private String modificationTime = KEEP;
+    private List passFiles;
+    private String unknownAttributeAction = PASS;
+    private Map classAttributeActions;
+    private Map fieldAttributeActions;
+    private Map methodAttributeActions;
+    private Map codeAttributeActions;
+    private boolean verbose = false;
+    private boolean quiet = true;
+    private String logFile;
+
+    private Attribute[] unknownAttributeTypes;
+
+    public boolean isRepack() {
+        return repack;
+    }
+
+    public void setRepack(boolean repack) {
+        this.repack = repack;
+    }
+
+    public boolean isGzip() {
+        return gzip;
+    }
+
+    public void setGzip(boolean gzip) {
+        this.gzip = gzip;
+    }
+
+    public boolean isStripDebug() {
+        return stripDebug;
+    }
+
+    /**
+     * Set strip debug attributes. If true, all debug attributes (i.e.
+     * LineNumberTable, SourceFile, LocalVariableTable and
+     * LocalVariableTypeTable attributes) are stripped when reading the input
+     * class files and not included in the output archive.
+     *
+     * @param stripDebug
+     */
+    public void setStripDebug(boolean stripDebug) {
+        this.stripDebug = stripDebug;
+    }
+
+    public boolean isKeepFileOrder() {
+        return keepFileOrder;
+    }
+
+    public void setKeepFileOrder(boolean keepFileOrder) {
+        this.keepFileOrder = keepFileOrder;
+    }
+
+    public long getSegmentLimit() {
+        return segmentLimit;
+    }
+
+    /**
+     * Set the segment limit (equivalent to -S command line option)
+     * @param segmentLimit - the limit in bytes
+     */
+    public void setSegmentLimit(long segmentLimit) {
+        this.segmentLimit = segmentLimit;
+    }
+
+    public int getEffort() {
+        return effort;
+    }
+
+    /**
+     * Set the compression effort level (0-9, equivalent to -E command line option)
+     * @param effort
+     */
+    public void setEffort(int effort) {
+        this.effort = effort;
+    }
+
+    public String getDeflateHint() {
+        return deflateHint;
+    }
+
+    public void setDeflateHint(String deflateHint) {
+        this.deflateHint = deflateHint;
+    }
+
+    public String getModificationTime() {
+        return modificationTime;
+    }
+
+    public void setModificationTime(String modificationTime) {
+        this.modificationTime = modificationTime;
+    }
+
+    public List getPassFiles() {
+        return passFiles;
+    }
+
+    /**
+     * Tell the compressor to pass the file with the given name, or if the name
+     * is a directory name all files under that directory will be passed.
+     *
+     * @param passFileName
+     *            the file name
+     */
+    public void addPassFile(String passFileName) {
+        if(passFiles == null) {
+            passFiles = new ArrayList();
+        }
+        passFiles.add(passFileName);
+    }
+
+    public void removePassFile(String passFileName) {
+        passFiles.remove(passFileName);
+    }
+
+    public String getUnknownAttributeAction() {
+        return unknownAttributeAction;
+    }
+
+    /**
+     * Tell the compressor what to do if an unknown attribute is encountered
+     * @param unknownAttributeAction - the action to perform
+     */
+    public void setUnknownAttributeAction(String unknownAttributeAction) {
+        this.unknownAttributeAction = unknownAttributeAction;
+        if (!unknownAttributeAction.equals(PASS)
+                && !unknownAttributeAction.equals(ERROR)
+                && !unknownAttributeAction.equals(STRIP)) {
+            throw new RuntimeException("Incorrect option for -U, "
+                    + unknownAttributeAction);
+        }
+    }
+
+    public Map getClassAttributeActions() {
+        return classAttributeActions;
+    }
+
+    public void addClassAttributeAction(String attributeName, String action) {
+        if(classAttributeActions == null) {
+            classAttributeActions = new HashMap();
+        }
+        classAttributeActions.put(attributeName, action);
+    }
+
+    public Map getFieldAttributeActions() {
+        return fieldAttributeActions;
+    }
+
+    public void addFieldAttributeAction(String attributeName, String action) {
+        if(fieldAttributeActions == null) {
+            fieldAttributeActions = new HashMap();
+        }
+        fieldAttributeActions.put(attributeName, action);
+    }
+
+    public Map getMethodAttributeActions() {
+        return methodAttributeActions;
+    }
+
+    public void addMethodAttributeAction(String attributeName, String action) {
+        if(methodAttributeActions == null) {
+            methodAttributeActions = new HashMap();
+        }
+        methodAttributeActions.put(attributeName, action);
+    }
+
+    public Map getCodeAttributeActions() {
+        return codeAttributeActions;
+    }
+
+    public void addCodeAttributeAction(String attributeName, String action) {
+        if(codeAttributeActions == null) {
+            codeAttributeActions = new HashMap();
+        }
+        codeAttributeActions.put(attributeName, action);
+    }
+
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    public boolean isQuiet() {
+        return quiet;
+    }
+
+    public void setQuiet(boolean quiet) {
+        this.quiet = quiet;
+    }
+
+    public String getLogFile() {
+        return logFile;
+    }
+
+    public void setLogFile(String logFile) {
+        this.logFile = logFile;
+    }
+
+    public Attribute[] getUnknownAttributePrototypes() {
+        if(unknownAttributeTypes == null) {
+            List prototypes = new ArrayList();
+            if(classAttributeActions != null) {
+                for (Iterator iterator = classAttributeActions.keySet().iterator(); iterator
+                        .hasNext();) {
+                    String name = (String) iterator.next();
+                    String action = (String) classAttributeActions.get(name);
+                    if(!(action.equals(ERROR)
+                            || action.equals(STRIP)
+                            || action.equals(PASS))) {
+                        NewAttribute prototype = new NewAttribute(name, action, AttributeDefinitionBands.CONTEXT_CLASS);
+                        prototypes.add(prototype);
+                    }
+                }
+            }
+            if(methodAttributeActions != null) {
+                for (Iterator iterator = methodAttributeActions.keySet().iterator(); iterator
+                        .hasNext();) {
+                    String name = (String) iterator.next();
+                    String action = (String) methodAttributeActions.get(name);
+                    if(!(action.equals(ERROR)
+                            || action.equals(STRIP)
+                            || action.equals(PASS))) {
+                        boolean prototypeExists = false;
+                        for (Iterator iterator2 = prototypes.iterator(); iterator2
+                                .hasNext();) {
+                            NewAttribute newAttr = (NewAttribute) iterator2.next();
+                            if(newAttr.type.equals(name)) {
+                                newAttr.addContext(AttributeDefinitionBands.CONTEXT_METHOD);
+                                prototypeExists = true;
+                                break;
+                            }
+                        }
+                        if(!prototypeExists) {
+                            NewAttribute prototype = new NewAttribute(name, action, AttributeDefinitionBands.CONTEXT_METHOD);
+                            prototypes.add(prototype);
+                        }
+                    }
+                }
+            }
+            if(fieldAttributeActions != null) {
+                for (Iterator iterator = fieldAttributeActions.keySet().iterator(); iterator
+                        .hasNext();) {
+                    String name = (String) iterator.next();
+                    String action = (String) fieldAttributeActions.get(name);
+                    if(!(action.equals(ERROR)
+                            || action.equals(STRIP)
+                            || action.equals(PASS))) {
+                        boolean prototypeExists = false;
+                        for (Iterator iterator2 = prototypes.iterator(); iterator2
+                                .hasNext();) {
+                            NewAttribute newAttr = (NewAttribute) iterator2.next();
+                            if(newAttr.type.equals(name)) {
+                                newAttr.addContext(AttributeDefinitionBands.CONTEXT_FIELD);
+                                prototypeExists = true;
+                                break;
+                            }
+                        }
+                        if(!prototypeExists) {
+                            NewAttribute prototype = new NewAttribute(name, action, AttributeDefinitionBands.CONTEXT_FIELD);
+                            prototypes.add(prototype);
+                        }
+                    }
+                }
+            }
+            if(codeAttributeActions != null) {
+                for (Iterator iterator = codeAttributeActions.keySet().iterator(); iterator
+                        .hasNext();) {
+                    String name = (String) iterator.next();
+                    String action = (String) codeAttributeActions.get(name);
+                    if(!(action.equals(ERROR)
+                            || action.equals(STRIP)
+                            || action.equals(PASS))) {
+                        boolean prototypeExists = false;
+                        for (Iterator iterator2 = prototypes.iterator(); iterator2
+                                .hasNext();) {
+                            NewAttribute newAttr = (NewAttribute) iterator2.next();
+                            if(newAttr.type.equals(name)) {
+                                newAttr.addContext(AttributeDefinitionBands.CONTEXT_CODE);
+                                prototypeExists = true;
+                                break;
+                            }
+                        }
+                        if(!prototypeExists) {
+                            NewAttribute prototype = new NewAttribute(name, action, AttributeDefinitionBands.CONTEXT_CODE);
+                            prototypes.add(prototype);
+                        }
+                    }
+                }
+            }
+            unknownAttributeTypes = new Attribute[prototypes.size()];
+            for (int i = 0; i < unknownAttributeTypes.length; i++) {
+                unknownAttributeTypes[i] = (Attribute) prototypes.get(i);
+            }
+        }
+        return unknownAttributeTypes;
+    }
+
+    public String getUnknownClassAttributeAction(String type) {
+        String action = (String) classAttributeActions.get(type);
+        if(action == null) {
+            action = unknownAttributeAction;
+        }
+        return action;
+    }
+
+    public String getUnknownMethodAttributeAction(String type) {
+        String action = (String) methodAttributeActions.get(type);
+        if(action == null) {
+            action = unknownAttributeAction;
+        }
+        return action;
+    }
+
+    public String getUnknownFieldAttributeAction(String type) {
+        String action = (String) fieldAttributeActions.get(type);
+        if(action == null) {
+            action = unknownAttributeAction;
+        }
+        return action;
+    }
+
+    public String getUnknownCodeAttributeAction(String type) {
+        String action = (String) codeAttributeActions.get(type);
+        if(action == null) {
+            action = unknownAttributeAction;
+        }
+        return action;
+    }
+
+}

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PackingOptions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PackingOptions.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=784048&r1=784047&r2=784048&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
Fri Jun 12 09:32:53 2009
@@ -23,6 +23,7 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.harmony.pack200.Archive.File;
 import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.Attribute;
 import org.objectweb.asm.ClassReader;
@@ -32,6 +33,9 @@
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Type;
 
+/**
+ * A Pack200 archive consists of one or more Segments.
+ */
 public class Segment implements ClassVisitor {
 
     private SegmentHeader segmentHeader;
@@ -45,24 +49,43 @@
     private final SegmentFieldVisitor fieldVisitor = new SegmentFieldVisitor();
     private final SegmentMethodVisitor methodVisitor = new SegmentMethodVisitor();
     private Pack200ClassReader currentClassReader;
+    private PackingOptions options;
     private boolean stripDebug;
-    private int effort;
+    private Attribute[] nonStandardAttributePrototypes;
 
-    public void pack(List classes, List files, OutputStream out, boolean stripDebug, int
effort)
+    /**
+     * The main method on Segment. Reads in all the class files, packs them and
+     * then writes the packed segment out to the given OutputStream.
+     *
+     * @param classes
+     *            List of Pack200ClassReaders, one for each class file in the
+     *            segment
+     * @param files
+     *            List of Archive.Files, one for each file in the segment
+     * @param out
+     *            the OutputStream to write the packed Segment to
+     * @param options
+     *            packing options
+     * @throws IOException
+     * @throws Pack200Exception
+     */
+    public void pack(List classes, List files, OutputStream out, PackingOptions options)
             throws IOException, Pack200Exception {
-        this.effort = effort;
-        this.stripDebug = stripDebug;
+        this.options = options;
+        this.stripDebug = options.isStripDebug();
+        int effort = options.getEffort();
+        nonStandardAttributePrototypes = options.getUnknownAttributePrototypes();
         segmentHeader = new SegmentHeader();
         segmentHeader.setFile_count(files.size());
         segmentHeader.setHave_all_code_flags(!stripDebug);
         cpBands = new CpBands(this, effort);
-        attributeDefinitionBands = new AttributeDefinitionBands(this, effort);
+        attributeDefinitionBands = new AttributeDefinitionBands(this, effort, nonStandardAttributePrototypes);
         icBands = new IcBands(segmentHeader, cpBands, effort);
-        classBands = new ClassBands(this, classes.size(), effort);
+        classBands = new ClassBands(this, classes.size(), effort, stripDebug);
         bcBands = new BcBands(cpBands, this, effort);
         fileBands = new FileBands(cpBands, segmentHeader, files, classes, effort);
 
-        processClasses(classes);
+        processClasses(classes, files);
 
         cpBands.finaliseBands();
         attributeDefinitionBands.finaliseBands();
@@ -71,8 +94,10 @@
         bcBands.finaliseBands();
         fileBands.finaliseBands();
 
-        // Temporary fix because we have to encode the other bands before
-        // segmentHeader, but probably not very good performance
+        // Using a temporary stream because we have to pack the other bands
+        // before segmentHeader because the band_headers band is only created
+        // when the other bands are packed, but comes before them in the packed
+        // file.
         ByteArrayOutputStream tempStream = new ByteArrayOutputStream();
 
         cpBands.pack(tempStream);
@@ -86,17 +111,37 @@
         tempStream.writeTo(out);
     }
 
-    private void processClasses(List classes) {
+    private void processClasses(List classes, List files) throws Pack200Exception {
         segmentHeader.setClass_count(classes.size());
         for (Iterator iterator = classes.iterator(); iterator.hasNext();) {
             Pack200ClassReader classReader = (Pack200ClassReader) iterator
                     .next();
             currentClassReader = classReader;
-            int flags = ClassReader.SKIP_FRAMES;
+            int flags = 0;
             if(stripDebug) {
                 flags |= ClassReader.SKIP_DEBUG;
             }
-            classReader.accept(this, flags);
+            try {
+                classReader.accept(this, flags);
+            } catch (PassException pe) {
+                // Pass this class through as-is rather than packing it
+                // TODO: probably need to deal with any inner classes
+                classBands.removeCurrentClass();
+                String name = classReader.getFileName();
+                boolean found = false;
+                for (Iterator iterator2 = files.iterator(); iterator2
+                        .hasNext();) {
+                    File file = (File) iterator2.next();
+                    if(file.getName().equals(name)) {
+                        found = true;
+                        file.setContents(classReader.b);
+                        break;
+                    }
+                }
+                if(!found) {
+                    throw new Pack200Exception("Error passing file " + name);
+                }
+            }
         }
     }
 
@@ -124,7 +169,30 @@
                 desc, visible);
     }
 
-    public void visitAttribute(Attribute arg0) {
+    public void visitAttribute(Attribute attribute) {
+        if(attribute.isUnknown()) {
+            String action = options.getUnknownAttributeAction();
+            if(action.equals(PackingOptions.PASS)) {
+                passCurrentClass();
+            } else if (action.equals(PackingOptions.ERROR)) {
+                throw new Error("Unknown attribute encountered");
+            } // else skip
+        } else {
+            if(attribute instanceof NewAttribute) {
+                NewAttribute newAttribute = (NewAttribute) attribute;
+                if(newAttribute.isUnknown(AttributeDefinitionBands.CONTEXT_CLASS)) {
+                    String action = options.getUnknownClassAttributeAction(newAttribute.type);
+                    if(action.equals(PackingOptions.PASS)) {
+                        passCurrentClass();
+                    } else if (action.equals(PackingOptions.ERROR)) {
+                        throw new Error("Unknown attribute encountered");
+                    } // else skip
+                }
+                classBands.addClassAttribute(newAttribute);
+            } else {
+                throw new RuntimeException("Unexpected attribute encountered: " + attribute.type);
+            }
+        }
     }
 
     public void visitInnerClass(String name, String outerName,
@@ -148,9 +216,12 @@
         classBands.endOfClass();
     }
 
-    /*
-     * This class delegates to BcBands for bytecode related visits and to
-     * ClassBands for everything else
+    /**
+     * This class implements MethodVisitor to visit the contents and metadata
+     * related to methods in a class file.
+     *
+     * It delegates to BcBands for bytecode related visits and to ClassBands for
+     * everything else.
      */
     public class SegmentMethodVisitor implements MethodVisitor {
 
@@ -163,12 +234,48 @@
             return new SegmentAnnotationVisitor(MetadataBandGroup.CONTEXT_METHOD);
         }
 
-        public void visitAttribute(Attribute arg0) {
-            classBands.addUnknownMethodAttribute(arg0);
+        public void visitAttribute(Attribute attribute) {
+            if(attribute.isUnknown()) {
+                String action = options.getUnknownAttributeAction();
+                if(action.equals(PackingOptions.PASS)) {
+                    passCurrentClass();
+                } else if (action.equals(PackingOptions.ERROR)) {
+                    throw new Error("Unknown attribute encountered");
+                } // else skip
+            } else {
+                if(attribute instanceof NewAttribute) {
+                    NewAttribute newAttribute = (NewAttribute) attribute;
+                    if (attribute.isCodeAttribute()) {
+                        if (newAttribute.isUnknown(AttributeDefinitionBands.CONTEXT_CODE))
{
+                            String action = options
+                                    .getUnknownCodeAttributeAction(newAttribute.type);
+                            if (action.equals(PackingOptions.PASS)) {
+                                passCurrentClass();
+                            } else if (action.equals(PackingOptions.ERROR)) {
+                                throw new Error("Unknown attribute encountered");
+                            } // else skip
+                        }
+                        classBands.addCodeAttribute(newAttribute);
+                    } else {
+                        if (newAttribute.isUnknown(AttributeDefinitionBands.CONTEXT_METHOD))
{
+                            String action = options
+                                    .getUnknownMethodAttributeAction(newAttribute.type);
+                            if (action.equals(PackingOptions.PASS)) {
+                                passCurrentClass();
+                            } else if (action.equals(PackingOptions.ERROR)) {
+                                throw new Error("Unknown attribute encountered");
+                            } // else skip
+                        }
+                        classBands.addMethodAttribute(newAttribute);
+                    }
+                } else {
+                    throw new RuntimeException("Unexpected attribute encountered: " + attribute.type);
+                }
+            }
         }
 
         public void visitCode() {
-            classBands.addCode(stripDebug);
+            classBands.addCode();
         }
 
         public void visitFrame(int arg0, int arg1, Object[] arg2, int arg3,
@@ -272,6 +379,10 @@
         return classBands;
     }
 
+    /**
+     * SegmentAnnotationVisitor implements <code>AnnotationVisitor</code> to
+     * visit Annotations found in a class file.
+     */
     public class SegmentAnnotationVisitor implements AnnotationVisitor {
 
         private int context = -1;
@@ -287,7 +398,6 @@
         private final List nestNameRU = new ArrayList();
         private final List nestPairN = new ArrayList();
 
-
         public SegmentAnnotationVisitor(int context, String desc,
                 boolean visible) {
             this.context = context;
@@ -369,7 +479,6 @@
                 }
 
                 public void visitEnd() {
-                    throw new RuntimeException("Not yet supported");
                 }
 
                 public void visitEnum(String name, String desc, String value) {
@@ -450,6 +559,10 @@
         }
     }
 
+    /**
+     * SegmentFieldVisitor implements <code>FieldVisitor</code> to visit the
+     * metadata relating to fields in a class file.
+     */
     public class SegmentFieldVisitor implements FieldVisitor {
 
         public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
@@ -457,8 +570,30 @@
                     desc, visible);
         }
 
-        public void visitAttribute(Attribute arg0) {
-            classBands.addUnknownFieldAttribute(arg0);
+        public void visitAttribute(Attribute attribute) {
+            if(attribute.isUnknown()) {
+                String action = options.getUnknownAttributeAction();
+                if(action.equals(PackingOptions.PASS)) {
+                    passCurrentClass();
+                } else if (action.equals(PackingOptions.ERROR)) {
+                    throw new Error("Unknown attribute encountered");
+                } // else skip
+            } else {
+                if(attribute instanceof NewAttribute) {
+                    NewAttribute newAttribute = (NewAttribute) attribute;
+                    if(newAttribute.isUnknown(AttributeDefinitionBands.CONTEXT_FIELD)) {
+                        String action = options.getUnknownFieldAttributeAction(newAttribute.type);
+                        if(action.equals(PackingOptions.PASS)) {
+                            passCurrentClass();
+                        } else if (action.equals(PackingOptions.ERROR)) {
+                            throw new Error("Unknown attribute encountered");
+                        } // else skip
+                    }
+                    classBands.addFieldAttribute(newAttribute);
+                } else {
+                    throw new RuntimeException("Unexpected attribute encountered: " + attribute.type);
+                }
+            }
         }
 
         public void visitEnd() {
@@ -488,4 +623,18 @@
     public Pack200ClassReader getCurrentClassReader() {
         return currentClassReader;
     }
+
+    private void passCurrentClass() {
+        throw new PassException();
+    }
+
+    /**
+     * Exception indicating that the class currently being visited contains an
+     * unknown attribute, which means that by default the class file needs to be
+     * passed through as-is in the file_bands rather than being packed with
+     * pack200.
+     */
+    public class PassException extends RuntimeException {
+
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java5/org/apache/harmony/pack200/Pack200PackerAdapter.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java5/org/apache/harmony/pack200/Pack200PackerAdapter.java?rev=784048&r1=784047&r2=784048&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java5/org/apache/harmony/pack200/Pack200PackerAdapter.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java5/org/apache/harmony/pack200/Pack200PackerAdapter.java
Fri Jun 12 09:32:53 2009
@@ -31,31 +31,72 @@
  */
 public class Pack200PackerAdapter extends Pack200Adapter implements Packer {
 
-	public void pack(JarFile file, OutputStream out) throws IOException {
+    private final PackingOptions options = new PackingOptions();
+
+    public void pack(JarFile file, OutputStream out) throws IOException {
         if (file == null || out == null)
             throw new IllegalArgumentException(
                     "Must specify both input and output streams");
         completed(0);
         try {
-            new org.apache.harmony.pack200.Archive(file, out, true).pack();
+            new org.apache.harmony.pack200.Archive(file, out, options).pack();
         } catch (Pack200Exception e) {
             throw new IOException("Failed to pack Jar:" + String.valueOf(e));
         }
         completed(1);
-	}
+    }
 
-	public void pack(JarInputStream in, OutputStream out) throws IOException {
-	    if (in == null || out == null)
+    public void pack(JarInputStream in, OutputStream out) throws IOException {
+        if (in == null || out == null)
             throw new IllegalArgumentException(
                     "Must specify both input and output streams");
         completed(0);
+        PackingOptions options = new PackingOptions();
+
         try {
-            new org.apache.harmony.pack200.Archive(in, out, true).pack();
+            new org.apache.harmony.pack200.Archive(in, out, options).pack();
         } catch (Pack200Exception e) {
             throw new IOException("Failed to pack Jar:" + String.valueOf(e));
         }
         completed(1);
         in.close();
-	}
+    }
+
+    protected void firePropertyChange(String propertyName, Object oldValue,
+            Object newValue) {
+        super.firePropertyChange(propertyName, oldValue, newValue);
+        if(newValue != null && !newValue.equals(oldValue)) {
+            if (propertyName.startsWith(CLASS_ATTRIBUTE_PFX)) {
+                String attributeName = propertyName.substring(CLASS_ATTRIBUTE_PFX.length());
+                options.addClassAttributeAction(attributeName, (String)newValue);
+            } else if (propertyName.startsWith(CODE_ATTRIBUTE_PFX)) {
+                String attributeName = propertyName.substring(CODE_ATTRIBUTE_PFX.length());
+                options.addCodeAttributeAction(attributeName, (String)newValue);
+            } else if (propertyName.equals(DEFLATE_HINT)) {
+                options.setDeflateHint((String) newValue);
+            } else if (propertyName.equals(EFFORT)) {
+                options.setEffort(Integer.parseInt((String)newValue));
+            } else if (propertyName.startsWith(FIELD_ATTRIBUTE_PFX)) {
+                String attributeName = propertyName.substring(FIELD_ATTRIBUTE_PFX.length());
+                options.addFieldAttributeAction(attributeName, (String)newValue);
+            } else if (propertyName.equals(KEEP_FILE_ORDER)) {
+                options.setKeepFileOrder(Boolean.parseBoolean((String)newValue));
+            } else if (propertyName.startsWith(METHOD_ATTRIBUTE_PFX)) {
+                String attributeName = propertyName.substring(METHOD_ATTRIBUTE_PFX.length());
+                options.addMethodAttributeAction(attributeName, (String)newValue);
+            } else if (propertyName.equals(MODIFICATION_TIME)) {
+                options.setModificationTime((String)newValue);
+            } else if (propertyName.startsWith(PASS_FILE_PFX)) {
+                if(oldValue != null && !oldValue.equals("")) {
+                    options.removePassFile((String)oldValue);
+                }
+                options.addPassFile((String) newValue);
+            } else if (propertyName.equals(SEGMENT_LIMIT)) {
+                options.setSegmentLimit(Long.parseLong((String)newValue));
+            } else if (propertyName.equals(UNKNOWN_ATTRIBUTE)) {
+                options.setUnknownAttributeAction((String)newValue);
+            }
+        }
+    }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java?rev=784048&r1=784047&r2=784048&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java
Fri Jun 12 09:32:53 2009
@@ -34,6 +34,7 @@
 
 import org.apache.harmony.pack200.Archive;
 import org.apache.harmony.pack200.Pack200Exception;
+import org.apache.harmony.pack200.PackingOptions;
 import org.apache.harmony.unpack200.Segment;
 
 public class ArchiveTest extends TestCase {
@@ -47,7 +48,7 @@
                 "/org/apache/harmony/pack200/tests/hw.jar").toURI()));
         file = File.createTempFile("helloworld", ".pack.gz");
         out = new FileOutputStream(file);
-        new Archive(in, out, true).pack();
+        new Archive(in, out, null).pack();
         in.close();
         out.close();
 
@@ -97,7 +98,10 @@
                 "/org/apache/harmony/pack200/tests/sqlUnpacked.jar").toURI()));
         file = File.createTempFile("sql", ".pack");
         out = new FileOutputStream(file);
-        new Archive(in, out, false).pack();
+        PackingOptions options = new PackingOptions();
+        options.setGzip(false);
+        Archive ar = new Archive(in, out, options);
+        ar.pack();
         in.close();
         out.close();
 
@@ -125,7 +129,9 @@
                 .toURI()));
         file = File.createTempFile("largeClass", ".pack");
         out = new FileOutputStream(file);
-        new Archive(in, out, false).pack();
+        PackingOptions options = new PackingOptions();
+        options.setGzip(false);
+        new Archive(in, out, options).pack();
         in.close();
         out.close();
 
@@ -152,7 +158,9 @@
                 "/org/apache/harmony/pack200/tests/jndi.jar").toURI()));
         file = File.createTempFile("jndi", ".pack");
         out = new FileOutputStream(file);
-        new Archive(in, out, false).pack();
+        PackingOptions options = new PackingOptions();
+        options.setGzip(false);
+        new Archive(in, out, options).pack();
         in.close();
         out.close();
 
@@ -176,8 +184,9 @@
                 "/org/apache/harmony/pack200/tests/hw.jar").toURI()));
         file = File.createTempFile("helloworld", ".pack.gz");
         out = new FileOutputStream(file);
-        Archive archive = new Archive(in, out, true);
-        archive.setSegmentLimit(0);
+        PackingOptions options = new PackingOptions();
+        options.setSegmentLimit(0);
+        Archive archive = new Archive(in, out, options);
         archive.pack();
         in.close();
         out.close();
@@ -186,8 +195,9 @@
                 "/org/apache/harmony/pack200/tests/hw.jar").toURI()));
         file = File.createTempFile("helloworld", ".pack.gz");
         out = new FileOutputStream(file);
-        archive = new Archive(in, out, true);
-        archive.setSegmentLimit(-1);
+        options = new PackingOptions();
+        options.setSegmentLimit(-1);
+        archive = new Archive(in, out, options);
         archive.pack();
         in.close();
         out.close();
@@ -196,8 +206,9 @@
                 "/org/apache/harmony/pack200/tests/hw.jar").toURI()));
         file = File.createTempFile("helloworld", ".pack.gz");
         out = new FileOutputStream(file);
-        archive = new Archive(in, out, true);
-        archive.setSegmentLimit(5000);
+        options = new PackingOptions();
+        options.setSegmentLimit(5000);
+        archive = new Archive(in, out, options);
         archive.pack();
         in.close();
         out.close();
@@ -208,8 +219,10 @@
                 .getResource("/org/apache/harmony/pack200/tests/sqlUnpacked.jar").toURI()));
         file = File.createTempFile("sql", ".pack");
         out = new FileOutputStream(file);
-        Archive archive = new Archive(in, out, false);
-        archive.stripDebugAttributes();
+        PackingOptions options = new PackingOptions();
+        options.setGzip(false);
+        options.setStripDebug(true);
+        Archive archive = new Archive(in, out, options);
         archive.pack();
         in.close();
         out.close();
@@ -239,7 +252,9 @@
                 .toURI()));
         file = File.createTempFile("annotations", ".pack");
         out = new FileOutputStream(file);
-        new Archive(in, out, false).pack();
+        PackingOptions options = new PackingOptions();
+        options.setGzip(false);
+        new Archive(in, out, options).pack();
         in.close();
         out.close();
 
@@ -264,8 +279,10 @@
         in = new JarFile(f1);
         file = File.createTempFile("jndiE0", ".pack");
         out = new FileOutputStream(file);
-        Archive archive = new Archive(in, out, false);
-        archive.setEffort(0);
+        PackingOptions options = new PackingOptions();
+        options.setGzip(false);
+        options.setEffort(0);
+        Archive archive = new Archive(in, out, options);
         archive.pack();
         in.close();
         out.close();
@@ -298,7 +315,7 @@
 				file = File.createTempFile("temp", ".pack.gz");
 		        out = new FileOutputStream(file);
 //		        System.out.println("packing " + children[i]);
-		        new Archive(in, out, true).pack();
+		        new Archive(in, out, null).pack();
 		        in.close();
 		        out.close();
 
@@ -319,6 +336,7 @@
             String name = entry.getName();
             JarEntry entry2 = jarFile2.getJarEntry(name);
             assertNotNull("Missing Entry: " + name, entry2);
+//            assertEquals(entry.getTime(), entry2.getTime());
             if (!name.equals("META-INF/MANIFEST.MF")) { // Manifests aren't
                                                         // necessarily
                                                         // byte-for-byte



Mime
View raw message