1
16 package org.modelmapper.internal;
17
18 import java.lang.reflect.Field;
19 import java.lang.reflect.Method;
20 import java.util.Map;
21 import java.util.Map.Entry;
22 import java.util.concurrent.ConcurrentHashMap;
23
24 import org.modelmapper.config.Configuration;
25 import org.modelmapper.internal.PropertyInfoImpl.FieldPropertyInfo;
26 import org.modelmapper.internal.PropertyInfoImpl.MethodAccessor;
27 import org.modelmapper.internal.PropertyInfoImpl.MethodMutator;
28
29
36 class PropertyInfoRegistry {
37
38 private static final Map<PropertyInfoKey, Mutator> MUTATOR_CACHE = new ConcurrentHashMap<PropertyInfoKey, Mutator>();
39 private static final Map<PropertyInfoKey, Accessor> ACCESSOR_CACHE = new ConcurrentHashMap<PropertyInfoKey, Accessor>();
40 private static final Map<PropertyInfoKey, FieldPropertyInfo> FIELD_CACHE = new ConcurrentHashMap<PropertyInfoKey, FieldPropertyInfo>();
41
42 private static class PropertyInfoKey {
43 private final Class<?> initialType;
44 private final String propertyName;
45 private final Configuration configuration;
46
47 PropertyInfoKey(Class<?> initialType, String propertyName, Configuration configuration) {
48 this.initialType = initialType;
49 this.propertyName = propertyName;
50 this.configuration = configuration;
51 }
52
53 @Override
54 public boolean equals(Object o) {
55 if (this == o)
56 return true;
57 if (!(o instanceof PropertyInfoKey))
58 return false;
59 PropertyInfoKey other = (PropertyInfoKey) o;
60 return initialType.equals(other.initialType) && propertyName.equals(other.propertyName)
61 && configuration.equals(other.configuration);
62 }
63
64 @Override
65 public int hashCode() {
66 int result = 31 + initialType.hashCode();
67 result = 31 * result + propertyName.hashCode();
68 result = 31 * result + configuration.hashCode();
69 return result;
70 }
71 }
72
73
76 static Accessor accessorFor(Class<?> type, String accessorName, InheritingConfiguration configuration) {
77 PropertyInfoKey key = new PropertyInfoKey(type, accessorName, configuration);
78 if (!ACCESSOR_CACHE.containsKey(key) && !FIELD_CACHE.containsKey(key)) {
79 @SuppressWarnings("unchecked")
80 Class<Object> uncheckedType = (Class<Object>) type;
81 for (Entry<String, Accessor> entry : TypeInfoRegistry.typeInfoFor(uncheckedType, configuration).getAccessors().entrySet()) {
82 if (entry.getValue().getMember() instanceof Method)
83 accessorFor(type, (Method) entry.getValue().getMember(), configuration, entry.getKey());
84 else if (entry.getValue().getMember() instanceof Field)
85 fieldPropertyFor(type, (Field) entry.getValue().getMember(), configuration, entry.getKey());
86 }
87 }
88
89 if (ACCESSOR_CACHE.containsKey(key))
90 return ACCESSOR_CACHE.get(key);
91 return FIELD_CACHE.get(key);
92 }
93
94
98 static synchronized Accessor accessorFor(Class<?> type, Method method,
99 Configuration configuration, String name) {
100 PropertyInfoKey key = new PropertyInfoKey(type, name, configuration);
101 Accessor accessor = ACCESSOR_CACHE.get(key);
102 if (accessor == null) {
103 accessor = new MethodAccessor(type, method, name);
104 ACCESSOR_CACHE.put(key, accessor);
105 }
106
107 return accessor;
108 }
109
110
113 static synchronized FieldPropertyInfo fieldPropertyFor(Class<?> type, Field field,
114 Configuration configuration, String name) {
115 PropertyInfoKey key = new PropertyInfoKey(type, name, configuration);
116 FieldPropertyInfo fieldPropertyInfo = FIELD_CACHE.get(key);
117 if (fieldPropertyInfo == null) {
118 fieldPropertyInfo = new FieldPropertyInfo(type, field, name);
119 FIELD_CACHE.put(key, fieldPropertyInfo);
120 }
121
122 return fieldPropertyInfo;
123 }
124
125
130 static synchronized Mutator mutatorFor(Class<?> type, String name, InheritingConfiguration configuration) {
131 PropertyInfoKey key = new PropertyInfoKey(type, name, configuration);
132 if (!MUTATOR_CACHE.containsKey(key) && !FIELD_CACHE.containsKey(key)) {
133 @SuppressWarnings("unchecked")
134 Class<Object> uncheckedType = (Class<Object>) type;
135 for (Entry<String, Mutator> entry : TypeInfoRegistry.typeInfoFor(uncheckedType, configuration).getMutators().entrySet()) {
136 if (entry.getValue().getMember() instanceof Method)
137 mutatorFor(type, (Method) entry.getValue().getMember(), configuration, entry.getKey());
138 else if (entry.getValue().getMember() instanceof Field)
139 fieldPropertyFor(type, (Field) entry.getValue().getMember(), configuration, entry.getKey());
140 }
141 }
142
143 if (MUTATOR_CACHE.containsKey(key))
144 return MUTATOR_CACHE.get(key);
145 return FIELD_CACHE.get(key);
146 }
147
148
152 static synchronized Mutator mutatorFor(Class<?> type, Method method, Configuration configuration,
153 String name) {
154 PropertyInfoKey key = new PropertyInfoKey(type, name, configuration);
155 Mutator mutator = MUTATOR_CACHE.get(key);
156 if (mutator == null) {
157 mutator = new MethodMutator(type, method, name);
158 MUTATOR_CACHE.put(key, mutator);
159 }
160
161 return mutator;
162 }
163 }
164