[ 
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)

Reply via email to