package com.codepoetics.phantompojo;
import com.codepoetics.phantompojo.impl.ReflectionUtils;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
final class PojoPromoter {
private PojoPromoter() {
}
static Object promote(Type type, Object object) {
Class<?> rawType = ReflectionUtils.rawTypeOf(type);
if (object instanceof Map && PhantomPojo.class.isAssignableFrom(rawType)) {
return PhantomPojo.wrapping((Map<String, Object>) object).with((Class) rawType);
}
if (rawType.isPrimitive()) {
return object;
}
if (object.getClass().isArray()) {
return promoteStream(Stream.of(ReflectionUtils.toObjectArray(object)), rawType, ReflectionUtils.getFirstTypeArgument(type));
}
if (object instanceof Collection) {
return promoteStream(((Collection<Object>) object).stream(), rawType, ReflectionUtils.getFirstTypeArgument(type));
}
if (!rawType.isAssignableFrom(object.getClass())) {
throw new IllegalArgumentException(String.format("Cannot convert %s into %s", object, type));
}
return object;
}
static Object promoteStream(Stream<Object> stream, Class<?> collectionType, Type itemType) {
Stream<Object> promotedStream = stream.map(item -> promote(itemType, item));
if (collectionType.equals(List.class)) {
return promotedStream.collect(Collectors.toList());
}
if (collectionType.equals(Set.class)) {
return promotedStream.collect(Collectors.toSet());
}
throw new IllegalArgumentException("Unable to convert collection to type " + collectionType.getSimpleName());
}
}