SlingInstallerSupportImpl.java 8.32 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.annotation.Nonnull
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Deactivate
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.jackrabbit.commons.JcrUtils
 *  org.apache.jackrabbit.util.Text
 *  org.apache.sling.jcr.api.SlingRepository
 *  org.apache.sling.settings.SlingSettingsService
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.crx.packaging.impl;

import com.day.crx.packaging.impl.SlingInstallerSupport;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.settings.SlingSettingsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(immediate=1)
@Service
public class SlingInstallerSupportImpl
implements SlingInstallerSupport {
    private static final Logger log = LoggerFactory.getLogger(SlingInstallerSupportImpl.class);
    private static final String SLING_JCR_INSTALLER_ROOT = "/system/sling/installer/jcr/pauseInstallation";
    private static final String SLING_INSTALLER_SERVICE = "slingInstallerService";
    private static final String SERVICE_NAME = SlingInstallerSupportImpl.class.getName();
    private static final String SLING_FOLDER = "sling:Folder";
    @Reference
    private SlingSettingsService slingSettings;
    @Reference
    private SlingRepository repository;
    private String instanceMarkerRootPath;

    @Activate
    private void activate() {
        String instanceName = Text.escapeIllegalJcrChars((String)this.slingSettings.getSlingId());
        this.instanceMarkerRootPath = "/system/sling/installer/jcr/pauseInstallation/" + instanceName;
        this.cleanupOrphanedMarkers();
    }

    @Deactivate
    private void deactivate() {
        this.instanceMarkerRootPath = null;
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @Nonnull
    @Override
    public SlingInstallerSupport.Handle pause() {
        if (this.instanceMarkerRootPath == null) {
            return INSTANCE;
        }
        Session session = null;
        try {
            session = this.login();
            Node root = this.getOrCreateInstanceNode(session);
            Node serviceNode = JcrUtils.getOrAddNode((Node)root, (String)SERVICE_NAME, (String)"sling:Folder");
            Node marker = serviceNode.addNode(UUID.randomUUID().toString(), "sling:Folder");
            marker.addMixin("mix:created");
            String path = marker.getPath();
            session.save();
            log.info("Sling installer node {} created.", (Object)path);
            HandleImpl handleImpl = new HandleImpl(path);
            return handleImpl;
        }
        catch (RepositoryException e) {
            log.error("Unable to pause operation.", (Throwable)e);
            SlingInstallerSupport.Handle serviceNode = INSTANCE;
            return serviceNode;
        }
        finally {
            if (session != null) {
                session.logout();
            }
        }
    }

    private Session login() throws RepositoryException {
        return this.repository.loginService("slingInstallerService", null);
    }

    private Node getOrCreateInstanceNode(Session session) throws RepositoryException {
        Node parent = session.getNode("/system/sling/installer/jcr/pauseInstallation");
        return JcrUtils.getOrAddNode((Node)parent, (String)Text.getName((String)this.instanceMarkerRootPath), (String)"sling:Folder");
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    private void cleanupOrphanedMarkers() {
        Session session = null;
        try {
            session = this.login();
            if (session.nodeExists(this.instanceMarkerRootPath)) {
                Node root = session.getNode(this.instanceMarkerRootPath);
                if (root.hasNode(SERVICE_NAME)) {
                    Node serviceNode = root.getNode(SERVICE_NAME);
                    NodeIterator children = serviceNode.getNodes();
                    while (children.hasNext()) {
                        Node child = children.nextNode();
                        log.warn("Cleaning up orphaned Sling installer node {}.", (Object)child.getPath());
                    }
                    serviceNode.remove();
                }
                if (!root.getNodes().hasNext()) {
                    root.remove();
                }
                session.save();
            }
            if (log.isInfoEnabled() && session.nodeExists("/system/sling/installer/jcr/pauseInstallation")) {
                Node installerRoot = session.getNode("/system/sling/installer/jcr/pauseInstallation");
                NodeIterator remainingBlockingNodes = installerRoot.getNodes();
                while (remainingBlockingNodes.hasNext()) {
                    Node blocking = remainingBlockingNodes.nextNode();
                    log.info("After orphan cleanup the installer is still blocked by Sling ID '{}'", (Object)blocking.getName());
                }
            }
        }
        catch (RepositoryException e) {
            log.error("Unable to clean up orphaned markers.", (Throwable)e);
        }
        finally {
            if (session != null) {
                session.logout();
            }
        }
    }

    protected void bindSlingSettings(SlingSettingsService slingSettingsService) {
        this.slingSettings = slingSettingsService;
    }

    protected void unbindSlingSettings(SlingSettingsService slingSettingsService) {
        if (this.slingSettings == slingSettingsService) {
            this.slingSettings = null;
        }
    }

    protected void bindRepository(SlingRepository slingRepository) {
        this.repository = slingRepository;
    }

    protected void unbindRepository(SlingRepository slingRepository) {
        if (this.repository == slingRepository) {
            this.repository = null;
        }
    }

    private static class EmptyHandle
    implements SlingInstallerSupport.Handle {
        private static SlingInstallerSupport.Handle INSTANCE = new EmptyHandle();

        private EmptyHandle() {
        }

        @Override
        public void release() {
        }
    }

    private class HandleImpl
    implements SlingInstallerSupport.Handle {
        private final String path;

        public HandleImpl(String path) {
            this.path = path;
        }

        /*
         * WARNING - Removed try catching itself - possible behaviour change.
         */
        @Override
        public void release() {
            Session session = null;
            try {
                session = SlingInstallerSupportImpl.this.login();
                Node marker = session.getNode(this.path);
                Node parent = marker.getParent();
                marker.remove();
                while (!parent.getPath().equals("/system/sling/installer/jcr/pauseInstallation") && !parent.getNodes().hasNext()) {
                    Node toRemove = parent;
                    parent = parent.getParent();
                    log.debug("Sling installer parent node {} removed.", (Object)toRemove.getPath());
                    toRemove.remove();
                }
                session.save();
                log.info("Sling installer node {} removed.", (Object)this.path);
            }
            catch (Throwable t) {
                log.error("Failed to unpause JCR installer, please manually delete the node {}", (Object)this.path, (Object)t);
                if (t instanceof RuntimeException) {
                    throw (RuntimeException)t;
                }
            }
            finally {
                if (session != null) {
                    session.logout();
                }
            }
        }
    }

}