
com.day.cq.dam.commons.util.GQLConverter Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2014 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.day.cq.dam.commons.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jcr.RepositoryException;
import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.search.Predicate;
import com.day.cq.search.PredicateConverter;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.eval.FulltextPredicateEvaluator;
import com.day.cq.search.eval.JcrPropertyPredicateEvaluator;
import com.day.cq.search.eval.RangePropertyPredicateEvaluator;
import com.day.cq.tagging.impl.search.TagSearchPredicateEvaluator;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.tenant.Tenant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GQLConverter {
private static final String OR_OP = " OR ";
private static final String TAGS_PROP = "tags";
private static final String DATERANGE_PRED = "daterange";
private static final String RANGEPROP_PRED = "rangeproperty";
private static final String JCR_PROPERTIES_PATH = "/var/dam/content/formitems";
private static final Logger log = LoggerFactory.getLogger(GQLConverter.class);
/**
* Parse and converts GQL statement from fulltext in conditions to QueryBuilder PredicateGroup.
*
* @param conditions the map containing initial conditions and fulltext to be processed
* @param resolver to resolve node containing gql to jcr properties mapping
* @return PredicateGroup containing conditions merged with new conditions formed from fulltext
* @throws RepositoryException
*/
public static PredicateGroup buildQuery(Map conditions, ResourceResolver resolver) throws RepositoryException {
PredicateGroup rootGrp = PredicateConverter.createPredicates(conditions);
List gqlExpressions = getValidGQLStatements(rootGrp);
if (!gqlExpressions.isEmpty()) {
for (String expression : gqlExpressions) {
PredicateGroup gqlPredicateGroup = PredicateConverter.createPredicatesFromGQL(expression.replace("*", "%"));
transformPredicates(gqlPredicateGroup, getJcrPropertyMapping(resolver));
rootGrp.addAll(gqlPredicateGroup);
}
}
return rootGrp;
}
/**
* populates and saves all valid schema editor formitems which can be used as gql facets
* @param sourceNode source for schema editor formitems
* @param destinationNode location to save found gql facets
*/
public static void populateGqlfacets(Resource sourceNode, Resource destinationNode) {
if (sourceNode == null) {
log.error("source node null, skipping GQL facets extraction");
return;
}
try {
findGqlFacets(sourceNode, destinationNode);
} catch(PersistenceException e) {
log.error("Error while GQL facets extraction" + e.getMessage(), e);
}
}
/**
* Collects fulltext from all fulltext predicates in predicateGroup which are valid GQL expressions
* and also removes such predicates from predicateGroup
* @param predicateGroup PredicateGroup to be processed
* @return List of valid gql expressions
*
*/
private static List getValidGQLStatements(PredicateGroup predicateGroup) {
List gqlExpressions = new ArrayList();
if (predicateGroup == null)
return gqlExpressions;
for (int i = 0; i < predicateGroup.size(); i++) {
if (predicateGroup.get(i) instanceof PredicateGroup) {
gqlExpressions.addAll(getValidGQLStatements((PredicateGroup) predicateGroup.get(i)));
} else if (predicateGroup.get(i) instanceof Predicate) {
Predicate predicate = predicateGroup.get(i);
if (FulltextPredicateEvaluator.FULLTEXT.equals(predicate.getType())) {
String fulltext = predicate.get(FulltextPredicateEvaluator.FULLTEXT, "");
if (fulltext != null && (fulltext.contains(":") || fulltext.contains(OR_OP))) {
gqlExpressions.add(fulltext);
predicateGroup.remove(i);
}
}
}
}
return gqlExpressions;
}
/**
* @param resolver to resolve node containing jcr properties mapping
* @return map containing gql to jcr properties mapping
* @throws RepositoryException
*/
private static Map getJcrPropertyMapping(ResourceResolver resolver) throws RepositoryException {
Map jcrPropertyMap = new HashMap();
if (resolver == null) {
log.warn("Resource resolver is null, skipping property name conversion");
return jcrPropertyMap;
}
Resource formItemsNode = resolver.getResource(getGqlFacetsDir(resolver));
for (Iterator itr = formItemsNode.listChildren(); itr.hasNext(); ) {
ValueMap prop = itr.next().adaptTo(ValueMap.class);
if (prop != null && prop.containsKey("fieldLabel") && prop.containsKey("name")) {
jcrPropertyMap.put(prop.get("fieldLabel").toString().toLowerCase().trim().replace(" ", ""),
prop.get("name").toString());
}
}
return jcrPropertyMap;
}
private static String getGqlFacetsDir(ResourceResolver resolver) {
String gqlFacetsDir = JCR_PROPERTIES_PATH;
Tenant tenant = resolver.adaptTo(Tenant.class);
if (tenant != null) {
if (tenant.getProperty(DamConfigurationConstants.DAM_GQL_FACETS_ROOT) != null) {
gqlFacetsDir = tenant.getProperty(DamConfigurationConstants.DAM_GQL_FACETS_ROOT).toString();
}
}
return gqlFacetsDir;
}
/**
* DAM level customization for different conditions
*
* @param predicateGroup PredicateGroup to be transformed
* @param jcrPropertyMap mapping of properties to jcr properties
*/
private static void transformPredicates(PredicateGroup predicateGroup, Map jcrPropertyMap) {
if (predicateGroup == null) {
return;
}
for (int i = 0; i < predicateGroup.size(); i++) {
if (predicateGroup.get(i) instanceof PredicateGroup) {
PredicateGroup optionalGrp = (PredicateGroup) predicateGroup.get(i);
transformPredicates(optionalGrp, jcrPropertyMap);
predicateGroup.set(i, optionalGrp);
} else if (predicateGroup.get(i) instanceof Predicate) {
Predicate predicate = predicateGroup.get(i);
modifyPredicate(predicateGroup, predicate, i, jcrPropertyMap);
}
}
}
private static void modifyPredicate(PredicateGroup parentGroup, Predicate predicate, int index, Map jcrPropertyMap) {
String property = predicate.get("property");
if (JcrPropertyPredicateEvaluator.PROPERTY.equals(predicate.getType())) {
String value = predicate.get("value");
if (property.equals(TAGS_PROP)) {
property = jcrPropertyMap.containsKey(property.toLowerCase()) ?
jcrPropertyMap.get(property.toLowerCase()) : property;
predicate = new Predicate(TagSearchPredicateEvaluator.TYPE);
predicate.set(JcrPropertyPredicateEvaluator.PROPERTY, property);
predicate.set(TagSearchPredicateEvaluator.TYPE, value);
} else {
property = jcrPropertyMap.containsKey(property.toLowerCase()) ?
jcrPropertyMap.get(property.toLowerCase()) : property;
predicate.set(JcrPropertyPredicateEvaluator.PROPERTY, property);
predicate.set(JcrPropertyPredicateEvaluator.VALUE, value);
predicate.set(JcrPropertyPredicateEvaluator.OPERATION, JcrPropertyPredicateEvaluator.OP_LIKE);
}
} else if (DATERANGE_PRED.equals(predicate.getType()) || RANGEPROP_PRED.equals(predicate.getType())) {
property = jcrPropertyMap.containsKey(property) ? jcrPropertyMap.get(property) : property;
predicate.set(JcrPropertyPredicateEvaluator.PROPERTY, property);
predicate.set(RangePropertyPredicateEvaluator.LOWER_OPERATION, ">=");
predicate.set(RangePropertyPredicateEvaluator.UPPER_OPERATION, "<=");
}
parentGroup.set(index,predicate);
}
private static void findGqlFacets(Resource sourceNode, Resource destinationNode) throws PersistenceException {
if (sourceNode == null) {
return;
}
for (Iterator itr = sourceNode.listChildren(); itr.hasNext();) {
Resource childNode = itr.next();
ValueMap childProps = childNode != null ? childNode.adaptTo(ValueMap.class) : null;
if (childProps != null) {
String jcrProperty = childProps.get("name", String.class);
String facetName = childProps.get("fieldLabel", String.class);
if (jcrProperty != null && facetName != null) {
String desNodeName = JcrUtil.createValidName(facetName);
if (destinationNode.getChild(desNodeName) == null) {
jcrProperty = (jcrProperty.length() > 2 && jcrProperty.startsWith("./")) ?
jcrProperty.substring(2) : jcrProperty;
Map props = new HashMap();
props.put("fieldLabel", facetName);
props.put("name", jcrProperty);
destinationNode.getResourceResolver().create(destinationNode, desNodeName, props);
}
}
}
findGqlFacets(childNode, destinationNode);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy