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

net.projectmonkey.object.mapper.construction.converter.resolver.StandardConverterResolver 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.construction.converter.resolver;

/*
 *
 *  * 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.
 *
 */

import net.projectmonkey.object.mapper.construction.ConfigurationResolutionUtil;
import net.projectmonkey.object.mapper.construction.PopulationContext;
import net.projectmonkey.object.mapper.construction.converter.*;
import net.projectmonkey.object.mapper.context.ConversionConfiguration;
import net.projectmonkey.object.mapper.util.Types;
import net.projectmonkey.object.mapper.analysis.result.PropertyConfiguration;

import java.util.*;

/**
 * The base ConverterResolver.
 * Resolves converters by:
 *
 * Returning the converter configured for the group by the {@link net.projectmonkey.object.mapper.annotations.group.Group}
 * annotations if there is precisely one. Throwing an error if more than one converter is configured for the current
 * group.
 *
 * Scanning the {@link #defaultConverterStore} and {@link net.projectmonkey.object.mapper.context.ConversionConfiguration#customConverterStore} lists
 * to find the first appropriate converter if there are no specific configured converters for the context and group
 * or that are configured for all properties.
 *
 *
 * @author Andy Moody
 */
public class StandardConverterResolver implements ConverterResolver
{

	public static final StandardConverterResolver INSTANCE = new StandardConverterResolver();

	private static final ConverterStore defaultConverterStore;
	private static final ConfigurationResolutionUtil util = ConfigurationResolutionUtil.INSTANCE;
	private static final ConverterRetriever retriever = new ConverterRetriever();

	static
	{
		defaultConverterStore = new ConverterStore();
		defaultConverterStore.addAll(
				StringConverter.INSTANCE,
				EnumConverter.INSTANCE,
				BooleanConverter.INSTANCE,
				NumberConverter.INSTANCE,
				CalendarToLongConverter.INSTANCE,
				DateToLongConverter.INSTANCE,
				DateConverter.INSTANCE,
				MappedDestinationTypeConverter.INSTANCE,
				MapConverter.INSTANCE,
				CollectionConverter.INSTANCE,
				ArrayConverter.INSTANCE,
				AssignableTypeConverter.INSTANCE
		);
	}

	private StandardConverterResolver(){}

	@Override
	public Converter getFirstAppropriateConverter(final PopulationContext context)
	{
		Converter toReturn = util.getFirstAppropriate(context, retriever);
		Class destinationType = context.getDestinationType();
		if(toReturn == null && Types.isKnownType(destinationType))
		{
			throw new IllegalStateException("Unable to convert " + context.getSource() + " to known type " + destinationType);
		}
		return toReturn;
	}


	private static class ConverterRetriever implements ConfigurationResolutionUtil.ConfiguredTypeRetriever
	{

		@Override
		public Class retrieveType(final PropertyConfiguration configuration)
		{
			return configuration.getConverter();
		}

		@Override
		public Class getTopLevelType()
		{
			return Converter.class;
		}

		@Override
		public List> getConfigured(final ConversionConfiguration configuration, final PopulationContext context)
		{
			ConverterStore customConverterStore = configuration.getCustomConverterStore();
			List> toReturn = new ArrayList>();

			Converter cachedCustomConverter = customConverterStore.getCached(context);
			if(cachedCustomConverter != null)
			{
				toReturn.add(cachedCustomConverter);
			}
			else
			{
				toReturn.addAll(customConverterStore.getNonCached());
				Converter cachedDefaultConverter = defaultConverterStore.getCached(context);
				if(cachedDefaultConverter != null)
				{
					toReturn.add(cachedDefaultConverter);
				}
				else
				{
					toReturn.addAll(defaultConverterStore.getNonCached());
				}
			}

			return toReturn;
		}

		@Override
		public boolean isApplicable(final Converter item, final PopulationContext context)
		{
			return item.canConvert(context);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy