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

org.simpleflatmapper.reflect.meta.MapClassMeta Maven / Gradle / Ivy

package org.simpleflatmapper.reflect.meta;

import org.simpleflatmapper.converter.ContextFactory;
import org.simpleflatmapper.converter.ConverterService;
import org.simpleflatmapper.converter.DefaultContextFactoryBuilder;
import org.simpleflatmapper.reflect.instantiator.ExecutableInstantiatorDefinition;
import org.simpleflatmapper.reflect.InstantiatorDefinition;
import org.simpleflatmapper.reflect.ReflectionService;
import org.simpleflatmapper.util.Consumer;
import org.simpleflatmapper.util.Predicate;
import org.simpleflatmapper.util.TypeHelper;
import org.simpleflatmapper.converter.ContextualConverter;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class MapClassMeta, K, V> implements ClassMeta {

	private final ReflectionService reflectionService;
	private final ContextualConverter keyConverter;
	private final ContextFactory keyContextFactory;
	private final ClassMeta valueClassMeta;
	private final Type type;

	private final Constructor constructor;

	public MapClassMeta(Type type, Type keyType, Type valueType, ReflectionService reflectionService) {
		this.type = type;

		DefaultContextFactoryBuilder contextFactoryBuilder = new DefaultContextFactoryBuilder();
		
		this.keyConverter = ConverterService.getInstance().findConverter(CharSequence.class, keyType, contextFactoryBuilder);
		this.keyContextFactory = contextFactoryBuilder.build();
		this.reflectionService = reflectionService;
		this.valueClassMeta = reflectionService.getClassMeta(valueType);
		this.constructor = getConstructor(type);
	}

	public MapClassMeta(ReflectionService reflectionService, ContextualConverter keyConverter, ContextFactory keyContextFactory, ClassMeta valueClassMeta, Type type, Constructor constructor) {
		this.reflectionService = reflectionService;
		this.keyConverter = keyConverter;
		this.keyContextFactory = keyContextFactory;
		this.valueClassMeta = valueClassMeta;
		this.type = type;
		this.constructor = constructor;
	}

	@Override
	public ClassMeta withReflectionService(ReflectionService reflectionService) {
		return new MapClassMeta(reflectionService, keyConverter, keyContextFactory, reflectionService.getClassMeta(valueClassMeta.getType()), type, constructor);
	}

	private Constructor getConstructor(Type type) {

		Class implClass = findMapImpl(type);
		try {
			return implClass.getDeclaredConstructor();
		} catch (NoSuchMethodException e) {
			throw new IllegalArgumentException("No empty constructor for " + implClass);
		}
	}

	private Class findMapImpl(Type type) {
		Class clazz = TypeHelper.toClass(type);

		if (clazz.isInterface()) {
			if (Map.class.equals(clazz)) {
				return HashMap.class;
			} else if(ConcurrentMap.class.equals(clazz)) {
				return ConcurrentHashMap.class;
			}
		} else if (!Modifier.isAbstract(clazz.getModifiers())) {
			return clazz;
		}

		throw new IllegalArgumentException("No known Map impl for " + type);
	}

	@Override
	public ReflectionService getReflectionService() {
		return reflectionService;
	}

	@Override
	public PropertyFinder newPropertyFinder() {
		return new MapPropertyFinder(this, valueClassMeta, keyConverter, keyContextFactory, reflectionService.selfScoreFullName());
	}

	@Override
	public Type getType() {
		return type;
	}

	@Override
	public List getInstantiatorDefinitions() {
		return Arrays.asList(new ExecutableInstantiatorDefinition(constructor));
	}

	@Override
	public void forEachProperties(Consumer> consumer) {
		throw new UnsupportedOperationException("Cannot list properties as non static");
	}

	@Override
	public int getNumberOfProperties() {
		return 10000;
	}

	@Override
	public boolean needTransformer() {
		return false;
	}


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy