Search in sources :

Example 1 with ModelConsumer

use of com.disney.groovity.model.ModelConsumer in project groovity by disney.

the class GroovityObjectConverter method convert.

@SuppressWarnings({ "unchecked", "rawtypes" })
public static Object convert(Object in, Type type) {
    if (in == null) {
        return null;
    }
    Class<?> out;
    Type[] typeArguments = null;
    if (type instanceof ParameterizedType) {
        ParameterizedType pt = (ParameterizedType) type;
        out = (Class<?>) pt.getRawType();
        typeArguments = pt.getActualTypeArguments();
    } else {
        out = (Class<?>) type;
    }
    if (out.equals(Object.class)) {
        // special case, no conversion at all
        return in;
    }
    if (type.equals(in.getClass())) {
        return in;
    }
    if (typeArguments == null && out.isAssignableFrom(in.getClass())) {
        return in;
    }
    if (in.getClass().isArray()) {
        return convertIterable(new ArrayIterable(in), out, typeArguments);
    }
    if (List.class.isAssignableFrom(in.getClass())) {
        List inList = (List) in;
        return convertIterable(inList, out, typeArguments);
    }
    if (out.equals(String.class)) {
        return in.toString();
    }
    if (out.isArray()) {
        Object val = convert(in, out.getComponentType());
        if (val != null) {
            // if we're expecting an array back but the input is not an array, let's wrap it
            Object[] ra = (Object[]) Array.newInstance(out.getComponentType(), 1);
            ra[0] = val;
            return ra;
        }
        return Array.newInstance(out.getComponentType(), 0);
    }
    if (out.isEnum()) {
        Enum val = Enum.valueOf((Class<Enum>) out, in.toString());
        return val;
    }
    if (!Number.class.isAssignableFrom(in.getClass())) {
        if (Number.class.isAssignableFrom(out)) {
            String ps = getParseable(in);
            if (ps == null) {
                return null;
            }
            // groovy can only convert single digit number strings for some odd reason, so we have to roll our own
            if (Integer.class.isAssignableFrom(out)) {
                return Integer.parseInt(ps);
            }
            if (Long.class.isAssignableFrom(out)) {
                return Long.parseLong(ps);
            }
            if (Float.class.isAssignableFrom(out)) {
                return Float.parseFloat(ps);
            }
            if (Double.class.isAssignableFrom(out)) {
                return Double.parseDouble(ps);
            }
        }
        if (out.isPrimitive()) {
            String ps = getParseable(in);
            if (ps == null) {
                return null;
            }
            if (out.equals(Integer.TYPE)) {
                return Integer.parseInt(ps);
            }
            if (out.equals(Long.TYPE)) {
                return Long.parseLong(ps);
            }
            if (out.equals(Float.TYPE)) {
                return Float.parseFloat(ps);
            }
            if (out.equals(Double.TYPE)) {
                return Double.parseDouble(ps);
            }
        }
    }
    if (Boolean.class.equals(out) || out == Boolean.TYPE) {
        Class ic = in.getClass();
        if (!Boolean.class.equals(ic) && ic != Boolean.TYPE) {
            String ps = getParseable(in);
            if (ps != null) {
                return Boolean.parseBoolean(ps);
            }
        }
    }
    if (Map.class.isAssignableFrom(out)) {
        Map<Object, Object> result = null;
        if (!out.isInterface()) {
            try {
                result = (Map<Object, Object>) out.newInstance();
            } catch (Exception e) {
            }
        }
        if (result == null) {
            result = new LinkedHashMap<>();
        }
        Type kType;
        Type vType;
        if (typeArguments != null) {
            kType = typeArguments[0];
            vType = typeArguments[1];
        } else {
            kType = Object.class;
            vType = Object.class;
        }
        Map<Object, Object> finalResult = result;
        ModelConsumer consumer = (k, v) -> {
            finalResult.put(convert(k, kType), convert(v, vType));
        };
        consume(in, consumer);
        return finalResult;
    }
    // TODO special handling for string inputs, look for string-based constructors
    if (!out.isPrimitive() && !out.isInterface()) {
        try {
            Constructor<?> c = out.getConstructor();
            Object o = c.newInstance();
            if (o instanceof Model) {
                consume(in, ((Model) o)::put);
            } else {
                consume(in, (k, v) -> {
                    Model.put(o, k, v);
                });
            }
            // System.out.println("USED MODEL TO CONVERT "+in.getClass().getName()+" to "+out.getName());
            return o;
        } catch (Exception e) {
        // e.printStackTrace();
        }
    }
    return DefaultTypeTransformation.castToType(in, out);
}
Also used : LinkedHashMap(java.util.LinkedHashMap) List(java.util.List) DefaultTypeTransformation(org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation) Array(java.lang.reflect.Array) ParameterizedType(java.lang.reflect.ParameterizedType) Iterator(java.util.Iterator) Type(java.lang.reflect.Type) Map(java.util.Map) Model(com.disney.groovity.model.Model) Constructor(java.lang.reflect.Constructor) ModelConsumer(com.disney.groovity.model.ModelConsumer) ArrayList(java.util.ArrayList) ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Model(com.disney.groovity.model.Model) List(java.util.List) ArrayList(java.util.ArrayList) ModelConsumer(com.disney.groovity.model.ModelConsumer)

Example 2 with ModelConsumer

use of com.disney.groovity.model.ModelConsumer in project groovity by disney.

the class TestModel method testModel.

@SuppressWarnings({ "rawtypes", "unchecked", "serial" })
@Test
public void testModel() throws Exception {
    HashMap place = new HashMap<>();
    place.put("name", "State Fairground");
    place.put("latitude", 1234);
    place.put("longitude", 5678);
    HashMap features = new HashMap();
    features.put("clowns", 5);
    HashMap menu = new HashMap();
    menu.put("appetizer", "pretzels");
    menu.put("mainCourse", "pizza");
    features.put("menu", menu);
    RealEvent event = new RealEvent();
    event.name = "State Fair";
    event.put("place", place);
    event.description = "State Fun";
    event.features = features;
    Exception e = null;
    try {
        event.put("time", "last week");
    } catch (IllegalArgumentException iae) {
        e = iae;
    }
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(event);
    oos.close();
    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
    Object o = ois.readObject();
    Assert.assertEquals(((Model) o).map(), event.map());
    Assert.assertNotNull("Expected IllegalArgumentException, none was thrown", e);
    event.put("time", 1000000000000l);
    ModelCollector collector = new ModelCollector();
    collector.setFilters(new ModelFilter[] { ModelFilter.invoke("", "reverseName", "reversedName", 2, 8), ModelFilter.exclude("description"), ModelFilter.copy("name", "allcaps", name -> {
        return name.toString().toUpperCase();
    }), ModelFilter.promote("place.name"), ModelFilter.invoke("place", "reverse", ""), ModelFilter.collapse("features.menu"), ModelFilter.include("*", "features.mainCourse", "features.clowns", "features.bands"), ModelFilter.transform("time", date -> {
        return ((Date) date).getTime();
    }), ModelFilter.rename("time", "date"), ModelFilter.add("features.bands", ev -> {
        return Arrays.asList("Foo", "Bar");
    }), ModelFilter.custom(new Closure(null) {

        @SuppressWarnings("unused")
        public void doCall(String k, Object v, ModelConsumer c) {
            if (k.equals("clowns")) {
                c.call(k, v.toString());
            } else {
                c.call(k, v);
            }
        }
    }) });
    HashMap expected = new HashMap<>();
    expected.put("name", "State Fair");
    expected.put("reversedName", "aF eta");
    expected.put("allcaps", "STATE FAIR");
    expected.put("date", 1000000000000l);
    expected.put("place", "dnuorgriaF etatS");
    HashMap expectedFeatures = new HashMap();
    expectedFeatures.put("mainCourse", "pizza");
    expectedFeatures.put("clowns", "5");
    expectedFeatures.put("bands", Arrays.asList("Foo", "Bar"));
    expected.put("features", expectedFeatures);
    collector.visit(event);
    Assert.assertEquals(expected, collector.getCollected());
    HashMap firstLevel = new HashMap();
    HashMap secondLevelA = new HashMap();
    HashMap secondLevelB = new HashMap();
    secondLevelA.put("name", "foo");
    secondLevelB.put("name", "bar");
    firstLevel.put("a", secondLevelA);
    firstLevel.put("b", secondLevelB);
    ModelCollector acc = new ModelCollector();
    acc.setFilters(new ModelFilter[] { ModelFilter.include("a.name") });
    acc.visit(firstLevel);
    HashMap exacc = new HashMap<>();
    exacc.put("a", secondLevelA);
    Assert.assertEquals(exacc, acc.getCollected());
    ModelCollector acc2 = new ModelCollector();
    acc2.setFilters(new ModelFilter[] { ModelFilter.exclude("a.name") });
    acc2.visit(firstLevel);
    HashMap exacc2 = new HashMap<>();
    exacc2.put("b", secondLevelB);
    exacc2.put("a", new HashMap<>());
    Assert.assertEquals(exacc2, acc2.getCollected());
}
Also used : Arrays(java.util.Arrays) ByteArrayOutputStream(java.io.ByteArrayOutputStream) GroovySystem(groovy.lang.GroovySystem) Date(java.util.Date) ModelFilter(com.disney.groovity.model.ModelFilter) ObjectInputStream(java.io.ObjectInputStream) Closure(groovy.lang.Closure) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) ModelConsumer(com.disney.groovity.model.ModelConsumer) LinkedHashMap(java.util.LinkedHashMap) MetaBeanProperty(groovy.lang.MetaBeanProperty) ReflectionCache(org.codehaus.groovy.reflection.ReflectionCache) ByteArrayInputStream(java.io.ByteArrayInputStream) Map(java.util.Map) ModelCollector(com.disney.groovity.model.ModelCollector) ObjectOutputStream(java.io.ObjectOutputStream) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Test(org.junit.Test) CachedClass(org.codehaus.groovy.reflection.CachedClass) MetaMethod(groovy.lang.MetaMethod) MetaClassImpl(groovy.lang.MetaClassImpl) ModelJsonWriter(com.disney.groovity.model.ModelJsonWriter) Modifier(java.lang.reflect.Modifier) Assert(org.junit.Assert) Model(com.disney.groovity.model.Model) Closure(groovy.lang.Closure) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ObjectOutputStream(java.io.ObjectOutputStream) ModelCollector(com.disney.groovity.model.ModelCollector) ByteArrayInputStream(java.io.ByteArrayInputStream) ObjectInputStream(java.io.ObjectInputStream) ModelConsumer(com.disney.groovity.model.ModelConsumer) Test(org.junit.Test)

Aggregations

Model (com.disney.groovity.model.Model)2 ModelConsumer (com.disney.groovity.model.ModelConsumer)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 ModelCollector (com.disney.groovity.model.ModelCollector)1 ModelFilter (com.disney.groovity.model.ModelFilter)1 ModelJsonWriter (com.disney.groovity.model.ModelJsonWriter)1 Closure (groovy.lang.Closure)1 GroovySystem (groovy.lang.GroovySystem)1 MetaBeanProperty (groovy.lang.MetaBeanProperty)1 MetaClassImpl (groovy.lang.MetaClassImpl)1 MetaMethod (groovy.lang.MetaMethod)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 ObjectInputStream (java.io.ObjectInputStream)1 ObjectOutputStream (java.io.ObjectOutputStream)1 Array (java.lang.reflect.Array)1 Constructor (java.lang.reflect.Constructor)1 Modifier (java.lang.reflect.Modifier)1 ParameterizedType (java.lang.reflect.ParameterizedType)1