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

org.sfm.map.impl.AbstractFieldMapperMapperBuilder Maven / Gradle / Ivy

Go to download

Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.

There is a newer version: 1.10.3
Show newest version
package org.sfm.map.impl;

import org.sfm.jdbc.impl.getter.MapperGetterAdapter;
import org.sfm.map.*;
import org.sfm.map.impl.fieldmapper.FieldMapperImpl;
import org.sfm.reflect.*;
import org.sfm.reflect.meta.*;
import org.sfm.utils.ForEachCallBack;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public abstract class AbstractFieldMapperMapperBuilder>  {

	private final Type source;
	private final Type target;

	private final FieldMapperFactory> fieldMapperFactory;
	private final GetterFactory getterFactory;

	private final PropertyMappingsBuilder> propertyMappingsBuilder;
	protected final ReflectionService reflectionService;
	
	protected final ColumnDefinitionProvider, K> columnDefinitions;
	private final List> additionalMappers = new ArrayList>();
	protected final PropertyNameMatcherFactory propertyNameMatcherFactory;

	private final FieldMapperColumnDefinition identity = FieldMapperColumnDefinition.identity();

	protected final MapperBuilderErrorHandler mapperBuilderErrorHandler;
	private FieldMapperErrorHandler fieldMapperErrorHandler;

	public AbstractFieldMapperMapperBuilder(final Type source,
											final ClassMeta classMeta,
											GetterFactory getterFactory,
											FieldMapperFactory> fieldMapperFactory,
											ColumnDefinitionProvider, K> columnDefinitions,
											PropertyNameMatcherFactory propertyNameMatcherFactory,
											MapperBuilderErrorHandler mapperBuilderErrorHandler) throws MapperBuildingException {
		if (source == null) {
			throw new NullPointerException("source is null");
		}
		if (classMeta == null) {
			throw new NullPointerException("classMeta is null");
		}
		if (getterFactory == null) {
			throw new NullPointerException("getterFactory is null");
		}
		if (fieldMapperFactory == null) {
			throw new NullPointerException("fieldMapperFactory is null");
		}
		if (columnDefinitions == null) {
			throw new NullPointerException("columnDefinitions is null");
		}
		if (propertyNameMatcherFactory == null) {
			throw new NullPointerException("propertyNameMatcherFactory is null");
		}
		if (mapperBuilderErrorHandler == null) {
			throw new NullPointerException("mapperBuilderErrorHandler is null");
		}
		this.source = source;
		this.getterFactory = getterFactory;
		this.fieldMapperFactory = fieldMapperFactory;
		this.propertyMappingsBuilder = new PropertyMappingsBuilder>(classMeta, propertyNameMatcherFactory, mapperBuilderErrorHandler);
		this.propertyNameMatcherFactory = propertyNameMatcherFactory;
		this.target = classMeta.getType();
		this.reflectionService = classMeta.getReflectionService();
		this.columnDefinitions = columnDefinitions;
		this.mapperBuilderErrorHandler = mapperBuilderErrorHandler;

	}

	protected Class getTargetClass() {
		return TypeHelper.toClass(target);
	}

	@SuppressWarnings("unchecked")
	protected Instantiator getInstantiator() throws MapperBuildingException {
		InstantiatorFactory instantiatorFactory = reflectionService.getInstantiatorFactory();
		try {
			return instantiatorFactory.getInstantiator(source, target, propertyMappingsBuilder, constructorInjections());
		} catch(Exception e) {
			throw new MapperBuildingException(e.getMessage(), e);
		}
	}

	private Map> constructorInjections() {
		final Map> injections = new HashMap>();
		
		propertyMappingsBuilder.forEachConstructorProperties(new ForEachCallBack>>() {
			@SuppressWarnings("unchecked")
			@Override
			public void handle(PropertyMapping> t) {
				PropertyMeta pm  = t.getPropertyMeta();
					ConstructorPropertyMeta cProp = (ConstructorPropertyMeta) pm;
					ConstructorParameter constructorParameter = cProp.getConstructorParameter();
					injections.put(constructorParameter, getterFor(t, constructorParameter.getResolvedType()));
			}
		});
		
		final Map> builderToInject = new HashMap>();
		propertyMappingsBuilder.forEachSubProperties(new ForEachCallBack>>() {
			@SuppressWarnings("unchecked")
			@Override
			public void handle(PropertyMapping> t) {
				PropertyMeta pm  = t.getPropertyMeta();
				SubPropertyMeta subProp = (SubPropertyMeta) pm;
				PropertyMeta propOwner = subProp.getOwnerProperty();
				if (propOwner.isConstructorProperty()) {
					ConstructorParameter param = ((ConstructorPropertyMeta)propOwner).getConstructorParameter();
					AbstractFieldMapperMapperBuilder builder = builderToInject.get(param);
					if (builder == null) {
						builder = newSubBuilder(propOwner.getType(), propOwner.getClassMeta());
						builderToInject.put(param, builder);
					}
					addPropertyBuilder(t, subProp, builder);
				}
			}

			@SuppressWarnings("unchecked")
			private 

void addPropertyBuilder(PropertyMapping> t, SubPropertyMeta subProp, AbstractFieldMapperMapperBuilder builder) { ((AbstractFieldMapperMapperBuilder)builder).addMapping(t.getColumnKey(), ((SubPropertyMeta)subProp).getSubProperty()); } }); for(Entry> e : builderToInject.entrySet()) { injections.put(e.getKey(), newSubMapperGetter(e.getValue())); } return injections; } @SuppressWarnings("unchecked") protected void _addMapping(K key, final FieldMapperColumnDefinition columnDefinition) { final FieldMapperColumnDefinition composedDefinition = FieldMapperColumnDefinition.compose(columnDefinition, columnDefinitions.getColumnDefinition(key)); final K mappedColumnKey = composedDefinition.rename(key); if (columnDefinition.getCustomFieldMapper() != null) { _addMapper((FieldMapper) columnDefinition.getCustomFieldMapper()); } else { propertyMappingsBuilder.addProperty(mappedColumnKey, composedDefinition); } } protected

void addMapping(K columnKey, PropertyMeta prop) { propertyMappingsBuilder.addProperty(columnKey, identity, prop); } private

Getter newSubMapperGetter(AbstractFieldMapperMapperBuilder value) { return new MapperGetterAdapter(value.mapper()); } @SuppressWarnings("unchecked") public final FieldMapper[] fields() { final List> fields = new ArrayList>(); final Map>, AbstractFieldMapperMapperBuilder> buildersByOwner = new HashMap>, AbstractFieldMapperMapperBuilder>(); propertyMappingsBuilder.forEachProperties(new ForEachCallBack>>() { final Map> builders = new HashMap>(); @Override public void handle(PropertyMapping> t) { if (t == null) return; PropertyMeta meta = t.getPropertyMeta(); if (meta == null) return; if (meta.isSubProperty()) { addSubProperty(t, (SubPropertyMeta) meta, t.getColumnKey()); } else if (!meta.isConstructorProperty()) { fields.add(newFieldMapper(t)); } } private

void addSubProperty(PropertyMapping> pm, SubPropertyMeta subPropertyMeta, K key) { PropertyMeta propertyOwner = subPropertyMeta.getOwnerProperty(); if (!propertyOwner.isConstructorProperty()) { AbstractFieldMapperMapperBuilder builder = (AbstractFieldMapperMapperBuilder) builders.get(propertyOwner.getName()); if (builder == null) { builder = (AbstractFieldMapperMapperBuilder) newSubBuilder(propertyOwner.getType(), propertyOwner.getClassMeta()); builders.put(propertyOwner.getName(), builder); buildersByOwner.put(pm, builder); } builder.addMapping(key, ((SubPropertyMeta)subPropertyMeta).getSubProperty()); } } }); for(Entry>, AbstractFieldMapperMapperBuilder> e : buildersByOwner.entrySet()) { SubPropertyMeta prop = (SubPropertyMeta) e.getKey().getPropertyMeta(); fields.add(newSubFieldMapper(prop.getOwnerProperty(), e.getValue(), e.getKey().getColumnKey())); } for(FieldMapper mapper : additionalMappers) { fields.add(mapper); } return fields.toArray(new FieldMapper[fields.size()]); } @SuppressWarnings("unchecked") private

FieldMapper newSubFieldMapper(PropertyMeta prop, AbstractFieldMapperMapperBuilder builder, K key) { Setter setter = (Setter) prop.getSetter(); return newFieldMapper(builder, setter, key); } @SuppressWarnings("unchecked") private

FieldMapper newFieldMapper( AbstractFieldMapperMapperBuilder builder, Setter setter, K key) { FieldMapper fm = new FieldMapperImpl((Getter) newSubMapperGetter(builder), setter); if (fieldMapperErrorHandler != null) { fm = new FieldErrorHandlerMapper(key, fm, fieldMapperErrorHandler); } return fm; } @SuppressWarnings("unchecked") protected

FieldMapper newFieldMapper(PropertyMapping> t) { FieldMapper fieldMapper = (FieldMapper) t.getColumnDefinition().getCustomFieldMapper(); if (fieldMapper == null) { fieldMapper = fieldMapperFactory.newFieldMapper(t, fieldMapperErrorHandler, mapperBuilderErrorHandler); } if (fieldMapperErrorHandler != null) { fieldMapper = new FieldErrorHandlerMapper(t.getColumnKey(), fieldMapper, fieldMapperErrorHandler); } return fieldMapper; } private Getter getterFor(PropertyMapping> t, Type paramType) { Getter getter = t.getColumnDefinition().getCustomGetter(); if (getter == null) { getter = getterFactory.newGetter(paramType, t.getColumnKey()); } if (getter == null) { mapperBuilderErrorHandler.getterNotFound("Could not find getter for " + t.getColumnKey() + " type " + paramType); } return getter; } protected void _addMapper(FieldMapper mapper) { additionalMappers.add(mapper); } protected abstract AbstractFieldMapperMapperBuilder newSubBuilder(Type type, ClassMeta classMeta); public abstract Mapper mapper(); protected void setFieldMapperErrorHandler( FieldMapperErrorHandler errorHandler) { this.fieldMapperErrorHandler = errorHandler; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy