blob: 557c605c159836b120c03ad306bd32bef22ed6c7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.queryparser.flexible.standard.processors;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.DateTools.Resolution;
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
import org.apache.lucene.queryparser.flexible.core.config.FieldConfig;
import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
/**
* This processors process {@link TermRangeQueryNode}s. It reads the lower and
* upper bounds value from the {@link TermRangeQueryNode} object and try
* to parse their values using a {@link DateFormat}. If the values cannot be
* parsed to a date value, it will only create the {@link TermRangeQueryNode}
* using the non-parsed values. <br>
* <br>
* If a {@link ConfigurationKeys#LOCALE} is defined in the
* {@link QueryConfigHandler} it will be used to parse the date, otherwise
* {@link Locale#getDefault()} will be used. <br>
* <br>
* If a {@link ConfigurationKeys#DATE_RESOLUTION} is defined and the
* {@link Resolution} is not <code>null</code> it will also be used to parse the
* date value.
*
* @see ConfigurationKeys#DATE_RESOLUTION
* @see ConfigurationKeys#LOCALE
* @see TermRangeQueryNode
*/
public class TermRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
public TermRangeQueryNodeProcessor() {
// empty constructor
}
@Override
protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
if (node instanceof TermRangeQueryNode) {
TermRangeQueryNode termRangeNode = (TermRangeQueryNode) node;
FieldQueryNode upper = termRangeNode.getUpperBound();
FieldQueryNode lower = termRangeNode.getLowerBound();
DateTools.Resolution dateRes = null;
boolean inclusive = false;
Locale locale = getQueryConfigHandler().get(ConfigurationKeys.LOCALE);
if (locale == null) {
locale = Locale.getDefault();
}
TimeZone timeZone = getQueryConfigHandler().get(ConfigurationKeys.TIMEZONE);
if (timeZone == null) {
timeZone = TimeZone.getDefault();
}
CharSequence field = termRangeNode.getField();
String fieldStr = null;
if (field != null) {
fieldStr = field.toString();
}
FieldConfig fieldConfig = getQueryConfigHandler()
.getFieldConfig(fieldStr);
if (fieldConfig != null) {
dateRes = fieldConfig.get(ConfigurationKeys.DATE_RESOLUTION);
}
if (termRangeNode.isUpperInclusive()) {
inclusive = true;
}
String part1 = lower.getTextAsString();
String part2 = upper.getTextAsString();
try {
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
df.setLenient(true);
if (part1.length() > 0) {
Date d1 = df.parse(part1);
part1 = DateTools.dateToString(d1, dateRes);
lower.setText(part1);
}
if (part2.length() > 0) {
Date d2 = df.parse(part2);
if (inclusive) {
// The user can only specify the date, not the time, so make sure
// the time is set to the latest possible time of that date to
// really
// include all documents:
Calendar cal = Calendar.getInstance(timeZone, locale);
cal.setTime(d2);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
d2 = cal.getTime();
}
part2 = DateTools.dateToString(d2, dateRes);
upper.setText(part2);
}
} catch (Exception e) {
// not a date
Analyzer analyzer = getQueryConfigHandler().get(ConfigurationKeys.ANALYZER);
if (analyzer != null) {
// because we call utf8ToString, this will only work with the default TermToBytesRefAttribute
part1 = analyzer.normalize(lower.getFieldAsString(), part1).utf8ToString();
part2 = analyzer.normalize(lower.getFieldAsString(), part2).utf8ToString();
lower.setText(part1);
upper.setText(part2);
}
}
}
return node;
}
@Override
protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
return node;
}
@Override
protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
throws QueryNodeException {
return children;
}
}