package tap.util;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import org.apache.avro.Schema;
import org.apache.avro.util.Utf8;
public class RecordUtils {
public static <T> void copy(T from, T to) {
Class<?> toClass = to.getClass();
Class<?> fromClass = from.getClass();
Class<?> level;
if (toClass.isAssignableFrom(fromClass)) {
level = toClass;
} else if (fromClass.isAssignableFrom(fromClass)) {
level = fromClass;
} else {
throw new IllegalArgumentException("Not yet supported: copying fields from classes without a common superclass");
}
try {
while (level != null && level != Object.class){
// replace this with cached codegen
for (Field f : level.getDeclaredFields()) {
f.setAccessible(true);
if (!Modifier.isStatic(f.getModifiers())) {
Object o = deepCopy(f.get(from));
f.set(to, o);
}
}
level = level.getSuperclass();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
private static Object deepCopy(Object o) throws InstantiationException, IllegalAccessException {
if(o == null)
return null;
if (o instanceof Utf8){
Utf8 old = (Utf8)o;
int len = old.getByteLength();
byte[] copy = new byte[len];
System.arraycopy(old.getBytes(), 0, copy, 0, len);
return new Utf8(copy);
} else if (o instanceof Collection) {
Collection copy = (Collection) o.getClass().newInstance();
for (Object item : (Collection)o) {
copy.add(deepCopy(item));
}
return copy;
} else if (o instanceof Map) {
Map copy = (Map)o.getClass().newInstance();
Map map = (Map)o;
for (Map.Entry entry : (Set<Map.Entry>)map.entrySet()) {
copy.put(deepCopy(entry.getKey()), deepCopy(entry.getValue()));
}
return copy;
} else if (o instanceof Integer || o instanceof String || o instanceof Long || o instanceof Double || o instanceof Float) {
return o;
} else {
Object copy = o.getClass().newInstance();
RecordUtils.copy(o, copy);
return copy;
}
}
public static<T> T jsonToAvro(String json, Schema inSchema) {
return null;
}
public static <T> String toJson(T value) {
// TODO Auto-generated method stub
return null;
}
}