in dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/argument/GeneralTypeConverter.java [858:931]
private Collection convertCollection(Collection source, Class targetClass) {
if (targetClass.isInstance(source)) {
return source;
}
if (targetClass.isInterface()) {
if (targetClass == List.class || targetClass == Collection.class) {
return new ArrayList<>(source);
}
if (targetClass == Set.class) {
return new HashSet<>(source);
}
if (targetClass == SortedSet.class) {
return new LinkedHashSet(source);
}
if (targetClass == Queue.class || targetClass == Deque.class) {
return new LinkedList<>(source);
}
} else {
if (targetClass == ArrayList.class) {
return new ArrayList<>(source);
}
if (targetClass == LinkedList.class) {
return new LinkedList(source);
}
if (targetClass == HashSet.class) {
return new HashSet(source);
}
if (targetClass == LinkedHashSet.class) {
return new LinkedHashSet(source);
}
if (Modifier.isAbstract(targetClass.getModifiers())) {
Collection collection = customCreateCollection(targetClass, source.size());
if (collection != null) {
collection.addAll(source);
return collection;
}
if (targetClass.isAssignableFrom(ArrayList.class)) {
return new ArrayList<>(source);
}
if (targetClass.isAssignableFrom(LinkedHashSet.class)) {
return new LinkedHashSet(source);
}
return null;
}
try {
Constructor defCt = null;
for (Constructor ct : targetClass.getConstructors()) {
if (Modifier.isPublic(ct.getModifiers())) {
switch (ct.getParameterCount()) {
case 0:
defCt = ct;
break;
case 1:
Class paramType = ct.getParameterTypes()[0];
if (paramType == Collection.class) {
return (Collection) ct.newInstance(source);
} else if (paramType == List.class) {
return (Collection) ct.newInstance(toList(source));
}
break;
default:
}
}
}
if (defCt != null) {
Collection c = (Collection) defCt.newInstance();
c.addAll(source);
return c;
}
} catch (Exception ignored) {
}
}
return null;
}