AssetReferenceSearch.java 6.44 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.dam.api.Asset
 *  com.day.cq.wcm.api.reference.Reference
 *  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.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.dam.commons.util;

import com.day.cq.dam.api.Asset;
import com.day.cq.dam.commons.util.S7SetHelper;
import com.day.cq.dam.commons.util.impl.AssetReferenceProvider;
import com.day.cq.wcm.api.reference.Reference;
import java.net.URI;
import java.net.URISyntaxException;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AssetReferenceSearch {
    private static final Logger log = LoggerFactory.getLogger(AssetReferenceSearch.class);
    private final Node node;
    private final String searchPath;
    private final ResourceResolver resolver;

    public AssetReferenceSearch(Node node, String searchPath, ResourceResolver resolver) {
        this.node = node;
        this.searchPath = searchPath;
        this.resolver = resolver;
    }

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

    protected void search(Node node, Map<String, Asset> assetRefs, Pattern pattern) {
        try {
            PropertyIterator pIter = node.getProperties();
            while (pIter.hasNext()) {
                Matcher matcher;
                boolean decode;
                String isImageContext;
                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()) {
                        String value = v.getString();
                        if (!pattern.matcher(value).find()) continue;
                        if (decode) {
                            value = this.tryDecode(value);
                        }
                        HashSet<String> refs = new HashSet<String>();
                        if (value.startsWith("/")) {
                            refs.add(value);
                        } else {
                            this.getRefs(value, refs, decode);
                        }
                        for (String ref : refs) {
                            if (this.resolver.getResource(ref) == null || this.resolver.getResource(ref).adaptTo(Asset.class) == null) continue;
                            assetRefs.put(ref, (Asset)this.resolver.getResource(ref).adaptTo(Asset.class));
                        }
                    }
                    continue;
                }
                String value = p.getString();
                if (value.startsWith(isImageContext = "/is/image")) {
                    value = value.split(isImageContext)[1];
                }
                HashSet<String> refs = new HashSet<String>();
                Resource r = this.resolver.getResource(value);
                if (r != null && (S7SetHelper.isS7Set(r) || S7SetHelper.isS7Video(r))) {
                    AssetReferenceProvider refProvider = new AssetReferenceProvider();
                    List<Reference> s7SetRefs = refProvider.findReferences(r);
                    int i = 0;
                    int len = s7SetRefs.size();
                    String path = value;
                    refs.add(decode ? this.tryDecode(path) : path);
                    for (i = 0; i < len; ++i) {
                        path = s7SetRefs.get(i).getResource().getPath();
                        refs.add(decode ? this.tryDecode(path) : path);
                    }
                }
                if (!(matcher = pattern.matcher(value)).find()) continue;
                if (value.startsWith("/")) {
                    refs.add(decode ? this.tryDecode(value) : value);
                } else {
                    this.getRefs(value, refs, decode);
                }
                for (String ref : refs) {
                    if (this.resolver.getResource(ref) == null || this.resolver.getResource(ref).adaptTo(Asset.class) == null) continue;
                    assetRefs.put(ref, (Asset)this.resolver.getResource(ref).adaptTo(Asset.class));
                }
            }
        }
        catch (RepositoryException re) {
            log.warn("Error occured while reading properties");
        }
        try {
            NodeIterator nItr = node.getNodes();
            while (nItr.hasNext()) {
                Node n = nItr.nextNode();
                this.search(n, assetRefs, pattern);
            }
        }
        catch (RepositoryException re) {
            log.warn("Error occured while reading nodes");
        }
    }

    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");
    }
}