You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by ib...@apache.org on 2020/11/19 21:52:04 UTC
[beam] branch master updated: [BEAM-10925] Move general-usage
helper methods from DoFnSignatures to ReflectHelpers.
This is an automated email from the ASF dual-hosted git repository.
ibzib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new b9f0538 [BEAM-10925] Move general-usage helper methods from DoFnSignatures to ReflectHelpers.
new 019ebb5 Merge pull request #13304 from ibzib/reflect-helpers
b9f0538 is described below
commit b9f0538290375ab17ec3814e327c7c2a9dcc9a50
Author: Kyle Weaver <kc...@google.com>
AuthorDate: Fri Oct 30 18:25:33 2020 -0700
[BEAM-10925] Move general-usage helper methods from DoFnSignatures to ReflectHelpers.
---
.../sdk/transforms/reflect/DoFnSignatures.java | 77 ++++------------------
.../beam/sdk/util/common/ReflectHelpers.java | 60 +++++++++++++++++
2 files changed, 72 insertions(+), 65 deletions(-)
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 550b547..e730e8a 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
@@ -21,7 +21,6 @@ import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Prec
import com.google.auto.value.AutoValue;
import java.lang.annotation.Annotation;
-import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -33,7 +32,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -542,7 +540,7 @@ public class DoFnSignatures {
findAnnotatedMethod(errors, DoFn.NewWatermarkEstimator.class, fnClass, false);
Collection<Method> onTimerMethods =
- declaredMethodsWithAnnotation(DoFn.OnTimer.class, fnClass, DoFn.class);
+ ReflectHelpers.declaredMethodsWithAnnotation(DoFn.OnTimer.class, fnClass, DoFn.class);
HashMap<String, DoFnSignature.OnTimerMethod> onTimerMethodMap =
Maps.newHashMapWithExpectedSize(onTimerMethods.size());
for (Method onTimerMethod : onTimerMethods) {
@@ -569,7 +567,7 @@ public class DoFnSignatures {
// Check for TimerFamily
Collection<Method> onTimerFamilyMethods =
- declaredMethodsWithAnnotation(DoFn.OnTimerFamily.class, fnClass, DoFn.class);
+ ReflectHelpers.declaredMethodsWithAnnotation(DoFn.OnTimerFamily.class, fnClass, DoFn.class);
HashMap<String, DoFnSignature.OnTimerFamilyMethod> onTimerFamilyMethodMap =
Maps.newHashMapWithExpectedSize(onTimerFamilyMethods.size());
@@ -1867,7 +1865,8 @@ public class DoFnSignatures {
private static ImmutableMap<String, TimerFamilyDeclaration> analyzeTimerFamilyDeclarations(
ErrorReporter errors, Class<?> fnClazz) {
Map<String, TimerFamilyDeclaration> declarations = new HashMap<>();
- for (Field field : declaredFieldsWithAnnotation(DoFn.TimerFamily.class, fnClazz, DoFn.class)) {
+ for (Field field :
+ ReflectHelpers.declaredFieldsWithAnnotation(DoFn.TimerFamily.class, fnClazz, DoFn.class)) {
// TimerSpec fields may generally be private, but will be accessed via the signature
field.setAccessible(true);
String id =
@@ -1882,7 +1881,8 @@ public class DoFnSignatures {
private static ImmutableMap<String, TimerDeclaration> analyzeTimerDeclarations(
ErrorReporter errors, Class<?> fnClazz) {
Map<String, DoFnSignature.TimerDeclaration> declarations = new HashMap<>();
- for (Field field : declaredFieldsWithAnnotation(DoFn.TimerId.class, fnClazz, DoFn.class)) {
+ for (Field field :
+ ReflectHelpers.declaredFieldsWithAnnotation(DoFn.TimerId.class, fnClazz, DoFn.class)) {
// TimerSpec fields may generally be private, but will be accessed via the signature
field.setAccessible(true);
// Add fixed prefix to avoid key collision with TimerFamily.
@@ -2200,66 +2200,11 @@ public class DoFnSignatures {
return DoFnSignature.GetSizeMethod.create(m, windowT, methodContext.getExtraParameters());
}
- private static Collection<Method> declaredMethodsWithAnnotation(
- Class<? extends Annotation> anno, Class<?> startClass, Class<?> stopClass) {
- return declaredMembersWithAnnotation(anno, startClass, stopClass, GET_METHODS);
- }
-
- private static Collection<Field> declaredFieldsWithAnnotation(
- Class<? extends Annotation> anno, Class<?> startClass, Class<?> stopClass) {
- return declaredMembersWithAnnotation(anno, startClass, stopClass, GET_FIELDS);
- }
-
- private interface MemberGetter<MemberT> {
- MemberT[] getMembers(Class<?> clazz);
- }
-
- private static final MemberGetter<Method> GET_METHODS = Class::getDeclaredMethods;
-
- private static final MemberGetter<Field> GET_FIELDS = Class::getDeclaredFields;
-
- private static <MemberT extends AnnotatedElement>
- Collection<MemberT> declaredMembersWithAnnotation(
- Class<? extends Annotation> anno,
- Class<?> startClass,
- Class<?> stopClass,
- MemberGetter<MemberT> getter) {
- Collection<MemberT> matches = new ArrayList<>();
-
- Class<?> clazz = startClass;
- LinkedHashSet<Class<?>> interfaces = new LinkedHashSet<>();
-
- // First, find all declared methods on the startClass and parents (up to stopClass)
- while (clazz != null && !clazz.equals(stopClass)) {
- for (MemberT member : getter.getMembers(clazz)) {
- if (member.isAnnotationPresent(anno)) {
- matches.add(member);
- }
- }
-
- // Add all interfaces, including transitive
- for (TypeDescriptor<?> iface : TypeDescriptor.of(clazz).getInterfaces()) {
- interfaces.add(iface.getRawType());
- }
-
- clazz = clazz.getSuperclass();
- }
-
- // Now, iterate over all the discovered interfaces
- for (Class<?> iface : interfaces) {
- for (MemberT member : getter.getMembers(iface)) {
- if (member.isAnnotationPresent(anno)) {
- matches.add(member);
- }
- }
- }
- return matches;
- }
-
private static Map<String, DoFnSignature.FieldAccessDeclaration> analyzeFieldAccessDeclaration(
ErrorReporter errors, Class<?> fnClazz) {
Map<String, FieldAccessDeclaration> fieldAccessDeclarations = new HashMap<>();
- for (Field field : declaredFieldsWithAnnotation(DoFn.FieldAccess.class, fnClazz, DoFn.class)) {
+ for (Field field :
+ ReflectHelpers.declaredFieldsWithAnnotation(DoFn.FieldAccess.class, fnClazz, DoFn.class)) {
field.setAccessible(true);
DoFn.FieldAccess fieldAccessAnnotation = field.getAnnotation(DoFn.FieldAccess.class);
if (!Modifier.isFinal(field.getModifiers())) {
@@ -2286,7 +2231,8 @@ public class DoFnSignatures {
Map<String, DoFnSignature.StateDeclaration> declarations = new HashMap<>();
- for (Field field : declaredFieldsWithAnnotation(DoFn.StateId.class, fnClazz, DoFn.class)) {
+ for (Field field :
+ ReflectHelpers.declaredFieldsWithAnnotation(DoFn.StateId.class, fnClazz, DoFn.class)) {
// StateSpec fields may generally be private, but will be accessed via the signature
field.setAccessible(true);
String id = field.getAnnotation(DoFn.StateId.class).value();
@@ -2349,7 +2295,8 @@ public class DoFnSignatures {
private static @Nullable Method findAnnotatedMethod(
ErrorReporter errors, Class<? extends Annotation> anno, Class<?> fnClazz, boolean required) {
- Collection<Method> matches = declaredMethodsWithAnnotation(anno, fnClazz, DoFn.class);
+ Collection<Method> matches =
+ ReflectHelpers.declaredMethodsWithAnnotation(anno, fnClazz, DoFn.class);
if (matches.isEmpty()) {
errors.checkArgument(!required, "No method annotated with @%s found", format(anno));
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/common/ReflectHelpers.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/common/ReflectHelpers.java
index bd47037..9c3652d 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/common/ReflectHelpers.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/common/ReflectHelpers.java
@@ -22,6 +22,8 @@ import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Prec
import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkNotNull;
import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
@@ -32,8 +34,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
+import java.util.LinkedHashSet;
import java.util.Queue;
import java.util.ServiceLoader;
+import org.apache.beam.sdk.values.TypeDescriptor;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Function;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Joiner;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.FluentIterable;
@@ -274,4 +278,60 @@ public class ReflectHelpers {
}
return false;
}
+
+ public static Collection<Method> declaredMethodsWithAnnotation(
+ Class<? extends Annotation> anno, Class<?> startClass, Class<?> stopClass) {
+ return declaredMembersWithAnnotation(anno, startClass, stopClass, GET_METHODS);
+ }
+
+ public static Collection<Field> declaredFieldsWithAnnotation(
+ Class<? extends Annotation> anno, Class<?> startClass, Class<?> stopClass) {
+ return declaredMembersWithAnnotation(anno, startClass, stopClass, GET_FIELDS);
+ }
+
+ private interface MemberGetter<MemberT> {
+ MemberT[] getMembers(Class<?> clazz);
+ }
+
+ private static final MemberGetter<Method> GET_METHODS = Class::getDeclaredMethods;
+
+ private static final MemberGetter<Field> GET_FIELDS = Class::getDeclaredFields;
+
+ private static <MemberT extends AnnotatedElement>
+ Collection<MemberT> declaredMembersWithAnnotation(
+ Class<? extends Annotation> anno,
+ Class<?> startClass,
+ Class<?> stopClass,
+ MemberGetter<MemberT> getter) {
+ Collection<MemberT> matches = new ArrayList<>();
+
+ Class<?> clazz = startClass;
+ LinkedHashSet<Class<?>> interfaces = new LinkedHashSet<>();
+
+ // First, find all declared methods on the startClass and parents (up to stopClass)
+ while (clazz != null && !clazz.equals(stopClass)) {
+ for (MemberT member : getter.getMembers(clazz)) {
+ if (member.isAnnotationPresent(anno)) {
+ matches.add(member);
+ }
+ }
+
+ // Add all interfaces, including transitive
+ for (TypeDescriptor<?> iface : TypeDescriptor.of(clazz).getInterfaces()) {
+ interfaces.add(iface.getRawType());
+ }
+
+ clazz = clazz.getSuperclass();
+ }
+
+ // Now, iterate over all the discovered interfaces
+ for (Class<?> iface : interfaces) {
+ for (MemberT member : getter.getMembers(iface)) {
+ if (member.isAnnotationPresent(anno)) {
+ matches.add(member);
+ }
+ }
+ }
+ return matches;
+ }
}