com.day.cq.search.facets.buckets.ValueRangeBucket 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.facets.buckets;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import com.day.cq.search.Predicate;
/**
* {@linkplain ValueRangeBucket} is a bucket that stands for an interval of
* values.
*
* @since 5.2
*/
public class ValueRangeBucket extends PredefinedBucket {
/**
* The lower bound of this bucket definition. If there is no lower bound
* then this value is null
.
*/
private final Comparable from;
/**
* The upper bound of this bucket definition. If there is no upper bound
* then this value is null
.
*/
private final Comparable to;
private boolean fromIncluded;
private boolean toIncluded;
/**
* Creates an interval matching bucket.
*
* @param name name of this bucket (for display)
* @param from lower end of interval
* @param fromIncluded if true
, will include the from value in the interval, ie. use >=
* @param to upper end of interval
* @param toIncluded if true
, will include the to value in the interval, ie. use <=
* @param predicate the predicate representing this bucket
*/
public ValueRangeBucket(String name, Comparable from, boolean fromIncluded, Comparable to, boolean toIncluded, Predicate predicate) {
super(predicate, name);
this.from = from;
this.to = to;
this.fromIncluded = fromIncluded;
this.toIncluded = toIncluded;
}
/**
* @return the lower bound or null
if none is set.
*/
public Comparable getFrom() {
return from;
}
/**
* @return the upper bound or null
if none is set.
*/
public Comparable getTo() {
return to;
}
/**
* Accepts the value
and increments the counter of this bucket
* if the value
matches this buckets definition.
*
* @param value the value to accept.
* @throws RepositoryException if an error occurs while reading from the
* repository.
*/
@Override
public void acceptValue(Value value) throws RepositoryException {
if (matches(valueToComparable(value))) {
increment();
}
}
protected Comparable valueToComparable(Value value) throws RepositoryException {
switch (value.getType()) {
case PropertyType.DATE:
return value.getLong();
case PropertyType.DOUBLE:
return value.getDouble();
case PropertyType.LONG:
return value.getLong();
default:
// anything else becomes string
return value.getString();
}
}
@SuppressWarnings({"unchecked"})
protected boolean matches(Comparable c) {
try {
Comparable value = coerce(c);
if (value == null) {
return false;
}
if (from == null && to == null) {
return true;
}
if (from != null) {
if (fromIncluded) {
// from == value would be a match
if (from.compareTo(value) > 0) {
return false; // from > value
}
} else {
if (from.compareTo(value) >= 0) {
return false; // from >= value
}
}
}
if (to != null) {
if (toIncluded) {
// to == value would be a match
if (to.compareTo(value) < 0) {
return false; // to < value
}
} else {
if (to.compareTo(value) <= 0) {
return false; // to <= value
}
}
}
return true;
} catch (ClassCastException e) {
return false;
}
}
/**
* Coerces the given value to the class of this range definition.
*
* @param value the value to coerce.
* @return the coerced value.
*/
private Comparable coerce(Comparable value) {
return coerceValue(from != null ? from.getClass() : to.getClass(), value);
}
/**
* Coerces the given value
into the given type
. If
* the value
cannot be coerced into the type
, then
* null
is returned.
*
* @param type the target type.
* @param value the value to coerce.
* @return the coerced value.
*/
protected Comparable coerceValue(Class type,
Comparable value) {
if (value.getClass() == type) {
return value;
}
if (type == Long.class) {
try {
return Long.parseLong(value.toString());
} catch (NumberFormatException e) {
return null;
}
} else if (type == Integer.class) {
try {
return Integer.parseInt(value.toString());
} catch (NumberFormatException e) {
return null;
}
} else if (type == Double.class) {
try {
return Double.parseDouble(value.toString());
} catch (NumberFormatException e) {
return null;
}
} else if (type == String.class) {
return value.toString();
} else {
return null;
}
}
}