in xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/PropertyEditorRegistry.java [295:396]
protected Converter findInternalConverter(final Type type) {
if (type == null) {
throw new NullPointerException("type is null");
}
final Class clazz = toClass(type);
// it's possible this was a request for an array class. We might not
// recognize the array type directly, but the component type might be
// resolvable
if (clazz.isArray() && !clazz.getComponentType().isArray()) {
// do a recursive lookup on the base type
PropertyEditor editor = findConverter(clazz.getComponentType());
// if we found a suitable editor for the base component type,
// wrapper this in an array adaptor for real use
if (editor != null) {
return new ArrayConverter(clazz, editor);
}
return null;
}
if (Collection.class.isAssignableFrom(clazz)){
Type[] types = getTypeParameters(Collection.class, type);
Type componentType = String.class;
if (types != null && types.length == 1 && types[0] instanceof Class) {
componentType = types[0];
}
PropertyEditor editor = findConverter(componentType);
if (editor != null){
if (RecipeHelper.hasDefaultConstructor(clazz)) {
return new GenericCollectionConverter(clazz, editor);
} else if (SortedSet.class.isAssignableFrom(clazz)) {
return new GenericCollectionConverter(TreeSet.class, editor);
} else if (Set.class.isAssignableFrom(clazz)) {
return new GenericCollectionConverter(LinkedHashSet.class, editor);
}
return new GenericCollectionConverter(ArrayList.class, editor);
}
return null;
}
if (Map.class.isAssignableFrom(clazz)){
Type[] types = getTypeParameters(Map.class, type);
Type keyType = String.class;
Type valueType = String.class;
if (types != null && types.length == 2 && types[0] instanceof Class && types[1] instanceof Class) {
keyType = types[0];
valueType = types[1];
}
final Converter keyConverter = findConverter(keyType);
final Converter valueConverter = findConverter(valueType);
if (keyConverter != null && valueConverter != null){
if (RecipeHelper.hasDefaultConstructor(clazz)) {
return new GenericMapConverter(clazz, keyConverter, valueConverter);
} else if (SortedMap.class.isAssignableFrom(clazz)) {
return new GenericMapConverter(TreeMap.class, keyConverter, valueConverter);
} else if (ConcurrentMap.class.isAssignableFrom(clazz)) {
return new GenericMapConverter(ConcurrentHashMap.class, keyConverter, valueConverter);
}
return new GenericMapConverter(LinkedHashMap.class, keyConverter, valueConverter);
}
return null;
}
Converter converter = registry.get(clazz);
// we're outta here if we got one.
if (converter != null) {
return converter;
}
final Class[] declaredClasses = clazz.getDeclaredClasses();
for (final Class<?> declaredClass : declaredClasses) {
if (Converter.class.isAssignableFrom(declaredClass)) {
try {
converter = (Converter) declaredClass.newInstance();
register(converter);
// try to get the converter from the registry... the converter
// created above may have been for another class
converter = registry.get(clazz);
if (converter != null) {
return converter;
}
} catch (Exception e) {
// no-op
}
}
}
// nothing found
return null;
}