/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2011, Red Hat, Inc. and/or its affiliates or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat, Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.hibernate.search.query.dsl.impl; import java.util.Date; import org.apache.lucene.search.NumericRangeQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermRangeQuery; import org.hibernate.annotations.common.AssertionFailure; import org.hibernate.search.bridge.spi.ConversionContext; import org.hibernate.search.bridge.util.impl.ContextualExceptionBridgeHelper; import org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity; import org.hibernate.search.query.facet.RangeFacet; /** * @author Hardy Ferentschik */ public class RangeFacetImpl<T> extends AbstractFacet implements RangeFacet<T> { /** * The facet range, speak the min and max values for this range facet */ private final FacetRange<T> range; /** * The index of the specified ranges */ private final int rangeIndex; /** * The document builder. */ private final DocumentBuilderIndexedEntity<?> documentBuilder; RangeFacetImpl(String facetingName, String fieldName, FacetRange<T> range, int count, int index, DocumentBuilderIndexedEntity<?> documentBuilder) { super( facetingName, fieldName, range.getRangeString(), count ); this.range = range; this.rangeIndex = index; this.documentBuilder = documentBuilder; } @Override public Query getFacetQuery() { Object minOrMax = getNonNullMinOrMax( range ); if ( minOrMax instanceof Number ) { return createNumericRangeQuery(); } else if ( minOrMax instanceof String ) { return createRangeQuery( (String) range.getMin(), (String) range.getMax(), range.isMinIncluded(), range.isMaxIncluded() ); } else if ( minOrMax instanceof Date ) { final ConversionContext conversionContext = new ContextualExceptionBridgeHelper(); return createRangeQuery( documentBuilder.objectToString( getFieldName(), range.getMin(), conversionContext ), documentBuilder.objectToString( getFieldName(), range.getMax(), conversionContext ), range.isMinIncluded(), range.isMaxIncluded() ); } else { throw new AssertionFailure( "Unsupported range type" ); } } public int getRangeIndex() { return rangeIndex; } public T getMin() { return range.getMin(); } public T getMax() { return range.getMax(); } public boolean isIncludeMin() { return range.isMinIncluded(); } public boolean isIncludeMax() { return range.isMaxIncluded(); } private Object getNonNullMinOrMax(FacetRange<T> range) { Object o = range.getMin(); if ( o == null ) { o = range.getMax(); } return o; } private Query createNumericRangeQuery() { NumericRangeQuery query; // either end of the range must have a valid value (see also HSEARCH-770) Object minOrMax = getNonNullMinOrMax( range ); if ( minOrMax instanceof Double ) { query = NumericRangeQuery.newDoubleRange( getFieldName(), (Double) range.getMin(), (Double) range.getMax(), range.isMinIncluded(), range.isMaxIncluded() ); } else if ( minOrMax instanceof Float ) { query = NumericRangeQuery.newFloatRange( getFieldName(), (Float) range.getMin(), (Float) range.getMax(), range.isMinIncluded(), range.isMaxIncluded() ); } else if ( minOrMax instanceof Integer ) { query = NumericRangeQuery.newIntRange( getFieldName(), (Integer) range.getMin(), (Integer) range.getMax(), range.isMinIncluded(), range.isMaxIncluded() ); } else if ( minOrMax instanceof Long ) { query = NumericRangeQuery.newLongRange( getFieldName(), (Long) range.getMin(), (Long) range.getMax(), range.isMinIncluded(), range.isMaxIncluded() ); } else { throw new AssertionFailure( "Unsupported range type" ); } return query; } private Query createRangeQuery(String min, String max, boolean includeMin, boolean includeMax) { return new TermRangeQuery( getFieldName(), min, max, includeMin, includeMax ); } }