/*
 * $Id: ResultFilter.java,v 1.12 2006/09/29 21:10:08 marbobo Exp $
 * 
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: ResultFilter.java,v $
 * Revision 1.12  2006/09/29 21:10:08  marbobo
 * + Sucheoptimiert
 *
 * Revision 1.11  2006/05/27 18:34:47  marbobo
 * + Neueste Lucene-Version eingebaut
 *
 * Revision 1.10  2004/07/20 08:37:47  jonyp
 * added copyright info + cvs log
 *
 * Revision 1.9  2004/04/17 21:00:46  marbobo
 * + Suche im beliebigem Zeitraum
 *
 * Revision 1.8  2004/03/25 15:47:57  bigmac
 * validCategories enthält jetzt Integer-Objekte
 *
 * Revision 1.7  2004/03/25 01:52:47  marbobo
 * Suche nach Bestimmten Dokumenttypen gefixt (nochmal)
 *
 * Revision 1.6  2004/03/24 19:07:15  marbobo
 * Suche nach Bestimmten Dokumenttypen gefixt
 *
 * Revision 1.5  2003/11/11 11:55:30  teng
 * *** empty log message ***
 *
 * Revision 1.4  2003/10/08 09:18:08  lawern
 * Suchergebnisse werden jetzt nur noch auf Kategorieleserechte geprüft.
 *
 * Revision 1.3  2003/04/23 14:55:33  lawern
 * Ergänzungen für Volltextverarbeitung
 *
 * Revision 1.2  2003/04/15 07:26:38  lawern
 * Schnittstelle von Seach.search hat sich geändert.
 *
 * Revision 1.1  2003/04/02 12:04:01  lawern
 * initiale Version
 *
 */
package vkc.search;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.BitSet;
import java.util.Date;
import java.util.Set;

import org.apache.lucene.document.DateTools;
import org.apache.lucene.index.IndexReader;

/**
 * Klasse filtert die Suchergebnisse für eine Anfrage
 * 
 * <p></p>
 *
 * @author lawern
 */
public final class ResultFilter extends org.apache.lucene.search.Filter {
	public static PrintWriter out = null;

	long currentMillis = System.currentTimeMillis();

	Date from = null;
	Date until = null;
	
	Integer minCount = null;

	String documentType = "*";

	Set validCategories = null;
	Set validDocumentIds = null;

	/**
	 * Konstruktor
	 *
	 * @param u VKCUser, für den die Suchergbnisse gefiltert werden sollen
	 * @param from gibt den Zeitraum an, ab wann Dokumente gesucht
	 *        werden sollen
	 * @param until gibt den Zeitraum an, bis wann Dokumente gesucht
	 *        werden sollen
	 * @param documentType gibt an, welcher Dokumenttyp in der Trefferliste
	 *        auftreten darf. Falls documentType == -1, werden alle Typen
	 *        erlaubt. Ansonsten siehe ID-Konstanten der DB-Tabelle
	 *        DOCUMENTTYPES.
	 */
	public ResultFilter(Date from, Date until, String documentType, Set validCategories) {
		this.from = from;
		this.until = until;
		this.documentType = documentType;
		this.validCategories = validCategories;
	}

	/**
	 * Methode liefert ein BitSet zurück, das angibt welche Dokumente im
	 * Ergebnis auftauchen sollen. d.h., falls das i-te Bit gesetzt ist, wird
	 * das i-te Dokument im Index für die Suche zugelassen.
	 *
	 * @param reader - Reader für den Lesezugriff auf den aktuellen Index von
	 *        Lucene
	 */
	final public BitSet bits(IndexReader reader) throws IOException {
		int indexSize = reader.maxDoc();
		BitSet bits = new BitSet(indexSize);
		org.apache.lucene.document.Document doc = null;

		Date p = null;

		for (int i = 0; i < indexSize; i++) {
			try {
				doc = reader.document(i);

				if (validDocumentIds != null && !validDocumentIds.contains(new Integer(doc.get("documentId")))) {
					// prüfen ob das Dokument angezeigt werden soll
					continue;
				}

				if (validCategories != null && !validCategories.contains(new Integer(doc.get("categoryId")))) {
					// prüfen ob das Dokument dem Benutzer angezeigt werden darf
					continue;
				}

				if (minCount != null) {
					if (minCount.intValue() > Integer.parseInt(doc.get("accessCount"))) {
						continue;
					}
				}
				
				if (!"*".equalsIgnoreCase(documentType)) {
					// nur Dokumente mit passendem Typ zulassen
					if (!documentType.equalsIgnoreCase(doc.get("docTypeName"))) {
						// Dokumenttyp passt nicht
						continue;
					}
				}

				// nur Dokumente mit passendem Zeitraum zulassen
				if (from != null && until != null && until.compareTo(from) >= 0) {
					p = DateTools.stringToDate(doc.get("published"));

					if (p.compareTo(from) < 0 || p.compareTo(until) > 0) {
						// Dokument ist nicht im passendem Zeitraum
						continue;
					}
				} else if (from != null) {
					p = DateTools.stringToDate(doc.get("published"));

					if (p.compareTo(from) < 0) {
						// Dokument ist zu alt
						continue;
					}
				} else if (until != null) {
					p = DateTools.stringToDate(doc.get("published"));

					if (p.compareTo(until) > 0) {
						// Dokument ist zu neu
						continue;
					}
				}

				bits.set(i);
			} catch (Exception ex) {
				continue;
			}
		}

		return bits;
	}
}