InternalClassLoaderWrapper.java 4.55 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.osgi.framework.Bundle
 *  org.osgi.framework.BundleContext
 */
package com.adobe.granite.crypto.internal;

import com.adobe.granite.crypto.internal.Activator;
import com.adobe.granite.crypto.internal.ProxyClassLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

public final class InternalClassLoaderWrapper {
    private static final String JAR_FILE_PATTERN = "*.jar";
    private static final String JAR_FILE_BUNDLE_PATH = "META-INF/lib";
    private static final String JAR_FILE_TARGET = "lib";
    private static volatile InternalClassLoaderWrapper instance;
    private final BundleContext bundleContext;
    private final ClassLoader classLoader;

    private InternalClassLoaderWrapper(BundleContext bundleContext) throws IOException {
        this.bundleContext = bundleContext;
        this.classLoader = this.createClassLoader();
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     * Enabled force condition propagation
     * Lifted jumps to return sites
     */
    protected static void init(BundleContext bundleContext) throws IOException {
        if (instance != null) return;
        Class<InternalClassLoaderWrapper> class_ = InternalClassLoaderWrapper.class;
        synchronized (InternalClassLoaderWrapper.class) {
            if (instance != null) return;
            {
                instance = new InternalClassLoaderWrapper(bundleContext);
            }
            // ** MonitorExit[var1_1] (shouldn't be in output)
            return;
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public static InternalClassLoaderWrapper getInstance() {
        Class<InternalClassLoaderWrapper> class_ = InternalClassLoaderWrapper.class;
        synchronized (InternalClassLoaderWrapper.class) {
            if (instance == null) {
                throw new IllegalStateException(InternalClassLoaderWrapper.class.getName() + " was not properly instantiated. The initial" + " " + "setup must " + "be performed through the " + Activator.class.getName() + " class.");
            }
            // ** MonitorExit[var0] (shouldn't be in output)
            return instance;
        }
    }

    private static URL copy(URL src, File target, long bundleLastModified) throws IOException {
        File targetFile = new File(target, InternalClassLoaderWrapper.toName(src, bundleLastModified));
        if (!targetFile.exists()) {
            int rd;
            FileOutputStream dstStream = new FileOutputStream(targetFile);
            InputStream srcStream = src.openStream();
            byte[] buf = new byte[8192];
            while ((rd = srcStream.read(buf)) > 0) {
                dstStream.write(buf, 0, rd);
            }
            srcStream.close();
            dstStream.close();
        }
        return targetFile.toURI().toURL();
    }

    private static String toName(URL url, long bundleLastModified) {
        String path = url.getPath();
        int lastSlash = path.lastIndexOf(47);
        String name = lastSlash < 0 ? path : path.substring(lastSlash);
        return name + "." + bundleLastModified + ".jar";
    }

    public ClassLoader getClassLoader() {
        return this.classLoader;
    }

    private ClassLoader createClassLoader() throws IOException {
        File target = this.bundleContext.getDataFile("lib");
        target.mkdirs();
        long bundleLastModified = this.bundleContext.getBundle().getLastModified();
        Enumeration entries = this.bundleContext.getBundle().findEntries("META-INF/lib", "*.jar", false);
        ArrayList<URL> classPathUrls = new ArrayList<URL>();
        if (entries != null) {
            while (entries.hasMoreElements()) {
                URL url = (URL)entries.nextElement();
                url = InternalClassLoaderWrapper.copy(url, target, bundleLastModified);
                String decodedURL = url.getProtocol() + ":" + URLDecoder.decode(url.getPath(), "UTF-8");
                URL classPathUrl = new URL(decodedURL);
                classPathUrls.add(classPathUrl);
            }
        }
        URL[] urls = classPathUrls.toArray(new URL[classPathUrls.size()]);
        return new URLClassLoader(urls, new ProxyClassLoader(this.getClass().getClassLoader()));
    }
}