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

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;
        }
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy