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

net.projectmonkey.object.mapper.context.ConversionConfiguration Maven / Gradle / Ivy

Go to download

Object mapping implementation written as an alternative to modelmapper which is able to support inheritance, handles flattening / expanding in a precise way, and is extensible / configurable

The newest version!
package net.projectmonkey.object.mapper.context;

import net.projectmonkey.object.mapper.analysis.cache.TypePair;
import net.projectmonkey.object.mapper.analysis.duplicates.ClosestMatchDuplicatesBehaviour;
import net.projectmonkey.object.mapper.analysis.duplicates.DuplicateMappingBehaviour;
import net.projectmonkey.object.mapper.analysis.matching.MatchingStrategies;
import net.projectmonkey.object.mapper.analysis.matching.MatchingStrategy;
import net.projectmonkey.object.mapper.analysis.resolver.PropertyResolver;
import net.projectmonkey.object.mapper.analysis.resolver.PropertyResolvers;
import net.projectmonkey.object.mapper.analysis.tokenizer.CamelCaseTokenizer;
import net.projectmonkey.object.mapper.analysis.tokenizer.PropertyNameTokenizer;
import net.projectmonkey.object.mapper.construction.converter.Converter;
import net.projectmonkey.object.mapper.construction.converter.resolver.ConverterStore;
import net.projectmonkey.object.mapper.construction.postprocessor.PostProcessor;
import net.projectmonkey.object.mapper.construction.rule.MappingRule;
import net.projectmonkey.object.mapper.construction.type.DefaultDestinationTypeProvider;
import net.projectmonkey.object.mapper.construction.type.DestinationTypeProvider;
import net.projectmonkey.object.mapper.construction.type.GenericTypeResolver;
import net.projectmonkey.object.mapper.util.Assert;
import net.projectmonkey.object.mapper.util.Logger;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.util.*;

/*
 *
 *  * Copyright 2012 the original author or authors.
 *  *
 *  * Licensed under the Apache License, Version 2.0 (the "License");
 *  * you may not use this file except in compliance with the License.
 *  * You may obtain a copy of the License at
 *  *
 *  *      http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  * Unless required by applicable law or agreed to in writing, software
 *  * distributed under the License is distributed on an "AS IS" BASIS,
 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  * See the License for the specific language governing permissions and
 *  * limitations under the License.
 *
 */

/**
 * @author Andy Moody
 *
 * The ConversionConfiguration allows complete customisation of the mapping process.
 */
public class ConversionConfiguration
{

	private static final Logger logger = Logger.getLogger(ConversionConfiguration.class);
	/**
	 * The group against which we are performing mapping.
	 */
	private Class group = Default.class;

	private PropertyResolver sourcePropertyResolver = PropertyResolvers.FIELD;
	private PropertyResolver destinationPropertyResolver = PropertyResolvers.FIELD;
	private PropertyNameTokenizer sourceTokenizer = CamelCaseTokenizer.INSTANCE;
	private PropertyNameTokenizer destinationTokenizer = CamelCaseTokenizer.INSTANCE;
	private MatchingStrategy matchingStrategy = MatchingStrategies.FLATTENING;
	private ConverterStore customConverterStore = new ConverterStore();
	private List> customRules = new ArrayList>();
	private List> postProcessors = new ArrayList>();
	private Collection dateFormats = new ArrayList();
	private DestinationTypeProvider destinationTypeProvider = new DefaultDestinationTypeProvider(); //new instance each time because it's stateful.
	private DuplicateMappingBehaviour duplicateMappingBehaviour = ClosestMatchDuplicatesBehaviour.INSTANCE;
	private Map, GenericTypeResolver> genericTypeResolvers = new HashMap, GenericTypeResolver>();

	public ConversionConfiguration(){}

	/**
	 * Constructor allowing creation of a new instance starting from a common base configuration.
	 * @param base
	 */
	public ConversionConfiguration(ConversionConfiguration base)
	{
		this.group = base.getGroup();
		this.sourcePropertyResolver = base.getSourcePropertyResolver();
		this.destinationPropertyResolver = base.getDestinationPropertyResolver();
		this.sourceTokenizer = base.getSourceTokenizer();
		this.destinationTokenizer = base.getDestinationTokenizer();
		this.matchingStrategy = base.getMatchingStrategy();
		this.customConverterStore = new ConverterStore(base.getCustomConverterStore());
		this.customRules = new ArrayList>(base.getCustomRules());
		this.postProcessors = new ArrayList>(base.getPostProcessors());
		this.dateFormats = new ArrayList(base.getDateFormats());
		this.destinationTypeProvider = new DefaultDestinationTypeProvider();
		this.duplicateMappingBehaviour = base.getDuplicateMappingBehaviour();
		for (TypePair typePair : base.getDestinationTypeProvider().getAllTypes())
		{
			this.destinationTypeProvider.addTypes(typePair);
		}
	}

	public Class getGroup()
	{
		return group;
	}

	public ConversionConfiguration setGroup(final Class group)
	{
		this.group = group;
		return this;
	}

	public ConversionConfiguration setSourcePropertyResolver(final PropertyResolver sourcePropertyResolver)
	{
		Assert.notNull(sourcePropertyResolver, "sourcePropertyResolver");
		this.sourcePropertyResolver = sourcePropertyResolver;
		return this;
	}

	public PropertyResolver getSourcePropertyResolver()
	{
		return sourcePropertyResolver;
	}

	public ConversionConfiguration setDestinationPropertyResolver(final PropertyResolver destinationPropertyResolver)
	{
		Assert.notNull(destinationPropertyResolver, "destinationPropertyResolver");
		this.destinationPropertyResolver = destinationPropertyResolver;
		return this;
	}

	public PropertyResolver getDestinationPropertyResolver()
	{
		return destinationPropertyResolver;
	}

	public ConversionConfiguration setSourceTokenizer(final PropertyNameTokenizer sourceTokenizer)
	{
		Assert.notNull(sourceTokenizer, "sourceTokenizer");
		this.sourceTokenizer = sourceTokenizer;
		return this;
	}

	public PropertyNameTokenizer getSourceTokenizer()
	{
		return sourceTokenizer;
	}

	public ConversionConfiguration setDestinationTokenizer(final PropertyNameTokenizer destinationTokenizer)
	{
		Assert.notNull(destinationTokenizer, "destinationTokenizer");
		this.destinationTokenizer = destinationTokenizer;
		return this;
	}

	public PropertyNameTokenizer getDestinationTokenizer()
	{
		return destinationTokenizer;
	}

	/**
	 * @param matchingStrategy
	 */
	public ConversionConfiguration setMatchingStrategy(final MatchingStrategy matchingStrategy)
	{
		Assert.notNull(matchingStrategy, "matchingStrategy");
		this.matchingStrategy = matchingStrategy;
		return this;
	}

	public MatchingStrategy getMatchingStrategy()
	{
		return matchingStrategy;
	}

	public ConversionConfiguration addConverter(Converter converter)
	{
		customConverterStore.add(converter);
		return this;
	}

	public ConversionConfiguration addConverters(Converter... converters)
	{
		for (Converter converter : converters)
		{
			addConverter(converter);
		}
		return this;
	}

	public ConverterStore getCustomConverterStore()
	{
		return customConverterStore;
	}

	public ConversionConfiguration addRule(MappingRule rule)
	{
		return addTo(this.customRules, rule, "rule");
	}

	public List> getCustomRules()
	{
		return customRules;
	}

	public List> getPostProcessors()
	{
		return postProcessors;
	}

	public ConversionConfiguration addPostProcessor(PostProcessor postProcessor)
	{
		return addTo(this.postProcessors, postProcessor, "postProcessor");
	}

	public ConversionConfiguration addDateFormat(String format)
	{
		return addTo(this.dateFormats, format, "format");
	}

	public Collection getDateFormats()
	{
		return dateFormats;
	}

	public DestinationTypeProvider getDestinationTypeProvider()
	{
		return destinationTypeProvider;
	}

	public ConversionConfiguration setDestinationTypeProvider(final DestinationTypeProvider destinationTypeProvider)
	{
		Assert.notNull(destinationTypeProvider, "destinationTypeProvider");
		this.destinationTypeProvider = destinationTypeProvider;
		return this;
	}

	/**
	 * @param sourceType the source type.
	 * @param destinationType the destination type
	 * @return this
	 */
	public ConversionConfiguration addDestinationTypeMapping(Class sourceType, Class destinationType)
	{
		Assert.notNull(sourceType, "sourceType");
		Assert.notNull(destinationType, "destinationType");
		this.destinationTypeProvider.addTypes(TypePair.of(sourceType, destinationType));
		return this;
	}

	public DuplicateMappingBehaviour getDuplicateMappingBehaviour()
	{
		return duplicateMappingBehaviour;
	}

	public ConversionConfiguration setDuplicateMappingBehaviour(final DuplicateMappingBehaviour duplicateMappingBehaviour)
	{
		Assert.notNull(duplicateMappingBehaviour, "duplicateMappingBehaviour");
		this.duplicateMappingBehaviour = duplicateMappingBehaviour;
		return this;
	}

	/**
	 * @param genericTypeResolver - types will be mapped using {@link GenericTypeResolver#getApplicableSourceTypes()}
	 * @return this
	 */
	public ConversionConfiguration addGenericTypeResolver(final GenericTypeResolver genericTypeResolver)
	{
		Assert.notNull(genericTypeResolver, "genericTypeResolver");
		return registerGenericTypeResolver(genericTypeResolver, genericTypeResolver.getApplicableSourceTypes());
	}

	/**
	 * Registers the type resolver against the classes specified. Types listed in {@link GenericTypeResolver#getApplicableSourceTypes()} are ignored
	 * @param genericTypeResolver
	 * @param types
	 * @return
	 */
	public ConversionConfiguration registerGenericTypeResolver(final GenericTypeResolver genericTypeResolver, Class...types)
	{
		Assert.notNull(genericTypeResolver, "genericTypeResolver");
		Assert.notNull(types, "types");
		for (Class type : types)
		{
			if(this.genericTypeResolvers.containsKey(type))
			{
				logger.warn("Overwriting generic type resolver for type %s with new resolver %s", type, genericTypeResolver);
			}
			this.genericTypeResolvers.put(type, genericTypeResolver);
		}
		return this;
	}

	public Map, GenericTypeResolver> getGenericTypeResolvers()
	{
		return genericTypeResolvers;
	}

	@Override
	public boolean equals(final Object o)
	{
		return EqualsBuilder.reflectionEquals(this, o);
	}

	@Override
	public int hashCode()
	{
		return HashCodeBuilder.reflectionHashCode(this);
	}

	private  ConversionConfiguration addTo(Collection items, T item, String itemName)
	{
		Assert.notNull(item, itemName);
		items.add(item);
		return this;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy