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);
}
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());
}
Aggregations