AEM分组查询:如何实现可配置大小写敏感性的自定义Predicate?
AEM大小写不敏感分组查询解决方案
一、内置Predicate支持情况
AEM原生的property Predicate没有直接支持通过group.1_property.caseSensitivity=false这类参数实现大小写不敏感查询。原生like操作默认大小写敏感,无法匹配Article、aRticle这类大小写变体。
二、自定义大小写不敏感Property Predicate实现方法
可以基于原生property Predicate逻辑,扩展出支持大小写敏感性配置的caseInsensitiveProperty Predicate,具体实现如下:
1. 自定义PredicateEvaluator代码
/* 本软件属于公有领域,可自由复制、修改、发布、使用、编译、销售或分发,无论以源代码还是编译后的二进制形式,用于任何商业或非商业目的,通过任何方式均可。 在承认版权法的司法管辖区内,本软件的作者将软件的所有版权权益奉献给公有领域。我们做出此奉献是为了广大公众的利益,同时损害我们的继承人和继任者的利益。我们打算此奉献是根据版权法永久放弃本软件所有当前和未来权利的公开行为。 本软件按“原样”提供,不提供任何明示或暗示的担保,包括但不限于适销性、特定用途适用性和非侵权性的担保。在任何情况下,作者均不对因本软件或本软件的使用或其他交易而产生的任何索赔、损害或其他责任承担责任,无论是合同诉讼、侵权诉讼还是其他诉讼。 */ package com.perficient.adobe.predicates; import java.util.Locale; import java.util.Optional; import com.day.cq.search.Predicate; import com.day.cq.search.eval.AbstractPredicateEvaluator; import com.day.cq.search.eval.EvaluationContext; import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component(factory = "com.day.cq.search.eval.PredicateEvaluator/caseInsensitiveProperty") public class CaseInsensitivePropertyPredicate extends AbstractPredicateEvaluator { private static final Logger log = LoggerFactory.getLogger(CaseInsensitivePropertyPredicate.class); static final String PREDICATE_PROPERTY = "property"; static final String PREDICATE_VALUE = "value"; static final String PREDICATE_LOCALE = "locale"; static final String PREDICATE_CASE_SENSITIVE = "caseSensitive"; static final String OPERATION_LIKE = "like"; @Override public String getXPathExpression(Predicate predicate, EvaluationContext context) { log.debug("评估Predicate: {}", predicate); String property = predicate.get(PREDICATE_PROPERTY); String value = predicate.get(PREDICATE_VALUE); boolean isCaseSensitive = Boolean.parseBoolean(predicate.get(PREDICATE_CASE_SENSITIVE, "false")); Locale locale = Optional.ofNullable(predicate.get(PREDICATE_LOCALE)) .map(Locale::forLanguageTag) .orElse(Locale.getDefault()); // 处理单引号转义,避免XPath语法错误 String escapedValue = value.replace("'", "''"); String xpathExpression; if (isCaseSensitive) { // 大小写敏感逻辑,复用原生property行为 String operation = predicate.get(PREDICATE_OPERATION, OPERATION_LIKE); if (OPERATION_LIKE.equalsIgnoreCase(operation)) { xpathExpression = String.format("@%s like '%s'", property, escapedValue); } else { // 可扩展equals等其他操作 xpathExpression = String.format("@%s='%s'", property, escapedValue); } } else { // 大小写不敏感逻辑,统一转小写后匹配 String lowerValue = escapedValue.toLowerCase(locale); String operation = predicate.get(PREDICATE_OPERATION, OPERATION_LIKE); if (OPERATION_LIKE.equalsIgnoreCase(operation)) { xpathExpression = String.format("fn:lower-case(@%s) like '%s'", property, lowerValue); } else { xpathExpression = String.format("fn:lower-case(@%s)='%s'", property, lowerValue); } } log.debug("生成的XPath查询语句: {}", xpathExpression); return xpathExpression; } }
2. 部署与使用示例
将上述代码编译为OSGi bundle部署到AEM后,即可在分组查询中使用该自定义Predicate:
nodename=master group.p.or=true group.1_caseInsensitiveProperty=title group.1_caseInsensitiveProperty.value=%article% group.1_caseInsensitiveProperty.operation=like group.1_caseInsensitiveProperty.caseSensitive=false group.2_caseInsensitiveProperty=body group.2_caseInsensitiveProperty.value=%article% group.2_caseInsensitiveProperty.operation=like group.2_caseInsensitiveProperty.caseSensitive=false
代码说明
- 新增
caseSensitive参数,默认值为false(默认大小写不敏感),可配置为true切换为大小写敏感模式 - 支持
like和equals两种常用操作,可根据需求扩展更多操作类型 - 加入Locale支持,确保多语言环境下大小写转换的准确性
- 处理单引号转义,避免XPath查询出现语法错误
内容的提问来源于stack exchange,提问作者Shivam Sahil
相关产品推荐
相关产品推荐

