package com.qoomon.domainvalue.type;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by qoomon on 30/12/14.
 */
public class DVUtil {

    private static Map<Class<?>, Constructor<?>> CONSTRUCTOR_CACHE = new HashMap<>();

    /**
     * @param dvType domain value type
     * @return a new DV instance
     */
    public static <V, T extends DV<V>> Constructor<T> getConstructor(Class<V> valueType, Class<T> dvType) {
        try {
            Constructor<T> dvConstructor = (Constructor<T>) CONSTRUCTOR_CACHE.get(dvType);
            if (dvConstructor == null) {
                dvConstructor = dvType.getDeclaredConstructor(valueType);
                dvConstructor.setAccessible(true);
                CONSTRUCTOR_CACHE.put(dvType, dvConstructor);
            }
            return dvConstructor;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @param value  to wrap
     * @param dvType domain value type
     * @return a new DV instance
     */
    public static <V, T extends DV<V>> T newInstance(V value, Class<V> valueType, Class<T> dvType) {
        try {
            Constructor<T> constructor = getConstructor(valueType, dvType);
            return constructor.newInstance(value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @param value  to wrap
     * @param dvType domain value type
     * @return true if value is not null, false else
     */
    public static <V, T extends DV<V>> boolean validate(V value, Class<V> valueType, Class<T> dvType) {
        T dv = newInstance(null, valueType, dvType);
        return dv.isValid(value);
    }

    /**
     * @param value  to wrap
     * @param dvType domain value type
     * @return a DV instance
     */
    public static <V, T extends DV<V>> T of(V value, Class<V> valueType, Class<T> dvType) {
        assert validate(value, valueType, dvType) : value + " is not a valid value for " + dvType.getClass().getSimpleName();
        return newInstance(value, valueType, dvType);
    }

}

@@ -466,34 +466,16 @@
 Type) %7B%0A
-        try %7B%0A    
         
@@ -561,20 +561,16 @@
         
-    
 if (dvCo
@@ -586,24 +586,42 @@
  == null) %7B%0A
+            try %7B%0A
             
@@ -678,32 +678,214 @@
 valueType);%0A    
+        %7D catch (Exception e) %7B%0A                throw new RuntimeException(%22missing constructor %22 + dvType.getSimpleName() + %22(%22 + valueType.getSimpleName() + %22)%22, e);%0A            %7D%0A
             dvCo
@@ -911,28 +911,24 @@
 ible(true);%0A
-    
             
@@ -973,20 +973,16 @@
 uctor);%0A
-    
         
@@ -987,28 +987,24 @@
   %7D%0A        
-    
 return dvCon
@@ -1017,93 +1017,8 @@
 or;%0A
-        %7D catch (Exception e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A
     

Add exception