package com.codepoetics.phantompojo.impl; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.*; import java.util.function.BiFunction; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; public final class PojoProperties { public static PojoProperties forGetters(Map<String, Method> getterMethodsByName) { String[] names = getterMethodsByName.keySet().stream().toArray(String[]::new); Type[] types = getFieldTypes(getterMethodsByName, names); return new PojoProperties(names, types); } private static Type[] getFieldTypes(Map<String, Method> getterMethods, String[] names) { return Stream.of(names).map(getterMethods::get).map(Method::getGenericReturnType).toArray(Type[]::new); } private final String[] names; private final Type[] types; private PojoProperties(String[] names, Type[] types) { this.names = names; this.types = types; } public String formatValues(Object[] values) { return IntStream.range(0, names.length) .filter(i -> values[i] != null) .mapToObj(i -> String.format("%s=%s", names[i], values[i])) .collect(Collectors.joining(",", "{", "}")); } public MethodIndexLookup createMethodIndexLookup(MethodSet methodSet) { return methodSet.getMethodIndexLookup(getNameIndices()); } private Map<String, Integer> getNameIndices() { Map<String, Integer> map = new HashMap<>(); for (int i = 0; i < names.length; i++) { map.put(names[i], i); } return map; } public Map<String, Object> createMap(Object[] values) { Map<String, Object> map = new HashMap<>(); for (int i = 0; i < names.length; i++) { map.put(names[i], values[i]); } return map; } public Object[] createEmptyValues() { return new Object[names.length]; } public Object[] createValues(Map<String, Object> map, BiFunction<Type, Object, Object> typeConverter) { Object[] values = createEmptyValues(); for (int i = 0; i < values.length; i++) { Object value = map.get(names[i]); if (value != null) { values[i] = typeConverter.apply(types[i], value); } } return values; } public Type getType(int index) { return types[index]; } }