import java.util.HashMap;
import java.util.function.Function;
import java.math.*;
import java.time.*;

class Ideone {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static Object parse(String argString, Class param) {
		Function<String,?> func = parser.get(param);
		if (func != null)
			return func.apply(argString);
		if (param.isEnum())
			return Enum.valueOf(param, argString);
		throw new UnsupportedOperationException("Cannot parse string to " + param.getName());
	}

	private static HashMap<Class<?>, Function<String,?>> parser = new HashMap<>();
	static {
		parser.put(boolean.class       , Boolean::parseBoolean);
		parser.put(byte.class          , Byte::parseByte);
		parser.put(short.class         , Short::parseShort);
		parser.put(int.class           , Integer::parseInt);
		parser.put(long.class          , Long::parseLong);
		parser.put(double.class        , Double::parseDouble);
		parser.put(float.class         , Float::parseFloat);
		parser.put(Boolean.class       , Boolean::valueOf);
		parser.put(Byte.class          , Byte::valueOf);
		parser.put(Short.class         , Short::valueOf);
		parser.put(Integer.class       , Integer::valueOf);
		parser.put(Long.class          , Long::valueOf);
		parser.put(Double.class        , Double::valueOf);
		parser.put(Float.class         , Float::valueOf);
		parser.put(String.class        , String::valueOf);
		parser.put(BigDecimal.class    , BigDecimal::new);
		parser.put(BigInteger.class    , BigInteger::new);
		parser.put(LocalDate.class     , LocalDate::parse);
		parser.put(LocalDateTime.class , LocalDateTime::parse);
		parser.put(LocalTime.class     , LocalTime::parse);
		parser.put(MonthDay.class      , MonthDay::parse);
		parser.put(OffsetDateTime.class, OffsetDateTime::parse);
		parser.put(OffsetTime.class    , OffsetTime::parse);
		parser.put(Year.class          , Year::parse);
		parser.put(YearMonth.class     , YearMonth::parse);
		parser.put(ZonedDateTime.class , ZonedDateTime::parse);
		parser.put(ZoneId.class        , ZoneId::of);
		parser.put(ZoneOffset.class    , ZoneOffset::of);
	}

	public static void main(String[] args) {
		test("true", boolean.class);
		test("123" , byte.class);
		test("123" , short.class);
		test("123" , int.class);
		test("123" , long.class);
		test("123" , double.class);
		test("123" , float.class);
		test("true", Boolean.class);
		test("123" , Byte.class);
		test("123" , Short.class);
		test("123" , Integer.class);
		test("123" , Long.class);
		test("123" , Double.class);
		test("123" , Float.class);
		test("123" , BigDecimal.class);
		test("123" , BigInteger.class);
		test("Hello World", String.class);       // String
		test("HALF_EVEN"  , RoundingMode.class); // enum
		test("2016"                                       , Year.class);
		test("2016-04"                                    , YearMonth.class);
		test("--04-01"                                    , MonthDay.class);
		test("2016-04-01"                                 , LocalDate.class);
		test("23:18:47"                                   , LocalTime.class);
		test("23:18:47-04:00"                             , OffsetTime.class);
		test("2016-04-01T23:18:47"                        , LocalDateTime.class);
		test("2016-04-01T23:18:47-04:00"                  , OffsetDateTime.class);
		test("2016-04-01T23:18:47-04:00[America/New_York]", ZonedDateTime.class);
		test("America/New_York"                           , ZoneId.class);
		test("-04:00"                                     , ZoneOffset.class);
		test("FRIDAY"                                     , DayOfWeek.class);     // enum
		test("APRIL"                                      , Month.class);         // enum
	}

	private static void test(String argString, Class<?> param) {
		Object ret = parse(argString, param);
		System.out.printf("%-21s -> %-19s   [%-22s -> %s]%n",
		                  '"' + argString + '"', ret, param.getName(), ret.getClass().getName());
	}

}