it.unibz.instasearch.indexing.querying.ModifiedTimeConverter.java Source code

Java tutorial

Introduction

Here is the source code for it.unibz.instasearch.indexing.querying.ModifiedTimeConverter.java

Source

/*
 * 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.concurrent.TimeUnit;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;

/**
 * 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());

        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.DATE), 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();
        NumericRangeQuery rangeQuery = NumericRangeQuery.newLongRange(field, start, end, true, true);

        return rangeQuery;
    }

    private static Interval getIntervalByName(String intervalName) {
        try {
            return Interval.valueOf(intervalName.toUpperCase());
        } catch (Throwable ignored) {
            return null;
        }
    }
}