com.servicerocket.confluence.randombits.supplier.core.general.NumberSupplier Maven / Gradle / Ivy
package com.servicerocket.confluence.randombits.supplier.core.general;
import org.apache.commons.lang.StringUtils;
import com.servicerocket.confluence.randombits.supplier.core.annotate.*;
import org.randombits.utils.lang.API;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Date;
@SupplierPrefix("number")
@SupportedTypes(Number.class)
public class NumberSupplier extends AnnotatedSupplier {
public NumberSupplier() {
}
@SupplierKey("is decimal")
@API("1.0.0")
public boolean isDecimal( @KeyValue Number number ) {
return !isWhole( number );
}
@SupplierKey("is nan")
@API("1.0.0")
public boolean isNaN( @KeyValue Number number ) {
return Double.isNaN( number.doubleValue() );
}
@SupplierKey("to date")
@API("1.0.0")
public Date toDate( @KeyValue Number number ) {
return new Date( number.longValue() );
}
@SupplierKey("abs")
@API("1.0.0")
public Number abs( @KeyValue Number value ) {
if ( isWhole( value ) )
return Math.abs( value.longValue() );
else
return Math.abs( value.doubleValue() );
}
@SupplierKey("less than {number}")
@API("1.0.0")
public Boolean isLessThan( @KeyValue Number value, @KeyParam("number") String otherNumber ) {
try {
Number target = parseNumber( otherNumber );
if ( isWhole( value ) && isWhole( target ) ) {
return value.longValue() < target.longValue();
} else {
return value.doubleValue() < target.doubleValue();
}
} catch ( NumberFormatException e ) {
return Boolean.FALSE;
}
}
@SupplierKey("greater than {number}")
@API("1.0.0")
public Boolean isGreaterThan( @KeyValue Number value, @KeyParam("number") String number ) {
try {
Number target = parseNumber( number );
if ( isWhole( value ) && isWhole( target ) ) {
return value.longValue() > target.longValue();
} else {
return value.doubleValue() > target.doubleValue();
}
} catch ( NumberFormatException e ) {
return Boolean.FALSE;
}
}
@SupplierKey("+{number}")
@API("1.0.0")
public Number plus( @KeyValue Number value, @KeyParam("number") String number ) {
try {
Number target = parseNumber( number );
if ( isWhole( value ) && isWhole( target ) ) {
return value.longValue() + target.longValue();
} else {
return value.doubleValue() + target.doubleValue();
}
} catch ( NumberFormatException e ) {
return Double.NaN;
}
}
@SupplierKey("-{number}")
@API("1.0.0")
public Number minus( @KeyValue Number value, @KeyParam("number") String number ) {
try {
Number target = parseNumber( number );
if ( isWhole( value ) && isWhole( target ) ) {
return value.longValue() - target.longValue();
} else {
return value.doubleValue() - target.doubleValue();
}
} catch ( NumberFormatException e ) {
return Double.NaN;
}
}
@SupplierKey("*{number}")
@API("1.0.0")
public Number multiply( @KeyValue Number value, @KeyParam("number") String number ) {
try {
Number target = parseNumber( number );
if ( isWhole( value ) && isWhole( target ) ) {
return value.longValue() * target.longValue();
} else {
return value.doubleValue() * target.doubleValue();
}
} catch ( NumberFormatException e ) {
return Double.NaN;
}
}
@SupplierKey("/{number}")
@API("1.0.0")
public Number div( @KeyValue Number value, @KeyParam("number") String number ) {
try {
Number target = parseNumber( number );
if ( isWhole( value ) && isWhole( target ) ) {
return value.longValue() / target.longValue();
} else {
return value.doubleValue() / target.doubleValue();
}
} catch ( NumberFormatException e ) {
return Double.NaN;
}
}
@SupplierKey("mod {number}")
@API("1.0.0")
public Number numberMod( @KeyValue Number value, @KeyParam("number") String number ) {
try {
Number target = parseNumber( number );
if ( isWhole( value ) && isWhole( target ) ) {
return value.longValue() % target.longValue();
} else {
return value.doubleValue() % target.doubleValue();
}
} catch ( NumberFormatException e ) {
return Double.NaN;
}
}
@SupplierKey("equals {number}")
@API("1.0.0")
public Boolean numberEquals( @KeyValue Number value, @KeyParam("number") String number ) {
try {
Number target = parseNumber( number );
if ( isWhole( value ) && isWhole( target ) )
return value.longValue() == target.longValue();
else
return value.doubleValue() == target.doubleValue();
} catch ( NumberFormatException e ) {
return Boolean.FALSE;
}
}
private Number parseNumber( String string ) {
Number target;
string = string.trim();
if ( !string.contains( "." ) ) {
target = new Long( string );
} else {
target = new Double( string );
}
return target;
}
@SupplierKey("is whole")
@API("1.0.0")
public boolean isWhole( @KeyValue Number number ) {
return number instanceof Integer || number instanceof Long || number instanceof BigInteger
|| number instanceof Short || number instanceof Byte;
}
@SupplierKey("type")
@API("1.0.0")
public String getType( @KeyValue Number number ) {
String name = number.getClass().getName();
int dot = name.lastIndexOf( '.' );
if ( dot >= 0 )
return name.substring( dot + 1 );
return name;
}
/**
* Formats the number with the specified pattern.
*
* @param number The number.
* @param pattern The pattern
* @return The formatted string.
*/
@SupplierKey({"format {format}", "{format}"})
@KeyWeight(-100)
@API("1.0.0")
public static String formatNumber( @KeyValue Number number, @KeyParam("format") String pattern ) {
// TODO: Replace this with a more general solution.
if ( number == null )
return null;
NumberFormat format = new DecimalFormat( pattern );
return format.format( number );
}
/**
* Parses the text into a {@link Number}.
*
* @param text The text to parse.
* @param pattern The pattern.
* @return The number.
* @throws java.text.ParseException if there is a parsing error.
*/
public static Number parseNumber( String text, String pattern ) throws ParseException {
// TODO: Replace this with a more general solution.
if ( text == null )
return null;
if ( StringUtils.isBlank( pattern ) ) {
// Try a direct parse
try {
if ( text.indexOf( '.' ) >= 0 )
return Double.valueOf( text );
else
return Long.valueOf( text );
} catch ( NumberFormatException e ) {
throw new ParseException( e.getMessage(), 0 );
}
} else {
// Use the pattern
DecimalFormat format = new DecimalFormat( pattern );
return format.parse( text );
}
}
}