1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.submitted.custom_collection_handling;
17
18 import java.lang.reflect.Array;
19 import java.lang.reflect.Constructor;
20 import java.util.Collection;
21 import java.util.HashSet;
22 import java.util.LinkedHashMap;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.SortedSet;
28 import java.util.TreeSet;
29
30 import org.apache.ibatis.reflection.ReflectionException;
31 import org.apache.ibatis.reflection.factory.ObjectFactory;
32
33 public class CustomObjectFactory implements ObjectFactory {
34
35 @Override
36 public <T> T create(Class<T> type) {
37 return create(type, null, null);
38 }
39
40 @Override
41 public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
42 Class<?> classToCreate = resolveInterface(type);
43 return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
44 }
45
46 private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
47 try {
48 Constructor<T> constructor;
49 if (constructorArgTypes == null || constructorArgs == null) {
50 constructor = type.getDeclaredConstructor();
51 if (!constructor.isAccessible()) {
52 constructor.setAccessible(true);
53 }
54 return constructor.newInstance();
55 }
56 constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
57 if (!constructor.isAccessible()) {
58 constructor.setAccessible(true);
59 }
60 return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
61 } catch (Exception e) {
62 StringBuilder argTypes = new StringBuilder();
63 if (constructorArgTypes != null) {
64 for (Class<?> argType : constructorArgTypes) {
65 argTypes.append(argType.getSimpleName());
66 argTypes.append(",");
67 }
68 }
69 StringBuilder argValues = new StringBuilder();
70 if (constructorArgs != null) {
71 for (Object argValue : constructorArgs) {
72 argValues.append(String.valueOf(argValue));
73 argValues.append(",");
74 }
75 }
76 throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values ("
77 + argValues + "). Cause: " + e, e);
78 }
79 }
80
81 private Class<?> resolveInterface(Class<?> type) {
82 Class<?> classToCreate;
83 if (type == List.class || type == Collection.class) {
84 classToCreate = LinkedList.class;
85 } else if (type == Map.class) {
86 classToCreate = LinkedHashMap.class;
87 } else if (type == SortedSet.class) {
88 classToCreate = TreeSet.class;
89 } else if (type == Set.class) {
90 classToCreate = HashSet.class;
91 } else {
92 classToCreate = type;
93 }
94 return classToCreate;
95 }
96
97 @Override
98 public <T> boolean isCollection(Class<T> type) {
99 return CustomCollection.class.isAssignableFrom(type);
100 }
101
102 @SuppressWarnings("unchecked")
103 public <T> T[] createArray(Class<T> type, int size) {
104 return (T[]) Array.newInstance(type, size);
105 }
106
107 }