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 @SuppressWarnings("unchecked")
44 T created = (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
45 return created;
46 }
47
48 private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
49 try {
50 Constructor<T> constructor;
51 if (constructorArgTypes == null || constructorArgs == null) {
52 constructor = type.getDeclaredConstructor();
53 if (!constructor.isAccessible()) {
54 constructor.setAccessible(true);
55 }
56 return constructor.newInstance();
57 }
58 constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
59 if (!constructor.isAccessible()) {
60 constructor.setAccessible(true);
61 }
62 return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
63 } catch (Exception e) {
64 StringBuilder argTypes = new StringBuilder();
65 if (constructorArgTypes != null) {
66 for (Class<?> argType : constructorArgTypes) {
67 argTypes.append(argType.getSimpleName());
68 argTypes.append(",");
69 }
70 }
71 StringBuilder argValues = new StringBuilder();
72 if (constructorArgs != null) {
73 for (Object argValue : constructorArgs) {
74 argValues.append(String.valueOf(argValue));
75 argValues.append(",");
76 }
77 }
78 throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);
79 }
80 }
81
82 private Class<?> resolveInterface(Class<?> type) {
83 Class<?> classToCreate;
84 if (type == List.class || type == Collection.class) {
85 classToCreate = LinkedList.class;
86 } else if (type == Map.class) {
87 classToCreate = LinkedHashMap.class;
88 } else if (type == SortedSet.class) {
89 classToCreate = TreeSet.class;
90 } else if (type == Set.class) {
91 classToCreate = HashSet.class;
92 } else {
93 classToCreate = type;
94 }
95 return classToCreate;
96 }
97
98 @Override
99 public <T> boolean isCollection(Class<T> type) {
100 return CustomCollection.class.isAssignableFrom(type);
101 }
102
103 @SuppressWarnings("unchecked")
104 public <T> T[] createArray(Class<T> type, int size) {
105 return (T[]) Array.newInstance(type, size);
106 }
107
108 }