package com.manning.hsia.dvdstore.bridge;
import java.util.Map;
import org.hibernate.search.bridge.ParameterizedBridge;
import org.hibernate.search.bridge.StringBridge;
/**
* Round a price by range of <code>round</code>, going to the upper boundaries
* pad the result with up to <code>pad</code> non-significant 0
* Accept double and Double
*
* Example 4.6
*/
public class ParameterizedPaddedRoundedPriceBridge implements StringBridge, ParameterizedBridge {
private int pad = 6; //price of 1,000,000 online seems like a decent default target
private double round = 1d; //by default round to the next non decimal amount
public void setParameterValues(Map parameters) { //parameters are injected in setParameterValues
if ( parameters.containsKey("pad") ) {
pad = Integer.parseInt( (String) parameters.get("pad") );
}
if ( parameters.containsKey("round") ) {
round = Double.parseDouble( (String) parameters.get("round") );
}
}
public String objectToString(Object value) {
if ( value == null ) return null;
if (value instanceof Double) {
long price = round( (Double) value );
return pad(price);
}
else {
throw new IllegalArgumentException(PaddedRoundedPriceBridge.class
+ " used one a non double type: " + value.getClass() );
}
}
private long round(double price) {
double rounded = Math.floor( price / round ) * round;
if ( rounded != price ) rounded+= round; //we round up
return (long) rounded;
}
private String pad(long price) {
String rawLong = Long.toString(price);
if (rawLong.length() > pad)
throw new IllegalArgumentException( "Try to pad on a number too big" );
StringBuilder paddedLong = new StringBuilder( );
for ( int padIndex = rawLong.length() ; padIndex < pad ; padIndex++ ) {
paddedLong.append('0');
}
return paddedLong.append( rawLong ).toString();
}
}