/**
* Copyright (c) 2012, The National Archives <pronom@nationalarchives.gsi.gov.uk>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the The National Archives nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.gov.nationalarchives.droid.core.interfaces.filter;
import java.util.Date;
import org.joda.time.DateMidnight;
import uk.gov.nationalarchives.droid.core.interfaces.filter.expressions.Criterion;
import uk.gov.nationalarchives.droid.core.interfaces.filter.expressions.Restrictions;
/**
* MApping between Criterion Fields and EJBQL.
* @author rflitcroft
*
*/
public final class RestrictionFactory {
private RestrictionFactory() { }
// CHECKSTYLE:OFF (TODO: switch statement causes cyclomatic complexity - better to refactor)
public static Criterion forFilterCriterion(FilterCriterion criterion) {
// CHECKSTYLE:ON
// Dates need special handling since they are ranges.
if (criterion.getValue() instanceof Date) {
return forDateCriterion(criterion);
}
final CriterionFieldEnum field = criterion.getField();
String propertyName = field.getPropertyName();
// if (field.ordinal() >= CriterionFieldEnum.PUID.ordinal()) {
// propertyName = "format." + field.getPropertyName();
// }
Criterion restriction;
final Object value = criterion.getValue();
switch (criterion.getOperator()) {
case EQ:
restriction = Restrictions.eq(propertyName, value);
break;
case NE:
restriction = Restrictions.neq(propertyName, value);
break;
case GT:
restriction = Restrictions.gt(propertyName, value);
break;
case GTE:
restriction = Restrictions.gte(propertyName, value);
break;
case LT:
restriction = Restrictions.lt(propertyName, value);
break;
case LTE:
restriction = Restrictions.lte(propertyName, value);
break;
case ANY_OF:
restriction = Restrictions.in(propertyName, (Object[]) value);
break;
case CONTAINS:
restriction = Restrictions.like(propertyName, '%' + (String) value + '%');
break;
case ENDS_WITH:
restriction = Restrictions.like(propertyName, '%' + (String) value);
break;
case STARTS_WITH:
restriction = Restrictions.like(propertyName, (String) value + '%');
break;
case NOT_CONTAINS:
restriction = Restrictions.notLike(propertyName, '%' + (String) value + '%');
break;
case NOT_ENDS_WITH:
restriction = Restrictions.notLike(propertyName, '%' + (String) value);
break;
case NOT_STARTS_WITH:
restriction = Restrictions.notLike(propertyName, (String) value + '%');
break;
case NONE_OF:
restriction = Restrictions.notIn(propertyName, (Object[]) value);
break;
default:
throw new IllegalArgumentException(
String.format("Invalid operator [%s]", criterion.getOperator()));
}
return restriction;
}
/**
* Dates need special handling!
* @param dateCriterion the date criterion
* @return the date criterion
*/
private static Criterion forDateCriterion(FilterCriterion dateCriterion) {
final CriterionFieldEnum field = dateCriterion.getField();
final Date dateValue = (Date) dateCriterion.getValue();
Date from = new DateMidnight(dateValue).toDate();
Date to = new DateMidnight(dateValue).plusDays(1).toDate();
String propertyName = field.getPropertyName();
Criterion criterion;
switch (dateCriterion.getOperator()) {
case EQ:
criterion = Restrictions.and(Restrictions.gte(propertyName, from), Restrictions.lt(propertyName, to));
break;
case NE:
criterion = Restrictions.or(Restrictions.lt(propertyName, from), Restrictions.gte(propertyName, to));
break;
case LT:
criterion = Restrictions.lt(propertyName, from);
break;
case LTE:
criterion = Restrictions.lt(propertyName, to);
break;
case GT:
criterion = Restrictions.gte(propertyName, to);
break;
case GTE:
criterion = Restrictions.gte(propertyName, from);
break;
default:
throw new IllegalArgumentException(
String.format("Invalid operator for date [%s]", dateCriterion.getOperator()));
}
return criterion;
}
}