Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2013 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.adobe.cq.social.commons.listing;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.jcr.PropertyType;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.cq.social.commons.Comment;
import com.adobe.cq.social.commons.CommentSystem;
import com.adobe.cq.social.ugc.api.ComparisonType;
import com.adobe.cq.social.ugc.api.Constraint;
import com.adobe.cq.social.ugc.api.ConstraintGroup;
import com.adobe.cq.social.ugc.api.FullTextConstraint;
import com.adobe.cq.social.ugc.api.Operator;
import com.adobe.cq.social.ugc.api.ValueConstraint;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.tagging.TagConstants;
/**
*
*
* {@code
* Query Filter Utility class uses to parse filter parameters. Filter query restricts the data returned in a query
* request, which should take a form of
* http://://.social.query..?
*
* A single filter uses the form: property operator expression where,
*
*
property - the property name. @see MAP_INDEX_TYPE for the list of valid name.
*
operator - defines the type of filter match to use.
*
expression - states the values included in the results. There are couple of important rules for filter
* expression.
*
*
URL-reversed characters - Characters such as '&' must be url-encoded.
*
Reversed characters - The comma and backslash must be backslash escaped when they appear in an
* expression.
*
*
*
* }
*
*/
public class QueryFilterUtil {
/**
* General Query Filter Exception, thrown when there is an error while parsing a filter.
*/
public static class QueryFilterException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public QueryFilterException(final String msg) {
super(msg);
}
public QueryFilterException(final String msg, final Exception cause) {
super(msg, cause);
}
public QueryFilterException(final Exception cause) {
super(cause);
}
}
private static final String PROP_TAG = "tag";
private static final String NULL_STRING = "null";
public static final String PROP_USER_DISPLAY_NAME = "author_display_name";
// Definition of the indexed properties.
private static Map MAP_INDEXED_TYPE;
static {
// Define by AbstractUgcNodeIndexerExtension
MAP_INDEXED_TYPE = new HashMap();
MAP_INDEXED_TYPE.put("jcr:primaryType", PropertyType.STRING);
MAP_INDEXED_TYPE.put(":uuid", PropertyType.STRING);
MAP_INDEXED_TYPE.put(":path", PropertyType.STRING);
MAP_INDEXED_TYPE.put(":parent", PropertyType.STRING);
MAP_INDEXED_TYPE.put(":name", PropertyType.STRING);
// Define by ModerationUgcNodeIndexerExtension:
MAP_INDEXED_TYPE.put(Comment.PROP_FLAGGED, PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put(Comment.PROP_SPAM, PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put("read", PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put("influence", PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put("attachments", PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put("sentiment", PropertyType.LONG);
MAP_INDEXED_TYPE.put("flagged", PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put("added", PropertyType.DATE);
MAP_INDEXED_TYPE.put("modifiedDate", PropertyType.DATE);
MAP_INDEXED_TYPE.put("state", PropertyType.STRING);
MAP_INDEXED_TYPE.put("userIdentifier", PropertyType.STRING);
MAP_INDEXED_TYPE.put("parentPath", PropertyType.STRING);
MAP_INDEXED_TYPE.put("parentTitle", PropertyType.STRING);
MAP_INDEXED_TYPE.put("replies", PropertyType.LONG);
MAP_INDEXED_TYPE.put(JcrConstants.JCR_TITLE, PropertyType.STRING);
MAP_INDEXED_TYPE.put(JcrConstants.JCR_DESCRIPTION, PropertyType.STRING);
MAP_INDEXED_TYPE.put(CommentSystem.NN_COMMENT_ATTACHMENTS, PropertyType.BOOLEAN);
// Define by JournalUgcNodeIndexerExtension
MAP_INDEXED_TYPE.put(SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE,
PropertyType.STRING);
// Define by ForumSCIndexExtension
// MAP_INDEXED_TYPE.put("replies", PropertyType.LONG);
MAP_INDEXED_TYPE.put("parentPath", PropertyType.STRING);
MAP_INDEXED_TYPE.put("parentTitle", PropertyType.STRING);
MAP_INDEXED_TYPE.put("allowThreadedReply", PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put(Comment.PROP_IS_DRAFT, PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put(Comment.PROP_PUBLISH_DATE, PropertyType.DATE);
MAP_INDEXED_TYPE.put(Comment.PROP_PUBLISH_JOB_ID, PropertyType.STRING);
// Define by QnaSCIndexExtension
MAP_INDEXED_TYPE.put("answered", PropertyType.BOOLEAN);
MAP_INDEXED_TYPE.put("chosenanswered", PropertyType.BOOLEAN);
// Define by HBSIndexExtension
MAP_INDEXED_TYPE.put(PROP_TAG, PropertyType.STRING);
MAP_INDEXED_TYPE.put(TagConstants.PN_TAGS, PropertyType.STRING);
MAP_INDEXED_TYPE.put(PROP_USER_DISPLAY_NAME, PropertyType.STRING);
// Needed for calendar search by keyword
MAP_INDEXED_TYPE.put("location_t", PropertyType.STRING);
MAP_INDEXED_TYPE.put("social:key", PropertyType.STRING);
}
/** default log. */
private static final Logger LOG = LoggerFactory.getLogger(QueryFilterUtil.class);
// Filter index
private static int NUMBER_FILTER_TOKENS = 3;
private static int FILTER_PROP_INDEX = 0;
private static int FILTER_OPERATOR_INDEX = 1;
private static int FILTER_EXPRESSION_INDEX = 2;
/**
* enum for avartar's size.
*/
public enum DATA_TYPE {
/**
* Data type for String, String Array, boolean, long and Date.
*/
STRING("s"), STRING_ARRAY("ss"), BOOLEAN("b"), LONG("l"), DATE("dt");
/**
* Avartar's size.
*/
private final String type;
/**
* Constructor.
* @param t the data type
*/
DATA_TYPE(final String t) {
type = t;
}
@Override
public String toString() {
return String.valueOf(this.type);
}
public static DATA_TYPE getEnum(final String value) {
for (final DATA_TYPE dt : values()) {
if (StringUtils.equals(dt.type, value)) {
return dt;
}
}
throw new IllegalArgumentException("Unsupported data type " + value);
}
}
/**
* Query Comparator types - map our URL comparator to UGC Comparator type.
*/
public enum Comparator {
EQ(ComparisonType.Equals), NE(ComparisonType.NotEquals), LT(ComparisonType.LessThan), LTE(
ComparisonType.LessThanOrEqualTo), GT(ComparisonType.GreaterThan), GTE(
ComparisonType.GreaterThanOrEqualTo), LIKE(null); // there is no comparison type for LIKE since it is a
// FullTextConstraint
ComparisonType comparator;
Comparator(final ComparisonType comparator) {
this.comparator = comparator;
}
ComparisonType getComparisonType() {
return comparator;
}
public static Comparator fromString(final String text) throws QueryFilterException {
if (text == null || text.length() == 0) {
return null;
}
return Comparator.valueOf(text.toUpperCase());
}
}
/**
* Abstract of a filter clause, which consists of a property name, a comparator, and a value. Example filter=name
* eq admin
*/
public static class QueryFilter {
private final Constraint constraint;
private final String name; // the name of the constraint property.
private final String value; // the value of the constraint property
private final Comparator comp;
@SuppressWarnings("unchecked")
private QueryFilter(final String name, final Comparator comp, final String value, final Operator operator)
throws QueryFilterException {
if (StringUtils.isEmpty(name)) {
throw new QueryFilterException("Name parameter can not be null.");
}
if (comp == null) {
throw new QueryFilterException("Invalid comparator value");
}
if (StringUtils.isEmpty(value)) {
throw new QueryFilterException("Value parameter can not be null.");
}
if (operator == null) {
throw new QueryFilterException("Operator parameter can not be null.");
}
this.name = name;
this.value = value;
this.comp = comp;
final Object typedValue = getPropertyValue(name, value);
this.constraint =
isTextSearchProperty(name, comp) && (typedValue instanceof String) ? new FullTextConstraint(
(String) typedValue, name, operator) : new ValueConstraint(name, typedValue,
comp.getComparisonType(), operator);
}
/**
* Gets the constraint.
* @return the constraint
*/
public Constraint getConstraint() {
return constraint;
}
/**
* Gets the value.If the Query expression is "isDraft eq true", the API will return isDraft
* @return the value
*/
public String getName() {
return name;
}
/**
* Gets the value.If the Query expression is "isDraft eq true", the API will return true
* @return the value
*/
public String getValue() {
return value;
}
/**
* Gets the comparator. If the Query expression is "isDraft eq true", the API will return eq
* @return the comparator
*/
public Comparator getComparator() {
return comp;
}
/**
* This api is for internal use only, and may be changed or removed at any time.
* @param filter String
* @param operator Operator
* @return QueryFilter
* @throws QueryFilterException QueryFilterException
*/
public static QueryFilter parse(final String filter, final Operator operator) throws QueryFilterException {
return parse(filter, operator, false);
}
/**
* This api is for internal use only, and may be changed or removed at any time
* @param filter String
* @param operator Operator
* @param bSupportsMultiLingualSearch boolean
* @return QueryFilter
* @throws QueryFilterException QueryFilterException
*/
public static QueryFilter parse(final String filter, final Operator operator,
final boolean bSupportsMultiLingualSearch) throws QueryFilterException {
final String[] words = filter.trim().split(" ", NUMBER_FILTER_TOKENS);
if (words.length < NUMBER_FILTER_TOKENS) {
throw new QueryFilterException("Invalid filter expression: " + filter);
}
String name = words[FILTER_PROP_INDEX].trim();
if (name.equals(PROP_TAG)) {
name = TagConstants.PN_TAGS;
}
final Comparator comp = Comparator.fromString(words[FILTER_OPERATOR_INDEX].trim());
final String value = escapeQueryValue(words[FILTER_EXPRESSION_INDEX].trim(), bSupportsMultiLingualSearch);
return new QueryFilter(name, comp, value, operator);
}
private boolean isTextSearchProperty(final String name, final Comparator comp) {
if (comp == Comparator.LIKE) {
return true;
}
return false;
}
private static String escapeQueryValue(final String value, final boolean bSupportsMultiLingualSearch) {
String escapeValue = value;
// Remove quotes around the value
if (escapeValue.startsWith("'") && escapeValue.endsWith("'")) {
escapeValue = escapeValue.substring(1, escapeValue.length() - 1);
}
if (!bSupportsMultiLingualSearch) {
if (escapeValue.length() > 1 && escapeValue.startsWith("\"") && escapeValue.endsWith("\"")) {
escapeValue = escapeValue.substring(1, escapeValue.length() - 1);
}
}
if (escapeValue.contains("\\,")) {
escapeValue = escapeValue.replace("\\,", ",");
}
return escapeValue;
}
}
/**
* OR Logic Example: filter=name eq 'admin', name eq 'peter' This api is for internal use only, and may be changed
* or removed at any time
* @param expressions String
* @param orFilters Map
* @throws QueryFilterException QueryFilterException
*/
public static void parseOrFilters(final String expressions, final Map orFilters)
throws QueryFilterException {
parseOrFilters(expressions, orFilters, false);
}
/**
* OR Logic Example: filter=name eq 'admin', name eq 'peter' This api is for internal use only, and may be changed
* or removed at any time
* @param expressions String
* @param orFilters Map
* @param bSupportsMultiLingualSearch boolean
* @throws QueryFilterException QueryFilterException
*/
public static void parseOrFilters(final String expressions, final Map orFilters,
final boolean bSupportsMultiLingualSearch) throws QueryFilterException {
if (StringUtils.isEmpty(expressions)) {
throw new QueryFilterException("Empty filter.");
}
final String[] filters = expressions.split("(?
* {@code
* AND logic - AND logic is achieved using multiple filters. Example: filter=name eq 'admin'&filter=message eq
* 'testing' Combining AND and OR filter=name eq 'admin',name eq 'peter'&filter=message eq testing This api is for
* internal use only, and may be changed or removed at any time
* }
*
* @param filters String[]
* @return List of constraint groups
* @throws QueryFilterException QueryFilterException
*/
public static List parseFilter(final String[] filters) throws QueryFilterException {
return parseFilter(filters, false);
}
/**
* {@code
* AND logic - AND logic is achieved using multiple filters. Example: filter=name eq 'admin'&filter=message eq
* 'testing' Combining AND and OR filter=name eq 'admin',name eq 'peter'&filter=message eq testing This api is for
* internal use only, and may be changed or removed at any time
* }
*
* @param filters String[]
* @param bSupportsMultiLingualSearch boolean
* @return List of constraint groups
* @throws QueryFilterException QueryFilterException
*/
public static List parseFilter(final String[] filters, final boolean bSupportsMultiLingualSearch)
throws QueryFilterException {
// Create a map for this group OR filters
final Map orFiltersMap = new HashMap();
final List andFilters = new ArrayList();
if (filters != null) {
for (int i = 0; i < filters.length; i++) {
final ConstraintGroup cg = new ConstraintGroup();
cg.setOperator(Operator.And);
andFilters.add(cg);
parseOrFilters(filters[i], orFiltersMap, bSupportsMultiLingualSearch);
for (final Entry entry : orFiltersMap.entrySet()) {
cg.or(entry.getValue());
}
orFiltersMap.clear();
}
}
return andFilters;
}
}