use of co.cask.cdap.etl.common.guice.TypeResolver in project cdap by caskdata.
the class PipelineTypeValidator method validateTypes.
/**
* Takes in an unresolved type list and resolves the types and verifies if the types are assignable.
* Ex: An unresolved type could be : String, T, List<T>, List<String>
* The above will resolve to : String, String, List<String>, List<String>
* And the assignability will be checked : String --> String && List<String> --> List<String>
* which is true in the case above.
*/
@VisibleForTesting
static void validateTypes(List<Type> unresTypeList) {
Preconditions.checkArgument(unresTypeList.size() % 2 == 0, "ETL Stages validation expects even number of types");
List<Type> resTypeList = Lists.newArrayListWithCapacity(unresTypeList.size());
// Add the source output to resolved type list as the first resolved type.
resTypeList.add(unresTypeList.get(0));
try {
// Resolve the second type using just the first resolved type.
Type nType = (new TypeResolver()).where(unresTypeList.get(1), resTypeList.get(0)).resolveType(unresTypeList.get(1));
resTypeList.add(nType);
} catch (IllegalArgumentException e) {
// If unable to resolve type, add the second type as is, to the resolved list.
resTypeList.add(unresTypeList.get(1));
}
for (int i = 2; i < unresTypeList.size(); i++) {
// ActualType is previous resolved type; FormalType is previous unresolved type;
// ToResolveType is current unresolved type;
// Ex: Actual = String; Formal = T; ToResolve = List<T>; ==> newType = List<String>
Type actualType = resTypeList.get(i - 1);
Type formalType = unresTypeList.get(i - 1);
Type toResolveType = unresTypeList.get(i);
try {
Type newType;
// newType should be List<String>. Hence resolve only from the previous resolved type (Actual)
if ((toResolveType instanceof TypeVariable) || (toResolveType instanceof GenericArrayType)) {
newType = (new TypeResolver()).where(toResolveType, actualType).resolveType(toResolveType);
} else {
newType = (new TypeResolver()).where(formalType, actualType).resolveType(toResolveType);
}
resTypeList.add(newType);
} catch (IllegalArgumentException e) {
// If resolution failed, add the type as is to the resolved list.
resTypeList.add(toResolveType);
}
}
// transform (which takes in type on its left and emits the type on its right).
for (int i = 0; i < resTypeList.size(); i += 2) {
Type firstType = resTypeList.get(i);
Type secondType = resTypeList.get(i + 1);
// Check if secondType can accept firstType
Preconditions.checkArgument(TypeToken.of(secondType).isAssignableFrom(firstType), "Types between stages didn't match. Mismatch between %s -> %s", firstType, secondType);
}
}
Aggregations