/**
* License Agreement for OpenSearchServer
*
* Copyright (C) 2008-2014 Emmanuel Keller / Jaeksoft
*
* http://www.open-search-server.com
*
* This file is part of OpenSearchServer.
*
* OpenSearchServer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenSearchServer 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenSearchServer.
* If not, see <http://www.gnu.org/licenses/>.
**/
package com.jaeksoft.searchlib.filter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import javax.xml.xpath.XPathExpressionException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Version;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import com.jaeksoft.searchlib.SearchLibException;
import com.jaeksoft.searchlib.crawler.common.database.TimeInterval;
import com.jaeksoft.searchlib.query.ParseException;
import com.jaeksoft.searchlib.request.AbstractLocalSearchRequest;
import com.jaeksoft.searchlib.schema.SchemaField;
import com.jaeksoft.searchlib.util.DomUtils;
import com.jaeksoft.searchlib.util.Timer;
import com.jaeksoft.searchlib.util.XPathParser;
import com.jaeksoft.searchlib.util.XmlWriter;
import com.jaeksoft.searchlib.web.ServletTransaction;
import com.jaeksoft.searchlib.webservice.query.search.SearchQueryAbstract.OperatorEnum;
public class RelativeDateFilter extends FilterAbstract<RelativeDateFilter> {
private final TimeInterval from;
private final TimeInterval to;
private String field;
private String dateFormat;
private transient SimpleDateFormat simpleDateFormat;
private transient Query query;
private transient String cachedQueryString;
public RelativeDateFilter(TimeInterval from, TimeInterval to, String field,
String dateFormat, boolean negative, Source src,
String paramPosition) {
super(FilterType.RELATIVE_DATE_FILTER, src, negative, paramPosition);
query = null;
this.from = from == null ? new TimeInterval() : from;
this.to = to == null ? new TimeInterval() : to;
this.field = field;
this.dateFormat = dateFormat;
simpleDateFormat = null;
}
public RelativeDateFilter() {
this(null, null, null, null, false, Source.REQUEST, null);
}
public RelativeDateFilter(XPathParser xpp, Node node)
throws XPathExpressionException {
this(new TimeInterval(DomUtils.getAttributeText(node, "from")),
new TimeInterval(DomUtils.getAttributeText(node, "to")),
DomUtils.getAttributeText(node, "field"), DomUtils
.getAttributeText(node, "dateFormat"), "yes"
.equals(XPathParser
.getAttributeString(node, "negative")),
Source.CONFIGXML, null);
}
private String getQueryString() {
long l = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
if (field != null && field.length() > 0) {
sb.append(field);
sb.append(':');
}
if (simpleDateFormat == null)
if (dateFormat != null && dateFormat.length() > 0)
simpleDateFormat = new SimpleDateFormat(dateFormat);
if (simpleDateFormat == null)
return sb.toString();
sb.append('[');
synchronized (simpleDateFormat) {
sb.append(simpleDateFormat.format(from.getPastDate(l)));
sb.append(" TO ");
sb.append(simpleDateFormat.format(to.getPastDate(l)));
}
sb.append("]");
return sb.toString();
}
private Query getQuery(SchemaField defaultField, Analyzer analyzer)
throws ParseException {
String queryString = getQueryString();
if (query != null)
if (queryString.equals(cachedQueryString))
return query;
QueryParser queryParser = new QueryParser(Version.LUCENE_36,
defaultField.getName(), analyzer);
queryParser.setLowercaseExpandedTerms(false);
try {
query = queryParser.parse(queryString);
} catch (org.apache.lucene.queryParser.ParseException e) {
throw new ParseException(e);
}
return query;
}
@Override
public String getDescription() {
StringBuilder sb = new StringBuilder("Date query filter: ");
sb.append(getQueryString());
return sb.toString();
}
@Override
public String getCacheKey(SchemaField defaultField, Analyzer analyzer,
AbstractLocalSearchRequest request) throws ParseException {
return "QueryFilter - " + getQuery(defaultField, analyzer).toString();
}
@Override
public void writeXmlConfig(XmlWriter xmlWriter) throws SAXException {
xmlWriter.startElement("relativeDateFilter", "field", field, "from",
from.getByText(), "to", to.getByText(), "dateFormat",
dateFormat, "negative", isNegative() ? "yes" : "no");
xmlWriter.endElement();
}
@Override
public FilterHits getFilterHits(SchemaField defaultField,
Analyzer analyzer, AbstractLocalSearchRequest request, Timer timer)
throws ParseException, IOException, SearchLibException {
Query query = getQuery(defaultField, analyzer);
return new FilterHits(
getResult(request.getConfig(), query, null, timer),
isNegative(), timer);
}
@Override
public RelativeDateFilter duplicate() {
return new RelativeDateFilter(new TimeInterval(from), new TimeInterval(
to), field, dateFormat, isNegative(), getSource(),
getParamPosition());
}
@Override
public void copyTo(FilterAbstract<?> selectedItem) {
if (!(selectedItem instanceof RelativeDateFilter))
throw new RuntimeException("Wrong filter type "
+ selectedItem.getClass().getName());
super.copyTo(selectedItem);
RelativeDateFilter copyTo = (RelativeDateFilter) selectedItem;
copyTo.field = field;
copyTo.dateFormat = dateFormat;
copyTo.from.set(from);
copyTo.to.set(to);
}
@Override
final public void setFromServlet(final ServletTransaction transaction,
final String prefix) {
}
@Override
final public void setParam(final String param) throws SearchLibException {
}
/**
* @return the field
*/
public String getField() {
return field;
}
/**
* @param field
* the field to set
*/
public void setField(String field) {
this.field = field;
}
/**
* @return the dateFormat
*/
public String getDateFormat() {
return dateFormat;
}
/**
* @param dateFormat
* the dateFormat to set
*/
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
/**
* @return the from
*/
public TimeInterval getFrom() {
return from;
}
/**
* @return the to
*/
public TimeInterval getTo() {
return to;
}
@Override
public void reset() {
query = null;
}
@Override
public OperatorEnum getOperator(OperatorEnum defaultOperator) {
return defaultOperator;
}
}