Repository: beam Updated Branches: refs/heads/master eec903fb5 -> b40b26501
Make DoFnSignatures robust to StateSpec subclasses Project: http://git-wip-us.apache.org/repos/asf/beam/repo Commit: http://git-wip-us.apache.org/repos/asf/beam/commit/190422ca Tree: http://git-wip-us.apache.org/repos/asf/beam/tree/190422ca Diff: http://git-wip-us.apache.org/repos/asf/beam/diff/190422ca Branch: refs/heads/master Commit: 190422cac34732ad722d58d2fecf03571f5f08e9 Parents: 8fe59c3 Author: Kenneth Knowles <[email protected]> Authored: Tue May 2 11:54:07 2017 -0700 Committer: Kenneth Knowles <[email protected]> Committed: Tue May 2 11:55:18 2017 -0700 ---------------------------------------------------------------------- .../sdk/transforms/reflect/DoFnSignatures.java | 25 +++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/beam/blob/190422ca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnSignatures.java ---------------------------------------------------------------------- diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnSignatures.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnSignatures.java index 7beeeb8..666c7f6 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnSignatures.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnSignatures.java @@ -1188,7 +1188,8 @@ public class DoFnSignatures { } Class<?> stateSpecRawType = field.getType(); - if (!(stateSpecRawType.equals(StateSpec.class))) { + if (!(TypeDescriptor.of(stateSpecRawType) + .isSubtypeOf(TypeDescriptor.of(StateSpec.class)))) { errors.throwIllegalArgument( "%s annotation on non-%s field [%s] that has class %s", DoFn.StateId.class.getSimpleName(), @@ -1208,14 +1209,26 @@ public class DoFnSignatures { Type stateSpecType = field.getGenericType(); + // A type descriptor for whatever type the @StateId-annotated class has, which + // must be some subtype of StateSpec + TypeDescriptor<? extends StateSpec<?>> stateSpecSubclassTypeDescriptor = + (TypeDescriptor) TypeDescriptor.of(stateSpecType); + + // A type descriptor for StateSpec, with the generic type parameters filled + // in according to the specialization of the subclass (or just straight params) + TypeDescriptor<StateSpec<?>> stateSpecTypeDescriptor = + (TypeDescriptor) + stateSpecSubclassTypeDescriptor.getSupertype(StateSpec.class); + + // The type of the state, which may still have free type variables from the + // context + Type unresolvedStateType = + ((ParameterizedType) stateSpecTypeDescriptor.getType()).getActualTypeArguments()[0]; + // By static typing this is already a well-formed State subclass TypeDescriptor<? extends State> stateType = (TypeDescriptor<? extends State>) - TypeDescriptor.of(fnClazz) - .resolveType( - TypeDescriptor.of( - ((ParameterizedType) stateSpecType).getActualTypeArguments()[1]) - .getType()); + TypeDescriptor.of(fnClazz).resolveType(unresolvedStateType); declarations.put(id, DoFnSignature.StateDeclaration.create(id, field, stateType)); }
