com.day.cq.search.eval.NodenamePredicateEvaluator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*
* Copyright 1997-2008 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.cq.search.eval;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.query.Row;
import com.day.cq.search.impl.util.GlobPatternUtil;
import org.apache.jackrabbit.util.ISO9075;
import org.apache.jackrabbit.util.Text;
import com.day.cq.search.Predicate;
import com.day.cq.search.facets.Facet;
import com.day.cq.search.facets.FacetExtractor;
import com.day.cq.search.facets.buckets.SimpleBucket;
import com.day.cq.search.facets.extractors.FacetImpl;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.propertytypes.ServiceVendor;
/**
* Matches on JCR node names.
*
*
* Supports facet extraction. Will provide buckets for each unique node name (filename).
*
*
Name:
* nodename
*
* Properties:
*
* - nodename
* - node name pattern that allows wildcards:
*
= any or no char, ?
= any char,
* [abc]
= only chars in brackets
*
*
* - case
* - option to enable case insensitivity
ignore
= case will be ignored
*
*
* @since 5.2
*/
@ServiceVendor("Adobe Systems Incorporated")
@Component(factory="com.day.cq.search.eval.PredicateEvaluator/nodename")
public class NodenamePredicateEvaluator extends AbstractPredicateEvaluator {
public static final String NODENAME = "nodename";
public static final String CASE = "case";
public static final String CASE_IGNORE = "ignore";
@Override
public String getXPathExpression(Predicate p, EvaluationContext context) {
if (!p.hasNonEmptyValue(NODENAME)) {
return null;
}
String name = p.get(NODENAME);
if (containsWildcard(name)) {
if (containsWildcardsNotSupportedWithJcrLike(name)) {
// must resort to filtering
return null;
} else {
if ((p.hasNonEmptyValue(CASE) && p.get(CASE).equals(CASE_IGNORE))) {
return XPath.JCR_LIKE + "(fn:lower-case(fn:name()), '" + convertWildcardsForJcrLike(name).toLowerCase() + "')";
}
return XPath.JCR_LIKE + "(fn:name(), '" + convertWildcardsForJcrLike(name) + "')";
}
}
if ((p.hasNonEmptyValue(CASE) && p.get(CASE).equals(CASE_IGNORE))) {
return "(fn:lower-case(fn:name()) = '" + ISO9075.encode(name).toLowerCase() + "')";
}
return "fn:name() = '" + ISO9075.encode(name) + "'";
}
@Override
public String[] getOrderByProperties(Predicate predicate, EvaluationContext context) {
return new String[]{XPath.XPATH_FUNCTION_NAME};
}
@Override
public boolean includes(Predicate p, Row row, EvaluationContext context) {
if (!p.hasNonEmptyValue(NODENAME)) {
return true;
}
String path = context.getPath(row);
if (path != null) {
if ((p.hasNonEmptyValue(CASE) && p.get(CASE).equals(CASE_IGNORE))) {
return Pattern.matches(GlobPatternUtil.convertWildcardToRegex(p.get(NODENAME)).toLowerCase(), Text.getName(path).toLowerCase());
}
return Pattern.matches(GlobPatternUtil.convertWildcardToRegex(p.get(NODENAME)), Text.getName(path));
}
return false;
}
@Deprecated
protected boolean containsWildcard(Predicate p) {
return containsWildcard(p.get(NODENAME));
}
protected boolean containsWildcard(String name) {
for (int i = 0; i < name.length(); i++) {
if ("*?[]".indexOf(name.charAt(i)) != -1) {
return true;
}
}
// not found, return -1
return false;
}
protected boolean containsWildcardsNotSupportedWithJcrLike(String name) {
// character sets [] are only supported via glob patterns
return name.indexOf('[') >= 0 || name.indexOf(']') >= 0;
}
private String convertWildcardsForJcrLike(String term) {
// glob pattern *? => jcr:like %_
return term.replace('*', XPath.JCR_LIKE_ANY_WILDCARD)
.replace('?', XPath.JCR_LIKE_SINGLE_WILDCARD);
}
@Override
public boolean canXpath(Predicate p, EvaluationContext context) {
if (p.hasNonEmptyValue(NODENAME)) {
String name = p.get(NODENAME);
if (containsWildcard(name) && containsWildcardsNotSupportedWithJcrLike(name)) {
return false;
} else {
return true;
}
}
return true;
}
@Override
public boolean canFilter(Predicate predicate, EvaluationContext context) {
return true;
}
@Override
public FacetExtractor getFacetExtractor(Predicate predicate, EvaluationContext context) {
return new NodenameFacetExtractor(predicate.clone());
}
private static class NodenameFacetExtractor implements FacetExtractor {
private Map nameBuckets = new HashMap();
private Predicate predicateTemplate;
public NodenameFacetExtractor(Predicate predicateTemplate) {
this.predicateTemplate = predicateTemplate;
}
public void handleNode(Node node) throws RepositoryException {
String name = node.getName();
SimpleBucket bucket = nameBuckets.get(name);
if (bucket == null) {
Predicate p = predicateTemplate.clone();
p.set(NODENAME, name);
bucket = new SimpleBucket(p, name);
nameBuckets.put(name, bucket);
}
bucket.increment();
}
public Facet getFacet() {
return new FacetImpl(nameBuckets.values());
}
public boolean equals(Object obj) {
return obj instanceof NodenameFacetExtractor;
}
public int hashCode() {
return 1; // all NodenameFacetExtractors are considered equal
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy