use of org.apache.flink.api.common.typeinfo.TypeInfoFactory in project flink by apache.
the class TypeExtractor method getClosestFactory.
/**
* Traverses the type hierarchy up until a type information factory can be found.
*
* @param typeHierarchy hierarchy to be filled while traversing up
* @param t type for which a factory needs to be found
* @return closest type information factory or null if there is no factory in the type hierarchy
*/
private static <OUT> TypeInfoFactory<? super OUT> getClosestFactory(ArrayList<Type> typeHierarchy, Type t) {
TypeInfoFactory factory = null;
while (factory == null && isClassType(t) && !(typeToClass(t).equals(Object.class))) {
typeHierarchy.add(t);
factory = getTypeInfoFactory(t);
t = typeToClass(t).getGenericSuperclass();
if (t == null) {
break;
}
}
return factory;
}
use of org.apache.flink.api.common.typeinfo.TypeInfoFactory in project flink by apache.
the class TypeExtractor method analyzePojo.
@SuppressWarnings("unchecked")
protected <OUT, IN1, IN2> TypeInformation<OUT> analyzePojo(Type type, List<Type> typeHierarchy, TypeInformation<IN1> in1Type, TypeInformation<IN2> in2Type) {
Class<OUT> clazz = typeToClass(type);
if (!Modifier.isPublic(clazz.getModifiers())) {
LOG.info("Class " + clazz.getName() + " is not public so it cannot be used as a POJO type " + "and must be processed as GenericType. Please read the Flink documentation " + "on \"Data Types & Serialization\" for details of the effect on performance.");
return new GenericTypeInfo<>(clazz);
}
// add the hierarchy of the POJO
getTypeHierarchy(typeHierarchy, type, Object.class);
List<Field> fields = getAllDeclaredFields(clazz, false);
if (fields.size() == 0) {
LOG.info("No fields were detected for " + clazz + " so it cannot be used as a POJO type " + "and must be processed as GenericType. Please read the Flink documentation " + "on \"Data Types & Serialization\" for details of the effect on performance.");
return new GenericTypeInfo<>(clazz);
}
List<PojoField> pojoFields = new ArrayList<>();
for (Field field : fields) {
Type fieldType = field.getGenericType();
if (!isValidPojoField(field, clazz, typeHierarchy) && clazz != Row.class) {
LOG.info("Class " + clazz + " cannot be used as a POJO type because not all fields are valid POJO fields, " + "and must be processed as GenericType. Please read the Flink documentation " + "on \"Data Types & Serialization\" for details of the effect on performance.");
return null;
}
try {
final TypeInformation<?> typeInfo;
List<Type> fieldTypeHierarchy = new ArrayList<>(typeHierarchy);
TypeInfoFactory factory = getTypeInfoFactory(field);
if (factory != null) {
typeInfo = createTypeInfoFromFactory(fieldType, in1Type, in2Type, fieldTypeHierarchy, factory, fieldType);
} else {
fieldTypeHierarchy.add(fieldType);
typeInfo = createTypeInfoWithTypeHierarchy(fieldTypeHierarchy, fieldType, in1Type, in2Type);
}
pojoFields.add(new PojoField(field, typeInfo));
} catch (InvalidTypesException e) {
Class<?> genericClass = Object.class;
if (isClassType(fieldType)) {
genericClass = typeToClass(fieldType);
}
pojoFields.add(new PojoField(field, new GenericTypeInfo<>((Class<OUT>) genericClass)));
}
}
CompositeType<OUT> pojoType = new PojoTypeInfo<>(clazz, pojoFields);
//
// Validate the correctness of the pojo.
// returning "null" will result create a generic type information.
//
List<Method> methods = getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (method.getName().equals("readObject") || method.getName().equals("writeObject")) {
LOG.info("Class " + clazz + " contains custom serialization methods we do not call, so it cannot be used as a POJO type " + "and must be processed as GenericType. Please read the Flink documentation " + "on \"Data Types & Serialization\" for details of the effect on performance.");
return null;
}
}
// Try retrieving the default constructor, if it does not have one
// we cannot use this because the serializer uses it.
Constructor<OUT> defaultConstructor = null;
try {
defaultConstructor = clazz.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
LOG.info(clazz + " is abstract or an interface, having a concrete " + "type can increase performance.");
} else {
LOG.info(clazz + " is missing a default constructor so it cannot be used as a POJO type " + "and must be processed as GenericType. Please read the Flink documentation " + "on \"Data Types & Serialization\" for details of the effect on performance.");
return null;
}
}
if (defaultConstructor != null && !Modifier.isPublic(defaultConstructor.getModifiers())) {
LOG.info("The default constructor of " + clazz + " is not Public so it cannot be used as a POJO type " + "and must be processed as GenericType. Please read the Flink documentation " + "on \"Data Types & Serialization\" for details of the effect on performance.");
return null;
}
// everything is checked, we return the pojo
return pojoType;
}
use of org.apache.flink.api.common.typeinfo.TypeInfoFactory in project flink by apache.
the class TypeExtractor method getTypeInfoFactory.
// --------------------------------------------------------------------------------------------
// Utility methods
// --------------------------------------------------------------------------------------------
/**
* Returns the type information factory for a type using the factory registry or annotations.
*/
@Internal
@SuppressWarnings("unchecked")
public static <OUT> TypeInfoFactory<OUT> getTypeInfoFactory(Type t) {
final Class<?> factoryClass;
if (!isClassType(t) || !typeToClass(t).isAnnotationPresent(TypeInfo.class)) {
return null;
}
final TypeInfo typeInfoAnnotation = typeToClass(t).getAnnotation(TypeInfo.class);
factoryClass = typeInfoAnnotation.value();
// check for valid factory class
if (!TypeInfoFactory.class.isAssignableFrom(factoryClass)) {
throw new InvalidTypesException("TypeInfo annotation does not specify a valid TypeInfoFactory.");
}
// instantiate
return (TypeInfoFactory<OUT>) InstantiationUtil.instantiate(factoryClass);
}
Aggregations