|
18 | 18 |
|
19 | 19 | import org.slf4j.*; |
20 | 20 |
|
| 21 | +import java.io.*; |
21 | 22 | import java.lang.reflect.*; |
22 | 23 | import java.net.*; |
23 | 24 | import java.util.*; |
@@ -51,13 +52,6 @@ private static Set<Class<?>> getWrapperTypes() |
51 | 52 |
|
52 | 53 | public static boolean isPrimitiveNumericType(final Class<?> clazz) |
53 | 54 | { |
54 | | -// numericTypes.add(Character.class); |
55 | | -// numericTypes.add(Byte.class); |
56 | | -// numericTypes.add(Short.class); |
57 | | -// numericTypes.add(Integer.class); |
58 | | -// numericTypes.add(Long.class); |
59 | | -// numericTypes.add(Float.class); |
60 | | -// numericTypes.add(Double.class); |
61 | 55 | return PRIMITIVE_NUMERIC_TYPES.contains(clazz); |
62 | 56 | } |
63 | 57 |
|
@@ -158,4 +152,74 @@ public static boolean allAssignableFrom(final Class<?> sharedType, |
158 | 152 | return matching; |
159 | 153 | } |
160 | 154 |
|
| 155 | + /** |
| 156 | + * This method will not extract the interfaces of the given types, since there is no way to determine, which |
| 157 | + * interface is the most specific one (due to their compositional nature). However, if one or more interfaces |
| 158 | + * are given as type, they will be considered as most specific shared type. |
| 159 | + * |
| 160 | + * @return The most specific class (or interface) shared by all given types. |
| 161 | + */ |
| 162 | + public static Class<?> mostSpecificSharedType(final Collection<Class<?>> types) |
| 163 | + { |
| 164 | + final Collection<Class<?>> potentiallySharedTypes = superclassesOf(types); |
| 165 | + potentiallySharedTypes.addAll(types); |
| 166 | + |
| 167 | + final Collection<Class<?>> sharedTypes = new TreeSet<Class<?>>(new ClassComparator()); |
| 168 | + for (final Class<?> potentiallySharedType : potentiallySharedTypes) |
| 169 | + { |
| 170 | + int matches = 0; |
| 171 | + for (final Class<?> type : types) |
| 172 | + { |
| 173 | + if (potentiallySharedType.isAssignableFrom(type)) |
| 174 | + { |
| 175 | + matches++; |
| 176 | + } |
| 177 | + } |
| 178 | + if (matches == types.size()) |
| 179 | + { |
| 180 | + sharedTypes.add(potentiallySharedType); |
| 181 | + } |
| 182 | + } |
| 183 | + if (sharedTypes.isEmpty()) |
| 184 | + { |
| 185 | + return null; |
| 186 | + } |
| 187 | + return sharedTypes.iterator().next(); |
| 188 | + } |
| 189 | + |
| 190 | + private static Collection<Class<?>> superclassesOf(final Iterable<Class<?>> types) |
| 191 | + { |
| 192 | + final Collection<Class<?>> superclasses = new HashSet<Class<?>>(); |
| 193 | + for (final Class<?> type : types) |
| 194 | + { |
| 195 | + Class<?> superclass = type.getSuperclass(); |
| 196 | + while (superclass != null && superclass != Object.class) |
| 197 | + { |
| 198 | + superclasses.add(superclass); |
| 199 | + superclass = superclass.getSuperclass(); |
| 200 | + } |
| 201 | + } |
| 202 | + return superclasses; |
| 203 | + } |
| 204 | + |
| 205 | + private static class ClassComparator implements Comparator<Class<?>>, Serializable |
| 206 | + { |
| 207 | + private static final long serialVersionUID = 56568941407903459L; |
| 208 | + |
| 209 | + public int compare(final Class<?> o1, final Class<?> o2) |
| 210 | + { |
| 211 | + if (o1.isAssignableFrom(o2)) |
| 212 | + { |
| 213 | + return 1; |
| 214 | + } |
| 215 | + else if (o2.isAssignableFrom(o1)) |
| 216 | + { |
| 217 | + return -1; |
| 218 | + } |
| 219 | + else |
| 220 | + { |
| 221 | + return 0; |
| 222 | + } |
| 223 | + } |
| 224 | + } |
161 | 225 | } |
0 commit comments