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(); } }