1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.reflection.factory;
17
18 import java.io.Serializable;
19 import java.lang.reflect.Constructor;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Optional;
28 import java.util.Set;
29 import java.util.SortedSet;
30 import java.util.TreeSet;
31 import java.util.stream.Collectors;
32
33 import org.apache.ibatis.reflection.ReflectionException;
34 import org.apache.ibatis.reflection.Reflector;
35
36
37
38
39 public class DefaultObjectFactory implements ObjectFactory, Serializable {
40
41 private static final long serialVersionUID = -8855120656740914948L;
42
43 @Override
44 public <T> T create(Class<T> type) {
45 return create(type, null, null);
46 }
47
48 @SuppressWarnings("unchecked")
49 @Override
50 public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
51 Class<?> classToCreate = resolveInterface(type);
52
53 return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
54 }
55
56 private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
57 try {
58 Constructor<T> constructor;
59 if (constructorArgTypes == null || constructorArgs == null) {
60 constructor = type.getDeclaredConstructor();
61 try {
62 return constructor.newInstance();
63 } catch (IllegalAccessException e) {
64 if (Reflector.canControlMemberAccessible()) {
65 constructor.setAccessible(true);
66 return constructor.newInstance();
67 } else {
68 throw e;
69 }
70 }
71 }
72 constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[0]));
73 try {
74 return constructor.newInstance(constructorArgs.toArray(new Object[0]));
75 } catch (IllegalAccessException e) {
76 if (Reflector.canControlMemberAccessible()) {
77 constructor.setAccessible(true);
78 return constructor.newInstance(constructorArgs.toArray(new Object[0]));
79 } else {
80 throw e;
81 }
82 }
83 } catch (Exception e) {
84 String argTypes = Optional.ofNullable(constructorArgTypes).orElseGet(Collections::emptyList)
85 .stream().map(Class::getSimpleName).collect(Collectors.joining(","));
86 String argValues = Optional.ofNullable(constructorArgs).orElseGet(Collections::emptyList)
87 .stream().map(String::valueOf).collect(Collectors.joining(","));
88 throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);
89 }
90 }
91
92 protected Class<?> resolveInterface(Class<?> type) {
93 Class<?> classToCreate;
94 if (type == List.class || type == Collection.class || type == Iterable.class) {
95 classToCreate = ArrayList.class;
96 } else if (type == Map.class) {
97 classToCreate = HashMap.class;
98 } else if (type == SortedSet.class) {
99 classToCreate = TreeSet.class;
100 } else if (type == Set.class) {
101 classToCreate = HashSet.class;
102 } else {
103 classToCreate = type;
104 }
105 return classToCreate;
106 }
107
108 @Override
109 public <T> boolean isCollection(Class<T> type) {
110 return Collection.class.isAssignableFrom(type);
111 }
112
113 }