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

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

import net.projectmonkey.object.mapper.ObjectMappingService;
import net.projectmonkey.object.mapper.construction.ElementPopulationContext;
import net.projectmonkey.object.mapper.construction.PopulationContext;
import net.projectmonkey.object.mapper.context.ExecutionContext;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;

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

/**
 * Support class for converting Iterable and psuedo-Iterable (array) instances. Implementors must
 * support source and destination types that are Iterable or array instances.
 * 

* Adapted from ModelMapper (modelmapper.org) * * @author Jonathan Halterman * @author Andy Moody */ abstract class IterableConverter implements Converter { @Override public DestinationType convert(final PopulationContext context) { SourceType source = context.getSource(); Class destinationType = (Class) context.getDestinationType(); int sourceLength = getSourceLength(source); TypeAndClass elementType = getElementType(destinationType, context); DestinationType destination = createDestination(destinationType, sourceLength, elementType); int index = 0; for (Iterator iterator = getSourceIterator(source); iterator.hasNext(); index++) { Object sourceElement = iterator.next(); ObjectMappingService mappingService = getMappingService(); PopulationContext elementContext = new ElementPopulationContext(sourceElement, elementType, context); Object element = mappingService.map(sourceElement, elementType.getClazz(), elementContext); setElement(destination, element, index); } return destination; } /** * Creates a destination instance for the {@code destinationType} where the destination supports * element {@code length}. */ protected abstract DestinationType createDestination(final Class destinationType, final int length, final TypeAndClass elementType); /** * Gets the contained element type for the {@code type} and nullable {@code genericType}. * * @param destinationType to retrieve element type for * @param context */ protected TypeAndClass getElementType(final Class destinationType, final PopulationContext context) { return new TypeAndClass(Object.class); } /** * Gets an Iterator for the Iterable or psuedo-Iterable (array) {@code source}. */ @SuppressWarnings("unchecked") protected Iterator getSourceIterator(final SourceType source) { return source.getClass().isArray() ? new ArrayIterator(source) : ((Iterable) source) .iterator(); } /** * Gets the source length of the Iterable or psuedo-Iterable (array) {@code source}. */ protected int getSourceLength(final SourceType source) { return source.getClass().isArray() ? Array.getLength(source) : ((Collection) source).size(); } /** * Gets the destination length of the Iterable or psuedo-Iterable (array) {@code destination}. */ protected int getDestinationLength(final DestinationType destination) { return destination.getClass().isArray() ? Array.getLength(destination) : ((Collection) destination).size(); } /** * Sets the {@code element} at the against the {@code destination} at the optional {@code index}. */ protected abstract void setElement(final DestinationType destination, final Object element, final int index); protected ObjectMappingService getMappingService() { return ExecutionContext.getMappingService(); } }