From 5f0a3d4d3424392aef87291b2840b86e30eb0ace Mon Sep 17 00:00:00 2001 From: Aljoscha Krettek Date: Tue, 27 May 2014 15:36:50 +0200 Subject: [PATCH] Change TypeExtractor to have non-static methods that do the actual work This is required because we need state to detect recursive data types. This will become necessary when introducing Pojo Types. --- .../api/java/typeutils/TypeExtractor.java | 70 +++++++++++++------ 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/stratosphere-java/src/main/java/eu/stratosphere/api/java/typeutils/TypeExtractor.java b/stratosphere-java/src/main/java/eu/stratosphere/api/java/typeutils/TypeExtractor.java index 26c11c313f2..6eeebc4b5f3 100644 --- a/stratosphere-java/src/main/java/eu/stratosphere/api/java/typeutils/TypeExtractor.java +++ b/stratosphere-java/src/main/java/eu/stratosphere/api/java/typeutils/TypeExtractor.java @@ -20,6 +20,8 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; import eu.stratosphere.types.TypeInformation; @@ -39,14 +41,22 @@ import eu.stratosphere.api.java.tuple.Tuple; import eu.stratosphere.types.Value; public class TypeExtractor { - + + // We need this to detect recursive types and not get caught + // in an endless recursion + private Set> alreadySeen; + + private TypeExtractor() { + alreadySeen = new HashSet>(); + } + @SuppressWarnings("unchecked") public static TypeInformation getMapReturnTypes(MapFunction mapFunction, TypeInformation inType) { validateInputType(MapFunction.class, mapFunction.getClass(), 0, inType); if(mapFunction instanceof ResultTypeQueryable) { return ((ResultTypeQueryable) mapFunction).getProducedType(); } - return createTypeInfo(MapFunction.class, mapFunction.getClass(), 1, inType, null); + return new TypeExtractor().privateCreateTypeInfo(MapFunction.class, mapFunction.getClass(), 1, inType, null); } @SuppressWarnings("unchecked") @@ -55,7 +65,7 @@ public class TypeExtractor { if(flatMapFunction instanceof ResultTypeQueryable) { return ((ResultTypeQueryable) flatMapFunction).getProducedType(); } - return createTypeInfo(FlatMapFunction.class, flatMapFunction.getClass(), 1, inType, null); + return new TypeExtractor().privateCreateTypeInfo(FlatMapFunction.class, flatMapFunction.getClass(), 1, inType, null); } @SuppressWarnings("unchecked") @@ -65,7 +75,7 @@ public class TypeExtractor { if(groupReduceFunction instanceof ResultTypeQueryable) { return ((ResultTypeQueryable) groupReduceFunction).getProducedType(); } - return createTypeInfo(GroupReduceFunction.class, groupReduceFunction.getClass(), 1, inType, null); + return new TypeExtractor().privateCreateTypeInfo(GroupReduceFunction.class, groupReduceFunction.getClass(), 1, inType, null); } @SuppressWarnings("unchecked") @@ -76,7 +86,7 @@ public class TypeExtractor { if(joinFunction instanceof ResultTypeQueryable) { return ((ResultTypeQueryable) joinFunction).getProducedType(); } - return createTypeInfo(JoinFunction.class, joinFunction.getClass(), 2, in1Type, in2Type); + return new TypeExtractor().privateCreateTypeInfo(JoinFunction.class, joinFunction.getClass(), 2, in1Type, in2Type); } @SuppressWarnings("unchecked") @@ -87,7 +97,7 @@ public class TypeExtractor { if(coGroupFunction instanceof ResultTypeQueryable) { return ((ResultTypeQueryable) coGroupFunction).getProducedType(); } - return createTypeInfo(CoGroupFunction.class, coGroupFunction.getClass(), 2, in1Type, in2Type); + return new TypeExtractor().privateCreateTypeInfo(CoGroupFunction.class, coGroupFunction.getClass(), 2, in1Type, in2Type); } @SuppressWarnings("unchecked") @@ -98,7 +108,7 @@ public class TypeExtractor { if(crossFunction instanceof ResultTypeQueryable) { return ((ResultTypeQueryable) crossFunction).getProducedType(); } - return createTypeInfo(CrossFunction.class, crossFunction.getClass(), 2, in1Type, in2Type); + return new TypeExtractor().privateCreateTypeInfo(CrossFunction.class, crossFunction.getClass(), 2, in1Type, in2Type); } @SuppressWarnings("unchecked") @@ -107,7 +117,7 @@ public class TypeExtractor { if(selector instanceof ResultTypeQueryable) { return ((ResultTypeQueryable) selector).getProducedType(); } - return createTypeInfo(KeySelector.class, selector.getClass(), 1, inType, null); + return new TypeExtractor().privateCreateTypeInfo(KeySelector.class, selector.getClass(), 1, inType, null); } @SuppressWarnings("unchecked") @@ -115,7 +125,7 @@ public class TypeExtractor { if(inputFormat instanceof ResultTypeQueryable) { return ((ResultTypeQueryable) inputFormat).getProducedType(); } - return createTypeInfo(InputFormat.class, inputFormat.getClass(), 0, null, null); + return new TypeExtractor().privateCreateTypeInfo(InputFormat.class, inputFormat.getClass(), 0, null, null); } // -------------------------------------------------------------------------------------------- @@ -123,13 +133,22 @@ public class TypeExtractor { // -------------------------------------------------------------------------------------------- public static TypeInformation createTypeInfo(Type t) { + return new TypeExtractor().privateCreateTypeInfo(t); + } + + private TypeInformation privateCreateTypeInfo(Type t) { ArrayList typeHierarchy = new ArrayList(); typeHierarchy.add(t); return createTypeInfoWithTypeHierarchy(typeHierarchy, t, null, null); } - - @SuppressWarnings("unchecked") + public static TypeInformation createTypeInfo(Class baseClass, Class clazz, int returnParamPos, + TypeInformation in1Type, TypeInformation in2Type) { + return new TypeExtractor().privateCreateTypeInfo(baseClass, clazz, returnParamPos, in1Type, in2Type); + } + + @SuppressWarnings("unchecked") + private TypeInformation privateCreateTypeInfo(Class baseClass, Class clazz, int returnParamPos, TypeInformation in1Type, TypeInformation in2Type) { ArrayList typeHierarchy = new ArrayList(); Type returnType = getParameterType(baseClass, typeHierarchy, clazz, returnParamPos); @@ -374,7 +393,7 @@ public class TypeExtractor { } @SuppressWarnings({ "unchecked", "rawtypes" }) - private static TypeInformation createTypeInfoWithTypeHierarchy(ArrayList typeHierarchy, Type t, + private TypeInformation createTypeInfoWithTypeHierarchy(ArrayList typeHierarchy, Type t, TypeInformation in1Type, TypeInformation in2Type) { // check if type is a subclass of tuple @@ -525,11 +544,11 @@ public class TypeExtractor { } // objects with generics are treated as raw type else if (t instanceof ParameterizedType) { - return getForClass((Class) ((ParameterizedType) t).getRawType()); + return privateGetForClass((Class) ((ParameterizedType) t).getRawType()); } // no tuple, no TypeVariable, no generic type else if (t instanceof Class) { - return getForClass((Class) t); + return privateGetForClass((Class) t); } throw new InvalidTypesException("Type Information could not be created."); @@ -639,9 +658,13 @@ public class TypeExtractor { // can not be materialized, most likely due to type erasure return null; } - - @SuppressWarnings("unchecked") + public static TypeInformation getForClass(Class clazz) { + return new TypeExtractor().privateGetForClass(clazz); + } + + @SuppressWarnings("unchecked") + private TypeInformation privateGetForClass(Class clazz) { Validate.notNull(clazz); // check for abstract classes or interfaces @@ -695,9 +718,13 @@ public class TypeExtractor { // return a generic type return new GenericTypeInfo(clazz); } - - @SuppressWarnings({ "unchecked", "rawtypes" }) + public static TypeInformation getForObject(X value) { + return new TypeExtractor().privateGetForObject(value); + + } + @SuppressWarnings({ "unchecked", "rawtypes" }) + private TypeInformation privateGetForObject(X value) { Validate.notNull(value); // check if we can extract the types from tuples, otherwise work with the class @@ -714,15 +741,12 @@ public class TypeExtractor { + "Please specify the types directly."); } - infos[i] = getForObject(field); + infos[i] = privateGetForObject(field); } return (TypeInformation) new TupleTypeInfo(value.getClass(), infos); } else { - return getForClass((Class) value.getClass()); + return privateGetForClass((Class) value.getClass()); } } - - private TypeExtractor() { - } } -- GitLab