/* * Copyright (c) 2009 Andrejs Jermakovics. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Andrejs Jermakovics - initial implementation */ package it.unibz.instasearch.indexing.querying; import it.unibz.instasearch.indexing.Field; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; import org.apache.commons.lang.math.NumberUtils; import org.apache.lucene.index.Term; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermRangeQuery; /** * Replaces named modified field values with millisecond range queries */ public class ModifiedTimeConverter extends QueryVisitor { private static ArrayList<String> intervalNames = new ArrayList<String>(); private static Calendar cal = Calendar.getInstance(); static { for(Interval interval: Interval.values()) intervalNames.add(interval.toString().toLowerCase(Locale.ENGLISH)); intervalNames.add("3 days"); // as an example, any number can be specified } private enum Interval { TODAY, YESTERDAY, HOUR(TimeUnit.HOURS.toMillis(1)), DAY(TimeUnit.DAYS.toMillis(1)), WEEK(TimeUnit.DAYS.toMillis(7)), MONTH(TimeUnit.DAYS.toMillis(30)) ; private long millis; Interval() { }; Interval(long millis) { this.millis = millis; } } public static List<String> getDurationNames() { return intervalNames; } /** * */ public ModifiedTimeConverter() { } @Override public Query visit(TermQuery termQuery, Field termField) { if( termField != Field.MODIFIED ) return super.visit(termQuery, termField); Term t = termQuery.getTerm(); String intervalName = t.text(); int multiplier = 1; if( intervalName.matches("^[0-9]+.*$") ) // e.g. "3 days" { String multiplierString = intervalName.replaceAll("[^0-9]+", ""); // remove non-digits multiplier = NumberUtils.toInt(multiplierString.trim(), 1); intervalName = intervalName.replaceAll("[0-9 ]+", "").trim(); // remove digits } if( intervalName.endsWith("s") ) intervalName = intervalName.substring(0, intervalName.length() - 1 ); Interval interval = getIntervalByName(intervalName); if( interval == null ) return super.visit(termQuery, termField); long start = 0, end = System.currentTimeMillis(); cal.setTimeInMillis(end); switch(interval) { case TODAY: cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); start = cal.getTimeInMillis(); break; case YESTERDAY: cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), 0, 0, 0); end = cal.getTimeInMillis(); cal.add(Calendar.DATE, -1); start = cal.getTimeInMillis(); break; default: start = end - multiplier * interval.millis; } String field = Field.MODIFIED.name().toLowerCase(Locale.ENGLISH); //NumericRangeQuery rangeQuery = NumericRangeQuery.newLongRange(field, start, end, true, true); return new TermRangeQuery(field, "" + start, "" + end, true, true); } private static Interval getIntervalByName(String intervalName) { try { return Interval.valueOf(intervalName.toUpperCase()); } catch(Throwable ignored) { return null; } } }