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

net.projectmonkey.object.mapper.construction.converter.ArrayConverter Maven / Gradle / Ivy

package net.projectmonkey.object.mapper.construction.converter;

import net.projectmonkey.object.mapper.construction.PopulationContext;
import net.projectmonkey.object.mapper.construction.type.GenericTypeUtils;
import net.projectmonkey.object.mapper.util.Iterables;
import net.projectmonkey.object.mapper.util.TypeResolver;
import org.apache.commons.lang3.ArrayUtils;

import java.lang.reflect.Array;

import static net.projectmonkey.object.mapper.construction.type.GenericTypeUtils.TypeAndClass;

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

/**
 * Converts {@link java.util.Collection} and array instances to array instances.
 *
 * Adapted from ModelMapper (modelmapper.org)
 *
 * N.B. This implementation ALWAYS replaces the destination array
 * with the converted contents of the source array.
 *
 * An alternative strategy would be to attempt to merge the destination
 * objects based on position in the array and remove any superfluous
 * destinations but this seemed likely to be error prone.
 *
 * @author Jonathan Halterman
 * @author Andy Moody
 */
public class ArrayConverter extends IterableConverter
{
	public static final ArrayConverter INSTANCE = new ArrayConverter();

	private ArrayConverter(){}


	@Override
	protected void setElement(Object destination, Object element, int index)
	{
		Array.set(destination, index, element);
	}

	@Override
	protected TypeAndClass getElementType(Class destinationType, final PopulationContext context)
	{
		TypeAndClass[] elementTypes = GenericTypeUtils.INSTANCE.getArgumentTypes(context);
		TypeAndClass elementType;
		TypeAndClass defaultElementType = new TypeAndClass(destinationType.getComponentType());
		if(ArrayUtils.isEmpty(elementTypes))
		{
			elementType = defaultElementType;
		}
		else
		{
			elementType = elementTypes[0];
			elementType = elementType.getClazz() == TypeResolver.Unknown.class ? new TypeAndClass(destinationType.getComponentType()) : elementType;
		}
		return elementType;
	}

	@Override
	protected Object createDestination(Class destinationType, int length, final TypeAndClass elementType)
	{
		Class componentType = elementType.getClazz();
		return Array.newInstance(destinationType.isArray() ? componentType : destinationType, length);
	}

	@Override
	public boolean canConvert(final PopulationContext context)
	{
		boolean toReturn = false;
		Object source = context.getSource();
		if(source != null)
		{
			toReturn = Iterables.isIterable(source.getClass()) && context.getDestinationType().isArray();
		}
		return toReturn;
	}

}