/* * eXist Open Source Native XML Database * Copyright (C) 2014 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * $Id$ */ package org.exist.indexing.range.conversion; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.document.Field; import org.apache.lucene.document.LongField; import org.exist.indexing.range.RangeIndexConfigElement; import org.exist.xquery.XPathException; import org.exist.xquery.value.DateValue; import org.exist.xquery.value.TimeUtils; import javax.xml.datatype.XMLGregorianCalendar; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Simple normalization of dates: if there is only a year, transform it into a date: yyy-01-01. * If full date is given, but with missing digits: fill them in. */ public class DateConverter implements TypeConverter { protected static final Logger LOG = LogManager.getLogger(DateConverter.class); private final static Pattern DATE_REGEX = Pattern.compile("(-?\\d+)-(\\d+)-(\\d+)"); @Override public Field toField(String fieldName, String content) { try { DateValue dv; if (content.indexOf('-') < 1) { // just year int year = Integer.parseInt(content); XMLGregorianCalendar calendar = TimeUtils.getInstance().newXMLGregorianCalendar(); calendar.setYear(year); calendar.setDay(1); calendar.setMonth(1); dv = new DateValue(calendar); } else { // try to handle missing digits as in 1980-8-4 Matcher matcher = DATE_REGEX.matcher(content); if (matcher.matches()) { try { int year = Integer.parseInt(matcher.group(1)); content = (year < 0 ? "-" : "") + String.format("%04d-%02d-%02d", Math.abs(year), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3))); } catch (NumberFormatException e) { // invalid content: ignore } } dv = new DateValue(content); } final long dl = RangeIndexConfigElement.dateToLong(dv); return new LongField(fieldName, dl, LongField.TYPE_NOT_STORED); } catch (XPathException e) { // wrong type: ignore LOG.debug("Invalid date format: " + content, e); } catch (NumberFormatException e) { // wrong type: ignore LOG.debug("Invalid date format: " + content, e); } catch (Exception e) { LOG.debug("Invalid date format: " + content, e); } return null; } }