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 }
68 throw e;
69 }
70 }
71 constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[0]));
72 try {
73 return constructor.newInstance(constructorArgs.toArray(new Object[0]));
74 } catch (IllegalAccessException e) {
75 if (Reflector.canControlMemberAccessible()) {
76 constructor.setAccessible(true);
77 return constructor.newInstance(constructorArgs.toArray(new Object[0]));
78 }
79 throw e;
80 }
81 } catch (Exception e) {
82 String argTypes = Optional.ofNullable(constructorArgTypes).orElseGet(Collections::emptyList).stream()
83 .map(Class::getSimpleName).collect(Collectors.joining(","));
84 String argValues = Optional.ofNullable(constructorArgs).orElseGet(Collections::emptyList).stream()
85 .map(String::valueOf).collect(Collectors.joining(","));
86 throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values ("
87 + argValues + "). Cause: " + e, e);
88 }
89 }
90
91 protected Class<?> resolveInterface(Class<?> type) {
92 Class<?> classToCreate;
93 if (type == List.class || type == Collection.class || type == Iterable.class) {
94 classToCreate = ArrayList.class;
95 } else if (type == Map.class) {
96 classToCreate = HashMap.class;
97 } else if (type == SortedSet.class) {
98 classToCreate = TreeSet.class;
99 } else if (type == Set.class) {
100 classToCreate = HashSet.class;
101 } else {
102 classToCreate = type;
103 }
104 return classToCreate;
105 }
106
107 @Override
108 public <T> boolean isCollection(Class<T> type) {
109 return Collection.class.isAssignableFrom(type);
110 }
111
112 }