All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.search.eval.RangePropertyPredicateEvaluator Maven / Gradle / Ivy

/*
 * 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.math.BigDecimal;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.query.Row;

import org.apache.felix.scr.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.search.Predicate;

/**
 * Matches a JCR property against an interval. This applies to properties with
 * linear types such as LONG, DOUBLE and DECIMAL. For DATE please see the
 * {@link DateRangePredicateEvaluator} that has optimized date format input.
 * 
 * 

* You can define a lower bound and an upper bound or only one of them. The * operation (eg. "lesser than" or "lesser or equals") can also be specified for * lower and upper bound individually. * *

* Does not support facet extraction. * *

Name:

* rangeproperty * *

Properties:

*
*
property
relative path to property
*
lowerBound
lower bound to check property for
*
lowerOperation
">" (default) or ">=", applies to the lowerValue
*
upperBound
upper bound to check property for
*
upperOperation
"<" (default) or "<=", applies to the lowerValue
*
decimal
"true" if the checked property is of type Decimal
*
* * @since 5.2 */ @Component(metatype = false, factory = "com.day.cq.search.eval.PredicateEvaluator/rangeproperty") public class RangePropertyPredicateEvaluator extends AbstractPredicateEvaluator { private static final Logger log = LoggerFactory.getLogger(RangePropertyPredicateEvaluator.class); public static final String PROPERTY = "property"; public static final String LOWER_BOUND = "lowerBound"; public static final String LOWER_OPERATION = "lowerOperation"; public static final String UPPER_BOUND = "upperBound"; public static final String UPPER_OPERATION = "upperOperation"; public static final String PROPERTY_DECIMAL = "decimal"; @Override public String getXPathExpression(Predicate p, EvaluationContext context) { if (p.getBool(PROPERTY_DECIMAL)) return null; return getXPathExpression(p.get(PROPERTY), p.get(LOWER_BOUND), p.get(LOWER_OPERATION), p.get(UPPER_BOUND), p.get(UPPER_OPERATION)); } protected String getXPathExpression(String property, String lowerValue, String lowerOperation, String upperValue, String upperOperation) { StringBuffer buffer = new StringBuffer(); if (lowerValue != null) { String op = lowerOperation; if (!">".equals(op) && !">=".equals(op)) { op = ">"; // default } buffer.append(XPath.getPropertyPath(property)).append(" ").append(op).append(" ").append(lowerValue); } if (upperValue != null) { if (buffer.length() > 1) { buffer.append(" and "); } String op = upperOperation; if (!"<".equals(op) && !"<=".equals(op)) { op = "<"; // default } buffer.append(XPath.getPropertyPath(property)).append(" ").append(op).append(" ").append(upperValue); } if (buffer.length() > 0) { return "(" + buffer.toString() + ")"; } else { return null; } } @Override public String[] getOrderByProperties(Predicate p, EvaluationContext context) { return new String[] { p.get(PROPERTY) }; } @Override public boolean canXpath(Predicate p, EvaluationContext context) { return !p.getBool(PROPERTY_DECIMAL); } @Override public boolean canFilter(Predicate p, EvaluationContext context) { return true; } @Override public boolean includes(final Predicate p, final Row row, final EvaluationContext context) { return includes(context.getNode(row), p.get(PROPERTY), p.get(LOWER_BOUND), p.get(LOWER_OPERATION), p.get(UPPER_BOUND), p.get(UPPER_OPERATION), p.getBool(PROPERTY_DECIMAL)); } protected boolean includes(final Node node, final String property, final String lowerValue, final String lowerOperation, final String upperValue, final String upperOperation, final boolean decimal) { if (property == null || property.length() == 0 || ((lowerValue == null || lowerValue.length() == 0) && (upperValue == null || upperValue.length() == 0))) { return true; } String path = null; try { path = node.getPath(); if (!node.hasProperty(property)) { return false; } final Property nodeProperty = node.getProperty(property); if (decimal) { if (nodeProperty.getType() != PropertyType.DECIMAL) return false; if (lowerValue != null) { final BigDecimal bdLowerValue = new BigDecimal(lowerValue); if (nodeProperty.isMultiple()) { boolean match = false; for (Value value: nodeProperty.getValues()) { if ((">=".equals(lowerOperation) && value.getDecimal().compareTo(bdLowerValue) >= 0) || (!">=".equals(lowerOperation) && value.getDecimal().compareTo(bdLowerValue) > 0)) { match = true; break; } } if (!match) return false; } else if ((">=".equals(lowerOperation) && nodeProperty.getDecimal().compareTo(bdLowerValue) < 0) || (!">=".equals(lowerOperation) && nodeProperty.getDecimal().compareTo(bdLowerValue) <= 0)) { return false; } } if (upperValue != null) { final BigDecimal bdUpperValue = new BigDecimal(upperValue); if (nodeProperty.isMultiple()) { boolean match = false; for (Value value: nodeProperty.getValues()) { if (("<=".equals(upperOperation) && value.getDecimal().compareTo(bdUpperValue) <= 0) || (!"<=".equals(upperOperation) && value.getDecimal().compareTo(bdUpperValue) < 0)) { match = true; break; } } if (!match) return false; } else if (("<=".equals(upperOperation) && nodeProperty.getDecimal().compareTo(bdUpperValue) > 0) || (!"<=".equals(upperOperation) && nodeProperty.getDecimal().compareTo(bdUpperValue) >= 0)) { return false; } } } else { boolean longValue = false; boolean doubleValue = false; long lLowerValue = 0; long lUpperValue = 0; double dLowerValue = 0; double dUpperValue = 0; try { if (lowerValue != null) lLowerValue = Long.parseLong(lowerValue); if (upperValue != null) lUpperValue = Long.parseLong(upperValue); longValue = true; } catch (NumberFormatException e) { try { if (lowerValue != null) dLowerValue = Double.parseDouble(lowerValue); if (upperValue != null) dUpperValue = Double.parseDouble(upperValue); doubleValue = true; } catch (NumberFormatException e2) { log.warn("invalid values for rangeproperty includes <{},{}>", lowerValue, upperValue); return true; } } if (longValue) { if (nodeProperty.getType() != PropertyType.LONG) return false; if (lowerValue != null) { if (nodeProperty.isMultiple()) { boolean match = false; for (Value value: nodeProperty.getValues()) { if ((">=".equals(lowerOperation) && value.getLong() >= lLowerValue) || (!">=".equals(lowerOperation) && value.getLong() > lLowerValue)) { match = true; break; } } if (!match) return false; } else if ((">=".equals(upperOperation) && nodeProperty.getLong() < lUpperValue) || (!">".equals(upperOperation) && nodeProperty.getLong() <= lUpperValue)) { return false; } } if (upperValue != null) { if (nodeProperty.isMultiple()) { boolean match = false; for (Value value: nodeProperty.getValues()) { if (("<=".equals(upperOperation) && value.getLong() <= lUpperValue) || (!"<=".equals(upperOperation) && value.getLong() < lUpperValue)) { match = true; break; } } if (!match) return false; } else if (("<=".equals(upperOperation) && nodeProperty.getLong() > lUpperValue) || (!"<=".equals(upperOperation) && nodeProperty.getLong() >= lUpperValue)) { return false; } } } else if (doubleValue) { if (nodeProperty.getType() != PropertyType.DOUBLE) return false; if (lowerValue != null) { if (nodeProperty.isMultiple()) { boolean match = false; for (Value value: nodeProperty.getValues()) { if ((">=".equals(lowerOperation) && value.getDouble() >= dLowerValue) || (!">=".equals(lowerOperation) && value.getDouble() > dLowerValue)) { match = true; break; } } if (!match) return false; } else if ((">=".equals(lowerOperation) && nodeProperty.getDouble() < dLowerValue) || (!">=".equals(lowerOperation) && nodeProperty.getDouble() <= dLowerValue)) { return false; } } if (upperValue != null) { if (nodeProperty.isMultiple()) { boolean match = false; for (Value value: nodeProperty.getValues()) { if (("<=".equals(upperOperation) && value.getDouble() <= dUpperValue) || (!"<=".equals(upperOperation) && value.getDouble() < dUpperValue)) { match = true; break; } } if (!match) return false; } else if (("<=".equals(upperOperation) && nodeProperty.getDouble() > dUpperValue) || (!"<=".equals(upperOperation) && nodeProperty.getDouble() >= dUpperValue)) { return false; } } } } } catch (ValueFormatException e) { log.warn("Could not evaluate range: property = '" + property + "', node = '" + path + "'", e); } catch (RepositoryException e) { throw new RuntimeException("Could not evaluate range: property = '" + property + "', node = '" + path + "'", e); } return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy