[
https://issues.apache.org/jira/browse/BEAM-6240?focusedWorklogId=181880&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-181880
]
ASF GitHub Bot logged work on BEAM-6240:
----------------------------------------
Author: ASF GitHub Bot
Created on: 07/Jan/19 16:06
Start Date: 07/Jan/19 16:06
Worklog Time Spent: 10m
Work Description: kanterov commented on pull request #7289: [BEAM-6240]
Add a library of schema annotations for POJO and JavaBeans
URL: https://github.com/apache/beam/pull/7289#discussion_r245697569
##########
File path:
sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java
##########
@@ -595,4 +614,163 @@ protected StackManipulation
convertDefault(TypeDescriptor<?> type) {
return readValue;
}
}
+
+ /**
+ * Invokes a constructor registered using SchemaCreate. As constructor
parameters might not be in
+ * the same order as the schema fields, reorders the parameters as necessary
before calling the
+ * constructor.
+ */
+ static class ConstructorCreateInstruction extends
InvokeUserCreateInstruction {
+ private final Constructor constructor;
+
+ ConstructorCreateInstruction(
+ List<FieldValueTypeInformation> fields, Class targetClass, Constructor
constructor) {
+ super(fields, targetClass,
Lists.newArrayList(constructor.getParameters()));
+ this.constructor = constructor;
+ }
+
+ @Override
+ public InstrumentedType prepare(InstrumentedType instrumentedType) {
+ return instrumentedType;
+ }
+
+ @Override
+ protected StackManipulation beforePushingParameters() {
+ // Create the target class.
+ ForLoadedType loadedType = new ForLoadedType(targetClass);
+ return new StackManipulation.Compound(TypeCreation.of(loadedType),
Duplication.SINGLE);
+ }
+
+ @Override
+ protected StackManipulation afterPushingParameters() {
+ return MethodInvocation.invoke(new ForLoadedConstructor(constructor));
+ }
+ }
+
+ /**
+ * Invokes a static factory method registered using SchemaCreate. As the
method parameters might
+ * not be in the same order as the schema fields, reorders the parameters as
necessary before
+ * calling the constructor.
+ */
+ static class StaticFactoryMethodInstruction extends
InvokeUserCreateInstruction {
+ private final Method creator;
+
+ StaticFactoryMethodInstruction(
+ List<FieldValueTypeInformation> fields, Class targetClass, Method
creator) {
+ super(fields, targetClass, Lists.newArrayList(creator.getParameters()));
+ if (!Modifier.isStatic(creator.getModifiers())) {
+ throw new IllegalArgumentException("Method " + creator + " is not
static");
+ }
+ this.creator = creator;
+ }
+
+ @Override
+ public InstrumentedType prepare(InstrumentedType instrumentedType) {
+ return instrumentedType;
+ }
+
+ @Override
+ protected StackManipulation afterPushingParameters() {
+ return MethodInvocation.invoke(new ForLoadedMethod(creator));
+ }
+ }
+
+ static class InvokeUserCreateInstruction implements Implementation {
+ protected final List<FieldValueTypeInformation> fields;
+ protected final Class targetClass;
+ protected final List<Parameter> parameters;
+ protected final Map<Integer, Integer> fieldMapping;
+
+ protected InvokeUserCreateInstruction(
+ List<FieldValueTypeInformation> fields, Class targetClass,
List<Parameter> parameters) {
+ this.fields = fields;
+ this.targetClass = targetClass;
+ this.parameters = parameters;
+
+ // Method parameters might not be in the same order as the schema
fields, and the input
+ // array to SchemaUserTypeCreator.create is in schema order. Examine the
parameter names
+ // and compare against field names to calculate the mapping between the
two lists.
+ Map<String, Integer> fieldsByLogicalName = Maps.newHashMap();
+ Map<String, Integer> fieldsByJavaClassMember = Maps.newHashMap();
+ for (int i = 0; i < fields.size(); ++i) {
+ // Method parameters are allowed to either correspond to the schema
field names or to the
+ // actual Java field or method names.
+ FieldValueTypeInformation fieldValue = checkNotNull(fields.get(i));
+ fieldsByLogicalName.put(fieldValue.getName(), i);
+ if (fieldValue.getField() != null) {
+ fieldsByJavaClassMember.put(fieldValue.getField().getName(), i);
+ } else if (fieldValue.getMethod() != null) {
+ String name =
ReflectUtils.stripPrefix(fieldValue.getMethod().getName(), "set");
+ fieldsByJavaClassMember.put(name, i);
+ }
+ }
+
+ fieldMapping = Maps.newHashMap();
+ for (int i = 0; i < parameters.size(); ++i) {
+ Parameter parameter = parameters.get(i);
+ String paramName = parameter.getName();
Review comment:
I don't know this topic well enough, but to my knowledge, `getName()` can
return `argN` if a class file doesn't have parameter metadata. There
`isParameter#isNamePresent()` to verify if name is synthetic.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
Issue Time Tracking
-------------------
Worklog Id: (was: 181880)
Time Spent: 3h 20m (was: 3h 10m)
> Allow users to annotate POJOs and JavaBeans for richer functionality
> --------------------------------------------------------------------
>
> Key: BEAM-6240
> URL: https://issues.apache.org/jira/browse/BEAM-6240
> Project: Beam
> Issue Type: Sub-task
> Components: sdk-java-core
> Reporter: Reuven Lax
> Assignee: Reuven Lax
> Priority: Major
> Time Spent: 3h 20m
> Remaining Estimate: 0h
>
> Desired annotations:
> * SchemaIgnore - ignore this field
> * FieldName - allow the user to explicitly specify a field name
> * SchemaCreate - register a function to be used to create an object (so
> fields can be final, and no default constructor need be assumed).
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)