diff options
-rw-r--r-- | buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java | 155 |
1 files changed, 71 insertions, 84 deletions
diff --git a/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java b/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java index be7d502baa..bf9bd7e068 100644 --- a/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java +++ b/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java @@ -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; } } |