我想编写一个查询并使用查询调试工具对其进行测试,以查找未被引用或未使用的图像。我知道我们可以实现这一点,如下所示:
http://wemcode.wemblog.com/get_asset_reference_in_page
但我想知道是否可以编写查询。另外,我想知道AEM资产中的内部参考搜索是如何工作的。它会触发查询吗?
答案 0 :(得分:0)
我们可以在页面上搜索资产的引用,但是我们无法在DAM中搜索以检查资产是否被任何页面引用。原因是,资产上没有任何属性表明对页面或任何其他资产的任何引用。在这里可以查询哪个属性?
页面上引用的资产可以通过组件节点的属性轻松确定。例如,图像组件创建了一个属性" damAssetReference"当作者从DAM拖放内容时。可以查询此属性以查找引用。
要了解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)