aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject svn commit: r1567159 - /aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java
Date Tue, 11 Feb 2014 14:44:51 GMT
Author: davidb
Date: Tue Feb 11 14:44:51 2014
New Revision: 1567159

URL: http://svn.apache.org/r1567159
Log:
Convert file to use unix line delimiters.

Modified:
    aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java

Modified: aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java?rev=1567159&r1=1567158&r2=1567159&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java
(original)
+++ aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java
Tue Feb 11 14:44:51 2014
@@ -1,348 +1,348 @@
-/**
- * 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.aries.spifly.statictool;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Properties;
-import java.util.Set;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-
-import org.apache.aries.spifly.ConsumerHeaderProcessor;
-import org.apache.aries.spifly.SpiFlyConstants;
-import org.apache.aries.spifly.Streams;
-import org.apache.aries.spifly.Util;
-import org.apache.aries.spifly.WeavingData;
-import org.apache.aries.spifly.weaver.TCCLSetterVisitor;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-public class Main {
-    private static final String MODIFIED_BUNDLE_SUFFIX = "_spifly.jar";
-    private static final String IMPORT_PACKAGE = "Import-Package";
-
-    public static void usage() {
-        System.err.println("This tool processes OSGi Bundles that use java.util.ServiceLoader.load()
to");
-        System.err.println("obtain implementations via META-INF/services. The byte code in
the bundles is");
-        System.err.println("modified so that the ThreadContextClassLoader is set appropriately
for the ");
-        System.err.println("duration of the java.util.ServiceLoader.load() call.");
-        System.err.println("To opt-in to this process, bundles need to have the following
MANIFEST.MF");
-        System.err.println("header set:");
-        System.err.println("    " + SpiFlyConstants.SPI_CONSUMER_HEADER + ": *");
-        System.err.println("Modified bundles are written out under the following name:");
-        System.err.println("    <original-bundle-name>" + MODIFIED_BUNDLE_SUFFIX);
-        System.err.println();
-        System.err.println("Usage: java " + Main.class.getName() + " bundle1.jar bundle2.jar
...");
-        System.exit(-1);
-    }
-
-    public static void main(String ... args) throws Exception {
-        if (args.length < 1)
-            usage();
-
-        for (String arg : args) {
-            weaveJar(arg);
-        }
-    }
-
-    private static void weaveJar(String jarPath) throws Exception {
-        System.out.println("[SPI Fly Static Tool] Processing: " + jarPath);
-
-        File jarFile = new File(jarPath);
-        File tempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + jarFile.getName()
+ "_" + System.currentTimeMillis());
-        Manifest manifest = unJar(jarFile, tempDir);
-        String consumerHeaderVal = manifest.getMainAttributes().getValue(SpiFlyConstants.SPI_CONSUMER_HEADER);
-        String consumerHeaderKey = null;
-        if (consumerHeaderVal != null) {
-            consumerHeaderKey = SpiFlyConstants.SPI_CONSUMER_HEADER;
-        } else {
-            consumerHeaderVal = manifest.getMainAttributes().getValue(SpiFlyConstants.REQUIRE_CAPABILITY);
-            if (consumerHeaderVal != null) {
-                consumerHeaderKey = SpiFlyConstants.REQUIRE_CAPABILITY;
-            }
-        }
-
-        if (consumerHeaderVal != null) {
-            String bcp = manifest.getMainAttributes().getValue(Constants.BUNDLE_CLASSPATH);
-            weaveDir(tempDir, consumerHeaderKey, consumerHeaderVal, bcp);
-
-            if (SpiFlyConstants.SPI_CONSUMER_HEADER.equals(consumerHeaderKey)) {
-                manifest.getMainAttributes().remove(new Attributes.Name(SpiFlyConstants.SPI_CONSUMER_HEADER));
-                manifest.getMainAttributes().putValue(SpiFlyConstants.PROCESSED_SPI_CONSUMER_HEADER,
consumerHeaderVal);
-            } else {
-                // It's SpiFlyConstants.REQUIRE_CAPABILITY
-
-                // Take out the processor requirement, this probably needs to be improved
a little bit
-                String newConsumerHeaderVal = consumerHeaderVal.replaceAll(
-                        "osgi[.]extender;\\s*filter[:][=][\"]?[(]osgi[.]extender[=]osgi[.]serviceloader[.]processor[)][\"]?",
"").
-                        trim();
-                if (newConsumerHeaderVal.startsWith(","))
-                    newConsumerHeaderVal = newConsumerHeaderVal.substring(1);
-
-                if (newConsumerHeaderVal.endsWith(","))
-                    newConsumerHeaderVal = newConsumerHeaderVal.substring(0, newConsumerHeaderVal.length()-1);
-                manifest.getMainAttributes().putValue(SpiFlyConstants.REQUIRE_CAPABILITY,
newConsumerHeaderVal);
-                manifest.getMainAttributes().putValue("X-SpiFly-Processed-Require-Capability",
consumerHeaderVal);
-            }
-
-            // TODO if new packages needed then...
-            extendImportPackage(manifest);
-
-            File newJar = getNewJarFile(jarFile);
-            jar(newJar, tempDir, manifest);
-        } else {
-            System.out.println("[SPI Fly Static Tool] This file is not marked as an SPI Consumer.");
-        }
-        delTree(tempDir);
-    }
-
-    private static void extendImportPackage(Manifest manifest) throws IOException {
-        String utilPkgVersion = getPackageVersion(Util.class);
-
-        Version osgiVersion = Version.parseVersion(utilPkgVersion);
-
-        Version minVersion = new Version(osgiVersion.getMajor(), osgiVersion.getMinor(),
osgiVersion.getMicro());
-        Version maxVersion = new Version(osgiVersion.getMajor(), osgiVersion.getMinor() +
1, 0);
-
-        String ip = manifest.getMainAttributes().getValue(IMPORT_PACKAGE);
-        if (ip == null)
-            ip = "";
-
-        StringBuilder sb = new StringBuilder(ip);
-        if (ip.length() > 0)
-            sb.append(",");
-        sb.append(Util.class.getPackage().getName());
-        sb.append(";version=\"[");
-        sb.append(minVersion);
-        sb.append(",");
-        sb.append(maxVersion);
-        sb.append(")\"");
-        manifest.getMainAttributes().putValue(IMPORT_PACKAGE, sb.toString());
-    }
-
-    private static String getPackageVersion(Class<?> clazz) throws IOException {
-        URL url = clazz.getResource("packageinfo");
-        if (url == null) {
-            throw new RuntimeException("'packageinfo' file with version information not found
for package: "
-                    + clazz.getPackage().getName());
-        }
-
-        byte[] bytes = Streams.suck(url.openStream());
-        Properties p = new Properties();
-        p.load(new ByteArrayInputStream(bytes));
-        return p.getProperty("version");
-    }
-
-    private static File getNewJarFile(File jarFile) {
-        String s = jarFile.getAbsolutePath();
-        int idx = s.lastIndexOf('.');
-        s = s.substring(0, idx);
-        s += MODIFIED_BUNDLE_SUFFIX;
-        return new File(s);
-    }
-
-    private static void weaveDir(File dir, String consumerHeaderKey, String consumerHeaderValue,
String bundleClassPath) throws Exception {
-        Set<WeavingData> wd = ConsumerHeaderProcessor.processHeader(consumerHeaderKey,
consumerHeaderValue);
-
-        URLClassLoader cl = new URLClassLoader(new URL [] {dir.toURI().toURL()}, Main.class.getClassLoader());
-        String dirName = dir.getAbsolutePath();
-
-        DirTree dt = new DirTree(dir);
-        for (File f : dt.getFiles()) {
-            if (!f.getName().endsWith(".class"))
-                continue;
-
-            String className = f.getAbsolutePath().substring(dirName.length());
-            if (className.startsWith(File.separator))
-                className = className.substring(1);
-            className = className.substring(0, className.length() - ".class".length());
-            className = className.replace(File.separator, ".");
-
-            InputStream is = new FileInputStream(f);
-            byte[] b;
-            try {
-                ClassReader cr = new ClassReader(is);
-                ClassWriter cw = new StaticToolClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES,
cl);
-                TCCLSetterVisitor cv = new TCCLSetterVisitor(cw, className, wd);
-                cr.accept(cv, ClassReader.SKIP_FRAMES);
-                if (cv.isWoven()) {
-                    b = cw.toByteArray();
-                } else {
-                    // if not woven, store the original bytes
-                    b = Streams.suck(new FileInputStream(f));
-                }
-            } finally {
-                is.close();
-            }
-
-            OutputStream os = new FileOutputStream(f);
-            try {
-                os.write(b);
-            } finally {
-                os.close();
-            }
-        }
-
-        if (bundleClassPath != null) {
-            for (String entry : bundleClassPath.split(",")) {
-                File jarFile = new File(dir, entry.trim());
-                if (jarFile.isFile()) {
-                    weaveBCPJar(jarFile, consumerHeaderKey, consumerHeaderValue);
-                }
-            }
-        }
-    }
-
-    private static void weaveBCPJar(File jarFile, String consumerHeaderKey, String consumerHeaderVal)
throws Exception {
-        File tempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + jarFile.getName()
+ "_" + System.currentTimeMillis());
-        try {
-            Manifest manifest = unJar(jarFile, tempDir);
-            weaveDir(tempDir, consumerHeaderKey, consumerHeaderVal, null);
-            if (!jarFile.delete()) {
-                throw new IOException("Could not replace file: " + jarFile);
-            }
-
-            jar(jarFile, tempDir, manifest);
-        } finally {
-            delTree(tempDir);
-        }
-    }
-
-    static Manifest unJar(File jarFile, File tempDir) throws IOException {
-        ensureDirectory(tempDir);
-
-        JarInputStream jis = new JarInputStream(new FileInputStream(jarFile));
-        JarEntry je = null;
-        while((je = jis.getNextJarEntry()) != null) {
-            if (je.isDirectory()) {
-                File outDir = new File(tempDir, je.getName());
-                ensureDirectory(outDir);
-
-                continue;
-            }
-
-            File outFile = new File(tempDir, je.getName());
-            File outDir = outFile.getParentFile();
-            ensureDirectory(outDir);
-
-            OutputStream out = new FileOutputStream(outFile);
-            try {
-                Streams.pump(jis, out);
-            } finally {
-                out.flush();
-                out.close();
-                jis.closeEntry();
-            }
-            outFile.setLastModified(je.getTime());
-        }
-
-        Manifest manifest = jis.getManifest();
-        if (manifest != null) {
-            File mf = new File(tempDir, "META-INF/MANIFEST.MF");
-            File mfDir = mf.getParentFile();
-            ensureDirectory(mfDir);
-
-            OutputStream out = new FileOutputStream(mf);
-            try {
-                manifest.write(out);
-            } finally {
-                out.flush();
-                out.close();
-            }
-        }
-
-        jis.close();
-        return manifest;
-    }
-
-    static void jar(File jarFile, File rootFile, Manifest manifest) throws IOException {
-        JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile), manifest);
-        try {
-            addToJarRecursively(jos, rootFile.getAbsoluteFile(), rootFile.getAbsolutePath());
-        } finally {
-            jos.close();
-        }
-    }
-
-    static void addToJarRecursively(JarOutputStream jar, File source, String rootDirectory)
throws IOException {
-        String sourceName = source.getAbsolutePath().replace("\\", "/");
-        sourceName = sourceName.substring(rootDirectory.length());
-
-        if (sourceName.startsWith("/")) {
-            sourceName = sourceName.substring(1);
-        }
-
-        if ("META-INF/MANIFEST.MF".equals(sourceName))
-            return;
-
-        if (source.isDirectory()) {
-            /* Is there any point in adding a directory beyond just taking up space?
-            if (!sourceName.isEmpty()) {
-                if (!sourceName.endsWith("/")) {
-                    sourceName += "/";
-                }
-                JarEntry entry = new JarEntry(sourceName);
-                jar.putNextEntry(entry);
-                jar.closeEntry();
-            }
-            */
-            for (File nested : source.listFiles()) {
-                addToJarRecursively(jar, nested, rootDirectory);
-            }
-            return;
-        }
-
-        JarEntry entry = new JarEntry(sourceName);
-        jar.putNextEntry(entry);
-        InputStream is = new FileInputStream(source);
-        try {
-            Streams.pump(is, jar);
-        } finally {
-            jar.closeEntry();
-            is.close();
-        }
-    }
-
-    static void delTree(File tempDir) throws IOException {
-        for (File f : new DirTree(tempDir).getFiles()) {
-            if (!f.delete())
-                throw new IOException("Problem deleting file: " + tempDir.getAbsolutePath());
-        }
-    }
-
-    private static void ensureDirectory(File outDir) throws IOException {
-        if (!outDir.isDirectory())
-            if (!outDir.mkdirs())
-                throw new IOException("Unable to create directory " + outDir.getAbsolutePath());
-    }
-}
-
+/**
+ * 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.aries.spifly.statictool;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.apache.aries.spifly.ConsumerHeaderProcessor;
+import org.apache.aries.spifly.SpiFlyConstants;
+import org.apache.aries.spifly.Streams;
+import org.apache.aries.spifly.Util;
+import org.apache.aries.spifly.WeavingData;
+import org.apache.aries.spifly.weaver.TCCLSetterVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+public class Main {
+    private static final String MODIFIED_BUNDLE_SUFFIX = "_spifly.jar";
+    private static final String IMPORT_PACKAGE = "Import-Package";
+
+    public static void usage() {
+        System.err.println("This tool processes OSGi Bundles that use java.util.ServiceLoader.load()
to");
+        System.err.println("obtain implementations via META-INF/services. The byte code in
the bundles is");
+        System.err.println("modified so that the ThreadContextClassLoader is set appropriately
for the ");
+        System.err.println("duration of the java.util.ServiceLoader.load() call.");
+        System.err.println("To opt-in to this process, bundles need to have the following
MANIFEST.MF");
+        System.err.println("header set:");
+        System.err.println("    " + SpiFlyConstants.SPI_CONSUMER_HEADER + ": *");
+        System.err.println("Modified bundles are written out under the following name:");
+        System.err.println("    <original-bundle-name>" + MODIFIED_BUNDLE_SUFFIX);
+        System.err.println();
+        System.err.println("Usage: java " + Main.class.getName() + " bundle1.jar bundle2.jar
...");
+        System.exit(-1);
+    }
+
+    public static void main(String ... args) throws Exception {
+        if (args.length < 1)
+            usage();
+
+        for (String arg : args) {
+            weaveJar(arg);
+        }
+    }
+
+    private static void weaveJar(String jarPath) throws Exception {
+        System.out.println("[SPI Fly Static Tool] Processing: " + jarPath);
+
+        File jarFile = new File(jarPath);
+        File tempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + jarFile.getName()
+ "_" + System.currentTimeMillis());
+        Manifest manifest = unJar(jarFile, tempDir);
+        String consumerHeaderVal = manifest.getMainAttributes().getValue(SpiFlyConstants.SPI_CONSUMER_HEADER);
+        String consumerHeaderKey = null;
+        if (consumerHeaderVal != null) {
+            consumerHeaderKey = SpiFlyConstants.SPI_CONSUMER_HEADER;
+        } else {
+            consumerHeaderVal = manifest.getMainAttributes().getValue(SpiFlyConstants.REQUIRE_CAPABILITY);
+            if (consumerHeaderVal != null) {
+                consumerHeaderKey = SpiFlyConstants.REQUIRE_CAPABILITY;
+            }
+        }
+
+        if (consumerHeaderVal != null) {
+            String bcp = manifest.getMainAttributes().getValue(Constants.BUNDLE_CLASSPATH);
+            weaveDir(tempDir, consumerHeaderKey, consumerHeaderVal, bcp);
+
+            if (SpiFlyConstants.SPI_CONSUMER_HEADER.equals(consumerHeaderKey)) {
+                manifest.getMainAttributes().remove(new Attributes.Name(SpiFlyConstants.SPI_CONSUMER_HEADER));
+                manifest.getMainAttributes().putValue(SpiFlyConstants.PROCESSED_SPI_CONSUMER_HEADER,
consumerHeaderVal);
+            } else {
+                // It's SpiFlyConstants.REQUIRE_CAPABILITY
+
+                // Take out the processor requirement, this probably needs to be improved
a little bit
+                String newConsumerHeaderVal = consumerHeaderVal.replaceAll(
+                        "osgi[.]extender;\\s*filter[:][=][\"]?[(]osgi[.]extender[=]osgi[.]serviceloader[.]processor[)][\"]?",
"").
+                        trim();
+                if (newConsumerHeaderVal.startsWith(","))
+                    newConsumerHeaderVal = newConsumerHeaderVal.substring(1);
+
+                if (newConsumerHeaderVal.endsWith(","))
+                    newConsumerHeaderVal = newConsumerHeaderVal.substring(0, newConsumerHeaderVal.length()-1);
+                manifest.getMainAttributes().putValue(SpiFlyConstants.REQUIRE_CAPABILITY,
newConsumerHeaderVal);
+                manifest.getMainAttributes().putValue("X-SpiFly-Processed-Require-Capability",
consumerHeaderVal);
+            }
+
+            // TODO if new packages needed then...
+            extendImportPackage(manifest);
+
+            File newJar = getNewJarFile(jarFile);
+            jar(newJar, tempDir, manifest);
+        } else {
+            System.out.println("[SPI Fly Static Tool] This file is not marked as an SPI Consumer.");
+        }
+        delTree(tempDir);
+    }
+
+    private static void extendImportPackage(Manifest manifest) throws IOException {
+        String utilPkgVersion = getPackageVersion(Util.class);
+
+        Version osgiVersion = Version.parseVersion(utilPkgVersion);
+
+        Version minVersion = new Version(osgiVersion.getMajor(), osgiVersion.getMinor(),
osgiVersion.getMicro());
+        Version maxVersion = new Version(osgiVersion.getMajor(), osgiVersion.getMinor() +
1, 0);
+
+        String ip = manifest.getMainAttributes().getValue(IMPORT_PACKAGE);
+        if (ip == null)
+            ip = "";
+
+        StringBuilder sb = new StringBuilder(ip);
+        if (ip.length() > 0)
+            sb.append(",");
+        sb.append(Util.class.getPackage().getName());
+        sb.append(";version=\"[");
+        sb.append(minVersion);
+        sb.append(",");
+        sb.append(maxVersion);
+        sb.append(")\"");
+        manifest.getMainAttributes().putValue(IMPORT_PACKAGE, sb.toString());
+    }
+
+    private static String getPackageVersion(Class<?> clazz) throws IOException {
+        URL url = clazz.getResource("packageinfo");
+        if (url == null) {
+            throw new RuntimeException("'packageinfo' file with version information not found
for package: "
+                    + clazz.getPackage().getName());
+        }
+
+        byte[] bytes = Streams.suck(url.openStream());
+        Properties p = new Properties();
+        p.load(new ByteArrayInputStream(bytes));
+        return p.getProperty("version");
+    }
+
+    private static File getNewJarFile(File jarFile) {
+        String s = jarFile.getAbsolutePath();
+        int idx = s.lastIndexOf('.');
+        s = s.substring(0, idx);
+        s += MODIFIED_BUNDLE_SUFFIX;
+        return new File(s);
+    }
+
+    private static void weaveDir(File dir, String consumerHeaderKey, String consumerHeaderValue,
String bundleClassPath) throws Exception {
+        Set<WeavingData> wd = ConsumerHeaderProcessor.processHeader(consumerHeaderKey,
consumerHeaderValue);
+
+        URLClassLoader cl = new URLClassLoader(new URL [] {dir.toURI().toURL()}, Main.class.getClassLoader());
+        String dirName = dir.getAbsolutePath();
+
+        DirTree dt = new DirTree(dir);
+        for (File f : dt.getFiles()) {
+            if (!f.getName().endsWith(".class"))
+                continue;
+
+            String className = f.getAbsolutePath().substring(dirName.length());
+            if (className.startsWith(File.separator))
+                className = className.substring(1);
+            className = className.substring(0, className.length() - ".class".length());
+            className = className.replace(File.separator, ".");
+
+            InputStream is = new FileInputStream(f);
+            byte[] b;
+            try {
+                ClassReader cr = new ClassReader(is);
+                ClassWriter cw = new StaticToolClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES,
cl);
+                TCCLSetterVisitor cv = new TCCLSetterVisitor(cw, className, wd);
+                cr.accept(cv, ClassReader.SKIP_FRAMES);
+                if (cv.isWoven()) {
+                    b = cw.toByteArray();
+                } else {
+                    // if not woven, store the original bytes
+                    b = Streams.suck(new FileInputStream(f));
+                }
+            } finally {
+                is.close();
+            }
+
+            OutputStream os = new FileOutputStream(f);
+            try {
+                os.write(b);
+            } finally {
+                os.close();
+            }
+        }
+
+        if (bundleClassPath != null) {
+            for (String entry : bundleClassPath.split(",")) {
+                File jarFile = new File(dir, entry.trim());
+                if (jarFile.isFile()) {
+                    weaveBCPJar(jarFile, consumerHeaderKey, consumerHeaderValue);
+                }
+            }
+        }
+    }
+
+    private static void weaveBCPJar(File jarFile, String consumerHeaderKey, String consumerHeaderVal)
throws Exception {
+        File tempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + jarFile.getName()
+ "_" + System.currentTimeMillis());
+        try {
+            Manifest manifest = unJar(jarFile, tempDir);
+            weaveDir(tempDir, consumerHeaderKey, consumerHeaderVal, null);
+            if (!jarFile.delete()) {
+                throw new IOException("Could not replace file: " + jarFile);
+            }
+
+            jar(jarFile, tempDir, manifest);
+        } finally {
+            delTree(tempDir);
+        }
+    }
+
+    static Manifest unJar(File jarFile, File tempDir) throws IOException {
+        ensureDirectory(tempDir);
+
+        JarInputStream jis = new JarInputStream(new FileInputStream(jarFile));
+        JarEntry je = null;
+        while((je = jis.getNextJarEntry()) != null) {
+            if (je.isDirectory()) {
+                File outDir = new File(tempDir, je.getName());
+                ensureDirectory(outDir);
+
+                continue;
+            }
+
+            File outFile = new File(tempDir, je.getName());
+            File outDir = outFile.getParentFile();
+            ensureDirectory(outDir);
+
+            OutputStream out = new FileOutputStream(outFile);
+            try {
+                Streams.pump(jis, out);
+            } finally {
+                out.flush();
+                out.close();
+                jis.closeEntry();
+            }
+            outFile.setLastModified(je.getTime());
+        }
+
+        Manifest manifest = jis.getManifest();
+        if (manifest != null) {
+            File mf = new File(tempDir, "META-INF/MANIFEST.MF");
+            File mfDir = mf.getParentFile();
+            ensureDirectory(mfDir);
+
+            OutputStream out = new FileOutputStream(mf);
+            try {
+                manifest.write(out);
+            } finally {
+                out.flush();
+                out.close();
+            }
+        }
+
+        jis.close();
+        return manifest;
+    }
+
+    static void jar(File jarFile, File rootFile, Manifest manifest) throws IOException {
+        JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile), manifest);
+        try {
+            addToJarRecursively(jos, rootFile.getAbsoluteFile(), rootFile.getAbsolutePath());
+        } finally {
+            jos.close();
+        }
+    }
+
+    static void addToJarRecursively(JarOutputStream jar, File source, String rootDirectory)
throws IOException {
+        String sourceName = source.getAbsolutePath().replace("\\", "/");
+        sourceName = sourceName.substring(rootDirectory.length());
+
+        if (sourceName.startsWith("/")) {
+            sourceName = sourceName.substring(1);
+        }
+
+        if ("META-INF/MANIFEST.MF".equals(sourceName))
+            return;
+
+        if (source.isDirectory()) {
+            /* Is there any point in adding a directory beyond just taking up space?
+            if (!sourceName.isEmpty()) {
+                if (!sourceName.endsWith("/")) {
+                    sourceName += "/";
+                }
+                JarEntry entry = new JarEntry(sourceName);
+                jar.putNextEntry(entry);
+                jar.closeEntry();
+            }
+            */
+            for (File nested : source.listFiles()) {
+                addToJarRecursively(jar, nested, rootDirectory);
+            }
+            return;
+        }
+
+        JarEntry entry = new JarEntry(sourceName);
+        jar.putNextEntry(entry);
+        InputStream is = new FileInputStream(source);
+        try {
+            Streams.pump(is, jar);
+        } finally {
+            jar.closeEntry();
+            is.close();
+        }
+    }
+
+    static void delTree(File tempDir) throws IOException {
+        for (File f : new DirTree(tempDir).getFiles()) {
+            if (!f.delete())
+                throw new IOException("Problem deleting file: " + tempDir.getAbsolutePath());
+        }
+    }
+
+    private static void ensureDirectory(File outDir) throws IOException {
+        if (!outDir.isDirectory())
+            if (!outDir.mkdirs())
+                throw new IOException("Unable to create directory " + outDir.getAbsolutePath());
+    }
+}
+



Mime
View raw message