package com.framework.utils.conversion; import com.google.common.collect.Lists; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; import java.net.UnknownHostException; import java.util.List; import java.util.Locale; /** * Created with IntelliJ IDEA ( LivePerson : www.liveperson.com ) * * Package: com.framework.utils.conversion * * Name : Converter * * User : solmarkn / Dani Vainstein * * Date : 2015-03-05 * * Time : 21:21 * */ public class Converter { /** Constant for the prefix of binary numbers.*/ private static final String BIN_PREFIX = "0b"; /** Constant for the prefix of hex numbers.*/ private static final String HEX_PREFIX = "0x"; /** Constant for the radix of hex numbers.*/ private static final int HEX_RADIX = 16; /** Constant for the radix of binary numbers.*/ private static final int BIN_RADIX = 2; /** Constant for the argument classes of the Number constructor that takes a String. */ private static final Class<?>[] CONSTR_ARGS = {String.class}; /** * Convert the specified object into a Locale. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a Locale */ public static Locale toLocale( Object value ) throws ConversionException { if ( value instanceof Locale ) { return ( Locale ) value; } else if ( value instanceof String ) { List<String> elements = Lists.newArrayList( StringUtils.split( ( String ) value, '_' ) ); int size = elements.size(); if ( size >= 1 && ( ( elements.get( 0 ) ).length() == 2 || ( elements.get( 0 ) ).length() == 0 ) ) { String language = elements.get( 0 ); String country = ( size >= 2 ) ? elements.get( 1 ) : ""; String variant = ( size >= 3 ) ? elements.get( 2 ) : ""; return new Locale( language, country, variant ); } else { throw new ConversionException( "The value " + value + " can't be converted to a Locale" ); } } else { throw new ConversionException( "The value " + value + " can't be converted to a Locale" ); } } /** * Convert the specified object into an URL. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to an URL */ public static URL toURL( Object value ) throws ConversionException { if ( value instanceof URL ) { return ( URL ) value; } else if ( value instanceof String ) { try { return new URL( ( String ) value ); } catch ( MalformedURLException e ) { throw new ConversionException( "The value " + value + " can't be converted to an URL", e ); } } else { throw new ConversionException( "The value " + value + " can't be converted to an URL" ); } } /** * Convert the specified value into an internet address. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a InetAddress * * @since 1.5 */ public static InetAddress toInetAddress( Object value ) throws ConversionException { if ( value instanceof InetAddress ) { return ( InetAddress ) value; } else if ( value instanceof String ) { try { return InetAddress.getByName( ( String ) value ); } catch ( UnknownHostException e ) { throw new ConversionException( "The value " + value + " can't be converted to a InetAddress", e ); } } else { throw new ConversionException( "The value " + value + " can't be converted to a InetAddress" ); } } /** * Convert the specified object into an Integer. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to an integer */ public static Integer toInteger( Object value ) throws ConversionException { Number n = toNumber( value, Integer.class ); if ( n instanceof Integer ) { return ( Integer ) n; } else { return new Integer( n.intValue() ); } } /** * Convert the specified object into a Long. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a Long */ public static Long toLong( Object value ) throws ConversionException { Number n = toNumber( value, Long.class ); if ( n instanceof Long ) { return ( Long ) n; } else { return new Long( n.longValue() ); } } /** * Convert the specified object into a Float. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a Float */ public static Float toFloat( Object value ) throws ConversionException { Number n = toNumber( value, Float.class ); if ( n instanceof Float ) { return ( Float ) n; } else { return new Float( n.floatValue() ); } } /** * Convert the specified object into a Double. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a Double */ public static Double toDouble( Object value ) throws ConversionException { Number n = toNumber( value, Double.class ); if ( n instanceof Double ) { return ( Double ) n; } else { return new Double( n.doubleValue() ); } } /** * Convert the specified object into a BigInteger. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a BigInteger */ public static BigInteger toBigInteger( Object value ) throws ConversionException { Number n = toNumber( value, BigInteger.class ); if ( n instanceof BigInteger ) { return ( BigInteger ) n; } else { return BigInteger.valueOf( n.longValue() ); } } /** * Convert the specified object into a BigDecimal. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a BigDecimal */ public static BigDecimal toBigDecimal( Object value ) throws ConversionException { Number n = toNumber( value, BigDecimal.class ); if ( n instanceof BigDecimal ) { return ( BigDecimal ) n; } else { return new BigDecimal( n.doubleValue() ); } } /** * Tries to convert the specified object into a number object. This method * is used by the conversion methods for number types. Note that the return * value is not in always of the specified target class, but only if a new * object has to be created. * * @param value the value to be converted (must not be <b>null</b>) * @param targetClass the target class of the conversion (must be derived * from {@code java.lang.Number}) * @return the converted number * @throws ConversionException if the object cannot be converted */ static Number toNumber( Object value, Class<?> targetClass ) throws ConversionException { if ( value instanceof Number ) { return ( Number ) value; } else { String str = value.toString(); if ( str.startsWith( HEX_PREFIX ) ) { try { return new BigInteger( str.substring( HEX_PREFIX.length() ), HEX_RADIX ); } catch ( NumberFormatException nex ) { throw new ConversionException( "Could not convert " + str + " to " + targetClass.getName() + "! Invalid hex number.", nex ); } } if ( str.startsWith( BIN_PREFIX ) ) { try { return new BigInteger( str.substring( BIN_PREFIX.length() ), BIN_RADIX ); } catch ( NumberFormatException nex ) { throw new ConversionException( "Could not convert " + str + " to " + targetClass.getName() + "! Invalid binary number.", nex ); } } try { Constructor<?> constr = targetClass.getConstructor( CONSTR_ARGS ); return ( Number ) constr.newInstance( new Object[] { str } ); } catch ( InvocationTargetException itex ) { throw new ConversionException( "Could not convert " + str + " to " + targetClass.getName(), itex .getTargetException() ); } catch ( Exception ex ) { // Treat all possible exceptions the same way throw new ConversionException( "Conversion error when trying to convert " + str + " to " + targetClass.getName(), ex ); } } } /** * Convert the specified object into a Boolean. Internally the * {@code org.apache.commons.lang.BooleanUtils} class from the * <a href="http://commons.apache.org/lang/">Commons Lang</a> * project is used to perform this conversion. This class accepts some more * tokens for the boolean value of <b>true</b>, e.g. {@code yes} and * {@code on}. Please refer to the documentation of this class for more * details. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a boolean */ public static Boolean toBoolean(Object value) throws ConversionException { if (value instanceof Boolean) { return (Boolean) value; } else if (value instanceof String) { Boolean b = BooleanUtils.toBooleanObject( ( String ) value ); if (b == null) { throw new ConversionException("The value " + value + " can't be converted to a Boolean object"); } return b; } else { throw new ConversionException("The value " + value + " can't be converted to a Boolean object"); } } }