use of org.apache.flink.api.common.typeinfo.BasicTypeInfo in project flink by apache.
the class TypeInfoParser method parse.
@SuppressWarnings({ "rawtypes", "unchecked" })
private static TypeInformation<?> parse(StringBuilder sb) throws ClassNotFoundException {
String infoString = sb.toString();
final Matcher tupleMatcher = tuplePattern.matcher(infoString);
final Matcher writableMatcher = writablePattern.matcher(infoString);
final Matcher enumMatcher = enumPattern.matcher(infoString);
final Matcher basicTypeMatcher = basicTypePattern.matcher(infoString);
final Matcher basicTypeDateMatcher = basicTypeDatePattern.matcher(infoString);
final Matcher basicTypeBigIntMatcher = basicTypeBigIntPattern.matcher(infoString);
final Matcher basicTypeBigDecMatcher = basicTypeBigDecPattern.matcher(infoString);
final Matcher primitiveTypeMatcher = primitiveTypePattern.matcher(infoString);
final Matcher valueTypeMatcher = valueTypePattern.matcher(infoString);
final Matcher pojoGenericMatcher = pojoGenericObjectPattern.matcher(infoString);
if (infoString.length() == 0) {
return null;
}
TypeInformation<?> returnType = null;
boolean isPrimitiveType = false;
// tuples
if (tupleMatcher.find()) {
boolean isGenericTuple = true;
String className = tupleMatcher.group(3);
if (className == null) {
// matched Tuple0
isGenericTuple = false;
className = tupleMatcher.group(2);
sb.delete(0, className.length());
} else {
// +1 for "<"
sb.delete(0, className.length() + 1);
}
if (infoString.startsWith(TUPLE_PACKAGE)) {
// +1 for trailing "."
sb.delete(0, TUPLE_PACKAGE.length() + 1);
}
int arity = Integer.parseInt(className.replaceAll("\\D", ""));
Class<?> clazz = loadClass(TUPLE_PACKAGE + "." + className);
TypeInformation<?>[] types = new TypeInformation<?>[arity];
for (int i = 0; i < arity; i++) {
types[i] = parse(sb);
if (types[i] == null) {
throw new IllegalArgumentException("Tuple arity does not match given parameters.");
}
}
if (isGenericTuple) {
if (sb.charAt(0) != '>') {
throw new IllegalArgumentException("Tuple arity does not match given parameters.");
}
// remove '>'
sb.deleteCharAt(0);
}
returnType = new TupleTypeInfo(clazz, types);
} else // writable types
if (writableMatcher.find()) {
String className = writableMatcher.group(1);
String fullyQualifiedName = writableMatcher.group(3);
sb.delete(0, className.length() + 1 + fullyQualifiedName.length() + 1);
Class<?> clazz = loadClass(fullyQualifiedName);
returnType = TypeExtractor.createHadoopWritableTypeInfo(clazz);
} else // enum types
if (enumMatcher.find()) {
String className = enumMatcher.group(1);
String fullyQualifiedName = enumMatcher.group(3);
sb.delete(0, className.length() + 1 + fullyQualifiedName.length() + 1);
Class<?> clazz = loadClass(fullyQualifiedName);
returnType = new EnumTypeInfo(clazz);
} else // basic types
if (basicTypeMatcher.find()) {
String className = basicTypeMatcher.group(1);
sb.delete(0, className.length());
Class<?> clazz;
// check if fully qualified
if (className.startsWith("java.lang")) {
clazz = loadClass(className);
} else {
clazz = loadClass("java.lang." + className);
}
returnType = BasicTypeInfo.getInfoFor(clazz);
} else // special basic type "Date"
if (basicTypeDateMatcher.find()) {
String className = basicTypeDateMatcher.group(1);
sb.delete(0, className.length());
Class<?> clazz;
// check if fully qualified
if (className.startsWith("java.util")) {
clazz = loadClass(className);
} else {
clazz = loadClass("java.util." + className);
}
returnType = BasicTypeInfo.getInfoFor(clazz);
} else // special basic type "BigInteger"
if (basicTypeBigIntMatcher.find()) {
String className = basicTypeBigIntMatcher.group(1);
sb.delete(0, className.length());
Class<?> clazz;
// check if fully qualified
if (className.startsWith("java.math")) {
clazz = loadClass(className);
} else {
clazz = loadClass("java.math." + className);
}
returnType = BasicTypeInfo.getInfoFor(clazz);
} else // special basic type "BigDecimal"
if (basicTypeBigDecMatcher.find()) {
String className = basicTypeBigDecMatcher.group(1);
sb.delete(0, className.length());
Class<?> clazz;
// check if fully qualified
if (className.startsWith("java.math")) {
clazz = loadClass(className);
} else {
clazz = loadClass("java.math." + className);
}
returnType = BasicTypeInfo.getInfoFor(clazz);
} else // primitive types
if (primitiveTypeMatcher.find()) {
String keyword = primitiveTypeMatcher.group(1);
sb.delete(0, keyword.length());
Class<?> clazz = null;
if (keyword.equals("int")) {
clazz = int.class;
} else if (keyword.equals("byte")) {
clazz = byte.class;
} else if (keyword.equals("short")) {
clazz = short.class;
} else if (keyword.equals("char")) {
clazz = char.class;
} else if (keyword.equals("double")) {
clazz = double.class;
} else if (keyword.equals("float")) {
clazz = float.class;
} else if (keyword.equals("long")) {
clazz = long.class;
} else if (keyword.equals("boolean")) {
clazz = boolean.class;
} else if (keyword.equals("void")) {
clazz = void.class;
}
returnType = BasicTypeInfo.getInfoFor(clazz);
isPrimitiveType = true;
} else // values
if (valueTypeMatcher.find()) {
String className = valueTypeMatcher.group(1);
sb.delete(0, className.length() + 5);
Class<?> clazz;
// check if fully qualified
if (className.startsWith(VALUE_PACKAGE)) {
clazz = loadClass(className + "Value");
} else {
clazz = loadClass(VALUE_PACKAGE + "." + className + "Value");
}
returnType = ValueTypeInfo.getValueTypeInfo((Class<Value>) clazz);
} else // pojo objects or generic types
if (pojoGenericMatcher.find()) {
String fullyQualifiedName = pojoGenericMatcher.group(1);
sb.delete(0, fullyQualifiedName.length());
boolean isPojo = pojoGenericMatcher.group(2) != null;
// pojo
if (isPojo) {
sb.deleteCharAt(0);
Class<?> clazz = loadClass(fullyQualifiedName);
ArrayList<PojoField> fields = new ArrayList<PojoField>();
while (sb.charAt(0) != '>') {
final Matcher fieldMatcher = fieldPattern.matcher(sb);
if (!fieldMatcher.find()) {
throw new IllegalArgumentException("Field name missing.");
}
String fieldName = fieldMatcher.group(1);
sb.delete(0, fieldName.length() + 1);
Field field = TypeExtractor.getDeclaredField(clazz, fieldName);
if (field == null) {
throw new IllegalArgumentException("Field '" + fieldName + "'could not be accessed.");
}
fields.add(new PojoField(field, parse(sb)));
}
// remove '>'
sb.deleteCharAt(0);
returnType = new PojoTypeInfo(clazz, fields);
} else // generic type
{
returnType = new GenericTypeInfo(loadClass(fullyQualifiedName));
}
}
if (returnType == null) {
throw new IllegalArgumentException("Error at '" + infoString + "'");
}
// arrays
int arrayDimensionCount = 0;
while (sb.length() > 1 && sb.charAt(0) == '[' && sb.charAt(1) == ']') {
arrayDimensionCount++;
sb.delete(0, 2);
}
if (sb.length() > 0 && sb.charAt(0) == '[') {
throw new IllegalArgumentException("Closing square bracket missing.");
}
// construct multidimension array
if (arrayDimensionCount > 0) {
TypeInformation<?> arrayInfo = null;
// primitive array
if (isPrimitiveType) {
if (returnType == BasicTypeInfo.INT_TYPE_INFO) {
arrayInfo = PrimitiveArrayTypeInfo.INT_PRIMITIVE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.BYTE_TYPE_INFO) {
arrayInfo = PrimitiveArrayTypeInfo.BYTE_PRIMITIVE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.SHORT_TYPE_INFO) {
arrayInfo = PrimitiveArrayTypeInfo.SHORT_PRIMITIVE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.CHAR_TYPE_INFO) {
arrayInfo = PrimitiveArrayTypeInfo.CHAR_PRIMITIVE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.DOUBLE_TYPE_INFO) {
arrayInfo = PrimitiveArrayTypeInfo.DOUBLE_PRIMITIVE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.FLOAT_TYPE_INFO) {
arrayInfo = PrimitiveArrayTypeInfo.FLOAT_PRIMITIVE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.LONG_TYPE_INFO) {
arrayInfo = PrimitiveArrayTypeInfo.LONG_PRIMITIVE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.BOOLEAN_TYPE_INFO) {
arrayInfo = PrimitiveArrayTypeInfo.BOOLEAN_PRIMITIVE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.VOID_TYPE_INFO) {
throw new IllegalArgumentException("Can not create an array of void.");
}
} else // basic array
if (returnType instanceof BasicTypeInfo && returnType != BasicTypeInfo.DATE_TYPE_INFO) {
if (returnType == BasicTypeInfo.INT_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.INT_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.BYTE_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.BYTE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.SHORT_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.SHORT_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.CHAR_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.CHAR_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.DOUBLE_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.DOUBLE_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.FLOAT_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.FLOAT_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.LONG_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.LONG_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.BOOLEAN_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.BOOLEAN_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.STRING_TYPE_INFO) {
arrayInfo = BasicArrayTypeInfo.STRING_ARRAY_TYPE_INFO;
} else if (returnType == BasicTypeInfo.VOID_TYPE_INFO) {
throw new IllegalArgumentException("Can not create an array of void.");
}
} else // object array
{
arrayInfo = ObjectArrayTypeInfo.getInfoFor(loadClass("[L" + returnType.getTypeClass().getName() + ";"), returnType);
}
// further dimensions
if (arrayDimensionCount > 1) {
String arrayPrefix = "[";
for (int i = 1; i < arrayDimensionCount; i++) {
arrayPrefix += "[";
arrayInfo = ObjectArrayTypeInfo.getInfoFor(loadClass(arrayPrefix + "L" + returnType.getTypeClass().getName() + ";"), arrayInfo);
}
}
returnType = arrayInfo;
}
// remove possible ','
if (sb.length() > 0 && sb.charAt(0) == ',') {
sb.deleteCharAt(0);
}
// check if end
return returnType;
}
use of org.apache.flink.api.common.typeinfo.BasicTypeInfo in project flink by apache.
the class PojoTypeExtractionTest method checkWCPojoAsserts.
@SuppressWarnings({ "unchecked", "rawtypes" })
private void checkWCPojoAsserts(TypeInformation<?> typeInfo) {
Assert.assertFalse(typeInfo.isBasicType());
Assert.assertFalse(typeInfo.isTupleType());
Assert.assertEquals(10, typeInfo.getTotalFields());
Assert.assertTrue(typeInfo instanceof PojoTypeInfo);
PojoTypeInfo<?> pojoType = (PojoTypeInfo<?>) typeInfo;
List<FlatFieldDescriptor> ffd = new ArrayList<FlatFieldDescriptor>();
String[] fields = { "count", "complex.date", "complex.collection", "complex.nothing", "complex.someFloat", "complex.someNumberWithÜnicödeNäme", "complex.valueType", "complex.word.f0", "complex.word.f1", "complex.word.f2" };
int[] positions = { 9, 1, 0, 2, 3, 4, 5, 6, 7, 8 };
Assert.assertEquals(fields.length, positions.length);
for (int i = 0; i < fields.length; i++) {
pojoType.getFlatFields(fields[i], 0, ffd);
Assert.assertEquals("Too many keys returned", 1, ffd.size());
Assert.assertEquals("position of field " + fields[i] + " wrong", positions[i], ffd.get(0).getPosition());
ffd.clear();
}
pojoType.getFlatFields("complex.word.*", 0, ffd);
Assert.assertEquals(3, ffd.size());
// check if it returns 5,6,7
for (FlatFieldDescriptor ffdE : ffd) {
final int pos = ffdE.getPosition();
Assert.assertTrue(pos <= 8);
Assert.assertTrue(6 <= pos);
if (pos == 6) {
Assert.assertEquals(Long.class, ffdE.getType().getTypeClass());
}
if (pos == 7) {
Assert.assertEquals(Long.class, ffdE.getType().getTypeClass());
}
if (pos == 8) {
Assert.assertEquals(String.class, ffdE.getType().getTypeClass());
}
}
ffd.clear();
// scala style full tuple selection for pojos
pojoType.getFlatFields("complex.word._", 0, ffd);
Assert.assertEquals(3, ffd.size());
ffd.clear();
pojoType.getFlatFields("complex.*", 0, ffd);
Assert.assertEquals(9, ffd.size());
// check if it returns 0-7
for (FlatFieldDescriptor ffdE : ffd) {
final int pos = ffdE.getPosition();
Assert.assertTrue(ffdE.getPosition() <= 8);
Assert.assertTrue(0 <= ffdE.getPosition());
if (pos == 0) {
Assert.assertEquals(List.class, ffdE.getType().getTypeClass());
}
if (pos == 1) {
Assert.assertEquals(Date.class, ffdE.getType().getTypeClass());
}
if (pos == 2) {
Assert.assertEquals(Object.class, ffdE.getType().getTypeClass());
}
if (pos == 3) {
Assert.assertEquals(Float.class, ffdE.getType().getTypeClass());
}
if (pos == 4) {
Assert.assertEquals(Integer.class, ffdE.getType().getTypeClass());
}
if (pos == 5) {
Assert.assertEquals(MyValue.class, ffdE.getType().getTypeClass());
}
if (pos == 6) {
Assert.assertEquals(Long.class, ffdE.getType().getTypeClass());
}
if (pos == 7) {
Assert.assertEquals(Long.class, ffdE.getType().getTypeClass());
}
if (pos == 8) {
Assert.assertEquals(String.class, ffdE.getType().getTypeClass());
}
if (pos == 9) {
Assert.assertEquals(Integer.class, ffdE.getType().getTypeClass());
}
}
ffd.clear();
pojoType.getFlatFields("*", 0, ffd);
Assert.assertEquals(10, ffd.size());
// check if it returns 0-8
for (FlatFieldDescriptor ffdE : ffd) {
Assert.assertTrue(ffdE.getPosition() <= 9);
Assert.assertTrue(0 <= ffdE.getPosition());
if (ffdE.getPosition() == 9) {
Assert.assertEquals(Integer.class, ffdE.getType().getTypeClass());
}
}
ffd.clear();
// ComplexNestedClass complex
TypeInformation<?> typeComplexNested = pojoType.getTypeAt(0);
Assert.assertTrue(typeComplexNested instanceof PojoTypeInfo);
Assert.assertEquals(7, typeComplexNested.getArity());
Assert.assertEquals(9, typeComplexNested.getTotalFields());
PojoTypeInfo<?> pojoTypeComplexNested = (PojoTypeInfo<?>) typeComplexNested;
boolean dateSeen = false, intSeen = false, floatSeen = false, tupleSeen = false, objectSeen = false, writableSeen = false, collectionSeen = false;
for (int i = 0; i < pojoTypeComplexNested.getArity(); i++) {
PojoField field = pojoTypeComplexNested.getPojoFieldAt(i);
String name = field.getField().getName();
if (name.equals("date")) {
if (dateSeen) {
Assert.fail("already seen");
}
dateSeen = true;
Assert.assertEquals(BasicTypeInfo.DATE_TYPE_INFO, field.getTypeInformation());
Assert.assertEquals(Date.class, field.getTypeInformation().getTypeClass());
} else if (name.equals("someNumberWithÜnicödeNäme")) {
if (intSeen) {
Assert.fail("already seen");
}
intSeen = true;
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, field.getTypeInformation());
Assert.assertEquals(Integer.class, field.getTypeInformation().getTypeClass());
} else if (name.equals("someFloat")) {
if (floatSeen) {
Assert.fail("already seen");
}
floatSeen = true;
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, field.getTypeInformation());
Assert.assertEquals(Float.class, field.getTypeInformation().getTypeClass());
} else if (name.equals("word")) {
if (tupleSeen) {
Assert.fail("already seen");
}
tupleSeen = true;
Assert.assertTrue(field.getTypeInformation() instanceof TupleTypeInfo<?>);
Assert.assertEquals(Tuple3.class, field.getTypeInformation().getTypeClass());
// do some more advanced checks on the tuple
TupleTypeInfo<?> tupleTypeFromComplexNested = (TupleTypeInfo<?>) field.getTypeInformation();
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tupleTypeFromComplexNested.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tupleTypeFromComplexNested.getTypeAt(1));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tupleTypeFromComplexNested.getTypeAt(2));
} else if (name.equals("nothing")) {
if (objectSeen) {
Assert.fail("already seen");
}
objectSeen = true;
Assert.assertEquals(new GenericTypeInfo<Object>(Object.class), field.getTypeInformation());
Assert.assertEquals(Object.class, field.getTypeInformation().getTypeClass());
} else if (name.equals("valueType")) {
if (writableSeen) {
Assert.fail("already seen");
}
writableSeen = true;
Assert.assertEquals(new ValueTypeInfo<>(MyValue.class), field.getTypeInformation());
Assert.assertEquals(MyValue.class, field.getTypeInformation().getTypeClass());
} else if (name.equals("collection")) {
if (collectionSeen) {
Assert.fail("already seen");
}
collectionSeen = true;
Assert.assertEquals(new GenericTypeInfo(List.class), field.getTypeInformation());
} else {
Assert.fail("field " + field + " is not expected");
}
}
Assert.assertTrue("Field was not present", dateSeen);
Assert.assertTrue("Field was not present", intSeen);
Assert.assertTrue("Field was not present", floatSeen);
Assert.assertTrue("Field was not present", tupleSeen);
Assert.assertTrue("Field was not present", objectSeen);
Assert.assertTrue("Field was not present", writableSeen);
Assert.assertTrue("Field was not present", collectionSeen);
// int count
TypeInformation<?> typeAtOne = pojoType.getTypeAt(1);
Assert.assertTrue(typeAtOne instanceof BasicTypeInfo);
Assert.assertEquals(typeInfo.getTypeClass(), WC.class);
Assert.assertEquals(typeInfo.getArity(), 2);
}
use of org.apache.flink.api.common.typeinfo.BasicTypeInfo in project flink by apache.
the class TypeExtractor method validateInfo.
@SuppressWarnings("unchecked")
private static void validateInfo(ArrayList<Type> typeHierarchy, Type type, TypeInformation<?> typeInfo) {
if (type == null) {
throw new InvalidTypesException("Unknown Error. Type is null.");
}
if (typeInfo == null) {
throw new InvalidTypesException("Unknown Error. TypeInformation is null.");
}
if (!(type instanceof TypeVariable<?>)) {
// check for Java Basic Types
if (typeInfo instanceof BasicTypeInfo) {
TypeInformation<?> actual;
// check if basic type at all
if (!(type instanceof Class<?>) || (actual = BasicTypeInfo.getInfoFor((Class<?>) type)) == null) {
throw new InvalidTypesException("Basic type expected.");
}
// check if correct basic type
if (!typeInfo.equals(actual)) {
throw new InvalidTypesException("Basic type '" + typeInfo + "' expected but was '" + actual + "'.");
}
} else // check for Java SQL time types
if (typeInfo instanceof SqlTimeTypeInfo) {
TypeInformation<?> actual;
// check if SQL time type at all
if (!(type instanceof Class<?>) || (actual = SqlTimeTypeInfo.getInfoFor((Class<?>) type)) == null) {
throw new InvalidTypesException("SQL time type expected.");
}
// check if correct SQL time type
if (!typeInfo.equals(actual)) {
throw new InvalidTypesException("SQL time type '" + typeInfo + "' expected but was '" + actual + "'.");
}
} else // check for Java Tuples
if (typeInfo instanceof TupleTypeInfo) {
// check if tuple at all
if (!(isClassType(type) && Tuple.class.isAssignableFrom(typeToClass(type)))) {
throw new InvalidTypesException("Tuple type expected.");
}
// do not allow usage of Tuple as type
if (isClassType(type) && typeToClass(type).equals(Tuple.class)) {
throw new InvalidTypesException("Concrete subclass of Tuple expected.");
}
// go up the hierarchy until we reach immediate child of Tuple (with or without generics)
while (!(isClassType(type) && typeToClass(type).getSuperclass().equals(Tuple.class))) {
typeHierarchy.add(type);
type = typeToClass(type).getGenericSuperclass();
}
if (type == Tuple0.class) {
return;
}
// check if immediate child of Tuple has generics
if (type instanceof Class<?>) {
throw new InvalidTypesException("Parameterized Tuple type expected.");
}
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) typeInfo;
Type[] subTypes = ((ParameterizedType) type).getActualTypeArguments();
if (subTypes.length != tti.getArity()) {
throw new InvalidTypesException("Tuple arity '" + tti.getArity() + "' expected but was '" + subTypes.length + "'.");
}
for (int i = 0; i < subTypes.length; i++) {
validateInfo(new ArrayList<Type>(typeHierarchy), subTypes[i], tti.getTypeAt(i));
}
} else // check for primitive array
if (typeInfo instanceof PrimitiveArrayTypeInfo) {
Type component;
// check if array at all
if (!(type instanceof Class<?> && ((Class<?>) type).isArray() && (component = ((Class<?>) type).getComponentType()) != null) && !(type instanceof GenericArrayType && (component = ((GenericArrayType) type).getGenericComponentType()) != null)) {
throw new InvalidTypesException("Array type expected.");
}
if (component instanceof TypeVariable<?>) {
component = materializeTypeVariable(typeHierarchy, (TypeVariable<?>) component);
if (component instanceof TypeVariable) {
return;
}
}
if (!(component instanceof Class<?> && ((Class<?>) component).isPrimitive())) {
throw new InvalidTypesException("Primitive component expected.");
}
} else // check for basic array
if (typeInfo instanceof BasicArrayTypeInfo<?, ?>) {
Type component;
// check if array at all
if (!(type instanceof Class<?> && ((Class<?>) type).isArray() && (component = ((Class<?>) type).getComponentType()) != null) && !(type instanceof GenericArrayType && (component = ((GenericArrayType) type).getGenericComponentType()) != null)) {
throw new InvalidTypesException("Array type expected.");
}
if (component instanceof TypeVariable<?>) {
component = materializeTypeVariable(typeHierarchy, (TypeVariable<?>) component);
if (component instanceof TypeVariable) {
return;
}
}
validateInfo(typeHierarchy, component, ((BasicArrayTypeInfo<?, ?>) typeInfo).getComponentInfo());
} else // check for object array
if (typeInfo instanceof ObjectArrayTypeInfo<?, ?>) {
// check if array at all
if (!(type instanceof Class<?> && ((Class<?>) type).isArray()) && !(type instanceof GenericArrayType)) {
throw new InvalidTypesException("Object array type expected.");
}
// check component
Type component;
if (type instanceof Class<?>) {
component = ((Class<?>) type).getComponentType();
} else {
component = ((GenericArrayType) type).getGenericComponentType();
}
if (component instanceof TypeVariable<?>) {
component = materializeTypeVariable(typeHierarchy, (TypeVariable<?>) component);
if (component instanceof TypeVariable) {
return;
}
}
validateInfo(typeHierarchy, component, ((ObjectArrayTypeInfo<?, ?>) typeInfo).getComponentInfo());
} else // check for value
if (typeInfo instanceof ValueTypeInfo<?>) {
// check if value at all
if (!(type instanceof Class<?> && Value.class.isAssignableFrom((Class<?>) type))) {
throw new InvalidTypesException("Value type expected.");
}
TypeInformation<?> actual;
// check value type contents
if (!((ValueTypeInfo<?>) typeInfo).equals(actual = ValueTypeInfo.getValueTypeInfo((Class<? extends Value>) type))) {
throw new InvalidTypesException("Value type '" + typeInfo + "' expected but was '" + actual + "'.");
}
} else // check for POJO
if (typeInfo instanceof PojoTypeInfo) {
Class<?> clazz = null;
if (!(isClassType(type) && ((PojoTypeInfo<?>) typeInfo).getTypeClass() == (clazz = typeToClass(type)))) {
throw new InvalidTypesException("POJO type '" + ((PojoTypeInfo<?>) typeInfo).getTypeClass().getCanonicalName() + "' expected but was '" + clazz.getCanonicalName() + "'.");
}
} else // check for Enum
if (typeInfo instanceof EnumTypeInfo) {
if (!(type instanceof Class<?> && Enum.class.isAssignableFrom((Class<?>) type))) {
throw new InvalidTypesException("Enum type expected.");
}
// check enum type contents
if (!(typeInfo.getTypeClass() == type)) {
throw new InvalidTypesException("Enum type '" + typeInfo.getTypeClass().getCanonicalName() + "' expected but was '" + typeToClass(type).getCanonicalName() + "'.");
}
} else // check for generic object
if (typeInfo instanceof GenericTypeInfo<?>) {
Class<?> clazz = null;
if (!(isClassType(type) && (clazz = typeToClass(type)).isAssignableFrom(((GenericTypeInfo<?>) typeInfo).getTypeClass()))) {
throw new InvalidTypesException("Generic type '" + ((GenericTypeInfo<?>) typeInfo).getTypeClass().getCanonicalName() + "' or a subclass of it expected but was '" + clazz.getCanonicalName() + "'.");
}
} else // check for Writable
{
validateIfWritable(typeInfo, type);
}
} else {
type = materializeTypeVariable(typeHierarchy, (TypeVariable<?>) type);
if (!(type instanceof TypeVariable)) {
validateInfo(typeHierarchy, type, typeInfo);
}
}
}
use of org.apache.flink.api.common.typeinfo.BasicTypeInfo in project flink by apache.
the class TypeExtractorTest method testTupleWithBasicTypes.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testTupleWithBasicTypes() throws Exception {
// use getMapReturnTypes()
RichMapFunction<?, ?> function = new RichMapFunction<Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte>, Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte>>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte> map(Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(9, ti.getArity());
Assert.assertTrue(ti instanceof TupleTypeInfo);
List<FlatFieldDescriptor> ffd = new ArrayList<FlatFieldDescriptor>();
((TupleTypeInfo) ti).getFlatFields("f3", 0, ffd);
Assert.assertTrue(ffd.size() == 1);
Assert.assertEquals(3, ffd.get(0).getPosition());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(Tuple9.class, tti.getTypeClass());
for (int i = 0; i < 9; i++) {
Assert.assertTrue(tti.getTypeAt(i) instanceof BasicTypeInfo);
}
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tti.getTypeAt(1));
Assert.assertEquals(BasicTypeInfo.DOUBLE_TYPE_INFO, tti.getTypeAt(2));
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti.getTypeAt(3));
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, tti.getTypeAt(4));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(5));
Assert.assertEquals(BasicTypeInfo.CHAR_TYPE_INFO, tti.getTypeAt(6));
Assert.assertEquals(BasicTypeInfo.SHORT_TYPE_INFO, tti.getTypeAt(7));
Assert.assertEquals(BasicTypeInfo.BYTE_TYPE_INFO, tti.getTypeAt(8));
// use getForObject()
Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte> t = new Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte>(1, 1L, 1.0, 1.0F, false, "Hello World", 'w', (short) 1, (byte) 1);
Assert.assertTrue(TypeExtractor.getForObject(t) instanceof TupleTypeInfo);
TupleTypeInfo<?> tti2 = (TupleTypeInfo<?>) TypeExtractor.getForObject(t);
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, tti2.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tti2.getTypeAt(1));
Assert.assertEquals(BasicTypeInfo.DOUBLE_TYPE_INFO, tti2.getTypeAt(2));
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti2.getTypeAt(3));
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, tti2.getTypeAt(4));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti2.getTypeAt(5));
Assert.assertEquals(BasicTypeInfo.CHAR_TYPE_INFO, tti2.getTypeAt(6));
Assert.assertEquals(BasicTypeInfo.SHORT_TYPE_INFO, tti2.getTypeAt(7));
Assert.assertEquals(BasicTypeInfo.BYTE_TYPE_INFO, tti2.getTypeAt(8));
// test that getForClass does not work
try {
TypeExtractor.getForClass(Tuple9.class);
Assert.fail("Exception expected here");
} catch (InvalidTypesException e) {
// that is correct
}
}
use of org.apache.flink.api.common.typeinfo.BasicTypeInfo in project flink by apache.
the class FieldAccessorFactory method getAccessor.
/**
* Creates a {@link FieldAccessor} for the field that is given by a field expression,
* which can be used to get and set the specified field on instances of this type.
*
* @param field The field expression
* @param config Configuration object
* @param <F> The type of the field to access
* @return The created FieldAccessor
*/
@Internal
public static <T, F> FieldAccessor<T, F> getAccessor(TypeInformation<T> typeInfo, String field, ExecutionConfig config) {
// In case of arrays
if (typeInfo instanceof BasicArrayTypeInfo || typeInfo instanceof PrimitiveArrayTypeInfo) {
try {
return new FieldAccessor.ArrayFieldAccessor<>(Integer.parseInt(field), typeInfo);
} catch (NumberFormatException ex) {
throw new CompositeType.InvalidFieldReferenceException("A field expression on an array must be an integer index (that might be given as a string).");
}
// In case of basic types
} else if (typeInfo instanceof BasicTypeInfo) {
try {
int pos = field.equals(Keys.ExpressionKeys.SELECT_ALL_CHAR) ? 0 : Integer.parseInt(field);
return FieldAccessorFactory.getAccessor(typeInfo, pos, config);
} catch (NumberFormatException ex) {
throw new CompositeType.InvalidFieldReferenceException("You tried to select the field \"" + field + "\" on a " + typeInfo.toString() + ". A field expression on a basic type can only be \"*\" or \"0\"" + " (both of which mean selecting the entire basic type).");
}
// In case of Pojos
} else if (typeInfo instanceof PojoTypeInfo) {
FieldExpression decomp = decomposeFieldExpression(field);
PojoTypeInfo<?> pojoTypeInfo = (PojoTypeInfo) typeInfo;
int fieldIndex = pojoTypeInfo.getFieldIndex(decomp.head);
if (fieldIndex == -1) {
throw new CompositeType.InvalidFieldReferenceException("Unable to find field \"" + decomp.head + "\" in type " + typeInfo + ".");
} else {
PojoField pojoField = pojoTypeInfo.getPojoFieldAt(fieldIndex);
TypeInformation<?> fieldType = pojoTypeInfo.getTypeAt(fieldIndex);
if (decomp.tail == null) {
@SuppressWarnings("unchecked") FieldAccessor<F, F> innerAccessor = new FieldAccessor.SimpleFieldAccessor<>((TypeInformation<F>) fieldType);
return new FieldAccessor.PojoFieldAccessor<>(pojoField.getField(), innerAccessor);
} else {
@SuppressWarnings("unchecked") FieldAccessor<Object, F> innerAccessor = FieldAccessorFactory.getAccessor((TypeInformation<Object>) fieldType, decomp.tail, config);
return new FieldAccessor.PojoFieldAccessor<>(pojoField.getField(), innerAccessor);
}
}
// In case of case classes
} else if (typeInfo.isTupleType() && ((TupleTypeInfoBase) typeInfo).isCaseClass()) {
TupleTypeInfoBase tupleTypeInfo = (TupleTypeInfoBase) typeInfo;
FieldExpression decomp = decomposeFieldExpression(field);
int fieldPos = tupleTypeInfo.getFieldIndex(decomp.head);
if (fieldPos < 0) {
throw new CompositeType.InvalidFieldReferenceException("Invalid field selected: " + field);
}
if (decomp.tail == null) {
return new FieldAccessor.SimpleProductFieldAccessor<>(fieldPos, typeInfo, config);
} else {
@SuppressWarnings("unchecked") FieldAccessor<Object, F> innerAccessor = getAccessor(tupleTypeInfo.getTypeAt(fieldPos), decomp.tail, config);
return new FieldAccessor.RecursiveProductFieldAccessor<>(fieldPos, typeInfo, innerAccessor, config);
}
// In case of tuples
} else if (typeInfo.isTupleType()) {
TupleTypeInfo tupleTypeInfo = (TupleTypeInfo) typeInfo;
FieldExpression decomp = decomposeFieldExpression(field);
int fieldPos = tupleTypeInfo.getFieldIndex(decomp.head);
if (fieldPos == -1) {
try {
fieldPos = Integer.parseInt(decomp.head);
} catch (NumberFormatException ex) {
throw new CompositeType.InvalidFieldReferenceException("Tried to select field \"" + decomp.head + "\" on " + typeInfo.toString() + " . Only integer values are allowed here.");
}
}
if (decomp.tail == null) {
@SuppressWarnings("unchecked") FieldAccessor<T, F> result = new FieldAccessor.SimpleTupleFieldAccessor(fieldPos, tupleTypeInfo);
return result;
} else {
@SuppressWarnings("unchecked") FieldAccessor<?, F> innerAccessor = getAccessor(tupleTypeInfo.getTypeAt(fieldPos), decomp.tail, config);
@SuppressWarnings("unchecked") FieldAccessor<T, F> result = new FieldAccessor.RecursiveTupleFieldAccessor(fieldPos, innerAccessor, tupleTypeInfo);
return result;
}
// Default statement
} else {
throw new CompositeType.InvalidFieldReferenceException("Cannot reference field by field expression on " + typeInfo.toString() + "Field expressions are only supported on POJO types, tuples, and case classes. " + "(See the Flink documentation on what is considered a POJO.)");
}
}
Aggregations