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

org.sklsft.commons.mapper.impl.DeepCopier Maven / Gradle / Ivy

There is a newer version: 5.0.0-M1
Show newest version
package org.sklsft.commons.mapper.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.sklsft.commons.api.annotations.compare.Deep;
import org.sklsft.commons.api.annotations.compare.Ignored;
import org.sklsft.commons.mapper.beans.AccessibleField;
import org.sklsft.commons.mapper.beans.MappableBean;
import org.sklsft.commons.mapper.beans.MappableBeanFactory;
import org.sklsft.commons.mapper.interfaces.Copier;

public class DeepCopier implements Copier {

	private final MappableBean mappableBean;
	
	private Class clazz;
	
	private Map, Copier> copiers = new HashMap<>();
	
	
	public DeepCopier (Class clazz) {
		this.clazz = clazz;
		mappableBean = MappableBeanFactory.getMappableBean(clazz);
	}


	@Override
	@SuppressWarnings({ "unchecked", "rawtypes" })	
	public T copy(Object src, boolean copyIgnoredFields) {
		
		if (src == null) {
			return null;
		}
		
		if (!clazz.isAssignableFrom(src.getClass())) {
			throw new IllegalArgumentException("Cannot copy an instance of : " + src.getClass().getName() + " in a : " + clazz.getName());
		}
		
		T dest;
		try {
			dest = clazz.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			throw new IllegalArgumentException("Cannot instantiate a : " + clazz.getName());
		}

		for (AccessibleField accessibleField : mappableBean.accessibleFields) {
			if (copyIgnoredFields || !accessibleField.field.isAnnotationPresent(Ignored.class)) {		
				
				if (accessibleField.field.isAnnotationPresent(Deep.class)) {
					
					if (accessibleField.isCollection) {
						
						Copier copier = getCopier(accessibleField.genericParameters.get(0));
						
						Collection srcCollection = (Collection) accessibleField.getValue(src);
						try {							
							Collection destCollection = (Collection) srcCollection.getClass().newInstance();
							for (Object obj:(Collection)srcCollection) {
								destCollection.add(copier.copy(obj, copyIgnoredFields));
							}
							accessibleField.setValue(destCollection, dest);
							
						} catch (InstantiationException | IllegalAccessException e) {
							throw new IllegalArgumentException("Cannot instantiate a : " + srcCollection.getClass().getName());
						}
					} else if (accessibleField.isMap) {
						
						Copier copier = getCopier(accessibleField.genericParameters.get(1));
						
						Map srcMap = (Map) accessibleField.getValue(src);
						try {							
							Map destMap = (Map) srcMap.getClass().newInstance();
							for (Object pair:srcMap.entrySet()) {
								Entry entry = (Entry)pair;
								destMap.put(entry.getKey(), copier.copy(entry.getValue()));
							}
							accessibleField.setValue(destMap, dest);
						} catch (InstantiationException | IllegalAccessException e) {
							throw new IllegalArgumentException("Cannot instantiate a : " + srcMap.getClass().getName());
						}
					} else {
						Class fieldClass = accessibleField.fieldClass;
						Copier copier = getCopier(fieldClass);
						accessibleField.setValue(copier.copy(accessibleField.getValue(src), copyIgnoredFields), dest);
					}
				} else {
					if (accessibleField.isCollection) {						
						Collection srcCollection = (Collection) accessibleField.getValue(src);
						try {							
							Collection destCollection = (Collection) srcCollection.getClass().newInstance();
							for (Object obj:srcCollection) {
								destCollection.add(obj);
							}
							accessibleField.setValue(destCollection, dest);
							
						} catch (InstantiationException | IllegalAccessException e) {
							throw new IllegalArgumentException("Cannot instantiate a : " + srcCollection.getClass().getName());
						}
						
					} else if (accessibleField.isMap) {
						Map srcMap = (Map) accessibleField.getValue(src);
						try {							
							Map destMap = (Map) srcMap.getClass().newInstance();
							for (Object pair:srcMap.entrySet()) {
								Entry entry = (Entry)pair;
								destMap.put(entry.getKey(), entry.getValue());
							}
							accessibleField.setValue(destMap, dest);
							
						} catch (InstantiationException | IllegalAccessException e) {
							throw new IllegalArgumentException("Cannot instantiate a : " + srcMap.getClass().getName());
						}
					} else {
						accessibleField.setValue(accessibleField.getValue(src), dest);
					}
				}
			}
		}
		
		return dest;
	}
	
	
	@Override
	public T copy(Object src) {
		return copy(src, false);
	}
	
	private Copier getCopier(Class clazz) {
		if (!copiers.containsKey(clazz)) {
			copiers.put(clazz, new DeepCopier<>(clazz));
		}
		return copiers.get(clazz);
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy