All Downloads are FREE. Search and download functionalities are using the official Maven repository.

consulting.omnia.util.cast.CastUtil Maven / Gradle / Ivy

package consulting.omnia.util.cast;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

import consulting.omnia.util.cast.collections.ListCastUtil;
import consulting.omnia.util.cast.number.NumberCast;
import consulting.omnia.util.cast.parser.BooleanCastParser;
import consulting.omnia.util.cast.parser.DateCastParser;
import consulting.omnia.util.cast.visitor.AbstractCastMainDataVisitor;

/**
 * Cast Util.
 * Casts and converts (simple easy conversions) types.
 * 
 * @author Ronaldo Blanc ronaldoblanc at omnia.consulting
 * @since Jul 17, 2015
 * @version 1.2.0
 */
public class CastUtil {

	private static final CastMainDataVisitor CAST_VISITOR = new CastUtil.CastMainDataVisitor();
	
	/**
	 * Casts or converts the value as type.
	 * This method is mostly a "number based" converter.
	 * If you pass a numeric value (number or string) it tries to convert data
	 * from this numeric value. So, if you try to convert a text format representation
	 * of a date value like "20150801", you will get undesirable result. 
	 * 
	 * @param value object to cast
	 * @param type class to cast object as
	 * @param  returning type
	 * @return if possible returns value cast as class type
	 * @throws RuntimeException if anything goes wrong
	 */
	public static  R castAs(final Object value, final Class type) {
		if(value == null || type == null) {
			throw CastUtilExceptionHandler.castException("Both value and type must be not null");
		}
		
		return CAST_VISITOR.asType(value, type); 
	}

	//TODO: improve this method
	public static  List getAsList(final List value) {
		return ListCastUtil.cast(value);
	}
	
	private static class CastMainDataVisitor extends AbstractCastMainDataVisitor {
		private Object result;
		private Class type;
		
		public  R asType(final Object value, final Class type) {
			if (type.isAssignableFrom(value.getClass())) {
				return castAs(value, type);
			}

			this.type = type;
			accept(value);
			return castAs(result, type);
		}

		@Override
		public void visit(final Character value) {
			result = value;
			visit(type);
		}

		@Override
		public void visit(final String value) {
			result = value;
			visit(type);
		}

		@Override
		public void visit(final Date value) {
			final BigDecimal number = NumberCast.asNumber(value, BigDecimal.class);;
			result = NumberCast.asType(number, type);			
		}

		@Override
		public void visit(final Boolean value) {
			final Boolean booleanValue = castAs(value, Boolean.class);
			result = booleanValue ? NumberCast.asType(BigDecimal.ONE, type) : NumberCast.asType(BigDecimal.ZERO, type); 
		}

		@Override
		public void visit(final Number value) {
			result = NumberCast.asType(castAs(value, Number.class), this.type);
		}

		@Override
		public void visit(final Class value) {
			// TODO improve this method (remove the 'if's) 
			if(Boolean.class.isAssignableFrom(type)) {
				if(result instanceof String){
					result =  type.cast(BooleanCastParser.stringToBoolean(castAs(result, String.class)));
					return;
				}
				
				if(result instanceof Character){
					result =  type.cast(BooleanCastParser.charToBoolean(castAs(result, Character.class)));
					return;
				}

			}

			if (Date.class.isAssignableFrom(type)) {
				try {
					result =  type.cast(DateCastParser.stringToDate(castAs(result, String.class)));
					return;
				} catch (ParseException e) {
					/* Ignored */
				}
			}
			
			tryAsNumber();
		}

		private void tryAsNumber() {
			try {
				final BigDecimal number = NumberCast.asNumber(result, BigDecimal.class);
				result =  NumberCast.asType(number, type);
			} catch(NumberFormatException nfe) {
				throw CastUtilExceptionHandler.castException(result, type);
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy