All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.wcm.designimporter.CanvasReferenceProvider Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * ___________________
 *
 *  Copyright 2012 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.day.cq.wcm.designimporter;

import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.designer.Designer;
import com.day.cq.wcm.api.reference.Reference;
import com.day.cq.wcm.api.reference.ReferenceProvider;
import com.day.cq.wcm.api.WCMException;
import com.day.cq.wcm.designimporter.util.ImporterUtil;
import com.day.cq.wcm.msm.api.LiveRelationship;
import com.day.cq.wcm.msm.api.LiveRelationshipManager;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.RepositoryException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

@Component
@Service
/**
 * Provides references for a canvas generated under the importer component.
 */
public class CanvasReferenceProvider implements ReferenceProvider {

    /**
     * default logger
     */
    private static final Logger logger = LoggerFactory.getLogger(CanvasReferenceProvider.class);

    private static final String CQ_CLIENT_LIBRARY_FOLDER = "cq:ClientLibraryFolder";

    private static final String NN_CANVAS = "canvas";

    private static final String PN_REIMPORT = "reimport";

    public List findReferences(Resource resource) {

        List references = new ArrayList();
        if (resource == null) {
            return references;
        }

        List foundComponents = new LinkedList();
        Set checkedPaths = new LinkedHashSet();

        findImporterComponent(resource, foundComponents);
        checkedPaths.add(resource.getPath());

        ResourceResolver resourceResolver = resource.getResourceResolver();
        LiveRelationshipManager liveRelationshipManager = resourceResolver.adaptTo(LiveRelationshipManager.class);
        if (liveRelationshipManager.hasLiveRelationship(resource)) {
            traverseLiveRelationships(resource, foundComponents, checkedPaths, resourceResolver, liveRelationshipManager);
        }

        for (Resource importerComponent : foundComponents) {
            references.addAll(getReferences(importerComponent));
        }

        Collections.reverse(references); // The list is processed in the reverse order, not sure why.
        return references;
    }

    private void traverseLiveRelationships(Resource root, List foundComponents, Set checkedPaths,
                                           ResourceResolver resourceResolver, LiveRelationshipManager liveRelationshipManager) {
        try {
            // live copy - look up references from the source
            LiveRelationship liveRelationship = liveRelationshipManager.getLiveRelationship(root, false);
            if (liveRelationship != null) {
                Resource liveRelationResource = resourceResolver.getResource(liveRelationship.getSourcePath());
                if (liveRelationResource != null && !checkedPaths.contains(liveRelationResource.getPath())) {
                    findImporterComponent(liveRelationResource, foundComponents);
                    checkedPaths.add(liveRelationResource.getPath());
                    traverseLiveRelationships(liveRelationResource, foundComponents, checkedPaths, resourceResolver,
                            liveRelationshipManager);
                }
            }
        } catch (WCMException e) {
            logger.error("Error looking up live relationship for the resource " + root.getPath(), e);
        }
    }

    private List getReferences(Resource importerComponent) {
        boolean hasCanvas = importerComponent.getChild(NN_CANVAS) != null;
        ValueMap properties = importerComponent.adaptTo(ValueMap.class);
        boolean isReimport = Boolean.TRUE.equals(properties.get(PN_REIMPORT));

        List references = new LinkedList();
        if (hasCanvas && !isReimport) { // If no package has been importer or if it's the case of reimport, bail out.
            try {
                references.addAll(getDesignReferences(importerComponent));
                references.addAll(getCanvasReferences(importerComponent));
            } catch (RepositoryException e) {
                logger.error("Error obtaining canvas references for the resource " + importerComponent.getPath(), e);
            }
        }
        return references;
    }

    /* Gets canvas design references */
    private List getDesignReferences(Resource importerComponent) throws RepositoryException {
        List references = new LinkedList();

        ResourceResolver resourceResolver = importerComponent.getResourceResolver();
        PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
        Page page = pageManager.getContainingPage(importerComponent);
        Designer designer = resourceResolver.adaptTo(Designer.class);
        String designPath = designer.getDesignPath(page);

        String canvasDesignPath = designPath + "/" + NN_CANVAS + importerComponent.getPath();
        Resource canvasDesign = resourceResolver.getResource(canvasDesignPath);
        if (canvasDesign != null) {
            addReferencesRecursive(canvasDesign, references);
        }
        return references;
    }

    /* Gets canvas component references */
    private List getCanvasReferences(Resource importerComponent) throws RepositoryException {
        List references = new LinkedList();
        Resource canvas = importerComponent.getChild(NN_CANVAS);
        String componentPath = "/apps/" + canvas.getResourceType();
        Resource component = canvas.getResourceResolver().resolve(componentPath);
        addReferencesRecursive(component, references);
        return references;
    }

    /* Traverses the subtree rooted at the passed root resource and adds its children to the references list
     * Note1: Excludes jcr:content because jcr:content nodes are atomically included with the parent node for replication
     * Note2: Keeps the clientlib folders pushed down the bottom. They must be published at last */
    private void addReferencesRecursive(Resource root, List references) throws RepositoryException {
        if (!isContentNode(root)) {
            if (isClientLibFolder(root)) {
                references.add(new Reference("artifact", root.getName(), root, -1));
            } else {
                references.add(0, new Reference("artifact", root.getName(), root, -1));
            }
        }
        Iterator iter = root.listChildren();
        while (iter.hasNext()) {
            addReferencesRecursive(iter.next(), references);
        }
    }

    /* Checks if the passed resource is a jcr:content node */
    private boolean isContentNode(Resource r) throws RepositoryException {
        if (r == null) {
            return false;
        }
        return JcrConstants.JCR_CONTENT.equals(r.getName());
    }

    /* Determines if the resource is a ClientLibraryFolder */
    private boolean isClientLibFolder(Resource r) throws RepositoryException {
        if (r != null) {
            ValueMap properties = r.adaptTo(ValueMap.class);
            if (properties != null) {
                String nodeType = properties.get(JcrConstants.JCR_PRIMARYTYPE, String.class);
                return CQ_CLIENT_LIBRARY_FOLDER.equals(nodeType);
            }
        }
        return false;
    }

    /* Looks up importer component nodes within the tree held by the passed root.
     * Upon finding, it pushes the importer component to the passed components list*/
    private void findImporterComponent(Resource root, List components) {
        if (ImporterUtil.isImporter(root)) {
            components.add(root);
        } else {
            Iterator childIterator = root.listChildren();
            while (childIterator.hasNext()) {
                Resource child = childIterator.next();
                findImporterComponent(child, components);
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy