/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.search.query;
import java.util.Date;
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.ReadableDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
/**
* This class implements the index value.
*/
public final class IndexValueConverter
{
private static final long SIGN_MASK = 0x8000000000000000L;
private static final int STRING_DOUBLE_LEN = Long.toString( Long.MAX_VALUE, Character.MAX_RADIX ).length() + 1;
private final static DateTimeFormatter FULL_DATE_FORMAT_WITH_TIME_ZONE = ISODateTimeFormat.dateTimeParser();
private final static DateTimeFormatter FULL_DATE_FORMAT = DateTimeFormat.forPattern( "yyyy-MM-dd'T'HH:mm:ss" );
private final static DateTimeFormatter DATE_FORMAT = DateTimeFormat.forPattern( "yyyy-MM-dd" );
private final static DateTimeFormatter DATETIME_WITH_SECS_FORMAT = DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ss" );
private final static DateTimeFormatter DATETIME_WITHOUT_SECS_FORMAT = DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm" );
// new format from CMS-2545
private final static DateTimeFormatter DATETIME_WITH_SECS_FORMAT_Z = DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ssZ" );
private final static DateTimeFormatter DATETIME_WITH_MILLISECS_FORMAT_WITHOUT_Z =
DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ss.SSS" );
private final static DateTimeFormatter DATETIME_WITH_MILLISECS_FORMAT_Z = DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ss.SSSZ" );
// new format from CMS-2545
private final static DateTimeFormatter DATETIME_WITHOUT_SECS_FORMAT_Z = DateTimeFormat.forPattern( "yyyy-MM-dd HH:mmZ" );
/**
* Private constructor.
*/
private IndexValueConverter()
{
}
public static String toString( long value )
{
return Long.toString( value );
}
public static String toString( double value )
{
return Double.toString( value );
}
public static String toString( Date value )
{
return value != null ? FULL_DATE_FORMAT.print( value.getTime() ) : null;
}
public static String toTypedString( Date value )
{
return value != null ? toTypedString( value.getTime() ) : null;
}
public static String toTypedString( double value )
{
long longValue = Double.doubleToLongBits( value );
StringBuffer sb = new StringBuffer( STRING_DOUBLE_LEN );
if ( ( longValue & SIGN_MASK ) == 0 )
{
String s = Long.toString( longValue, Character.MAX_RADIX );
sb.append( '1' );
while ( ( sb.length() + s.length() ) < STRING_DOUBLE_LEN )
{
sb.append( '0' );
}
sb.append( s );
}
else
{
longValue = -longValue;
String s = Long.toString( longValue, Character.MAX_RADIX );
while ( ( sb.length() + s.length() ) < STRING_DOUBLE_LEN )
{
sb.append( '0' );
}
sb.append( s );
}
return sb.toString().toLowerCase();
}
public static Double toDouble( String value )
{
try
{
Double num = new Double( value );
if ( num.isNaN() || num.isInfinite() )
{
return null;
}
else
{
return num;
}
}
catch ( NumberFormatException e )
{
return null;
}
}
public static ReadableDateTime toDate( String value )
{
value = value.toUpperCase();
// used in Queries as indicator for expressions like "myDate = '2013-05-05'"
// TODO move this hack outside.
final DateTime dateByDateFormat = toDateTime( value, DATE_FORMAT );
if ( dateByDateFormat != null )
{
// We use DateMidnight to later recognise that user have not specified time
return new DateMidnight( dateByDateFormat );
}
// hza: i do not know why we test for FULL_DATE_FORMAT but then parse using FULL_DATE_FORMAT_WITH_TIME_ZONE
final DateTime dateTimeByFullFormat = toDateTime( value, FULL_DATE_FORMAT );
if ( dateTimeByFullFormat != null )
{
final DateTime dateTimeByFullFormatTimeZone = toDateTime( value, FULL_DATE_FORMAT_WITH_TIME_ZONE );
if ( dateTimeByFullFormatTimeZone != null )
{
return dateTimeByFullFormatTimeZone;
}
return dateTimeByFullFormat;
}
final DateTimeFormatter[] dateTimeFormatterArray = new DateTimeFormatter[]{ //
DATETIME_WITH_SECS_FORMAT, //
DATETIME_WITHOUT_SECS_FORMAT, //
FULL_DATE_FORMAT_WITH_TIME_ZONE, //
DATETIME_WITH_SECS_FORMAT_Z, //
DATETIME_WITHOUT_SECS_FORMAT_Z, //
DATETIME_WITH_MILLISECS_FORMAT_Z, //
DATETIME_WITH_MILLISECS_FORMAT_WITHOUT_Z};
for ( final DateTimeFormatter dateTimeFormatter : dateTimeFormatterArray )
{
final DateTime dateTime = toDateTime( value, dateTimeFormatter );
if ( dateTime != null )
{
return dateTime;
}
}
return null;
}
private static DateTime toDateTime( String value, DateTimeFormatter format )
{
try
{
return format.parseDateTime( value );
}
catch ( IllegalArgumentException e )
{
return null;
}
}
}