package eu.dnetlib.iis.common.utils;
import java.lang.reflect.Field;
import org.apache.avro.Schema;
import org.apache.avro.generic.IndexedRecord;
import eu.dnetlib.iis.common.java.io.JsonUtils;
/**
*
* @author Mateusz Kobos
*
*/
public final class AvroUtils {
public final static String primitiveTypePrefix = "org.apache.avro.Schema.Type.";
//------------------------ CONSTRUCTORS -------------------
private AvroUtils() {}
//------------------------ LOGIC --------------------------
/**
* For a given name of a class generated from Avro schema return
* a JSON schema.
*
* Apart from a name of a class you can also give a name of one of enums
* defined in {@link org.apache.avro.Schema.Type}; in such case an
* appropriate primitive type will be returned.
*
* @param typeName fully qualified name of a class generated from Avro schema,
* e.g. {@code eu.dnetlib.iis.common.avro.Person},
* or a fully qualified name of enum defined by
* {@link org.apache.avro.Schema.Type},
* e.g. {@link org.apache.avro.Schema.Type.STRING}.
* @return JSON string
*/
public static Schema toSchema(String typeName) {
Schema schema = null;
if(typeName.startsWith(primitiveTypePrefix)){
String shortName = typeName.substring(
primitiveTypePrefix.length(), typeName.length());
schema = getPrimitiveTypeSchema(shortName);
} else {
schema = getAvroClassSchema(typeName);
}
return schema;
}
private static Schema getPrimitiveTypeSchema(String shortName){
Schema.Type type = Schema.Type.valueOf(shortName);
return Schema.create(type);
}
private static Schema getAvroClassSchema(String className){
try {
Class<?> avroClass = Class.forName(className);
Field f = avroClass.getDeclaredField("SCHEMA$");
return (Schema) f.get(null);
} catch (ClassNotFoundException e) {
throw new RuntimeException(
"Class \""+className+"\" does not exist", e);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* Creates a copy of a given AVRO object by serializing it to JSON string
* and deserializing it again.
*/
public static <T> T getCopy(T object, Schema schema, Class<T> type) {
if (!(object instanceof IndexedRecord)) {
throw new RuntimeException("Object is not an IndexedRecord instance!");
}
IndexedRecord record = (IndexedRecord) object;
return JsonUtils.convertToListFromString(record.toString(), schema, type).get(0);
}
}