
com.day.cq.search.eval.RelativeDateRangePredicateEvaluator Maven / Gradle / Ivy
/*
* Copyright 1997-2009 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.GregorianCalendar;
import java.util.Scanner;
import com.day.cq.search.Predicate;
import org.apache.felix.scr.annotations.Component;
/**
* RelativeDateRangePredicateEvaluator
is an extension of the
* {@link DateRangePredicateEvaluator} that does not use absolute UNIX
* timestamps for lowerBound
and upperBound
, but
* relative offsets to the current server time. If you only specify either one,
* the default value will be 0, indicating now.
*
*
* It also supports the bugzilla syntax 1s 2m 3h 4d 5w 6M 7y (one second, two
* minutes, three hours, four days, five weeks, 6 months, 7 years). It does not
* take leap years into consideration and all months are 30 days.
*
*
* Note: Does not implement filtering, which means this predicate
* cannot be used together with filter-only predicates in an OR group.
*
*
* upperBound=3600000
* - In the next hour
* lowerBound=-86400000
* - In the last day
* lowerBound=86400000
, upperBound=172800000
* - The day after tomorrow
*
*
* Name:
* relativedaterange
*/
@Component(metatype = false, factory = "com.day.cq.search.eval.PredicateEvaluator/relativedaterange")
public class RelativeDateRangePredicateEvaluator extends
DateRangePredicateEvaluator {
@Override
public String getXPathExpression(final Predicate p, final EvaluationContext context) {
//get a new predicate that we can modify
Predicate modifiedPredicate = p.clone();
//what time is it now
long now = new GregorianCalendar().getTimeInMillis();
//default values for lower bound and upper bound offset
long upperBound = 0;
long lowerBound = 0;
//try to parse values, fallback to 0 if it fails
//calculate the offset
//modify the predicate
try {
upperBound = parseDateRange(p.get(UPPER_BOUND));
upperBound += now;
modifiedPredicate.set(UPPER_BOUND, "" + upperBound);
} catch (Exception nfe) {
modifiedPredicate.set(UPPER_BOUND, null);
}
try {
lowerBound = parseDateRange(p.get(LOWER_BOUND));
lowerBound += now;
modifiedPredicate.set(LOWER_BOUND, "" + lowerBound);
} catch (Exception nfe) {
modifiedPredicate.set(LOWER_BOUND, null);
}
//let the super class handle the complicated XPath stuff
return super.getXPathExpression(modifiedPredicate, context);
}
public long parseDateRange(String daterange) throws NumberFormatException {
if ((daterange==null)||(daterange.length()==0)) {
throw new NumberFormatException("cannot parse empty string");
} else if (daterange.matches("^(-)?\\d+$")) {
return Long.parseLong(daterange);
}
String cleandaterange = daterange.replaceAll("[^dsmhdwMy\\d-]", "");
boolean negative = cleandaterange.matches("^-.*");
cleandaterange = cleandaterange.replaceAll("-", "");
if (!cleandaterange.matches("^(\\d+\\w)+$")) {
throw new NumberFormatException("only s, m, h, d, w, M, y are allowed modifiers");
}
cleandaterange = cleandaterange.replaceAll("(\\d+)(\\w)", "$1 $2 ");
Scanner scanner = new Scanner(cleandaterange);
long value = 0;
while (scanner.hasNext()) {
long number = scanner.nextLong();
String unit = scanner.next();
if ("s".equals(unit)) {
value += number * 1000;
} else if ("m".equals(unit)) {
// minute
value += number * 60 * 1000;
} else if ("h".equals(unit)) {
value += number * 60 * 60 * 1000;
} else if ("d".equals(unit)) {
value += number * 24 * 60 * 60 * 1000;
} else if ("w".equals(unit)) {
value += number * 7 * 24 * 60 * 60 * 1000;
} else if ("M".equals(unit)) {
// month
value += number * 30 * 24 * 60 * 60 * 1000;
} else if ("y".equals(unit)) {
value += number * 365 * 24 * 60 * 60 * 1000;
}
}
if (negative) {
value *= -1;
}
return value;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy