package phantomlancer;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import org.apache.avro.Schema;
import org.apache.commons.lang3.Validate;
import phantomlancer.annotation.AvroScan;
import phantomlancer.tools.JavaClass2Type;
import phantomlancer.tools.StrUtils;
import com.google.common.collect.Sets;
@Setter
@Getter
public class AvscSchemaBuilder {
private Class<?> clazz;
private AvroScan avroScan;
private volatile Schema schema;
private boolean nameSpaceByPKN;
public AvscSchemaBuilder(Class<?> clazz) {
this.clazz = clazz;
this.avroScan = clazz.getAnnotation(AvroScan.class);
Validate.notNull(avroScan, "[%s] not found annotation(AvroScan.class)", clazz);
}
public synchronized Schema createSchema() {
String tableName = StrUtils.camelConvert(avroScan, clazz.getSimpleName());
String nameSpace = (avroScan.nameSpaceByPackageName() ? clazz.getPackage().getName() : avroScan.nameSpaceByManul());
Schema sc = Schema.createRecord(tableName, "Auto Schema " + tableName, nameSpace, false);
List<org.apache.avro.Schema.Field> avroFields = new ArrayList<org.apache.avro.Schema.Field>();
HashSet<String> fieldNames = Sets.newHashSet();
for (Class<?> tclazz = clazz; tclazz != Object.class; tclazz = tclazz.getSuperclass()) {
Field[] fs = tclazz.getDeclaredFields();
for (Field field : fs) {
if ((avroScan.skipStaticField() && Modifier.isStatic(field.getModifiers()) || (avroScan.skipTransientField() && Modifier.isTransient(field.getModifiers())))) {
continue;
}
String fieldName = StrUtils.camelConvert(avroScan, field.getName());
org.apache.avro.Schema.Field avroField = null;
if (!fieldNames.contains(fieldName)) {
fieldNames.add(fieldName);
avroField = JavaClass2Type.toAvroField(field, avroScan);
}
if (avroField != null) {
avroFields.add(avroField);
}
}
}
sc.setFields(avroFields);
schema = sc;
return getSchema();
}
}