package org.smoothbuild.lang.function.nativ; import static org.smoothbuild.lang.function.base.Parameter.parameter; import static org.smoothbuild.lang.type.Types.jTypeToType; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import org.smoothbuild.lang.function.base.Parameter; import org.smoothbuild.lang.plugin.Required; import org.smoothbuild.lang.type.Type; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import com.google.inject.TypeLiteral; public class NativeParameterFactory { public static Parameter createParameter(Method method, java.lang.reflect.Parameter jParameter, Annotation[] annotations) throws NativeFunctionImplementationException { Multimap<Class<?>, Annotation> annotationMap = annotationsMap(annotations); Type type = type(method, jParameter.getParameterizedType()); String name = jParameter.getName(); boolean isRequired = isRequired(method, annotationMap); return parameter(type, name, isRequired); } private static Type type(Method method, java.lang.reflect.Type reflectType) throws NativeFunctionImplementationException { Type type = jTypeToType(TypeLiteral.get(reflectType)); if (type == null) { throw new NativeFunctionImplementationException(method, "It has parameter with illegal java type '" + reflectType.getTypeName() + "'."); } return type; } private static boolean isRequired(Method method, Multimap<Class<?>, Annotation> annotations) throws NativeFunctionImplementationException { switch (annotations.get(Required.class).size()) { case 0: return false; case 1: return true; default: throw new NativeFunctionImplementationException(method, "One of its parameters is annotated twice as " + Required.class.getName()); } } private static Multimap<Class<?>, Annotation> annotationsMap(Annotation[] annotations) { ImmutableMultimap.Builder<Class<?>, Annotation> builder = ImmutableMultimap.builder(); for (Annotation annotation : annotations) { builder.put(annotation.annotationType(), annotation); } return builder.build(); } }