JrVltInstallHookProcessor.java 10.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.commons.io.FileUtils
 *  org.apache.commons.io.IOUtils
 *  org.apache.jackrabbit.vault.fs.api.VaultInputSource
 *  org.apache.jackrabbit.vault.fs.config.MetaInf
 *  org.apache.jackrabbit.vault.fs.io.Archive
 *  org.apache.jackrabbit.vault.fs.io.Archive$Entry
 *  org.apache.jackrabbit.vault.packaging.InstallContext
 *  org.apache.jackrabbit.vault.packaging.InstallHook
 *  org.apache.jackrabbit.vault.packaging.InstallHookProcessor
 *  org.apache.jackrabbit.vault.packaging.PackageException
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.jcr.vault.packaging.impl;

import com.day.jcr.vault.packaging.InstallContext;
import com.day.jcr.vault.packaging.InstallHook;
import com.day.jcr.vault.packaging.PackageException;
import com.day.jcr.vault.packaging.impl.JrVltInstallContextAdapter;
import com.day.jcr.vault.packaging.impl.JrVltInstallHookAdapter;
import com.day.jcr.vault.util.Text;
import java.io.File;
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.Collection;
import java.util.Enumeration;
import java.util.Properties;
import java.util.TreeMap;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.vault.fs.api.VaultInputSource;
import org.apache.jackrabbit.vault.fs.config.MetaInf;
import org.apache.jackrabbit.vault.fs.io.Archive;
import org.apache.jackrabbit.vault.packaging.InstallHookProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JrVltInstallHookProcessor
implements InstallHookProcessor {
    private static final Logger log = LoggerFactory.getLogger(JrVltInstallHookProcessor.class);
    private final TreeMap<String, Hook> hooks = new TreeMap();

    public void registerHooks(Archive archive, ClassLoader classLoader) throws org.apache.jackrabbit.vault.packaging.PackageException {
        try {
            Archive.Entry root = archive.getRoot();
            root = root.getChild("META-INF");
            if (root == null) {
                log.warn("Archive {} does not have a {} directory.", (Object)archive, (Object)"META-INF");
                return;
            }
            if ((root = root.getChild("vault")) == null) {
                log.warn("Archive {} does not have a {} directory.", (Object)archive, (Object)"vault");
                return;
            }
            if ((root = root.getChild("hooks")) == null) {
                log.debug("Archive {} does not have a {} directory.", (Object)archive, (Object)"hooks");
            } else {
                for (Archive.Entry entry : root.getChildren()) {
                    if (!entry.getName().endsWith(".jar")) continue;
                    this.registerHook(archive.getInputSource(entry), classLoader);
                }
            }
            Properties props = archive.getMetaInf().getProperties();
            if (props != null) {
                Enumeration names = props.propertyNames();
                while (names.hasMoreElements()) {
                    String name = names.nextElement().toString();
                    if (!name.startsWith("installhook.")) continue;
                    String[] segs = Text.explode(name.substring("installhook.".length()), 46);
                    if (segs.length == 0 || segs.length > 2 || !segs[1].equals("class")) {
                        throw new org.apache.jackrabbit.vault.packaging.PackageException("Invalid installhook property: " + name);
                    }
                    Hook hook = new Hook(this, segs[0], props.getProperty(name), classLoader);
                    this.initHook(hook);
                }
            }
        }
        catch (IOException e) {
            throw new org.apache.jackrabbit.vault.packaging.PackageException("I/O Error while registering hooks", (Throwable)e);
        }
    }

    public void registerHook(VaultInputSource input, ClassLoader classLoader) throws IOException, org.apache.jackrabbit.vault.packaging.PackageException {
        File jarFile = File.createTempFile("vaulthook", ".jar");
        Hook hook = new Hook(this, input.getSystemId(), jarFile, classLoader);
        FileOutputStream out = null;
        InputStream in = input.getByteStream();
        try {
            out = FileUtils.openOutputStream((File)jarFile);
            IOUtils.copy((InputStream)in, (OutputStream)out);
        }
        catch (IOException e) {
            hook.destroy();
            throw e;
        }
        finally {
            IOUtils.closeQuietly((InputStream)in);
            IOUtils.closeQuietly((OutputStream)out);
        }
        this.initHook(hook);
    }

    private void initHook(Hook hook) throws IOException, org.apache.jackrabbit.vault.packaging.PackageException {
        try {
            hook.init();
        }
        catch (IOException e) {
            log.error("Error while initializing hook: {}", (Object)e.toString());
            hook.destroy();
            throw e;
        }
        catch (PackageException e) {
            log.error("Error while initializing hook: {}", (Object)e.toString());
            hook.destroy();
            throw new org.apache.jackrabbit.vault.packaging.PackageException((Throwable)e);
        }
        this.hooks.put(hook.name, hook);
        log.info("Hook {} registered.", (Object)hook.name);
    }

    public boolean hasHooks() {
        return !this.hooks.isEmpty();
    }

    public boolean execute(org.apache.jackrabbit.vault.packaging.InstallContext context) {
        InstallContext ctx = JrVltInstallContextAdapter.create(context);
        for (Hook hook : this.hooks.values()) {
            try {
                hook.getHook().execute(ctx);
            }
            catch (PackageException e) {
                if (ctx.getPhase() == InstallContext.Phase.PREPARE) {
                    log.warn("Hook " + hook.name + " threw package exception. Prepare aborted.", (Throwable)e);
                    return false;
                }
                log.warn("Hook " + hook.name + " threw package exception. Ignored", (Throwable)e);
            }
            catch (Throwable e) {
                log.warn("Hook " + hook.name + " threw runtime exception.", e);
            }
            if (ctx.getPhase() != InstallContext.Phase.END) continue;
            hook.destroy();
        }
        return true;
    }

    private class Hook {
        private final String name;
        private final File jarFile;
        private ClassLoader classLoader;
        private ClassLoader parentClassLoader;
        private InstallHook hook;
        private String mainClassName;
        final /* synthetic */ JrVltInstallHookProcessor this$0;

        private Hook(JrVltInstallHookProcessor jrVltInstallHookProcessor, String name, String mainClassName, ClassLoader parentClassLoader) {
            this.this$0 = jrVltInstallHookProcessor;
            this.name = name;
            this.mainClassName = mainClassName;
            this.parentClassLoader = parentClassLoader;
            this.jarFile = null;
        }

        private Hook(JrVltInstallHookProcessor jrVltInstallHookProcessor, String name, File jarFile, ClassLoader parentClassLoader) {
            this.this$0 = jrVltInstallHookProcessor;
            this.name = name;
            this.jarFile = jarFile;
            this.parentClassLoader = parentClassLoader;
        }

        private void destroy() {
            this.parentClassLoader = null;
            this.classLoader = null;
            this.hook = null;
            if (this.jarFile != null) {
                FileUtils.deleteQuietly((File)this.jarFile);
            }
        }

        private void init() throws IOException, PackageException {
            if (this.parentClassLoader == null) {
                this.parentClassLoader = Thread.currentThread().getContextClassLoader();
            }
            if (this.jarFile != null) {
                JarFile jar = new JarFile(this.jarFile);
                Manifest mf = jar.getManifest();
                if (mf == null) {
                    throw new PackageException("hook jar file does not have a manifest: " + this.name);
                }
                this.mainClassName = mf.getMainAttributes().getValue("Main-Class");
                if (this.mainClassName == null) {
                    throw new PackageException("hook manifest file does not have a Main-Class entry: " + this.name);
                }
                this.classLoader = URLClassLoader.newInstance(new URL[]{this.jarFile.toURL()}, this.parentClassLoader);
            } else {
                this.classLoader = this.parentClassLoader;
            }
            this.loadMainClass();
        }

        private void loadMainClass() throws PackageException {
            block7 : {
                Class clazz;
                log.info("Loading Hook {}: Main-Class = {}", (Object)this.name, (Object)this.mainClassName);
                try {
                    clazz = this.classLoader.loadClass(this.mainClassName);
                }
                catch (ClassNotFoundException e) {
                    throw new PackageException("hook's main class " + this.mainClassName + " not found: " + this.name, e);
                }
                try {
                    if (InstallHook.class.isAssignableFrom(clazz)) {
                        this.hook = (InstallHook)clazz.newInstance();
                        log.warn("com.day.jcr.vault.* is deprecated since vault 2.5.0 (CQ 6.0.0). Use the org.apache.jackrabbit.vault API instead.");
                        break block7;
                    }
                    if (org.apache.jackrabbit.vault.packaging.InstallHook.class.isAssignableFrom(clazz)) {
                        this.hook = JrVltInstallHookAdapter.create((org.apache.jackrabbit.vault.packaging.InstallHook)clazz.newInstance());
                        break block7;
                    }
                    throw new PackageException("hook's main class " + this.mainClassName + " does not implement the InstallHook interface: " + this.name);
                }
                catch (InstantiationException e) {
                    throw new PackageException("hook's main class " + this.mainClassName + " could not be instantiated.", e);
                }
                catch (IllegalAccessException e) {
                    throw new PackageException("hook's main class " + this.mainClassName + " could not be instantiated.", e);
                }
            }
        }

        public InstallHook getHook() {
            return this.hook;
        }
    }

}