All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.polaris.core.converter.CollectionConverter Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package io.polaris.core.converter;

import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

import io.polaris.core.collection.Iterables;
import io.polaris.core.consts.SymbolConsts;
import io.polaris.core.json.JsonSerializer;
import io.polaris.core.lang.JavaType;
import io.polaris.core.lang.Types;
import io.polaris.core.log.ILogger;
import io.polaris.core.log.ILoggers;
import io.polaris.core.reflect.Reflects;
import io.polaris.core.service.StatefulServiceLoader;

/**
 * @author Qt
 * @since 1.8
 */
public class CollectionConverter, E> extends AbstractConverter {
	private static final ILogger log = ILoggers.of(CollectionConverter.class);
	/** 集合类型 */
	private final JavaType collectionType;
	/** 集合元素类型 */
	private final JavaType elementType;


	public CollectionConverter(JavaType collectionType, JavaType elementType) {
		this.collectionType = collectionType;
		if (elementType == null) {
			elementType = JavaType.of(collectionType.getActualType(Collection.class, 0));
		}
		this.elementType = elementType;
	}

	public CollectionConverter(JavaType collectionType) {
		this(collectionType, null);
	}

	public CollectionConverter(Type collectionType) {
		this(JavaType.of(collectionType), null);
	}

	public CollectionConverter() {
		this(Collection.class);
	}


	@Override
	public JavaType getTargetType() {
		return collectionType;
	}

	@Override
	protected  T doConvert(S value, JavaType targetType, JavaType sourceType) {
		if (this.collectionType.getRawClass().isAssignableFrom(sourceType.getRawClass())) {
			Type sourceElementType = sourceType.getActualType(Collection.class, 0);
			// 元素泛型一致
			if (sourceElementType instanceof Class) {
				if (this.elementType.getRawClass().isAssignableFrom((Class) sourceElementType)) {
					return (T) value;
				}
			} else if (this.elementType.getRawType() == sourceElementType) {
				return (T) value;
			}
		}

		T c = (T) create(Types.getClass(this.collectionType), Types.getClass(this.elementType));
		Iterator iter = null;
		if (value instanceof Iterator) {
			iter = ((Iterator) value);
		} else if (value instanceof Iterable) {
			iter = ((Iterable) value).iterator();
		} else if (value instanceof Enumeration) {
			iter = Iterables.iterator((Enumeration) value);
		} else if (value != null) {
			if (value.getClass().isArray()) {
				int length = Array.getLength(value);
				for (int i = 0; i < length; i++) {
					Object value1 = Array.get(value, i);
					c.add(Converters.convert(elementType, value1));
				}
			} else if (value instanceof CharSequence) {
				try {
					// 扩展json实现,
					Optional optional = StatefulServiceLoader.load(JsonSerializer.class).optionalService();
					if (optional.isPresent()) {
						String json = value.toString();
						return optional.get().deserialize(json, collectionType.getRawType());
					}
				} catch (Exception e) {
					log.warn("解析JSON失败:{}", e.getMessage());
					if (log.isDebugEnabled()) {
						log.debug(e.getMessage(), e);
					}
				}
				splitCharSequence((CharSequence) value, c);
			} else {
				c.add(Converters.convert(elementType, value));
			}
		}
		if (iter != null) {
			while (iter.hasNext()) {
				Object next = iter.next();
				c.add(Converters.convert(elementType, next));
			}
		}
		return c;
	}

	private void splitCharSequence(CharSequence value, Collection c) {
		int begin = 0;
		int end = value.length();
		for (int i = 0; i < value.length(); i++) {
			char ch = value.charAt(i);
			if (Character.isWhitespace(ch)) {
				begin = i;
			} else {
				if (ch == '[') {
					begin = i + 1;
				}
				break;
			}
		}
		for (int i = value.length() - 1; i >= 0; i--) {
			char ch = value.charAt(i);
			if (Character.isWhitespace(ch)) {
				end = i;
			} else {
				if (ch == ']') {
					end = i;
				}
				break;
			}
		}
		if (end > begin) {
			for (String s : value.subSequence(begin, end).toString().trim().split(SymbolConsts.COMMA)) {
				c.add(Converters.convert(elementType, s));
			}
		} else {
			c.add(null);
		}
	}

	static  Collection create(Class collectionType, Class elementType) {
		final Collection c;
		if (collectionType.isAssignableFrom(AbstractCollection.class)) {
			// 抽象集合默认使用ArrayList
			c = new ArrayList<>();
		} else if (collectionType.isAssignableFrom(HashSet.class)) {
			c = new HashSet<>();
		} else if (collectionType.isAssignableFrom(LinkedHashSet.class)) {
			c = new LinkedHashSet<>();
		} else if (collectionType.isAssignableFrom(TreeSet.class)) {
			c = new TreeSet<>((o1, o2) -> {
				// 优先按照对象本身比较,如果没有实现比较接口,默认按照toString内容比较
				if (o1 instanceof Comparable) {
					return ((Comparable) o1).compareTo(o2);
				}
				return o1.toString().compareTo(o2.toString());
			});
		} else if (collectionType.isAssignableFrom(EnumSet.class)) {
			c = (Collection) EnumSet.noneOf((Class) elementType);
		} else if (collectionType.isAssignableFrom(BlockingDeque.class)) {
			c = new LinkedBlockingDeque<>();
		} else if (collectionType.isAssignableFrom(Deque.class)) {
			c = new ArrayDeque<>();
		} else if (collectionType.isAssignableFrom(ArrayList.class)) {
			c = new ArrayList<>();
		} else if (collectionType.isAssignableFrom(LinkedList.class)) {
			c = new LinkedList<>();
		} else {
			try {
				c = (Collection) Reflects.newInstance(collectionType);
			} catch (final Exception e) {
				// 无法创建当前类型的对象,尝试创建父类型对象
				final Class superclass = collectionType.getSuperclass();
				if (null != superclass && collectionType != superclass) {
					return create(superclass, elementType);
				}
				throw new ConversionException("集合类型对象无法创建", e);
			}
		}
		return c;
	}
}