]> source.dussan.org Git - vaadin-framework.git/commitdiff
Cleaned up GeneratePackageExports (#9793) 72/72/1
authorArtur Signell <artur@vaadin.com>
Mon, 8 Oct 2012 12:50:21 +0000 (15:50 +0300)
committerArtur Signell <artur@vaadin.com>
Mon, 8 Oct 2012 12:52:03 +0000 (15:52 +0300)
No longer deletes existing Export-Packages or generate empty Export-Package attributes

Change-Id: I17df2f74b42a50a3b2c63bc4fb79a92721aabd72

buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java

index be7d502baae4e0a1a3718311545d9990c8d8f444..bf9bd7e068032098a5e81eea2cb023851dfcf9c9 100644 (file)
@@ -5,28 +5,26 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Vector;
 import java.util.jar.Attributes;
-import java.util.jar.Attributes.Name;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 
 /**
  * Generates Export-Packages attribute for OSGi compatible manifest.
- * 
- * Reads the included Java packages in Vaadin JAR, generates a corresponding
- * MANIFEST.MF file, and replaces the dummy one in the JAR with the generated
- * one.
- * 
+ * <p>
+ * Reads the included Java packages in a jar file, generates a corresponding
+ * Export-Package attribute, and appends it to the jar's MANIFEST.MF.
+ * <p>
  * See #3521 for details.
  * 
  * @author magi
  */
 public class GeneratePackageExports {
 
+    private static final String EXPORT_PACKAGE_ATTRIBUTE = "Export-Package";
+
     public static void main(String[] args) {
         if (args.length < 2) {
             System.err
@@ -52,6 +50,70 @@ public class GeneratePackageExports {
         }
 
         // List the included Java packages
+        HashSet<String> packages = getPackages(jar, acceptedPackagePrefixes);
+
+        // Avoid writing empty Export-Package attribute
+        if (packages.isEmpty()) {
+            return;
+        }
+
+        String exportPackage = sortAndJoinPackages(packages);
+
+        // Read old manifest
+        Manifest oldMF = null;
+        try {
+            oldMF = jar.getManifest();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        Attributes mainAttributes = oldMF.getMainAttributes();
+
+        String existingExportPackage = mainAttributes
+                .getValue(EXPORT_PACKAGE_ATTRIBUTE);
+        if (existingExportPackage != null) {
+            exportPackage = existingExportPackage + "," + exportPackage;
+        }
+
+        // Jar must be closed before updating it below, as it's
+        // locked in Windows until closed. (#6045)
+        try {
+            jar.close();
+        } catch (IOException e) {
+            System.err.println("Unable to close JAR '" + jarFilename + "'");
+        }
+
+        // Create the modified manifest
+        ManifestWriter manifest = new ManifestWriter();
+        manifest.writeAttribute(EXPORT_PACKAGE_ATTRIBUTE, exportPackage);
+
+        // Update the manifest in the Jar. The jar must be closed
+        // before this is done.
+        int status = manifest.updateJar(jarFilename);
+
+        if (status != 0) {
+            System.exit(status);
+        }
+    }
+
+    private static String sortAndJoinPackages(HashSet<String> packages) {
+        // Produce an ordered listing of the package names
+        String packageArray[] = new String[packages.size()];
+        packages.toArray(packageArray);
+        Arrays.sort(packageArray);
+        StringBuilder joinedPackages = new StringBuilder();
+        for (int i = 0; i < packageArray.length; i++) {
+            if (i != 0) {
+                joinedPackages.append(",");
+            }
+
+            joinedPackages.append(packageArray[i]);
+        }
+
+        return joinedPackages.toString();
+    }
+
+    private static HashSet<String> getPackages(JarFile jar,
+            List<String> acceptedPackagePrefixes) {
         HashSet<String> packages = new HashSet<String>();
         for (Enumeration<JarEntry> it = jar.entries(); it.hasMoreElements();) {
             JarEntry entry = it.nextElement();
@@ -89,81 +151,6 @@ public class GeneratePackageExports {
             }
         }
 
-        // Replacement for the "Export-Package" attribute in the manifest
-        String exportPackage = "";
-
-        // Produce an ordered listing of the package names
-        String packageArray[] = new String[packages.size()];
-        packages.toArray(packageArray);
-        Arrays.sort(packageArray);
-        for (int i = 0; i < packageArray.length; i++) {
-            if (i == 0) {
-                exportPackage = packageArray[i];
-            } else {
-                exportPackage += ", " + packageArray[i];
-            }
-        }
-
-        // Read old manifest
-        Manifest oldMF = null;
-        try {
-            oldMF = jar.getManifest();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-        // Read main attributes
-        Attributes mainAtts = oldMF.getMainAttributes();
-        Vector<String> keys = new Vector<String>(mainAtts.size());
-        for (Iterator<Object> attrit = mainAtts.keySet().iterator(); attrit
-                .hasNext();) {
-            Name name = (Name) attrit.next();
-            keys.add(name.toString());
-        }
-
-        // Jar must be closed before updating it below, as it's
-        // locked in Windows until closed. (#6045)
-        try {
-            jar.close();
-        } catch (IOException e) {
-            System.err.println("Unable to close JAR '" + jarFilename + "'");
-        }
-
-        // Put the manifest version as the first line
-        String orderedKeys[] = new String[keys.size()];
-        keys.toArray(orderedKeys);
-        Arrays.sort(orderedKeys); // Must sort to be able to search
-        int mvPos = Arrays.binarySearch(orderedKeys, "Manifest-Version");
-        orderedKeys[mvPos] = orderedKeys[0]; // Swap
-        orderedKeys[0] = "Manifest-Version";
-
-        // This final ordering is just for esthetic reasons and
-        // in practice unnecessary and will actually be messed up
-        // when the 'jar' command reads the manifest
-        Arrays.sort(orderedKeys, 1, orderedKeys.length - 1);
-
-        // Create the modified manifest
-        ManifestWriter manifest = new ManifestWriter();
-        for (int i = 0; i < orderedKeys.length; i++) {
-            // Skip an existing Export-Package attribute
-            if (orderedKeys[i].equals("Export-Package")) {
-                // Copy the attribute to the modified manifest
-                manifest.writeAttribute(orderedKeys[i],
-                        mainAtts.getValue(orderedKeys[i]));
-            }
-        }
-
-        // Add the Export-Package attribute at the end of the manifest.
-        // The alternative would be replacing an existing attribute in
-        // the loop above, but it's not guaranteed that it exists.
-        manifest.writeAttribute("Export-Package", exportPackage);
-
-        // Update the manifest in the Jar. The jar must be closed
-        // before this is done.
-        int status = manifest.updateJar(jarFilename);
-
-        if (status != 0) {
-            System.exit(status);
-        }
+        return packages;
     }
 }