AEM 6.X:在DAM资产中查找未使用的资产

时间:2018-02-02 16:46:11

标签: aem dam

我想编写一个查询并使用查询调试工具对其进行测试,以查找未被引用或未使用的图像。我知道我们可以实现这一点,如下所示:

http://wemcode.wemblog.com/get_asset_reference_in_page

但我想知道是否可以编写查询。另外,我想知道AEM资产中的内部参考搜索是如何工作的。它会触发查询吗?

3 个答案:

答案 0 :(得分:0)

  1. 我们可以在页面上搜索资产的引用,但是我们无法在DAM中搜索以检查资产是否被任何页面引用。原因是,资产上没有任何属性表明对页面或任何其他资产的任何引用。在这里可以查询哪个属性?

  2. 页面上引用的资产可以通过组件节点的属性轻松确定。例如,图像组件创建了一个属性" damAssetReference"当作者从DAM拖放内容时。可以查询此属性以查找引用。

  3. 要了解AEM中的参考搜索,您可以查看AssetReferenceSearch类的源代码。看起来他们遍历每个节点和每个属性来查找引用。 Adobe开发人员也通过如上所述的Point 2进行操作。

    package com.day.cq.dam.commons.util;
    
    import com.day.cq.dam.api.Asset;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.HashMap;
    import java.util.HashSet;
    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()
      {
        Map<String, Asset> assetRefs = new HashMap();
        Pattern pattern = getPattern(this.searchPath);
        search(this.node, assetRefs, pattern);
        return assetRefs;
      }
    
      protected void search(Node node, Map<String, Asset> assetRefs, Pattern pattern)
      {
        try
        {
          for (pIter = node.getProperties(); pIter.hasNext();)
          {
            Property p = pIter.nextProperty();
            if ((p.getType() == 1) || (p.getType() == 7))
            {
              boolean decode = p.getType() == 1;
              if (p.getDefinition().isMultiple())
              {
                for (Value v : p.getValues())
                {
                  String value = v.getString();
                  if (pattern.matcher(value).find())
                  {
                    if (decode) {
                      value = tryDecode(value);
                    }
                    Set<String> refs = new HashSet();
                    if (value.startsWith("/")) {
                      refs.add(value);
                    } else {
                      getRefs(value, refs, decode);
                    }
                    for (String ref : refs) {
                      if ((this.resolver.getResource(ref) != null) && (this.resolver.getResource(ref).adaptTo(Asset.class) != null)) {
                        assetRefs.put(ref, this.resolver.getResource(ref).adaptTo(Asset.class));
                      }
                    }
                  }
                }
              }
              else
              {
                String value = p.getString();
    
                String isImageContext = "/is/image";
                if (value.startsWith(isImageContext)) {
                  value = value.split(isImageContext)[1];
                }
                Matcher matcher = pattern.matcher(value);
                if (matcher.find())
                {
                  Set<String> refs = new HashSet();
                  if (value.startsWith("/")) {
                    refs.add(decode ? tryDecode(value) : value);
                  } else {
                    getRefs(value, refs, decode);
                  }
                  for (String ref : refs) {
                    if ((this.resolver.getResource(ref) != null) && (this.resolver.getResource(ref).adaptTo(Asset.class) != null)) {
                      assetRefs.put(ref, this.resolver.getResource(ref).adaptTo(Asset.class));
                    }
                  }
                }
              }
            }
          }
        }
        catch (RepositoryException re)
        {
          PropertyIterator pIter;
          log.warn("Error occured while reading properties");
        }
        try
        {
          for (nItr = node.getNodes(); nItr.hasNext();)
          {
            Node n = nItr.nextNode();
            search(n, assetRefs, pattern);
          }
        }
        catch (RepositoryException re)
        {
          NodeIterator nItr;
          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)
        {
          char charBeforeStartPos = value.charAt(startPos - 1);
          if ((charBeforeStartPos == '\'') || (charBeforeStartPos == '"'))
          {
            int endPos = value.indexOf(charBeforeStartPos, startPos);
            if (endPos > startPos)
            {
              String ref = value.substring(startPos, endPos);
              refs.add(decode ? tryDecode(ref) : ref);
              startPos = endPos;
            }
          }
          startPos = value.indexOf(this.searchPath, startPos + 1);
        }
      }
    
      protected Pattern getPattern(String path)
      {
        return Pattern.compile("(.[\"']|^|^[\"'])(" + path + ")\\b");
      }
    }
    

答案 1 :(得分:0)

ReferenceSearch也可用于检测未引用资产的资产。下面的示例代码段:

private void findUnreferencedNodes(ResourceResolver resourceResolver, String path) {
    this.resourceResolver = resourceResolver;
    this.path = path; //DAM root path

    try {
      Node root = resourceResolver.getResource(path).adaptTo(Node.class);
      NodeIterator nodeIterator = root.getNodes();

      while (nodeIterator.hasNext()) {
        Node currentNode = nodeIterator.nextNode();
        if (currentNode.getProperty("jcr:primaryType").getString().equals("dam:Asset")) {
          Map<String, ReferenceSearch.Info> searchResult = referenceSearch.search(resourceResolver, currentNode.getPath());
          if (searchResult.isEmpty()) {
            //These are the nodes/assets not referenced anywhere
          }
        }
        //Recursively iterate through all the assets from root path
        findUnreferencedNodes(resourceResolver, currentNode.getPath());
      }
    } catch (RepositoryException e) {
      e.printStackTrace();
    }
  }

答案 2 :(得分:0)

https://github.com/frappierer/unrefAemAssets

它不像已经给出的解决方案那样复杂,但是它可以工作:)。

编码不好,但是可以解决您的问题。