AssetReferenceRecursiveSearch.java 7.09 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.dam.api.Asset
 *  com.day.cq.dam.api.collection.SmartCollection
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.Property
 *  javax.jcr.PropertyIterator
 *  javax.jcr.RepositoryException
 *  javax.jcr.Value
 *  javax.jcr.nodetype.PropertyDefinition
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceUtil
 *  org.apache.sling.resource.collection.ResourceCollection
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.dam.commons.util;

import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.collection.SmartCollection;
import com.day.cq.dam.commons.util.S7SetHelper;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.nodetype.PropertyDefinition;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.resource.collection.ResourceCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AssetReferenceRecursiveSearch {
    private static final Logger log = LoggerFactory.getLogger(AssetReferenceRecursiveSearch.class);
    private final Node node;
    private final String searchPath;
    private final ResourceResolver resolver;
    private List<String> pathsTraversed = new ArrayList<String>();
    private final List<String> ignoredNodes;

    public AssetReferenceRecursiveSearch(Node node, String searchPath, ResourceResolver resolver) {
        this.ignoredNodes = new ArrayList<String>(){};
        this.node = node;
        this.searchPath = searchPath;
        this.resolver = resolver;
    }

    public Map<String, Resource> search() {
        HashMap<String, Resource> assetRefs = new HashMap<String, Resource>();
        Pattern pattern = this.getPattern(this.searchPath);
        this.search(this.node, assetRefs, pattern);
        return assetRefs;
    }

    protected void search(Node node, Map<String, Resource> resourceRefs, Pattern pattern) {
        try {
            Resource referencedResource;
            if (node.hasProperty("sling:resource") && (referencedResource = this.resolver.resolve(node.getProperty("sling:resource").getString())) != null && !ResourceUtil.isNonExistingResource((Resource)referencedResource) && (S7SetHelper.isS7Set(referencedResource) || S7SetHelper.isS7Video(referencedResource) || referencedResource.adaptTo(ResourceCollection.class) != null || referencedResource.adaptTo(SmartCollection.class) != null || ((Node)referencedResource.adaptTo(Node.class)).isNodeType("nt:folder")) && !this.pathsTraversed.contains(referencedResource.getPath())) {
                this.pathsTraversed.add(referencedResource.getPath());
                this.search((Node)referencedResource.adaptTo(Node.class), resourceRefs, pattern);
            }
            if (!this.ignoredNodes.contains(node.getName()) && !node.getPath().equals(this.node.getPath())) {
                this.locateMatch(pattern, node.getPath(), true, resourceRefs);
            }
            if (!this.ignoredNodes.contains(node.getName())) {
                this.searchInProps(node, resourceRefs, pattern);
                this.searchInChildren(node, resourceRefs, pattern);
            }
        }
        catch (RepositoryException re) {
            log.warn("Error occurred while reading properties", (Throwable)re);
        }
    }

    protected void searchInProps(Node node, Map<String, Resource> resourceRefs, Pattern pattern) {
        try {
            PropertyIterator pIter = node.getProperties();
            while (pIter.hasNext()) {
                boolean decode;
                Property p = pIter.nextProperty();
                if (p.getType() != 1 && p.getType() != 7) continue;
                boolean bl = decode = p.getType() == 1;
                if (p.getDefinition().isMultiple()) {
                    for (Value v : p.getValues()) {
                        this.locateMatch(pattern, v.getString(), decode, resourceRefs);
                    }
                    continue;
                }
                this.locateMatch(pattern, p.getString(), decode, resourceRefs);
            }
        }
        catch (RepositoryException re) {
            log.warn("Error occured while reading properties");
        }
    }

    protected void searchInChildren(Node node, Map<String, Resource> resourceRefs, Pattern pattern) {
        try {
            NodeIterator nItr = node.getNodes();
            while (nItr.hasNext()) {
                Node n = nItr.nextNode();
                this.search(n, resourceRefs, pattern);
            }
        }
        catch (RepositoryException re) {
            log.warn("Error occured while reading nodes");
        }
    }

    private void locateMatch(Pattern pattern, String value, boolean decode, Map<String, Resource> resourceRefs) throws RepositoryException {
        Matcher matcher = pattern.matcher(value);
        if (matcher.find()) {
            HashSet<String> refs = new HashSet<String>();
            if (value.startsWith("/")) {
                refs.add(decode ? this.tryDecode(value) : value);
            } else {
                this.getRefs(value, refs, decode);
            }
            for (String ref : refs) {
                Resource resource = this.resolver.getResource(ref);
                if (resource == null || ResourceUtil.isNonExistingResource((Resource)resource) || resource.adaptTo(Asset.class) == null && !S7SetHelper.isS7Set(resource) && !S7SetHelper.isS7Video(resource) && resource.adaptTo(ResourceCollection.class) == null && !((Node)resource.adaptTo(Node.class)).isNodeType("nt:folder")) continue;
                resourceRefs.put(ref, this.resolver.getResource(ref));
            }
        }
    }

    private String tryDecode(String url) {
        try {
            return new URI(url).getPath();
        }
        catch (URISyntaxException e) {
            return url;
        }
    }

    private void getRefs(String value, Set<String> refs, boolean decode) {
        int startPos = value.indexOf(this.searchPath, 1);
        while (startPos != -1) {
            int endPos;
            char charBeforeStartPos = value.charAt(startPos - 1);
            if ((charBeforeStartPos == '\'' || charBeforeStartPos == '\"') && (endPos = value.indexOf(charBeforeStartPos, startPos)) > startPos) {
                String ref = value.substring(startPos, endPos);
                refs.add(decode ? this.tryDecode(ref) : ref);
                startPos = endPos;
            }
            startPos = value.indexOf(this.searchPath, startPos + 1);
        }
    }

    protected Pattern getPattern(String path) {
        return Pattern.compile("(.[\"']|^|^[\"'])(" + path + ")\\b");
    }

}