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.HashMap;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Properties;
27 import java.util.Set;
28 import java.util.SortedSet;
29 import java.util.TreeSet;
30
31 import org.apache.ibatis.reflection.ReflectionException;
32
33
34
35
36 public class DefaultObjectFactory implements ObjectFactory, Serializable {
37
38 private static final long serialVersionUID = -8855120656740914948L;
39
40 @Override
41 public <T> T create(Class<T> type) {
42 return create(type, null, null);
43 }
44
45 @SuppressWarnings("unchecked")
46 @Override
47 public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
48 Class<?> classToCreate = resolveInterface(type);
49
50 return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
51 }
52
53 @Override
54 public void setProperties(Properties properties) {
55
56 }
57
58 <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
59 try {
60 Constructor<T> constructor;
61 if (constructorArgTypes == null || constructorArgs == null) {
62 constructor = type.getDeclaredConstructor();
63 if (!constructor.isAccessible()) {
64 constructor.setAccessible(true);
65 }
66 return constructor.newInstance();
67 }
68 constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
69 if (!constructor.isAccessible()) {
70 constructor.setAccessible(true);
71 }
72 return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
73 } catch (Exception e) {
74 StringBuilder argTypes = new StringBuilder();
75 if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) {
76 for (Class<?> argType : constructorArgTypes) {
77 argTypes.append(argType.getSimpleName());
78 argTypes.append(",");
79 }
80 argTypes.deleteCharAt(argTypes.length() - 1);
81 }
82 StringBuilder argValues = new StringBuilder();
83 if (constructorArgs != null && !constructorArgs.isEmpty()) {
84 for (Object argValue : constructorArgs) {
85 argValues.append(String.valueOf(argValue));
86 argValues.append(",");
87 }
88 argValues.deleteCharAt(argValues.length() - 1);
89 }
90 throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);
91 }
92 }
93
94 protected Class<?> resolveInterface(Class<?> type) {
95 Class<?> classToCreate;
96 if (type == List.class || type == Collection.class || type == Iterable.class) {
97 classToCreate = ArrayList.class;
98 } else if (type == Map.class) {
99 classToCreate = HashMap.class;
100 } else if (type == SortedSet.class) {
101 classToCreate = TreeSet.class;
102 } else if (type == Set.class) {
103 classToCreate = HashSet.class;
104 } else {
105 classToCreate = type;
106 }
107 return classToCreate;
108 }
109
110 @Override
111 public <T> boolean isCollection(Class<T> type) {
112 return Collection.class.isAssignableFrom(type);
113 }
114
115 }