/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.search.builder; import java.util.Date; import org.apache.commons.lang.StringUtils; import com.enonic.cms.core.search.ElasticSearchFormatter; public class ContentIndexOrderbyValueResolver { public static String getOrderbyValue( Object value ) { if ( value == null ) { return null; } if ( value instanceof Number ) { return getNumericOrderBy( (Number) value ); } if ( value instanceof Date ) { return getOrderbyValueForDate( (Date) value ); } final Double doubleValue = ContentIndexNumberValueResolver.resolveNumberValue( value ); if ( doubleValue != null ) { return getNumericOrderBy( doubleValue ); } return getOrderbyValueForString( value.toString() ); } private static String getNumericOrderBy( Number value ) { if ( value instanceof Double ) { return doubleToPrefixCoded( (Double) value ); } if ( value instanceof Float ) { return floatToPrefixCoded( (Float) value ); } if ( value instanceof Long ) { return longToPrefixCoded( (Long) value ); } return intToPrefixCoded( value.intValue() ); } private static String getOrderbyValueForDate( Date value ) { return ElasticSearchFormatter.formatDateAsStringFull( value ); } private static String getOrderbyValueForString( String value ) { return StringUtils.lowerCase( value ); } private static String doubleToPrefixCoded( double val ) { return longToPrefixCoded( org.apache.lucene.util.NumericUtils.doubleToSortableLong( val ) ); } private static String floatToPrefixCoded( float val ) { return intToPrefixCoded( org.apache.lucene.util.NumericUtils.floatToSortableInt( val ) ); } private static String longToPrefixCoded( final long val ) { return longToPrefixCoded( val, 0 ); } private static String longToPrefixCoded( final long val, final int shift ) { final char[] buffer = new char[org.apache.lucene.util.NumericUtils.BUF_SIZE_LONG]; final int len = longToPrefixCoded( val, shift, buffer ); return new String( buffer, 0, len ); } private static int longToPrefixCoded( final long val, final int shift, final char[] buffer ) { if ( shift > 63 || shift < 0 ) { throw new IllegalArgumentException( "Illegal shift value, must be 0..63" ); } int nChars = ( 63 - shift ) / 7 + 1, len = nChars + 1; buffer[0] = (char) ( org.apache.lucene.util.NumericUtils.SHIFT_START_LONG + shift ); long sortableBits = val ^ 0x8000000000000000L; sortableBits >>>= shift; while ( nChars >= 1 ) { // Store 7 bits per character for good efficiency when UTF-8 encoding. // The whole number is right-justified so that lucene can prefix-encode // the terms more efficiently. buffer[nChars--] = (char) ( sortableBits & 0x7f ); sortableBits >>>= 7; } return len; } private static String intToPrefixCoded( final int val ) { return intToPrefixCoded( val, 0 ); } private static String intToPrefixCoded( final int val, final int shift ) { final char[] buffer = new char[org.apache.lucene.util.NumericUtils.BUF_SIZE_INT]; final int len = intToPrefixCoded( val, shift, buffer ); return new String( buffer, 0, len ); } private static int intToPrefixCoded( final int val, final int shift, final char[] buffer ) { if ( shift > 31 || shift < 0 ) { throw new IllegalArgumentException( "Illegal shift value, must be 0..31" ); } int nChars = ( 31 - shift ) / 7 + 1, len = nChars + 1; buffer[0] = (char) ( org.apache.lucene.util.NumericUtils.SHIFT_START_INT + shift ); int sortableBits = val ^ 0x80000000; sortableBits >>>= shift; while ( nChars >= 1 ) { // Store 7 bits per character for good efficiency when UTF-8 encoding. // The whole number is right-justified so that lucene can prefix-encode // the terms more efficiently. buffer[nChars--] = (char) ( sortableBits & 0x7f ); sortableBits >>>= 7; } return len; } }