RolloutContextImpl.java 14.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.Filter
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.WCMException
 *  com.day.cq.wcm.msm.api.LiveCopy
 *  com.day.cq.wcm.msm.api.LiveRelationship
 *  com.day.cq.wcm.msm.api.LiveRelationshipManager
 *  com.day.cq.wcm.msm.api.LiveStatus
 *  com.day.cq.wcm.msm.api.RolloutConfig
 *  com.day.cq.wcm.msm.api.RolloutExceptionHandler
 *  com.day.cq.wcm.msm.api.RolloutExceptionHandler$RolloutInfo
 *  com.day.cq.wcm.msm.api.RolloutManager
 *  com.day.cq.wcm.msm.api.RolloutManager$RolloutProgress
 *  com.day.cq.wcm.msm.api.RolloutManager$Trigger
 *  com.day.text.Text
 *  javax.jcr.RangeIterator
 *  org.apache.commons.collections.CollectionUtils
 *  org.apache.sling.api.resource.NonExistingResource
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 */
package com.day.cq.wcm.msm.impl;

import com.day.cq.commons.Filter;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.WCMException;
import com.day.cq.wcm.msm.api.LiveCopy;
import com.day.cq.wcm.msm.api.LiveRelationship;
import com.day.cq.wcm.msm.api.LiveRelationshipManager;
import com.day.cq.wcm.msm.api.LiveStatus;
import com.day.cq.wcm.msm.api.RolloutConfig;
import com.day.cq.wcm.msm.api.RolloutExceptionHandler;
import com.day.cq.wcm.msm.api.RolloutManager;
import com.day.cq.wcm.msm.impl.LiveCopyManagerImpl;
import com.day.text.Text;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.jcr.RangeIterator;
import org.apache.commons.collections.CollectionUtils;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;

public class RolloutContextImpl {
    private static final RolloutManager.Trigger[] TRIGGER_SEARCH_ORDER = new RolloutManager.Trigger[]{RolloutManager.Trigger.ROLLOUT, RolloutManager.Trigger.MODIFICATION, RolloutManager.Trigger.PUBLICATION, RolloutManager.Trigger.DEACTIVATION};
    private final boolean isReset;
    private final RolloutManager.RolloutProgress progress;
    private final LiveRelationship relationship;
    private final ResourceResolver resourceResolver;
    private final RolloutManager.Trigger trigger;
    private final HashMap<String, RolloutContextImpl> configChanges = new HashMap();
    private Resource source;
    private Resource target;
    private List<RolloutConfig> allConfigs;
    private int currentConfigIdx = -1;
    private HashSet<RolloutContextImpl> nameConflicts = new HashSet();
    private ArrayList<RolloutContextImpl> children = null;
    private RolloutContextImpl parent;
    private boolean isDeep;
    private boolean forceUpdate;

    RolloutContextImpl(ResourceResolver resourceResolver, RolloutManager.Trigger trigger, boolean isDeep, boolean isReset, LiveRelationship liveRelationship, RolloutManager.RolloutProgress rolloutProgress) {
        this.resourceResolver = resourceResolver;
        this.trigger = trigger;
        this.isDeep = isDeep;
        this.isReset = isReset;
        this.relationship = liveRelationship;
        this.progress = rolloutProgress;
        this.source = resourceResolver.getResource(this.relationship.getSourcePath());
    }

    private RolloutContextImpl(RolloutContextImpl parent, LiveRelationship liveRelationship, Resource targetResource) {
        this(parent.resourceResolver, parent.trigger, parent.isDeep, parent.isReset, liveRelationship, parent.progress);
        this.parent = parent;
        this.target = targetResource;
    }

    public boolean isDeep() {
        return this.isDeep;
    }

    public boolean isReset() {
        return this.isReset;
    }

    public RolloutManager.Trigger getTrigger() {
        return this.trigger;
    }

    public void reportProgress(String oppertation) {
        if (this.relationship == null) {
            throw new IllegalStateException("Only report Progress on Relationship");
        }
        this.reportProgress(this.relationship.getTargetPath(), oppertation);
    }

    public void reportProgress(String path, String opperation) {
        this.progress.reportProgress(path, opperation);
    }

    public void setSource(Resource source) {
        this.source = source;
    }

    public void loadTarget() {
        if (this.relationship != null) {
            this.target = this.resourceResolver.getResource(this.relationship.getTargetPath());
        }
    }

    public RolloutContextImpl forRelationship(LiveRelationship relation) {
        return this.forRelationship(relation, false);
    }

    public RolloutContextImpl forRelationship(LiveRelationship relation, boolean reset) {
        RolloutContextImpl relContext = new RolloutContextImpl(this.resourceResolver, this.trigger, this.isDeep, this.isReset, relation, this.progress);
        relContext.currentConfigIdx = reset ? -1 : this.currentConfigIdx;
        relContext.nameConflicts = this.nameConflicts;
        relContext.parent = this.parent;
        relContext.loadTarget();
        return relContext;
    }

    public LiveRelationship getRelationship() {
        return this.relationship;
    }

    public Resource getSource() {
        return this.getSource(false);
    }

    public Resource getSource(boolean forced) {
        if (this.source == null && this.relationship == null) {
            throw new IllegalStateException("Source Resource only available if Relationship is set");
        }
        return this.source == null && forced ? new NonExistingResource(this.resourceResolver, this.relationship.getSourcePath()) : this.source;
    }

    public Resource getTarget() {
        if (this.relationship == null) {
            throw new IllegalStateException("Target Resource only available if Relationship is set");
        }
        return this.target;
    }

    public ResourceResolver getResourceResolver() {
        return this.resourceResolver;
    }

    public RolloutConfig getCurrentRolloutConfig() {
        RolloutConfig result = null;
        if (this.parent == null) {
            List<RolloutConfig> all = this.getRolloutConfigs();
            if (all != null) {
                result = this.currentConfigIdx == -1 && this.hasNextRolloutConfig() ? this.getNextRolloutConfig() : all.get(this.currentConfigIdx);
            }
        } else {
            result = this.parent.getCurrentRolloutConfig();
        }
        return result;
    }

    public boolean hasNextRolloutConfig() {
        return this.relationship != null && this.getRolloutConfigs() != null && this.currentConfigIdx < this.getRolloutConfigs().size() - 1;
    }

    public RolloutContextImpl nextRolloutConfig() {
        if (this.parent == null) {
            if (!this.hasNextRolloutConfig()) {
                throw new IllegalStateException("Call has next first");
            }
            ++this.currentConfigIdx;
        } else {
            this.parent.getNextRolloutConfig();
        }
        return this;
    }

    private List<RolloutConfig> getRolloutConfigs() {
        if (this.allConfigs == null) {
            if (this.trigger == null) {
                for (int i = 0; this.allConfigs == null && i < TRIGGER_SEARCH_ORDER.length; ++i) {
                    List check = this.relationship.getRolloutConfigs(TRIGGER_SEARCH_ORDER[i]);
                    if (check.isEmpty()) continue;
                    this.allConfigs = check;
                }
            } else {
                this.allConfigs = this.relationship.getRolloutConfigs(this.trigger);
            }
        }
        return this.allConfigs;
    }

    public void setDeep(boolean deep) {
        this.isDeep = deep;
    }

    public void setForceUpdate(boolean force) {
        this.forceUpdate = force;
    }

    public boolean isForceUpdate() {
        if (this.parent == null) {
            return this.forceUpdate || this.isReset() || this.getSource() == null || this.isMoved();
        }
        return this.parent.isForceUpdate();
    }

    public RolloutExceptionHandler.RolloutInfo getRolloutInfo() {
        return new RolloutExceptionHandler.RolloutInfo(){};
    }

    public void addNameConflict(RolloutContextImpl conflictingContet) {
        if (this.parent == null) {
            this.nameConflicts.add(conflictingContet);
        } else {
            this.parent.addNameConflict(conflictingContet);
        }
    }

    public Set<RolloutContextImpl> getAllNameConflicts() {
        return this.parent == null ? Collections.unmodifiableSet(this.nameConflicts) : this.parent.getAllNameConflicts();
    }

    public boolean hasNameConflicts() {
        return this.parent == null ? !this.nameConflicts.isEmpty() : this.parent.hasNameConflicts();
    }

    public boolean hasChangesToRollout() {
        boolean hasChanges;
        LiveStatus status = this.relationship.getStatus();
        if (status.getLastRolledOut() == null) {
            hasChanges = true;
        } else if (status.isPage()) {
            if (this.getTarget() == null && status.isTargetExisting()) {
                this.loadTarget();
            }
            Resource source = this.getSource(false);
            Resource target = this.getTarget();
            if (source == null || target == null) {
                hasChanges = true;
            } else {
                Calendar targetMod;
                Calendar now = Calendar.getInstance();
                Calendar sourceMod = (Calendar)((ValueMap)source.adaptTo(ValueMap.class)).get("cq:lastModified", (Object)now);
                Calendar youngest = sourceMod.before(targetMod = (Calendar)((ValueMap)target.adaptTo(ValueMap.class)).get("cq:lastModified", (Object)now)) ? targetMod : sourceMod;
                hasChanges = status.getLastRolledOut().before(youngest.getTime());
            }
        } else {
            hasChanges = true;
        }
        return hasChanges;
    }

    public Iterator<RolloutContextImpl> getChildren(LiveRelationshipManager relManager) throws WCMException {
        if (this.children == null) {
            ArrayList<RolloutContextImpl> children = new ArrayList<RolloutContextImpl>();
            PageManager pageManager = (PageManager)this.getResourceResolver().adaptTo(PageManager.class);
            Page page = this.getSource() == null ? null : (Page)this.getSource().getParent().adaptTo(Page.class);
            String targetPath = this.getRelationship().getTargetPath();
            Page slave = pageManager.getContainingPage(targetPath);
            if (slave != null) {
                Filter<Page> filter = null;
                if (page != null) {
                    Iterator sourceChildren = page.listChildren();
                    while (sourceChildren.hasNext()) {
                        RangeIterator ships = relManager.getLiveRelationships(((Page)sourceChildren.next()).getContentResource(), slave.getPath(), this.getTrigger());
                        while (ships.hasNext()) {
                            LiveRelationship ship = (LiveRelationship)ships.next();
                            if (ship.getStatus().isCancelled()) continue;
                            if (this.isSame(ship)) {
                                Resource targetResource = this.resourceResolver.getResource(ship.getTargetPath());
                                children.add(new RolloutContextImpl(this, ship, targetResource));
                                continue;
                            }
                            if (!this.contains(ship)) continue;
                            this.configChanges.put(ship.getTargetPath(), this.forRelationship(ship, true));
                        }
                    }
                    final Resource pageResource = (Resource)page.adaptTo(Resource.class);
                    filter = new Filter<Page>(){

                        public boolean includes(Page element) {
                            return pageResource.getChild(element.getName()) == null;
                        }
                    };
                }
                Iterator targetChildren = slave.listChildren((Filter)filter);
                while (targetChildren.hasNext()) {
                    Page child = (Page)targetChildren.next();
                    LiveRelationship childRelation = relManager.getLiveRelationship(child.getContentResource(), true);
                    if (childRelation == null || childRelation.getStatus().isCancelled()) continue;
                    if (this.isSame(childRelation)) {
                        children.add(new RolloutContextImpl(this, childRelation, child.getContentResource()));
                        continue;
                    }
                    if (!this.contains(childRelation)) continue;
                    this.configChanges.put(childRelation.getTargetPath(), this.forRelationship(childRelation, true));
                }
            }
            this.children = children;
        }
        return this.children.listIterator();
    }

    public Map<String, RolloutContextImpl> getConfigChanges() {
        TreeMap<String, RolloutContextImpl> all = new TreeMap<String, RolloutContextImpl>();
        all.putAll(this.configChanges);
        if (this.children != null) {
            for (RolloutContextImpl child : this.children) {
                all.putAll(child.getConfigChanges());
            }
        }
        return all;
    }

    boolean isSame(LiveRelationship other) {
        String otherBlueprint = other.getLiveCopy().getBlueprintPath();
        return otherBlueprint.equals(this.getRelationship().getLiveCopy().getBlueprintPath()) && CollectionUtils.isEqualCollection((Collection)other.getRolloutConfigs(), this.getRolloutConfigs());
    }

    boolean contains(LiveRelationship other) {
        LiveCopyManagerImpl.LiveCopyImpl liveCopy = (LiveCopyManagerImpl.LiveCopyImpl)this.getRelationship().getLiveCopy();
        boolean parent = Text.getRelativeParent((String)other.getLiveCopy().getPath(), (int)1).equals(liveCopy.getPath());
        return parent || Text.isDescendantOrEqual((String)liveCopy.getBlueprintPath(), (String)other.getSourcePath()) && liveCopy.contains(other.getTargetPath());
    }

    boolean isMoved() {
        return this.getRelationship().getLiveCopy() instanceof LiveCopyManagerImpl.LiveCopyImpl && ((LiveCopyManagerImpl.LiveCopyImpl)this.getRelationship().getLiveCopy()).isMoved();
    }

    private RolloutConfig getNextRolloutConfig() {
        return this.getRolloutConfigs().get(++this.currentConfigIdx);
    }

}