View Javadoc
1   package org.neo4j.driver.projection;
2   
3   import org.neo4j.driver.exception.Neo4jClientException;
4   import org.neo4j.driver.v1.Value;
5   
6   import java.lang.reflect.Method;
7   import java.lang.reflect.Modifier;
8   import java.lang.reflect.Type;
9   import java.util.HashMap;
10  import java.util.Map;
11  
12  /**
13   * Class that helps to dynamically construct object.
14   */
15  public class DynamicClassConstructor<T> {
16  
17      /**
18       * Type to construct.
19       */
20      protected Class type;
21  
22      /**
23       * List of setters of the class {@link #type}
24       */
25      private Map<String, Method> setters = new HashMap<>();
26  
27      /**
28       * Constructor that initialize the {@link #type} and compute class setter.
29       *
30       * @param type : the type to construct.
31       */
32      public DynamicClassConstructor(Class type) {
33          this.type = type;
34  
35          // Find setters of class
36          Method[] methods = type.getDeclaredMethods();
37          for (Method method : methods) {
38              if (this.isSetter(method)) {
39                  String attributName = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
40                  this.setters.put(attributName, method);
41              }
42          }
43      }
44  
45      /**
46       * Create a new instance object of type {@link #type}.
47       */
48      public T construct() {
49          try {
50              return (T) type.newInstance();
51          } catch (Exception e) {
52              throw new Neo4jClientException(e);
53          }
54      }
55  
56      /**
57       * Add a property to an object by it's name.
58       *
59       * @param obj   Object to enhanced
60       * @param key   Parameter name
61       * @param value Value of the parameter
62       */
63      public void add(T obj, String key, Value value) {
64          try {
65              if (this.setters.containsKey(key)) {
66                  Method setter = this.setters.get(key);
67                  Type pType = setter.getGenericParameterTypes()[0];
68                  Object prop = ConversionHelper.convertDriverValueTo(pType, value);
69                  if (value != null) {
70                      setter.invoke(obj, prop);
71                  }
72  
73              }
74          } catch (Exception e) {
75              throw new Neo4jClientException(e);
76          }
77      }
78  
79      /**
80       * Determinate if the specified method is a setter.
81       * A Setter is a method :
82       * - public
83       * - no return type
84       * - only one parameter
85       * - name that stats with 'set'
86       *
87       * @param method The method to check
88       * @return Return <code>TRUE</code> if the specified method is a Setter, <code>FALSE</code> otherwise.
89       */
90      private boolean isSetter(Method method) {
91          return Modifier.isPublic(method.getModifiers()) && method.getReturnType().equals(void.class) && method.getParameterTypes().length == 1 && method
92                  .getName().matches("^set[A-Z_].*");
93      }
94  }