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

com.aol.cyclops.lambda.tuple.ParamMatcher Maven / Gradle / Ivy

The newest version!
package com.aol.cyclops.lambda.tuple;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.aol.cyclops.invokedynamic.ExceptionSoftener;

class ParamMatcher {

	public   T create(Class to, int arity, List values, Throwable t){
		List classes = Stream.of(values).map(v->v==null? null : v.getClass())
							.collect(Collectors.toList());
		
		List> cons = Stream.of(to.getConstructors())
				.filter(c -> c.getParameterCount()==arity)
				.collect(Collectors.toList());
		
		for(Constructor c : cons){
			if(match(c,classes))
				try {
					//constructors from successful conversions should be cached
					return (T)c.newInstance(order(values,c).toArray());
				} catch (InstantiationException | IllegalAccessException
						| IllegalArgumentException | InvocationTargetException e) {
					
				}
		}
		ExceptionSoftener.throwSoftenedException(t);
		return null;
	}
	 private List order(List values,Constructor c) {
		Class[] order = c.getParameterTypes();
		List result = new ArrayList<>();
		for(Class next : order){
			result.add(find(next,values));
		}
		return result;
		
	}
	private Object find(Class next, List values) {
		return values.stream().filter(v->v!=null)
					.filter(v->v.getClass().isAssignableFrom(next))
					.findFirst().orElse(null);
	}
	boolean match(Constructor c, List values){
		return values.stream()
		 	.filter(v->v!=null)
		 	.map(v->matchFor(v,c))
		 	.allMatch(t->t);
		
	}
	private boolean matchFor(Class v, Constructor c) {
		return Stream.of(c.getParameterTypes()).anyMatch(ct->v.isAssignableFrom(ct));
	}
}