Search in sources :

Example 26 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class TypeExtractor method createSubTypesInfo.

/**
 * Creates the TypeInformation for all elements of a type that expects a certain number of
 * subtypes (e.g. TupleXX).
 *
 * @param originalType most concrete subclass
 * @param definingType type that defines the number of subtypes (e.g. Tuple2 -> 2 subtypes)
 * @param typeHierarchy necessary for type inference
 * @param in1Type necessary for type inference
 * @param in2Type necessary for type inference
 * @param lenient decides whether exceptions should be thrown if a subtype can not be determined
 * @return array containing TypeInformation of sub types or null if definingType contains more
 *     subtypes (fields) that defined
 */
private <IN1, IN2> TypeInformation<?>[] createSubTypesInfo(Type originalType, ParameterizedType definingType, List<Type> typeHierarchy, TypeInformation<IN1> in1Type, TypeInformation<IN2> in2Type, boolean lenient) {
    Type[] subtypes = new Type[definingType.getActualTypeArguments().length];
    // materialize possible type variables
    for (int i = 0; i < subtypes.length; i++) {
        final Type actualTypeArg = definingType.getActualTypeArguments()[i];
        // materialize immediate TypeVariables
        if (actualTypeArg instanceof TypeVariable<?>) {
            subtypes[i] = materializeTypeVariable(typeHierarchy, (TypeVariable<?>) actualTypeArg);
        } else // class or parameterized type
        {
            subtypes[i] = actualTypeArg;
        }
    }
    TypeInformation<?>[] subTypesInfo = new TypeInformation<?>[subtypes.length];
    for (int i = 0; i < subtypes.length; i++) {
        final List<Type> subTypeHierarchy = new ArrayList<>(typeHierarchy);
        subTypeHierarchy.add(subtypes[i]);
        // as a last attempt
        if (subtypes[i] instanceof TypeVariable<?>) {
            subTypesInfo[i] = createTypeInfoFromInputs((TypeVariable<?>) subtypes[i], subTypeHierarchy, in1Type, in2Type);
            // variable could not be determined
            if (subTypesInfo[i] == null && !lenient) {
                throw new InvalidTypesException("Type of TypeVariable '" + ((TypeVariable<?>) subtypes[i]).getName() + "' in '" + ((TypeVariable<?>) subtypes[i]).getGenericDeclaration() + "' could not be determined. This is most likely a type erasure problem. " + "The type extraction currently supports types with generic variables only in cases where " + "all variables in the return type can be deduced from the input type(s). " + "Otherwise the type has to be specified explicitly using type information.");
            }
        } else {
            // create the type information of the subtype or null/exception
            try {
                subTypesInfo[i] = createTypeInfoWithTypeHierarchy(subTypeHierarchy, subtypes[i], in1Type, in2Type);
            } catch (InvalidTypesException e) {
                if (lenient) {
                    subTypesInfo[i] = null;
                } else {
                    throw e;
                }
            }
        }
    }
    // check that number of fields matches the number of subtypes
    if (!lenient) {
        Class<?> originalTypeAsClass = null;
        if (isClassType(originalType)) {
            originalTypeAsClass = typeToClass(originalType);
        }
        checkNotNull(originalTypeAsClass, "originalType has an unexpected type");
        // check if the class we assumed to conform to the defining type so far is actually a
        // pojo because the
        // original type contains additional fields.
        // check for additional fields.
        int fieldCount = countFieldsInClass(originalTypeAsClass);
        if (fieldCount > subTypesInfo.length) {
            return null;
        }
    }
    return subTypesInfo;
}
Also used : GenericArrayType(java.lang.reflect.GenericArrayType) TypeExtractionUtils.isClassType(org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType) Type(java.lang.reflect.Type) CompositeType(org.apache.flink.api.common.typeutils.CompositeType) ParameterizedType(java.lang.reflect.ParameterizedType) TypeVariable(java.lang.reflect.TypeVariable) ArrayList(java.util.ArrayList) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException) TypeInformation(org.apache.flink.api.common.typeinfo.TypeInformation)

Example 27 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class TypeExtractor method createTypeInfoFromInput.

/**
 * Finds the type information to a type variable.
 *
 * <p>It solve the following:
 *
 * <p>Return the type information for "returnTypeVar" given that "inType" has type information
 * "inTypeInfo". Thus "inType" must contain "returnTypeVar" in a "inputTypeHierarchy", otherwise
 * null is returned.
 */
private <IN1> TypeInformation<?> createTypeInfoFromInput(TypeVariable<?> returnTypeVar, List<Type> inputTypeHierarchy, Type inType, TypeInformation<IN1> inTypeInfo) {
    TypeInformation<?> info = null;
    // use a factory to find corresponding type information to type variable
    final List<Type> factoryHierarchy = new ArrayList<>(inputTypeHierarchy);
    final TypeInfoFactory<?> factory = getClosestFactory(factoryHierarchy, inType);
    if (factory != null) {
        // the type that defines the factory is last in factory hierarchy
        final Type factoryDefiningType = factoryHierarchy.get(factoryHierarchy.size() - 1);
        // type information
        if (factoryDefiningType instanceof ParameterizedType) {
            final Type[] typeParams = typeToClass(factoryDefiningType).getTypeParameters();
            final Type[] actualParams = ((ParameterizedType) factoryDefiningType).getActualTypeArguments();
            // go thru all elements and search for type variables
            for (int i = 0; i < actualParams.length; i++) {
                final Map<String, TypeInformation<?>> componentInfo = inTypeInfo.getGenericParameters();
                final String typeParamName = typeParams[i].toString();
                if (!componentInfo.containsKey(typeParamName) || componentInfo.get(typeParamName) == null) {
                    throw new InvalidTypesException("TypeInformation '" + inTypeInfo.getClass().getSimpleName() + "' does not supply a mapping of TypeVariable '" + typeParamName + "' to corresponding TypeInformation. " + "Input type inference can only produce a result with this information. " + "Please implement method 'TypeInformation.getGenericParameters()' for this.");
                }
                info = createTypeInfoFromInput(returnTypeVar, factoryHierarchy, actualParams[i], componentInfo.get(typeParamName));
                if (info != null) {
                    break;
                }
            }
        }
    } else // the input is a type variable
    if (sameTypeVars(inType, returnTypeVar)) {
        return inTypeInfo;
    } else if (inType instanceof TypeVariable) {
        Type resolvedInType = materializeTypeVariable(inputTypeHierarchy, (TypeVariable<?>) inType);
        if (resolvedInType != inType) {
            info = createTypeInfoFromInput(returnTypeVar, inputTypeHierarchy, resolvedInType, inTypeInfo);
        }
    } else // input is an array
    if (inType instanceof GenericArrayType) {
        TypeInformation<?> componentInfo = null;
        if (inTypeInfo instanceof BasicArrayTypeInfo) {
            componentInfo = ((BasicArrayTypeInfo<?, ?>) inTypeInfo).getComponentInfo();
        } else if (inTypeInfo instanceof PrimitiveArrayTypeInfo) {
            componentInfo = BasicTypeInfo.getInfoFor(inTypeInfo.getTypeClass().getComponentType());
        } else if (inTypeInfo instanceof ObjectArrayTypeInfo) {
            componentInfo = ((ObjectArrayTypeInfo<?, ?>) inTypeInfo).getComponentInfo();
        }
        info = createTypeInfoFromInput(returnTypeVar, inputTypeHierarchy, ((GenericArrayType) inType).getGenericComponentType(), componentInfo);
    } else // the input is a tuple
    if (inTypeInfo instanceof TupleTypeInfo && isClassType(inType) && Tuple.class.isAssignableFrom(typeToClass(inType))) {
        ParameterizedType tupleBaseClass;
        // get tuple from possible tuple subclass
        while (!(isClassType(inType) && typeToClass(inType).getSuperclass().equals(Tuple.class))) {
            inputTypeHierarchy.add(inType);
            inType = typeToClass(inType).getGenericSuperclass();
        }
        inputTypeHierarchy.add(inType);
        // we can assume to be parameterized since we
        // already did input validation
        tupleBaseClass = (ParameterizedType) inType;
        Type[] tupleElements = tupleBaseClass.getActualTypeArguments();
        // go thru all tuple elements and search for type variables
        for (int i = 0; i < tupleElements.length; i++) {
            info = createTypeInfoFromInput(returnTypeVar, inputTypeHierarchy, tupleElements[i], ((TupleTypeInfo<?>) inTypeInfo).getTypeAt(i));
            if (info != null) {
                break;
            }
        }
    } else // the input is a pojo
    if (inTypeInfo instanceof PojoTypeInfo && isClassType(inType)) {
        // build the entire type hierarchy for the pojo
        getTypeHierarchy(inputTypeHierarchy, inType, Object.class);
        // determine a field containing the type variable
        List<Field> fields = getAllDeclaredFields(typeToClass(inType), false);
        for (Field field : fields) {
            Type fieldType = field.getGenericType();
            if (fieldType instanceof TypeVariable && sameTypeVars(returnTypeVar, materializeTypeVariable(inputTypeHierarchy, (TypeVariable<?>) fieldType))) {
                return getTypeOfPojoField(inTypeInfo, field);
            } else if (fieldType instanceof ParameterizedType || fieldType instanceof GenericArrayType) {
                List<Type> typeHierarchyWithFieldType = new ArrayList<>(inputTypeHierarchy);
                typeHierarchyWithFieldType.add(fieldType);
                TypeInformation<?> foundInfo = createTypeInfoFromInput(returnTypeVar, typeHierarchyWithFieldType, fieldType, getTypeOfPojoField(inTypeInfo, field));
                if (foundInfo != null) {
                    return foundInfo;
                }
            }
        }
    }
    return info;
}
Also used : ArrayList(java.util.ArrayList) GenericArrayType(java.lang.reflect.GenericArrayType) TypeInformation(org.apache.flink.api.common.typeinfo.TypeInformation) ParameterizedType(java.lang.reflect.ParameterizedType) Field(java.lang.reflect.Field) GenericArrayType(java.lang.reflect.GenericArrayType) TypeExtractionUtils.isClassType(org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType) Type(java.lang.reflect.Type) CompositeType(org.apache.flink.api.common.typeutils.CompositeType) ParameterizedType(java.lang.reflect.ParameterizedType) TypeVariable(java.lang.reflect.TypeVariable) PrimitiveArrayTypeInfo(org.apache.flink.api.common.typeinfo.PrimitiveArrayTypeInfo) List(java.util.List) ArrayList(java.util.ArrayList) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException) BasicArrayTypeInfo(org.apache.flink.api.common.typeinfo.BasicArrayTypeInfo) Tuple(org.apache.flink.api.java.tuple.Tuple)

Example 28 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class TypeExtractor method getAllDeclaredFields.

/**
 * Recursively determine all declared fields This is required because class.getFields() is not
 * returning fields defined in parent classes.
 *
 * @param clazz class to be analyzed
 * @param ignoreDuplicates if true, in case of duplicate field names only the lowest one in a
 *     hierarchy will be returned; throws an exception otherwise
 * @return list of fields
 */
@PublicEvolving
public static List<Field> getAllDeclaredFields(Class<?> clazz, boolean ignoreDuplicates) {
    List<Field> result = new ArrayList<>();
    while (clazz != null) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
                // we have no use for transient or static fields
                continue;
            }
            if (hasFieldWithSameName(field.getName(), result)) {
                if (ignoreDuplicates) {
                    continue;
                } else {
                    throw new InvalidTypesException("The field " + field + " is already contained in the hierarchy of the " + clazz + "." + "Please use unique field names through your classes hierarchy");
                }
            }
            result.add(field);
        }
        clazz = clazz.getSuperclass();
    }
    return result;
}
Also used : Field(java.lang.reflect.Field) ArrayList(java.util.ArrayList) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException) PublicEvolving(org.apache.flink.annotation.PublicEvolving)

Example 29 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class TypeExtractor method getParameterType.

private static Type getParameterType(Class<?> baseClass, List<Type> typeHierarchy, Class<?> clazz, int pos) {
    if (typeHierarchy != null) {
        typeHierarchy.add(clazz);
    }
    Type[] interfaceTypes = clazz.getGenericInterfaces();
    // search in interfaces for base class
    for (Type t : interfaceTypes) {
        Type parameter = getParameterTypeFromGenericType(baseClass, typeHierarchy, t, pos);
        if (parameter != null) {
            return parameter;
        }
    }
    // search in superclass for base class
    Type t = clazz.getGenericSuperclass();
    Type parameter = getParameterTypeFromGenericType(baseClass, typeHierarchy, t, pos);
    if (parameter != null) {
        return parameter;
    }
    throw new InvalidTypesException("The types of the interface " + baseClass.getName() + " could not be inferred. " + "Support for synthetic interfaces, lambdas, and generic or raw types is limited at this point");
}
Also used : GenericArrayType(java.lang.reflect.GenericArrayType) TypeExtractionUtils.isClassType(org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType) Type(java.lang.reflect.Type) CompositeType(org.apache.flink.api.common.typeutils.CompositeType) ParameterizedType(java.lang.reflect.ParameterizedType) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException)

Example 30 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException 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) TypeInformation.of(new TypeHint<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
    }
}
Also used : ArrayList(java.util.ArrayList) Tuple9(org.apache.flink.api.java.tuple.Tuple9) FlatFieldDescriptor(org.apache.flink.api.common.typeutils.CompositeType.FlatFieldDescriptor) TypeHint(org.apache.flink.api.common.typeinfo.TypeHint) BigInteger(java.math.BigInteger) RichMapFunction(org.apache.flink.api.common.functions.RichMapFunction) BasicTypeInfo(org.apache.flink.api.common.typeinfo.BasicTypeInfo) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException) Test(org.junit.Test)

Aggregations

InvalidTypesException (org.apache.flink.api.common.functions.InvalidTypesException)31 GenericArrayType (java.lang.reflect.GenericArrayType)19 ParameterizedType (java.lang.reflect.ParameterizedType)19 Type (java.lang.reflect.Type)19 CompositeType (org.apache.flink.api.common.typeutils.CompositeType)19 TypeExtractionUtils.isClassType (org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType)19 ArrayList (java.util.ArrayList)12 TypeInformation (org.apache.flink.api.common.typeinfo.TypeInformation)12 Field (java.lang.reflect.Field)6 TypeVariable (java.lang.reflect.TypeVariable)6 PrimitiveArrayTypeInfo (org.apache.flink.api.common.typeinfo.PrimitiveArrayTypeInfo)6 Method (java.lang.reflect.Method)5 PublicEvolving (org.apache.flink.annotation.PublicEvolving)5 BasicArrayTypeInfo (org.apache.flink.api.common.typeinfo.BasicArrayTypeInfo)5 Tuple (org.apache.flink.api.java.tuple.Tuple)5 TypeExtractionUtils.typeToClass (org.apache.flink.api.java.typeutils.TypeExtractionUtils.typeToClass)5 BasicTypeInfo (org.apache.flink.api.common.typeinfo.BasicTypeInfo)4 LambdaExecutable (org.apache.flink.api.java.typeutils.TypeExtractionUtils.LambdaExecutable)4 SqlTimeTypeInfo (org.apache.flink.api.common.typeinfo.SqlTimeTypeInfo)3 Constructor (java.lang.reflect.Constructor)2